summaryrefslogtreecommitdiff
path: root/apps/codecs/libgme/z80_cpu_run.h
diff options
context:
space:
mode:
authorTorne Wuff <torne@wolfpuppy.org.uk>2011-11-06 22:44:25 +0000
committerTorne Wuff <torne@wolfpuppy.org.uk>2011-11-06 22:44:25 +0000
commit569285794b9112f0134ddad4bb886308ea4a7be6 (patch)
treece702cb07829820261a682c471133c76d11c610e /apps/codecs/libgme/z80_cpu_run.h
parentd9b7d58fa6c9ceb136bea429adf6746cc7138208 (diff)
downloadrockbox-569285794b9112f0134ddad4bb886308ea4a7be6.tar.gz
rockbox-569285794b9112f0134ddad4bb886308ea4a7be6.zip
Bulk convert all DOS line endings to UNIX.
For the git migration we want a nice clean repository with UNIX line endings. git does not use svn:eol-style, we just need the file contents to be sane. Sorry everybody. I know this messes up blame. Scumbag *NIX developer says migrating to git will make line ending issues go away; commits giant change to svn which changes line endings anyway. :) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30924 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libgme/z80_cpu_run.h')
-rw-r--r--apps/codecs/libgme/z80_cpu_run.h3392
1 files changed, 1696 insertions, 1696 deletions
diff --git a/apps/codecs/libgme/z80_cpu_run.h b/apps/codecs/libgme/z80_cpu_run.h
index 18195ac92b..a453487bb0 100644
--- a/apps/codecs/libgme/z80_cpu_run.h
+++ b/apps/codecs/libgme/z80_cpu_run.h
@@ -1,1696 +1,1696 @@
1// Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/ 1// Game_Music_Emu 0.6-pre. http://www.slack.net/~ant/
2 2
3// Last validated with zexall 2009.12.05. 3// Last validated with zexall 2009.12.05.
4// Doesn't implement the R register or immediate interrupt after EI. 4// Doesn't implement the R register or immediate interrupt after EI.
5// Address wrap-around isn't completely correct, but is prevented from crashing emulator. 5// Address wrap-around isn't completely correct, but is prevented from crashing emulator.
6// 16-bit memory accesses are made directly to mapped memory, instead of using macro. 6// 16-bit memory accesses are made directly to mapped memory, instead of using macro.
7 7
8#if 0 8#if 0
9/* Define these macros in the source file before #including this file. 9/* Define these macros in the source file before #including this file.
10- Parameters might be expressions, so they are best evaluated only once, 10- Parameters might be expressions, so they are best evaluated only once,
11though they NEVER have side-effects, so multiple evaluation is OK. 11though they NEVER have side-effects, so multiple evaluation is OK.
12- Output parameters might be a multiple-assignment expression like "a=x", 12- Output parameters might be a multiple-assignment expression like "a=x",
13so they must NOT be parenthesized. 13so they must NOT be parenthesized.
14- Except where noted, time() and related functions will NOT work 14- Except where noted, time() and related functions will NOT work
15correctly inside a macro. TIME() is always correct, and between FLUSH_TIME() and 15correctly inside a macro. TIME() is always correct, and between FLUSH_TIME() and
16CACHE_TIME() the normal time changing functions can be used. 16CACHE_TIME() the normal time changing functions can be used.
17- Macros "returning" void may use a {} statement block. */ 17- Macros "returning" void may use a {} statement block. */
18 18
19 // 0 <= addr <= 0xFFFF + 0x100 19 // 0 <= addr <= 0xFFFF + 0x100
20 // Optional; default uses whatever was set with map_mem() 20 // Optional; default uses whatever was set with map_mem()
21 int READ_MEM( addr_t ); 21 int READ_MEM( addr_t );
22 void WRITE_MEM( addr_t, int data ); 22 void WRITE_MEM( addr_t, int data );
23 23
24 // 0 <= port <= 0xFFFF (apparently upper 8 bits are output by hardware) 24 // 0 <= port <= 0xFFFF (apparently upper 8 bits are output by hardware)
25 void OUT_PORT( int port, int data ); 25 void OUT_PORT( int port, int data );
26 int IN_PORT int port ); 26 int IN_PORT int port );
27 27
28 // Reference to Z80_Cpu object used for emulation 28 // Reference to Z80_Cpu object used for emulation
29 #define CPU cpu 29 #define CPU cpu
30 30
31// The following can be used within macros: 31// The following can be used within macros:
32 32
33 // Current time 33 // Current time
34 time_t TIME(); 34 time_t TIME();
35 35
36 // Allows use of time functions 36 // Allows use of time functions
37 void FLUSH_TIME(); 37 void FLUSH_TIME();
38 38
39 // Must be used before end of macro if FLUSH_TIME() was used earlier 39 // Must be used before end of macro if FLUSH_TIME() was used earlier
40 void CACHE_TIME(); 40 void CACHE_TIME();
41 41
42// Configuration (optional; commented behavior if defined) 42// Configuration (optional; commented behavior if defined)
43 43
44 // Optimizes as if map_mem( 0, 0x10000, FLAT_MEM, FLAT_MEM ) is always in effect 44 // Optimizes as if map_mem( 0, 0x10000, FLAT_MEM, FLAT_MEM ) is always in effect
45 #define FLAT_MEM my_mem_array 45 #define FLAT_MEM my_mem_array
46 46
47 // If RST 7 ($FF) is encountered and PC = IDLE_ADDR, stops execution 47 // If RST 7 ($FF) is encountered and PC = IDLE_ADDR, stops execution
48 #define IDLE_ADDR 0x1234 48 #define IDLE_ADDR 0x1234
49 49
50 // Expanded just before beginning of code, to help debugger 50 // Expanded just before beginning of code, to help debugger
51 #define CPU_BEGIN void my_run_cpu() { 51 #define CPU_BEGIN void my_run_cpu() {
52 52
53#endif 53#endif
54 54
55/* Copyright (C) 2006-2008 Shay Green. This module is free software; you 55/* Copyright (C) 2006-2008 Shay Green. This module is free software; you
56can redistribute it and/or modify it under the terms of the GNU Lesser 56can redistribute it and/or modify it under the terms of the GNU Lesser
57General Public License as published by the Free Software Foundation; either 57General Public License as published by the Free Software Foundation; either
58version 2.1 of the License, or (at your option) any later version. This 58version 2.1 of the License, or (at your option) any later version. This
59module is distributed in the hope that it will be useful, but WITHOUT ANY 59module is distributed in the hope that it will be useful, but WITHOUT ANY
60WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 60WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
61FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 61FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
62details. You should have received a copy of the GNU Lesser General Public 62details. You should have received a copy of the GNU Lesser General Public
63License along with this module; if not, write to the Free Software Foundation, 63License along with this module; if not, write to the Free Software Foundation,
64Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 64Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
65 65
66#ifdef CPU_BEGIN 66#ifdef CPU_BEGIN
67 CPU_BEGIN 67 CPU_BEGIN
68#endif 68#endif
69 69
70#define R cpu->r 70#define R cpu->r
71 71
72// flags, named with hex value for clarity 72// flags, named with hex value for clarity
73int const S80 = 0x80; 73int const S80 = 0x80;
74int const Z40 = 0x40; 74int const Z40 = 0x40;
75int const F20 = 0x20; 75int const F20 = 0x20;
76int const H10 = 0x10; 76int const H10 = 0x10;
77int const F08 = 0x08; 77int const F08 = 0x08;
78int const V04 = 0x04; 78int const V04 = 0x04;
79int const P04 = 0x04; 79int const P04 = 0x04;
80int const N02 = 0x02; 80int const N02 = 0x02;
81int const C01 = 0x01; 81int const C01 = 0x01;
82 82
83#define SZ28P( n ) cpu->szpc [n] 83#define SZ28P( n ) cpu->szpc [n]
84#define SZ28PC( n ) cpu->szpc [n] 84#define SZ28PC( n ) cpu->szpc [n]
85#define SZ28C( n ) (cpu->szpc [n] & ~P04) 85#define SZ28C( n ) (cpu->szpc [n] & ~P04)
86#define SZ28( n ) SZ28C( n ) 86#define SZ28( n ) SZ28C( n )
87 87
88#define SET_R( n ) (void) (R.r = n) 88#define SET_R( n ) (void) (R.r = n)
89#define GET_R() (R.r) 89#define GET_R() (R.r)
90 90
91// Time 91// Time
92#define TIME() (s_time + s.base) 92#define TIME() (s_time + s.base)
93#define FLUSH_TIME() {s.time = s_time;} 93#define FLUSH_TIME() {s.time = s_time;}
94#define CACHE_TIME() {s_time = s.time;} 94#define CACHE_TIME() {s_time = s.time;}
95 95
96// Memory 96// Memory
97#define RW_MEM( addr, rw ) RW_PAGE( addr, rw ) [RW_OFFSET( addr )] 97#define RW_MEM( addr, rw ) RW_PAGE( addr, rw ) [RW_OFFSET( addr )]
98#define READ_CODE( addr ) RW_MEM( addr, read ) 98#define READ_CODE( addr ) RW_MEM( addr, read )
99 99
100#ifdef FLAT_MEM 100#ifdef FLAT_MEM
101 #define RW_PAGE( addr, rw ) FLAT_MEM 101 #define RW_PAGE( addr, rw ) FLAT_MEM
102 #define RW_OFFSET( addr ) (addr) 102 #define RW_OFFSET( addr ) (addr)
103 #define INSTR( off, addr ) READ_CODE( addr ) 103 #define INSTR( off, addr ) READ_CODE( addr )
104#else 104#else
105 #define RW_PAGE( addr, rw ) s.rw [(unsigned) (addr) >> page_bits] 105 #define RW_PAGE( addr, rw ) s.rw [(unsigned) (addr) >> page_bits]
106 #define RW_OFFSET( addr ) Z80_CPU_OFFSET( addr ) 106 #define RW_OFFSET( addr ) Z80_CPU_OFFSET( addr )
107 #define INSTR( off, addr ) instr [off] 107 #define INSTR( off, addr ) instr [off]
108#endif 108#endif
109 109
110#ifndef READ_MEM 110#ifndef READ_MEM
111 #define READ_MEM( addr ) RW_MEM( addr, read ) 111 #define READ_MEM( addr ) RW_MEM( addr, read )
112#endif 112#endif
113 113
114#ifndef WRITE_MEM 114#ifndef WRITE_MEM
115 #define WRITE_MEM( addr, data ) (RW_MEM( addr, write ) = data) 115 #define WRITE_MEM( addr, data ) (RW_MEM( addr, write ) = data)
116#endif 116#endif
117 117
118#define READ_WORD( addr ) GET_LE16( &RW_MEM( addr, read ) ) 118#define READ_WORD( addr ) GET_LE16( &RW_MEM( addr, read ) )
119#define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data ) 119#define WRITE_WORD( addr, data ) SET_LE16( &RW_MEM( addr, write ), data )
120 120
121// Truncation 121// Truncation
122#define BYTE( n ) ((uint8_t ) (n)) /* (unsigned) n & 0xFF */ 122#define BYTE( n ) ((uint8_t ) (n)) /* (unsigned) n & 0xFF */
123#define SBYTE( n ) ((int8_t ) (n)) /* (BYTE( n ) ^ 0x80) - 0x80 */ 123#define SBYTE( n ) ((int8_t ) (n)) /* (BYTE( n ) ^ 0x80) - 0x80 */
124#define WORD( n ) ((uint16_t) (n)) /* (unsigned) n & 0xFFFF */ 124#define WORD( n ) ((uint16_t) (n)) /* (unsigned) n & 0xFFFF */
125 125
126// Misc 126// Misc
127#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e 127#define CASE5( a, b, c, d, e ) case 0x##a:case 0x##b:case 0x##c:case 0x##d:case 0x##e
128#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f 128#define CASE6( a, b, c, d, e, f ) CASE5( a, b, c, d, e ): case 0x##f
129#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g 129#define CASE7( a, b, c, d, e, f, g ) CASE6( a, b, c, d, e, f ): case 0x##g
130#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h 130#define CASE8( a, b, c, d, e, f, g, h ) CASE7( a, b, c, d, e, f, g ): case 0x##h
131 131
132#ifdef BLARGG_BIG_ENDIAN 132#ifdef BLARGG_BIG_ENDIAN
133 #define R8( n, offset ) ((r.r8_ - offset) [n]) 133 #define R8( n, offset ) ((r.r8_ - offset) [n])
134#elif BLARGG_LITTLE_ENDIAN 134#elif BLARGG_LITTLE_ENDIAN
135 #define R8( n, offset ) ((r.r8_ - offset) [(n) ^ 1]) 135 #define R8( n, offset ) ((r.r8_ - offset) [(n) ^ 1])
136#else 136#else
137 #error "Byte order of CPU must be known" 137 #error "Byte order of CPU must be known"
138#endif 138#endif
139 139
140#define R16( n, shift, offset ) (r.r16_ [((unsigned) (n) >> shift) - (offset >> shift)]) 140#define R16( n, shift, offset ) (r.r16_ [((unsigned) (n) >> shift) - (offset >> shift)])
141 141
142#define EX( x, y ) \ 142#define EX( x, y ) \
143 {\ 143 {\
144 int temp = x;\ 144 int temp = x;\
145 x = y;\ 145 x = y;\
146 y = temp;\ 146 y = temp;\
147 } 147 }
148 148
149#define EXX( name ) \ 149#define EXX( name ) \
150 EX( R.alt.name, r.name ) 150 EX( R.alt.name, r.name )
151 151
152bool warning = false; 152bool warning = false;
153{ 153{
154 struct cpu_state_t s; 154 struct cpu_state_t s;
155 #ifdef FLAT_MEM 155 #ifdef FLAT_MEM
156 s.base = cpu->cpu_state_.base; 156 s.base = cpu->cpu_state_.base;
157 #else 157 #else
158 s = cpu->cpu_state_; 158 s = cpu->cpu_state_;
159 #endif 159 #endif
160 cpu->cpu_state = &s; 160 cpu->cpu_state = &s;
161 161
162 162
163 union r_t { 163 union r_t {
164 struct regs_t b; 164 struct regs_t b;
165 struct pairs_t w; 165 struct pairs_t w;
166 byte r8_ [8]; // indexed 166 byte r8_ [8]; // indexed
167 uint16_t r16_ [4]; 167 uint16_t r16_ [4];
168 } r; 168 } r;
169 r.b = R.b; 169 r.b = R.b;
170 170
171 cpu_time_t s_time = cpu->cpu_state_.time; 171 cpu_time_t s_time = cpu->cpu_state_.time;
172 int pc = R.pc; 172 int pc = R.pc;
173 int sp = R.sp; 173 int sp = R.sp;
174 int ix = R.ix; // TODO: keep in memory for direct access? 174 int ix = R.ix; // TODO: keep in memory for direct access?
175 int iy = R.iy; 175 int iy = R.iy;
176 int flags = R.b.flags; 176 int flags = R.b.flags;
177 177
178 //goto loop; // confuses optimizer 178 //goto loop; // confuses optimizer
179 s_time += 7; 179 s_time += 7;
180 pc -= 2; 180 pc -= 2;
181 181
182call_not_taken: 182call_not_taken:
183 s_time -= 7; 183 s_time -= 7;
184jp_not_taken: 184jp_not_taken:
185 pc += 2; 185 pc += 2;
186loop: 186loop:
187 187
188 check( (unsigned) pc < 0x10000 + 1 ); // +1 so emulator can catch wrap-around 188 check( (unsigned) pc < 0x10000 + 1 ); // +1 so emulator can catch wrap-around
189 check( (unsigned) sp < 0x10000 ); 189 check( (unsigned) sp < 0x10000 );
190 check( (unsigned) flags < 0x100 ); 190 check( (unsigned) flags < 0x100 );
191 check( (unsigned) ix < 0x10000 ); 191 check( (unsigned) ix < 0x10000 );
192 check( (unsigned) iy < 0x10000 ); 192 check( (unsigned) iy < 0x10000 );
193 193
194 byte const* instr = RW_PAGE( pc, read ); 194 byte const* instr = RW_PAGE( pc, read );
195 195
196 int opcode; 196 int opcode;
197 197
198 if ( RW_OFFSET( ~0 ) == ~0 ) 198 if ( RW_OFFSET( ~0 ) == ~0 )
199 { 199 {
200 opcode = instr [RW_OFFSET( pc )]; 200 opcode = instr [RW_OFFSET( pc )];
201 pc++; 201 pc++;
202 instr += RW_OFFSET( pc ); 202 instr += RW_OFFSET( pc );
203 } 203 }
204 else 204 else
205 { 205 {
206 instr += RW_OFFSET( pc ); 206 instr += RW_OFFSET( pc );
207 opcode = *instr++; 207 opcode = *instr++;
208 pc++; 208 pc++;
209 } 209 }
210 210
211 static byte const clock_table [256 * 2] = { 211 static byte const clock_table [256 * 2] = {
212 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 212 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
213 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0 213 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 0
214 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1 214 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, // 1
215 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, // 2 215 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, // 2
216 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4, // 3 216 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4, // 3
217 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4 217 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 4
218 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5 218 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 5
219 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6 219 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 6
220 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7 220 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 7
221 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8 221 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 8
222 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9 222 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 9
223 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A 223 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // A
224 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B 224 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // B
225 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C 225 11,10,10,10,17,11, 7,11,11,10,10, 8,17,17, 7,11, // C
226 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D 226 11,10,10,11,17,11, 7,11,11, 4,10,11,17, 8, 7,11, // D
227 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E 227 11,10,10,19,17,11, 7,11,11, 4,10, 4,17, 8, 7,11, // E
228 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F 228 11,10,10, 4,17,11, 7,11,11, 6,10, 4,17, 8, 7,11, // F
229 229
230 // high four bits are $ED time - 8, low four bits are $DD/$FD time - 8 230 // high four bits are $ED time - 8, low four bits are $DD/$FD time - 8
231 //0 1 2 3 4 5 6 7 8 9 A B C D E F 231 //0 1 2 3 4 5 6 7 8 9 A B C D E F
232 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, 232 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
233 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, 233 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
234 0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00, 234 0x00,0x06,0x0C,0x02,0x00,0x00,0x03,0x00,0x00,0x07,0x0C,0x02,0x00,0x00,0x03,0x00,
235 0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00, 235 0x00,0x00,0x00,0x00,0x0F,0x0F,0x0B,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,
236 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10, 236 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
237 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10, 237 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x10,
238 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0, 238 0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0xA0,
239 0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00, 239 0x4B,0x4B,0x7B,0xCB,0x0B,0x6B,0x00,0x0B,0x40,0x40,0x70,0xC0,0x00,0x60,0x0B,0x00,
240 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00, 240 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
241 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00, 241 0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x00,
242 0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00, 242 0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0B,0x00,
243 0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00, 243 0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,0xD0,0xD0,0xD0,0xD0,0x00,0x00,0x0B,0x00,
244 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00, 244 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,
245 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 245 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
246 0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 246 0x00,0x06,0x00,0x0F,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
247 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00, 247 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
248 }; 248 };
249 249
250 if ( s_time >= 0 ) 250 if ( s_time >= 0 )
251 goto out_of_time; 251 goto out_of_time;
252 s_time += clock_table [opcode]; 252 s_time += clock_table [opcode];
253 253
254 #ifdef Z80_CPU_LOG_H 254 #ifdef Z80_CPU_LOG_H
255 //log_opcode( opcode, READ_CODE( pc ) ); 255 //log_opcode( opcode, READ_CODE( pc ) );
256 z80_cpu_log( "log.txt", pc - 1, opcode, READ_CODE( pc ), 256 z80_cpu_log( "log.txt", pc - 1, opcode, READ_CODE( pc ),
257 READ_CODE( pc + 1 ), READ_CODE( pc + 2 ) ); 257 READ_CODE( pc + 1 ), READ_CODE( pc + 2 ) );
258 z80_log_regs( r.b.a, r.w.bc, r.w.de, r.w.hl, sp, ix, iy ); 258 z80_log_regs( r.b.a, r.w.bc, r.w.de, r.w.hl, sp, ix, iy );
259 #endif 259 #endif
260 260
261#define GET_ADDR() GET_LE16( &INSTR( 0, pc ) ) 261#define GET_ADDR() GET_LE16( &INSTR( 0, pc ) )
262 262
263 int data; 263 int data;
264 data = INSTR( 0, pc ); 264 data = INSTR( 0, pc );
265 265
266 switch ( opcode ) 266 switch ( opcode )
267 { 267 {
268// Common 268// Common
269 269
270 case 0x00: // NOP 270 case 0x00: // NOP
271 CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc. 271 CASE7( 40, 49, 52, 5B, 64, 6D, 7F ): // LD B,B etc.
272 goto loop; 272 goto loop;
273 273
274 case 0x08:{// EX AF,AF' 274 case 0x08:{// EX AF,AF'
275 EXX( b.a ); 275 EXX( b.a );
276 EX( R.alt.b.flags, flags ); 276 EX( R.alt.b.flags, flags );
277 goto loop; 277 goto loop;
278 } 278 }
279 279
280 case 0xD3: // OUT (imm),A 280 case 0xD3: // OUT (imm),A
281 pc++; 281 pc++;
282 OUT_PORT( (data + r.b.a * 0x100), r.b.a ); 282 OUT_PORT( (data + r.b.a * 0x100), r.b.a );
283 goto loop; 283 goto loop;
284 284
285 case 0x2E: // LD L,imm 285 case 0x2E: // LD L,imm
286 pc++; 286 pc++;
287 r.b.l = data; 287 r.b.l = data;
288 goto loop; 288 goto loop;
289 289
290 case 0x3E: // LD A,imm 290 case 0x3E: // LD A,imm
291 pc++; 291 pc++;
292 r.b.a = data; 292 r.b.a = data;
293 goto loop; 293 goto loop;
294 294
295 case 0x3A:{// LD A,(addr) 295 case 0x3A:{// LD A,(addr)
296 int addr = GET_ADDR(); 296 int addr = GET_ADDR();
297 pc += 2; 297 pc += 2;
298 r.b.a = READ_MEM( addr ); 298 r.b.a = READ_MEM( addr );
299 goto loop; 299 goto loop;
300 } 300 }
301 301
302// Conditional 302// Conditional
303 303
304#define ZERO (flags & Z40) 304#define ZERO (flags & Z40)
305#define CARRY (flags & C01) 305#define CARRY (flags & C01)
306#define EVEN (flags & P04) 306#define EVEN (flags & P04)
307#define MINUS (flags & S80) 307#define MINUS (flags & S80)
308 308
309// JR 309// JR
310// TODO: more efficient way to handle negative branch that wraps PC around 310// TODO: more efficient way to handle negative branch that wraps PC around
311#define JR_( cond, clocks ) {\ 311#define JR_( cond, clocks ) {\
312 pc++;\ 312 pc++;\
313 if ( !(cond) )\ 313 if ( !(cond) )\
314 goto loop;\ 314 goto loop;\
315 int offset = SBYTE( data );\ 315 int offset = SBYTE( data );\
316 pc = WORD( pc + offset );\ 316 pc = WORD( pc + offset );\
317 s_time += clocks;\ 317 s_time += clocks;\
318 goto loop;\ 318 goto loop;\
319} 319}
320 320
321#define JR( cond ) JR_( cond, 5 ) 321#define JR( cond ) JR_( cond, 5 )
322 322
323 case 0x20: JR( !ZERO ) // JR NZ,disp 323 case 0x20: JR( !ZERO ) // JR NZ,disp
324 case 0x28: JR( ZERO ) // JR Z,disp 324 case 0x28: JR( ZERO ) // JR Z,disp
325 case 0x30: JR( !CARRY ) // JR NC,disp 325 case 0x30: JR( !CARRY ) // JR NC,disp
326 case 0x38: JR( CARRY ) // JR C,disp 326 case 0x38: JR( CARRY ) // JR C,disp
327 case 0x18: JR_( true,0) // JR disp 327 case 0x18: JR_( true,0) // JR disp
328 328
329 case 0x10:{// DJNZ disp 329 case 0x10:{// DJNZ disp
330 int temp = r.b.b - 1; 330 int temp = r.b.b - 1;
331 r.b.b = temp; 331 r.b.b = temp;
332 JR( temp ) 332 JR( temp )
333 } 333 }
334 334
335// JP 335// JP
336#define JP( cond ) \ 336#define JP( cond ) \
337 if ( !(cond) )\ 337 if ( !(cond) )\
338 goto jp_not_taken;\ 338 goto jp_not_taken;\
339 pc = GET_ADDR();\ 339 pc = GET_ADDR();\
340 goto loop; 340 goto loop;
341 341
342 case 0xC2: JP( !ZERO ) // JP NZ,addr 342 case 0xC2: JP( !ZERO ) // JP NZ,addr
343 case 0xCA: JP( ZERO ) // JP Z,addr 343 case 0xCA: JP( ZERO ) // JP Z,addr
344 case 0xD2: JP( !CARRY ) // JP NC,addr 344 case 0xD2: JP( !CARRY ) // JP NC,addr
345 case 0xDA: JP( CARRY ) // JP C,addr 345 case 0xDA: JP( CARRY ) // JP C,addr
346 case 0xE2: JP( !EVEN ) // JP PO,addr 346 case 0xE2: JP( !EVEN ) // JP PO,addr
347 case 0xEA: JP( EVEN ) // JP PE,addr 347 case 0xEA: JP( EVEN ) // JP PE,addr
348 case 0xF2: JP( !MINUS ) // JP P,addr 348 case 0xF2: JP( !MINUS ) // JP P,addr
349 case 0xFA: JP( MINUS ) // JP M,addr 349 case 0xFA: JP( MINUS ) // JP M,addr
350 350
351 case 0xC3: // JP addr 351 case 0xC3: // JP addr
352 pc = GET_ADDR(); 352 pc = GET_ADDR();
353 goto loop; 353 goto loop;
354 354
355 case 0xE9: // JP HL 355 case 0xE9: // JP HL
356 pc = r.w.hl; 356 pc = r.w.hl;
357 goto loop; 357 goto loop;
358 358
359// RET 359// RET
360#define RET( cond ) \ 360#define RET( cond ) \
361 if ( cond )\ 361 if ( cond )\
362 goto ret_taken;\ 362 goto ret_taken;\
363 s_time -= 6;\ 363 s_time -= 6;\
364 goto loop; 364 goto loop;
365 365
366 case 0xC0: RET( !ZERO ) // RET NZ 366 case 0xC0: RET( !ZERO ) // RET NZ
367 case 0xC8: RET( ZERO ) // RET Z 367 case 0xC8: RET( ZERO ) // RET Z
368 case 0xD0: RET( !CARRY ) // RET NC 368 case 0xD0: RET( !CARRY ) // RET NC
369 case 0xD8: RET( CARRY ) // RET C 369 case 0xD8: RET( CARRY ) // RET C
370 case 0xE0: RET( !EVEN ) // RET PO 370 case 0xE0: RET( !EVEN ) // RET PO
371 case 0xE8: RET( EVEN ) // RET PE 371 case 0xE8: RET( EVEN ) // RET PE
372 case 0xF0: RET( !MINUS ) // RET P 372 case 0xF0: RET( !MINUS ) // RET P
373 case 0xF8: RET( MINUS ) // RET M 373 case 0xF8: RET( MINUS ) // RET M
374 374
375 case 0xC9: // RET 375 case 0xC9: // RET
376 ret_taken: 376 ret_taken:
377 pc = READ_WORD( sp ); 377 pc = READ_WORD( sp );
378 sp = WORD( sp + 2 ); 378 sp = WORD( sp + 2 );
379 goto loop; 379 goto loop;
380 380
381// CALL 381// CALL
382#define CALL( cond ) \ 382#define CALL( cond ) \
383 if ( cond )\ 383 if ( cond )\
384 goto call_taken;\ 384 goto call_taken;\
385 goto call_not_taken; 385 goto call_not_taken;
386 386
387 case 0xC4: CALL( !ZERO ) // CALL NZ,addr 387 case 0xC4: CALL( !ZERO ) // CALL NZ,addr
388 case 0xCC: CALL( ZERO ) // CALL Z,addr 388 case 0xCC: CALL( ZERO ) // CALL Z,addr
389 case 0xD4: CALL( !CARRY ) // CALL NC,addr 389 case 0xD4: CALL( !CARRY ) // CALL NC,addr
390 case 0xDC: CALL( CARRY ) // CALL C,addr 390 case 0xDC: CALL( CARRY ) // CALL C,addr
391 case 0xE4: CALL( !EVEN ) // CALL PO,addr 391 case 0xE4: CALL( !EVEN ) // CALL PO,addr
392 case 0xEC: CALL( EVEN ) // CALL PE,addr 392 case 0xEC: CALL( EVEN ) // CALL PE,addr
393 case 0xF4: CALL( !MINUS ) // CALL P,addr 393 case 0xF4: CALL( !MINUS ) // CALL P,addr
394 case 0xFC: CALL( MINUS ) // CALL M,addr 394 case 0xFC: CALL( MINUS ) // CALL M,addr
395 395
396 case 0xCD:{// CALL addr 396 case 0xCD:{// CALL addr
397 call_taken: { 397 call_taken: {
398 int addr = pc + 2; 398 int addr = pc + 2;
399 pc = GET_ADDR(); 399 pc = GET_ADDR();
400 sp = WORD( sp - 2 ); 400 sp = WORD( sp - 2 );
401 WRITE_WORD( sp, addr ); 401 WRITE_WORD( sp, addr );
402 goto loop; 402 goto loop;
403 } 403 }
404 } 404 }
405 405
406 case 0xFF: // RST 406 case 0xFF: // RST
407 #ifdef IDLE_ADDR 407 #ifdef IDLE_ADDR
408 if ( pc == IDLE_ADDR + 1 ) 408 if ( pc == IDLE_ADDR + 1 )
409 goto hit_idle_addr; 409 goto hit_idle_addr;
410 #else 410 #else
411 if ( pc > 0x10000 ) 411 if ( pc > 0x10000 )
412 { 412 {
413 pc = WORD( pc - 1 ); 413 pc = WORD( pc - 1 );
414 s_time -= 11; 414 s_time -= 11;
415 goto loop; 415 goto loop;
416 } 416 }
417 #endif 417 #endif
418 CASE7( C7, CF, D7, DF, E7, EF, F7 ): 418 CASE7( C7, CF, D7, DF, E7, EF, F7 ):
419 data = pc; 419 data = pc;
420 pc = opcode & 0x38; 420 pc = opcode & 0x38;
421 #ifdef RST_BASE 421 #ifdef RST_BASE
422 pc += RST_BASE; 422 pc += RST_BASE;
423 #endif 423 #endif
424 goto push_data; 424 goto push_data;
425 425
426// PUSH/POP 426// PUSH/POP
427 case 0xF5: // PUSH AF 427 case 0xF5: // PUSH AF
428 data = r.b.a * 0x100u + flags; 428 data = r.b.a * 0x100u + flags;
429 goto push_data; 429 goto push_data;
430 430
431 case 0xC5: // PUSH BC 431 case 0xC5: // PUSH BC
432 case 0xD5: // PUSH DE 432 case 0xD5: // PUSH DE
433 case 0xE5: // PUSH HL 433 case 0xE5: // PUSH HL
434 data = R16( opcode, 4, 0xC5 ); 434 data = R16( opcode, 4, 0xC5 );
435 push_data: 435 push_data:
436 sp = WORD( sp - 2 ); 436 sp = WORD( sp - 2 );
437 WRITE_WORD( sp, data ); 437 WRITE_WORD( sp, data );
438 goto loop; 438 goto loop;
439 439
440 case 0xF1: // POP AF 440 case 0xF1: // POP AF
441 flags = READ_MEM( sp ); 441 flags = READ_MEM( sp );
442 r.b.a = READ_MEM( (sp + 1) ); 442 r.b.a = READ_MEM( (sp + 1) );
443 sp = WORD( sp + 2 ); 443 sp = WORD( sp + 2 );
444 goto loop; 444 goto loop;
445 445
446 case 0xC1: // POP BC 446 case 0xC1: // POP BC
447 case 0xD1: // POP DE 447 case 0xD1: // POP DE
448 case 0xE1: // POP HL 448 case 0xE1: // POP HL
449 R16( opcode, 4, 0xC1 ) = READ_WORD( sp ); 449 R16( opcode, 4, 0xC1 ) = READ_WORD( sp );
450 sp = WORD( sp + 2 ); 450 sp = WORD( sp + 2 );
451 goto loop; 451 goto loop;
452 452
453// ADC/ADD/SBC/SUB 453// ADC/ADD/SBC/SUB
454 case 0x96: // SUB (HL) 454 case 0x96: // SUB (HL)
455 case 0x86: // ADD (HL) 455 case 0x86: // ADD (HL)
456 flags &= ~C01; 456 flags &= ~C01;
457 case 0x9E: // SBC (HL) 457 case 0x9E: // SBC (HL)
458 case 0x8E: // ADC (HL) 458 case 0x8E: // ADC (HL)
459 data = READ_MEM( r.w.hl ); 459 data = READ_MEM( r.w.hl );
460 goto adc_data; 460 goto adc_data;
461 461
462 case 0xD6: // SUB A,imm 462 case 0xD6: // SUB A,imm
463 case 0xC6: // ADD imm 463 case 0xC6: // ADD imm
464 flags &= ~C01; 464 flags &= ~C01;
465 case 0xDE: // SBC A,imm 465 case 0xDE: // SBC A,imm
466 case 0xCE: // ADC imm 466 case 0xCE: // ADC imm
467 pc++; 467 pc++;
468 goto adc_data; 468 goto adc_data;
469 469
470 CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r 470 CASE7( 90, 91, 92, 93, 94, 95, 97 ): // SUB r
471 CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r 471 CASE7( 80, 81, 82, 83, 84, 85, 87 ): // ADD r
472 flags &= ~C01; 472 flags &= ~C01;
473 CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r 473 CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // SBC r
474 CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r 474 CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // ADC r
475 data = R8( opcode & 7, 0 ); 475 data = R8( opcode & 7, 0 );
476 adc_data: { 476 adc_data: {
477 int result = data + (flags & C01); 477 int result = data + (flags & C01);
478 data ^= r.b.a; 478 data ^= r.b.a;
479 flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes 479 flags = opcode >> 3 & N02; // bit 4 is set in subtract opcodes
480 if ( flags ) 480 if ( flags )
481 result = -result; 481 result = -result;
482 result += r.b.a; 482 result += r.b.a;
483 data ^= result; 483 data ^= result;
484 flags +=(data & H10) + 484 flags +=(data & H10) +
485 ((data + 0x80) >> 6 & V04) + 485 ((data + 0x80) >> 6 & V04) +
486 SZ28C( result & 0x1FF ); 486 SZ28C( result & 0x1FF );
487 r.b.a = result; 487 r.b.a = result;
488 goto loop; 488 goto loop;
489 } 489 }
490 490
491// CP 491// CP
492 case 0xBE: // CP (HL) 492 case 0xBE: // CP (HL)
493 data = READ_MEM( r.w.hl ); 493 data = READ_MEM( r.w.hl );
494 goto cp_data; 494 goto cp_data;
495 495
496 case 0xFE: // CP imm 496 case 0xFE: // CP imm
497 pc++; 497 pc++;
498 goto cp_data; 498 goto cp_data;
499 499
500 CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r 500 CASE7( B8, B9, BA, BB, BC, BD, BF ): // CP r
501 data = R8( opcode, 0xB8 ); 501 data = R8( opcode, 0xB8 );
502 cp_data: { 502 cp_data: {
503 int result = r.b.a - data; 503 int result = r.b.a - data;
504 flags = N02 + (data & (F20 | F08)) + (result >> 8 & C01); 504 flags = N02 + (data & (F20 | F08)) + (result >> 8 & C01);
505 data ^= r.b.a; 505 data ^= r.b.a;
506 flags +=(((result ^ r.b.a) & data) >> 5 & V04) + 506 flags +=(((result ^ r.b.a) & data) >> 5 & V04) +
507 (((data & H10) ^ result) & (S80 | H10)); 507 (((data & H10) ^ result) & (S80 | H10));
508 if ( BYTE( result ) ) 508 if ( BYTE( result ) )
509 goto loop; 509 goto loop;
510 flags += Z40; 510 flags += Z40;
511 goto loop; 511 goto loop;
512 } 512 }
513 513
514// ADD HL,r.w 514// ADD HL,r.w
515 515
516 case 0x39: // ADD HL,SP 516 case 0x39: // ADD HL,SP
517 data = sp; 517 data = sp;
518 goto add_hl_data; 518 goto add_hl_data;
519 519
520 case 0x09: // ADD HL,BC 520 case 0x09: // ADD HL,BC
521 case 0x19: // ADD HL,DE 521 case 0x19: // ADD HL,DE
522 case 0x29: // ADD HL,HL 522 case 0x29: // ADD HL,HL
523 data = R16( opcode, 4, 0x09 ); 523 data = R16( opcode, 4, 0x09 );
524 add_hl_data: { 524 add_hl_data: {
525 int sum = r.w.hl + data; 525 int sum = r.w.hl + data;
526 data ^= r.w.hl; 526 data ^= r.w.hl;
527 r.w.hl = sum; 527 r.w.hl = sum;
528 flags = (flags & (S80 | Z40 | V04)) + 528 flags = (flags & (S80 | Z40 | V04)) +
529 (sum >> 16) + 529 (sum >> 16) +
530 (sum >> 8 & (F20 | F08)) + 530 (sum >> 8 & (F20 | F08)) +
531 ((data ^ sum) >> 8 & H10); 531 ((data ^ sum) >> 8 & H10);
532 goto loop; 532 goto loop;
533 } 533 }
534 534
535 case 0x27:{// DAA 535 case 0x27:{// DAA
536 int a = r.b.a; 536 int a = r.b.a;
537 if ( a > 0x99 ) 537 if ( a > 0x99 )
538 flags |= C01; 538 flags |= C01;
539 539
540 int adjust = 0x60 * (flags & C01); 540 int adjust = 0x60 * (flags & C01);
541 541
542 if ( flags & H10 || (a & 0x0F) > 9 ) 542 if ( flags & H10 || (a & 0x0F) > 9 )
543 adjust += 0x06; 543 adjust += 0x06;
544 544
545 if ( flags & N02 ) 545 if ( flags & N02 )
546 adjust = -adjust; 546 adjust = -adjust;
547 a += adjust; 547 a += adjust;
548 548
549 flags = (flags & (C01 | N02)) + 549 flags = (flags & (C01 | N02)) +
550 ((r.b.a ^ a) & H10) + 550 ((r.b.a ^ a) & H10) +
551 SZ28P( BYTE( a ) ); 551 SZ28P( BYTE( a ) );
552 r.b.a = a; 552 r.b.a = a;
553 goto loop; 553 goto loop;
554 } 554 }
555 555
556// INC/DEC 556// INC/DEC
557 case 0x34: // INC (HL) 557 case 0x34: // INC (HL)
558 data = READ_MEM( r.w.hl ) + 1; 558 data = READ_MEM( r.w.hl ) + 1;
559 WRITE_MEM( r.w.hl, data ); 559 WRITE_MEM( r.w.hl, data );
560 goto inc_set_flags; 560 goto inc_set_flags;
561 561
562 CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r 562 CASE7( 04, 0C, 14, 1C, 24, 2C, 3C ): // INC r
563 data = ++R8( opcode >> 3, 0 ); 563 data = ++R8( opcode >> 3, 0 );
564 inc_set_flags: 564 inc_set_flags:
565 flags = (flags & C01) + 565 flags = (flags & C01) +
566 (((data & 0x0F) - 1) & H10) + 566 (((data & 0x0F) - 1) & H10) +
567 SZ28( BYTE( data ) ); 567 SZ28( BYTE( data ) );
568 if ( data != 0x80 ) 568 if ( data != 0x80 )
569 goto loop; 569 goto loop;
570 flags += V04; 570 flags += V04;
571 goto loop; 571 goto loop;
572 572
573 case 0x35: // DEC (HL) 573 case 0x35: // DEC (HL)
574 data = READ_MEM( r.w.hl ) - 1; 574 data = READ_MEM( r.w.hl ) - 1;
575 WRITE_MEM( r.w.hl, data ); 575 WRITE_MEM( r.w.hl, data );
576 goto dec_set_flags; 576 goto dec_set_flags;
577 577
578 CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r 578 CASE7( 05, 0D, 15, 1D, 25, 2D, 3D ): // DEC r
579 data = --R8( opcode >> 3, 0 ); 579 data = --R8( opcode >> 3, 0 );
580 dec_set_flags: 580 dec_set_flags:
581 flags = (flags & C01) + N02 + 581 flags = (flags & C01) + N02 +
582 (((data & 0x0F) + 1) & H10) + 582 (((data & 0x0F) + 1) & H10) +
583 SZ28( BYTE( data ) ); 583 SZ28( BYTE( data ) );
584 if ( data != 0x7F ) 584 if ( data != 0x7F )
585 goto loop; 585 goto loop;
586 flags += V04; 586 flags += V04;
587 goto loop; 587 goto loop;
588 588
589 case 0x03: // INC BC 589 case 0x03: // INC BC
590 case 0x13: // INC DE 590 case 0x13: // INC DE
591 case 0x23: // INC HL 591 case 0x23: // INC HL
592 R16( opcode, 4, 0x03 )++; 592 R16( opcode, 4, 0x03 )++;
593 goto loop; 593 goto loop;
594 594
595 case 0x33: // INC SP 595 case 0x33: // INC SP
596 sp = WORD( sp + 1 ); 596 sp = WORD( sp + 1 );
597 goto loop; 597 goto loop;
598 598
599 case 0x0B: // DEC BC 599 case 0x0B: // DEC BC
600 case 0x1B: // DEC DE 600 case 0x1B: // DEC DE
601 case 0x2B: // DEC HL 601 case 0x2B: // DEC HL
602 R16( opcode, 4, 0x0B )--; 602 R16( opcode, 4, 0x0B )--;
603 goto loop; 603 goto loop;
604 604
605 case 0x3B: // DEC SP 605 case 0x3B: // DEC SP
606 sp = WORD( sp - 1 ); 606 sp = WORD( sp - 1 );
607 goto loop; 607 goto loop;
608 608
609// AND 609// AND
610 case 0xA6: // AND (HL) 610 case 0xA6: // AND (HL)
611 data = READ_MEM( r.w.hl ); 611 data = READ_MEM( r.w.hl );
612 goto and_data; 612 goto and_data;
613 613
614 case 0xE6: // AND imm 614 case 0xE6: // AND imm
615 pc++; 615 pc++;
616 goto and_data; 616 goto and_data;
617 617
618 CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r 618 CASE7( A0, A1, A2, A3, A4, A5, A7 ): // AND r
619 data = R8( opcode, 0xA0 ); 619 data = R8( opcode, 0xA0 );
620 and_data: 620 and_data:
621 r.b.a &= data; 621 r.b.a &= data;
622 flags = SZ28P( r.b.a ) + H10; 622 flags = SZ28P( r.b.a ) + H10;
623 goto loop; 623 goto loop;
624 624
625// OR 625// OR
626 case 0xB6: // OR (HL) 626 case 0xB6: // OR (HL)
627 data = READ_MEM( r.w.hl ); 627 data = READ_MEM( r.w.hl );
628 goto or_data; 628 goto or_data;
629 629
630 case 0xF6: // OR imm 630 case 0xF6: // OR imm
631 pc++; 631 pc++;
632 goto or_data; 632 goto or_data;
633 633
634 CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r 634 CASE7( B0, B1, B2, B3, B4, B5, B7 ): // OR r
635 data = R8( opcode, 0xB0 ); 635 data = R8( opcode, 0xB0 );
636 or_data: 636 or_data:
637 r.b.a |= data; 637 r.b.a |= data;
638 flags = SZ28P( r.b.a ); 638 flags = SZ28P( r.b.a );
639 goto loop; 639 goto loop;
640 640
641// XOR 641// XOR
642 case 0xAE: // XOR (HL) 642 case 0xAE: // XOR (HL)
643 data = READ_MEM( r.w.hl ); 643 data = READ_MEM( r.w.hl );
644 goto xor_data; 644 goto xor_data;
645 645
646 case 0xEE: // XOR imm 646 case 0xEE: // XOR imm
647 pc++; 647 pc++;
648 goto xor_data; 648 goto xor_data;
649 649
650 CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r 650 CASE7( A8, A9, AA, AB, AC, AD, AF ): // XOR r
651 data = R8( opcode, 0xA8 ); 651 data = R8( opcode, 0xA8 );
652 xor_data: 652 xor_data:
653 r.b.a ^= data; 653 r.b.a ^= data;
654 flags = SZ28P( r.b.a ); 654 flags = SZ28P( r.b.a );
655 goto loop; 655 goto loop;
656 656
657// LD 657// LD
658 CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r 658 CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (HL),r
659 WRITE_MEM( r.w.hl, R8( opcode, 0x70 ) ); 659 WRITE_MEM( r.w.hl, R8( opcode, 0x70 ) );
660 goto loop; 660 goto loop;
661 661
662 CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r 662 CASE6( 41, 42, 43, 44, 45, 47 ): // LD B,r
663 CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r 663 CASE6( 48, 4A, 4B, 4C, 4D, 4F ): // LD C,r
664 CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r 664 CASE6( 50, 51, 53, 54, 55, 57 ): // LD D,r
665 CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r 665 CASE6( 58, 59, 5A, 5C, 5D, 5F ): // LD E,r
666 CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r 666 CASE6( 60, 61, 62, 63, 65, 67 ): // LD H,r
667 CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r 667 CASE6( 68, 69, 6A, 6B, 6C, 6F ): // LD L,r
668 CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r 668 CASE6( 78, 79, 7A, 7B, 7C, 7D ): // LD A,r
669 R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 ); 669 R8( opcode >> 3 & 7, 0 ) = R8( opcode & 7, 0 );
670 goto loop; 670 goto loop;
671 671
672 CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm 672 CASE5( 06, 0E, 16, 1E, 26 ): // LD r,imm
673 R8( opcode >> 3, 0 ) = data; 673 R8( opcode >> 3, 0 ) = data;
674 pc++; 674 pc++;
675 goto loop; 675 goto loop;
676 676
677 case 0x36: // LD (HL),imm 677 case 0x36: // LD (HL),imm
678 pc++; 678 pc++;
679 WRITE_MEM( r.w.hl, data ); 679 WRITE_MEM( r.w.hl, data );
680 goto loop; 680 goto loop;
681 681
682 CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL) 682 CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(HL)
683 R8( opcode >> 3, 8 ) = READ_MEM( r.w.hl ); 683 R8( opcode >> 3, 8 ) = READ_MEM( r.w.hl );
684 goto loop; 684 goto loop;
685 685
686 case 0x01: // LD r.w,imm 686 case 0x01: // LD r.w,imm
687 case 0x11: 687 case 0x11:
688 case 0x21: 688 case 0x21:
689 R16( opcode, 4, 0x01 ) = GET_ADDR(); 689 R16( opcode, 4, 0x01 ) = GET_ADDR();
690 pc += 2; 690 pc += 2;
691 goto loop; 691 goto loop;
692 692
693 case 0x31: // LD sp,imm 693 case 0x31: // LD sp,imm
694 sp = GET_ADDR(); 694 sp = GET_ADDR();
695 pc += 2; 695 pc += 2;
696 goto loop; 696 goto loop;
697 697
698 case 0x2A:{// LD HL,(addr) 698 case 0x2A:{// LD HL,(addr)
699 int addr = GET_ADDR(); 699 int addr = GET_ADDR();
700 pc += 2; 700 pc += 2;
701 r.w.hl = READ_WORD( addr ); 701 r.w.hl = READ_WORD( addr );
702 goto loop; 702 goto loop;
703 } 703 }
704 704
705 case 0x32:{// LD (addr),A 705 case 0x32:{// LD (addr),A
706 int addr = GET_ADDR(); 706 int addr = GET_ADDR();
707 pc += 2; 707 pc += 2;
708 WRITE_MEM( addr, r.b.a ); 708 WRITE_MEM( addr, r.b.a );
709 goto loop; 709 goto loop;
710 } 710 }
711 711
712 case 0x22:{// LD (addr),HL 712 case 0x22:{// LD (addr),HL
713 int addr = GET_ADDR(); 713 int addr = GET_ADDR();
714 pc += 2; 714 pc += 2;
715 WRITE_WORD( addr, r.w.hl ); 715 WRITE_WORD( addr, r.w.hl );
716 goto loop; 716 goto loop;
717 } 717 }
718 718
719 case 0x02: // LD (BC),A 719 case 0x02: // LD (BC),A
720 case 0x12: // LD (DE),A 720 case 0x12: // LD (DE),A
721 WRITE_MEM( R16( opcode, 4, 0x02 ), r.b.a ); 721 WRITE_MEM( R16( opcode, 4, 0x02 ), r.b.a );
722 goto loop; 722 goto loop;
723 723
724 case 0x0A: // LD A,(BC) 724 case 0x0A: // LD A,(BC)
725 case 0x1A: // LD A,(DE) 725 case 0x1A: // LD A,(DE)
726 r.b.a = READ_MEM( R16( opcode, 4, 0x0A ) ); 726 r.b.a = READ_MEM( R16( opcode, 4, 0x0A ) );
727 goto loop; 727 goto loop;
728 728
729 case 0xF9: // LD SP,HL 729 case 0xF9: // LD SP,HL
730 sp = r.w.hl; 730 sp = r.w.hl;
731 goto loop; 731 goto loop;
732 732
733// Rotate 733// Rotate
734 734
735 case 0x07:{// RLCA 735 case 0x07:{// RLCA
736 int temp = r.b.a; 736 int temp = r.b.a;
737 temp = (temp << 1) + (temp >> 7); 737 temp = (temp << 1) + (temp >> 7);
738 flags = (flags & (S80 | Z40 | P04)) + 738 flags = (flags & (S80 | Z40 | P04)) +
739 (temp & (F20 | F08 | C01)); 739 (temp & (F20 | F08 | C01));
740 r.b.a = temp; 740 r.b.a = temp;
741 goto loop; 741 goto loop;
742 } 742 }
743 743
744 case 0x0F:{// RRCA 744 case 0x0F:{// RRCA
745 int temp = r.b.a; 745 int temp = r.b.a;
746 flags = (flags & (S80 | Z40 | P04)) + 746 flags = (flags & (S80 | Z40 | P04)) +
747 (temp & C01); 747 (temp & C01);
748 temp = (temp << 7) + (temp >> 1); 748 temp = (temp << 7) + (temp >> 1);
749 flags += temp & (F20 | F08); 749 flags += temp & (F20 | F08);
750 r.b.a = temp; 750 r.b.a = temp;
751 goto loop; 751 goto loop;
752 } 752 }
753 753
754 case 0x17:{// RLA 754 case 0x17:{// RLA
755 int temp = (r.b.a << 1) + (flags & C01); 755 int temp = (r.b.a << 1) + (flags & C01);
756 flags = (flags & (S80 | Z40 | P04)) + 756 flags = (flags & (S80 | Z40 | P04)) +
757 (temp & (F20 | F08)) + 757 (temp & (F20 | F08)) +
758 (temp >> 8); 758 (temp >> 8);
759 r.b.a = temp; 759 r.b.a = temp;
760 goto loop; 760 goto loop;
761 } 761 }
762 762
763 case 0x1F:{// RRA 763 case 0x1F:{// RRA
764 int temp = (flags << 7) + (r.b.a >> 1); 764 int temp = (flags << 7) + (r.b.a >> 1);
765 flags = (flags & (S80 | Z40 | P04)) + 765 flags = (flags & (S80 | Z40 | P04)) +
766 (temp & (F20 | F08)) + 766 (temp & (F20 | F08)) +
767 (r.b.a & C01); 767 (r.b.a & C01);
768 r.b.a = temp; 768 r.b.a = temp;
769 goto loop; 769 goto loop;
770 } 770 }
771 771
772// Misc 772// Misc
773 case 0x2F:{// CPL 773 case 0x2F:{// CPL
774 int temp = ~r.b.a; 774 int temp = ~r.b.a;
775 flags = (flags & (S80 | Z40 | P04 | C01)) + 775 flags = (flags & (S80 | Z40 | P04 | C01)) +
776 (temp & (F20 | F08)) + 776 (temp & (F20 | F08)) +
777 (H10 | N02); 777 (H10 | N02);
778 r.b.a = temp; 778 r.b.a = temp;
779 goto loop; 779 goto loop;
780 } 780 }
781 781
782 case 0x3F:{// CCF 782 case 0x3F:{// CCF
783 flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) + 783 flags = ((flags & (S80 | Z40 | P04 | C01)) ^ C01) +
784 (flags << 4 & H10) + 784 (flags << 4 & H10) +
785 (r.b.a & (F20 | F08)); 785 (r.b.a & (F20 | F08));
786 goto loop; 786 goto loop;
787 } 787 }
788 788
789 case 0x37: // SCF 789 case 0x37: // SCF
790 flags = ((flags & (S80 | Z40 | P04)) | C01) + 790 flags = ((flags & (S80 | Z40 | P04)) | C01) +
791 (r.b.a & (F20 | F08)); 791 (r.b.a & (F20 | F08));
792 goto loop; 792 goto loop;
793 793
794 case 0xDB: // IN A,(imm) 794 case 0xDB: // IN A,(imm)
795 pc++; 795 pc++;
796 r.b.a = IN_PORT( (data + r.b.a * 0x100) ); 796 r.b.a = IN_PORT( (data + r.b.a * 0x100) );
797 goto loop; 797 goto loop;
798 798
799 case 0xE3:{// EX (SP),HL 799 case 0xE3:{// EX (SP),HL
800 int temp = READ_WORD( sp ); 800 int temp = READ_WORD( sp );
801 WRITE_WORD( sp, r.w.hl ); 801 WRITE_WORD( sp, r.w.hl );
802 r.w.hl = temp; 802 r.w.hl = temp;
803 goto loop; 803 goto loop;
804 } 804 }
805 805
806 case 0xEB: // EX DE,HL 806 case 0xEB: // EX DE,HL
807 EX( r.w.hl, r.w.de ); 807 EX( r.w.hl, r.w.de );
808 goto loop; 808 goto loop;
809 809
810 case 0xD9: // EXX DE,HL 810 case 0xD9: // EXX DE,HL
811 EXX( w.bc ); 811 EXX( w.bc );
812 EXX( w.de ); 812 EXX( w.de );
813 EXX( w.hl ); 813 EXX( w.hl );
814 goto loop; 814 goto loop;
815 815
816 case 0xF3: // DI 816 case 0xF3: // DI
817 R.iff1 = 0; 817 R.iff1 = 0;
818 R.iff2 = 0; 818 R.iff2 = 0;
819 goto loop; 819 goto loop;
820 820
821 case 0xFB: // EI 821 case 0xFB: // EI
822 R.iff1 = 1; 822 R.iff1 = 1;
823 R.iff2 = 1; 823 R.iff2 = 1;
824 // TODO: delayed effect 824 // TODO: delayed effect
825 goto loop; 825 goto loop;
826 826
827 case 0x76: // HALT 827 case 0x76: // HALT
828 goto halt; 828 goto halt;
829 829
830//////////////////////////////////////// CB prefix 830//////////////////////////////////////// CB prefix
831 { 831 {
832 case 0xCB: 832 case 0xCB:
833 pc++; 833 pc++;
834 switch ( data ) 834 switch ( data )
835 { 835 {
836 836
837 // Rotate left 837 // Rotate left
838 838
839 #define RLC( read, write ) {\ 839 #define RLC( read, write ) {\
840 int result = read;\ 840 int result = read;\
841 result = BYTE( result << 1 ) + (result >> 7);\ 841 result = BYTE( result << 1 ) + (result >> 7);\
842 flags = SZ28P( result ) + (result & C01);\ 842 flags = SZ28P( result ) + (result & C01);\
843 write;\ 843 write;\
844 goto loop;\ 844 goto loop;\
845 } 845 }
846 846
847 case 0x06: // RLC (HL) 847 case 0x06: // RLC (HL)
848 s_time += 7; 848 s_time += 7;
849 data = r.w.hl; 849 data = r.w.hl;
850 rlc_data_addr: 850 rlc_data_addr:
851 RLC( READ_MEM( data ), WRITE_MEM( data, result ) ) 851 RLC( READ_MEM( data ), WRITE_MEM( data, result ) )
852 852
853 CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r 853 CASE7( 00, 01, 02, 03, 04, 05, 07 ):{// RLC r
854 byte* reg = &R8( data, 0 ); 854 byte* reg = &R8( data, 0 );
855 RLC( *reg, *reg = result ) 855 RLC( *reg, *reg = result )
856 } 856 }
857 857
858 #define RL( read, write ) {\ 858 #define RL( read, write ) {\
859 int result = (read << 1) + (flags & C01);\ 859 int result = (read << 1) + (flags & C01);\
860 flags = SZ28PC( result );\ 860 flags = SZ28PC( result );\
861 write;\ 861 write;\
862 goto loop;\ 862 goto loop;\
863 } 863 }
864 864
865 case 0x16: // RL (HL) 865 case 0x16: // RL (HL)
866 s_time += 7; 866 s_time += 7;
867 data = r.w.hl; 867 data = r.w.hl;
868 rl_data_addr: 868 rl_data_addr:
869 RL( READ_MEM( data ), WRITE_MEM( data, result ) ) 869 RL( READ_MEM( data ), WRITE_MEM( data, result ) )
870 870
871 CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r 871 CASE7( 10, 11, 12, 13, 14, 15, 17 ):{// RL r
872 byte* reg = &R8( data, 0x10 ); 872 byte* reg = &R8( data, 0x10 );
873 RL( *reg, *reg = result ) 873 RL( *reg, *reg = result )
874 } 874 }
875 875
876 #define SLA( read, low_bit, write ) {\ 876 #define SLA( read, low_bit, write ) {\
877 int result = (read << 1) + low_bit;\ 877 int result = (read << 1) + low_bit;\
878 flags = SZ28PC( result );\ 878 flags = SZ28PC( result );\
879 write;\ 879 write;\
880 goto loop;\ 880 goto loop;\
881 } 881 }
882 882
883 case 0x26: // SLA (HL) 883 case 0x26: // SLA (HL)
884 s_time += 7; 884 s_time += 7;
885 data = r.w.hl; 885 data = r.w.hl;
886 sla_data_addr: 886 sla_data_addr:
887 SLA( READ_MEM( data ), 0, WRITE_MEM( data, result ) ) 887 SLA( READ_MEM( data ), 0, WRITE_MEM( data, result ) )
888 888
889 CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r 889 CASE7( 20, 21, 22, 23, 24, 25, 27 ):{// SLA r
890 byte* reg = &R8( data, 0x20 ); 890 byte* reg = &R8( data, 0x20 );
891 SLA( *reg, 0, *reg = result ) 891 SLA( *reg, 0, *reg = result )
892 } 892 }
893 893
894 case 0x36: // SLL (HL) 894 case 0x36: // SLL (HL)
895 s_time += 7; 895 s_time += 7;
896 data = r.w.hl; 896 data = r.w.hl;
897 sll_data_addr: 897 sll_data_addr:
898 SLA( READ_MEM( data ), 1, WRITE_MEM( data, result ) ) 898 SLA( READ_MEM( data ), 1, WRITE_MEM( data, result ) )
899 899
900 CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r 900 CASE7( 30, 31, 32, 33, 34, 35, 37 ):{// SLL r
901 byte* reg = &R8( data, 0x30 ); 901 byte* reg = &R8( data, 0x30 );
902 SLA( *reg, 1, *reg = result ) 902 SLA( *reg, 1, *reg = result )
903 } 903 }
904 904
905 // Rotate right 905 // Rotate right
906 906
907 #define RRC( read, write ) {\ 907 #define RRC( read, write ) {\
908 int result = read;\ 908 int result = read;\
909 flags = result & C01;\ 909 flags = result & C01;\
910 result = BYTE( result << 7 ) + (result >> 1);\ 910 result = BYTE( result << 7 ) + (result >> 1);\
911 flags += SZ28P( result );\ 911 flags += SZ28P( result );\
912 write;\ 912 write;\
913 goto loop;\ 913 goto loop;\
914 } 914 }
915 915
916 case 0x0E: // RRC (HL) 916 case 0x0E: // RRC (HL)
917 s_time += 7; 917 s_time += 7;
918 data = r.w.hl; 918 data = r.w.hl;
919 rrc_data_addr: 919 rrc_data_addr:
920 RRC( READ_MEM( data ), WRITE_MEM( data, result ) ) 920 RRC( READ_MEM( data ), WRITE_MEM( data, result ) )
921 921
922 CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r 922 CASE7( 08, 09, 0A, 0B, 0C, 0D, 0F ):{// RRC r
923 byte* reg = &R8( data, 0x08 ); 923 byte* reg = &R8( data, 0x08 );
924 RRC( *reg, *reg = result ) 924 RRC( *reg, *reg = result )
925 } 925 }
926 926
927 #define RR( read, write ) {\ 927 #define RR( read, write ) {\
928 int result = read;\ 928 int result = read;\
929 int temp = result & C01;\ 929 int temp = result & C01;\
930 result = BYTE( flags << 7 ) + (result >> 1);\ 930 result = BYTE( flags << 7 ) + (result >> 1);\
931 flags = SZ28P( result ) + temp;\ 931 flags = SZ28P( result ) + temp;\
932 write;\ 932 write;\
933 goto loop;\ 933 goto loop;\
934 } 934 }
935 935
936 case 0x1E: // RR (HL) 936 case 0x1E: // RR (HL)
937 s_time += 7; 937 s_time += 7;
938 data = r.w.hl; 938 data = r.w.hl;
939 rr_data_addr: 939 rr_data_addr:
940 RR( READ_MEM( data ), WRITE_MEM( data, result ) ) 940 RR( READ_MEM( data ), WRITE_MEM( data, result ) )
941 941
942 CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r 942 CASE7( 18, 19, 1A, 1B, 1C, 1D, 1F ):{// RR r
943 byte* reg = &R8( data, 0x18 ); 943 byte* reg = &R8( data, 0x18 );
944 RR( *reg, *reg = result ) 944 RR( *reg, *reg = result )
945 } 945 }
946 946
947 #define SRA( read, write ) {\ 947 #define SRA( read, write ) {\
948 int result = read;\ 948 int result = read;\
949 flags = result & C01;\ 949 flags = result & C01;\
950 result = (result & 0x80) + (result >> 1);\ 950 result = (result & 0x80) + (result >> 1);\
951 flags += SZ28P( result );\ 951 flags += SZ28P( result );\
952 write;\ 952 write;\
953 goto loop;\ 953 goto loop;\
954 } 954 }
955 955
956 case 0x2E: // SRA (HL) 956 case 0x2E: // SRA (HL)
957 data = r.w.hl; 957 data = r.w.hl;
958 s_time += 7; 958 s_time += 7;
959 sra_data_addr: 959 sra_data_addr:
960 SRA( READ_MEM( data ), WRITE_MEM( data, result ) ) 960 SRA( READ_MEM( data ), WRITE_MEM( data, result ) )
961 961
962 CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r 962 CASE7( 28, 29, 2A, 2B, 2C, 2D, 2F ):{// SRA r
963 byte* reg = &R8( data, 0x28 ); 963 byte* reg = &R8( data, 0x28 );
964 SRA( *reg, *reg = result ) 964 SRA( *reg, *reg = result )
965 } 965 }
966 966
967 #define SRL( read, write ) {\ 967 #define SRL( read, write ) {\
968 int result = read;\ 968 int result = read;\
969 flags = result & C01;\ 969 flags = result & C01;\
970 result >>= 1;\ 970 result >>= 1;\
971 flags += SZ28P( result );\ 971 flags += SZ28P( result );\
972 write;\ 972 write;\
973 goto loop;\ 973 goto loop;\
974 } 974 }
975 975
976 case 0x3E: // SRL (HL) 976 case 0x3E: // SRL (HL)
977 s_time += 7; 977 s_time += 7;
978 data = r.w.hl; 978 data = r.w.hl;
979 srl_data_addr: 979 srl_data_addr:
980 SRL( READ_MEM( data ), WRITE_MEM( data, result ) ) 980 SRL( READ_MEM( data ), WRITE_MEM( data, result ) )
981 981
982 CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r 982 CASE7( 38, 39, 3A, 3B, 3C, 3D, 3F ):{// SRL r
983 byte* reg = &R8( data, 0x38 ); 983 byte* reg = &R8( data, 0x38 );
984 SRL( *reg, *reg = result ) 984 SRL( *reg, *reg = result )
985 } 985 }
986 986
987 // BIT 987 // BIT
988 { 988 {
989 int temp; 989 int temp;
990 CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL) 990 CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ): // BIT b,(HL)
991 s_time += 4; 991 s_time += 4;
992 temp = READ_MEM( r.w.hl ); 992 temp = READ_MEM( r.w.hl );
993 flags &= C01; 993 flags &= C01;
994 goto bit_temp; 994 goto bit_temp;
995 CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r 995 CASE7( 40, 41, 42, 43, 44, 45, 47 ): // BIT 0,r
996 CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r 996 CASE7( 48, 49, 4A, 4B, 4C, 4D, 4F ): // BIT 1,r
997 CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r 997 CASE7( 50, 51, 52, 53, 54, 55, 57 ): // BIT 2,r
998 CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r 998 CASE7( 58, 59, 5A, 5B, 5C, 5D, 5F ): // BIT 3,r
999 CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r 999 CASE7( 60, 61, 62, 63, 64, 65, 67 ): // BIT 4,r
1000 CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r 1000 CASE7( 68, 69, 6A, 6B, 6C, 6D, 6F ): // BIT 5,r
1001 CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r 1001 CASE7( 70, 71, 72, 73, 74, 75, 77 ): // BIT 6,r
1002 CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r 1002 CASE7( 78, 79, 7A, 7B, 7C, 7D, 7F ): // BIT 7,r
1003 temp = R8( data & 7, 0 ); 1003 temp = R8( data & 7, 0 );
1004 flags = (flags & C01) + (temp & (F20 | F08)); 1004 flags = (flags & C01) + (temp & (F20 | F08));
1005 bit_temp: 1005 bit_temp:
1006 temp = temp & (1 << (data >> 3 & 7)); 1006 temp = temp & (1 << (data >> 3 & 7));
1007 flags += (temp & S80) + H10; 1007 flags += (temp & S80) + H10;
1008 flags += (unsigned) --temp >> 8 & (Z40 | P04); 1008 flags += (unsigned) --temp >> 8 & (Z40 | P04);
1009 goto loop; 1009 goto loop;
1010 } 1010 }
1011 1011
1012 // SET/RES 1012 // SET/RES
1013 CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL) 1013 CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(HL)
1014 CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL) 1014 CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(HL)
1015 s_time += 7; 1015 s_time += 7;
1016 int temp = READ_MEM( r.w.hl ); 1016 int temp = READ_MEM( r.w.hl );
1017 int bit = 1 << (data >> 3 & 7); 1017 int bit = 1 << (data >> 3 & 7);
1018 temp |= bit; // SET 1018 temp |= bit; // SET
1019 if ( !(data & 0x40) ) 1019 if ( !(data & 0x40) )
1020 temp ^= bit; // RES 1020 temp ^= bit; // RES
1021 WRITE_MEM( r.w.hl, temp ); 1021 WRITE_MEM( r.w.hl, temp );
1022 goto loop; 1022 goto loop;
1023 } 1023 }
1024 1024
1025 CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r 1025 CASE7( C0, C1, C2, C3, C4, C5, C7 ): // SET 0,r
1026 CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r 1026 CASE7( C8, C9, CA, CB, CC, CD, CF ): // SET 1,r
1027 CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r 1027 CASE7( D0, D1, D2, D3, D4, D5, D7 ): // SET 2,r
1028 CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r 1028 CASE7( D8, D9, DA, DB, DC, DD, DF ): // SET 3,r
1029 CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r 1029 CASE7( E0, E1, E2, E3, E4, E5, E7 ): // SET 4,r
1030 CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r 1030 CASE7( E8, E9, EA, EB, EC, ED, EF ): // SET 5,r
1031 CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r 1031 CASE7( F0, F1, F2, F3, F4, F5, F7 ): // SET 6,r
1032 CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r 1032 CASE7( F8, F9, FA, FB, FC, FD, FF ): // SET 7,r
1033 R8( data & 7, 0 ) |= 1 << (data >> 3 & 7); 1033 R8( data & 7, 0 ) |= 1 << (data >> 3 & 7);
1034 goto loop; 1034 goto loop;
1035 1035
1036 CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r 1036 CASE7( 80, 81, 82, 83, 84, 85, 87 ): // RES 0,r
1037 CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r 1037 CASE7( 88, 89, 8A, 8B, 8C, 8D, 8F ): // RES 1,r
1038 CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r 1038 CASE7( 90, 91, 92, 93, 94, 95, 97 ): // RES 2,r
1039 CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r 1039 CASE7( 98, 99, 9A, 9B, 9C, 9D, 9F ): // RES 3,r
1040 CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r 1040 CASE7( A0, A1, A2, A3, A4, A5, A7 ): // RES 4,r
1041 CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r 1041 CASE7( A8, A9, AA, AB, AC, AD, AF ): // RES 5,r
1042 CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r 1042 CASE7( B0, B1, B2, B3, B4, B5, B7 ): // RES 6,r
1043 CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r 1043 CASE7( B8, B9, BA, BB, BC, BD, BF ): // RES 7,r
1044 R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7)); 1044 R8( data & 7, 0 ) &= ~(1 << (data >> 3 & 7));
1045 goto loop; 1045 goto loop;
1046 } 1046 }
1047 assert( false ); 1047 assert( false );
1048 } 1048 }
1049 1049
1050#undef GET_ADDR 1050#undef GET_ADDR
1051#define GET_ADDR() GET_LE16( &INSTR( 1, pc ) ) 1051#define GET_ADDR() GET_LE16( &INSTR( 1, pc ) )
1052 1052
1053//////////////////////////////////////// ED prefix 1053//////////////////////////////////////// ED prefix
1054 { 1054 {
1055 case 0xED: 1055 case 0xED:
1056 pc++; 1056 pc++;
1057 s_time += (clock_table + 256) [data] >> 4; 1057 s_time += (clock_table + 256) [data] >> 4;
1058 switch ( data ) 1058 switch ( data )
1059 { 1059 {
1060 { 1060 {
1061 int temp; 1061 int temp;
1062 case 0x72: // SBC HL,SP 1062 case 0x72: // SBC HL,SP
1063 case 0x7A: // ADC HL,SP 1063 case 0x7A: // ADC HL,SP
1064 temp = sp; 1064 temp = sp;
1065 if ( 0 ) 1065 if ( 0 )
1066 case 0x42: // SBC HL,BC 1066 case 0x42: // SBC HL,BC
1067 case 0x52: // SBC HL,DE 1067 case 0x52: // SBC HL,DE
1068 case 0x62: // SBC HL,HL 1068 case 0x62: // SBC HL,HL
1069 case 0x4A: // ADC HL,BC 1069 case 0x4A: // ADC HL,BC
1070 case 0x5A: // ADC HL,DE 1070 case 0x5A: // ADC HL,DE
1071 case 0x6A: // ADC HL,HL 1071 case 0x6A: // ADC HL,HL
1072 temp = R16( data >> 3 & 6, 1, 0 ); 1072 temp = R16( data >> 3 & 6, 1, 0 );
1073 int sum = temp + (flags & C01); 1073 int sum = temp + (flags & C01);
1074 flags = ~data >> 2 & N02; 1074 flags = ~data >> 2 & N02;
1075 if ( flags ) 1075 if ( flags )
1076 sum = -sum; 1076 sum = -sum;
1077 sum += r.w.hl; 1077 sum += r.w.hl;
1078 temp ^= r.w.hl; 1078 temp ^= r.w.hl;
1079 temp ^= sum; 1079 temp ^= sum;
1080 flags +=(sum >> 16 & C01) + 1080 flags +=(sum >> 16 & C01) +
1081 (temp >> 8 & H10) + 1081 (temp >> 8 & H10) +
1082 (sum >> 8 & (S80 | F20 | F08)) + 1082 (sum >> 8 & (S80 | F20 | F08)) +
1083 ((temp + 0x8000) >> 14 & V04); 1083 ((temp + 0x8000) >> 14 & V04);
1084 r.w.hl = sum; 1084 r.w.hl = sum;
1085 if ( WORD( sum ) ) 1085 if ( WORD( sum ) )
1086 goto loop; 1086 goto loop;
1087 flags += Z40; 1087 flags += Z40;
1088 goto loop; 1088 goto loop;
1089 } 1089 }
1090 1090
1091 CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C) 1091 CASE8( 40, 48, 50, 58, 60, 68, 70, 78 ):{// IN r,(C)
1092 int temp = IN_PORT( r.w.bc ); 1092 int temp = IN_PORT( r.w.bc );
1093 R8( data >> 3, 8 ) = temp; 1093 R8( data >> 3, 8 ) = temp;
1094 flags = (flags & C01) + SZ28P( temp ); 1094 flags = (flags & C01) + SZ28P( temp );
1095 goto loop; 1095 goto loop;
1096 } 1096 }
1097 1097
1098 case 0x71: // OUT (C),0 1098 case 0x71: // OUT (C),0
1099 r.b.flags = 0; 1099 r.b.flags = 0;
1100 CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r 1100 CASE7( 41, 49, 51, 59, 61, 69, 79 ): // OUT (C),r
1101 OUT_PORT( r.w.bc, R8( data >> 3, 8 ) ); 1101 OUT_PORT( r.w.bc, R8( data >> 3, 8 ) );
1102 goto loop; 1102 goto loop;
1103 1103
1104 { 1104 {
1105 int temp; 1105 int temp;
1106 case 0x73: // LD (ADDR),SP 1106 case 0x73: // LD (ADDR),SP
1107 temp = sp; 1107 temp = sp;
1108 if ( 0 ) 1108 if ( 0 )
1109 case 0x43: // LD (ADDR),BC 1109 case 0x43: // LD (ADDR),BC
1110 case 0x53: // LD (ADDR),DE 1110 case 0x53: // LD (ADDR),DE
1111 temp = R16( data, 4, 0x43 ); 1111 temp = R16( data, 4, 0x43 );
1112 int addr = GET_ADDR(); 1112 int addr = GET_ADDR();
1113 pc += 2; 1113 pc += 2;
1114 WRITE_WORD( addr, temp ); 1114 WRITE_WORD( addr, temp );
1115 goto loop; 1115 goto loop;
1116 } 1116 }
1117 1117
1118 case 0x4B: // LD BC,(ADDR) 1118 case 0x4B: // LD BC,(ADDR)
1119 case 0x5B:{// LD DE,(ADDR) 1119 case 0x5B:{// LD DE,(ADDR)
1120 int addr = GET_ADDR(); 1120 int addr = GET_ADDR();
1121 pc += 2; 1121 pc += 2;
1122 R16( data, 4, 0x4B ) = READ_WORD( addr ); 1122 R16( data, 4, 0x4B ) = READ_WORD( addr );
1123 goto loop; 1123 goto loop;
1124 } 1124 }
1125 1125
1126 case 0x7B:{// LD SP,(ADDR) 1126 case 0x7B:{// LD SP,(ADDR)
1127 int addr = GET_ADDR(); 1127 int addr = GET_ADDR();
1128 pc += 2; 1128 pc += 2;
1129 sp = READ_WORD( addr ); 1129 sp = READ_WORD( addr );
1130 goto loop; 1130 goto loop;
1131 } 1131 }
1132 1132
1133 case 0x67:{// RRD 1133 case 0x67:{// RRD
1134 int temp = READ_MEM( r.w.hl ); 1134 int temp = READ_MEM( r.w.hl );
1135 WRITE_MEM( r.w.hl, ((r.b.a << 4) + (temp >> 4)) ); 1135 WRITE_MEM( r.w.hl, ((r.b.a << 4) + (temp >> 4)) );
1136 temp = (r.b.a & 0xF0) + (temp & 0x0F); 1136 temp = (r.b.a & 0xF0) + (temp & 0x0F);
1137 flags = (flags & C01) + SZ28P( temp ); 1137 flags = (flags & C01) + SZ28P( temp );
1138 r.b.a = temp; 1138 r.b.a = temp;
1139 goto loop; 1139 goto loop;
1140 } 1140 }
1141 1141
1142 case 0x6F:{// RLD 1142 case 0x6F:{// RLD
1143 int temp = READ_MEM( r.w.hl ); 1143 int temp = READ_MEM( r.w.hl );
1144 WRITE_MEM( r.w.hl, ((temp << 4) + (r.b.a & 0x0F)) ); 1144 WRITE_MEM( r.w.hl, ((temp << 4) + (r.b.a & 0x0F)) );
1145 temp = (r.b.a & 0xF0) + (temp >> 4); 1145 temp = (r.b.a & 0xF0) + (temp >> 4);
1146 flags = (flags & C01) + SZ28P( temp ); 1146 flags = (flags & C01) + SZ28P( temp );
1147 r.b.a = temp; 1147 r.b.a = temp;
1148 goto loop; 1148 goto loop;
1149 } 1149 }
1150 1150
1151 CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG 1151 CASE8( 44, 4C, 54, 5C, 64, 6C, 74, 7C ): // NEG
1152 opcode = 0x10; // flag to do SBC instead of ADC 1152 opcode = 0x10; // flag to do SBC instead of ADC
1153 flags &= ~C01; 1153 flags &= ~C01;
1154 data = r.b.a; 1154 data = r.b.a;
1155 r.b.a = 0; 1155 r.b.a = 0;
1156 goto adc_data; 1156 goto adc_data;
1157 1157
1158 { 1158 {
1159 int inc; 1159 int inc;
1160 case 0xA9: // CPD 1160 case 0xA9: // CPD
1161 case 0xB9: // CPDR 1161 case 0xB9: // CPDR
1162 inc = -1; 1162 inc = -1;
1163 if ( 0 ) 1163 if ( 0 )
1164 case 0xA1: // CPI 1164 case 0xA1: // CPI
1165 case 0xB1: // CPIR 1165 case 0xB1: // CPIR
1166 inc = +1; 1166 inc = +1;
1167 int addr = r.w.hl; 1167 int addr = r.w.hl;
1168 r.w.hl = addr + inc; 1168 r.w.hl = addr + inc;
1169 int temp = READ_MEM( addr ); 1169 int temp = READ_MEM( addr );
1170 1170
1171 int result = r.b.a - temp; 1171 int result = r.b.a - temp;
1172 flags = (flags & C01) + N02 + 1172 flags = (flags & C01) + N02 +
1173 ((((temp ^ r.b.a) & H10) ^ result) & (S80 | H10)); 1173 ((((temp ^ r.b.a) & H10) ^ result) & (S80 | H10));
1174 1174
1175 if ( !BYTE( result ) ) 1175 if ( !BYTE( result ) )
1176 flags += Z40; 1176 flags += Z40;
1177 result -= (flags & H10) >> 4; 1177 result -= (flags & H10) >> 4;
1178 flags += result & F08; 1178 flags += result & F08;
1179 flags += result << 4 & F20; 1179 flags += result << 4 & F20;
1180 if ( !--r.w.bc ) 1180 if ( !--r.w.bc )
1181 goto loop; 1181 goto loop;
1182 1182
1183 flags += V04; 1183 flags += V04;
1184 if ( flags & Z40 || data < 0xB0 ) 1184 if ( flags & Z40 || data < 0xB0 )
1185 goto loop; 1185 goto loop;
1186 1186
1187 pc -= 2; 1187 pc -= 2;
1188 s_time += 5; 1188 s_time += 5;
1189 goto loop; 1189 goto loop;
1190 } 1190 }
1191 1191
1192 { 1192 {
1193 int inc; 1193 int inc;
1194 case 0xA8: // LDD 1194 case 0xA8: // LDD
1195 case 0xB8: // LDDR 1195 case 0xB8: // LDDR
1196 inc = -1; 1196 inc = -1;
1197 if ( 0 ) 1197 if ( 0 )
1198 case 0xA0: // LDI 1198 case 0xA0: // LDI
1199 case 0xB0: // LDIR 1199 case 0xB0: // LDIR
1200 inc = +1; 1200 inc = +1;
1201 int addr = r.w.hl; 1201 int addr = r.w.hl;
1202 r.w.hl = addr + inc; 1202 r.w.hl = addr + inc;
1203 int temp = READ_MEM( addr ); 1203 int temp = READ_MEM( addr );
1204 1204
1205 addr = r.w.de; 1205 addr = r.w.de;
1206 r.w.de = addr + inc; 1206 r.w.de = addr + inc;
1207 WRITE_MEM( addr, temp ); 1207 WRITE_MEM( addr, temp );
1208 1208
1209 temp += r.b.a; 1209 temp += r.b.a;
1210 flags = (flags & (S80 | Z40 | C01)) + 1210 flags = (flags & (S80 | Z40 | C01)) +
1211 (temp & F08) + (temp << 4 & F20); 1211 (temp & F08) + (temp << 4 & F20);
1212 if ( !--r.w.bc ) 1212 if ( !--r.w.bc )
1213 goto loop; 1213 goto loop;
1214 1214
1215 flags += V04; 1215 flags += V04;
1216 if ( data < 0xB0 ) 1216 if ( data < 0xB0 )
1217 goto loop; 1217 goto loop;
1218 1218
1219 pc -= 2; 1219 pc -= 2;
1220 s_time += 5; 1220 s_time += 5;
1221 goto loop; 1221 goto loop;
1222 } 1222 }
1223 1223
1224 { 1224 {
1225 int inc; 1225 int inc;
1226 case 0xAB: // OUTD 1226 case 0xAB: // OUTD
1227 case 0xBB: // OTDR 1227 case 0xBB: // OTDR
1228 inc = -1; 1228 inc = -1;
1229 if ( 0 ) 1229 if ( 0 )
1230 case 0xA3: // OUTI 1230 case 0xA3: // OUTI
1231 case 0xB3: // OTIR 1231 case 0xB3: // OTIR
1232 inc = +1; 1232 inc = +1;
1233 int addr = r.w.hl; 1233 int addr = r.w.hl;
1234 r.w.hl = addr + inc; 1234 r.w.hl = addr + inc;
1235 int temp = READ_MEM( addr ); 1235 int temp = READ_MEM( addr );
1236 1236
1237 int b = --r.b.b; 1237 int b = --r.b.b;
1238 flags = (temp >> 6 & N02) + SZ28( b ); 1238 flags = (temp >> 6 & N02) + SZ28( b );
1239 if ( b && data >= 0xB0 ) 1239 if ( b && data >= 0xB0 )
1240 { 1240 {
1241 pc -= 2; 1241 pc -= 2;
1242 s_time += 5; 1242 s_time += 5;
1243 } 1243 }
1244 1244
1245 OUT_PORT( r.w.bc, temp ); 1245 OUT_PORT( r.w.bc, temp );
1246 goto loop; 1246 goto loop;
1247 } 1247 }
1248 1248
1249 { 1249 {
1250 int inc; 1250 int inc;
1251 case 0xAA: // IND 1251 case 0xAA: // IND
1252 case 0xBA: // INDR 1252 case 0xBA: // INDR
1253 inc = -1; 1253 inc = -1;
1254 if ( 0 ) 1254 if ( 0 )
1255 case 0xA2: // INI 1255 case 0xA2: // INI
1256 case 0xB2: // INIR 1256 case 0xB2: // INIR
1257 inc = +1; 1257 inc = +1;
1258 1258
1259 int addr = r.w.hl; 1259 int addr = r.w.hl;
1260 r.w.hl = addr + inc; 1260 r.w.hl = addr + inc;
1261 1261
1262 int temp = IN_PORT( r.w.bc ); 1262 int temp = IN_PORT( r.w.bc );
1263 1263
1264 int b = --r.b.b; 1264 int b = --r.b.b;
1265 flags = (temp >> 6 & N02) + SZ28( b ); 1265 flags = (temp >> 6 & N02) + SZ28( b );
1266 if ( b && data >= 0xB0 ) 1266 if ( b && data >= 0xB0 )
1267 { 1267 {
1268 pc -= 2; 1268 pc -= 2;
1269 s_time += 5; 1269 s_time += 5;
1270 } 1270 }
1271 1271
1272 WRITE_MEM( addr, temp ); 1272 WRITE_MEM( addr, temp );
1273 goto loop; 1273 goto loop;
1274 } 1274 }
1275 1275
1276 case 0x47: // LD I,A 1276 case 0x47: // LD I,A
1277 R.i = r.b.a; 1277 R.i = r.b.a;
1278 goto loop; 1278 goto loop;
1279 1279
1280 case 0x4F: // LD R,A 1280 case 0x4F: // LD R,A
1281 SET_R( r.b.a ); 1281 SET_R( r.b.a );
1282 dprintf( "LD R,A not supported\n" ); 1282 dprintf( "LD R,A not supported\n" );
1283 warning = true; 1283 warning = true;
1284 goto loop; 1284 goto loop;
1285 1285
1286 case 0x57: // LD A,I 1286 case 0x57: // LD A,I
1287 r.b.a = R.i; 1287 r.b.a = R.i;
1288 goto ld_ai_common; 1288 goto ld_ai_common;
1289 1289
1290 case 0x5F: // LD A,R 1290 case 0x5F: // LD A,R
1291 r.b.a = GET_R(); 1291 r.b.a = GET_R();
1292 dprintf( "LD A,R not supported\n" ); 1292 dprintf( "LD A,R not supported\n" );
1293 warning = true; 1293 warning = true;
1294 ld_ai_common: 1294 ld_ai_common:
1295 flags = (flags & C01) + SZ28( r.b.a ) + (R.iff2 << 2 & V04); 1295 flags = (flags & C01) + SZ28( r.b.a ) + (R.iff2 << 2 & V04);
1296 goto loop; 1296 goto loop;
1297 1297
1298 CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN 1298 CASE8( 45, 4D, 55, 5D, 65, 6D, 75, 7D ): // RETI/RETN
1299 R.iff1 = R.iff2; 1299 R.iff1 = R.iff2;
1300 goto ret_taken; 1300 goto ret_taken;
1301 1301
1302 case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0 1302 case 0x46: case 0x4E: case 0x66: case 0x6E: // IM 0
1303 R.im = 0; 1303 R.im = 0;
1304 goto loop; 1304 goto loop;
1305 1305
1306 case 0x56: case 0x76: // IM 1 1306 case 0x56: case 0x76: // IM 1
1307 R.im = 1; 1307 R.im = 1;
1308 goto loop; 1308 goto loop;
1309 1309
1310 case 0x5E: case 0x7E: // IM 2 1310 case 0x5E: case 0x7E: // IM 2
1311 R.im = 2; 1311 R.im = 2;
1312 goto loop; 1312 goto loop;
1313 1313
1314 default: 1314 default:
1315 dprintf( "Opcode $ED $%02X not supported\n", data ); 1315 dprintf( "Opcode $ED $%02X not supported\n", data );
1316 warning = true; 1316 warning = true;
1317 goto loop; 1317 goto loop;
1318 } 1318 }
1319 assert( false ); 1319 assert( false );
1320 } 1320 }
1321 1321
1322//////////////////////////////////////// DD/FD prefix 1322//////////////////////////////////////// DD/FD prefix
1323 { 1323 {
1324 int ixy; 1324 int ixy;
1325 case 0xDD: 1325 case 0xDD:
1326 ixy = ix; 1326 ixy = ix;
1327 goto ix_prefix; 1327 goto ix_prefix;
1328 case 0xFD: 1328 case 0xFD:
1329 ixy = iy; 1329 ixy = iy;
1330 ix_prefix: 1330 ix_prefix:
1331 pc++; 1331 pc++;
1332 int data2 = READ_CODE( pc ); 1332 int data2 = READ_CODE( pc );
1333 s_time += (clock_table + 256) [data] & 0x0F; 1333 s_time += (clock_table + 256) [data] & 0x0F;
1334 switch ( data ) 1334 switch ( data )
1335 { 1335 {
1336 // TODO: more efficient way of avoid negative address 1336 // TODO: more efficient way of avoid negative address
1337 // TODO: avoid using this as argument to READ_MEM() since it is evaluated twice 1337 // TODO: avoid using this as argument to READ_MEM() since it is evaluated twice
1338 #define IXY_DISP( ixy, disp ) WORD( (ixy ) + (disp)) 1338 #define IXY_DISP( ixy, disp ) WORD( (ixy ) + (disp))
1339 1339
1340 #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in; 1340 #define SET_IXY( in ) if ( opcode == 0xDD ) ix = in; else iy = in;
1341 1341
1342 // ADD/ADC/SUB/SBC 1342 // ADD/ADC/SUB/SBC
1343 1343
1344 case 0x96: // SUB (IXY+disp) 1344 case 0x96: // SUB (IXY+disp)
1345 case 0x86: // ADD (IXY+disp) 1345 case 0x86: // ADD (IXY+disp)
1346 flags &= ~C01; 1346 flags &= ~C01;
1347 case 0x9E: // SBC (IXY+disp) 1347 case 0x9E: // SBC (IXY+disp)
1348 case 0x8E: // ADC (IXY+disp) 1348 case 0x8E: // ADC (IXY+disp)
1349 pc++; 1349 pc++;
1350 opcode = data; 1350 opcode = data;
1351 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); 1351 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) );
1352 goto adc_data; 1352 goto adc_data;
1353 1353
1354 case 0x94: // SUB HXY 1354 case 0x94: // SUB HXY
1355 case 0x84: // ADD HXY 1355 case 0x84: // ADD HXY
1356 flags &= ~C01; 1356 flags &= ~C01;
1357 case 0x9C: // SBC HXY 1357 case 0x9C: // SBC HXY
1358 case 0x8C: // ADC HXY 1358 case 0x8C: // ADC HXY
1359 opcode = data; 1359 opcode = data;
1360 data = ixy >> 8; 1360 data = ixy >> 8;
1361 goto adc_data; 1361 goto adc_data;
1362 1362
1363 case 0x95: // SUB LXY 1363 case 0x95: // SUB LXY
1364 case 0x85: // ADD LXY 1364 case 0x85: // ADD LXY
1365 flags &= ~C01; 1365 flags &= ~C01;
1366 case 0x9D: // SBC LXY 1366 case 0x9D: // SBC LXY
1367 case 0x8D: // ADC LXY 1367 case 0x8D: // ADC LXY
1368 opcode = data; 1368 opcode = data;
1369 data = BYTE( ixy ); 1369 data = BYTE( ixy );
1370 goto adc_data; 1370 goto adc_data;
1371 1371
1372 { 1372 {
1373 int temp; 1373 int temp;
1374 case 0x39: // ADD IXY,SP 1374 case 0x39: // ADD IXY,SP
1375 temp = sp; 1375 temp = sp;
1376 goto add_ixy_data; 1376 goto add_ixy_data;
1377 1377
1378 case 0x29: // ADD IXY,HL 1378 case 0x29: // ADD IXY,HL
1379 temp = ixy; 1379 temp = ixy;
1380 goto add_ixy_data; 1380 goto add_ixy_data;
1381 1381
1382 case 0x09: // ADD IXY,BC 1382 case 0x09: // ADD IXY,BC
1383 case 0x19: // ADD IXY,DE 1383 case 0x19: // ADD IXY,DE
1384 temp = R16( data, 4, 0x09 ); 1384 temp = R16( data, 4, 0x09 );
1385 add_ixy_data: { 1385 add_ixy_data: {
1386 int sum = ixy + temp; 1386 int sum = ixy + temp;
1387 temp ^= ixy; 1387 temp ^= ixy;
1388 ixy = WORD( sum ); 1388 ixy = WORD( sum );
1389 flags = (flags & (S80 | Z40 | V04)) + 1389 flags = (flags & (S80 | Z40 | V04)) +
1390 (sum >> 16) + 1390 (sum >> 16) +
1391 (sum >> 8 & (F20 | F08)) + 1391 (sum >> 8 & (F20 | F08)) +
1392 ((temp ^ sum) >> 8 & H10); 1392 ((temp ^ sum) >> 8 & H10);
1393 goto set_ixy; 1393 goto set_ixy;
1394 } 1394 }
1395 } 1395 }
1396 1396
1397 // AND 1397 // AND
1398 case 0xA6: // AND (IXY+disp) 1398 case 0xA6: // AND (IXY+disp)
1399 pc++; 1399 pc++;
1400 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); 1400 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) );
1401 goto and_data; 1401 goto and_data;
1402 1402
1403 case 0xA4: // AND HXY 1403 case 0xA4: // AND HXY
1404 data = ixy >> 8; 1404 data = ixy >> 8;
1405 goto and_data; 1405 goto and_data;
1406 1406
1407 case 0xA5: // AND LXY 1407 case 0xA5: // AND LXY
1408 data = BYTE( ixy ); 1408 data = BYTE( ixy );
1409 goto and_data; 1409 goto and_data;
1410 1410
1411 // OR 1411 // OR
1412 case 0xB6: // OR (IXY+disp) 1412 case 0xB6: // OR (IXY+disp)
1413 pc++; 1413 pc++;
1414 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); 1414 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) );
1415 goto or_data; 1415 goto or_data;
1416 1416
1417 case 0xB4: // OR HXY 1417 case 0xB4: // OR HXY
1418 data = ixy >> 8; 1418 data = ixy >> 8;
1419 goto or_data; 1419 goto or_data;
1420 1420
1421 case 0xB5: // OR LXY 1421 case 0xB5: // OR LXY
1422 data = BYTE( ixy ); 1422 data = BYTE( ixy );
1423 goto or_data; 1423 goto or_data;
1424 1424
1425 // XOR 1425 // XOR
1426 case 0xAE: // XOR (IXY+disp) 1426 case 0xAE: // XOR (IXY+disp)
1427 pc++; 1427 pc++;
1428 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); 1428 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) );
1429 goto xor_data; 1429 goto xor_data;
1430 1430
1431 case 0xAC: // XOR HXY 1431 case 0xAC: // XOR HXY
1432 data = ixy >> 8; 1432 data = ixy >> 8;
1433 goto xor_data; 1433 goto xor_data;
1434 1434
1435 case 0xAD: // XOR LXY 1435 case 0xAD: // XOR LXY
1436 data = BYTE( ixy ); 1436 data = BYTE( ixy );
1437 goto xor_data; 1437 goto xor_data;
1438 1438
1439 // CP 1439 // CP
1440 case 0xBE: // CP (IXY+disp) 1440 case 0xBE: // CP (IXY+disp)
1441 pc++; 1441 pc++;
1442 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); 1442 data = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) );
1443 goto cp_data; 1443 goto cp_data;
1444 1444
1445 case 0xBC: // CP HXY 1445 case 0xBC: // CP HXY
1446 data = ixy >> 8; 1446 data = ixy >> 8;
1447 goto cp_data; 1447 goto cp_data;
1448 1448
1449 case 0xBD: // CP LXY 1449 case 0xBD: // CP LXY
1450 data = BYTE( ixy ); 1450 data = BYTE( ixy );
1451 goto cp_data; 1451 goto cp_data;
1452 1452
1453 // LD 1453 // LD
1454 CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r 1454 CASE7( 70, 71, 72, 73, 74, 75, 77 ): // LD (IXY+disp),r
1455 data = R8( data, 0x70 ); 1455 data = R8( data, 0x70 );
1456 if ( 0 ) 1456 if ( 0 )
1457 case 0x36: // LD (IXY+disp),imm 1457 case 0x36: // LD (IXY+disp),imm
1458 pc++, data = READ_CODE( pc ); 1458 pc++, data = READ_CODE( pc );
1459 pc++; 1459 pc++;
1460 WRITE_MEM( IXY_DISP( ixy, SBYTE( data2 ) ), data ); 1460 WRITE_MEM( IXY_DISP( ixy, SBYTE( data2 ) ), data );
1461 goto loop; 1461 goto loop;
1462 1462
1463 CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY 1463 CASE5( 44, 4C, 54, 5C, 7C ): // LD r,HXY
1464 R8( data >> 3, 8 ) = ixy >> 8; 1464 R8( data >> 3, 8 ) = ixy >> 8;
1465 goto loop; 1465 goto loop;
1466 1466
1467 case 0x64: // LD HXY,HXY 1467 case 0x64: // LD HXY,HXY
1468 case 0x6D: // LD LXY,LXY 1468 case 0x6D: // LD LXY,LXY
1469 goto loop; 1469 goto loop;
1470 1470
1471 CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY 1471 CASE5( 45, 4D, 55, 5D, 7D ): // LD r,LXY
1472 R8( data >> 3, 8 ) = ixy; 1472 R8( data >> 3, 8 ) = ixy;
1473 goto loop; 1473 goto loop;
1474 1474
1475 CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp) 1475 CASE7( 46, 4E, 56, 5E, 66, 6E, 7E ): // LD r,(IXY+disp)
1476 pc++; 1476 pc++;
1477 R8( data >> 3, 8 ) = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) ); 1477 R8( data >> 3, 8 ) = READ_MEM( IXY_DISP( ixy, SBYTE( data2 ) ) );
1478 goto loop; 1478 goto loop;
1479 1479
1480 case 0x26: // LD HXY,imm 1480 case 0x26: // LD HXY,imm
1481 pc++; 1481 pc++;
1482 goto ld_hxy_data; 1482 goto ld_hxy_data;
1483 1483
1484 case 0x65: // LD HXY,LXY 1484 case 0x65: // LD HXY,LXY
1485 data2 = BYTE( ixy ); 1485 data2 = BYTE( ixy );
1486 goto ld_hxy_data; 1486 goto ld_hxy_data;
1487 1487
1488 CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r 1488 CASE5( 60, 61, 62, 63, 67 ): // LD HXY,r
1489 data2 = R8( data, 0x60 ); 1489 data2 = R8( data, 0x60 );
1490 ld_hxy_data: 1490 ld_hxy_data:
1491 ixy = BYTE( ixy ) + (data2 << 8); 1491 ixy = BYTE( ixy ) + (data2 << 8);
1492 goto set_ixy; 1492 goto set_ixy;
1493 1493
1494 case 0x2E: // LD LXY,imm 1494 case 0x2E: // LD LXY,imm
1495 pc++; 1495 pc++;
1496 goto ld_lxy_data; 1496 goto ld_lxy_data;
1497 1497
1498 case 0x6C: // LD LXY,HXY 1498 case 0x6C: // LD LXY,HXY
1499 data2 = ixy >> 8; 1499 data2 = ixy >> 8;
1500 goto ld_lxy_data; 1500 goto ld_lxy_data;
1501 1501
1502 CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r 1502 CASE5( 68, 69, 6A, 6B, 6F ): // LD LXY,r
1503 data2 = R8( data, 0x68 ); 1503 data2 = R8( data, 0x68 );
1504 ld_lxy_data: 1504 ld_lxy_data:
1505 ixy = (ixy & 0xFF00) + data2; 1505 ixy = (ixy & 0xFF00) + data2;
1506 set_ixy: 1506 set_ixy:
1507 if ( opcode == 0xDD ) 1507 if ( opcode == 0xDD )
1508 { 1508 {
1509 ix = ixy; 1509 ix = ixy;
1510 goto loop; 1510 goto loop;
1511 } 1511 }
1512 iy = ixy; 1512 iy = ixy;
1513 goto loop; 1513 goto loop;
1514 1514
1515 case 0xF9: // LD SP,IXY 1515 case 0xF9: // LD SP,IXY
1516 sp = ixy; 1516 sp = ixy;
1517 goto loop; 1517 goto loop;
1518 1518
1519 case 0x22:{// LD (ADDR),IXY 1519 case 0x22:{// LD (ADDR),IXY
1520 int addr = GET_ADDR(); 1520 int addr = GET_ADDR();
1521 pc += 2; 1521 pc += 2;
1522 WRITE_WORD( addr, ixy ); 1522 WRITE_WORD( addr, ixy );
1523 goto loop; 1523 goto loop;
1524 } 1524 }
1525 1525
1526 case 0x21: // LD IXY,imm 1526 case 0x21: // LD IXY,imm
1527 ixy = GET_ADDR(); 1527 ixy = GET_ADDR();
1528 pc += 2; 1528 pc += 2;
1529 goto set_ixy; 1529 goto set_ixy;
1530 1530
1531 case 0x2A:{// LD IXY,(addr) 1531 case 0x2A:{// LD IXY,(addr)
1532 int addr = GET_ADDR(); 1532 int addr = GET_ADDR();
1533 ixy = READ_WORD( addr ); 1533 ixy = READ_WORD( addr );
1534 pc += 2; 1534 pc += 2;
1535 goto set_ixy; 1535 goto set_ixy;
1536 } 1536 }
1537 1537
1538 // DD/FD CB prefix 1538 // DD/FD CB prefix
1539 case 0xCB: { 1539 case 0xCB: {
1540 data = IXY_DISP( ixy, SBYTE( data2 ) ); 1540 data = IXY_DISP( ixy, SBYTE( data2 ) );
1541 pc++; 1541 pc++;
1542 data2 = READ_CODE( pc ); 1542 data2 = READ_CODE( pc );
1543 pc++; 1543 pc++;
1544 switch ( data2 ) 1544 switch ( data2 )
1545 { 1545 {
1546 case 0x06: goto rlc_data_addr; // RLC (IXY) 1546 case 0x06: goto rlc_data_addr; // RLC (IXY)
1547 case 0x16: goto rl_data_addr; // RL (IXY) 1547 case 0x16: goto rl_data_addr; // RL (IXY)
1548 case 0x26: goto sla_data_addr; // SLA (IXY) 1548 case 0x26: goto sla_data_addr; // SLA (IXY)
1549 case 0x36: goto sll_data_addr; // SLL (IXY) 1549 case 0x36: goto sll_data_addr; // SLL (IXY)
1550 case 0x0E: goto rrc_data_addr; // RRC (IXY) 1550 case 0x0E: goto rrc_data_addr; // RRC (IXY)
1551 case 0x1E: goto rr_data_addr; // RR (IXY) 1551 case 0x1E: goto rr_data_addr; // RR (IXY)
1552 case 0x2E: goto sra_data_addr; // SRA (IXY) 1552 case 0x2E: goto sra_data_addr; // SRA (IXY)
1553 case 0x3E: goto srl_data_addr; // SRL (IXY) 1553 case 0x3E: goto srl_data_addr; // SRL (IXY)
1554 1554
1555 CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp) 1555 CASE8( 46, 4E, 56, 5E, 66, 6E, 76, 7E ):{// BIT b,(IXY+disp)
1556 int temp = READ_MEM( data ); 1556 int temp = READ_MEM( data );
1557 temp = temp & (1 << (data2 >> 3 & 7)); 1557 temp = temp & (1 << (data2 >> 3 & 7));
1558 flags = (flags & C01) + H10 + (temp & S80); 1558 flags = (flags & C01) + H10 + (temp & S80);
1559 flags += (unsigned) --temp >> 8 & (Z40 | P04); 1559 flags += (unsigned) --temp >> 8 & (Z40 | P04);
1560 goto loop; 1560 goto loop;
1561 } 1561 }
1562 1562
1563 CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp) 1563 CASE8( 86, 8E, 96, 9E, A6, AE, B6, BE ): // RES b,(IXY+disp)
1564 CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp) 1564 CASE8( C6, CE, D6, DE, E6, EE, F6, FE ):{// SET b,(IXY+disp)
1565 int temp = READ_MEM( data ); 1565 int temp = READ_MEM( data );
1566 int bit = 1 << (data2 >> 3 & 7); 1566 int bit = 1 << (data2 >> 3 & 7);
1567 temp |= bit; // SET 1567 temp |= bit; // SET
1568 if ( !(data2 & 0x40) ) 1568 if ( !(data2 & 0x40) )
1569 temp ^= bit; // RES 1569 temp ^= bit; // RES
1570 WRITE_MEM( data, temp ); 1570 WRITE_MEM( data, temp );
1571 goto loop; 1571 goto loop;
1572 } 1572 }
1573 1573
1574 default: 1574 default:
1575 dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 ); 1575 dprintf( "Opcode $%02X $CB $%02X not supported\n", opcode, data2 );
1576 warning = true; 1576 warning = true;
1577 goto loop; 1577 goto loop;
1578 } 1578 }
1579 assert( false ); 1579 assert( false );
1580 } 1580 }
1581 1581
1582 // INC/DEC 1582 // INC/DEC
1583 case 0x23: // INC IXY 1583 case 0x23: // INC IXY
1584 ixy = WORD( ixy + 1 ); 1584 ixy = WORD( ixy + 1 );
1585 goto set_ixy; 1585 goto set_ixy;
1586 1586
1587 case 0x2B: // DEC IXY 1587 case 0x2B: // DEC IXY
1588 ixy = WORD( ixy - 1 ); 1588 ixy = WORD( ixy - 1 );
1589 goto set_ixy; 1589 goto set_ixy;
1590 1590
1591 case 0x34: // INC (IXY+disp) 1591 case 0x34: // INC (IXY+disp)
1592 ixy = IXY_DISP( ixy, SBYTE( data2 ) ); 1592 ixy = IXY_DISP( ixy, SBYTE( data2 ) );
1593 pc++; 1593 pc++;
1594 data = READ_MEM( ixy ) + 1; 1594 data = READ_MEM( ixy ) + 1;
1595 WRITE_MEM( ixy, data ); 1595 WRITE_MEM( ixy, data );
1596 goto inc_set_flags; 1596 goto inc_set_flags;
1597 1597
1598 case 0x35: // DEC (IXY+disp) 1598 case 0x35: // DEC (IXY+disp)
1599 ixy = IXY_DISP( ixy, SBYTE( data2 ) ); 1599 ixy = IXY_DISP( ixy, SBYTE( data2 ) );
1600 pc++; 1600 pc++;
1601 data = READ_MEM( ixy ) - 1; 1601 data = READ_MEM( ixy ) - 1;
1602 WRITE_MEM( ixy, data ); 1602 WRITE_MEM( ixy, data );
1603 goto dec_set_flags; 1603 goto dec_set_flags;
1604 1604
1605 case 0x24: // INC HXY 1605 case 0x24: // INC HXY
1606 ixy = WORD( ixy + 0x100 ); 1606 ixy = WORD( ixy + 0x100 );
1607 data = ixy >> 8; 1607 data = ixy >> 8;
1608 goto inc_xy_common; 1608 goto inc_xy_common;
1609 1609
1610 case 0x2C: // INC LXY 1610 case 0x2C: // INC LXY
1611 data = BYTE( ixy + 1 ); 1611 data = BYTE( ixy + 1 );
1612 ixy = (ixy & 0xFF00) + data; 1612 ixy = (ixy & 0xFF00) + data;
1613 inc_xy_common: 1613 inc_xy_common:
1614 if ( opcode == 0xDD ) 1614 if ( opcode == 0xDD )
1615 { 1615 {
1616 ix = ixy; 1616 ix = ixy;
1617 goto inc_set_flags; 1617 goto inc_set_flags;
1618 } 1618 }
1619 iy = ixy; 1619 iy = ixy;
1620 goto inc_set_flags; 1620 goto inc_set_flags;
1621 1621
1622 case 0x25: // DEC HXY 1622 case 0x25: // DEC HXY
1623 ixy = WORD( ixy - 0x100 ); 1623 ixy = WORD( ixy - 0x100 );
1624 data = ixy >> 8; 1624 data = ixy >> 8;
1625 goto dec_xy_common; 1625 goto dec_xy_common;
1626 1626
1627 case 0x2D: // DEC LXY 1627 case 0x2D: // DEC LXY
1628 data = BYTE( ixy - 1 ); 1628 data = BYTE( ixy - 1 );
1629 ixy = (ixy & 0xFF00) + data; 1629 ixy = (ixy & 0xFF00) + data;
1630 dec_xy_common: 1630 dec_xy_common:
1631 if ( opcode == 0xDD ) 1631 if ( opcode == 0xDD )
1632 { 1632 {
1633 ix = ixy; 1633 ix = ixy;
1634 goto dec_set_flags; 1634 goto dec_set_flags;
1635 } 1635 }
1636 iy = ixy; 1636 iy = ixy;
1637 goto dec_set_flags; 1637 goto dec_set_flags;
1638 1638
1639 // PUSH/POP 1639 // PUSH/POP
1640 case 0xE5: // PUSH IXY 1640 case 0xE5: // PUSH IXY
1641 data = ixy; 1641 data = ixy;
1642 goto push_data; 1642 goto push_data;
1643 1643
1644 case 0xE1:{// POP IXY 1644 case 0xE1:{// POP IXY
1645 ixy = READ_WORD( sp ); 1645 ixy = READ_WORD( sp );
1646 sp = WORD( sp + 2 ); 1646 sp = WORD( sp + 2 );
1647 goto set_ixy; 1647 goto set_ixy;
1648 } 1648 }
1649 1649
1650 // Misc 1650 // Misc
1651 1651
1652 case 0xE9: // JP (IXY) 1652 case 0xE9: // JP (IXY)
1653 pc = ixy; 1653 pc = ixy;
1654 goto loop; 1654 goto loop;
1655 1655
1656 case 0xE3:{// EX (SP),IXY 1656 case 0xE3:{// EX (SP),IXY
1657 int temp = READ_WORD( sp ); 1657 int temp = READ_WORD( sp );
1658 WRITE_WORD( sp, ixy ); 1658 WRITE_WORD( sp, ixy );
1659 ixy = temp; 1659 ixy = temp;
1660 goto set_ixy; 1660 goto set_ixy;
1661 } 1661 }
1662 1662
1663 default: 1663 default:
1664 dprintf( "Unnecessary DD/FD prefix encountered\n" ); 1664 dprintf( "Unnecessary DD/FD prefix encountered\n" );
1665 warning = true; 1665 warning = true;
1666 pc--; 1666 pc--;
1667 goto loop; 1667 goto loop;
1668 } 1668 }
1669 assert( false ); 1669 assert( false );
1670 } 1670 }
1671 1671
1672 } 1672 }
1673 dprintf( "Unhandled main opcode: $%02X\n", opcode ); 1673 dprintf( "Unhandled main opcode: $%02X\n", opcode );
1674 assert( false ); 1674 assert( false );
1675 1675
1676#ifdef IDLE_ADDR 1676#ifdef IDLE_ADDR
1677hit_idle_addr: 1677hit_idle_addr:
1678 s_time -= 11; 1678 s_time -= 11;
1679 goto out_of_time; 1679 goto out_of_time;
1680#endif 1680#endif
1681halt: 1681halt:
1682 s_time &= 3; // increment by multiple of 4 1682 s_time &= 3; // increment by multiple of 4
1683out_of_time: 1683out_of_time:
1684 pc--; 1684 pc--;
1685 1685
1686 r.b.flags = flags; 1686 r.b.flags = flags;
1687 R.ix = ix; 1687 R.ix = ix;
1688 R.iy = iy; 1688 R.iy = iy;
1689 R.sp = sp; 1689 R.sp = sp;
1690 R.pc = pc; 1690 R.pc = pc;
1691 R.b = r.b; 1691 R.b = r.b;
1692 1692
1693 cpu->cpu_state_.base = s.base; 1693 cpu->cpu_state_.base = s.base;
1694 cpu->cpu_state_.time = s_time; 1694 cpu->cpu_state_.time = s_time;
1695 cpu->cpu_state = &cpu->cpu_state_; 1695 cpu->cpu_state = &cpu->cpu_state_;
1696} 1696}