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