#include "../copyright" #ifndef USE_BLARGG_APU #include "snes9x.h" #include "spc700.h" #include "memmap.h" #include "display.h" #include "cpuexec.h" #include "apu.h" #include "apumem.h" int8_t Int8 = 0; int16_t Int16 = 0; int32_t Int32 = 0; uint8_t W1; uint8_t W2; uint8_t Work8 = 0; uint16_t Work16 = 0; uint32_t Work32 = 0; #define OP1 IAPU.PC[1] #define OP2 IAPU.PC[2] #define APUShutdown() \ if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \ { \ if (IAPU.WaitCounter == 0) \ { \ if (!ICPU.CPUExecuting) \ APU.Cycles = CPU.Cycles = CPU.NextEvent; \ else \ IAPU.APUExecuting = false; \ } \ else if (IAPU.WaitCounter >= 2) \ IAPU.WaitCounter = 1; \ else \ IAPU.WaitCounter--; \ } #define APUSetZN8(b) \ IAPU._Zero = (b) #define APUSetZN16(w) \ IAPU._Zero = ((w) != 0) | ((w) >> 8) #define TCALL(n) \ {\ PushW (IAPU.PC - IAPU.RAM + 1); \ IAPU.PC = IAPU.RAM + S9xAPUGetByte(0xffc0 + ((15 - n) << 1)) + \ (S9xAPUGetByte(0xffc1 + ((15 - n) << 1)) << 8); \ } #define SBC(a, b) \ Int16 = (int16_t) (a) - (int16_t) (b) + (int16_t) (APUCheckCarry ()) - 1; \ IAPU._Carry = Int16 >= 0; \ if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8_t) Int16) & 0x80)) \ APUSetOverflow (); \ else \ APUClearOverflow (); \ APUSetHalfCarry (); \ if(((a) ^ (b) ^ (uint8_t) Int16) & 0x10) \ APUClearHalfCarry (); \ (a) = (uint8_t) Int16; \ APUSetZN8 ((uint8_t) Int16) #define ADC(a,b) \ Work16 = (a) + (b) + APUCheckCarry(); \ IAPU._Carry = Work16 >= 0x100; \ if (~((a) ^ (b)) & ((b) ^ (uint8_t) Work16) & 0x80) \ APUSetOverflow (); \ else \ APUClearOverflow (); \ APUClearHalfCarry (); \ if(((a) ^ (b) ^ (uint8_t) Work16) & 0x10) \ APUSetHalfCarry (); \ (a) = (uint8_t) Work16; \ APUSetZN8 ((uint8_t) Work16) #define CMP(a,b) \ Int16 = (int16_t) (a) - (int16_t) (b); \ IAPU._Carry = Int16 >= 0; \ APUSetZN8((uint8_t) Int16) #define ASL(b) \ IAPU._Carry = ((b) & 0x80) != 0; \ (b) <<= 1; \ APUSetZN8 (b) #define LSR(b) \ IAPU._Carry = (b) & 1; \ (b) >>= 1; \ APUSetZN8 (b) #define ROL(b) \ Work16 = ((b) << 1) | APUCheckCarry (); \ IAPU._Carry = Work16 >= 0x100; \ (b) = (uint8_t) Work16; \ APUSetZN8 (b) #define ROR(b) \ Work16 = (b) | ((uint16_t) APUCheckCarry () << 8); \ IAPU._Carry = (uint8_t) Work16 & 1; \ Work16 >>= 1; \ (b) = (uint8_t) Work16; \ APUSetZN8 (b) #define Push(b) \ IAPU.RAM[0x100 + IAPU.Registers.S] = b; \ IAPU.Registers.S-- #define Pop(b) \ IAPU.Registers.S++; \ (b) = IAPU.RAM[0x100 + IAPU.Registers.S] #ifdef FAST_LSB_WORD_ACCESS #define PushW(w) \ if (IAPU.Registers.S == 0) \ {\ IAPU.RAM[0x1ff] = (w); \ IAPU.RAM[0x100] = ((w) >> 8); \ } \ else \ *(uint16_t *) (IAPU.RAM + 0xff + IAPU.Registers.S) = w; \ IAPU.Registers.S -= 2 #define PopW(w) \ IAPU.Registers.S += 2; \ if (IAPU.Registers.S == 0) \ (w) = IAPU.RAM[0x1ff] | (IAPU.RAM[0x100] << 8); \ else \ (w) = *(uint16_t *) (IAPU.RAM + 0xff + IAPU.Registers.S) #else #define PushW(w) \ IAPU.RAM[0xff + IAPU.Registers.S] = w; \ IAPU.RAM[0x100 + IAPU.Registers.S] = ((w) >> 8); \ IAPU.Registers.S -= 2 #define PopW(w) \ IAPU.Registers.S += 2; \ if(IAPU.Registers.S == 0) \ (w) = IAPU.RAM[0x1ff] | (IAPU.RAM[0x100] << 8); \ else \ (w) = IAPU.RAM[0xff + IAPU.Registers.S] + (IAPU.RAM[0x100 + IAPU.Registers.S] << 8) #endif #define Relative() \ Int8 = OP1; \ Int16 = (int16_t) (IAPU.PC + 2 - IAPU.RAM) + Int8; #define Relative2() \ Int8 = OP2; \ Int16 = (int16_t) (IAPU.PC + 3 - IAPU.RAM) + Int8; #ifdef FAST_LSB_WORD_ACCESS #define IndexedXIndirect() \ IAPU.Address = *(uint16_t *) (IAPU.DirectPage + ((OP1 + IAPU.Registers.X) & 0xff)); #define Absolute() \ IAPU.Address = *(uint16_t *) (IAPU.PC + 1); #define AbsoluteX() \ IAPU.Address = *(uint16_t *) (IAPU.PC + 1) + IAPU.Registers.X; #define AbsoluteY() \ IAPU.Address = *(uint16_t *) (IAPU.PC + 1) + IAPU.Registers.YA.B.Y; #define MemBit() \ IAPU.Address = *(uint16_t *) (IAPU.PC + 1); \ IAPU.Bit = (uint8_t)(IAPU.Address >> 13); \ IAPU.Address &= 0x1fff; #define IndirectIndexedY() \ IAPU.Address = *(uint16_t *) (IAPU.DirectPage + OP1) + IAPU.Registers.YA.B.Y; #else #define IndexedXIndirect() \ IAPU.Address = IAPU.DirectPage[(OP1 + IAPU.Registers.X) & 0xff] + \ (IAPU.DirectPage[(OP1 + IAPU.Registers.X + 1) & 0xff] << 8); #define Absolute() \ IAPU.Address = OP1 + (OP2 << 8); #define AbsoluteX() \ IAPU.Address = OP1 + (OP2 << 8) + IAPU.Registers.X; #define AbsoluteY() \ IAPU.Address = OP1 + (OP2 << 8) + IAPU.Registers.YA.B.Y; #define MemBit() \ IAPU.Address = OP1 + (OP2 << 8); \ IAPU.Bit = (int8_t) (IAPU.Address >> 13); \ IAPU.Address &= 0x1fff; #define IndirectIndexedY() \ IAPU.Address = IAPU.DirectPage[OP1] + \ (IAPU.DirectPage[OP1 + 1] << 8) + \ IAPU.Registers.YA.B.Y; #endif void Apu00(void) /* NOP */ { IAPU.PC++; } void Apu01(void) { TCALL(0); } void Apu11(void) { TCALL(1); } void Apu21(void) { TCALL(2); } void Apu31(void) { TCALL(3); } void Apu41(void) { TCALL(4); } void Apu51(void) { TCALL(5); } void Apu61(void) { TCALL(6); } void Apu71(void) { TCALL(7); } void Apu81(void) { TCALL(8); } void Apu91(void) { TCALL(9); } void ApuA1(void) { TCALL(10); } void ApuB1(void) { TCALL(11); } void ApuC1(void) { TCALL(12); } void ApuD1(void) { TCALL(13); } void ApuE1(void) { TCALL(14); } void ApuF1(void) { TCALL(15); } void Apu3F(void) /* CALL absolute */ { Absolute(); /* 0xB6f for Star Fox 2 */ PushW(IAPU.PC + 3 - IAPU.RAM); IAPU.PC = IAPU.RAM + IAPU.Address; } void Apu4F(void) /* PCALL $XX */ { Work8 = OP1; PushW(IAPU.PC + 2 - IAPU.RAM); IAPU.PC = IAPU.RAM + 0xff00 + Work8; } #define SET(b) \ S9xAPUSetByteZ ((uint8_t) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \ IAPU.PC += 2 void Apu02(void) { SET(0); } void Apu22(void) { SET(1); } void Apu42(void) { SET(2); } void Apu62(void) { SET(3); } void Apu82(void) { SET(4); } void ApuA2(void) { SET(5); } void ApuC2(void) { SET(6); } void ApuE2(void) { SET(7); } #define CLR(b) \ S9xAPUSetByteZ ((uint8_t) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \ IAPU.PC += 2; void Apu12(void) { CLR(0); } void Apu32(void) { CLR(1); } void Apu52(void) { CLR(2); } void Apu72(void) { CLR(3); } void Apu92(void) { CLR(4); } void ApuB2(void) { CLR(5); } void ApuD2(void) { CLR(6); } void ApuF2(void) { CLR(7); } #define BBS(b) \ Work8 = OP1; \ Relative2 (); \ if (S9xAPUGetByteZ (Work8) & (1 << (b))) \ { \ IAPU.PC = IAPU.RAM + (uint16_t) Int16; \ APU.Cycles += IAPU.TwoCycles; \ } \ else \ IAPU.PC += 3 void Apu03(void) { BBS(0); } void Apu23(void) { BBS(1); } void Apu43(void) { BBS(2); } void Apu63(void) { BBS(3); } void Apu83(void) { BBS(4); } void ApuA3(void) { BBS(5); } void ApuC3(void) { BBS(6); } void ApuE3(void) { BBS(7); } #define BBC(b) \ Work8 = OP1; \ Relative2 (); \ if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \ { \ IAPU.PC = IAPU.RAM + (uint16_t) Int16; \ APU.Cycles += IAPU.TwoCycles; \ } \ else \ IAPU.PC += 3 void Apu13(void) { BBC(0); } void Apu33(void) { BBC(1); } void Apu53(void) { BBC(2); } void Apu73(void) { BBC(3); } void Apu93(void) { BBC(4); } void ApuB3(void) { BBC(5); } void ApuD3(void) { BBC(6); } void ApuF3(void) { BBC(7); } void Apu04(void) { /* OR A,dp */ IAPU.Registers.YA.B.A |= S9xAPUGetByteZ(OP1); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu05(void) { /* OR A,abs */ Absolute(); IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu06(void) { /* OR A,(X) */ IAPU.Registers.YA.B.A |= S9xAPUGetByteZ(IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu07(void) { /* OR A,(dp+X) */ IndexedXIndirect(); IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu08(void) { /* OR A,#00 */ IAPU.Registers.YA.B.A |= OP1; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu09(void) { /* OR dp(dest),dp(src) */ Work8 = S9xAPUGetByteZ(OP1); Work8 |= S9xAPUGetByteZ(OP2); S9xAPUSetByteZ(Work8, OP2); APUSetZN8(Work8); IAPU.PC += 3; } void Apu14(void) { /* OR A,dp+X */ IAPU.Registers.YA.B.A |= S9xAPUGetByteZ(OP1 + IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu15(void) { /* OR A,abs+X */ AbsoluteX(); IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu16(void) { /* OR A,abs+Y */ AbsoluteY(); IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu17(void) { /* OR A,(dp)+Y */ IndirectIndexedY(); IAPU.Registers.YA.B.A |= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu18(void) { /* OR dp,#00 */ Work8 = OP1; Work8 |= S9xAPUGetByteZ(OP2); S9xAPUSetByteZ(Work8, OP2); APUSetZN8(Work8); IAPU.PC += 3; } void Apu19(void) { /* OR (X),(Y) */ Work8 = S9xAPUGetByteZ(IAPU.Registers.X) | S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); APUSetZN8(Work8); S9xAPUSetByteZ(Work8, IAPU.Registers.X); IAPU.PC++; } void Apu0A(void) { /* OR1 C,membit */ MemBit(); if (!APUCheckCarry()) if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) APUSetCarry(); IAPU.PC += 3; } void Apu2A(void) { /* OR1 C,not membit */ MemBit(); if (!APUCheckCarry()) if (!(S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit))) APUSetCarry(); IAPU.PC += 3; } void Apu4A(void) { /* AND1 C,membit */ MemBit(); if (APUCheckCarry()) if (!(S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit))) APUClearCarry(); IAPU.PC += 3; } void Apu6A(void) { /* AND1 C, not membit */ MemBit(); if (APUCheckCarry()) if ((S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit))) APUClearCarry(); IAPU.PC += 3; } void Apu8A(void) { /* EOR1 C, membit */ MemBit(); if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) { if (APUCheckCarry()) APUClearCarry(); else APUSetCarry(); } IAPU.PC += 3; } void ApuAA(void) { /* MOV1 C,membit */ MemBit(); if (S9xAPUGetByte(IAPU.Address) & (1 << IAPU.Bit)) APUSetCarry(); else APUClearCarry(); IAPU.PC += 3; } void ApuCA(void) { /* MOV1 membit,C */ MemBit(); if (APUCheckCarry()) S9xAPUSetByte(S9xAPUGetByte(IAPU.Address) | (1 << IAPU.Bit), IAPU.Address); else S9xAPUSetByte(S9xAPUGetByte(IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address); IAPU.PC += 3; } void ApuEA(void) { /* NOT1 membit */ MemBit(); S9xAPUSetByte(S9xAPUGetByte(IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address); IAPU.PC += 3; } void Apu0B(void) { /* ASL dp */ Work8 = S9xAPUGetByteZ(OP1); ASL(Work8); S9xAPUSetByteZ(Work8, OP1); IAPU.PC += 2; } void Apu0C(void) { /* ASL abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); ASL(Work8); S9xAPUSetByte(Work8, IAPU.Address); IAPU.PC += 3; } void Apu1B(void) { /* ASL dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); ASL(Work8); S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu1C(void) { /* ASL A */ ASL(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu0D(void) { /* PUSH PSW */ S9xAPUPackStatus(); Push(IAPU.Registers.P); IAPU.PC++; } void Apu2D(void) { /* PUSH A */ Push(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu4D(void) { /* PUSH X */ Push(IAPU.Registers.X); IAPU.PC++; } void Apu6D(void) { /* PUSH Y */ Push(IAPU.Registers.YA.B.Y); IAPU.PC++; } void Apu8E(void) { /* POP PSW */ Pop(IAPU.Registers.P); S9xAPUUnpackStatus(); if (APUCheckDirectPage()) IAPU.DirectPage = IAPU.RAM + 0x100; else IAPU.DirectPage = IAPU.RAM; IAPU.PC++; } void ApuAE(void) { /* POP A */ Pop(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuCE(void) { /* POP X */ Pop(IAPU.Registers.X); IAPU.PC++; } void ApuEE(void) { /* POP Y */ Pop(IAPU.Registers.YA.B.Y); IAPU.PC++; } void Apu0E(void) { /* TSET1 abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); S9xAPUSetByte(Work8 | IAPU.Registers.YA.B.A, IAPU.Address); Work8 = IAPU.Registers.YA.B.A - Work8; APUSetZN8(Work8); IAPU.PC += 3; } void Apu4E(void) { /* TCLR1 abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); S9xAPUSetByte(Work8 & ~IAPU.Registers.YA.B.A, IAPU.Address); Work8 = IAPU.Registers.YA.B.A - Work8; APUSetZN8(Work8); IAPU.PC += 3; } void Apu0F(void) { /* BRK */ PushW(IAPU.PC + 1 - IAPU.RAM); S9xAPUPackStatus(); Push(IAPU.Registers.P); APUSetBreak(); APUClearInterrupt(); IAPU.PC = IAPU.RAM + S9xAPUGetByte(0xffde) + (S9xAPUGetByte(0xffdf) << 8); } void ApuEF(void) { /* SLEEP */ APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = false; IAPU.APUExecuting = false; } void ApuFF(void) { /* STOP */ APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = false; IAPU.APUExecuting = false; Settings.APUEnabled = false; /* re-enabled on next APU reset */ } void Apu10(void) { /* BPL */ Relative(); if (!APUCheckNegative()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 2; } void Apu30(void) { /* BMI */ Relative(); if (APUCheckNegative()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 2; } void Apu90(void) { /* BCC */ Relative(); if (!APUCheckCarry()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 2; } void ApuB0(void) { /* BCS */ Relative(); if (APUCheckCarry()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 2; } void ApuD0(void) { /* BNE */ Relative(); if (!APUCheckZero()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 2; } void ApuF0(void) { /* BEQ */ Relative(); if (APUCheckZero()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 2; } void Apu50(void) { /* BVC */ Relative(); if (!APUCheckOverflow()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; } else IAPU.PC += 2; } void Apu70(void) { /* BVS */ Relative(); if (APUCheckOverflow()) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; } else IAPU.PC += 2; } void Apu2F(void) { /* BRA */ Relative(); IAPU.PC = IAPU.RAM + (uint16_t) Int16; } void Apu80(void) { /* SETC */ APUSetCarry(); IAPU.PC++; } void ApuED(void) { /* NOTC */ IAPU._Carry ^= 1; IAPU.PC++; } void Apu40(void) { /* SETP */ APUSetDirectPage(); IAPU.DirectPage = IAPU.RAM + 0x100; IAPU.PC++; } void Apu1A(void) { /* DECW dp */ Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8) - 1; S9xAPUSetByteZ((uint8_t) Work16, OP1); S9xAPUSetByteZ(Work16 >> 8, OP1 + 1); APUSetZN16(Work16); IAPU.PC += 2; } void Apu5A(void) { /* CMPW YA,dp */ Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); Int32 = (int32_t) IAPU.Registers.YA.W - (int32_t) Work16; IAPU._Carry = Int32 >= 0; APUSetZN16((uint16_t) Int32); IAPU.PC += 2; } void Apu3A(void) { /* INCW dp */ Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8) + 1; S9xAPUSetByteZ((uint8_t) Work16, OP1); S9xAPUSetByteZ(Work16 >> 8, OP1 + 1); APUSetZN16(Work16); IAPU.PC += 2; } void Apu7A(void) { /* ADDW YA,dp */ Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); Work32 = (uint32_t) IAPU.Registers.YA.W + Work16; IAPU._Carry = Work32 >= 0x10000; if (~(IAPU.Registers.YA.W ^ Work16) & (Work16 ^ (uint16_t) Work32) & 0x8000) APUSetOverflow(); else APUClearOverflow(); APUClearHalfCarry(); if ((IAPU.Registers.YA.W ^ Work16 ^ (uint16_t) Work32) & 0x1000) APUSetHalfCarry(); IAPU.Registers.YA.W = (uint16_t) Work32; APUSetZN16(IAPU.Registers.YA.W); IAPU.PC += 2; } void Apu9A(void) { /* SUBW YA,dp */ Work16 = S9xAPUGetByteZ(OP1) + (S9xAPUGetByteZ(OP1 + 1) << 8); Int32 = (int32_t) IAPU.Registers.YA.W - (int32_t) Work16; APUClearHalfCarry(); IAPU._Carry = Int32 >= 0; if (((IAPU.Registers.YA.W ^ Work16) & 0x8000) && ((IAPU.Registers.YA.W ^ (uint16_t) Int32) & 0x8000)) APUSetOverflow(); else APUClearOverflow(); APUSetHalfCarry(); if ((IAPU.Registers.YA.W ^ Work16 ^ (uint16_t) Int32) & 0x1000) APUClearHalfCarry(); IAPU.Registers.YA.W = (uint16_t) Int32; APUSetZN16(IAPU.Registers.YA.W); IAPU.PC += 2; } void ApuBA(void) { /* MOVW YA,dp */ IAPU.Registers.YA.B.A = S9xAPUGetByteZ(OP1); IAPU.Registers.YA.B.Y = S9xAPUGetByteZ(OP1 + 1); APUSetZN16(IAPU.Registers.YA.W); IAPU.PC += 2; } void ApuDA(void) { /* MOVW dp,YA */ S9xAPUSetByteZ(IAPU.Registers.YA.B.A, OP1); S9xAPUSetByteZ(IAPU.Registers.YA.B.Y, OP1 + 1); IAPU.PC += 2; } void Apu64(void) { /* CMP A,dp */ Work8 = S9xAPUGetByteZ(OP1); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu65(void) { /* CMP A,abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu66(void) { /* CMP A,(X) */ Work8 = S9xAPUGetByteZ(IAPU.Registers.X); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC++; } void Apu67(void) { /* CMP A,(dp+X) */ IndexedXIndirect(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu68(void) { /* CMP A,#00 */ Work8 = OP1; CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu69(void) { /* CMP dp(dest), dp(src) */ W1 = S9xAPUGetByteZ(OP1); Work8 = S9xAPUGetByteZ(OP2); CMP(Work8, W1); IAPU.PC += 3; } void Apu74(void) { /* CMP A, dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu75(void) { /* CMP A,abs+X */ AbsoluteX(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu76(void) { /* CMP A, abs+Y */ AbsoluteY(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu77(void) { /* CMP A,(dp)+Y */ IndirectIndexedY(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu78(void) { /* CMP dp,#00 */ Work8 = OP1; W1 = S9xAPUGetByteZ(OP2); CMP(W1, Work8); IAPU.PC += 3; } void Apu79(void) { /* CMP (X),(Y) */ W1 = S9xAPUGetByteZ(IAPU.Registers.X); Work8 = S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); CMP(W1, Work8); IAPU.PC++; } void Apu1E(void) { /* CMP X,abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.X, Work8); IAPU.PC += 3; } void Apu3E(void) { /* CMP X,dp */ Work8 = S9xAPUGetByteZ(OP1); CMP(IAPU.Registers.X, Work8); IAPU.PC += 2; } void ApuC8(void) { /* CMP X,#00 */ CMP(IAPU.Registers.X, OP1); IAPU.PC += 2; } void Apu5E(void) { /* CMP Y,abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); CMP(IAPU.Registers.YA.B.Y, Work8); IAPU.PC += 3; } void Apu7E(void) { /* CMP Y,dp */ Work8 = S9xAPUGetByteZ(OP1); CMP(IAPU.Registers.YA.B.Y, Work8); IAPU.PC += 2; } void ApuAD(void) { /* CMP Y,#00 */ Work8 = OP1; CMP(IAPU.Registers.YA.B.Y, Work8); IAPU.PC += 2; } void Apu1F(void) { /* JMP (abs+X) */ Absolute(); IAPU.PC = IAPU.RAM + S9xAPUGetByte(IAPU.Address + IAPU.Registers.X) + (S9xAPUGetByte(IAPU.Address + IAPU.Registers.X + 1) << 8); } void Apu5F(void) { /* JMP abs */ Absolute(); IAPU.PC = IAPU.RAM + IAPU.Address; } void Apu20(void) { /* CLRP */ APUClearDirectPage(); IAPU.DirectPage = IAPU.RAM; IAPU.PC++; } void Apu60(void) { /* CLRC */ APUClearCarry(); IAPU.PC++; } void ApuE0(void) { /* CLRV */ APUClearHalfCarry(); APUClearOverflow(); IAPU.PC++; } void Apu24(void) { /* AND A,dp */ IAPU.Registers.YA.B.A &= S9xAPUGetByteZ(OP1); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu25(void) { /* AND A,abs */ Absolute(); IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu26(void) { /* AND A,(X) */ IAPU.Registers.YA.B.A &= S9xAPUGetByteZ(IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu27(void) { /* AND A,(dp+X) */ IndexedXIndirect(); IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu28(void) { /* AND A,#00 */ IAPU.Registers.YA.B.A &= OP1; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu29(void) { /* AND dp(dest),dp(src) */ Work8 = S9xAPUGetByteZ(OP1); Work8 &= S9xAPUGetByteZ(OP2); S9xAPUSetByteZ(Work8, OP2); APUSetZN8(Work8); IAPU.PC += 3; } void Apu34(void) { /* AND A,dp+X */ IAPU.Registers.YA.B.A &= S9xAPUGetByteZ(OP1 + IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu35(void) { /* AND A,abs+X */ AbsoluteX(); IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu36(void) { /* AND A,abs+Y */ AbsoluteY(); IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu37(void) { /* AND A,(dp)+Y */ IndirectIndexedY(); IAPU.Registers.YA.B.A &= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu38(void) { /* AND dp,#00 */ Work8 = OP1; Work8 &= S9xAPUGetByteZ(OP2); S9xAPUSetByteZ(Work8, OP2); APUSetZN8(Work8); IAPU.PC += 3; } void Apu39(void) { /* AND (X),(Y) */ Work8 = S9xAPUGetByteZ(IAPU.Registers.X) & S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); APUSetZN8(Work8); S9xAPUSetByteZ(Work8, IAPU.Registers.X); IAPU.PC++; } void Apu2B(void) { /* ROL dp */ Work8 = S9xAPUGetByteZ(OP1); ROL(Work8); S9xAPUSetByteZ(Work8, OP1); IAPU.PC += 2; } void Apu2C(void) { /* ROL abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); ROL(Work8); S9xAPUSetByte(Work8, IAPU.Address); IAPU.PC += 3; } void Apu3B(void) { /* ROL dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); ROL(Work8); S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu3C(void) { /* ROL A */ ROL(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu2E(void) { /* CBNE dp,rel */ Work8 = OP1; Relative2(); if (S9xAPUGetByteZ(Work8) != IAPU.Registers.YA.B.A) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 3; } void ApuDE(void) { /* CBNE dp+X,rel */ Work8 = OP1 + IAPU.Registers.X; Relative2(); if (S9xAPUGetByteZ(Work8) != IAPU.Registers.YA.B.A) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; APUShutdown(); } else IAPU.PC += 3; } void Apu3D(void) { /* INC X */ IAPU.Registers.X++; APUSetZN8(IAPU.Registers.X); IAPU.WaitCounter++; IAPU.PC++; } void ApuFC(void) { /* INC Y */ IAPU.Registers.YA.B.Y++; APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.WaitCounter++; IAPU.PC++; } void Apu1D(void) { /* DEC X */ IAPU.Registers.X--; APUSetZN8(IAPU.Registers.X); IAPU.WaitCounter++; IAPU.PC++; } void ApuDC(void) { /* DEC Y */ IAPU.Registers.YA.B.Y--; APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.WaitCounter++; IAPU.PC++; } void ApuAB(void) { /* INC dp */ Work8 = S9xAPUGetByteZ(OP1) + 1; S9xAPUSetByteZ(Work8, OP1); APUSetZN8(Work8); IAPU.WaitCounter++; IAPU.PC += 2; } void ApuAC(void) { /* INC abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address) + 1; S9xAPUSetByte(Work8, IAPU.Address); APUSetZN8(Work8); IAPU.WaitCounter++; IAPU.PC += 3; } void ApuBB(void) { /* INC dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X) + 1; S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); APUSetZN8(Work8); IAPU.WaitCounter++; IAPU.PC += 2; } void ApuBC(void) { /* INC A */ IAPU.Registers.YA.B.A++; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.WaitCounter++; IAPU.PC++; } void Apu8B(void) { /* DEC dp */ Work8 = S9xAPUGetByteZ(OP1) - 1; S9xAPUSetByteZ(Work8, OP1); APUSetZN8(Work8); IAPU.WaitCounter++; IAPU.PC += 2; } void Apu8C(void) { /* DEC abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address) - 1; S9xAPUSetByte(Work8, IAPU.Address); APUSetZN8(Work8); IAPU.WaitCounter++; IAPU.PC += 3; } void Apu9B(void) { /* DEC dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X) - 1; S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); APUSetZN8(Work8); IAPU.WaitCounter++; IAPU.PC += 2; } void Apu9C(void) { /* DEC A */ IAPU.Registers.YA.B.A--; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.WaitCounter++; IAPU.PC++; } void Apu44(void) { /* EOR A,dp */ IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ(OP1); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu45(void) { /* EOR A,abs */ Absolute(); IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu46(void) { /* EOR A,(X) */ IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ(IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu47(void) { /* EOR A,(dp+X) */ IndexedXIndirect(); IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu48(void) { /* EOR A,#00 */ IAPU.Registers.YA.B.A ^= OP1; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu49(void) { /* EOR dp(dest),dp(src) */ Work8 = S9xAPUGetByteZ(OP1); Work8 ^= S9xAPUGetByteZ(OP2); S9xAPUSetByteZ(Work8, OP2); APUSetZN8(Work8); IAPU.PC += 3; } void Apu54(void) { /* EOR A,dp+X */ IAPU.Registers.YA.B.A ^= S9xAPUGetByteZ(OP1 + IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu55(void) { /* EOR A,abs+X */ AbsoluteX(); IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu56(void) { /* EOR A,abs+Y */ AbsoluteY(); IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void Apu57(void) { /* EOR A,(dp)+Y */ IndirectIndexedY(); IAPU.Registers.YA.B.A ^= S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void Apu58(void) { /* EOR dp,#00 */ Work8 = OP1; Work8 ^= S9xAPUGetByteZ(OP2); S9xAPUSetByteZ(Work8, OP2); APUSetZN8(Work8); IAPU.PC += 3; } void Apu59(void) { /* EOR (X),(Y) */ Work8 = S9xAPUGetByteZ(IAPU.Registers.X) ^ S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); APUSetZN8(Work8); S9xAPUSetByteZ(Work8, IAPU.Registers.X); IAPU.PC++; } void Apu4B(void) { /* LSR dp */ Work8 = S9xAPUGetByteZ(OP1); LSR(Work8); S9xAPUSetByteZ(Work8, OP1); IAPU.PC += 2; } void Apu4C(void) { /* LSR abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); LSR(Work8); S9xAPUSetByte(Work8, IAPU.Address); IAPU.PC += 3; } void Apu5B(void) { /* LSR dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); LSR(Work8); S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu5C(void) { /* LSR A */ LSR(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu7D(void) { /* MOV A,X */ IAPU.Registers.YA.B.A = IAPU.Registers.X; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuDD(void) { /* MOV A,Y */ IAPU.Registers.YA.B.A = IAPU.Registers.YA.B.Y; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu5D(void) { /* MOV X,A */ IAPU.Registers.X = IAPU.Registers.YA.B.A; APUSetZN8(IAPU.Registers.X); IAPU.PC++; } void ApuFD(void) { /* MOV Y,A */ IAPU.Registers.YA.B.Y = IAPU.Registers.YA.B.A; APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.PC++; } void Apu9D(void) { /* MOV X,SP */ IAPU.Registers.X = IAPU.Registers.S; APUSetZN8(IAPU.Registers.X); IAPU.PC++; } void ApuBD(void) { /* MOV SP,X */ IAPU.Registers.S = IAPU.Registers.X; IAPU.PC++; } void Apu6B(void) { /* ROR dp */ Work8 = S9xAPUGetByteZ(OP1); ROR(Work8); S9xAPUSetByteZ(Work8, OP1); IAPU.PC += 2; } void Apu6C(void) { /* ROR abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); ROR(Work8); S9xAPUSetByte(Work8, IAPU.Address); IAPU.PC += 3; } void Apu7B(void) { /* ROR dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); ROR(Work8); S9xAPUSetByteZ(Work8, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void Apu7C(void) { /* ROR A */ ROR(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu6E(void) { /* DBNZ dp,rel */ Work8 = OP1; Relative2(); W1 = S9xAPUGetByteZ(Work8) - 1; S9xAPUSetByteZ(W1, Work8); if (W1 != 0) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; } else IAPU.PC += 3; } void ApuFE(void) { /* DBNZ Y,rel */ Relative(); IAPU.Registers.YA.B.Y--; if (IAPU.Registers.YA.B.Y != 0) { IAPU.PC = IAPU.RAM + (uint16_t) Int16; APU.Cycles += IAPU.TwoCycles; } else IAPU.PC += 2; } void Apu6F(void) { /* RET */ PopW(IAPU.Registers.PC); IAPU.PC = IAPU.RAM + IAPU.Registers.PC; } void Apu7F(void) { /* RETI */ Pop(IAPU.Registers.P); S9xAPUUnpackStatus(); PopW(IAPU.Registers.PC); IAPU.PC = IAPU.RAM + IAPU.Registers.PC; } void Apu84(void) { /* ADC A,dp */ Work8 = S9xAPUGetByteZ(OP1); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu85(void) { /* ADC A, abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu86(void) { /* ADC A,(X) */ Work8 = S9xAPUGetByteZ(IAPU.Registers.X); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC++; } void Apu87(void) { /* ADC A,(dp+X) */ IndexedXIndirect(); Work8 = S9xAPUGetByte(IAPU.Address); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu88(void) { /* ADC A,#00 */ Work8 = OP1; ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu89(void) { /* ADC dp(dest),dp(src) */ Work8 = S9xAPUGetByteZ(OP1); W1 = S9xAPUGetByteZ(OP2); ADC(W1, Work8); S9xAPUSetByteZ(W1, OP2); IAPU.PC += 3; } void Apu94(void) { /* ADC A,dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu95(void) { /* ADC A, abs+X */ AbsoluteX(); Work8 = S9xAPUGetByte(IAPU.Address); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu96(void) { /* ADC A, abs+Y */ AbsoluteY(); Work8 = S9xAPUGetByte(IAPU.Address); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void Apu97(void) { /* ADC A, (dp)+Y */ IndirectIndexedY(); Work8 = S9xAPUGetByte(IAPU.Address); ADC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void Apu98(void) { /* ADC dp,#00 */ Work8 = OP1; W1 = S9xAPUGetByteZ(OP2); ADC(W1, Work8); S9xAPUSetByteZ(W1, OP2); IAPU.PC += 3; } void Apu99(void) { /* ADC (X),(Y) */ W1 = S9xAPUGetByteZ(IAPU.Registers.X); Work8 = S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); ADC(W1, Work8); S9xAPUSetByteZ(W1, IAPU.Registers.X); IAPU.PC++; } void Apu8D(void) { /* MOV Y,#00 */ IAPU.Registers.YA.B.Y = OP1; APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.PC += 2; } void Apu8F(void) { /* MOV dp,#00 */ Work8 = OP1; S9xAPUSetByteZ(Work8, OP2); IAPU.PC += 3; } void Apu9E(void) { uint32_t i; uint32_t yva; uint32_t x; /* DIV YA,X */ if ((IAPU.Registers.X & 0x0f) <= (IAPU.Registers.YA.B.Y & 0x0f)) APUSetHalfCarry(); else APUClearHalfCarry(); yva = IAPU.Registers.YA.W; x = IAPU.Registers.X << 9; for (i = 0 ; i < 9 ; ++i) { yva <<= 1; if (yva & 0x20000) yva = (yva & 0x1ffff) | 1; if (yva >= x) yva ^= 1; if (yva & 1) yva = (yva - x) & 0x1ffff; } if (yva & 0x100) APUSetOverflow(); else APUClearOverflow(); IAPU.Registers.YA.B.Y = (yva >> 9) & 0xff; IAPU.Registers.YA.B.A = yva & 0xff; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void Apu9F(void) { /* XCN A */ IAPU.Registers.YA.B.A = (IAPU.Registers.YA.B.A >> 4) | (IAPU.Registers.YA.B.A << 4); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuA4(void) { /* SBC A, dp */ Work8 = S9xAPUGetByteZ(OP1); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void ApuA5(void) { /* SBC A, abs */ Absolute(); Work8 = S9xAPUGetByte(IAPU.Address); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void ApuA6(void) { /* SBC A, (X) */ Work8 = S9xAPUGetByteZ(IAPU.Registers.X); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC++; } void ApuA7(void) { /* SBC A,(dp+X) */ IndexedXIndirect(); Work8 = S9xAPUGetByte(IAPU.Address); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void ApuA8(void) { /* SBC A,#00 */ Work8 = OP1; SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void ApuA9(void) { /* SBC dp(dest), dp(src) */ Work8 = S9xAPUGetByteZ(OP1); W1 = S9xAPUGetByteZ(OP2); SBC(W1, Work8); S9xAPUSetByteZ(W1, OP2); IAPU.PC += 3; } void ApuB4(void) { /* SBC A, dp+X */ Work8 = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void ApuB5(void) { /* SBC A,abs+X */ AbsoluteX(); Work8 = S9xAPUGetByte(IAPU.Address); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void ApuB6(void) { /* SBC A,abs+Y */ AbsoluteY(); Work8 = S9xAPUGetByte(IAPU.Address); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 3; } void ApuB7(void) { /* SBC A,(dp)+Y */ IndirectIndexedY(); Work8 = S9xAPUGetByte(IAPU.Address); SBC(IAPU.Registers.YA.B.A, Work8); IAPU.PC += 2; } void ApuB8(void) { /* SBC dp,#00 */ Work8 = OP1; W1 = S9xAPUGetByteZ(OP2); SBC(W1, Work8); S9xAPUSetByteZ(W1, OP2); IAPU.PC += 3; } void ApuB9(void) { /* SBC (X),(Y) */ W1 = S9xAPUGetByteZ(IAPU.Registers.X); Work8 = S9xAPUGetByteZ(IAPU.Registers.YA.B.Y); SBC(W1, Work8); S9xAPUSetByteZ(W1, IAPU.Registers.X); IAPU.PC++; } void ApuAF(void) { /* MOV (X)+, A */ S9xAPUSetByteZ(IAPU.Registers.YA.B.A, IAPU.Registers.X++); IAPU.PC++; } void ApuBE(void) { /* DAS */ if (IAPU.Registers.YA.B.A > 0x99 || !IAPU._Carry) { IAPU.Registers.YA.B.A -= 0x60; APUClearCarry(); } else APUSetCarry(); if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) IAPU.Registers.YA.B.A -= 6; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuBF(void) { /* MOV A,(X)+ */ IAPU.Registers.YA.B.A = S9xAPUGetByteZ(IAPU.Registers.X++); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuC0(void) { /* DI */ APUClearInterrupt(); IAPU.PC++; } void ApuA0(void) { /* EI */ APUSetInterrupt(); IAPU.PC++; } void ApuC4(void) { /* MOV dp,A */ S9xAPUSetByteZ(IAPU.Registers.YA.B.A, OP1); IAPU.PC += 2; } void ApuC5(void) { /* MOV abs,A */ Absolute(); S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 3; } void ApuC6(void) { /* MOV (X), A */ S9xAPUSetByteZ(IAPU.Registers.YA.B.A, IAPU.Registers.X); IAPU.PC++; } void ApuC7(void) { /* MOV (dp+X),A */ IndexedXIndirect(); S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 2; } void ApuC9(void) { /* MOV abs,X */ Absolute(); S9xAPUSetByte(IAPU.Registers.X, IAPU.Address); IAPU.PC += 3; } void ApuCB(void) { /* MOV dp,Y */ S9xAPUSetByteZ(IAPU.Registers.YA.B.Y, OP1); IAPU.PC += 2; } void ApuCC(void) { /* MOV abs,Y */ Absolute(); S9xAPUSetByte(IAPU.Registers.YA.B.Y, IAPU.Address); IAPU.PC += 3; } void ApuCD(void) { /* MOV X,#00 */ IAPU.Registers.X = OP1; APUSetZN8(IAPU.Registers.X); IAPU.PC += 2; } void ApuCF(void) { /* MUL YA */ IAPU.Registers.YA.W = (uint16_t) IAPU.Registers.YA.B.A * IAPU.Registers.YA.B.Y; APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.PC++; } void ApuD4(void) { /* MOV dp+X, A */ S9xAPUSetByteZ(IAPU.Registers.YA.B.A, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void ApuD5(void) { /* MOV abs+X,A */ AbsoluteX(); S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 3; } void ApuD6(void) { /* MOV abs+Y,A */ AbsoluteY(); S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 3; } void ApuD7(void) { /* MOV (dp)+Y,A */ IndirectIndexedY(); S9xAPUSetByte(IAPU.Registers.YA.B.A, IAPU.Address); IAPU.PC += 2; } void ApuD8(void) { /* MOV dp,X */ S9xAPUSetByteZ(IAPU.Registers.X, OP1); IAPU.PC += 2; } void ApuD9(void) { /* MOV dp+Y,X */ S9xAPUSetByteZ(IAPU.Registers.X, OP1 + IAPU.Registers.YA.B.Y); IAPU.PC += 2; } void ApuDB(void) { /* MOV dp+X,Y */ S9xAPUSetByteZ(IAPU.Registers.YA.B.Y, OP1 + IAPU.Registers.X); IAPU.PC += 2; } void ApuDF(void) { /* DAA */ if (IAPU.Registers.YA.B.A > 0x99 || IAPU._Carry) { IAPU.Registers.YA.B.A += 0x60; APUSetCarry(); } else APUClearCarry(); if ((IAPU.Registers.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) IAPU.Registers.YA.B.A += 6; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuE4(void) { /* MOV A, dp */ IAPU.Registers.YA.B.A = S9xAPUGetByteZ(OP1); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuE5(void) { /* MOV A,abs */ Absolute(); IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void ApuE6(void) { /* MOV A,(X) */ IAPU.Registers.YA.B.A = S9xAPUGetByteZ(IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC++; } void ApuE7(void) { /* MOV A,(dp+X) */ IndexedXIndirect(); IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuE8(void) { /* MOV A,#00 */ IAPU.Registers.YA.B.A = OP1; APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuE9(void) { /* MOV X, abs */ Absolute(); IAPU.Registers.X = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.X); IAPU.PC += 3; } void ApuEB(void) { /* MOV Y,dp */ IAPU.Registers.YA.B.Y = S9xAPUGetByteZ(OP1); APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.PC += 2; } void ApuEC(void) { /* MOV Y,abs */ Absolute(); IAPU.Registers.YA.B.Y = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.PC += 3; } void ApuF4(void) { /* MOV A, dp+X */ IAPU.Registers.YA.B.A = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuF5(void) { /* MOV A, abs+X */ AbsoluteX(); IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void ApuF6(void) { /* MOV A, abs+Y */ AbsoluteY(); IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 3; } void ApuF7(void) { /* MOV A, (dp)+Y */ IndirectIndexedY(); IAPU.Registers.YA.B.A = S9xAPUGetByte(IAPU.Address); APUSetZN8(IAPU.Registers.YA.B.A); IAPU.PC += 2; } void ApuF8(void) { /* MOV X,dp */ IAPU.Registers.X = S9xAPUGetByteZ(OP1); APUSetZN8(IAPU.Registers.X); IAPU.PC += 2; } void ApuF9(void) { /* MOV X,dp+Y */ IAPU.Registers.X = S9xAPUGetByteZ(OP1 + IAPU.Registers.YA.B.Y); APUSetZN8(IAPU.Registers.X); IAPU.PC += 2; } void ApuFA(void) { /* MOV dp(dest),dp(src) */ S9xAPUSetByteZ(S9xAPUGetByteZ(OP1), OP2); IAPU.PC += 3; } void ApuFB(void) { /* MOV Y,dp+X */ IAPU.Registers.YA.B.Y = S9xAPUGetByteZ(OP1 + IAPU.Registers.X); APUSetZN8(IAPU.Registers.YA.B.Y); IAPU.PC += 2; } void (*S9xApuOpcodes[256])(void) = { Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07, Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F, Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17, Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F, Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27, Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F, Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37, Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F, Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47, Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F, Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57, Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F, Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67, Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F, Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77, Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F, Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87, Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F, Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97, Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F, ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7, ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF, ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7, ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF, ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7, ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF, ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7, ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF, ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7, ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF, ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7, ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF }; #endif