/src/vlc/contrib/contrib-build/game-music-emu/gme/Gb_Cpu.cpp
Line | Count | Source |
1 | | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/ |
2 | | |
3 | | #include "Gb_Cpu.h" |
4 | | |
5 | | #include <string.h> |
6 | | |
7 | | //#include "gb_cpu_log.h" |
8 | | |
9 | | /* Copyright (C) 2003-2006 Shay Green. This module is free software; you |
10 | | can redistribute it and/or modify it under the terms of the GNU Lesser |
11 | | General Public License as published by the Free Software Foundation; either |
12 | | version 2.1 of the License, or (at your option) any later version. This |
13 | | module is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
15 | | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
16 | | details. You should have received a copy of the GNU Lesser General Public |
17 | | License along with this module; if not, write to the Free Software Foundation, |
18 | | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
19 | | |
20 | | #include "gb_cpu_io.h" |
21 | | |
22 | | #include "blargg_source.h" |
23 | | |
24 | | // Common instructions: |
25 | | // |
26 | | // 365880 FA LD A,IND16 |
27 | | // 355863 20 JR NZ |
28 | | // 313655 21 LD HL,IMM |
29 | | // 274580 28 JR Z |
30 | | // 252878 FE CMP IMM |
31 | | // 230541 7E LD A,(HL) |
32 | | // 226209 2A LD A,(HL+) |
33 | | // 217467 CD CALL |
34 | | // 212034 C9 RET |
35 | | // 208376 CB CB prefix |
36 | | // |
37 | | // 27486 CB 7E BIT 7,(HL) |
38 | | // 15925 CB 76 BIT 6,(HL) |
39 | | // 13035 CB 19 RR C |
40 | | // 11557 CB 7F BIT 7,A |
41 | | // 10898 CB 37 SWAP A |
42 | | // 10208 CB 66 BIT 4,(HL) |
43 | | |
44 | | #if BLARGG_NONPORTABLE |
45 | | #define PAGE_OFFSET( addr ) (addr) |
46 | | #else |
47 | 20.6G | #define PAGE_OFFSET( addr ) ((addr) & (page_size - 1)) |
48 | | #endif |
49 | | |
50 | | inline void Gb_Cpu::set_code_page( int i, uint8_t* p ) |
51 | 20.0M | { |
52 | 20.0M | state->code_map [i] = p - PAGE_OFFSET( i * (blargg_long) page_size ); |
53 | 20.0M | } |
54 | | |
55 | | void Gb_Cpu::reset( void* unmapped ) |
56 | 1.46k | { |
57 | 1.46k | check( state == &state_ ); |
58 | 1.46k | state = &state_; |
59 | | |
60 | 1.46k | state_.remain = 0; |
61 | | |
62 | 14.6k | for ( int i = 0; i < page_count + 1; i++ ) |
63 | 13.1k | set_code_page( i, (uint8_t*) unmapped ); |
64 | | |
65 | 1.46k | memset( &r, 0, sizeof r ); |
66 | | //interrupts_enabled = false; |
67 | | |
68 | 1.46k | blargg_verify_byte_order(); |
69 | 1.46k | } |
70 | | |
71 | | void Gb_Cpu::map_code( gb_addr_t start, unsigned size, void* data ) |
72 | 10.0M | { |
73 | | // address range must begin and end on page boundaries |
74 | 10.0M | require( start % page_size == 0 ); |
75 | 10.0M | require( size % page_size == 0 ); |
76 | | |
77 | 10.0M | unsigned first_page = start / page_size; |
78 | 30.0M | for ( unsigned i = size / page_size; i--; ) |
79 | 20.0M | set_code_page( first_page + i, (uint8_t*) data + i * page_size ); |
80 | 10.0M | } |
81 | | |
82 | 27.5M | #define READ( addr ) CPU_READ( this, (addr), s.remain ) |
83 | 821M | #define WRITE( addr, data ) {CPU_WRITE( this, (addr), (data), s.remain );} |
84 | 45.7M | #define READ_FAST( addr, out ) CPU_READ_FAST( this, (addr), s.remain, out ) |
85 | 45.7M | #define READ_PROG( addr ) (s.code_map [(addr) >> page_shift] [PAGE_OFFSET( addr )]) |
86 | | |
87 | | |
88 | | static unsigned const z_flag = 0x80; |
89 | | static unsigned const n_flag = 0x40; |
90 | | static unsigned const h_flag = 0x20; |
91 | | static unsigned const c_flag = 0x10; |
92 | | |
93 | | bool Gb_Cpu::run( blargg_long cycle_count ) |
94 | 47.0M | { |
95 | 47.0M | state_.remain = blargg_ulong (cycle_count + clocks_per_instr) / clocks_per_instr; |
96 | 47.0M | state_t s; |
97 | 47.0M | this->state = &s; |
98 | 47.0M | memcpy( &s, &this->state_, sizeof s ); |
99 | | |
100 | | #if BLARGG_BIG_ENDIAN |
101 | | #define R8( n ) (r8_ [n]) |
102 | | #elif BLARGG_LITTLE_ENDIAN |
103 | 2.73G | #define R8( n ) (r8_ [(n) ^ 1]) |
104 | | #else |
105 | | #error "Byte order of CPU must be known" |
106 | | #endif |
107 | | |
108 | 47.0M | union { |
109 | 47.0M | core_regs_t rg; // individual registers |
110 | | |
111 | 47.0M | struct { |
112 | 47.0M | uint16_t bc, de, hl, unused; // pairs |
113 | 47.0M | } rp; |
114 | | |
115 | 47.0M | uint8_t r8_ [8]; // indexed registers (use R8 macro due to endian dependence) |
116 | 47.0M | uint16_t r16 [4]; // indexed pairs |
117 | 47.0M | }; |
118 | 47.0M | static_assert( sizeof rg == 8 && sizeof rp == 8, "Unhandled word size" ); |
119 | | |
120 | 47.0M | rg = r; |
121 | 47.0M | unsigned pc = r.pc; |
122 | 47.0M | unsigned sp = r.sp; |
123 | 47.0M | unsigned flags = r.flags; |
124 | | |
125 | 20.6G | loop: |
126 | | |
127 | 20.6G | check( (unsigned long) pc < 0x10000 ); |
128 | 20.6G | check( (unsigned long) sp < 0x10000 ); |
129 | 20.6G | check( (flags & ~0xF0) == 0 ); |
130 | | |
131 | 20.6G | uint8_t const* instr = s.code_map [pc >> page_shift]; |
132 | 20.6G | unsigned op; |
133 | | |
134 | | // TODO: eliminate this special case |
135 | | #if BLARGG_NONPORTABLE |
136 | | op = instr [pc]; |
137 | | pc++; |
138 | | instr += pc; |
139 | | #else |
140 | 20.6G | instr += PAGE_OFFSET( pc ); |
141 | 20.6G | op = *instr++; |
142 | 20.6G | pc++; |
143 | 20.6G | #endif |
144 | | |
145 | 20.6G | #define GET_ADDR() GET_LE16( instr ) |
146 | | |
147 | 20.6G | if ( !--s.remain ) |
148 | 392k | goto stop; |
149 | | |
150 | 20.6G | unsigned data; |
151 | 20.6G | data = *instr; |
152 | | |
153 | | #ifdef GB_CPU_LOG_H |
154 | | gb_cpu_log( "new", pc - 1, op, data, instr [1] ); |
155 | | #endif |
156 | | |
157 | 20.6G | switch ( op ) |
158 | 20.6G | { |
159 | | |
160 | | // TODO: more efficient way to handle negative branch that wraps PC around |
161 | 30.6M | #define BRANCH( cond )\ |
162 | 30.6M | {\ |
163 | 30.6M | pc++;\ |
164 | 30.6M | int offset = (int8_t) data;\ |
165 | 41.8M | if ( !(cond) ) goto loop;\ |
166 | 30.6M | pc = uint16_t (pc + offset);\ |
167 | 30.6M | goto loop;\ |
168 | 30.6M | } |
169 | | |
170 | | // Most Common |
171 | | |
172 | 12.7M | case 0x20: // JR NZ |
173 | 12.7M | BRANCH( !(flags & z_flag) ) |
174 | | |
175 | 529k | case 0x21: // LD HL,IMM (common) |
176 | 529k | rp.hl = GET_ADDR(); |
177 | 529k | pc += 2; |
178 | 529k | goto loop; |
179 | | |
180 | 310k | case 0x28: // JR Z |
181 | 310k | BRANCH( flags & z_flag ) |
182 | | |
183 | 0 | { |
184 | 0 | unsigned temp; |
185 | 666k | case 0xF0: // LD A,(0xFF00+imm) |
186 | 666k | temp = data | 0xFF00; |
187 | 666k | pc++; |
188 | 666k | goto ld_a_ind_comm; |
189 | | |
190 | 93.6k | case 0xF2: // LD A,(0xFF00+C) |
191 | 93.6k | temp = rg.c | 0xFF00; |
192 | 93.6k | goto ld_a_ind_comm; |
193 | | |
194 | 730k | case 0x0A: // LD A,(BC) |
195 | 730k | temp = rp.bc; |
196 | 730k | goto ld_a_ind_comm; |
197 | | |
198 | 6.30M | case 0x3A: // LD A,(HL-) |
199 | 6.30M | temp = rp.hl; |
200 | 6.30M | rp.hl = temp - 1; |
201 | 6.30M | goto ld_a_ind_comm; |
202 | | |
203 | 13.1M | case 0x1A: // LD A,(DE) |
204 | 13.1M | temp = rp.de; |
205 | 13.1M | goto ld_a_ind_comm; |
206 | | |
207 | 101k | case 0x2A: // LD A,(HL+) (common) |
208 | 101k | temp = rp.hl; |
209 | 101k | rp.hl = temp + 1; |
210 | 101k | goto ld_a_ind_comm; |
211 | | |
212 | 1.71M | case 0xFA: // LD A,IND16 (common) |
213 | 1.71M | temp = GET_ADDR(); |
214 | 1.71M | pc += 2; |
215 | 22.7M | ld_a_ind_comm: |
216 | 22.7M | READ_FAST( temp, rg.a ); |
217 | 22.7M | goto loop; |
218 | 1.71M | } |
219 | | |
220 | 61.2k | case 0xBE: // CMP (HL) |
221 | 61.2k | data = READ( rp.hl ); |
222 | 61.2k | goto cmp_comm; |
223 | | |
224 | 733k | case 0xB8: // CMP B |
225 | 752k | case 0xB9: // CMP C |
226 | 4.30M | case 0xBA: // CMP D |
227 | 5.43M | case 0xBB: // CMP E |
228 | 5.45M | case 0xBC: // CMP H |
229 | 17.8M | case 0xBD: // CMP L |
230 | 17.8M | data = R8( op & 7 ); |
231 | 17.8M | goto cmp_comm; |
232 | | |
233 | 16.8M | case 0xFE: // CMP IMM |
234 | 16.8M | pc++; |
235 | 34.7M | cmp_comm: |
236 | 34.7M | op = rg.a; |
237 | 34.7M | data = op - data; |
238 | 110M | sub_set_flags: |
239 | 110M | flags = ((op & 15) - (data & 15)) & h_flag; |
240 | 110M | flags |= (data >> 4) & c_flag; |
241 | 110M | flags |= n_flag; |
242 | 110M | if ( data & 0xFF ) |
243 | 67.9M | goto loop; |
244 | 42.9M | flags |= z_flag; |
245 | 42.9M | goto loop; |
246 | | |
247 | 2.77M | case 0x46: // LD B,(HL) |
248 | 10.7M | case 0x4E: // LD C,(HL) |
249 | 16.0M | case 0x56: // LD D,(HL) |
250 | 16.0M | case 0x5E: // LD E,(HL) |
251 | 19.4M | case 0x66: // LD H,(HL) |
252 | 21.7M | case 0x6E: // LD L,(HL) |
253 | 22.9M | case 0x7E:{// LD A,(HL) |
254 | 22.9M | unsigned addr = rp.hl; |
255 | 22.9M | READ_FAST( addr, R8( (op >> 3) & 7 ) ); |
256 | 22.9M | goto loop; |
257 | 21.7M | } |
258 | | |
259 | 213k | case 0xC4: // CNZ (next-most-common) |
260 | 213k | pc += 2; |
261 | 213k | if ( flags & z_flag ) |
262 | 188k | goto loop; |
263 | 803k | call: |
264 | 803k | pc -= 2; // FALLTHRU |
265 | 901k | case 0xCD: // CALL (most-common) |
266 | 901k | data = pc + 2; |
267 | 901k | pc = GET_ADDR(); |
268 | 396M | push: |
269 | 396M | sp = (sp - 1) & 0xFFFF; |
270 | 396M | WRITE( sp, data >> 8 ); |
271 | 396M | sp = (sp - 1) & 0xFFFF; |
272 | 396M | WRITE( sp, data & 0xFF ); |
273 | 396M | goto loop; |
274 | | |
275 | 128k | case 0xC8: // RNZ (next-most-common) |
276 | 128k | if ( !(flags & z_flag) ) |
277 | 123k | goto loop; |
278 | | // FALLTHRU |
279 | 43.8k | case 0xC9: // RET (most common) |
280 | 2.25M | ret: |
281 | 2.25M | pc = READ( sp ); |
282 | 2.25M | pc += 0x100 * READ( sp + 1 ); |
283 | 2.25M | sp = (sp + 2) & 0xFFFF; |
284 | 2.25M | goto loop; |
285 | | |
286 | 17.8G | case 0x00: // NOP |
287 | 17.8G | case 0x40: // LD B,B |
288 | 17.8G | case 0x49: // LD C,C |
289 | 17.8G | case 0x52: // LD D,D |
290 | 17.8G | case 0x5B: // LD E,E |
291 | 17.8G | case 0x64: // LD H,H |
292 | 17.8G | case 0x6D: // LD L,L |
293 | 17.8G | case 0x7F: // LD A,A |
294 | 17.8G | goto loop; |
295 | | |
296 | | // CB Instructions |
297 | | |
298 | 466k | case 0xCB: |
299 | 466k | pc++; |
300 | | // now data is the opcode |
301 | 466k | switch ( data ) { |
302 | | |
303 | 0 | { |
304 | 0 | int temp; |
305 | 0 | case 0x46: // BIT b,(HL) |
306 | 0 | case 0x4E: |
307 | 0 | case 0x56: |
308 | 0 | case 0x5E: |
309 | 0 | case 0x66: |
310 | 0 | case 0x6E: |
311 | 0 | case 0x76: |
312 | 0 | case 0x7E: |
313 | 0 | { |
314 | 0 | unsigned addr = rp.hl; |
315 | 0 | READ_FAST( addr, temp ); |
316 | 0 | goto bit_comm; |
317 | 0 | } |
318 | | |
319 | 0 | case 0x40: case 0x41: case 0x42: case 0x43: // BIT b,r |
320 | 0 | case 0x44: case 0x45: case 0x47: case 0x48: |
321 | 0 | case 0x49: case 0x4A: case 0x4B: case 0x4C: |
322 | 0 | case 0x4D: case 0x4F: case 0x50: case 0x51: |
323 | 0 | case 0x52: case 0x53: case 0x54: case 0x55: |
324 | 0 | case 0x57: case 0x58: case 0x59: case 0x5A: |
325 | 0 | case 0x5B: case 0x5C: case 0x5D: case 0x5F: |
326 | 7.33k | case 0x60: case 0x61: case 0x62: case 0x63: |
327 | 7.33k | case 0x64: case 0x65: case 0x67: case 0x68: |
328 | 7.33k | case 0x69: case 0x6A: case 0x6B: case 0x6C: |
329 | 7.33k | case 0x6D: case 0x6F: case 0x70: case 0x71: |
330 | 7.33k | case 0x72: case 0x73: case 0x74: case 0x75: |
331 | 7.33k | case 0x77: case 0x78: case 0x79: case 0x7A: |
332 | 7.33k | case 0x7B: case 0x7C: case 0x7D: case 0x7F: |
333 | 7.33k | temp = R8( data & 7 ); |
334 | 7.33k | bit_comm: |
335 | 7.33k | int bit = (~data >> 3) & 7; |
336 | 7.33k | flags &= ~n_flag; |
337 | 7.33k | flags |= h_flag | z_flag; |
338 | 7.33k | flags ^= (temp << bit) & z_flag; |
339 | 7.33k | goto loop; |
340 | 7.33k | } |
341 | | |
342 | 0 | case 0x86: // RES b,(HL) |
343 | 0 | case 0x8E: |
344 | 0 | case 0x96: |
345 | 0 | case 0x9E: |
346 | 0 | case 0xA6: |
347 | 0 | case 0xAE: |
348 | 0 | case 0xB6: |
349 | 0 | case 0xBE: |
350 | 0 | case 0xC6: // SET b,(HL) |
351 | 0 | case 0xCE: |
352 | 0 | case 0xD6: |
353 | 0 | case 0xDE: |
354 | 0 | case 0xE6: |
355 | 0 | case 0xEE: |
356 | 0 | case 0xF6: |
357 | 0 | case 0xFE: { |
358 | 0 | int temp = READ( rp.hl ); |
359 | 0 | int bit = 1 << ((data >> 3) & 7); |
360 | 0 | temp &= ~bit; |
361 | 0 | if ( !(data & 0x40) ) |
362 | 0 | bit = 0; |
363 | 0 | WRITE( rp.hl, temp | bit ); |
364 | 0 | goto loop; |
365 | 0 | } |
366 | | |
367 | 0 | case 0xC0: case 0xC1: case 0xC2: case 0xC3: // SET b,r |
368 | 0 | case 0xC4: case 0xC5: case 0xC7: case 0xC8: |
369 | 12.1k | case 0xC9: case 0xCA: case 0xCB: case 0xCC: |
370 | 12.1k | case 0xCD: case 0xCF: case 0xD0: case 0xD1: |
371 | 12.1k | case 0xD2: case 0xD3: case 0xD4: case 0xD5: |
372 | 12.1k | case 0xD7: case 0xD8: case 0xD9: case 0xDA: |
373 | 12.1k | case 0xDB: case 0xDC: case 0xDD: case 0xDF: |
374 | 12.1k | case 0xE0: case 0xE1: case 0xE2: case 0xE3: |
375 | 12.1k | case 0xE4: case 0xE5: case 0xE7: case 0xE8: |
376 | 12.1k | case 0xE9: case 0xEA: case 0xEB: case 0xEC: |
377 | 12.1k | case 0xED: case 0xEF: case 0xF0: case 0xF1: |
378 | 12.1k | case 0xF2: case 0xF3: case 0xF4: case 0xF5: |
379 | 12.6k | case 0xF7: case 0xF8: case 0xF9: case 0xFA: |
380 | 58.3k | case 0xFB: case 0xFC: case 0xFD: case 0xFF: |
381 | 58.3k | R8( data & 7 ) |= 1 << ((data >> 3) & 7); |
382 | 58.3k | goto loop; |
383 | | |
384 | 0 | case 0x80: case 0x81: case 0x82: case 0x83: // RES b,r |
385 | 0 | case 0x84: case 0x85: case 0x87: case 0x88: |
386 | 0 | case 0x89: case 0x8A: case 0x8B: case 0x8C: |
387 | 262k | case 0x8D: case 0x8F: case 0x90: case 0x91: |
388 | 262k | case 0x92: case 0x93: case 0x94: case 0x95: |
389 | 262k | case 0x97: case 0x98: case 0x99: case 0x9A: |
390 | 262k | case 0x9B: case 0x9C: case 0x9D: case 0x9F: |
391 | 293k | case 0xA0: case 0xA1: case 0xA2: case 0xA3: |
392 | 293k | case 0xA4: case 0xA5: case 0xA7: case 0xA8: |
393 | 293k | case 0xA9: case 0xAA: case 0xAB: case 0xAC: |
394 | 293k | case 0xAD: case 0xAF: case 0xB0: case 0xB1: |
395 | 293k | case 0xB2: case 0xB3: case 0xB4: case 0xB5: |
396 | 293k | case 0xB7: case 0xB8: case 0xB9: case 0xBA: |
397 | 293k | case 0xBB: case 0xBC: case 0xBD: case 0xBF: |
398 | 293k | R8( data & 7 ) &= ~(1 << ((data >> 3) & 7)); |
399 | 293k | goto loop; |
400 | | |
401 | 0 | { |
402 | 0 | int temp; |
403 | 0 | case 0x36: // SWAP (HL) |
404 | 0 | temp = READ( rp.hl ); |
405 | 0 | goto swap_comm; |
406 | | |
407 | 0 | case 0x30: // SWAP B |
408 | 0 | case 0x31: // SWAP C |
409 | 0 | case 0x32: // SWAP D |
410 | 0 | case 0x33: // SWAP E |
411 | 0 | case 0x34: // SWAP H |
412 | 0 | case 0x35: // SWAP L |
413 | 0 | case 0x37: // SWAP A |
414 | 0 | temp = R8( data & 7 ); |
415 | 0 | swap_comm: |
416 | 0 | op = (temp >> 4) | (temp << 4); |
417 | 0 | flags = 0; |
418 | 0 | goto shift_comm; |
419 | 0 | } |
420 | | |
421 | | // Shift/Rotate |
422 | | |
423 | 0 | case 0x06: // RLC (HL) |
424 | 0 | case 0x16: // RL (HL) |
425 | 0 | case 0x26: // SLA (HL) |
426 | 0 | op = READ( rp.hl ); |
427 | 0 | goto rl_comm; |
428 | | |
429 | 0 | case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x27: // SLA A |
430 | 107k | case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x07: // RLC A |
431 | 107k | case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x17: // RL A |
432 | 107k | op = R8( data & 7 ); |
433 | 107k | goto rl_comm; |
434 | | |
435 | 0 | case 0x3E: // SRL (HL) |
436 | 0 | data += 0x10; /* fallthrough */ // bump up to 0x4n to avoid preserving sign bit |
437 | 0 | case 0x1E: // RR (HL) |
438 | 0 | case 0x0E: // RRC (HL) |
439 | 0 | case 0x2E: // SRA (HL) |
440 | 0 | op = READ( rp.hl ); |
441 | 0 | goto rr_comm; |
442 | | |
443 | 0 | case 0x38: case 0x39: case 0x3A: case 0x3B: case 0x3C: case 0x3D: case 0x3F: // SRL A |
444 | 0 | data += 0x10; /* fallthrough */ // bump up to 0x4n |
445 | 0 | case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1F: // RR A |
446 | 0 | case 0x08: case 0x09: case 0x0A: case 0x0B: case 0x0C: case 0x0D: case 0x0F: // RRC A |
447 | 227 | case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2F: // SRA A |
448 | 227 | op = R8( data & 7 ); |
449 | 227 | goto rr_comm; |
450 | | |
451 | 466k | } // CB op |
452 | 466k | assert( false ); // unhandled CB op |
453 | | // fallthrough |
454 | |
|
455 | 3.32M | case 0x07: // RLCA |
456 | 5.02M | case 0x17: // RLA |
457 | 5.02M | data = op; |
458 | 5.02M | op = rg.a; |
459 | 5.12M | rl_comm: |
460 | 5.12M | op <<= 1; |
461 | 5.12M | op |= ((data & flags) >> 4) & 1; // RL and carry is set |
462 | 5.12M | flags = (op >> 4) & c_flag; // C = bit shifted out |
463 | 5.12M | if ( data < 0x10 ) // RLC |
464 | 3.43M | op |= op >> 8; |
465 | | // SLA doesn't fill lower bit |
466 | 5.12M | goto shift_comm; |
467 | | |
468 | 679k | case 0x0F: // RRCA |
469 | 867k | case 0x1F: // RRA |
470 | 867k | data = op; |
471 | 867k | op = rg.a; |
472 | 868k | rr_comm: |
473 | 868k | op |= (data & flags) << 4; // RR and carry is set |
474 | 868k | flags = (op << 4) & c_flag; // C = bit shifted out |
475 | 868k | if ( data < 0x10 ) // RRC |
476 | 679k | op |= op << 8; |
477 | 868k | op >>= 1; |
478 | 868k | if ( data & 0x20 ) // SRA propagates sign bit |
479 | 227 | op |= (op << 1) & 0x80; |
480 | 5.99M | shift_comm: |
481 | 5.99M | data &= 7; |
482 | 5.99M | if ( !(op & 0xFF) ) |
483 | 4.42M | flags |= z_flag; |
484 | 5.99M | if ( data == 6 ) |
485 | 0 | goto write_hl_op_ff; |
486 | 5.99M | R8( data ) = op; |
487 | 5.99M | goto loop; |
488 | | |
489 | | // Load |
490 | | |
491 | 1.23M | case 0x70: // LD (HL),B |
492 | 1.26M | case 0x71: // LD (HL),C |
493 | 1.79M | case 0x72: // LD (HL),D |
494 | 3.81M | case 0x73: // LD (HL),E |
495 | 4.41M | case 0x74: // LD (HL),H |
496 | 4.65M | case 0x75: // LD (HL),L |
497 | 4.88M | case 0x77: // LD (HL),A |
498 | 4.88M | op = R8( op & 7 ); |
499 | 4.88M | write_hl_op_ff: |
500 | 4.88M | WRITE( rp.hl, op & 0xFF ); |
501 | 4.88M | goto loop; |
502 | | |
503 | 56.5M | case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x47: // LD r,r |
504 | 76.3M | case 0x48: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4F: |
505 | 120M | case 0x50: case 0x51: case 0x53: case 0x54: case 0x55: case 0x57: |
506 | 133M | case 0x58: case 0x59: case 0x5A: case 0x5C: case 0x5D: case 0x5F: |
507 | 1.03G | case 0x60: case 0x61: case 0x62: case 0x63: case 0x65: case 0x67: |
508 | 1.04G | case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6F: |
509 | 1.04G | case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: |
510 | 1.04G | R8( (op >> 3) & 7 ) = R8( op & 7 ); |
511 | 1.04G | goto loop; |
512 | | |
513 | 6.56M | case 0x08: // LD IND16,SP |
514 | 6.56M | data = GET_ADDR(); |
515 | 6.56M | pc += 2; |
516 | 6.56M | WRITE( data, sp&0xFF ); |
517 | 6.56M | data++; |
518 | 6.56M | WRITE( data, sp >> 8 ); |
519 | 6.56M | goto loop; |
520 | | |
521 | 10.2M | case 0xF9: // LD SP,HL |
522 | 10.2M | sp = rp.hl; |
523 | 10.2M | goto loop; |
524 | | |
525 | 3.65M | case 0x31: // LD SP,IMM |
526 | 3.65M | sp = GET_ADDR(); |
527 | 3.65M | pc += 2; |
528 | 3.65M | goto loop; |
529 | | |
530 | 29.2M | case 0x01: // LD BC,IMM |
531 | 29.5M | case 0x11: // LD DE,IMM |
532 | 29.5M | r16 [op >> 4] = GET_ADDR(); |
533 | 29.5M | pc += 2; |
534 | 29.5M | goto loop; |
535 | | |
536 | 0 | { |
537 | 0 | unsigned temp; |
538 | 590k | case 0xE0: // LD (0xFF00+imm),A |
539 | 590k | temp = data | 0xFF00; |
540 | 590k | pc++; |
541 | 590k | goto write_data_rg_a; |
542 | | |
543 | 898k | case 0xE2: // LD (0xFF00+C),A |
544 | 898k | temp = rg.c | 0xFF00; |
545 | 898k | goto write_data_rg_a; |
546 | | |
547 | 732k | case 0x32: // LD (HL-),A |
548 | 732k | temp = rp.hl; |
549 | 732k | rp.hl = temp - 1; |
550 | 732k | goto write_data_rg_a; |
551 | | |
552 | 4.17M | case 0x02: // LD (BC),A |
553 | 4.17M | temp = rp.bc; |
554 | 4.17M | goto write_data_rg_a; |
555 | | |
556 | 170k | case 0x12: // LD (DE),A |
557 | 170k | temp = rp.de; |
558 | 170k | goto write_data_rg_a; |
559 | | |
560 | 391k | case 0x22: // LD (HL+),A |
561 | 391k | temp = rp.hl; |
562 | 391k | rp.hl = temp + 1; |
563 | 391k | goto write_data_rg_a; |
564 | | |
565 | 210k | case 0xEA: // LD IND16,A (common) |
566 | 210k | temp = GET_ADDR(); |
567 | 210k | pc += 2; |
568 | 7.16M | write_data_rg_a: |
569 | 7.16M | WRITE( temp, rg.a ); |
570 | 7.16M | goto loop; |
571 | 210k | } |
572 | | |
573 | 7.34M | case 0x06: // LD B,IMM |
574 | 7.34M | rg.b = data; |
575 | 7.34M | pc++; |
576 | 7.34M | goto loop; |
577 | | |
578 | 126k | case 0x0E: // LD C,IMM |
579 | 126k | rg.c = data; |
580 | 126k | pc++; |
581 | 126k | goto loop; |
582 | | |
583 | 8.10k | case 0x16: // LD D,IMM |
584 | 8.10k | rg.d = data; |
585 | 8.10k | pc++; |
586 | 8.10k | goto loop; |
587 | | |
588 | 170k | case 0x1E: // LD E,IMM |
589 | 170k | rg.e = data; |
590 | 170k | pc++; |
591 | 170k | goto loop; |
592 | | |
593 | 482k | case 0x26: // LD H,IMM |
594 | 482k | rg.h = data; |
595 | 482k | pc++; |
596 | 482k | goto loop; |
597 | | |
598 | 1.02M | case 0x2E: // LD L,IMM |
599 | 1.02M | rg.l = data; |
600 | 1.02M | pc++; |
601 | 1.02M | goto loop; |
602 | | |
603 | 469k | case 0x36: // LD (HL),IMM |
604 | 469k | WRITE( rp.hl, data ); |
605 | 469k | pc++; |
606 | 469k | goto loop; |
607 | | |
608 | 517k | case 0x3E: // LD A,IMM |
609 | 517k | rg.a = data; |
610 | 517k | pc++; |
611 | 517k | goto loop; |
612 | | |
613 | | // Increment/Decrement |
614 | | |
615 | 2.11M | case 0x03: // INC BC |
616 | 2.20M | case 0x13: // INC DE |
617 | 2.67M | case 0x23: // INC HL |
618 | 2.67M | r16 [op >> 4]++; |
619 | 2.67M | goto loop; |
620 | | |
621 | 982k | case 0x33: // INC SP |
622 | 982k | sp = (sp + 1) & 0xFFFF; |
623 | 982k | goto loop; |
624 | | |
625 | 4.73k | case 0x0B: // DEC BC |
626 | 1.85M | case 0x1B: // DEC DE |
627 | 3.41M | case 0x2B: // DEC HL |
628 | 3.41M | r16 [op >> 4]--; |
629 | 3.41M | goto loop; |
630 | | |
631 | 1.20M | case 0x3B: // DEC SP |
632 | 1.20M | sp = (sp - 1) & 0xFFFF; |
633 | 1.20M | goto loop; |
634 | | |
635 | 541k | case 0x34: // INC (HL) |
636 | 541k | op = rp.hl; |
637 | 541k | data = READ( op ); |
638 | 541k | data++; |
639 | 541k | WRITE( op, data & 0xFF ); |
640 | 541k | goto inc_comm; |
641 | | |
642 | 49.6M | case 0x04: // INC B |
643 | 53.3M | case 0x0C: // INC C (common) |
644 | 56.8M | case 0x14: // INC D |
645 | 75.2M | case 0x1C: // INC E |
646 | 75.3M | case 0x24: // INC H |
647 | 92.0M | case 0x2C: // INC L |
648 | 92.7M | case 0x3C: // INC A |
649 | 92.7M | op = (op >> 3) & 7; |
650 | 92.7M | R8( op ) = data = R8( op ) + 1; |
651 | 93.2M | inc_comm: |
652 | 93.2M | flags = (flags & c_flag) | (((data & 15) - 1) & h_flag) | ((data >> 1) & z_flag); |
653 | 93.2M | goto loop; |
654 | | |
655 | 1.57M | case 0x35: // DEC (HL) |
656 | 1.57M | op = rp.hl; |
657 | 1.57M | data = READ( op ); |
658 | 1.57M | data--; |
659 | 1.57M | WRITE( op, data & 0xFF ); |
660 | 1.57M | goto dec_comm; |
661 | | |
662 | 79.7M | case 0x05: // DEC B |
663 | 81.6M | case 0x0D: // DEC C |
664 | 81.7M | case 0x15: // DEC D |
665 | 83.1M | case 0x1D: // DEC E |
666 | 83.6M | case 0x25: // DEC H |
667 | 88.6M | case 0x2D: // DEC L |
668 | 89.4M | case 0x3D: // DEC A |
669 | 89.4M | op = (op >> 3) & 7; |
670 | 89.4M | data = R8( op ) - 1; |
671 | 89.4M | R8( op ) = data; |
672 | 91.0M | dec_comm: |
673 | 91.0M | flags = (flags & c_flag) | n_flag | (((data & 15) + 0x31) & h_flag); |
674 | 91.0M | if ( data & 0xFF ) |
675 | 90.5M | goto loop; |
676 | 464k | flags |= z_flag; |
677 | 464k | goto loop; |
678 | | |
679 | | // Add 16-bit |
680 | | |
681 | 0 | { |
682 | 0 | blargg_ulong temp; // need more than 16 bits for carry |
683 | 0 | unsigned prev; |
684 | |
|
685 | 522M | case 0xF8: // LD HL,SP+imm |
686 | 522M | temp = int8_t (data); // sign-extend to 16 bits |
687 | 522M | pc++; |
688 | 522M | flags = 0; |
689 | 522M | temp += sp; |
690 | 522M | prev = sp; |
691 | 522M | goto add_16_hl; |
692 | | |
693 | 764k | case 0xE8: // ADD SP,IMM |
694 | 764k | temp = int8_t (data); // sign-extend to 16 bits |
695 | 764k | pc++; |
696 | 764k | flags = 0; |
697 | 764k | temp += sp; |
698 | 764k | prev = sp; |
699 | 764k | sp = temp & 0xFFFF; |
700 | 764k | goto add_16_comm; |
701 | | |
702 | 827k | case 0x39: // ADD HL,SP |
703 | 827k | temp = sp; |
704 | 827k | goto add_hl_comm; |
705 | | |
706 | 210k | case 0x09: // ADD HL,BC |
707 | 260k | case 0x19: // ADD HL,DE |
708 | 2.53M | case 0x29: // ADD HL,HL |
709 | 2.53M | temp = r16 [op >> 4]; |
710 | 3.36M | add_hl_comm: |
711 | 3.36M | prev = rp.hl; |
712 | 3.36M | temp += prev; |
713 | 3.36M | flags &= z_flag; |
714 | 526M | add_16_hl: |
715 | 526M | rp.hl = temp; |
716 | 527M | add_16_comm: |
717 | 527M | flags |= (temp >> 12) & c_flag; |
718 | 527M | flags |= (((temp & 0x0FFF) - (prev & 0x0FFF)) >> 7) & h_flag; |
719 | 527M | goto loop; |
720 | 526M | } |
721 | | |
722 | 260k | case 0x86: // ADD (HL) |
723 | 260k | data = READ( rp.hl ); |
724 | 260k | goto add_comm; |
725 | | |
726 | 6.11M | case 0x80: // ADD B |
727 | 25.0M | case 0x81: // ADD C |
728 | 25.0M | case 0x82: // ADD D |
729 | 25.3M | case 0x83: // ADD E |
730 | 25.5M | case 0x84: // ADD H |
731 | 26.2M | case 0x85: // ADD L |
732 | 26.2M | case 0x87: // ADD A |
733 | 26.2M | data = R8( op & 7 ); |
734 | 26.2M | goto add_comm; |
735 | | |
736 | 6.37k | case 0xC6: // ADD IMM |
737 | 6.37k | pc++; |
738 | 126M | add_comm: |
739 | 126M | flags = rg.a; |
740 | 126M | data += flags; |
741 | 126M | flags = ((data & 15) - (flags & 15)) & h_flag; |
742 | 126M | flags |= (data >> 4) & c_flag; |
743 | 126M | rg.a = data; |
744 | 126M | if ( data & 0xFF ) |
745 | 91.7M | goto loop; |
746 | 34.3M | flags |= z_flag; |
747 | 34.3M | goto loop; |
748 | | |
749 | | // Add/Subtract |
750 | | |
751 | 44.1k | case 0x8E: // ADC (HL) |
752 | 44.1k | data = READ( rp.hl ); |
753 | 44.1k | goto adc_comm; |
754 | | |
755 | 1.13M | case 0x88: // ADC B |
756 | 1.23M | case 0x89: // ADC C |
757 | 1.37M | case 0x8A: // ADC D |
758 | 2.20M | case 0x8B: // ADC E |
759 | 8.04M | case 0x8C: // ADC H |
760 | 98.4M | case 0x8D: // ADC L |
761 | 99.3M | case 0x8F: // ADC A |
762 | 99.3M | data = R8( op & 7 ); |
763 | 99.3M | goto adc_comm; |
764 | | |
765 | 171k | case 0xCE: // ADC IMM |
766 | 171k | pc++; |
767 | 99.6M | adc_comm: |
768 | 99.6M | data += (flags >> 4) & 1; |
769 | 99.6M | data &= 0xFF; // to do: does carry get set when sum + carry = 0x100? |
770 | 99.6M | goto add_comm; |
771 | | |
772 | 210k | case 0x96: // SUB (HL) |
773 | 210k | data = READ( rp.hl ); |
774 | 210k | goto sub_comm; |
775 | | |
776 | 3.21M | case 0x90: // SUB B |
777 | 4.40M | case 0x91: // SUB C |
778 | 8.87M | case 0x92: // SUB D |
779 | 8.93M | case 0x93: // SUB E |
780 | 10.4M | case 0x94: // SUB H |
781 | 56.0M | case 0x95: // SUB L |
782 | 56.0M | case 0x97: // SUB A |
783 | 56.0M | data = R8( op & 7 ); |
784 | 56.0M | goto sub_comm; |
785 | | |
786 | 1.42M | case 0xD6: // SUB IMM |
787 | 1.42M | pc++; |
788 | 76.2M | sub_comm: |
789 | 76.2M | op = rg.a; |
790 | 76.2M | data = op - data; |
791 | 76.2M | rg.a = data; |
792 | 76.2M | goto sub_set_flags; |
793 | | |
794 | 3.27M | case 0x9E: // SBC (HL) |
795 | 3.27M | data = READ( rp.hl ); |
796 | 3.27M | goto sbc_comm; |
797 | | |
798 | 298k | case 0x98: // SBC B |
799 | 1.49M | case 0x99: // SBC C |
800 | 1.49M | case 0x9A: // SBC D |
801 | 1.54M | case 0x9B: // SBC E |
802 | 11.4M | case 0x9C: // SBC H |
803 | 11.4M | case 0x9D: // SBC L |
804 | 15.0M | case 0x9F: // SBC A |
805 | 15.0M | data = R8( op & 7 ); |
806 | 15.0M | goto sbc_comm; |
807 | | |
808 | 185k | case 0xDE: // SBC IMM |
809 | 185k | pc++; |
810 | 18.5M | sbc_comm: |
811 | 18.5M | data += (flags >> 4) & 1; |
812 | 18.5M | data &= 0xFF; // to do: does carry get set when sum + carry = 0x100? |
813 | 18.5M | goto sub_comm; |
814 | | |
815 | | // Logical |
816 | | |
817 | 15.2M | case 0xA0: // AND B |
818 | 15.3M | case 0xA1: // AND C |
819 | 15.6M | case 0xA2: // AND D |
820 | 15.7M | case 0xA3: // AND E |
821 | 16.0M | case 0xA4: // AND H |
822 | 16.7M | case 0xA5: // AND L |
823 | 16.7M | data = R8( op & 7 ); |
824 | 16.7M | goto and_comm; |
825 | | |
826 | 1.02M | case 0xA6: // AND (HL) |
827 | 1.02M | data = READ( rp.hl ); |
828 | 1.02M | pc--; // FALLTHRU |
829 | 5.49M | case 0xE6: // AND IMM |
830 | 5.49M | pc++; |
831 | 22.2M | and_comm: |
832 | 22.2M | rg.a &= data; // FALLTHRU |
833 | 22.4M | case 0xA7: // AND A |
834 | 22.4M | flags = h_flag | (((rg.a - 1) >> 1) & z_flag); |
835 | 22.4M | goto loop; |
836 | | |
837 | 22.3k | case 0xB0: // OR B |
838 | 9.00M | case 0xB1: // OR C |
839 | 12.9M | case 0xB2: // OR D |
840 | 13.0M | case 0xB3: // OR E |
841 | 13.1M | case 0xB4: // OR H |
842 | 13.1M | case 0xB5: // OR L |
843 | 13.1M | data = R8( op & 7 ); |
844 | 13.1M | goto or_comm; |
845 | | |
846 | 577k | case 0xB6: // OR (HL) |
847 | 577k | data = READ( rp.hl ); |
848 | 577k | pc--; // FALLTHRU |
849 | 585k | case 0xF6: // OR IMM |
850 | 585k | pc++; |
851 | 13.7M | or_comm: |
852 | 13.7M | rg.a |= data; // FALLTHRU |
853 | 13.7M | case 0xB7: // OR A |
854 | 13.7M | flags = ((rg.a - 1) >> 1) & z_flag; |
855 | 13.7M | goto loop; |
856 | | |
857 | 2.57M | case 0xA8: // XOR B |
858 | 2.59M | case 0xA9: // XOR C |
859 | 9.80M | case 0xAA: // XOR D |
860 | 10.0M | case 0xAB: // XOR E |
861 | 14.0M | case 0xAC: // XOR H |
862 | 15.4M | case 0xAD: // XOR L |
863 | 15.4M | data = R8( op & 7 ); |
864 | 15.4M | goto xor_comm; |
865 | | |
866 | 305k | case 0xAE: // XOR (HL) |
867 | 305k | data = READ( rp.hl ); |
868 | 305k | pc--; // FALLTHRU |
869 | 531k | case 0xEE: // XOR IMM |
870 | 531k | pc++; |
871 | 15.9M | xor_comm: |
872 | 15.9M | data ^= rg.a; |
873 | 15.9M | rg.a = data; |
874 | 15.9M | data--; |
875 | 15.9M | flags = (data >> 1) & z_flag; |
876 | 15.9M | goto loop; |
877 | | |
878 | 5.83k | case 0xAF: // XOR A |
879 | 5.83k | rg.a = 0; |
880 | 5.83k | flags = z_flag; |
881 | 5.83k | goto loop; |
882 | | |
883 | | // Stack |
884 | | |
885 | 1.15M | case 0xF1: // POP AF |
886 | 1.18M | case 0xC1: // POP BC |
887 | 3.20M | case 0xD1: // POP DE |
888 | 7.55M | case 0xE1: // POP HL (common) |
889 | 7.55M | data = READ( sp ); |
890 | 7.55M | r16 [(op >> 4) & 3] = data + 0x100 * READ( sp + 1 ); |
891 | 7.55M | sp = (sp + 2) & 0xFFFF; |
892 | 7.55M | if ( op != 0xF1 ) |
893 | 6.40M | goto loop; |
894 | 1.15M | flags = rg.a & 0xF0; |
895 | 1.15M | rg.a = rg.flags; |
896 | 1.15M | goto loop; |
897 | | |
898 | 26.6k | case 0xC5: // PUSH BC |
899 | 26.6k | data = rp.bc; |
900 | 26.6k | goto push; |
901 | | |
902 | 790k | case 0xD5: // PUSH DE |
903 | 790k | data = rp.de; |
904 | 790k | goto push; |
905 | | |
906 | 524k | case 0xE5: // PUSH HL |
907 | 524k | data = rp.hl; |
908 | 524k | goto push; |
909 | | |
910 | 4.21M | case 0xF5: // PUSH AF |
911 | 4.21M | data = (rg.a << 8) | flags; |
912 | 4.21M | goto push; |
913 | | |
914 | | // Flow control |
915 | | |
916 | 312M | case 0xFF: |
917 | 312M | if ( pc == idle_addr + 1 ) |
918 | 46.1k | goto stop; |
919 | | // FALLTHRU |
920 | 360M | case 0xC7: case 0xCF: case 0xD7: case 0xDF: // RST |
921 | 390M | case 0xE7: case 0xEF: case 0xF7: |
922 | 390M | data = pc; |
923 | 390M | pc = (op & 0x38) + rst_base; |
924 | 390M | goto push; |
925 | | |
926 | 568k | case 0xCC: // CZ |
927 | 568k | pc += 2; |
928 | 568k | if ( flags & z_flag ) |
929 | 118k | goto call; |
930 | 450k | goto loop; |
931 | | |
932 | 610k | case 0xD4: // CNC |
933 | 610k | pc += 2; |
934 | 610k | if ( !(flags & c_flag) ) |
935 | 591k | goto call; |
936 | 18.4k | goto loop; |
937 | | |
938 | 108k | case 0xDC: // CC |
939 | 108k | pc += 2; |
940 | 108k | if ( flags & c_flag ) |
941 | 69.3k | goto call; |
942 | 39.5k | goto loop; |
943 | | |
944 | 42.2k | case 0xD9: // RETI |
945 | | //interrupts_enabled = 1; |
946 | 42.2k | goto ret; |
947 | | |
948 | 2.00M | case 0xC0: // RZ |
949 | 2.00M | if ( !(flags & z_flag) ) |
950 | 1.57M | goto ret; |
951 | 421k | goto loop; |
952 | | |
953 | 588k | case 0xD0: // RNC |
954 | 588k | if ( !(flags & c_flag) ) |
955 | 575k | goto ret; |
956 | 12.7k | goto loop; |
957 | | |
958 | 1.22M | case 0xD8: // RC |
959 | 1.22M | if ( flags & c_flag ) |
960 | 17.9k | goto ret; |
961 | 1.20M | goto loop; |
962 | | |
963 | 6.66M | case 0x18: // JR |
964 | 6.66M | BRANCH( true ) |
965 | | |
966 | 14.6M | case 0x30: // JR NC |
967 | 14.6M | BRANCH( !(flags & c_flag) ) |
968 | | |
969 | 7.45M | case 0x38: // JR C |
970 | 7.45M | BRANCH( flags & c_flag ) |
971 | | |
972 | 15.1M | case 0xE9: // JP_HL |
973 | 15.1M | pc = rp.hl; |
974 | 15.1M | goto loop; |
975 | | |
976 | 3.57M | case 0xC3: // JP (next-most-common) |
977 | 3.57M | pc = GET_ADDR(); |
978 | 3.57M | goto loop; |
979 | | |
980 | 152k | case 0xC2: // JP NZ |
981 | 152k | pc += 2; |
982 | 152k | if ( !(flags & z_flag) ) |
983 | 151k | goto jp_taken; |
984 | 921 | goto loop; |
985 | | |
986 | 5.39M | case 0xCA: // JP Z (most common) |
987 | 5.39M | pc += 2; |
988 | 5.39M | if ( !(flags & z_flag) ) |
989 | 419k | goto loop; |
990 | 8.76M | jp_taken: |
991 | 8.76M | pc -= 2; |
992 | 8.76M | pc = GET_ADDR(); |
993 | 8.76M | goto loop; |
994 | | |
995 | 3.65M | case 0xD2: // JP NC |
996 | 3.65M | pc += 2; |
997 | 3.65M | if ( !(flags & c_flag) ) |
998 | 3.62M | goto jp_taken; |
999 | 27.3k | goto loop; |
1000 | | |
1001 | 211k | case 0xDA: // JP C |
1002 | 211k | pc += 2; |
1003 | 211k | if ( flags & c_flag ) |
1004 | 12.8k | goto jp_taken; |
1005 | 199k | goto loop; |
1006 | | |
1007 | | // Flags |
1008 | | |
1009 | 14.0M | case 0x2F: // CPL |
1010 | 14.0M | rg.a = ~rg.a; |
1011 | 14.0M | flags |= n_flag | h_flag; |
1012 | 14.0M | goto loop; |
1013 | | |
1014 | 568k | case 0x3F: // CCF |
1015 | 568k | flags = (flags ^ c_flag) & ~(n_flag | h_flag); |
1016 | 568k | goto loop; |
1017 | | |
1018 | 2.08M | case 0x37: // SCF |
1019 | 2.08M | flags = (flags | c_flag) & ~(n_flag | h_flag); |
1020 | 2.08M | goto loop; |
1021 | | |
1022 | 5.60M | case 0xF3: // DI |
1023 | | //interrupts_enabled = 0; |
1024 | 5.60M | goto loop; |
1025 | | |
1026 | 340k | case 0xFB: // EI |
1027 | | //interrupts_enabled = 1; |
1028 | 340k | goto loop; |
1029 | | |
1030 | | // Special |
1031 | | |
1032 | 17.6M | case 0xDD: case 0xD3: case 0xDB: case 0xE3: case 0xE4: // ? |
1033 | 39.7M | case 0xEB: case 0xEC: case 0xF4: case 0xFD: case 0xFC: |
1034 | 43.0M | case 0x10: // STOP |
1035 | 43.3M | case 0x27: // DAA (I'll have to implement this eventually...) |
1036 | 44.3M | case 0xBF: |
1037 | 46.2M | case 0xED: // Z80 prefix |
1038 | 46.6M | case 0x76: // HALT |
1039 | 46.6M | s.remain++; |
1040 | 46.6M | goto stop; |
1041 | 20.6G | } |
1042 | | |
1043 | | // If this fails then the case above is missing an opcode |
1044 | 20.6G | assert( false ); |
1045 | |
|
1046 | 47.0M | stop: |
1047 | 47.0M | pc--; |
1048 | | |
1049 | | // copy state back |
1050 | 47.0M | STATIC_CAST(core_regs_t&,r) = rg; |
1051 | 47.0M | r.pc = pc; |
1052 | 47.0M | r.sp = sp; |
1053 | 47.0M | r.flags = flags; |
1054 | | |
1055 | 47.0M | this->state = &state_; |
1056 | 47.0M | memcpy( &this->state_, &s, sizeof this->state_ ); |
1057 | | |
1058 | 47.0M | return s.remain > 0; |
1059 | 0 | } |