7 u8int sA, sX, sY, sP, sS;
29 if(p >= 0xffc0 && (spcmem[0xf1] & 0x80) != 0)
30 return ipl[p - 0xffc0];
31 if((p & 0xfff0) == 0x00f0)
34 return dspread(spcmem[0xf2]);
39 return reg[0x2140 | p & 3];
55 spcwrite(u16int p, u8int v)
57 if((p & 0xfff0) == 0x00f0)
61 print("SPC test register set to value %#x != 0xa\n", v);
65 reg[0x2140] = reg[0x2141] = 0;
67 reg[0x2142] = reg[0x2143] = 0;
68 if((spcmem[0xf1] & 1) == 0 && (v & 1) != 0)
69 spctimer[0] = spcmem[0xfd] = 0;
70 if((spcmem[0xf1] & 2) == 0 && (v & 2) != 0)
71 spctimer[1] = spcmem[0xfe] = 0;
72 if((spcmem[0xf1] & 4) == 0 && (v & 4) != 0)
73 spctimer[2] = spcmem[0xff] = 0;
76 dspwrite(spcmem[0xf2], v);
94 if((m & 1) != 0 && ++spctimer[0] == spcmem[0xfa]){
96 spcmem[0xfd] = (spcmem[0xfd] + 1) & 0xf;
98 if((m & 2) != 0 && ++spctimer[1] == spcmem[0xfb]){
100 spcmem[0xfe] = (spcmem[0xfe] + 1) & 0xf;
104 if((m & 4) != 0 && ++spctimer[2] == spcmem[0xfc]){
106 spcmem[0xff] = (spcmem[0xff] + 1) & 0xf;
113 return spcread(spc++);
132 a |= spcread(p) << 8;
142 if((p & 0xff) == 0xff)
146 a |= spcread(p) << 8;
153 spcwrite(0x100 | sS--, v);
159 spcwrite(0x100 | sS--, v>>8);
160 spcwrite(0x100 | sS--, v);
166 return spcread(0x100 | ++sS);
174 v = spcread(0x100 | ++sS);
175 v |= spcread(0x100 | ++sS) << 8;
179 #define imm() fetch8()
180 #define dp ((sP&SPCP)<<3)
181 #define azp() (fetch8()|dp)
182 #define azpX() ((u8int)(fetch8()+sX)|dp)
183 #define azpY() ((u8int)(fetch8()+sY)|dp)
184 #define zp() spcread(azp())
185 #define zpX() spcread(azpX())
186 #define zpY() spcread(azpY())
187 #define abs() spcread(fetch16())
188 #define absX() spcread(fetch16()+sX)
189 #define absY() spcread(fetch16()+sY)
190 #define indX() spcread(aindX())
191 #define indY() spcread(aindY())
200 a = spcread(r++ | dp);
201 a |= spcread(r | dp) << 8;
212 a = spcread(r++ | dp) + sY;
213 a += spcread(r | dp) << 8;
231 if(sA == 0 && sY == 0)
249 if(((npc ^ spc) & 0xff00) != 0)
256 clrb(u16int a, int b)
258 spcwrite(a, spcread(a) & ~(1<<b));
262 cmp(u8int a, u8int b)
264 sP &= ~(SPCZ|SPCN|SPCC);
274 adc(u8int a, u8int b)
279 r8 = r = a + b + (sP & SPCC);
280 sP &= ~(SPCC|SPCZ|SPCH|SPCV|SPCN);
284 if((a ^ b ^ r) & 0x10)
286 if((~(a ^ b) & (a ^ r)) & 0x80)
296 spcwrite(a, nz(spcread(a) + 1));
313 spcwrite(a, nz(v << 1));
324 spcwrite(a, nz(v >> 1));
341 inc16(u16int a, int c)
349 if((v & 0x8000) != 0)
369 sbc(u8int a, u8int b)
375 setb(u16int a, int b)
377 spcwrite(a, spcread(a) | (1<<b));
381 setnbit(u16int a, int c)
386 v = spcread(a & 0x1fff) & ~(1<<b);
389 spcwrite(a & 0x1fff, v);
393 tset(u16int a, int set)
413 if((sX & 0xf) <= (sY & 0xf))
417 for(i = 0; i < 9; i++){
418 v = (v << 1 | v >> 16) & 0x1ffff;
422 v = (v - x) & 0x1ffff;
435 spc = spcread(0xfffe) | spcread(0xffff) << 8;
448 print("SPC %.4x %.2x A=%.2x X=%.2x Y=%.2x P=%.2x S=%.2x\n", spc-1, op, sA, sX, sY, sP, sS);
451 case 0x01: jsr(mem16(0xffde)); return 8;
452 case 0x02: setb(azp(), 0); return 4;
453 case 0x03: return branch((zp() & 0x01) != 0, 5);
454 case 0x04: nz(sA |= zp()); return 3;
455 case 0x05: nz(sA |= abs()); return 4;
456 case 0x06: nz(sA |= spcread(sX|dp)); return 3;
457 case 0x07: nz(sA |= indX()); return 6;
458 case 0x08: nz(sA |= imm()); return 2;
459 case 0x09: b = zp(); c = azp(); spcwrite(c, nz(b | spcread(c))); return 6;
460 case 0x0A: b = fetch16(); sP |= (spcread(b & 0x1fff) >> (b >> 13)) & 1; return 4;
461 case 0x0B: asl(azp()); return 5;
462 case 0x0C: asl(fetch16()); return 5;
463 case 0x0D: push8(sP); return 4;
464 case 0x0E: tset(fetch16(), 1); return 6;
465 case 0x10: return branch((sP & SPCN) == 0, 2);
466 case 0x11: jsr(mem16(0xffdc)); return 8;
467 case 0x12: clrb(azp(), 0); return 4;
468 case 0x13: return branch((zp() & 0x01) == 0, 5);
469 case 0x14: nz(sA |= zpX()); return 4;
470 case 0x15: nz(sA |= absX()); return 5;
471 case 0x16: nz(sA |= absY()); return 5;
472 case 0x17: nz(sA |= indY()); return 6;
473 case 0x18: a = imm(); b = azp(); spcwrite(b, nz(spcread(b) | a)); return 5;
474 case 0x19: spcwrite(sX|dp, nz(spcread(sX|dp) | spcread(sY|dp))); return 5;
475 case 0x1A: inc16(azp(), -1); return 6;
476 case 0x1B: asl(azpX()); return 5;
477 case 0x1C: sP &= ~SPCC; sP |= sA >> 7; nz(sA <<= 1); return 2;
478 case 0x1D: nz(--sX); return 2;
479 case 0x1E: cmp(sX, abs()); return 4;
480 case 0x1F: spc = mem16(fetch16() + sX); return 6;
481 case 0x20: sP &= ~SPCP; return 2;
482 case 0x21: jsr(mem16(0xffda)); return 8;
483 case 0x22: setb(azp(), 1); return 4;
484 case 0x23: return branch((zp() & 0x02) != 0, 5);
485 case 0x24: nz(sA &= zp()); return 3;
486 case 0x25: nz(sA &= abs()); return 4;
487 case 0x26: nz(sA &= spcread(sX|dp)); return 3;
488 case 0x27: nz(sA &= indX()); return 6;
489 case 0x28: nz(sA &= imm()); return 2;
490 case 0x29: b = zp(); c = azp(); spcwrite(c, nz(b & spcread(c))); return 6;
491 case 0x2A: b = fetch16(); sP |= (~spcread(b & 0x1fff) >> (b >> 13)) & 1; return 4;
492 case 0x2B: rol(azp()); return 4;
493 case 0x2C: rol(fetch16()); return 5;
494 case 0x2D: push8(sA); return 4;
495 case 0x2E: return branch(sA != zp(), 5);
496 case 0x2F: return branch(1, 2);
497 case 0x30: return branch((sP & SPCN) != 0, 2);
498 case 0x31: jsr(mem16(0xffd8)); return 8;
499 case 0x32: clrb(azp(), 1); return 4;
500 case 0x33: return branch((zp() & 0x02) == 0, 5);
501 case 0x34: nz(sA &= zpX()); return 4;
502 case 0x35: nz(sA &= absX()); return 5;
503 case 0x36: nz(sA &= absY()); return 5;
504 case 0x37: nz(sA &= indY()); return 6;
505 case 0x38: a = imm(); b = azp(); spcwrite(b, nz(spcread(b) & a)); return 5;
506 case 0x39: spcwrite(sX|dp, nz(spcread(sX|dp) & spcread(sY|dp))); return 5;
507 case 0x3A: inc16(azp(), 1); return 6;
508 case 0x3B: rol(azpX()); return 5;
516 case 0x3D: nz(++sX); return 2;
517 case 0x3E: cmp(sX, zp()); return 3;
518 case 0x3F: jsr(fetch16()); return 8;
519 case 0x40: sP |= SPCP; return 2;
520 case 0x41: jsr(mem16(0xffd6)); return 8;
521 case 0x42: setb(azp(), 2); return 4;
522 case 0x43: return branch((zp() & 0x04) != 0, 5);
523 case 0x44: nz(sA ^= zp()); return 3;
524 case 0x45: nz(sA ^= abs()); return 4;
525 case 0x46: nz(sA ^= spcread(sX|dp)); return 3;
526 case 0x47: nz(sA ^= indX()); return 6;
527 case 0x48: nz(sA ^= imm()); return 2;
528 case 0x49: b = zp(); c = azp(); spcwrite(c, nz(b ^ spcread(c))); return 6;
529 case 0x4A: b = fetch16(); sP &= 0xfe | (spcread(b & 0x1fff) >> (b >> 13)) & 1; return 4;
530 case 0x4B: lsr(azp()); return 4;
531 case 0x4C: lsr(fetch16()); return 5;
532 case 0x4D: push8(sX); return 4;
533 case 0x4E: tset(fetch16(), 0); return 5;
534 case 0x4F: jsr(0xff00 | fetch8()); return 6;
535 case 0x50: return branch((sP & SPCV) == 0, 2);
536 case 0x51: jsr(mem16(0xffd4)); return 8;
537 case 0x52: clrb(azp(), 2); return 4;
538 case 0x53: return branch((zp() & 0x04) == 0, 5);
539 case 0x54: nz(sA ^= zpX()); return 4;
540 case 0x55: nz(sA ^= absX()); return 5;
541 case 0x56: nz(sA ^= absY()); return 5;
542 case 0x57: nz(sA ^= indY()); return 6;
543 case 0x58: a = imm(); b = azp(); spcwrite(b, nz(spcread(b) ^ a)); return 5;
544 case 0x59: spcwrite(sX|dp, nz(spcread(sX|dp) ^ spcread(sY|dp))); return 5;
548 sP &= ~(SPCN|SPCZ|SPCC);
553 if(((b - c) & 0x8000) != 0)
556 case 0x5B: lsr(azpX()); return 4;
557 case 0x5C: sP &= ~SPCC; sP |= sA & 1; nz(sA >>= 1); return 2;
558 case 0x5D: nz(sX = sA); return 2;
559 case 0x5E: cmp(sY, abs()); return 4;
560 case 0x5F: spc = fetch16(); return 3;
561 case 0x60: sP &= ~SPCC; return 2;
562 case 0x61: jsr(mem16(0xffd2)); return 8;
563 case 0x62: setb(azp(), 3); return 4;
564 case 0x63: return branch((zp() & 0x08) != 0, 5);
565 case 0x64: cmp(sA, zp()); return 3;
566 case 0x65: cmp(sA, abs()); return 4;
567 case 0x66: cmp(sA, spcread(sX|dp)); return 3;
568 case 0x67: cmp(sA, indX()); return 6;
569 case 0x68: cmp(sA, imm()); return 2;
570 case 0x69: a = zp(); cmp(zp(), a); return 6;
571 case 0x6A: b = fetch16(); sP &= ~((spcread(b & 0x1fff) >> (b >> 13)) & 1); return 4;
572 case 0x6B: ror(azp()); return 4;
573 case 0x6C: ror(fetch16()); return 5;
574 case 0x6D: push8(sY); return 4;
575 case 0x6E: b = azp(); a = spcread(b)-1; spcwrite(b, a); return branch(a != 0, 5);
576 case 0x6F: spc = pop16(); return 5;
577 case 0x70: return branch((sP & SPCV) != 0, 2);
578 case 0x72: clrb(azp(), 3); return 4;
579 case 0x71: jsr(mem16(0xffd0)); return 8;
580 case 0x73: return branch((zp() & 0x08) == 0, 5);
581 case 0x74: cmp(sA, zpX()); return 4;
582 case 0x75: cmp(sA, absX()); return 5;
583 case 0x76: cmp(sA, absY()); return 5;
584 case 0x77: cmp(sA, indY()); return 6;
585 case 0x78: a = imm(); cmp(zp(), a); return 5;
586 case 0x79: cmp(spcread(sX|dp), spcread(sY|dp)); return 5;
591 sY = adc(sY, b >> 8);
595 case 0x7B: ror(azpX()); return 5;
600 sA = sA >> 1 | a << 7;
603 case 0x7D: nz(sA = sX); return 2;
604 case 0x7E: cmp(sY, zp()); return 3;
605 case 0x7F: sP = pop8(); spc = pop16(); return 6;
606 case 0x80: sP |= SPCC; return 2;
607 case 0x81: jsr(mem16(0xffce)); return 8;
608 case 0x82: setb(azp(), 4); return 4;
609 case 0x83: return branch((zp() & 0x10) != 0, 5);
610 case 0x84: sA = adc(sA, zp()); return 3;
611 case 0x85: sA = adc(sA, abs()); return 4;
612 case 0x86: sA = adc(sA, spcread(sX|dp)); return 3;
613 case 0x87: sA = adc(sA, indX()); return 6;
614 case 0x88: sA = adc(sA, imm()); return 2;
615 case 0x89: b = zp(); c = azp(); spcwrite(c, adc(b, spcread(c))); return 6;
616 case 0x8A: b = fetch16(); sP ^= (spcread(b & 0x1fff) >> (b >> 13)) & 1; return 4;
617 case 0x8B: b = azp(); spcwrite(b, nz(spcread(b)-1)); return 4;
618 case 0x8C: b = fetch16(); spcwrite(b, nz(spcread(b)-1)); return 4;
619 case 0x8D: nz(sY = imm()); return 2;
620 case 0x8E: sP = pop8(); return 2;
621 case 0x8F: a = fetch8(); spcwrite(azp(), a); return 5;
622 case 0x90: return branch((sP & SPCC) == 0, 2);
623 case 0x91: jsr(mem16(0xffcc)); return 8;
624 case 0x92: clrb(azp(), 4); return 4;
625 case 0x93: return branch((zp() & 0x10) == 0, 5);
626 case 0x94: sA = adc(sA, zpX()); return 4;
627 case 0x95: sA = adc(sA, absX()); return 5;
628 case 0x96: sA = adc(sA, absY()); return 5;
629 case 0x97: sA = adc(sA, indY()); return 6;
630 case 0x98: a = imm(); b = azp(); spcwrite(b, adc(spcread(b), a)); return 5;
631 case 0x99: spcwrite(sX|dp, adc(spcread(sX|dp), spcread(sY|dp))); return 5;
636 sY = sbc(sY, b >> 8);
640 case 0x9B: b = azpX(); spcwrite(b, nz(spcread(b)-1)); return 4;
641 case 0x9C: nz(--sA); return 2;
642 case 0x9D: nz(sX = sS); return 2;
643 case 0x9E: div(); return 12;
644 case 0x9F: nz(sA = sA >> 4 | sA << 4); return 5;
645 case 0xA0: sP |= SPCI; return 2;
646 case 0xA1: jsr(mem16(0xffca)); return 8;
647 case 0xA2: setb(azp(), 5); return 4;
648 case 0xA3: return branch((zp() & 0x20) != 0, 5);
649 case 0xA4: sA = sbc(sA, zp()); return 3;
650 case 0xA5: sA = sbc(sA, abs()); return 4;
651 case 0xA6: sA = sbc(sA, spcread(sX|dp)); return 3;
652 case 0xA7: sA = sbc(sA, indX()); return 6;
653 case 0xA8: sA = sbc(sA, imm()); return 2;
654 case 0xA9: b = zp(); c = azp(); spcwrite(c, sbc(spcread(c), b)); return 6;
655 case 0xAA: b = fetch16(); sP &= ~1; sP |= (spcread(b & 0x1fff) >> (b >> 13)) & 1; return 4;
656 case 0xAB: inc(azp()); return 4;
657 case 0xAC: inc(fetch16()); return 5;
658 case 0xAD: cmp(sY, imm()); return 2;
659 case 0xAE: sA = pop8(); return 2;
660 case 0xAF: spcwrite(sX++|dp, sA); return 4;
661 case 0xB0: return branch((sP & SPCC) != 0, 2);
662 case 0xB1: jsr(mem16(0xffc8)); return 8;
663 case 0xB2: clrb(azp(), 5); return 4;
664 case 0xB3: return branch((zp() & 0x20) == 0, 5);
665 case 0xB4: sA = sbc(sA, zpX()); return 4;
666 case 0xB5: sA = sbc(sA, absX()); return 5;
667 case 0xB6: sA = sbc(sA, absY()); return 5;
668 case 0xB7: sA = sbc(sA, indY()); return 6;
669 case 0xB8: a = imm(); b = azp(); spcwrite(b, sbc(spcread(b), a)); return 5;
670 case 0xB9: spcwrite(sX|dp, sbc(spcread(sX|dp), spcread(sY|dp))); return 5;
671 case 0xBA: a = fetch8(); sA = spcread(a++|dp); sY = spcread(a|dp); nz16(); return 5;
672 case 0xBB: inc(azpX()); return 4;
673 case 0xBC: nz(++sA); return 2;
674 case 0xBD: sS = sX; return 2;
675 case 0xBF: nz(sA = spcread(sX++|dp)); return 3;
676 case 0xC0: sP &= ~SPCI; return 2;
677 case 0xC1: jsr(mem16(0xffc6)); return 8;
678 case 0xC2: setb(azp(), 6); return 4;
679 case 0xC3: return branch((zp() & 0x40) != 0, 5);
680 case 0xC4: spcwrite(azp(), sA); return 4;
681 case 0xC5: spcwrite(fetch16(), sA); return 5;
682 case 0xC6: spcwrite(sX|dp, sA); return 4;
683 case 0xC7: spcwrite(aindX(), sA); return 7;
684 case 0xC8: cmp(sX, imm()); return 2;
685 case 0xC9: spcwrite(fetch16(), sX); return 5;
686 case 0xCA: b = fetch16(); setnbit(b, sP & SPCC); return 6;
687 case 0xCB: spcwrite(azp(), sY); return 4;
688 case 0xCC: spcwrite(fetch16(), sY); return 5;
689 case 0xCD: nz(sX = imm()); return 2;
690 case 0xCE: sX = pop8(); return 2;
691 case 0xCF: b = sY * sA; nz(sY = b >> 8); sA = b; return 9;
692 case 0xD0: return branch((sP & SPCZ) == 0, 2);
693 case 0xD1: jsr(mem16(0xffc4)); return 8;
694 case 0xD2: clrb(azp(), 6); return 4;
695 case 0xD3: return branch((zp() & 0x40) == 0, 5);
696 case 0xD4: spcwrite(azpX(), sA); return 4;
697 case 0xD5: spcwrite(fetch16() + sX, sA); return 6;
698 case 0xD6: spcwrite(fetch16() + sY, sA); return 6;
699 case 0xD7: spcwrite(aindY(), sA); return 7;
700 case 0xD8: spcwrite(azp(), sX); return 4;
701 case 0xD9: spcwrite(azpY(), sX); return 5;
702 case 0xDA: a = fetch8(); spcwrite(a++|dp, sA); spcwrite(a|dp, sY); return 5;
703 case 0xDB: spcwrite(azpX(), sY); return 5;
704 case 0xDC: nz(--sY); return 2;
705 case 0xDD: nz(sA = sY); return 2;
706 case 0xDE: return branch(sA != zpX(), 6);
707 case 0xE0: sP &= ~(SPCV|SPCH); return 2;
708 case 0xE1: jsr(mem16(0xffc2)); return 8;
709 case 0xE2: setb(azp(), 7); return 4;
710 case 0xE3: return branch((zp() & 0x80) != 0, 5);
711 case 0xE4: nz(sA = zp()); return 3;
712 case 0xE5: nz(sA = abs()); return 4;
713 case 0xE6: nz(sA = spcread(sX|dp)); return 3;
714 case 0xE7: nz(sA = indX()); return 6;
715 case 0xE8: nz(sA = imm()); return 2;
716 case 0xE9: nz(sX = abs()); return 4;
717 case 0xEA: b = fetch16(); spcwrite(b & 0x1fff, spcread(b & 0x1fff) ^ (1<<(b>>13))); return 6;
718 case 0xEB: nz(sY = zp()); return 3;
719 case 0xEC: nz(sY = abs()); return 4;
720 case 0xED: sP ^= SPCC; return 3;
721 case 0xEE: sY = pop8(); return 4;
722 case 0xF0: return branch((sP & SPCZ) != 0, 2);
723 case 0xF1: jsr(mem16(0xffc0)); return 8;
724 case 0xF2: clrb(azp(), 7); return 4;
725 case 0xF3: return branch((zp() & 0x80) == 0, 5);
726 case 0xF4: nz(sA = zpX()); return 4;
727 case 0xF5: nz(sA = absX()); return 5;
728 case 0xF6: nz(sA = absY()); return 5;
729 case 0xF7: nz(sA = indY()); return 6;
730 case 0xF8: nz(sX = zp()); return 3;
731 case 0xF9: nz(sX = zpY()); return 4;
732 case 0xFA: a = zp(); spcwrite(azp(), a); return 5;
733 case 0xFB: nz(sY = zpX()); return 4;
734 case 0xFC: nz(++sY); return 2;
735 case 0xFD: nz(sY = sA); return 2;
736 case 0xFE: return branch(--sY, 4);
738 print("undefined spc op %.2x at %.4x\n", op, spc-1);
743 static u8int ipl[64] = {
744 0xcd, 0xef, 0xbd, 0xe8, 0x00, 0xc6, 0x1d, 0xd0, 0xfc, 0x8f, 0xaa, 0xf4, 0x8f, 0xbb, 0xf5, 0x78,
745 0xcc, 0xf4, 0xd0, 0xfb, 0x2f, 0x19, 0xeb, 0xf4, 0xd0, 0xfc, 0x7e, 0xf4, 0xd0, 0x0b, 0xe4, 0xf5,
746 0xcb, 0xf4, 0xd7, 0x00, 0xfc, 0xd0, 0xf3, 0xab, 0x01, 0x10, 0xef, 0x7e, 0xf4, 0x10, 0xeb, 0xba,
747 0xf6, 0xda, 0x00, 0xba, 0xf4, 0xc4, 0xf4, 0xdd, 0x5d, 0xd0, 0xdb, 0x1f, 0x00, 0x00, 0xc0, 0xff,