diff options
Diffstat (limited to 'apps/plugins/rockboy/cpu.c')
-rw-r--r-- | apps/plugins/rockboy/cpu.c | 1363 |
1 files changed, 680 insertions, 683 deletions
diff --git a/apps/plugins/rockboy/cpu.c b/apps/plugins/rockboy/cpu.c index 3c295dcdf5..00cfc42684 100644 --- a/apps/plugins/rockboy/cpu.c +++ b/apps/plugins/rockboy/cpu.c | |||
@@ -17,19 +17,12 @@ | |||
17 | struct cpu cpu IBSS_ATTR; | 17 | struct cpu cpu IBSS_ATTR; |
18 | 18 | ||
19 | 19 | ||
20 | |||
21 | |||
22 | #define ZFLAG(n) ( (n) ? 0 : FZ ) | 20 | #define ZFLAG(n) ( (n) ? 0 : FZ ) |
23 | 21 | ||
24 | 22 | ||
25 | #define PUSH(w) ( (SP -= 2), (writew(xSP, (w))) ) | 23 | #define PUSH(w) ( (SP -= 2), (writew(xSP, (w))) ) |
26 | #define POP(w) ( ((w) = readw(xSP)), (SP += 2) ) | 24 | #define POP(w) ( ((w) = readw(xSP)), (SP += 2) ) |
27 | 25 | ||
28 | |||
29 | #define FETCH_OLD ( mbc.rmap[PC>>12] \ | ||
30 | ? mbc.rmap[PC>>12][PC++] \ | ||
31 | : mem_read(PC++) ) | ||
32 | |||
33 | #define FETCH (readb(PC++)) | 26 | #define FETCH (readb(PC++)) |
34 | 27 | ||
35 | 28 | ||
@@ -227,7 +220,7 @@ label: op(b); break; | |||
227 | #define RET ( POP(PC) ) | 220 | #define RET ( POP(PC) ) |
228 | 221 | ||
229 | #define EI ( IMA = 1 ) | 222 | #define EI ( IMA = 1 ) |
230 | #define DI ( cpu.halt = IMA = IME = 0 ) | 223 | #define DI ( IMA = IME = 0 ) |
231 | 224 | ||
232 | 225 | ||
233 | 226 | ||
@@ -246,127 +239,122 @@ int blockcount; | |||
246 | 239 | ||
247 | void cpu_reset(void) | 240 | void cpu_reset(void) |
248 | { | 241 | { |
249 | union reg acc; | 242 | union reg acc; |
250 | #ifdef DYNAREC | 243 | #ifdef DYNAREC |
251 | int i; | 244 | int i; |
252 | dynapointer=0; | 245 | dynapointer=0; |
253 | #endif | 246 | #endif |
254 | cpu.speed = 0; | 247 | cpu.speed = 0; |
255 | cpu.halt = 0; | 248 | cpu.halt = 0; |
256 | cpu.div = 0; | 249 | cpu.div = 0; |
257 | cpu.tim = 0; | 250 | cpu.tim = 0; |
258 | cpu.lcdc = 40; | 251 | cpu.lcdc = 40; |
259 | 252 | ||
260 | IME = 0; | 253 | IME = 0; |
261 | IMA = 0; | 254 | IMA = 0; |
262 | 255 | ||
263 | PC = 0x0100; | 256 | PC = 0x0100; |
264 | SP = 0xFFFE; | 257 | SP = 0xFFFE; |
265 | W(acc) = 0x01B0; | 258 | W(acc) = 0x01B0; |
266 | A=HB(acc); | 259 | A=HB(acc); |
267 | F=LB(acc); | 260 | F=LB(acc); |
268 | W(acc) = 0x0013; | 261 | W(acc) = 0x0013; |
269 | B=HB(acc); | 262 | B=HB(acc); |
270 | C=LB(acc); | 263 | C=LB(acc); |
271 | W(acc) = 0x00D8; | 264 | W(acc) = 0x00D8; |
272 | D=HB(acc); | 265 | D=HB(acc); |
273 | E=LB(acc); | 266 | E=LB(acc); |
274 | HL = 0x014D; | 267 | HL = 0x014D; |
275 | 268 | ||
276 | if (hw.cgb) A = 0x11; | 269 | if (hw.cgb) A = 0x11; |
277 | if (hw.gba) B = 0x01; | ||
278 | #ifdef DYNAREC | 270 | #ifdef DYNAREC |
279 | for(i=0;i<(1<<HASH_SIGNIFICANT_LOWER_BITS);i++) | 271 | for(i=0;i<(1<<HASH_SIGNIFICANT_LOWER_BITS);i++) |
280 | address_map[i]=0; | 272 | address_map[i]=0; |
281 | #endif | 273 | #endif |
282 | } | 274 | } |
283 | 275 | ||
284 | 276 | ||
285 | void div_advance(int cnt) | 277 | void div_advance(int cnt) |
286 | { | 278 | { |
287 | cpu.div += (cnt<<1); | 279 | cpu.div += (cnt<<1); |
288 | if (cpu.div >= 256) | 280 | if (cpu.div >= 256) |
289 | { | 281 | { |
290 | R_DIV += (cpu.div >> 8); | 282 | R_DIV += (cpu.div >> 8); |
291 | cpu.div &= 0xff; | 283 | cpu.div &= 0xff; |
292 | } | 284 | } |
293 | } | 285 | } |
294 | 286 | ||
295 | void timer_advance(int cnt) | 287 | void timer_advance(int cnt) |
296 | { | 288 | { |
297 | int unit, tima; | 289 | int unit, tima; |
298 | 290 | ||
299 | if (!(R_TAC & 0x04)) return; | 291 | if (!(R_TAC & 0x04)) return; |
300 | 292 | ||
301 | unit = ((-R_TAC) & 3) << 1; | 293 | unit = ((-R_TAC) & 3) << 1; |
302 | cpu.tim += (cnt<<unit); | 294 | cpu.tim += (cnt<<unit); |
303 | 295 | ||
304 | if (cpu.tim >= 512) | 296 | if (cpu.tim >= 512) |
305 | { | 297 | { |
306 | tima = R_TIMA + (cpu.tim >> 9); | 298 | tima = R_TIMA + (cpu.tim >> 9); |
307 | cpu.tim &= 0x1ff; | 299 | cpu.tim &= 0x1ff; |
308 | if (tima >= 256) | 300 | if (tima >= 256) |
309 | { | 301 | { |
310 | hw_interrupt(IF_TIMER, IF_TIMER); | 302 | hw_interrupt(IF_TIMER, IF_TIMER); |
311 | hw_interrupt(0, IF_TIMER); | 303 | hw_interrupt(0, IF_TIMER); |
312 | } | 304 | } |
313 | while (tima >= 256) | 305 | while (tima >= 256) |
314 | tima = tima - 256 + R_TMA; | 306 | tima = tima - 256 + R_TMA; |
315 | R_TIMA = tima; | 307 | R_TIMA = tima; |
316 | } | 308 | } |
317 | } | 309 | } |
318 | 310 | ||
319 | void lcdc_advance(int cnt) | 311 | void lcdc_advance(int cnt) |
320 | { | 312 | { |
321 | cpu.lcdc -= cnt; | 313 | cpu.lcdc -= cnt; |
322 | if (cpu.lcdc <= 0) lcdc_trans(); | 314 | if (cpu.lcdc <= 0) lcdc_trans(); |
323 | } | 315 | } |
324 | 316 | ||
325 | void sound_advance(int cnt) | 317 | void sound_advance(int cnt) |
326 | { | 318 | { |
327 | cpu.snd += cnt; | 319 | cpu.snd += cnt; |
328 | } | 320 | } |
329 | 321 | ||
330 | void cpu_timers(int cnt) | 322 | void cpu_timers(int cnt) |
331 | { | 323 | { |
332 | div_advance(cnt << cpu.speed); | 324 | div_advance(cnt << cpu.speed); |
333 | timer_advance(cnt << cpu.speed); | 325 | timer_advance(cnt << cpu.speed); |
334 | lcdc_advance(cnt); | 326 | lcdc_advance(cnt); |
335 | sound_advance(cnt); | 327 | if(options.sound) |
328 | sound_advance(cnt); | ||
336 | } | 329 | } |
337 | 330 | ||
338 | int cpu_idle(int max) | 331 | int cpu_idle(int max) |
339 | { | 332 | { |
340 | int cnt, unit; | 333 | int cnt, unit; |
341 | 334 | ||
342 | if (!(cpu.halt && IME)) return 0; | 335 | if (!(cpu.halt && IME)) return 0; |
343 | if (R_IF & R_IE) | 336 | |
344 | { | 337 | /* Make sure we don't miss lcdc status events! */ |
345 | cpu.halt = 0; | 338 | if ((R_IE & (IF_VBLANK | IF_STAT)) && (max > cpu.lcdc)) |
346 | return 0; | 339 | max = cpu.lcdc; |
347 | } | 340 | |
348 | 341 | /* If timer interrupt cannot happen, this is very simple! */ | |
349 | /* Make sure we don't miss lcdc status events! */ | 342 | if (!((R_IE & IF_TIMER) && (R_TAC & 0x04))) |
350 | if ((R_IE & (IF_VBLANK | IF_STAT)) && (max > cpu.lcdc)) | 343 | { |
351 | max = cpu.lcdc; | 344 | cpu_timers(max); |
352 | 345 | return max; | |
353 | /* If timer interrupt cannot happen, this is very simple! */ | 346 | } |
354 | if (!((R_IE & IF_TIMER) && (R_TAC & 0x04))) | 347 | |
355 | { | 348 | /* Figure out when the next timer interrupt will happen */ |
356 | cpu_timers(max); | 349 | unit = ((-R_TAC) & 3) << 1; |
357 | return max; | 350 | cnt = (511 - cpu.tim + (1<<unit)) >> unit; |
358 | } | 351 | cnt += (255 - R_TIMA) << (9 - unit); |
359 | 352 | ||
360 | /* Figure out when the next timer interrupt will happen */ | 353 | if (max < cnt) |
361 | unit = ((-R_TAC) & 3) << 1; | 354 | cnt = max; |
362 | cnt = (511 - cpu.tim + (1<<unit)) >> unit; | 355 | |
363 | cnt += (255 - R_TIMA) << (9 - unit); | 356 | cpu_timers(cnt); |
364 | 357 | return cnt; | |
365 | if (max < cnt) | ||
366 | cnt = max; | ||
367 | |||
368 | cpu_timers(cnt); | ||
369 | return cnt; | ||
370 | } | 358 | } |
371 | 359 | ||
372 | #ifndef ASM_CPU_EMULATE | 360 | #ifndef ASM_CPU_EMULATE |
@@ -375,627 +363,636 @@ extern int debug_trace; | |||
375 | 363 | ||
376 | int cpu_emulate(int cycles) | 364 | int cpu_emulate(int cycles) |
377 | { | 365 | { |
378 | int i; | 366 | int i; |
379 | byte op, cbop; | 367 | static byte op IBSS_ATTR; |
380 | int clen; | 368 | static byte cbop IBSS_ATTR; |
381 | static union reg acc; | 369 | int clen; |
382 | static byte b IBSS_ATTR; | 370 | static union reg acc IBSS_ATTR; |
383 | static word w IBSS_ATTR; | 371 | static byte b IBSS_ATTR; |
384 | 372 | static word w IBSS_ATTR; | |
385 | i = cycles; | 373 | |
374 | i = cycles; | ||
386 | next: | 375 | next: |
387 | #ifdef DYNAREC | 376 | #ifdef DYNAREC |
388 | if(shut) | 377 | if(shut) |
389 | return cycles-i; | 378 | return cycles-i; |
390 | #endif | 379 | #endif |
391 | if ((clen = cpu_idle(i))) | 380 | if ((clen = cpu_idle(i))) |
392 | { | 381 | { |
393 | i -= clen; | 382 | i -= clen; |
394 | if (i > 0) goto next; | 383 | if (i > 0) goto next; |
395 | return cycles-i; | 384 | return cycles-i; |
396 | } | 385 | } |
397 | 386 | ||
398 | if (IME && (IF & IE)) | 387 | if (IME && (IF & IE)) |
399 | { | 388 | { |
400 | PRE_INT; | 389 | PRE_INT; |
401 | switch ((byte)(IF & IE)) | 390 | switch ((byte)(IF & IE)) |
402 | { | 391 | { |
403 | case 0x01: case 0x03: case 0x05: case 0x07: | 392 | case 0x01: case 0x03: case 0x05: case 0x07: |
404 | case 0x09: case 0x0B: case 0x0D: case 0x0F: | 393 | case 0x09: case 0x0B: case 0x0D: case 0x0F: |
405 | case 0x11: case 0x13: case 0x15: case 0x17: | 394 | case 0x11: case 0x13: case 0x15: case 0x17: |
406 | case 0x19: case 0x1B: case 0x1D: case 0x1F: | 395 | case 0x19: case 0x1B: case 0x1D: case 0x1F: |
407 | THROW_INT(0); break; | 396 | THROW_INT(0); break; |
408 | case 0x02: case 0x06: case 0x0A: case 0x0E: | 397 | case 0x02: case 0x06: case 0x0A: case 0x0E: |
409 | case 0x12: case 0x16: case 0x1A: case 0x1E: | 398 | case 0x12: case 0x16: case 0x1A: case 0x1E: |
410 | THROW_INT(1); break; | 399 | THROW_INT(1); break; |
411 | case 0x04: case 0x0C: case 0x14: case 0x1C: | 400 | case 0x04: case 0x0C: case 0x14: case 0x1C: |
412 | THROW_INT(2); break; | 401 | THROW_INT(2); break; |
413 | case 0x08: case 0x18: | 402 | case 0x08: case 0x18: |
414 | THROW_INT(3); break; | 403 | THROW_INT(3); break; |
415 | case 0x10: | 404 | case 0x10: |
416 | THROW_INT(4); break; | 405 | THROW_INT(4); break; |
417 | } | 406 | } |
418 | } | 407 | } |
419 | IME = IMA; | 408 | IME = IMA; |
420 | 409 | ||
421 | /* if (debug_trace) debug_disassemble(PC, 1); */ | 410 | /* if (debug_trace) debug_disassemble(PC, 1); */ |
422 | #ifdef DYNAREC | 411 | #ifdef DYNAREC |
423 | if(PC&0x8000) { | 412 | if(PC&0x8000) { |
424 | #endif | 413 | #endif |
425 | op = FETCH; | 414 | op = FETCH; |
426 | clen = cycles_table[op]; | 415 | clen = cycles_table[op]; |
427 | 416 | ||
428 | switch(op) | 417 | switch(op) |
429 | { | 418 | { |
430 | case 0x00: /* NOP */ | 419 | case 0x00: /* NOP */ |
431 | case 0x40: /* LD B,B */ | 420 | case 0x40: /* LD B,B */ |
432 | case 0x49: /* LD C,C */ | 421 | case 0x49: /* LD C,C */ |
433 | case 0x52: /* LD D,D */ | 422 | case 0x52: /* LD D,D */ |
434 | case 0x5B: /* LD E,E */ | 423 | case 0x5B: /* LD E,E */ |
435 | case 0x64: /* LD H,H */ | 424 | case 0x64: /* LD H,H */ |
436 | case 0x6D: /* LD L,L */ | 425 | case 0x6D: /* LD L,L */ |
437 | case 0x7F: /* LD A,A */ | 426 | case 0x7F: /* LD A,A */ |
438 | break; | 427 | break; |
439 | 428 | ||
440 | case 0x41: /* LD B,C */ | 429 | case 0x41: /* LD B,C */ |
441 | B = C; break; | 430 | B = C; break; |
442 | case 0x42: /* LD B,D */ | 431 | case 0x42: /* LD B,D */ |
443 | B = D; break; | 432 | B = D; break; |
444 | case 0x43: /* LD B,E */ | 433 | case 0x43: /* LD B,E */ |
445 | B = E; break; | 434 | B = E; break; |
446 | case 0x44: /* LD B,H */ | 435 | case 0x44: /* LD B,H */ |
447 | B = H; break; | 436 | B = H; break; |
448 | case 0x45: /* LD B,L */ | 437 | case 0x45: /* LD B,L */ |
449 | B = L; break; | 438 | B = L; break; |
450 | case 0x46: /* LD B,(HL) */ | 439 | case 0x46: /* LD B,(HL) */ |
451 | B = readb(xHL); break; | 440 | B = readb(xHL); break; |
452 | case 0x47: /* LD B,A */ | 441 | case 0x47: /* LD B,A */ |
453 | B = A; break; | 442 | B = A; break; |
454 | 443 | ||
455 | case 0x48: /* LD C,B */ | 444 | case 0x48: /* LD C,B */ |
456 | C = B; break; | 445 | C = B; break; |
457 | case 0x4A: /* LD C,D */ | 446 | case 0x4A: /* LD C,D */ |
458 | C = D; break; | 447 | C = D; break; |
459 | case 0x4B: /* LD C,E */ | 448 | case 0x4B: /* LD C,E */ |
460 | C = E; break; | 449 | C = E; break; |
461 | case 0x4C: /* LD C,H */ | 450 | case 0x4C: /* LD C,H */ |
462 | C = H; break; | 451 | C = H; break; |
463 | case 0x4D: /* LD C,L */ | 452 | case 0x4D: /* LD C,L */ |
464 | C = L; break; | 453 | C = L; break; |
465 | case 0x4E: /* LD C,(HL) */ | 454 | case 0x4E: /* LD C,(HL) */ |
466 | C = readb(xHL); break; | 455 | C = readb(xHL); break; |
467 | case 0x4F: /* LD C,A */ | 456 | case 0x4F: /* LD C,A */ |
468 | C = A; break; | 457 | C = A; break; |
469 | 458 | ||
470 | case 0x50: /* LD D,B */ | 459 | case 0x50: /* LD D,B */ |
471 | D = B; break; | 460 | D = B; break; |
472 | case 0x51: /* LD D,C */ | 461 | case 0x51: /* LD D,C */ |
473 | D = C; break; | 462 | D = C; break; |
474 | case 0x53: /* LD D,E */ | 463 | case 0x53: /* LD D,E */ |
475 | D = E; break; | 464 | D = E; break; |
476 | case 0x54: /* LD D,H */ | 465 | case 0x54: /* LD D,H */ |
477 | D = H; break; | 466 | D = H; break; |
478 | case 0x55: /* LD D,L */ | 467 | case 0x55: /* LD D,L */ |
479 | D = L; break; | 468 | D = L; break; |
480 | case 0x56: /* LD D,(HL) */ | 469 | case 0x56: /* LD D,(HL) */ |
481 | D = readb(xHL); break; | 470 | D = readb(xHL); break; |
482 | case 0x57: /* LD D,A */ | 471 | case 0x57: /* LD D,A */ |
483 | D = A; break; | 472 | D = A; break; |
484 | 473 | ||
485 | case 0x58: /* LD E,B */ | 474 | case 0x58: /* LD E,B */ |
486 | E = B; break; | 475 | E = B; break; |
487 | case 0x59: /* LD E,C */ | 476 | case 0x59: /* LD E,C */ |
488 | E = C; break; | 477 | E = C; break; |
489 | case 0x5A: /* LD E,D */ | 478 | case 0x5A: /* LD E,D */ |
490 | E = D; break; | 479 | E = D; break; |
491 | case 0x5C: /* LD E,H */ | 480 | case 0x5C: /* LD E,H */ |
492 | E = H; break; | 481 | E = H; break; |
493 | case 0x5D: /* LD E,L */ | 482 | case 0x5D: /* LD E,L */ |
494 | E = L; break; | 483 | E = L; break; |
495 | case 0x5E: /* LD E,(HL) */ | 484 | case 0x5E: /* LD E,(HL) */ |
496 | E = readb(xHL); break; | 485 | E = readb(xHL); break; |
497 | case 0x5F: /* LD E,A */ | 486 | case 0x5F: /* LD E,A */ |
498 | E = A; break; | 487 | E = A; break; |
499 | 488 | ||
500 | case 0x60: /* LD H,B */ | 489 | case 0x60: /* LD H,B */ |
501 | H = B; break; | 490 | H = B; break; |
502 | case 0x61: /* LD H,C */ | 491 | case 0x61: /* LD H,C */ |
503 | H = C; break; | 492 | H = C; break; |
504 | case 0x62: /* LD H,D */ | 493 | case 0x62: /* LD H,D */ |
505 | H = D; break; | 494 | H = D; break; |
506 | case 0x63: /* LD H,E */ | 495 | case 0x63: /* LD H,E */ |
507 | H = E; break; | 496 | H = E; break; |
508 | case 0x65: /* LD H,L */ | 497 | case 0x65: /* LD H,L */ |
509 | H = L; break; | 498 | H = L; break; |
510 | case 0x66: /* LD H,(HL) */ | 499 | case 0x66: /* LD H,(HL) */ |
511 | H = readb(xHL); break; | 500 | H = readb(xHL); break; |
512 | case 0x67: /* LD H,A */ | 501 | case 0x67: /* LD H,A */ |
513 | H = A; break; | 502 | H = A; break; |
514 | 503 | ||
515 | case 0x68: /* LD L,B */ | 504 | case 0x68: /* LD L,B */ |
516 | L = B; break; | 505 | L = B; break; |
517 | case 0x69: /* LD L,C */ | 506 | case 0x69: /* LD L,C */ |
518 | L = C; break; | 507 | L = C; break; |
519 | case 0x6A: /* LD L,D */ | 508 | case 0x6A: /* LD L,D */ |
520 | L = D; break; | 509 | L = D; break; |
521 | case 0x6B: /* LD L,E */ | 510 | case 0x6B: /* LD L,E */ |
522 | L = E; break; | 511 | L = E; break; |
523 | case 0x6C: /* LD L,H */ | 512 | case 0x6C: /* LD L,H */ |
524 | L = H; break; | 513 | L = H; break; |
525 | case 0x6E: /* LD L,(HL) */ | 514 | case 0x6E: /* LD L,(HL) */ |
526 | L = readb(xHL); break; | 515 | L = readb(xHL); break; |
527 | case 0x6F: /* LD L,A */ | 516 | case 0x6F: /* LD L,A */ |
528 | L = A; break; | 517 | L = A; break; |
529 | 518 | ||
530 | case 0x70: /* LD (HL),B */ | 519 | case 0x70: /* LD (HL),B */ |
531 | b = B; goto __LD_HL; | 520 | b = B; goto __LD_HL; |
532 | case 0x71: /* LD (HL),C */ | 521 | case 0x71: /* LD (HL),C */ |
533 | b = C; goto __LD_HL; | 522 | b = C; goto __LD_HL; |
534 | case 0x72: /* LD (HL),D */ | 523 | case 0x72: /* LD (HL),D */ |
535 | b = D; goto __LD_HL; | 524 | b = D; goto __LD_HL; |
536 | case 0x73: /* LD (HL),E */ | 525 | case 0x73: /* LD (HL),E */ |
537 | b = E; goto __LD_HL; | 526 | b = E; goto __LD_HL; |
538 | case 0x74: /* LD (HL),H */ | 527 | case 0x74: /* LD (HL),H */ |
539 | b = H; goto __LD_HL; | 528 | b = H; goto __LD_HL; |
540 | case 0x75: /* LD (HL),L */ | 529 | case 0x75: /* LD (HL),L */ |
541 | b = L; goto __LD_HL; | 530 | b = L; goto __LD_HL; |
542 | case 0x77: /* LD (HL),A */ | 531 | case 0x77: /* LD (HL),A */ |
543 | b = A; | 532 | b = A; |
544 | __LD_HL: | 533 | __LD_HL: |
545 | writeb(xHL,b); | 534 | writeb(xHL,b); |
546 | break; | 535 | break; |
547 | 536 | ||
548 | case 0x78: /* LD A,B */ | 537 | case 0x78: /* LD A,B */ |
549 | A = B; break; | 538 | A = B; break; |
550 | case 0x79: /* LD A,C */ | 539 | case 0x79: /* LD A,C */ |
551 | A = C; break; | 540 | A = C; break; |
552 | case 0x7A: /* LD A,D */ | 541 | case 0x7A: /* LD A,D */ |
553 | A = D; break; | 542 | A = D; break; |
554 | case 0x7B: /* LD A,E */ | 543 | case 0x7B: /* LD A,E */ |
555 | A = E; break; | 544 | A = E; break; |
556 | case 0x7C: /* LD A,H */ | 545 | case 0x7C: /* LD A,H */ |
557 | A = H; break; | 546 | A = H; break; |
558 | case 0x7D: /* LD A,L */ | 547 | case 0x7D: /* LD A,L */ |
559 | A = L; break; | 548 | A = L; break; |
560 | case 0x7E: /* LD A,(HL) */ | 549 | case 0x7E: /* LD A,(HL) */ |
561 | A = readb(xHL); break; | 550 | A = readb(xHL); break; |
562 | 551 | ||
563 | case 0x01: /* LD BC,imm */ | 552 | case 0x01: /* LD BC,imm */ |
564 | #ifdef DYNAREC | 553 | #ifdef DYNAREC |
565 | W(acc) = readw(xPC); | 554 | W(acc) = readw(xPC); |
566 | B=HB(acc); | 555 | B=HB(acc); |
567 | C=LB(acc); | 556 | C=LB(acc); |
568 | #else | 557 | #else |
569 | BC = readw(xPC); | 558 | BC = readw(xPC); |
570 | #endif | 559 | #endif |
571 | PC += 2; | 560 | PC += 2; |
572 | break; | 561 | break; |
573 | case 0x11: /* LD DE,imm */ | 562 | case 0x11: /* LD DE,imm */ |
574 | #ifdef DYNAREC | 563 | #ifdef DYNAREC |
575 | W(acc) = readw(xPC); | 564 | W(acc) = readw(xPC); |
576 | D=HB(acc); | 565 | D=HB(acc); |
577 | E=LB(acc); | 566 | E=LB(acc); |
578 | #else | 567 | #else |
579 | DE = readw(xPC); | 568 | DE = readw(xPC); |
580 | #endif | 569 | #endif |
581 | PC += 2; | 570 | PC += 2; |
582 | break; | 571 | break; |
583 | case 0x21: /* LD HL,imm */ | 572 | case 0x21: /* LD HL,imm */ |
584 | HL = readw(xPC); PC += 2; break; | 573 | HL = readw(xPC); PC += 2; break; |
585 | case 0x31: /* LD SP,imm */ | 574 | case 0x31: /* LD SP,imm */ |
586 | SP = readw(xPC); PC += 2; break; | 575 | SP = readw(xPC); PC += 2; break; |
587 | 576 | ||
588 | case 0x02: /* LD (BC),A */ | 577 | case 0x02: /* LD (BC),A */ |
589 | writeb(xBC, A); break; | 578 | writeb(xBC, A); break; |
590 | case 0x0A: /* LD A,(BC) */ | 579 | case 0x0A: /* LD A,(BC) */ |
591 | A = readb(xBC); break; | 580 | A = readb(xBC); break; |
592 | case 0x12: /* LD (DE),A */ | 581 | case 0x12: /* LD (DE),A */ |
593 | writeb(xDE, A); break; | 582 | writeb(xDE, A); break; |
594 | case 0x1A: /* LD A,(DE) */ | 583 | case 0x1A: /* LD A,(DE) */ |
595 | A = readb(xDE); break; | 584 | A = readb(xDE); break; |
596 | 585 | ||
597 | case 0x22: /* LDI (HL),A */ | 586 | case 0x22: /* LDI (HL),A */ |
598 | writeb(xHL, A); HL++; break; | 587 | writeb(xHL, A); HL++; break; |
599 | case 0x2A: /* LDI A,(HL) */ | 588 | case 0x2A: /* LDI A,(HL) */ |
600 | A = readb(xHL); HL++; break; | 589 | A = readb(xHL); HL++; break; |
601 | case 0x32: /* LDD (HL),A */ | 590 | case 0x32: /* LDD (HL),A */ |
602 | writeb(xHL, A); HL--; break; | 591 | writeb(xHL, A); HL--; break; |
603 | case 0x3A: /* LDD A,(HL) */ | 592 | case 0x3A: /* LDD A,(HL) */ |
604 | A = readb(xHL); HL--; break; | 593 | A = readb(xHL); HL--; break; |
605 | 594 | ||
606 | case 0x06: /* LD B,imm */ | 595 | case 0x06: /* LD B,imm */ |
607 | B = FETCH; break; | 596 | B = FETCH; break; |
608 | case 0x0E: /* LD C,imm */ | 597 | case 0x0E: /* LD C,imm */ |
609 | C = FETCH; break; | 598 | C = FETCH; break; |
610 | case 0x16: /* LD D,imm */ | 599 | case 0x16: /* LD D,imm */ |
611 | D = FETCH; break; | 600 | D = FETCH; break; |
612 | case 0x1E: /* LD E,imm */ | 601 | case 0x1E: /* LD E,imm */ |
613 | E = FETCH; break; | 602 | E = FETCH; break; |
614 | case 0x26: /* LD H,imm */ | 603 | case 0x26: /* LD H,imm */ |
615 | H = FETCH; break; | 604 | H = FETCH; break; |
616 | case 0x2E: /* LD L,imm */ | 605 | case 0x2E: /* LD L,imm */ |
617 | L = FETCH; break; | 606 | L = FETCH; break; |
618 | case 0x36: /* LD (HL),imm */ | 607 | case 0x36: /* LD (HL),imm */ |
619 | b = FETCH; writeb(xHL, b); break; | 608 | b = FETCH; writeb(xHL, b); break; |
620 | case 0x3E: /* LD A,imm */ | 609 | case 0x3E: /* LD A,imm */ |
621 | A = FETCH; break; | 610 | A = FETCH; break; |
622 | 611 | ||
623 | case 0x08: /* LD (imm),SP */ | 612 | case 0x08: /* LD (imm),SP */ |
624 | writew(readw(xPC), SP); PC += 2; break; | 613 | writew(readw(xPC), SP); PC += 2; break; |
625 | case 0xEA: /* LD (imm),A */ | 614 | case 0xEA: /* LD (imm),A */ |
626 | writeb(readw(xPC), A); PC += 2; break; | 615 | writeb(readw(xPC), A); PC += 2; break; |
627 | 616 | ||
628 | case 0xE0: /* LDH (imm),A */ | 617 | case 0xE0: /* LDH (imm),A */ |
629 | writehi(FETCH, A); break; | 618 | writehi(FETCH, A); break; |
630 | case 0xE2: /* LDH (C),A */ | 619 | case 0xE2: /* LDH (C),A */ |
631 | writehi(C, A); break; | 620 | writehi(C, A); break; |
632 | case 0xF0: /* LDH A,(imm) */ | 621 | case 0xF0: /* LDH A,(imm) */ |
633 | A = readhi(FETCH); break; | 622 | A = readhi(FETCH); break; |
634 | case 0xF2: /* LDH A,(C) (undocumented) */ | 623 | case 0xF2: /* LDH A,(C) (undocumented) */ |
635 | A = readhi(C); break; | 624 | A = readhi(C); break; |
636 | 625 | ||
637 | 626 | ||
638 | case 0xF8: /* LD HL,SP+imm */ | 627 | case 0xF8: /* LD HL,SP+imm */ |
639 | b = FETCH; LDHLSP(b); break; | 628 | b = FETCH; LDHLSP(b); break; |
640 | case 0xF9: /* LD SP,HL */ | 629 | case 0xF9: /* LD SP,HL */ |
641 | SP = HL; break; | 630 | SP = HL; break; |
642 | case 0xFA: /* LD A,(imm) */ | 631 | case 0xFA: /* LD A,(imm) */ |
643 | A = readb(readw(xPC)); PC += 2; break; | 632 | A = readb(readw(xPC)); PC += 2; break; |
644 | 633 | ||
645 | ALU_CASES(0x80, 0xC6, ADD, __ADD) | 634 | ALU_CASES(0x80, 0xC6, ADD, __ADD) |
646 | ALU_CASES(0x88, 0xCE, ADC, __ADC) | 635 | ALU_CASES(0x88, 0xCE, ADC, __ADC) |
647 | ALU_CASES(0x90, 0xD6, SUB, __SUB) | 636 | ALU_CASES(0x90, 0xD6, SUB, __SUB) |
648 | ALU_CASES(0x98, 0xDE, SBC, __SBC) | 637 | ALU_CASES(0x98, 0xDE, SBC, __SBC) |
649 | ALU_CASES(0xA0, 0xE6, AND, __AND) | 638 | ALU_CASES(0xA0, 0xE6, AND, __AND) |
650 | ALU_CASES(0xA8, 0xEE, XOR, __XOR) | 639 | ALU_CASES(0xA8, 0xEE, XOR, __XOR) |
651 | ALU_CASES(0xB0, 0xF6, OR, __OR) | 640 | ALU_CASES(0xB0, 0xF6, OR, __OR) |
652 | ALU_CASES(0xB8, 0xFE, CP, __CP) | 641 | ALU_CASES(0xB8, 0xFE, CP, __CP) |
653 | 642 | ||
654 | case 0x09: /* ADD HL,BC */ | 643 | case 0x09: /* ADD HL,BC */ |
655 | w = BC; goto __ADDW; | 644 | w = BC; goto __ADDW; |
656 | case 0x19: /* ADD HL,DE */ | 645 | case 0x19: /* ADD HL,DE */ |
657 | w = DE; goto __ADDW; | 646 | w = DE; goto __ADDW; |
658 | case 0x39: /* ADD HL,SP */ | 647 | case 0x39: /* ADD HL,SP */ |
659 | w = SP; goto __ADDW; | 648 | w = SP; goto __ADDW; |
660 | case 0x29: /* ADD HL,HL */ | 649 | case 0x29: /* ADD HL,HL */ |
661 | w = HL; | 650 | w = HL; |
662 | __ADDW: | 651 | __ADDW: |
663 | ADDW(w); | 652 | ADDW(w); |
664 | break; | 653 | break; |
665 | 654 | ||
666 | case 0x04: /* INC B */ | 655 | case 0x04: /* INC B */ |
667 | INC(B); break; | 656 | INC(B); break; |
668 | case 0x0C: /* INC C */ | 657 | case 0x0C: /* INC C */ |
669 | INC(C); break; | 658 | INC(C); break; |
670 | case 0x14: /* INC D */ | 659 | case 0x14: /* INC D */ |
671 | INC(D); break; | 660 | INC(D); break; |
672 | case 0x1C: /* INC E */ | 661 | case 0x1C: /* INC E */ |
673 | INC(E); break; | 662 | INC(E); break; |
674 | case 0x24: /* INC H */ | 663 | case 0x24: /* INC H */ |
675 | INC(H); break; | 664 | INC(H); break; |
676 | case 0x2C: /* INC L */ | 665 | case 0x2C: /* INC L */ |
677 | INC(L); break; | 666 | INC(L); break; |
678 | case 0x34: /* INC (HL) */ | 667 | case 0x34: /* INC (HL) */ |
679 | b = readb(xHL); | 668 | b = readb(xHL); |
680 | INC(b); | 669 | INC(b); |
681 | writeb(xHL, b); | 670 | writeb(xHL, b); |
682 | break; | 671 | break; |
683 | case 0x3C: /* INC A */ | 672 | case 0x3C: /* INC A */ |
684 | INC(A); break; | 673 | INC(A); break; |
685 | 674 | ||
686 | case 0x03: /* INC BC */ | 675 | case 0x03: /* INC BC */ |
687 | #ifdef DYNAREC | 676 | #ifdef DYNAREC |
688 | W(acc)=((B<<8)|C)+1; | 677 | W(acc)=((B<<8)|C)+1; |
689 | B=HB(acc); | 678 | B=HB(acc); |
690 | C=LB(acc); | 679 | C=LB(acc); |
691 | #else | 680 | #else |
692 | INCW(BC); | 681 | INCW(BC); |
693 | #endif | 682 | #endif |
694 | break; | 683 | break; |
695 | case 0x13: /* INC DE */ | 684 | case 0x13: /* INC DE */ |
696 | #ifdef DYNAREC | 685 | #ifdef DYNAREC |
697 | W(acc)=((D<<8)|E)+1; | 686 | W(acc)=((D<<8)|E)+1; |
698 | D=HB(acc); | 687 | D=HB(acc); |
699 | E=LB(acc); | 688 | E=LB(acc); |
700 | #else | 689 | #else |
701 | INCW(DE); | 690 | INCW(DE); |
702 | #endif | 691 | #endif |
703 | break; | 692 | break; |
704 | case 0x23: /* INC HL */ | 693 | case 0x23: /* INC HL */ |
705 | INCW(HL); break; | 694 | INCW(HL); break; |
706 | case 0x33: /* INC SP */ | 695 | case 0x33: /* INC SP */ |
707 | INCW(SP); break; | 696 | INCW(SP); break; |
708 | 697 | ||
709 | case 0x05: /* DEC B */ | 698 | case 0x05: /* DEC B */ |
710 | DEC(B); break; | 699 | DEC(B); break; |
711 | case 0x0D: /* DEC C */ | 700 | case 0x0D: /* DEC C */ |
712 | DEC(C); break; | 701 | DEC(C); break; |
713 | case 0x15: /* DEC D */ | 702 | case 0x15: /* DEC D */ |
714 | DEC(D); break; | 703 | DEC(D); break; |
715 | case 0x1D: /* DEC E */ | 704 | case 0x1D: /* DEC E */ |
716 | DEC(E); break; | 705 | DEC(E); break; |
717 | case 0x25: /* DEC H */ | 706 | case 0x25: /* DEC H */ |
718 | DEC(H); break; | 707 | DEC(H); break; |
719 | case 0x2D: /* DEC L */ | 708 | case 0x2D: /* DEC L */ |
720 | DEC(L); break; | 709 | DEC(L); break; |
721 | case 0x35: /* DEC (HL) */ | 710 | case 0x35: /* DEC (HL) */ |
722 | b = readb(xHL); | 711 | b = readb(xHL); |
723 | DEC(b); | 712 | DEC(b); |
724 | writeb(xHL, b); | 713 | writeb(xHL, b); |
725 | break; | 714 | break; |
726 | case 0x3D: /* DEC A */ | 715 | case 0x3D: /* DEC A */ |
727 | DEC(A); break; | 716 | DEC(A); break; |
728 | 717 | ||
729 | case 0x0B: /* DEC BC */ | 718 | case 0x0B: /* DEC BC */ |
730 | #ifdef DYNAREC | 719 | #ifdef DYNAREC |
731 | W(acc)=((B<<8)|C)-1; | 720 | W(acc)=((B<<8)|C)-1; |
732 | B=HB(acc); | 721 | B=HB(acc); |
733 | C=LB(acc); | 722 | C=LB(acc); |
734 | #else | 723 | #else |
735 | DECW(BC); | 724 | DECW(BC); |
736 | #endif | 725 | #endif |
737 | break; | 726 | break; |
738 | case 0x1B: /* DEC DE */ | 727 | case 0x1B: /* DEC DE */ |
739 | #ifdef DYNAREC | 728 | #ifdef DYNAREC |
740 | W(acc)=((D<<8)|E)-1; | 729 | W(acc)=((D<<8)|E)-1; |
741 | D=HB(acc); | 730 | D=HB(acc); |
742 | E=LB(acc); | 731 | E=LB(acc); |
743 | #else | 732 | #else |
744 | DECW(DE); | 733 | DECW(DE); |
745 | #endif | 734 | #endif |
746 | break; | 735 | break; |
747 | case 0x2B: /* DEC HL */ | 736 | case 0x2B: /* DEC HL */ |
748 | DECW(HL); break; | 737 | DECW(HL); break; |
749 | case 0x3B: /* DEC SP */ | 738 | case 0x3B: /* DEC SP */ |
750 | DECW(SP); break; | 739 | DECW(SP); break; |
751 | 740 | ||
752 | case 0x07: /* RLCA */ | 741 | case 0x07: /* RLCA */ |
753 | RLCA(A); break; | 742 | RLCA(A); break; |
754 | case 0x0F: /* RRCA */ | 743 | case 0x0F: /* RRCA */ |
755 | RRCA(A); break; | 744 | RRCA(A); break; |
756 | case 0x17: /* RLA */ | 745 | case 0x17: /* RLA */ |
757 | RLA(A); break; | 746 | RLA(A); break; |
758 | case 0x1F: /* RRA */ | 747 | case 0x1F: /* RRA */ |
759 | RRA(A); break; | 748 | RRA(A); break; |
760 | 749 | ||
761 | case 0x27: /* DAA */ | 750 | case 0x27: /* DAA */ |
762 | DAA; break; | 751 | DAA; break; |
763 | case 0x2F: /* CPL */ | 752 | case 0x2F: /* CPL */ |
764 | CPL(A); break; | 753 | CPL(A); break; |
765 | 754 | ||
766 | case 0x18: /* JR */ | 755 | case 0x18: /* JR */ |
767 | __JR: | 756 | __JR: |
768 | JR; break; | 757 | JR; break; |
769 | case 0x20: /* JR NZ */ | 758 | case 0x20: /* JR NZ */ |
770 | if (!(F&FZ)) goto __JR; NOJR; break; | 759 | if (!(F&FZ)) goto __JR; NOJR; break; |
771 | case 0x28: /* JR Z */ | 760 | case 0x28: /* JR Z */ |
772 | if (F&FZ) goto __JR; NOJR; break; | 761 | if (F&FZ) goto __JR; NOJR; break; |
773 | case 0x30: /* JR NC */ | 762 | case 0x30: /* JR NC */ |
774 | if (!(F&FC)) goto __JR; NOJR; break; | 763 | if (!(F&FC)) goto __JR; NOJR; break; |
775 | case 0x38: /* JR C */ | 764 | case 0x38: /* JR C */ |
776 | if (F&FC) goto __JR; NOJR; break; | 765 | if (F&FC) goto __JR; NOJR; break; |
777 | 766 | ||
778 | case 0xC3: /* JP */ | 767 | case 0xC3: /* JP */ |
779 | __JP: | 768 | __JP: |
780 | JP; break; | 769 | JP; break; |
781 | case 0xC2: /* JP NZ */ | 770 | case 0xC2: /* JP NZ */ |
782 | if (!(F&FZ)) goto __JP; NOJP; break; | 771 | if (!(F&FZ)) goto __JP; NOJP; break; |
783 | case 0xCA: /* JP Z */ | 772 | case 0xCA: /* JP Z */ |
784 | if (F&FZ) goto __JP; NOJP; break; | 773 | if (F&FZ) goto __JP; NOJP; break; |
785 | case 0xD2: /* JP NC */ | 774 | case 0xD2: /* JP NC */ |
786 | if (!(F&FC)) goto __JP; NOJP; break; | 775 | if (!(F&FC)) goto __JP; NOJP; break; |
787 | case 0xDA: /* JP C */ | 776 | case 0xDA: /* JP C */ |
788 | if (F&FC) goto __JP; NOJP; break; | 777 | if (F&FC) goto __JP; NOJP; break; |
789 | case 0xE9: /* JP HL */ | 778 | case 0xE9: /* JP HL */ |
790 | PC = HL; break; | 779 | PC = HL; break; |
791 | 780 | ||
792 | case 0xC9: /* RET */ | 781 | case 0xC9: /* RET */ |
793 | __RET: | 782 | __RET: |
794 | RET; break; | 783 | RET; break; |
795 | case 0xC0: /* RET NZ */ | 784 | case 0xC0: /* RET NZ */ |
796 | if (!(F&FZ)) goto __RET; NORET; break; | 785 | if (!(F&FZ)) goto __RET; NORET; break; |
797 | case 0xC8: /* RET Z */ | 786 | case 0xC8: /* RET Z */ |
798 | if (F&FZ) goto __RET; NORET; break; | 787 | if (F&FZ) goto __RET; NORET; break; |
799 | case 0xD0: /* RET NC */ | 788 | case 0xD0: /* RET NC */ |
800 | if (!(F&FC)) goto __RET; NORET; break; | 789 | if (!(F&FC)) goto __RET; NORET; break; |
801 | case 0xD8: /* RET C */ | 790 | case 0xD8: /* RET C */ |
802 | if (F&FC) goto __RET; NORET; break; | 791 | if (F&FC) goto __RET; NORET; break; |
803 | case 0xD9: /* RETI */ | 792 | case 0xD9: /* RETI */ |
804 | IME = IMA = 1; goto __RET; | 793 | IME = IMA = 1; goto __RET; |
805 | 794 | ||
806 | case 0xCD: /* CALL */ | 795 | case 0xCD: /* CALL */ |
807 | __CALL: | 796 | __CALL: |
808 | CALL; break; | 797 | CALL; break; |
809 | case 0xC4: /* CALL NZ */ | 798 | case 0xC4: /* CALL NZ */ |
810 | if (!(F&FZ)) goto __CALL; NOCALL; break; | 799 | if (!(F&FZ)) goto __CALL; NOCALL; break; |
811 | case 0xCC: /* CALL Z */ | 800 | case 0xCC: /* CALL Z */ |
812 | if (F&FZ) goto __CALL; NOCALL; break; | 801 | if (F&FZ) goto __CALL; NOCALL; break; |
813 | case 0xD4: /* CALL NC */ | 802 | case 0xD4: /* CALL NC */ |
814 | if (!(F&FC)) goto __CALL; NOCALL; break; | 803 | if (!(F&FC)) goto __CALL; NOCALL; break; |
815 | case 0xDC: /* CALL C */ | 804 | case 0xDC: /* CALL C */ |
816 | if (F&FC) goto __CALL; NOCALL; break; | 805 | if (F&FC) goto __CALL; NOCALL; break; |
817 | 806 | ||
818 | case 0xC7: /* RST 0 */ | 807 | case 0xC7: /* RST 0 */ |
819 | b = 0x00; goto __RST; | 808 | b = 0x00; goto __RST; |
820 | case 0xCF: /* RST 8 */ | 809 | case 0xCF: /* RST 8 */ |
821 | b = 0x08; goto __RST; | 810 | b = 0x08; goto __RST; |
822 | case 0xD7: /* RST 10 */ | 811 | case 0xD7: /* RST 10 */ |
823 | b = 0x10; goto __RST; | 812 | b = 0x10; goto __RST; |
824 | case 0xDF: /* RST 18 */ | 813 | case 0xDF: /* RST 18 */ |
825 | b = 0x18; goto __RST; | 814 | b = 0x18; goto __RST; |
826 | case 0xE7: /* RST 20 */ | 815 | case 0xE7: /* RST 20 */ |
827 | b = 0x20; goto __RST; | 816 | b = 0x20; goto __RST; |
828 | case 0xEF: /* RST 28 */ | 817 | case 0xEF: /* RST 28 */ |
829 | b = 0x28; goto __RST; | 818 | b = 0x28; goto __RST; |
830 | case 0xF7: /* RST 30 */ | 819 | case 0xF7: /* RST 30 */ |
831 | b = 0x30; goto __RST; | 820 | b = 0x30; goto __RST; |
832 | case 0xFF: /* RST 38 */ | 821 | case 0xFF: /* RST 38 */ |
833 | b = 0x38; | 822 | b = 0x38; |
834 | __RST: | 823 | __RST: |
835 | RST(b); break; | 824 | RST(b); break; |
836 | 825 | ||
837 | case 0xC1: /* POP BC */ | 826 | case 0xC1: /* POP BC */ |
838 | #ifdef DYNAREC | 827 | #ifdef DYNAREC |
839 | POP(W(acc)); | 828 | POP(W(acc)); |
840 | B=HB(acc); | 829 | B=HB(acc); |
841 | C=LB(acc); | 830 | C=LB(acc); |
842 | #else | 831 | #else |
843 | POP(BC); | 832 | POP(BC); |
844 | #endif | 833 | #endif |
845 | break; | 834 | break; |
846 | case 0xC5: /* PUSH BC */ | 835 | case 0xC5: /* PUSH BC */ |
847 | PUSH(BC); break; | 836 | PUSH(BC); break; |
848 | case 0xD1: /* POP DE */ | 837 | case 0xD1: /* POP DE */ |
849 | #ifdef DYNAREC | 838 | #ifdef DYNAREC |
850 | POP(W(acc)); | 839 | POP(W(acc)); |
851 | D=HB(acc); | 840 | D=HB(acc); |
852 | E=LB(acc); | 841 | E=LB(acc); |
853 | #else | 842 | #else |
854 | POP(DE); | 843 | POP(DE); |
855 | #endif | 844 | #endif |
856 | break; | 845 | break; |
857 | case 0xD5: /* PUSH DE */ | 846 | case 0xD5: /* PUSH DE */ |
858 | PUSH(DE); break; | 847 | PUSH(DE); break; |
859 | case 0xE1: /* POP HL */ | 848 | case 0xE1: /* POP HL */ |
860 | POP(HL); break; | 849 | POP(HL); break; |
861 | case 0xE5: /* PUSH HL */ | 850 | case 0xE5: /* PUSH HL */ |
862 | PUSH(HL); break; | 851 | PUSH(HL); break; |
863 | case 0xF1: /* POP AF */ | 852 | case 0xF1: /* POP AF */ |
864 | #ifdef DYNAREC | 853 | #ifdef DYNAREC |
865 | POP(W(acc)); | 854 | POP(W(acc)); |
866 | A=HB(acc); | 855 | A=HB(acc); |
867 | F=LB(acc); | 856 | F=LB(acc); |
868 | #else | 857 | #else |
869 | POP(AF); | 858 | POP(AF); |
870 | break; | 859 | break; |
871 | #endif | 860 | #endif |
872 | case 0xF5: /* PUSH AF */ | 861 | case 0xF5: /* PUSH AF */ |
873 | PUSH(AF); break; | 862 | PUSH(AF); break; |
874 | 863 | ||
875 | case 0xE8: /* ADD SP,imm */ | 864 | case 0xE8: /* ADD SP,imm */ |
876 | b = FETCH; ADDSP(b); break; | 865 | b = FETCH; ADDSP(b); break; |
877 | 866 | ||
878 | case 0xF3: /* DI */ | 867 | case 0xF3: /* DI */ |
879 | DI; break; | 868 | DI; break; |
880 | case 0xFB: /* EI */ | 869 | case 0xFB: /* EI */ |
881 | EI; break; | 870 | EI; break; |
882 | 871 | ||
883 | case 0x37: /* SCF */ | 872 | case 0x37: /* SCF */ |
884 | SCF; break; | 873 | SCF; break; |
885 | case 0x3F: /* CCF */ | 874 | case 0x3F: /* CCF */ |
886 | CCF; break; | 875 | CCF; break; |
887 | 876 | ||
888 | case 0x10: /* STOP */ | 877 | case 0x10: /* STOP */ |
889 | PC++; | 878 | PC++; |
890 | if (R_KEY1 & 1) | 879 | if (R_KEY1 & 1) |
891 | { | 880 | { |
892 | cpu.speed = cpu.speed ^ 1; | 881 | cpu.speed = cpu.speed ^ 1; |
893 | R_KEY1 = (R_KEY1 & 0x7E) | (cpu.speed << 7); | 882 | R_KEY1 = (R_KEY1 & 0x7E) | (cpu.speed << 7); |
894 | break; | 883 | break; |
895 | } | 884 | } |
896 | /* NOTE - we do not implement dmg STOP whatsoever */ | 885 | /* NOTE - we do not implement dmg STOP whatsoever */ |
897 | break; | 886 | break; |
898 | 887 | ||
899 | case 0x76: /* HALT */ | 888 | case 0x76: /* HALT */ |
900 | cpu.halt = 1; | 889 | cpu.halt = 1; |
901 | break; | 890 | break; |
902 | 891 | ||
903 | case 0xCB: /* CB prefix */ | 892 | case 0xCB: /* CB prefix */ |
904 | cbop = FETCH; | 893 | cbop = FETCH; |
905 | clen = cb_cycles_table[cbop]; | 894 | clen = cb_cycles_table[cbop]; |
906 | switch (cbop) | 895 | switch (cbop) |
907 | { | 896 | { |
908 | CB_REG_CASES(B, 0); | 897 | CB_REG_CASES(B, 0); |
909 | CB_REG_CASES(C, 1); | 898 | CB_REG_CASES(C, 1); |
910 | CB_REG_CASES(D, 2); | 899 | CB_REG_CASES(D, 2); |
911 | CB_REG_CASES(E, 3); | 900 | CB_REG_CASES(E, 3); |
912 | CB_REG_CASES(H, 4); | 901 | CB_REG_CASES(H, 4); |
913 | CB_REG_CASES(L, 5); | 902 | CB_REG_CASES(L, 5); |
914 | CB_REG_CASES(A, 7); | 903 | CB_REG_CASES(A, 7); |
915 | default: | 904 | default: |
916 | b = readb(xHL); | 905 | b = readb(xHL); |
917 | switch(cbop) | 906 | switch(cbop) |
918 | { | 907 | { |
919 | CB_REG_CASES(b, 6); | 908 | CB_REG_CASES(b, 6); |
920 | } | 909 | } |
921 | if ((cbop & 0xC0) != 0x40) /* exclude BIT */ | 910 | if ((cbop & 0xC0) != 0x40) /* exclude BIT */ |
922 | writeb(xHL, b); | 911 | writeb(xHL, b); |
923 | break; | 912 | break; |
924 | } | 913 | } |
925 | break; | 914 | break; |
926 | 915 | ||
927 | default: | 916 | default: |
928 | die( | 917 | die( |
929 | "invalid opcode 0x%02X at address 0x%04X, rombank = %d\n", | 918 | "invalid opcode 0x%02X at address 0x%04X, rombank = %d\n", |
930 | op, (PC-1) & 0xffff, mbc.rombank); | 919 | op, (PC-1) & 0xffff, mbc.rombank); |
931 | break; | 920 | break; |
932 | } | 921 | } |
933 | #ifdef DYNAREC | 922 | #ifdef DYNAREC |
934 | } else { // ROM, dynarec. | 923 | } |
924 | else | ||
925 | { /* ROM, dynarec. */ | ||
935 | struct dynarec_block *p=0,*b=address_map[PC&HASH_BITMASK]; | 926 | struct dynarec_block *p=0,*b=address_map[PC&HASH_BITMASK]; |
936 | char meow[500]; | 927 | char meow[500]; |
937 | byte *ptr=mbc.rmap[PC>>12]; | 928 | byte *ptr=mbc.rmap[PC>>12]; |
938 | snprintf(meow,499,"PC: 0x%x 0x%x a: 0x%x\n", | 929 | snprintf(meow,499,"PC: 0x%x 0x%x a: 0x%x\n", |
939 | ptr,PC, b ? b->address.d : 0); | 930 | ptr,PC, b ? b->address.d : 0); |
940 | rb->splash(HZ*2,true,meow); | 931 | rb->splash(HZ*2,true,meow); |
941 | while(b&&b->address.d!=(ptr+PC)) { | 932 | while(b&&b->address.d!=((unsigned int)(ptr)+PC)) |
933 | { | ||
942 | p=b; | 934 | p=b; |
943 | b=b->next; | 935 | b=b->next; |
944 | } | 936 | } |
945 | if(b) { // call block | 937 | if(b) |
938 | { /* call block */ | ||
946 | int fd; | 939 | int fd; |
947 | blockcount++; | 940 | blockcount++; |
948 | snprintf(meow,499,"/dyna_0x%x_run.rb",PC); | 941 | snprintf(meow,499,"/dyna_0x%x_run.rb",PC); |
949 | fd=open(meow,O_WRONLY|O_CREAT|O_TRUNC); | 942 | fd=open(meow,O_WRONLY|O_CREAT|O_TRUNC); |
950 | if(fd>=0) { | 943 | if(fd>=0) |
951 | fdprintf(fd,"Block 0x%x Blockcount: %d\n",PC,blockcount); | 944 | { |
952 | fdprintf(fd,"before: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 945 | fdprintf(fd,"Block 0x%x Blockcount: %d\n",PC,blockcount); |
953 | cpu.a,cpu.b,cpu.c,cpu.d,cpu.e,cpu.hl,cpu.f,cpu.sp,cpu.pc, | 946 | fdprintf(fd,"before: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
954 | cpu.ime); | 947 | cpu.a,cpu.b,cpu.c,cpu.d,cpu.e,cpu.hl,cpu.f,cpu.sp,cpu.pc, |
955 | if(blockcount<MAXBLOCK) { | 948 | cpu.ime); |
956 | asm volatile ("movem.l (%0),%%d1-%%d7/%%a0-%%a1\n\t" | 949 | if(blockcount<MAXBLOCK) |
957 | "jsr (%1)\n\t" | 950 | { |
958 | "movem.l %%d1-%%d7/%%a0-%%a1,(%0)\n\t" | 951 | asm volatile ("movem.l (%0),%%d1-%%d7/%%a0-%%a1\n\t" |
959 | : | 952 | "jsr (%1)\n\t" |
960 | : "a" (&cpu.a), "a" (b->block) | 953 | "movem.l %%d1-%%d7/%%a0-%%a1,(%0)\n\t" |
961 | : "d0", "d1", "d2", "d3", "d4", "d5", "d6", | 954 | : |
962 | "d7", "a0","a1", "a2","a3","a4"); | 955 | : "a" (&cpu.a), "a" (b->block) |
963 | clen=blockclen; | 956 | : "d0", "d1", "d2", "d3", "d4", "d5", "d6", |
964 | fdprintf(fd,"after: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 957 | "d7", "a0","a1", "a2","a3","a4"); |
965 | cpu.a,cpu.b,cpu.c,cpu.d,cpu.e,cpu.hl,cpu.f,cpu.sp, | 958 | clen=blockclen; |
966 | cpu.pc,cpu.ime); | 959 | fdprintf(fd,"after: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
967 | } | 960 | cpu.a,cpu.b,cpu.c,cpu.d,cpu.e,cpu.hl,cpu.f,cpu.sp, |
968 | else | 961 | cpu.pc,cpu.ime); |
969 | die("end"); | 962 | } |
970 | close(fd); | 963 | else |
971 | } | 964 | die("end"); |
972 | } | 965 | close(fd); |
973 | else { // Hash miss -> not found -> recompile block and add it | 966 | } |
967 | } | ||
968 | else | ||
969 | { /* Hash miss -> not found -> recompile block and add it */ | ||
974 | struct dynarec_block *newblock; | 970 | struct dynarec_block *newblock; |
975 | newblock=malloc(sizeof(struct dynarec_block)); | 971 | newblock=malloc(sizeof(struct dynarec_block)); |
976 | memset(newblock,0,sizeof(struct dynarec_block)); | 972 | memset(newblock,0,sizeof(struct dynarec_block)); |
977 | newblock->address.d=ptr+PC; | 973 | newblock->address.d=(unsigned int)(ptr)+PC; |
978 | dynamic_recompile(newblock); | 974 | dynamic_recompile(newblock); |
979 | if(p) | 975 | if(p) |
980 | p->next=newblock; | 976 | p->next=newblock; |
981 | else | 977 | else |
982 | address_map[PC&HASH_BITMASK]=newblock; | 978 | address_map[PC&HASH_BITMASK]=newblock; |
983 | } | 979 | } |
984 | } | 980 | } |
985 | #endif | 981 | #endif |
986 | 982 | ||
987 | 983 | ||
988 | 984 | ||
989 | clen <<= 1; | 985 | clen <<= 1; |
990 | div_advance(clen); | 986 | div_advance(clen); |
991 | timer_advance(clen); | 987 | timer_advance(clen); |
992 | clen >>= cpu.speed; | 988 | clen >>= cpu.speed; |
993 | lcdc_advance(clen); | 989 | lcdc_advance(clen); |
994 | sound_advance(clen); | 990 | if(options.sound) |
995 | 991 | sound_advance(clen); | |
996 | i -= clen; | 992 | |
997 | if (i > 0) goto next; | 993 | i -= clen; |
998 | return cycles-i; | 994 | if (i > 0) goto next; |
995 | return cycles-i; | ||
999 | } | 996 | } |
1000 | 997 | ||
1001 | #endif /* ASM_CPU_EMULATE */ | 998 | #endif /* ASM_CPU_EMULATE */ |
@@ -1005,9 +1002,9 @@ next: | |||
1005 | 1002 | ||
1006 | inline int cpu_step(int max) | 1003 | inline int cpu_step(int max) |
1007 | { | 1004 | { |
1008 | register int cnt; | 1005 | register int cnt; |
1009 | if ((cnt = cpu_idle(max))) return cnt; | 1006 | if ((cnt = cpu_idle(max))) return cnt; |
1010 | return cpu_emulate(1); | 1007 | return cpu_emulate(1); |
1011 | } | 1008 | } |
1012 | 1009 | ||
1013 | #endif /* ASM_CPU_STEP */ | 1010 | #endif /* ASM_CPU_STEP */ |