workaround a problem with the harmattan gcc
[drnoksnes] / cpuexec.h
1 /*
2  * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  *
4  * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5  *                           Jerremy Koot (jkoot@snes9x.com)
6  *
7  * Super FX C emulator code 
8  * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
9  *                           Gary Henderson.
10  * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
11  *
12  * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13  * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14  * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
15  *
16  * DOS port code contains the works of other authors. See headers in
17  * individual files.
18  *
19  * Snes9x homepage: http://www.snes9x.com
20  *
21  * Permission to use, copy, modify and distribute Snes9x in both binary and
22  * source form, for non-commercial purposes, is hereby granted without fee,
23  * providing that this license information and copyright notice appear with
24  * all copies and any derived work.
25  *
26  * This software is provided 'as-is', without any express or implied
27  * warranty. In no event shall the authors be held liable for any damages
28  * arising from the use of this software.
29  *
30  * Snes9x is freeware for PERSONAL USE only. Commercial users should
31  * seek permission of the copyright holders first. Commercial use includes
32  * charging money for Snes9x or software derived from Snes9x.
33  *
34  * The copyright holders request that bug fixes and improvements to the code
35  * should be forwarded to them so everyone can benefit from the modifications
36  * in future versions.
37  *
38  * Super NES and Super Nintendo Entertainment System are trademarks of
39  * Nintendo Co., Limited and its subsidiary companies.
40  */
41 #ifndef _CPUEXEC_H_
42 #define _CPUEXEC_H_
43 #include "ppu.h"
44 #include "memmap.h"
45 #include "65c816.h"
46
47 #define DO_HBLANK_CHECK() \
48     if (CPU.Cycles >= CPU.NextEvent) \
49                 S9xDoHBlankProcessing ();
50
51 struct SOpcodes {
52         void (*S9xOpcode)();
53 };
54
55 struct SICPU
56 {
57 #if !defined(CONF_BUILD_ASM_CORE) || !CONF_BUILD_ASM_CORE
58     uint8  *Speed;
59     struct SOpcodes *S9xOpcodes;
60     uint8  _Carry;
61     uint8  _Zero;
62     uint8  _Negative;
63     uint8  _Overflow;
64 #endif
65         bool8  CPUExecuting;
66     uint32 ShiftedPB;
67     uint32 ShiftedDB;
68     uint32 Frame;
69     uint32 Scanline;
70     uint32 FrameAdvanceCount;
71 };
72
73 START_EXTERN_C
74 void S9xMainLoop (void);
75 void S9xReset (void);
76 void S9xDoHBlankProcessing ();
77 void S9xClearIRQ (uint32);
78 void S9xSetIRQ (uint32);
79
80 extern struct SOpcodes S9xOpcodesM1X1 [256];
81 extern struct SOpcodes S9xOpcodesM1X0 [256];
82 extern struct SOpcodes S9xOpcodesM0X1 [256];
83 extern struct SOpcodes S9xOpcodesM0X0 [256];
84
85 #ifndef VAR_CYCLES
86 extern uint8 S9xE1M1X1 [256];
87 extern uint8 S9xE0M1X0 [256];
88 extern uint8 S9xE0M1X1 [256];
89 extern uint8 S9xE0M0X0 [256];
90 extern uint8 S9xE0M0X1 [256];
91 #endif
92
93 extern struct SICPU ICPU;
94 END_EXTERN_C
95
96 STATIC inline void CLEAR_IRQ_SOURCE (uint32 M)
97 {
98     CPU.IRQActive &= ~M;
99     if (!CPU.IRQActive)
100         CPU.Flags &= ~IRQ_PENDING_FLAG;
101 }
102
103 #if !CONF_BUILD_ASM_CPU
104 STATIC inline void S9xUnpackStatus()
105 {
106     ICPU._Zero = (Registers.PL & Zero) == 0;
107     ICPU._Negative = (Registers.PL & Negative);
108     ICPU._Carry = (Registers.PL & Carry);
109     ICPU._Overflow = (Registers.PL & Overflow) >> 6;
110 }
111
112 STATIC inline void S9xPackStatus()
113 {
114     Registers.PL &= ~(Zero | Negative | Carry | Overflow);
115     Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) |
116                     (ICPU._Negative & 0x80) | (ICPU._Overflow << 6);
117 }
118
119 STATIC inline void S9xFixCycles ()
120 {
121     if (CheckEmulation ())
122     {
123 #ifndef VAR_CYCLES
124         ICPU.Speed = S9xE1M1X1;
125 #endif
126         ICPU.S9xOpcodes = S9xOpcodesM1X1;
127     }
128     else
129     if (CheckMemory ())
130     {
131         if (CheckIndex ())
132         {
133 #ifndef VAR_CYCLES
134             ICPU.Speed = S9xE0M1X1;
135 #endif
136             ICPU.S9xOpcodes = S9xOpcodesM1X1;
137         }
138         else
139         {
140 #ifndef VAR_CYCLES
141             ICPU.Speed = S9xE0M1X0;
142 #endif
143             ICPU.S9xOpcodes = S9xOpcodesM1X0;
144         }
145     }
146     else
147     {
148         if (CheckIndex ())
149         {
150 #ifndef VAR_CYCLES
151             ICPU.Speed = S9xE0M0X1;
152 #endif
153             ICPU.S9xOpcodes = S9xOpcodesM0X1;
154         }
155         else
156         {
157 #ifndef VAR_CYCLES
158             ICPU.Speed = S9xE0M0X0;
159 #endif
160             ICPU.S9xOpcodes = S9xOpcodesM0X0;
161         }
162     }
163 }
164 #endif
165
166 STATIC inline void S9xReschedule ()
167 {
168     uint8 which;
169     long max;
170     
171     if (CPU.WhichEvent == HBLANK_START_EVENT ||
172         CPU.WhichEvent == HTIMER_AFTER_EVENT)
173     {
174         which = HBLANK_END_EVENT;
175         max = Settings.H_Max;
176     }
177     else
178     {
179         which = HBLANK_START_EVENT;
180         max = Settings.HBlankStart;
181     }
182
183     if (PPU.HTimerEnabled &&
184         (long) PPU.HTimerPosition < max &&
185         (long) PPU.HTimerPosition > CPU.NextEvent &&
186         (!PPU.VTimerEnabled ||
187          (PPU.VTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos)))
188     {
189         which = (long) PPU.HTimerPosition < Settings.HBlankStart ?
190                         HTIMER_BEFORE_EVENT : HTIMER_AFTER_EVENT;
191         max = PPU.HTimerPosition;
192     }
193     CPU.NextEvent = max;
194     CPU.WhichEvent = which;
195 }
196
197 #endif