/* R65C02 Processor Emulator for SoftAtom version 0.9 * * Date : May 12, 1994 (c) Dick Bronsdijk * * This file contains a hughe Switch for processing * the R65C02 Opcodes. It calls the GRAFIX2.ASM file * for 6502 memory emulation. For menu's and debugging * it calls functions in the main program : ATOM9.C * * The 'goto' in the ADC and SBC instruction is done * to prevent a compiler table overflow. */ void FunKey( void ); void ProcessOpcode( void ) { unsigned register addr, tmp, a_flags; register char wrk; #ifdef DEBUG unsigned int PCx = 0xFF; #endif unsigned char XC, XD; while (!Stop) { if (FKey == TRUE) /* Do only if Function Key pressed */ { FunKey(); } if (nmi_set) /* NMI Occured */ if (!P.F.I) INT(NMI); /*********************** Process 6502 Instruction ******************/ #ifdef DEBUG if (DebugSet) { if (PC == xhalt || Step) DebugMenu(); if (Debug) { delay(Pause); DebugDisp(); // !!! Test } } PCe = PCx; PCx = PC; switch( Op = MRead( PC++ ) ) #else switch( MRead( PC++ ) ) #endif { case 0x00 : /* BREAK */ P.F.B = 1; PC++; #ifdef DEBUG if (BreakDetect && !Continue) Step = 1; else #endif { Continue = 0; MWrite( 0x100 + SP--, PC >> 8 ); MWrite( 0x100 + SP--, PC & 0xFF ); MWrite( 0x100 + SP--, P.P & 0xFF ); PC = MRead( 0xFFFE ) + ((MRead( 0xFFFF )) << 8); } P.F.I = 1; break; case 0x01 : /* ORA 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; A |= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x02 : /* Dummy */ goto NoOpCode; case 0x03 : /* Dummy */ goto NoOpCode; case 0x04 : /* TSB 1 */ addr = MRead( PC++ ); tmp = MRead( addr ); tmp |= A; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x05 : /* ORA 1 */ A |= MRead( MRead( PC++ ) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x06 : /* ASL 1 */ addr = MRead( PC++ ); tmp = (MRead( addr )) << 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x07 : /* RMB 0 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xFE ); break; case 0x08 : /* PHP */ MWrite( 0x100 + SP--, P.P); break; case 0x09 : /* ORA 2 */ A |= MRead( PC++ ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x0A : /* ASL A */ tmp = A << 1; A = tmp & 0xFF; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x0B : /* Dummy */ goto NoOpCode; case 0x0C : /* TSB 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = MRead( addr ); tmp |= A; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x0D : /* ORA 3 */ A |= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x0E : /* ASL 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = (MRead( addr )) << 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x0F : /* BBR 0 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x01 )) PC += (char) MRead( PC ); PC++; break; case 0x10 : /* BPL */ if (!P.F.S) PC += (char) MRead( PC ); PC++; break; case 0x11 : /* ORA 4 */ addr = MRead( PC++ ); A |= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x12 : /* ORA R */ addr = MRead( PC++ ); A |= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x13 : /* Dummy */ goto NoOpCode; case 0x14 : /* TRB 1 */ addr = MRead( PC++ ); tmp = MRead( addr ); tmp &= ~A; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x15 : /* ORA 5 */ A |= MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x16 : /* ASL 5 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = (MRead( addr )) << 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x17 : /* RMB 1 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xFD ); break; case 0x18 : /* CLC */ P.F.C = 0; break; case 0x19 : /* ORA 6 */ A |= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x1A : /* INC A */ A++; P.F.S = (A & 0x80) ? 1 : 0; P.F.Z = !A; break; case 0x1B : /* Dummy */ goto NoOpCode; case 0x1C : /* TRB 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = MRead( addr ); tmp &= ~A; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x1D : /* ORA 7 */ A |= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x1E : /* ASL 7 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8) + X; tmp = (MRead( addr )) << 1; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x1F : /* BBR 1 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x02 )) PC += (char) MRead( PC ); PC++; break; case 0x20 : /* JSR */ addr = MRead( PC++ ) + (MRead( PC ) << 8); MWrite( 0x100 + SP--, PC >> 8); MWrite( 0x100 + SP--, PC & 0xFF); PC = addr; break; case 0x21 : /* AND 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; A &= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x23 : /* Dummy */ goto NoOpCode; case 0x24 : /* BIT 0 */ tmp = MRead( MRead( PC++ ) ); P.F.Z = !(A & tmp); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x25 : /* AND 1 */ A &= MRead( MRead( PC++ ) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x26 : /* ROL 1 */ addr = MRead( PC++ ); tmp = (MRead( addr )) << 1; tmp |= P.F.C; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x27 : /* RMB 2 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xFB ); break; case 0x28 : /* PLP */ P.P = MRead( 0x100 + ++SP ); break; case 0x29 : /* AND 2 */ A &= MRead( PC++ ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x2A : /* ROL A */ tmp = A << 1; tmp |= P.F.C; A = tmp & 0xFF; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x2B : /* Dummy */ goto NoOpCode; case 0x2C : /* BIT 1 */ tmp = MRead( MRead( PC++ ) + ((MRead( PC++ )) << 8) ); P.F.Z = !(A & tmp); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x2D : /* AND 3 */ A &= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x2E : /* ROL 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = (MRead( addr )) << 1; tmp |= P.F.C; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x2F : /* BBR 2 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x04 )) PC += (char) MRead( PC ); PC++; break; case 0x30 : /* BMI */ if (P.F.S) PC += (char) MRead( PC ); PC++; break; case 0x31 : /* AND 4 */ addr = MRead( PC++ ); A &= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x32 : /* AND R */ addr = MRead( PC++ ); A &= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x33 : /* Dummy */ goto NoOpCode; case 0x34 : /* BIT R3 */ tmp = MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.Z = !(A & tmp); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x35 : /* AND 5 */ A &= MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x36 : /* ROL 5 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = (MRead( addr )) << 1; tmp |= P.F.C; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x37 : /* RMB 3 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xF7 ); break; case 0x38 : /* SEC */ P.F.C = 1; break; case 0x39 : /* AND 6 */ A &= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x3A : /* DEC R */ A--; P.F.S = (A & 0x80) ? 1 : 0; P.F.Z = !A; break; case 0x3B : /* Dummy */ goto NoOpCode; case 0x3C : /* BIT R1 */ tmp = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.Z = !(A & tmp); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x3D : /* AND 7 */ A &= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x3E : /* ROL 7 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8) + X; tmp = (MRead( addr )) << 1; tmp |= P.F.C; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.C = (tmp & 0x100) ? 1 : 0; break; case 0x3F : /* BBR 3 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x08 )) PC += (char) MRead( PC ); PC++; break; case 0x40 : /* RTI */ P.P = MRead( 0x100 + ++SP ); PC = MRead( 0x100 + ++SP ) + (MRead( 0x100 + ++SP ) << 8); break; case 0x41 : /* EOR 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; A ^= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x42 : /* Dummy */ goto NoOpCode; case 0x43 : /* Dummy */ goto NoOpCode; case 0x44 : /* Dummy */ goto NoOpCode; case 0x45 : /* EOR 1 */ A ^= MRead( MRead( PC++ ) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x46 : /* LSR 1 */ addr = MRead( PC++ ); tmp = MRead( addr ); P.F.C = tmp & 0x01; tmp >>= 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = 0; break; case 0x47 : /* RMB 4 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xEF ); break; case 0x48 : /* PHA */ MWrite( 0x100 + SP--, A); /* PUSH */ break; case 0x49 : /* EOR 2 */ A ^= MRead( PC++ ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x4A : /* LSR A */ P.F.C = A & 0x01; A >>= 1; P.F.Z = !A; P.F.S = 0; break; case 0x4B : /* Dummy */ goto NoOpCode; case 0x4C : /* JMP 0 */ PC = MRead( PC++ ) + (MRead( PC ) << 8); break; case 0x4D : /* EOR 3 */ A ^= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x4E : /* LSR 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = MRead( addr ); P.F.C = tmp & 0x01; tmp >>= 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = 0; break; case 0x4F : /* BBR 4 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x10 )) PC += (char) MRead( PC ); PC++; break; case 0x50 : /* BVC */ if (!P.F.V) PC += (char) MRead( PC ); PC++; break; case 0x51 : /* EOR 4 */ addr = MRead( PC++ ); A ^= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x52 : /* EOR R */ addr = MRead( PC++ ); A ^= MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x53 : /* Dummy */ goto NoOpCode; case 0x54 : /* Dummy */ goto NoOpCode; case 0x55 : /* EOR 5 */ A ^= MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x56 : /* LSR 5 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = MRead( addr ); P.F.C = tmp & 0x01; tmp >>= 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = 0; break; case 0x57 : /* RMB 5 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xDF ); break; case 0x58 : /* CLI */ P.F.I = 0; break; case 0x59 : /* EOR 6 */ A ^= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x5A : /* PHY */ MWrite( 0x100 + SP--, Y); /* PUSH */ break; case 0x5B : /* Dummy */ goto NoOpCode; case 0x5C : /* Dummy */ goto NoOpCode; case 0x5D : /* EOR 7 */ A ^= MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x5E : /* LSR 7 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8) + X; tmp = MRead( addr ); P.F.C = tmp & 0x01; tmp >>= 1; MWrite( addr, tmp & 0xFF); P.F.Z = !(tmp & 0xFF); P.F.S = 0; break; case 0x5F : /* BBR 5 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x20 )) PC += (char) MRead( PC ); PC++; break; case 0x60 : /* RTS */ PC = MRead( 0x100 + ++SP ) + (MRead( 0x100 + ++SP ) << 8); PC++; break; case 0x61 : /* ADC 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; wrk = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); goto ADCX; case 0x62 : /* Dummy */ goto NoOpCode; case 0x63 : /* Dummy */ goto NoOpCode; case 0x64 : /* STZ 1 */ MWrite( MRead( PC++ ), 0 ); break; case 0x65 : /* ADC 1 */ wrk = MRead( MRead( PC++ ) ); goto ADCX; case 0x66 : /* ROR 1 */ addr = MRead( PC++ ); tmp = MRead( addr ); P.F.X = tmp & 0x01; tmp >>= 1; tmp |= (P.F.C) ? 0x80 : 0x00; MWrite( addr, tmp & 0xFF); P.F.C = P.F.X; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0x67 : /* RMB 6 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0xBF ); break; case 0x68 : /* PLA */ A = MRead( 0x100 + ++SP ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0x69 : /* ADC 2 */ wrk = MRead( PC++ ); goto ADCX; case 0x6A : /* ROR A */ tmp = A >> 1; P.F.X = A & 0x01; tmp |= (P.F.C) ? 0x80 : 0x00; A = tmp & 0xFF; P.F.C = P.F.X; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0x6B : /* Dummy */ goto NoOpCode; case 0x6C : /* JMP 1 */ addr = MRead( PC++ ) + (MRead( PC ) << 8); PC = MRead( addr++ ) + (MRead( addr ) << 8); break; case 0x6D : /* ADC 3 */ wrk = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) ); goto ADCX; case 0x6E : /* ROR 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = MRead( addr ); P.F.X = tmp & 0x01; tmp >>= 1; tmp |= (P.F.C) ? 0x80 : 0x00; MWrite( addr, tmp & 0xFF); P.F.C = P.F.X; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0x6F : /* BBR 6 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x40 )) PC += (char) MRead( PC ); PC++; break; case 0x70 : /* BVS */ if (P.F.V) PC += (char) MRead( PC ); PC++; break; case 0x71 : /* ADC 4 */ addr = MRead( PC++ ); wrk = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y ); goto ADCX; case 0x72 : /* ADC R */ addr = MRead( PC++ ); wrk = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); goto ADCX; case 0x73 : /* Dummy */ goto NoOpCode; case 0x74 : /* STZ 5 */ MWrite( ( MRead( PC++ ) + X ) & 0xFF, 0 ); break; case 0x75 : /* ADC 5 */ wrk = MRead( ( MRead( PC++ ) + X ) & 0xFF ); goto ADCX; case 0x76 : /* ROR 5 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = MRead( addr ); P.F.X = tmp & 0x01; tmp >>= 1; tmp |= (P.F.C) ? 0x80 : 0x00; MWrite( addr, tmp & 0xFF); P.F.C = P.F.X; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0x77 : /* RMB 7 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) & 0x7F ); break; case 0x78 : /* SEI */ P.F.I = 1; break; case 0x79 : /* ADC 6 */ wrk = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); goto ADCX; case 0x7A : /* PLY */ Y = MRead( 0x100 + ++SP ); P.F.Z = !Y; P.F.S = (Y & 0x80) ? 1 : 0; break; case 0x7B : /* Dummy */ goto NoOpCode; case 0x7C : /* JMP R */ addr = MRead( PC++ ) + (MRead( PC ) << 8) + X; PC = MRead( addr++ ) + (MRead( addr ) << 8); break; case 0x7D : /* ADC 7 */ wrk = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); ADCX: XC = P.F.C; XD = P.F.D; asm mov al,A /* maak AL gelijk aan 6502 accu */ asm shr XC,1 /* set carry 0 of 1, XC gaat verloren */ asm adc al,wrk /* doe de optelling */ asm pushf /* sla x86 flags op */ asm shr XD,1 /* maak carry gelijk aan Decimal_flag */ asm jnc adc1 /* in niet Decimal sla DAA dan over */ asm popf /* haal flags op */ asm daa /* doe een decimal adjust */ asm pushf /* bewaar flags */ adc1: /* label (zie JNC hiervoor */ asm mov byte ptr A,al /* zet 6502 accu op nieuwe waarde */ asm pop a_flags /* zet flags in unsigned int */ P.F.C = a_flags & 1; /* zet 6502 carry */ P.F.Z = (a_flags & 0x40) != 0; /* zet 6502 zero */ P.F.S = (a_flags & 0x80) != 0; /* zet 6502 sign */ P.F.V = (a_flags & 0x800) != 0; /* zet 6502 overflow */ break; case 0x7E : /* ROR 7 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8) + X; tmp = MRead( addr ); P.F.X = tmp & 0x01; tmp >>= 1; tmp |= (P.F.C) ? 0x80 : 0x00; MWrite( addr, tmp & 0xFF); P.F.C = P.F.X; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0x7F : /* BBR 7 */ addr = MRead( PC++ ); if ( !(MRead ( addr ) & 0x80 )) PC += (char) MRead( PC ); PC++; break; case 0x80 : /* BRA */ PC += (char) MRead( PC ); PC++; break; case 0x81 : /* STA 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; MWrite( MRead( addr ) + (MRead( addr + 1 ) << 8), A ); break; case 0x82 : /* Dummy */ goto NoOpCode; case 0x83 : /* Dummy */ goto NoOpCode; case 0x84 : /* STY 1 */ MWrite( MRead( PC++ ), Y ); break; case 0x85 : /* STA 1 */ MWrite( MRead( PC++ ), A ); break; case 0x86 : /* STX 1 */ MWrite( MRead( PC++ ), X ); break; case 0x87 : /* SMB 0 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x01 ); break; case 0x88 : /* DEY */ Y--; P.F.S = (Y & 0x80) ? 1 : 0; P.F.Z = !Y; break; case 0x89 : /* BIT R2 */ tmp = MRead( PC++ ); P.F.Z = !(A & tmp); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.V = (tmp & 0x40) ? 1 : 0; break; case 0x8A : /* TXA */ A = X; P.F.S = (A & 0x80) ? 1 : 0; P.F.Z = !A; break; case 0x8B : /* Dummy */ goto NoOpCode; case 0x8C : /* STY 3 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8 ), Y ); break; case 0x8D : /* STA 3 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8), A ); break; case 0x8E : /* STX 3 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8 ), X ); break; case 0x8F : /* BBS 0 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x01 ) PC += (char) MRead( PC ); PC++; break; case 0x90 : /* BCC */ if (!P.F.C) PC += (char) MRead( PC ); PC++; break; case 0x91 : /* STA 4 */ addr = MRead( PC++ ); MWrite( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y, A ); break; case 0x92 : /* STA R */ addr = MRead( PC++ ); MWrite( MRead( addr ) + (MRead( addr + 1 ) << 8), A ); break; case 0x93 : /* Dummy */ goto NoOpCode; case 0x94 : /* STY 5 */ MWrite( ( MRead( PC++ ) + X ) & 0xFF, Y ); break; case 0x95 : /* STA 5 */ MWrite( ( MRead( PC++ ) + X ) & 0xFF, A ); break; case 0x96 : /* STX 5 */ MWrite( ( MRead( PC++ ) + Y ) & 0xFF, X ); break; case 0x97 : /* SMB 1 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x02 ); break; case 0x98 : /* TYA */ A = Y; P.F.S = (A & 0x80) ? 1 : 0; P.F.Z = !A; break; case 0x99 : /* STA 6 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y, A ); break; case 0x9A : /* TXS */ SP = X; break; case 0x9B : /* Dummy */ goto NoOpCode; case 0x9C : /* STZ 3 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8), 0 ); break; case 0x9D : /* STA 7 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8) + X, A ); break; case 0x9E : /* STZ 7 */ MWrite( MRead( PC++ ) + (MRead( PC++ ) << 8) + X, 0 ); break; case 0x9F : /* BBS 1 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x02 ) PC += (char) MRead( PC ); PC++; break; case 0xA0 : /* LDY 0 */ Y = MRead( PC++ ); P.F.Z = !Y; P.F.S = (Y & 0x80) ? 1 : 0; break; case 0xA1 : /* LDA 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; A = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xA2 : /* LDX 0 */ X = MRead( PC++ ); P.F.Z = !X; P.F.S = (X & 0x80) ? 1 : 0; break; case 0xA3 : /* Dummy */ goto NoOpCode; case 0xA4 : /* LDY 1 */ Y = MRead( MRead( PC++ ) ); P.F.Z = !Y; P.F.S = (Y & 0x80) ? 1 : 0; break; case 0xA5 : /* LDA 1 */ A = MRead( MRead( PC++ ) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xA6 : /* LDX 1 */ X = MRead( MRead( PC++ ) ); P.F.Z = !X; P.F.S = (X & 0x80) ? 1 : 0; break; case 0xA7 : /* SMB 2 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x04 ); break; case 0xA8 : /* TAY */ Y = A; P.F.S = (Y & 0x80) ? 1 : 0; P.F.Z = !Y; break; case 0xA9 : /* LDA 2 */ A = MRead( PC++ ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xAA : /* TAX */ X = A; P.F.S = (X & 0x80) ? 1 : 0; P.F.Z = !X; break; case 0xAB : /* Dummy */ goto NoOpCode; case 0xAC : /* LDY 3 */ Y = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8 ) ); P.F.Z = !Y; P.F.S = (Y & 0x80) ? 1 : 0; break; case 0xAD : /* LDA 3 */ A = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xAE : /* LDX 3 */ X = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8 ) ); P.F.Z = !X; P.F.S = (X & 0x80) ? 1 : 0; break; case 0xAF : /* BBS 2 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x04 ) PC += (char) MRead( PC ); PC++; break; case 0xB0 : /* BCS */ if (P.F.C) PC += (char) MRead( PC ); PC++; break; case 0xB1 : /* LDA 4 */ addr = MRead( PC++ ); A = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xB2 : /* LDA R */ addr = MRead( PC++ ); A = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xB3 : /* Dummy */ goto NoOpCode; case 0xB4 : /* LDY 5 */ Y = MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.Z = !Y; P.F.S = (Y & 0x80) ? 1 : 0; break; case 0xB5 : /* LDA 5 */ A = MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xB6 : /* LDX 5 */ X = MRead( ( MRead( PC++ ) + Y ) & 0xFF ); P.F.Z = !X; P.F.S = (X & 0x80) ? 1 : 0; break; case 0xB7 : /* SMB 3 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x08 ); break; case 0xB8 : /* CLV */ P.F.V = 0; break; case 0xB9 : /* LDA 6 */ A = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xBA : /* TSX */ X = SP; P.F.S = (X & 0x80) ? 1 : 0; P.F.Z = !X; break; case 0xBB : /* Dummy */ goto NoOpCode; case 0xBC : /* LDY 7 */ Y = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.Z = !Y; P.F.S = (Y & 0x80) ? 1 : 0; break; case 0xBD : /* LDA 7 */ A = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.Z = !A; P.F.S = (A & 0x80) ? 1 : 0; break; case 0xBE : /* LDX 7 */ X = MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); P.F.Z = !X; P.F.S = (X & 0x80) ? 1 : 0; break; case 0xBF : /* BBS 3 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x08 ) PC += (char) MRead( PC ); PC++; break; case 0xC0 : /* CPY 0 */ tmp = Y - MRead( PC++ ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xC1 : /* CMP 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = A - MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xC3 : /* Dummy */ goto NoOpCode; case 0xC4 : /* CPY 1 */ tmp = Y - MRead( MRead ( PC++ ) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xC5 : /* CMP 1 */ tmp = A - MRead( MRead( PC++ ) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xC6 : /* DEC 1 */ addr = MRead( PC++ ); tmp = MRead( addr ); tmp--; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xC7 : /* SMB 4 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x10 ); break; case 0xC8 : /* INY */ Y++; P.F.S = (Y & 0x80) ? 1 : 0; P.F.Z = !Y; break; case 0xC9 : /* CMP 2 */ tmp = A - MRead( PC++ ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xCA : /* DEX */ X--; P.F.S = (X & 0x80) ? 1 : 0; P.F.Z = !X; break; case 0xCB : /* Dummy */ goto NoOpCode; case 0xCC : /* CPY 3 */ tmp = Y - MRead( MRead( PC++ ) + ((MRead( PC++ )) << 8) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xCD : /* CMP 3 */ tmp = A - MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xCE : /* DEC 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = MRead( addr ); tmp--; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xCF : /* BBS 4 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x10 ) PC += (char) MRead( PC ); PC++; break; case 0xD0 : /* BNE */ if (!P.F.Z) PC += (char) MRead( PC ); PC++; break; case 0xD1 : /* CMP 4 */ addr = MRead( PC++ ); tmp = A - MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) + Y ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xD2 : /* CMP R */ addr = MRead( PC++ ); tmp = A - MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xD3 : /* Dummy */ goto NoOpCode; case 0xD4 : /* Dummy */ goto NoOpCode; case 0xD5 : /* CMP 5 */ tmp = A - MRead( ( MRead( PC++ ) + X ) & 0xFF ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xD6 : /* DEC 5 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = MRead( addr ); tmp--; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xD7 : /* SMB 5 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x20 ); break; case 0xD8 : /* CLD */ P.F.D = 0; break; case 0xD9 : /* CMP 6 */ tmp = A - MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + Y ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xDA : /* PHX */ MWrite( 0x100 + SP--, X); /* PUSH */ break; case 0xDB : /* Dummy */ goto NoOpCode; case 0xDC : /* Dummy */ goto NoOpCode; case 0xDD : /* CMP 7 */ tmp = A - MRead( MRead( PC++ ) + (MRead( PC++ ) << 8) + X ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.Z = !(tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; break; case 0xDE : /* DEC 7 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8) + X; tmp = MRead( addr ); tmp--; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xDF : /* BBS 5 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x20 ) PC += (char) MRead( PC ); PC++; break; case 0xE0 : /* CPX 0 */ tmp = X - MRead( PC++ ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xE1 : /* SBC 0 */ addr = ( MRead( PC++ ) + X ) & 0xFF; wrk = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); goto SBCX; case 0xE2 : /* Dummy */ goto NoOpCode; case 0xE3 : /* Dummy */ goto NoOpCode; case 0xE4 : /* CPX 1 */ tmp = X - MRead( MRead ( PC++ ) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xE5 : /* SBC 1 */ wrk = MRead( MRead( PC++ ) ); goto SBCX; case 0xE6 : /* INC 1 */ addr = MRead( PC++ ); tmp = MRead( addr ); tmp++; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xE7 : /* SMB 6 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x40 ); break; case 0xE8 : /* INX */ X++; P.F.S = (X & 0x80) ? 1 : 0; P.F.Z = !X; break; case 0xE9 : /* SBC 2 */ wrk = MRead( PC++ ); goto SBCX; case 0xEA : /* NOP */ break; case 0xEB : /* Dummy */ goto NoOpCode; case 0xEC : /* CPX 3 */ tmp = X - MRead( MRead( PC++ ) + ((MRead( PC++ )) << 8) ); P.F.C = (tmp > 0xFF) ? 0 : 1; P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xED : /* SBC 3 */ wrk = MRead( MRead( PC++ ) + ((MRead( PC++ )) << 8) ); goto SBCX; case 0xEE : /* INC 3 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8); tmp = MRead( addr ); tmp++; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xEF : /* BBS 6 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x40 ) PC += (char) MRead( PC ); PC++; break; case 0xF0 : /* BEQ */ if (P.F.Z) PC += (char) MRead( PC ); PC++; break; case 0xF1 : /* SBC 4 */ addr = MRead( PC++ ); wrk = MRead( MRead( addr ) + ((MRead( addr + 1 )) << 8) + Y ); goto SBCX; case 0xF2 : /* SBC R */ addr = MRead( PC++ ); wrk = MRead( MRead( addr ) + (MRead( addr + 1 ) << 8) ); goto SBCX; case 0xF3 : /* Dummy */ goto NoOpCode; case 0xF4 : /* Dummy */ goto NoOpCode; case 0xF5 : /* SBC 5 */ wrk = MRead( ( MRead( PC++ ) + X ) & 0xFF ); goto SBCX; case 0xF6 : /* INC 5 */ addr = ( MRead( PC++ ) + X ) & 0xFF; tmp = MRead( addr ); tmp++; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xF7 : /* SMB 7 */ addr = MRead( PC++ ); MWrite ( addr, MRead( addr ) | 0x80 ); break; case 0xF8 : /* SED */ P.F.D = 1; break; case 0xF9 : /* SBC 6 */ wrk = MRead( MRead( PC++ ) + ((MRead( PC++ )) << 8 ) + Y ); goto SBCX; case 0xFA : /* PLX */ X = MRead( 0x100 + ++SP ); P.F.Z = !X; P.F.S = (X & 0x80) ? 1 : 0; break; case 0xFB : /* Dummy */ goto NoOpCode; case 0xFC : /* Dummy */ goto NoOpCode; case 0xFD : /* SBC 7 */ wrk = MRead( MRead( PC++ ) + ((MRead( PC++ )) << 8 ) + X ); SBCX: XC = P.F.C; XD = P.F.D; asm mov al,A /* maak AL gelijk aan 6502 accu */ asm xor XC,1 /* invert carry (zie 6502 borrow) */ asm shr XC,1 /* set carry 0 of 1, XC gaat verloren */ asm sbb al,wrk /* doe de aftrekking */ asm pushf /* sla x86 flags op */ asm shr XD,1 /* maak carry gelijk aan Decimal_flag */ asm jnc sbc1 /* in niet Decimal sla DAA dan over */ asm popf /* haal flags op */ asm daa /* doe een decimal adjust */ asm pushf /* bewaar flags */ sbc1: /* label (zie JNC hiervoor */ asm mov byte ptr A,al /* zet 6502 accu op nieuwe waarde */ asm pop a_flags /* zet flags in unsigned int */ P.F.C = !(a_flags & 1); /* zet 6502 carry */ P.F.Z = (a_flags & 0x40) != 0; /* zet 6502 zero */ P.F.S = (a_flags & 0x80) != 0; /* zet 6502 sign */ P.F.V = (a_flags & 0x800) != 0; /* zet 6502 overflow */ break; case 0xFE : /* INC 7 */ addr = MRead( PC++ ) + ((MRead( PC++ )) << 8) + X; tmp = MRead( addr ); tmp++; MWrite( addr, tmp & 0xFF); P.F.S = (tmp & 0x80) ? 1 : 0; P.F.Z = !(tmp & 0xFF); break; case 0xFF : /* BBS 7 */ addr = MRead( PC++ ); if ( MRead ( addr ) & 0x80 ) PC += (char) MRead( PC ); PC++; break; #ifdef DEBUG default : NoOpCode: XXX(); break; #else NoOpCode: break; #endif } } } void INT( int type ) /* type == 0 : IRQ, type == 1 : NMI */ { MWrite( 0x100 + SP--, PC >> 8); /* PUSH */ MWrite( 0x100 + SP--, PC & 0xFF); /* PUSH */ MWrite( 0x100 + SP--, P.P & 0xFF); /* PUSH */ if (type == IRQ) PC = MRead( 0xFFFE ) + ((MRead( 0xFFFF )) << 8); else PC = MRead( 0xFFFA ) + ((MRead( 0xFFFB )) << 8); P.F.I = 1; } void XXX( void ) { cprintf("\r\n\nInvalid Opcode (%02X) at address (%04X) (From %04X)\r\n", Op, PC - 1, PCe); Step = TRUE; DebugSet = TRUE; }