diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index cda2552..8dcdff1 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -9,12 +9,14 @@ /* Begin PBXBuildFile section */ 32439F8722ECD8AD0077AAE0 /* 6502.c in Sources */ = {isa = PBXBuildFile; fileRef = 32439F7422ECD8AD0077AAE0 /* 6502.c */; }; 32439F8822ECD8AD0077AAE0 /* apple.rom in Resources */ = {isa = PBXBuildFile; fileRef = 32439F8422ECD8AD0077AAE0 /* apple.rom */; }; + 326ED2EF232D7A0000A41337 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */; }; 32BFFB5B22EACC630003B53F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5A22EACC630003B53F /* AppDelegate.swift */; }; 32BFFB5D22EACC630003B53F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB5C22EACC630003B53F /* ViewController.swift */; }; 32BFFB5F22EACC660003B53F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB5E22EACC660003B53F /* Assets.xcassets */; }; 32BFFB6222EACC660003B53F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; 32BFFB6E22EACC660003B53F /* A2MacTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB6D22EACC660003B53F /* A2MacTests.swift */; }; 32BFFB7922EACC660003B53F /* A2MacUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32BFFB7822EACC660003B53F /* A2MacUITests.swift */; }; + 32C45306232E3EEF0000EBA1 /* RepeatingTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */; }; 32EDB7A223272CA80073AF2D /* fail1.txt in Resources */ = {isa = PBXBuildFile; fileRef = 32EDB7A123272CA80073AF2D /* fail1.txt */; }; /* End PBXBuildFile section */ @@ -58,6 +60,7 @@ 32439F8622ECD8AD0077AAE0 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = ""; }; 3264261023284F6F008B615F /* Apple2_mmio_8bit_ioaddr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Apple2_mmio_8bit_ioaddr.h; sourceTree = ""; }; 326426112328ADF4008B615F /* Apple_II_ROM.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = Apple_II_ROM.s; sourceTree = ""; }; + 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = SOURCE_ROOT; }; 32BFFB5722EACC630003B53F /* A2Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = A2Mac.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32BFFB5A22EACC630003B53F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 32BFFB5C22EACC630003B53F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -71,6 +74,7 @@ 32BFFB7422EACC660003B53F /* A2MacUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = A2MacUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 32BFFB7822EACC660003B53F /* A2MacUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = A2MacUITests.swift; sourceTree = ""; }; 32BFFB7A22EACC660003B53F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatingTimer.swift; sourceTree = ""; }; 32EDB7A123272CA80073AF2D /* fail1.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = fail1.txt; sourceTree = ""; }; /* End PBXFileReference section */ @@ -148,11 +152,13 @@ 32439F7422ECD8AD0077AAE0 /* 6502.c */, 32439F8522ECD8AD0077AAE0 /* 6502.h */, 32439F8422ECD8AD0077AAE0 /* apple.rom */, + 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */, 32439F7322ECD8AD0077AAE0 /* Apple2_mmio.h */, 3264261023284F6F008B615F /* Apple2_mmio_8bit_ioaddr.h */, 32439F8622ECD8AD0077AAE0 /* common.h */, 32BFFB5A22EACC630003B53F /* AppDelegate.swift */, 32BFFB5C22EACC630003B53F /* ViewController.swift */, + 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */, 32EDB7A123272CA80073AF2D /* fail1.txt */, 32BFFB5E22EACC660003B53F /* Assets.xcassets */, 32BFFB6022EACC660003B53F /* Main.storyboard */, @@ -290,6 +296,7 @@ 32BFFB5F22EACC660003B53F /* Assets.xcassets in Resources */, 32439F8822ECD8AD0077AAE0 /* apple.rom in Resources */, 32BFFB6222EACC660003B53F /* Main.storyboard in Resources */, + 326ED2EF232D7A0000A41337 /* 6502_functional_test.bin in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -317,6 +324,7 @@ 32439F8722ECD8AD0077AAE0 /* 6502.c in Sources */, 32BFFB5D22EACC630003B53F /* ViewController.swift in Sources */, 32BFFB5B22EACC630003B53F /* AppDelegate.swift in Sources */, + 32C45306232E3EEF0000EBA1 /* RepeatingTimer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/A2Mac/6502.c b/A2Mac/6502.c index 2e469e8..df27a98 100644 --- a/A2Mac/6502.c +++ b/A2Mac/6502.c @@ -6,20 +6,35 @@ // Copyright © 2019 GameAlloy. All rights reserved. // +#define CLK_WAIT +#define NO_SPEED_TEST + #include #include #include +#include + +#ifdef DEBUG +#define INLINE +#else +#define INLINE static __attribute__((always_inline)) +#endif #include "common.h" #include "Apple2_mmio.h" -#define SOFTRESET_VECTOR 0x3F2 +#define SOFTRESET_VECTOR 0x3F2 + +#define NMI_VECTOR 0xFFFA +#define RESET_VECTOR 0xFFFC +#define IRQ_VECTOR 0xFFFE + /** Instruction Implementations !!!! `his has to be here!!! - This idea is that "static inline" would work only if it is + This idea is that "INLINE" would work only if it is located in the same source file -- hence the include... **/ #include "6502_instructions.h" @@ -31,7 +46,7 @@ unsigned long long int clktime = 0; m6502_t m6502 = {0}; -static inline int m6502_step() { +INLINE int m6502_step() { // switch ( fetch16() ) { // case 0xFCD0: // D0 FC BNE @@ -43,6 +58,26 @@ static inline int m6502_step() { // default: // m6502.pc -= 2; // + +#ifdef DEBUG + switch ( m6502.PC ) { + case 0x400: + dbgPrintf("START...\n"); + break; + + case 0x9D1: + dbgPrintf("BREAK POINT...\n"); + break; + + case 0x35BD: + if ( ( m6502.A == 0x35 ) && ( m6502.C ) ) + dbgPrintf("BREAK POINT...\n"); + break; + + default: + break; + } +#endif switch ( fetch() ) { case 0x00: BRK(); return 2; // BRK case 0x01: ORA( src_X_ind() ); return 6; // ORA X,ind @@ -78,84 +113,84 @@ static inline int m6502_step() { // case 0x1F: // SLO* (undocumented) case 0x20: JSR( abs_addr() ); return 6; // JSR abs case 0x21: AND( src_X_ind() ); return 6; // AND X,ind -// case 0x22: -// case 0x23: +// case 0x22: KIL +// case 0x23: RLA izx 8 case 0x24: BIT( src_zp() ); return 3; // BIT zpg case 0x25: AND( src_zp() ); return 3; // AND zpg case 0x26: ROL( dest_zp() ); return 5; // ROL zpg -// case 0x27: +// case 0x27: RLA zp 5 case 0x28: PLP(); return 4; // PLP case 0x29: AND( imm() ); return 2; // AND imm case 0x2A: ROLA(); return 2; // ROL A -// case 0x2B: +// case 0x2B: ANC imm 2 case 0x2C: BIT( src_abs() ); return 4; // BIT abs case 0x2D: AND( src_abs() ); return 4; // AND abs case 0x2E: ROL( dest_abs() ); return 6; // ROL abs -// case 0x2F: +// case 0x2F: RLA abs 6 case 0x30: BMI( rel_addr() ); return 2; // BMI rel case 0x31: AND( src_ind_Y() ); return 5; // AND ind,Y -// case 0x32: -// case 0x33: -// case 0x34: +// case 0x32: KIL +// case 0x33: RLA izy 8 +// case 0x34: NOP zpx 4 case 0x35: AND( src_zp_X() ); return 4; // AND zpg,X case 0x36: ROL( dest_zp_X() ); return 6; // ROL zpg,X -// case 0x37: +// case 0x37: RLA zpx 6 case 0x38: SEC(); return 2; // SEC case 0x39: AND( src_abs_Y() ); return 4; // AND abs,Y -// case 0x3A: -// case 0x3B: -// case 0x3C: +// case 0x3A: NOP 2 +// case 0x3B: RLA aby 7 +// case 0x3C: NOP abx 4 case 0x3D: AND( src_abs_X() ); return 4; // AND abs,X case 0x3E: ROL( dest_abs_X() ); return 7; // ROL abs,X -// case 0x3F: +// case 0x3F: RLA abx 7 case 0x40: RTI(); return 6; // RTI case 0x41: EOR( src_X_ind() ); return 6; // EOR X,ind -// case 0x42: -// case 0x43: -// case 0x44: +// case 0x42: KIL +// case 0x43: SRE izx 8 +// case 0x44: NOP zp 3 case 0x45: EOR( src_zp() ); return 3; // EOR zpg case 0x46: LSR( dest_zp() ); return 5; // LSR zpg -// case 0x47: +// case 0x47: SRE zp 5 case 0x48: PHA(); return 3; // PHA case 0x49: EOR( imm() ); return 2; // EOR imm case 0x4A: LSRA(); return 2; // LSR A -// case 0x4B: +// case 0x4B: ALR imm 2 case 0x4C: JMP( abs_addr() ); return 3; // JMP abs case 0x4D: EOR( src_abs() ); return 4; // EOR abs case 0x4E: LSR( dest_abs() ); return 6; // LSR abs -// case 0x4F: +// case 0x4F: SRE abs 6 case 0x50: BVC( rel_addr() ); return 2; // BVC rel case 0x51: EOR( src_ind_Y() ); return 5; // EOR ind,Y -// case 0x52: -// case 0x53: -// case 0x54: +// case 0x52: KIL +// case 0x53: SRE izy 8 +// case 0x54: NOP zpx 4 case 0x55: EOR( src_zp_X() ); return 4; // AND zpg,X case 0x56: LSR( dest_zp_X() ); return 6; // LSR zpg,X -// case 0x57: +// case 0x57: SRE zpx 6 case 0x58: CLI(); return 2; // CLI case 0x59: EOR( src_abs_Y() ); return 4; // EOR abs,Y -// case 0x5A: -// case 0x5B: -// case 0x5C: +// case 0x5A: NOP 2 +// case 0x5B: SRE aby 7 +// case 0x5C: NOP abx 4 case 0x5D: EOR( src_abs_X() ); return 4; // EOR abs,X case 0x5E: LSR( dest_abs_X() ); return 7; // LSR abs,X -// case 0x5F: +// case 0x5F: SRE abx 7 case 0x60: RTS(); return 6; // RTS case 0x61: ADC( src_X_ind() ); return 6; // ADC X,ind -// case 0x62: -// case 0x63: -// case 0x64: +// case 0x62: KIL +// case 0x63: RRA izx 8 +// case 0x64: NOP zp 3 case 0x65: ADC( src_zp() ); return 3; // ADC zpg case 0x66: ROR( dest_zp() ); return 5; // ROR zpg -// case 0x67: +// case 0x67: RRA zp 5 case 0x68: PLA(); break; // PLA case 0x69: ADC( imm() ); return 2; // ADC imm case 0x6A: RORA(); return 2; // ROR A -// case 0x6B: +// case 0x6B: ARR imm 2 case 0x6C: JMP( ind_addr() ); return 5; // JMP ind case 0x6D: ADC( src_abs() ); return 4; // ADC abs case 0x6E: ROR( dest_abs() ); return 6; // ROR abs -// case 0x6F: +// case 0x6F: RRA abs 6 case 0x70: BVS( rel_addr() ); break; // BVS rel case 0x71: ADC( src_ind_Y() ); return 5; // ADC ind,Y // case 0x72: @@ -181,7 +216,7 @@ static inline int m6502_step() { case 0x86: STX( dest_zp() ); return 3; // STX zpg // case 0x87: case 0x88: DEY(); return 2; // DEY -// case 0x89: +// case 0x89: NOP(); imm(); return 4; // NOP imm case 0x8A: TXA(); return 2; // TXA // case 0x8B: case 0x8C: STY( dest_abs() ); return 4; // STY abs @@ -194,7 +229,7 @@ static inline int m6502_step() { // case 0x93: case 0x94: STY( dest_zp_X() ); return 4; // STY zpg,X case 0x95: STA( dest_zp_X() ); return 4; // STA zpg,X - case 0x96: STX( dest_zp_X() ); return 4; // STX zpg,Y + case 0x96: STX( dest_zp_Y() ); return 4; // STX zpg,Y // case 0x97: case 0x98: TYA(); return 2; // TYA case 0x99: STA( dest_abs_Y() ); return 5; // STA abs,Y @@ -302,7 +337,7 @@ static inline int m6502_step() { // case 0xFF: default: - printf("Unimplemented Instruction 0x%02X\n", memread( m6502.pc -1 )); + printf("%04X: Unimplemented Instruction 0x%02X\n", m6502.PC -1, memread( m6502.PC -1 )); break; } // } // fetch16 @@ -312,28 +347,39 @@ static inline int m6502_step() { const unsigned long long int iterations = G; -unsigned long long TICK_PER_SEC = G; -unsigned long long TICK_6502_PER_SEC = 0; +unsigned long long tick_per_sec = G; +unsigned long long tick_6502_per_sec = 0; unsigned long long MHz_6502 = 1.023 * M; -static __inline__ unsigned long long rdtsc(void) +static __attribute__((always_inline)) unsigned long long rdtsc(void) { unsigned hi, lo; __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi) ); return ( (unsigned long long)lo) | ( ((unsigned long long)hi) << 32 ); } +// nanosec does not work very well for some reason +struct timespec tim, tim2; -static inline void m6502_run() { - uint8_t clk = 0; +INLINE void m6502_run() { // init time -// unsigned long long s = rdtsc(); +#ifdef CLK_WAIT + unsigned long long s = rdtsc(); unsigned long long e = (unsigned long long)-1LL; +#endif -// for ( unsigned long long int i = 0; i < iterations ; i++ ) { -// for ( ; m6502.pc ; ) { - for ( ; ; ) { - if ( m6502.interrupt_flag ) { +#ifdef SPEED_TEST + for ( unsigned long long int i = 0; i < iterations ; i++ ) +#else +// for ( ; m6502.pc ; ) + + tim.tv_sec = 0; + tim.tv_nsec = 500L; + + for ( ; ; ) +#endif + { + if ( m6502.IF ) { switch (m6502.interrupt) { case NMI: break; @@ -342,25 +388,31 @@ static inline void m6502_run() { break; case SOFTRESET: - m6502.pc = memread16(SOFTRESET_VECTOR); + m6502.PC = memread16(SOFTRESET_VECTOR); break; default: break; } - m6502.interrupt_flag = 0; + m6502.IF = 0; } - dbgPrintf("%04u %04X: ", clktime, m6502.pc); - clk = m6502_step(); - clktime += clk; - e = TICK_6502_PER_SEC * clktime; + dbgPrintf("%llu %04X: ", clktime, m6502.PC); + clktime += m6502_step(); + +#ifdef CLK_WAIT + e = tick_6502_per_sec * clktime; // query time + wait -// usleep(1); + + // TODO: We should use nanosleep + usleep(1); // this is good enough for debugging + +// nanosleep(&tim, &tim2); // tight loop gives us the most precise wait time // while ( rdtsc() - s < e ) {} +#endif dbgPrintf("\n"); } @@ -370,11 +422,11 @@ void init() { unsigned long long s = rdtsc(); sleep(1); unsigned long long e = rdtsc(); - TICK_PER_SEC = e - s; - TICK_6502_PER_SEC = TICK_PER_SEC / MHz_6502; + tick_per_sec = e - s; + tick_6502_per_sec = tick_per_sec / MHz_6502; memset( RAM, 0, sizeof(RAM) ); - + // RAM[ 0 ] = 0x4C; // RAM[ 1 ] = 0; @@ -384,6 +436,29 @@ void init() { // RAM[ 0xBFFE ] = 0; // RAM[ 0xBFFF ] = 0; + m6502.A = m6502.X = m6502.Y = 0xFF; + // reset vector + m6502.SP = 0xFF -3; + m6502.SR = 0x30; + + // memory size + *((uint16_t*)(&RAM[0x73])) = 0xC000; + +#define NO_FUNCTIONTEST + +#ifdef FUNCTIONTEST + FILE * f = fopen("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/6502_functional_test.bin", "rb"); + if (f == NULL) { + perror("Failed: "); + return; + } + + fread( RAM, 1, 65536, f); + fclose(f); + + m6502.PC = 0x400; + +#else FILE * f = fopen("/Users/trudnai/Library/Containers/com.gamealloy.A2Mac/Data/apple.rom", "rb"); if (f == NULL) { perror("Failed: "); @@ -392,10 +467,9 @@ void init() { fread( RAM + 0xD000, 1, 0x3000, f); fclose(f); - - // reset vector - m6502.pc = memread16( 0xFFFC ); - m6502.sp = 0xFF; + + m6502.PC = memread16( RESET_VECTOR ); +#endif uint8_t counter[] = { @@ -517,11 +591,11 @@ void tst6502() { // double execution_time = ((double) (end - start)) / CLOCKS_PER_SEC; unsigned long long e = rdtsc(); unsigned long long t = e - s; - double execution_time = (double)t / TICK_PER_SEC; + double execution_time = (double)t / tick_per_sec; double mips = iterations / (execution_time * M); double mhz = clktime / (execution_time * M); - printf("clk:%llu Elpased time: (%llu / %llu / %llu), %.3lfs (%.3lf MIPS, %.3lf MHz)\n", clktime, TICK_PER_SEC, MHz_6502, TICK_6502_PER_SEC, execution_time, mips, mhz); + printf("clk:%llu Elpased time: (%llu / %llu / %llu), %.3lfs (%.3lf MIPS, %.3lf MHz)\n", clktime, tick_per_sec, MHz_6502, tick_6502_per_sec, execution_time, mips, mhz); } int ___main(int argc, const char * argv[]) { diff --git a/A2Mac/6502.h b/A2Mac/6502.h index 89ad9f8..a92ec2a 100644 --- a/A2Mac/6502.h +++ b/A2Mac/6502.h @@ -27,32 +27,33 @@ typedef struct m6502_s { uint8_t A; // Accumulator uint8_t X; // X index register uint8_t Y; // Y index register +// union { +// uint8_t instr; // Instruction +// struct { +// uint8_t cc:2; +// uint8_t bbb:3; +// uint8_t aaa:3; +// }; +// }; union { - uint8_t instr; // Instruction + uint8_t SR; // Status Register struct { - uint8_t aaa:3; - uint8_t bbb:3; - uint8_t cc:2; + uint8_t C:1; // Carry Flag + uint8_t Z:1; // Zero Flag + uint8_t I:1; // Interrupt Flag + uint8_t D:1; // Decimal Flag + uint8_t B:1; // B Flag + uint8_t res:1; // reserved -- should be always 1 + uint8_t V:1; // Overflow Flag ??? + uint8_t N:1; // Negative Flag }; }; - union { - uint8_t sr; // Status Register as 1 byte - struct { - uint8_t N:1; // Negative Flag - uint8_t V:1; // Overflow Flag ??? - uint8_t B:2; // B Flag - uint8_t D:1; // Decimal Flag - uint8_t I:1; // Interrupt Flag - uint8_t Z:1; // Zero Flag - uint8_t C:1; // Carry Flag - } flags; // Status Register - }; - uint16_t pc; // Program Counter - uint8_t sp; // Stack Pointer ( stack addr = 0x01 + sp ) + uint16_t PC; // Program Counter + uint8_t SP; // Stack Pointer ( stack addr = 0x01 + sp ) unsigned clk; // Clock Counter union { - int interrupt_flag; + int IF; // interrut flag interrupt_t interrupt; }; } m6502_t; diff --git a/A2Mac/Apple2_mmio.h b/A2Mac/Apple2_mmio.h index 5f0c3ce..2740334 100644 --- a/A2Mac/Apple2_mmio.h +++ b/A2Mac/Apple2_mmio.h @@ -71,8 +71,8 @@ typedef union address16_u { } address16_t; -static inline uint8_t ioRead( uint16_t addr ) { -// printf("mmio:%04X\n", addr); +INLINE uint8_t ioRead( uint16_t addr ) { +// printf("mmio read:%04X\n", addr); switch (addr) { case io_KBD: return RAM[io_KBD]; @@ -88,7 +88,7 @@ static inline uint8_t ioRead( uint16_t addr ) { return 0; } -static inline void ioWrite( uint16_t addr ) { +INLINE void ioWrite( uint16_t addr ) { // printf("mmio:%04X\n", addr); switch (addr) { case io_KBD: @@ -104,11 +104,11 @@ static inline void ioWrite( uint16_t addr ) { Naive implementation of RAM read from address **/ -static inline uint8_t memread_zp( uint8_t addr ) { +INLINE uint8_t memread_zp( uint8_t addr ) { return RAM[ addr ]; } -static inline uint8_t memread( uint16_t addr ) { +INLINE uint8_t memread( uint16_t addr ) { // switch ( ((address16_t)addr).page ) { // case 0xC0: // case 0xC1: @@ -142,20 +142,25 @@ static inline uint8_t memread( uint16_t addr ) { /** Naive implementation of RAM read from address **/ -static inline uint8_t memread8( uint16_t addr ) { +INLINE uint8_t memread8( uint16_t addr ) { +// if ( addr == 0xD2AD ) { +// dbgPrintf("OUT OF MEMORY!\n"); +// } + + return RAM[ addr ]; } /** Naive implementation of RAM read from address **/ -static inline uint16_t memread16( uint16_t addr ) { +INLINE uint16_t memread16( uint16_t addr ) { return * (uint16_t*) (& RAM[ addr ]); } /** Naive implementation of RAM read from address **/ -//static inline uint16_t memioread16( uint16_t addr ) { +//INLINE uint16_t memioread16( uint16_t addr ) { // return (uint16_t)mmio_read[ addr ](addr); //} @@ -189,19 +194,19 @@ static void memwrite( uint16_t addr, uint8_t byte ) { Fetching 1 byte from memory address pc (program counter) increase pc by one **/ -static inline uint8_t fetch() { - dbgPrintf("%02X ", RAM[m6502.pc]); - return memread( m6502.pc++ ); +INLINE uint8_t fetch() { + dbgPrintf("%02X ", RAM[m6502.PC]); + return memread( m6502.PC++ ); } /** Fetching 2 bytes as a 16 bit number from memory address pc (program counter) increase pc by one **/ -static inline uint16_t fetch16() { - dbgPrintf("%04X ", memread16(m6502.pc)); - uint16_t word = memread16( m6502.pc ); - m6502.pc += 2; +INLINE uint16_t fetch16() { + dbgPrintf("%04X ", memread16(m6502.PC)); + uint16_t word = memread16( m6502.PC ); + m6502.PC += 2; return word; } @@ -209,24 +214,25 @@ static inline uint16_t fetch16() { abs .... absolute OPC $LLHH,X operand is address; effective address is address incremented by X with carry ** **/ -static inline uint16_t addr_abs() { +INLINE uint16_t addr_abs() { + dbgPrintf("abs:%04X(%02X) ", *((uint16_t*)&RAM[m6502.PC]), RAM[*((uint16_t*)&RAM[m6502.PC])]); return fetch16(); } -static inline uint8_t src_abs() { +INLINE uint8_t src_abs() { return memread( addr_abs() ); } -static inline uint8_t * dest_abs() { +INLINE uint8_t * dest_abs() { return & RAM[ addr_abs() ]; } -static inline int8_t rel_addr() { +INLINE int8_t rel_addr() { return fetch(); } -static inline uint16_t abs_addr() { +INLINE uint16_t abs_addr() { return fetch16(); } -static inline uint16_t ind_addr() { +INLINE uint16_t ind_addr() { return memread16( fetch16() ); } @@ -234,13 +240,14 @@ static inline uint16_t ind_addr() { abs,X .... absolute, X-indexed OPC $LLHH,X operand is address; effective address is address incremented by X with carry ** **/ -static inline uint16_t addr_abs_X() { +INLINE uint16_t addr_abs_X() { + dbgPrintf("abs,X:%04X(%02X) ", *((uint16_t*)&RAM[m6502.PC]) + m6502.X, RAM[*((uint16_t*)&RAM[m6502.PC]) + m6502.X]); return fetch16() + m6502.X; } -static inline uint8_t src_abs_X() { +INLINE uint8_t src_abs_X() { return memread8( addr_abs_X() ); } -static inline uint8_t * dest_abs_X() { +INLINE uint8_t * dest_abs_X() { return & RAM[ addr_abs_X() ]; } @@ -249,17 +256,18 @@ static inline uint8_t * dest_abs_X() { abs,Y .... absolute, Y-indexed OPC $LLHH,Y operand is address; effective address is address incremented by Y with carry ** **/ -static inline uint16_t addr_abs_Y() { +INLINE uint16_t addr_abs_Y() { + dbgPrintf("abs,Y:%04X(%02X) ", *((uint16_t*)&RAM[m6502.PC]) + m6502.Y, RAM[*((uint16_t*)&RAM[m6502.PC]) + m6502.Y]); return abs_addr() + m6502.Y; } -static inline uint8_t src_abs_Y() { +INLINE uint8_t src_abs_Y() { return memread8(addr_abs_Y()); } -static inline uint8_t * dest_abs_Y() { +INLINE uint8_t * dest_abs_Y() { return & RAM[ addr_abs_Y() ]; } -static inline uint16_t imm() { +INLINE uint16_t imm() { return fetch(); } @@ -268,20 +276,22 @@ static inline uint16_t imm() { zpg .... zeropage OPC $LL operand is zeropage address (hi-byte is zero, address = $00LL) **/ -static inline uint8_t addr_zp() { +INLINE uint8_t addr_zp() { + dbgPrintf("zp:%02X(%02X) ", RAM[m6502.PC], RAM[ RAM[m6502.PC]] ); return fetch(); } -static inline uint8_t src_zp() { +INLINE uint8_t src_zp() { return memread_zp(addr_zp()); } -static inline uint8_t * dest_zp() { +INLINE uint8_t * dest_zp() { return & RAM[ addr_zp() ]; } /** get a 16 bit address from the zp:zp+1 **/ -static inline uint16_t addr_zp_ind( uint8_t addr ) { +INLINE uint16_t addr_zp_ind( uint8_t addr ) { + dbgPrintf("zpi:%02X:%04X(%02X) ", RAM[m6502.PC], *((uint16_t*)&RAM[m6502.PC]), RAM[*((uint16_t*)&RAM[m6502.PC])]); return memread16(addr); } @@ -290,13 +300,14 @@ static inline uint16_t addr_zp_ind( uint8_t addr ) { operand is zeropage address; effective address is word in (LL + X, LL + X + 1), inc. without carry: C.w($00LL + X) **/ -static inline uint16_t addr_X_ind() { +INLINE uint16_t addr_X_ind() { + dbgPrintf("zpXi:%02X:%04X(%02X) ", RAM[m6502.PC], *((uint16_t*)&RAM[m6502.PC]) + m6502.X, RAM[*((uint16_t*)&RAM[m6502.PC]) + m6502.X]); return addr_zp_ind( addr_zp() + m6502.X ); } -static inline uint8_t src_X_ind() { +INLINE uint8_t src_X_ind() { return memread8( addr_X_ind() ); } -static inline uint8_t * dest_X_ind() { +INLINE uint8_t * dest_X_ind() { return & RAM[ addr_X_ind() ]; } @@ -305,15 +316,15 @@ static inline uint8_t * dest_X_ind() { operand is zeropage address; effective address is word in (LL, LL + 1) incremented by Y with carry: C.w($00LL) + Y **/ -static inline uint16_t addr_ind_Y() { +INLINE uint16_t addr_ind_Y() { // uint8_t a = fetch(); // dbgPrintf("addr_ind_Y: %04X + %02X = %04X ", addr_zpg_ind( a ), m6502.Y, addr_zpg_ind( a ) + m6502.Y); return addr_zp_ind( addr_zp() ) + m6502.Y; } -static inline uint8_t src_ind_Y() { +INLINE uint8_t src_ind_Y() { return memread8( addr_ind_Y() ); } -static inline uint8_t * dest_ind_Y() { +INLINE uint8_t * dest_ind_Y() { return & RAM[ addr_ind_Y() ]; } @@ -322,13 +333,13 @@ static inline uint8_t * dest_ind_Y() { operand is zeropage address; effective address is address incremented by X without carry ** **/ -static inline uint8_t addr_zp_X() { +INLINE uint8_t addr_zp_X() { return addr_zp() + m6502.X; } -static inline uint8_t src_zp_X() { +INLINE uint8_t src_zp_X() { return memread_zp(addr_zp_X()); } -static inline uint8_t * dest_zp_X() { +INLINE uint8_t * dest_zp_X() { return & RAM[ addr_zp_X() ]; } @@ -337,13 +348,13 @@ static inline uint8_t * dest_zp_X() { operand is zeropage address; effective address is address incremented by Y without carry ** **/ -static inline uint8_t addr_zp_Y() { +INLINE uint8_t addr_zp_Y() { return addr_zp() + m6502.Y; } -static inline uint8_t src_zp_Y() { +INLINE uint8_t src_zp_Y() { return memread_zp(addr_zp_Y()); } -static inline uint8_t * dest_zp_Y() { +INLINE uint8_t * dest_zp_Y() { return & RAM[ addr_zp_Y() ]; } diff --git a/A2Mac/Apple2_mmio_8bit_ioaddr.h b/A2Mac/Apple2_mmio_8bit_ioaddr.h index 1b9d9fa..76ae160 100644 --- a/A2Mac/Apple2_mmio_8bit_ioaddr.h +++ b/A2Mac/Apple2_mmio_8bit_ioaddr.h @@ -71,7 +71,7 @@ typedef union address16_u { } address16_t; -static inline uint8_t ioRead( uint16_t addr ) { +INLINE uint8_t ioRead( uint16_t addr ) { // printf("mmio:%04X\n", addr); // C0xx @@ -362,7 +362,7 @@ static inline uint8_t ioRead( uint16_t addr ) { return 0; } -static inline void ioWrite( uint16_t addr ) { +INLINE void ioWrite( uint16_t addr ) { // printf("mmio:%04X\n", addr); switch (addr) { case io_KBD: @@ -378,11 +378,11 @@ static inline void ioWrite( uint16_t addr ) { Naive implementation of RAM read from address **/ -static inline uint8_t memread_zp( uint8_t addr ) { +INLINE uint8_t memread_zp( uint8_t addr ) { return RAM[ addr ]; } -static inline uint8_t memread( uint16_t addr ) { +INLINE uint8_t memread( uint16_t addr ) { // switch ( ((address16_t)addr).page ) { // case 0xC0: // case 0xC1: @@ -416,7 +416,7 @@ static inline uint8_t memread( uint16_t addr ) { /** Naive implementation of RAM read from address **/ -static inline uint16_t memread16( uint16_t addr ) { +INLINE uint16_t memread16( uint16_t addr ) { // if ( ( addr >= 0xC000 ) && ( addr < 0xD000 ) ) { // return mmioRead(addr); // } @@ -428,7 +428,7 @@ static inline uint16_t memread16( uint16_t addr ) { /** Naive implementation of RAM read from address **/ -//static inline uint16_t memioread16( uint16_t addr ) { +//INLINE uint16_t memioread16( uint16_t addr ) { // return (uint16_t)mmio_read[ addr ](addr); //} @@ -462,7 +462,7 @@ static void memwrite( uint16_t addr, uint8_t byte ) { Fetching 1 byte from memory address pc (program counter) increase pc by one **/ -static inline uint8_t fetch() { +INLINE uint8_t fetch() { dbgPrintf("%02X ", RAM[m6502.pc]); return memread( m6502.pc++ ); } @@ -471,7 +471,7 @@ static inline uint8_t fetch() { Fetching 2 bytes as a 16 bit number from memory address pc (program counter) increase pc by one **/ -static inline uint16_t fetch16() { +INLINE uint16_t fetch16() { dbgPrintf("%04X ", memread16(m6502.pc)); uint16_t word = memread16( m6502.pc ); m6502.pc += 2; @@ -481,7 +481,7 @@ static inline uint16_t fetch16() { /** get a 16 bit address from the zp:zp+1 **/ -static inline uint16_t addr_zp_ind( uint8_t addr ) { +INLINE uint16_t addr_zp_ind( uint8_t addr ) { return memread16(addr); } @@ -490,13 +490,13 @@ static inline uint16_t addr_zp_ind( uint8_t addr ) { operand is zeropage address; effective address is word in (LL + X, LL + X + 1), inc. without carry: C.w($00LL + X) **/ -static inline uint16_t addr_X_ind() { +INLINE uint16_t addr_X_ind() { return addr_zp_ind( fetch() + m6502.X ); } -static inline uint8_t src_X_ind() { +INLINE uint8_t src_X_ind() { return memread( addr_X_ind() ); } -static inline uint8_t * dest_X_ind() { +INLINE uint8_t * dest_X_ind() { return & RAM[ addr_X_ind() ]; } @@ -505,7 +505,7 @@ static inline uint8_t * dest_X_ind() { operand is zeropage address; effective address is word in (LL, LL + 1) incremented by Y with carry: C.w($00LL) + Y **/ -static inline uint16_t addr_ind_Y() { +INLINE uint16_t addr_ind_Y() { uint8_t a = fetch(); // dbgPrintf("addr_ind_Y: %04X + %02X = %04X ", addr_zpg_ind( a ), m6502.Y, addr_zpg_ind( a ) + m6502.Y); return addr_zp_ind( a ) + m6502.Y; @@ -515,18 +515,18 @@ static inline uint16_t addr_ind_Y() { abs,X .... absolute, X-indexed OPC $LLHH,X operand is address; effective address is address incremented by X with carry ** **/ -static inline uint16_t addr_abs_X() { +INLINE uint16_t addr_abs_X() { return fetch16() + m6502.X; } -static inline uint8_t src_abs_X() { +INLINE uint8_t src_abs_X() { return memread( addr_abs_X() ); } -static inline uint8_t * dest_abs_X() { +INLINE uint8_t * dest_abs_X() { return & RAM[ addr_abs_X() ]; } -static inline uint16_t abs_addr() { +INLINE uint16_t abs_addr() { return fetch16(); } @@ -534,13 +534,13 @@ static inline uint16_t abs_addr() { abs,Y .... absolute, Y-indexed OPC $LLHH,Y operand is address; effective address is address incremented by Y with carry ** **/ -static inline uint16_t addr_abs_Y() { +INLINE uint16_t addr_abs_Y() { return fetch16() + m6502.Y; } -static inline uint8_t src_abs_Y() { +INLINE uint8_t src_abs_Y() { return memread(addr_abs_Y()); } -static inline uint8_t * dest_abs_Y() { +INLINE uint8_t * dest_abs_Y() { return & RAM[ addr_abs_Y() ]; } @@ -548,13 +548,13 @@ static inline uint8_t * dest_abs_Y() { zpg .... zeropage OPC $LL operand is zeropage address (hi-byte is zero, address = $00LL) **/ -static inline uint16_t addr_zp() { +INLINE uint16_t addr_zp() { return fetch(); } -static inline uint8_t src_zp() { +INLINE uint8_t src_zp() { return memread_zp(addr_zp()); } -static inline uint8_t * dest_zp() { +INLINE uint8_t * dest_zp() { return & RAM[ addr_zp() ]; } @@ -563,7 +563,7 @@ static inline uint8_t * dest_zp() { operand is zeropage address; effective address is address incremented by X without carry ** **/ -static inline uint16_t addr_zp_X() { +INLINE uint16_t addr_zp_X() { return addr_zp() + m6502.X; } @@ -572,7 +572,7 @@ static inline uint16_t addr_zp_X() { operand is zeropage address; effective address is address incremented by Y without carry ** **/ -static inline uint16_t addr_zp_Y() { +INLINE uint16_t addr_zp_Y() { return addr_zp() + m6502.Y; } diff --git a/A2Mac/Base.lproj/Main.storyboard b/A2Mac/Base.lproj/Main.storyboard index 3f97ada..c4b8024 100644 --- a/A2Mac/Base.lproj/Main.storyboard +++ b/A2Mac/Base.lproj/Main.storyboard @@ -714,7 +714,7 @@ - + diff --git a/A2Mac/RepeatingTimer.swift b/A2Mac/RepeatingTimer.swift new file mode 100644 index 0000000..6fc7209 --- /dev/null +++ b/A2Mac/RepeatingTimer.swift @@ -0,0 +1,66 @@ +// +// RepeatingTimer.swift +// A2Mac +// +// Created by Tamas Rudnai on 9/15/19. +// Copyright © 2019 GameAlloy. All rights reserved. +// + +import Foundation + +/// RepeatingTimer mimics the API of DispatchSourceTimer but in a way that prevents +/// crashes that occur from calling resume multiple times on a timer that is +/// already resumed (noted by https://github.com/SiftScience/sift-ios/issues/52 +class RepeatingTimer { + + let timeInterval: TimeInterval + var eventHandler: (() -> Void)? + + private enum State { + case suspended + case resumed + } + + private var state: State = .suspended + + init(timeInterval: TimeInterval) { + self.timeInterval = timeInterval + } + + private lazy var timer: DispatchSourceTimer = { + let t = DispatchSource.makeTimerSource() + t.schedule(deadline: .now() + self.timeInterval, repeating: self.timeInterval) + t.setEventHandler(handler: { [weak self] in + self?.eventHandler?() + }) + return t + }() + + + deinit { + timer.setEventHandler {} + timer.cancel() + /* + If the timer is suspended, calling cancel without resuming + triggers a crash. This is documented here https://forums.developer.apple.com/thread/15902 + */ + resume() + eventHandler = nil + } + + func resume() { + if state == .resumed { + return + } + state = .resumed + timer.resume() + } + + func suspend() { + if state == .suspended { + return + } + state = .suspended + timer.suspend() + } +} diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift index 74032ac..29b90af 100644 --- a/A2Mac/ViewController.swift +++ b/A2Mac/ViewController.swift @@ -39,7 +39,9 @@ class ViewController: NSViewController { } else { workItem = DispatchWorkItem { - DispatchQueue.global(qos: .userInitiated).async { +// DispatchQueue.global(qos: .userInteractive).async { +// DispatchQueue.global(qos: .userInitiated).async { + DispatchQueue.global(qos: .background).async { tst6502() } } @@ -62,75 +64,83 @@ class ViewController: NSViewController { override func keyDown(with event: NSEvent) { - switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { - case [.command] where event.characters == "l", - [.command, .shift] where event.characters == "l": - print("command-l or command-shift-l") - default: - break - } - print( "key = " + (event.charactersIgnoringModifiers ?? "")) - print( "\ncharacter = " + (event.characters ?? "")) +// switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { +// case [.command] where event.characters == "l", +// [.command, .shift] where event.characters == "l": +// print("command-l or command-shift-l") +// default: +// break +// } +// print( "key = " + (event.charactersIgnoringModifiers ?? "")) +// print( "\ncharacter = " + (event.characters ?? "")) + #if FUNCTIONTEST + #else if let chars = event.characters { let char = chars.uppercased()[chars.startIndex] if let code = char.asciiValue { var A2code = code | 0x80 - if ( code == 13 ) { + switch ( code ) { + case 13: A2code = 141 + break + + default: + break } print("keycode: \(code) --> \(A2code)") - let resetPointer = UnsafeMutableRawBufferPointer(start: &RAM + 0xC000, count: 1) - resetPointer[0] = A2code + let kbdPointer = UnsafeMutableRawBufferPointer(start: &RAM + 0xC000, count: 1) + kbdPointer[0] = A2code } } + #endif } override func flagsChanged(with event: NSEvent) { - switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { - case [.shift]: - print("shift key is pressed") - case [.control]: - print("control key is pressed") - case [.option] : - print("option key is pressed") - case [.command]: - print("Command key is pressed") - case [.control, .shift]: - print("control-shift keys are pressed") - case [.option, .shift]: - print("option-shift keys are pressed") - case [.command, .shift]: - print("command-shift keys are pressed") - case [.control, .option]: - print("control-option keys are pressed") - case [.control, .command]: - print("control-command keys are pressed") - case [.option, .command]: - print("option-command keys are pressed") - case [.shift, .control, .option]: - print("shift-control-option keys are pressed") - case [.shift, .control, .command]: - print("shift-control-command keys are pressed") - case [.control, .option, .command]: - print("control-option-command keys are pressed") - case [.shift, .command, .option]: - print("shift-command-option keys are pressed") - case [.shift, .control, .option, .command]: - print("shift-control-option-command keys are pressed") - default: - print("no modifier keys are pressed") - } +// switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) { +// case [.shift]: +// print("shift key is pressed") +// case [.control]: +// print("control key is pressed") +// case [.option] : +// print("option key is pressed") +// case [.command]: +// print("Command key is pressed") +// case [.control, .shift]: +// print("control-shift keys are pressed") +// case [.option, .shift]: +// print("option-shift keys are pressed") +// case [.command, .shift]: +// print("command-shift keys are pressed") +// case [.control, .option]: +// print("control-option keys are pressed") +// case [.control, .command]: +// print("control-command keys are pressed") +// case [.option, .command]: +// print("option-command keys are pressed") +// case [.shift, .control, .option]: +// print("shift-control-option keys are pressed") +// case [.shift, .control, .command]: +// print("shift-control-command keys are pressed") +// case [.control, .option, .command]: +// print("control-option-command keys are pressed") +// case [.shift, .command, .option]: +// print("shift-command-option keys are pressed") +// case [.shift, .control, .option, .command]: +// print("shift-control-option-command keys are pressed") +// default: +// print("no modifier keys are pressed") +// } } func update() { - while true { - usleep(33333) // 1/30 sec +// while true { +// usleep(33333) // 1/30 sec let textBaseAddr = 0x400 let textLines = 24 @@ -142,28 +152,24 @@ class ViewController: NSViewController { let textAddr = textBaseAddr + textLineOfs[y] let textBufferPointer = UnsafeRawBufferPointer(start: &RAM + textAddr, count: textCols) - for (index, byte) in textBufferPointer.enumerated() { + for (_, byte) in textBufferPointer.enumerated() { let idx = Int(byte); let chr = ViewController.charConvTbl[idx] // print("byte \(index): \(chr)") - txt = txt + " \(chr)" + txt = txt + "\(chr)" } - txt = txt + " |\n" + txt = txt + "\n" } DispatchQueue.main.async { self.display.stringValue = txt; } - } +// } -// DispatchQueue.main.asyncAfter(deadline: .now() + 1/30, execute: { -// self.update() -// }) - } - + // func FromBuf(ptr: UnsafeMutablePointer, length len: Int) -> String? { // // convert the bytes using the UTF8 encoding @@ -174,17 +180,27 @@ class ViewController: NSViewController { // } // } + + let upd = RepeatingTimer(timeInterval: 1/30) + override func viewDidLoad() { super.viewDidLoad() // DispatchQueue.main.asyncAfter(deadline: .now() + 1/30, execute: { // self.update() // }) + + #if FUNCTIONTEST + #else +// DispatchQueue.global(qos: .background).async { +// self.update() +// } - DispatchQueue.global(qos: .background).async { + upd.eventHandler = { self.update() } - + upd.resume() + #endif } override var representedObject: Any? { diff --git a/A2Mac/common.h b/A2Mac/common.h index 74ab6d4..e1978c6 100644 --- a/A2Mac/common.h +++ b/A2Mac/common.h @@ -41,50 +41,50 @@ union { #define BITTEST(n,x) ((bits_t)(n)).b##x -static inline void set_flags_N( const uint8_t test ) { - m6502.flags.N = BITTEST(test, 7); - dbgPrintf("%c", m6502.flags.N ? 'N' : 'n'); +INLINE void set_flags_N( const uint8_t test ) { + m6502.N = BITTEST(test, 7); + dbgPrintf("%c", m6502.N ? 'N' : 'n'); } -static inline void set_flags_V( const uint8_t test ) { - m6502.flags.V = BITTEST(test, 6); - dbgPrintf("%c", m6502.flags.V ? 'V' : 'v'); +INLINE void set_flags_V( const uint8_t test ) { + m6502.V = BITTEST(test, 6); + dbgPrintf("%c", m6502.V ? 'V' : 'v'); } -static inline void set_flags_Z( const uint8_t test ) { - m6502.flags.Z = test == 0; - dbgPrintf("%c", m6502.flags.Z ? 'Z' : 'z'); +INLINE void set_flags_Z( const uint8_t test ) { + m6502.Z = test == 0; + dbgPrintf("%c", m6502.Z ? 'Z' : 'z'); } -static inline void set_flags_C( const int16_t test ) { - m6502.flags.C = test >= 0; - dbgPrintf("%c", m6502.flags.C ? 'C' : 'c'); +INLINE void set_flags_C( const int16_t test ) { + m6502.C = test >= 0; + dbgPrintf("%c", m6502.C ? 'C' : 'c'); } -static inline void set_flags_NZ( const uint8_t test ) { +INLINE void set_flags_NZ( const uint8_t test ) { set_flags_N(test); set_flags_Z(test); } -static inline void set_flags_NV( const uint8_t test ) { +INLINE void set_flags_NV( const uint8_t test ) { set_flags_N(test); set_flags_V(test); } -static inline void set_flags_NVZ( const uint8_t test ) { +INLINE void set_flags_NVZ( const uint8_t test ) { set_flags_NZ(test); set_flags_V(test); } -static inline void set_flags_NZC( const int16_t test ) { +INLINE void set_flags_NZC( const int16_t test ) { set_flags_NZ(test); set_flags_C(test); } -static inline void set_flags_NZCV( int test ) { - set_flags_NZC(test); - set_flags_V(test); -} +//INLINE void set_flags_NZCV( int test ) { +// set_flags_NZC(test); +// set_flags_V(test); +//} diff --git a/A2Mac/instructions/6502_instr_arithmetic.h b/A2Mac/instructions/6502_instr_arithmetic.h index 5599581..1e79fb0 100644 --- a/A2Mac/instructions/6502_instr_arithmetic.h +++ b/A2Mac/instructions/6502_instr_arithmetic.h @@ -29,12 +29,13 @@ (indirect,X) ADC (oper,X) 61 2 6 (indirect),Y ADC (oper),Y 71 2 5* **/ -static inline void ADC( uint8_t imm ) { - dbgPrintf("ADC(%02X) A:%02X + %02X ", imm, m6502.A, imm); +INLINE void ADC( uint8_t src ) { + dbgPrintf("ADC(%02X) A:%02X + %02X ", src, m6502.A, src); - int16_t tmp; - set_flags_NVZ( m6502.A = tmp = (int16_t)m6502.A + imm + m6502.flags.C ); - m6502.flags.C = tmp > 0xFF; + uint16_t tmp; + set_flags_NZ( m6502.A = tmp = (uint16_t)m6502.A + src + m6502.C ); + m6502.V = (!((m6502.A ^ src) & 0x80)) && ((m6502.A ^ tmp) & 0x80); + m6502.C = tmp > 0xFF; dbgPrintf("-> A:%02X ", m6502.A); } @@ -56,9 +57,9 @@ static inline void ADC( uint8_t imm ) { (indirect,X) SBC (oper,X) E1 2 6 (indirect),Y SBC (oper),Y F1 2 5* **/ -static inline void SBC( uint8_t imm ) { - dbgPrintf("SBC(%02X) ", imm); - ADC( ~imm ); +INLINE void SBC( uint8_t src ) { + dbgPrintf("SBC(%02X) ", src); + ADC( ~src ); } #endif // __6502_INSTR_ARITHMETIC_H__ diff --git a/A2Mac/instructions/6502_instr_branch.h b/A2Mac/instructions/6502_instr_branch.h index b05ebe4..0b84efb 100644 --- a/A2Mac/instructions/6502_instr_branch.h +++ b/A2Mac/instructions/6502_instr_branch.h @@ -9,9 +9,14 @@ #ifndef __6502_INSTR_BRANCH_H__ #define __6502_INSTR_BRANCH_H__ -static inline void BRA( int8_t reladdr ) { - m6502.pc += reladdr; - dbgPrintf("BRA %04X ", m6502.pc); +INLINE void BRA( int8_t reladdr ) { + m6502.PC += reladdr; +#ifdef DEBUG + if ( reladdr == -2 ) { + dbgPrintf("Infinite Loop at %04X!\n", m6502.PC); + } +#endif + dbgPrintf("BRA %04X ", m6502.PC); } /** @@ -24,9 +29,9 @@ static inline void BRA( int8_t reladdr ) { -------------------------------------------- relative BCC oper 90 2 2** **/ -static inline void BCC( int8_t reladdr ) { +INLINE void BCC( int8_t reladdr ) { dbgPrintf("BCC "); - if ( m6502.flags.C == 0 ) { + if ( m6502.C == 0 ) { BRA( reladdr ); } else { @@ -44,9 +49,9 @@ static inline void BCC( int8_t reladdr ) { -------------------------------------------- relative BCS oper B0 2 2** **/ -static inline void BCS( int8_t reladdr ) { +INLINE void BCS( int8_t reladdr ) { dbgPrintf("BCS "); - if ( m6502.flags.C == 1 ) { + if ( m6502.C == 1 ) { BRA( reladdr ); } else { @@ -64,9 +69,9 @@ static inline void BCS( int8_t reladdr ) { -------------------------------------------- relative BNE oper D0 2 2** **/ -static inline void BNE( int8_t reladdr ) { +INLINE void BNE( int8_t reladdr ) { dbgPrintf("BNE "); - if ( m6502.flags.Z == 0 ) { + if ( m6502.Z == 0 ) { BRA( reladdr ); } else { @@ -84,9 +89,9 @@ static inline void BNE( int8_t reladdr ) { -------------------------------------------- relative BEQ oper F0 2 2** **/ -static inline void BEQ( int8_t reladdr ) { +INLINE void BEQ( int8_t reladdr ) { dbgPrintf("BEQ "); - if ( m6502.flags.Z == 1 ) { + if ( m6502.Z == 1 ) { BRA( reladdr ); } else { @@ -104,9 +109,9 @@ static inline void BEQ( int8_t reladdr ) { -------------------------------------------- relative BPL oper 10 2 2** **/ -static inline void BPL( int8_t reladdr ) { +INLINE void BPL( int8_t reladdr ) { dbgPrintf("BPL "); - if ( m6502.flags.N == 0 ) { + if ( m6502.N == 0 ) { BRA( reladdr ); } else { @@ -124,9 +129,9 @@ static inline void BPL( int8_t reladdr ) { -------------------------------------------- relative BMI oper 30 2 2** **/ -static inline void BMI( int8_t reladdr ) { +INLINE void BMI( int8_t reladdr ) { dbgPrintf("BMI "); - if ( m6502.flags.N == 1 ) { + if ( m6502.N == 1 ) { BRA( reladdr ); } else { @@ -144,9 +149,9 @@ static inline void BMI( int8_t reladdr ) { -------------------------------------------- relative BVC oper 50 2 2** **/ -static inline void BVC( int8_t reladdr ) { +INLINE void BVC( int8_t reladdr ) { dbgPrintf("BVC "); - if ( m6502.flags.V == 0 ) { + if ( m6502.V == 0 ) { BRA( reladdr ); } else { @@ -164,9 +169,9 @@ static inline void BVC( int8_t reladdr ) { -------------------------------------------- relative BVC oper 70 2 2** **/ -static inline void BVS( int8_t reladdr ) { +INLINE void BVS( int8_t reladdr ) { dbgPrintf("BVS "); - if ( m6502.flags.V == 1 ) { + if ( m6502.V == 1 ) { BRA( reladdr ); } else { diff --git a/A2Mac/instructions/6502_instr_call_ret_jump.h b/A2Mac/instructions/6502_instr_call_ret_jump.h index 5fb9e52..12ed5c5 100644 --- a/A2Mac/instructions/6502_instr_call_ret_jump.h +++ b/A2Mac/instructions/6502_instr_call_ret_jump.h @@ -21,9 +21,14 @@ absolute JMP oper 4C 3 3 indirect JMP (oper) 6C 3 5 **/ -static inline void JMP( uint16_t addr ) { +INLINE void JMP( uint16_t addr ) { dbgPrintf("JMP %04X ", addr); - m6502.pc = addr; +#ifdef DEBUG + if ( addr == m6502.PC - 3 ) { + dbgPrintf("Infinite Loop at %04X!\n", m6502.PC); + } +#endif + m6502.PC = addr; } /** @@ -37,9 +42,9 @@ static inline void JMP( uint16_t addr ) { -------------------------------------------- absolute JSR oper 20 3 6 **/ -static inline void JSR( uint16_t addr ) { +INLINE void JSR( uint16_t addr ) { dbgPrintf("JSR "); - PUSH_addr(m6502.pc); + PUSH_addr(m6502.PC -1); JMP( addr ); } @@ -53,9 +58,9 @@ static inline void JSR( uint16_t addr ) { -------------------------------------------- implied RTS 60 1 6 **/ -static inline void RTS() { +INLINE void RTS() { dbgPrintf("RTS "); - JMP( POP_addr() ); + JMP( POP_addr() +1); } /** @@ -68,10 +73,11 @@ static inline void RTS() { -------------------------------------------- implied RTI 40 1 6 **/ -static inline void RTI() { +INLINE void RTI() { dbgPrintf("RTI "); - m6502.sr = POP(); - RTS(); + m6502.SR = POP(); +// m6502.I = 0; + JMP( POP_addr() ); } diff --git a/A2Mac/instructions/6502_instr_compare_test.h b/A2Mac/instructions/6502_instr_compare_test.h index 05d8cd2..f7d0725 100644 --- a/A2Mac/instructions/6502_instr_compare_test.h +++ b/A2Mac/instructions/6502_instr_compare_test.h @@ -24,10 +24,10 @@ absolute BIT oper 2C 3 4 **/ -static inline void BIT( uint8_t imm ) { - dbgPrintf("BIT(%02X) ", imm); - set_flags_NV(imm); - set_flags_Z(m6502.A & imm); +INLINE void BIT( uint8_t src ) { + dbgPrintf("BIT(%02X) ", src); + set_flags_NV(src); + set_flags_Z(m6502.A & src); } /** @@ -47,9 +47,9 @@ static inline void BIT( uint8_t imm ) { (indirect,X) CMP (oper,X) C1 2 6 (indirect),Y CMP (oper),Y D1 2 5* **/ -static inline void CMP( uint8_t imm ) { - dbgPrintf("CMP(%02X) ", imm); - set_flags_NZC( (int16_t)m6502.A - imm ); +INLINE void CMP( uint8_t src ) { + dbgPrintf("CMP(%02X) ", src); + set_flags_NZC( (int16_t)m6502.A - src ); } /** @@ -64,9 +64,9 @@ static inline void CMP( uint8_t imm ) { zeropage CPX oper E4 2 3 absolute CPX oper EC 3 4 **/ -static inline void CPX( uint8_t imm ) { - dbgPrintf("CPX(%02X) ", imm); - set_flags_NZC( (int16_t)m6502.X - imm ); +INLINE void CPX( uint8_t src ) { + dbgPrintf("CPX(%02X) ", src); + set_flags_NZC( (int16_t)m6502.X - src ); } /** @@ -81,9 +81,9 @@ static inline void CPX( uint8_t imm ) { zeropage CPY oper C4 2 3 absolute CPY oper CC 3 4 **/ -static inline void CPY( uint8_t imm ) { - dbgPrintf("CPY(%02X) ", imm); - set_flags_NZC( (int16_t)m6502.Y - imm ); +INLINE void CPY( uint8_t src ) { + dbgPrintf("CPY(%02X) ", src); + set_flags_NZC( (int16_t)m6502.Y - src ); } #endif // __6502_INSTR_COMPARE_TEST_H__ diff --git a/A2Mac/instructions/6502_instr_inc_dec.h b/A2Mac/instructions/6502_instr_inc_dec.h index f018a86..87bad57 100644 --- a/A2Mac/instructions/6502_instr_inc_dec.h +++ b/A2Mac/instructions/6502_instr_inc_dec.h @@ -23,7 +23,7 @@ absolute INC oper EE 3 6 absolute,X INC oper,X FE 3 7 **/ -static inline void INC( uint8_t * dst ) { +INLINE void INC( uint8_t * dst ) { dbgPrintf("INC %02X -> ", *dst); set_flags_NZ( ++(*dst) ); dbgPrintf("%02X ", *dst); @@ -39,7 +39,7 @@ static inline void INC( uint8_t * dst ) { -------------------------------------------- implied INX E8 1 2 **/ -static inline void INX() { +INLINE void INX() { dbgPrintf("INX %02X -> ", m6502.X); set_flags_NZ( ++m6502.X ); dbgPrintf("%02X ", m6502.X); @@ -55,7 +55,7 @@ static inline void INX() { -------------------------------------------- implied INY C8 1 2 **/ -static inline void INY() { +INLINE void INY() { dbgPrintf("INY %02X -> ", m6502.Y); set_flags_NZ( ++m6502.Y ); dbgPrintf("%02X ", m6502.Y); @@ -74,7 +74,7 @@ static inline void INY() { absolute DEC oper CE 3 3 absolute,X DEC oper,X DE 3 7 **/ -static inline void DEC( uint8_t * dst ) { +INLINE void DEC( uint8_t * dst ) { dbgPrintf("DEC %02X -> ", *dst); set_flags_NZ( --(*dst) ); dbgPrintf("%02X ", *dst); @@ -90,7 +90,7 @@ static inline void DEC( uint8_t * dst ) { -------------------------------------------- implied DEC CA 1 2 **/ -static inline void DEX() { +INLINE void DEX() { dbgPrintf("DEX %02X -> ", m6502.X); set_flags_NZ( --m6502.X ); dbgPrintf("%02X ", m6502.X); @@ -106,7 +106,7 @@ static inline void DEX() { -------------------------------------------- implied DEC 88 1 2 **/ -static inline void DEY() { +INLINE void DEY() { dbgPrintf("DEY %02X -> ", m6502.Y); set_flags_NZ( --m6502.Y ); dbgPrintf("%02X ", m6502.Y); diff --git a/A2Mac/instructions/6502_instr_load_store.h b/A2Mac/instructions/6502_instr_load_store.h index c9f6298..653edbb 100644 --- a/A2Mac/instructions/6502_instr_load_store.h +++ b/A2Mac/instructions/6502_instr_load_store.h @@ -29,10 +29,10 @@ (indirect,X) LDA (oper,X) A1 2 6 (indirect),Y LDA (oper),Y B1 2 5* **/ -static inline void LDA( uint8_t imm ) { - dbgPrintf("LDA(%02X) ", imm); - m6502.A = imm; - set_flags_NZ(imm); +INLINE void LDA( uint8_t src ) { + dbgPrintf("LDA(%02X) ", src); + m6502.A = src; + set_flags_NZ(src); } /** @@ -49,10 +49,10 @@ static inline void LDA( uint8_t imm ) { absolute LDX oper AE 3 4 absolute,Y LDX oper,Y BE 3 4* **/ -static inline void LDX( uint8_t imm ) { - dbgPrintf("LDX(%02X) ", imm); - m6502.X = imm; - set_flags_NZ(imm); +INLINE void LDX( uint8_t src ) { + dbgPrintf("LDX(%02X) ", src); + m6502.X = src; + set_flags_NZ(src); } /** @@ -69,10 +69,10 @@ static inline void LDX( uint8_t imm ) { absolute LDY oper AC 3 4 absolute,X LDY oper,X BC 3 4* **/ -static inline void LDY( uint8_t imm ) { - dbgPrintf("LDY(%02X) ", imm); - m6502.Y = imm; - set_flags_NZ(imm); +INLINE void LDY( uint8_t src ) { + dbgPrintf("LDY(%02X) ", src); + m6502.Y = src; + set_flags_NZ(src); } @@ -89,32 +89,50 @@ char * charConv = (not a real instruction, only a helper function) **/ -static inline void STR( uint8_t * dst, uint8_t imm ) { - *dst = imm; +INLINE void STR( uint8_t * dst, uint8_t src ) { + dbgPrintf("STR %02X -> %04X ", src, (int)(dst - RAM)); + *dst = src; -// uint16_t v = dst - RAM; -// if ( ( v >= 0x400 ) && ( v < 0x800 ) ) { -// char c = charConv[imm]; +// uint16_t addr = dst - RAM; +// if ( ( addr >= 0x400 ) && ( addr < 0x800 ) ) { +// char c = charConv[src]; //// if ( c == '?' ) { //// printf("? SYNTAX ERROR\n"); //// } // -// if (( imm > ' ' ) && ( c < 0x7F )) -// printf("*** PRINT: %04X: t:%02X '%c'\n", v, imm, isprint(c) ? c : ' '); +// if (( src > ' ' ) && ( c < 0x7F )) +// printf("*** PRINT: %04X: t:%02X '%c'\n", addr, src, isprint(c) ? c : ' '); +// } +// else if ( ( addr >= 0xC000 ) && ( addr < 0xD000 ) ) { +// printf("mmio write:[%04X] = %02X\n", addr, src); // } // // -// else switch ( v ) { +// else switch ( addr ) { // case 0x36: // case 0x37: -// dbgPrintf("*** OUTROUT %04X: %02X\n", v, imm); +// dbgPrintf("*** OUTROUT %04X: %02X\n", addr, src); // break; // // case 0x9B: // case 0x9C: -// dbgPrintf("*** LOWTR %04X: %02X\n", v, imm); +// dbgPrintf("*** LOWTR %04X: %02X\n", addr, src); // break; // +// case 0x6F: // FRETOP +// case 0x70: +// dbgPrintf("*** FRETOP %04X: %02X\n", addr, src); +// break; +// +// case 0x73: // MEMSIZ +// case 0x74: +// dbgPrintf("*** MEMSIZ %04X: %02X\n", addr, src); +// break; +// +// case 0x5E: +// dbgPrintf("*** ??? %04X: %02X\n", addr, src); +// break; +// // default: // break; // } @@ -136,7 +154,7 @@ static inline void STR( uint8_t * dst, uint8_t imm ) { (indirect,X) STA (oper,X) 81 2 6 (indirect),Y STA (oper),Y 91 2 6 **/ -static inline void STA( uint8_t * dst ) { +INLINE void STA( uint8_t * dst ) { dbgPrintf("STA "); STR(dst, m6502.A); } @@ -153,7 +171,7 @@ static inline void STA( uint8_t * dst ) { zeropage,Y STX oper,Y 96 2 4 absolute STX oper 8E 3 4 **/ -static inline void STX( uint8_t * dst ) { +INLINE void STX( uint8_t * dst ) { dbgPrintf("STX "); STR(dst, m6502.X); } @@ -170,7 +188,7 @@ static inline void STX( uint8_t * dst ) { zeropage,X STY oper,X 94 2 4 absolute STY oper 8C 3 4 **/ -static inline void STY( uint8_t * dst ) { +INLINE void STY( uint8_t * dst ) { dbgPrintf("STY "); STR(dst, m6502.Y); } diff --git a/A2Mac/instructions/6502_instr_logic.h b/A2Mac/instructions/6502_instr_logic.h index 544608e..b15beda 100644 --- a/A2Mac/instructions/6502_instr_logic.h +++ b/A2Mac/instructions/6502_instr_logic.h @@ -27,9 +27,9 @@ (indirect,X) ORA (oper,X) 01 2 6 (indirect),Y ORA (oper),Y 11 2 5* **/ -static inline void ORA( uint8_t imm ) { - dbgPrintf("ORA(%02X) ", imm); - set_flags_NZ( m6502.A |= imm ); +INLINE void ORA( uint8_t src ) { + dbgPrintf("ORA(%02X) ", src); + set_flags_NZ( m6502.A |= src ); } /** @@ -49,9 +49,9 @@ static inline void ORA( uint8_t imm ) { (indirect,X) AND (oper,X) 21 2 6 (indirect),Y AND (oper),Y 31 2 5* **/ -static inline void AND( uint8_t imm ) { - dbgPrintf("AND(%02X) ", imm); - set_flags_NZ( m6502.A &= imm ); +INLINE void AND( uint8_t src ) { + dbgPrintf("AND(%02X) ", src); + set_flags_NZ( m6502.A &= src ); } /** @@ -71,9 +71,9 @@ static inline void AND( uint8_t imm ) { (indirect,X) EOR (oper,X) 41 2 6 (indirect),Y EOR (oper),Y 51 2 5* **/ -static inline void EOR( uint8_t imm ) { - dbgPrintf("EOR(%02X) ", imm); - set_flags_NZ( m6502.A ^= imm ); +INLINE void EOR( uint8_t src ) { + dbgPrintf("EOR(%02X) ", src); + set_flags_NZ( m6502.A ^= src ); } #endif // __6502_INSTR_LOGIC_H__ diff --git a/A2Mac/instructions/6502_instr_misc.h b/A2Mac/instructions/6502_instr_misc.h index 0a697a4..ae82b14 100644 --- a/A2Mac/instructions/6502_instr_misc.h +++ b/A2Mac/instructions/6502_instr_misc.h @@ -20,8 +20,12 @@ -------------------------------------------- implied BRK 00 1 7 **/ -static inline void BRK() { +INLINE void BRK() { dbgPrintf("BRK "); + PUSH_addr(m6502.PC +1); // PC +2, however, fetch already incremented it by 1 + PUSH(m6502.SR); + m6502.I = 1; + JMP(memread16(IRQ_VECTOR)); } /** @@ -34,8 +38,8 @@ static inline void BRK() { -------------------------------------------- implied NOP EA 1 2 **/ -static inline void NOP() { - dbgPrintf("STA "); +INLINE void NOP() { + dbgPrintf("NOP "); } #endif // __6502_INSTR_MISC_H__ diff --git a/A2Mac/instructions/6502_instr_set_clr.h b/A2Mac/instructions/6502_instr_set_clr.h index 974b9cb..5a65170 100644 --- a/A2Mac/instructions/6502_instr_set_clr.h +++ b/A2Mac/instructions/6502_instr_set_clr.h @@ -19,9 +19,9 @@ -------------------------------------------- implied CLC 18 1 2 **/ -static inline void CLC() { +INLINE void CLC() { dbgPrintf("CLC "); - m6502.flags.C = 0; + m6502.C = 0; } /** @@ -34,9 +34,9 @@ static inline void CLC() { -------------------------------------------- implied CLD D8 1 2 **/ -static inline void CLD() { +INLINE void CLD() { dbgPrintf("CLD "); - m6502.flags.D = 0; + m6502.D = 0; } /** @@ -49,9 +49,9 @@ static inline void CLD() { -------------------------------------------- implied CLI 58 1 2 **/ -static inline void CLI() { +INLINE void CLI() { dbgPrintf("CLI "); - m6502.flags.I = 0; + m6502.I = 0; } /** @@ -64,9 +64,9 @@ static inline void CLI() { -------------------------------------------- implied CLV B8 1 2 **/ -static inline void CLV() { +INLINE void CLV() { dbgPrintf("CLV "); - m6502.flags.V = 0; + m6502.V = 0; } /** @@ -79,9 +79,9 @@ static inline void CLV() { -------------------------------------------- implied SEC 38 1 2 **/ -static inline void SEC() { +INLINE void SEC() { dbgPrintf("SEC "); - m6502.flags.C = 1; + m6502.C = 1; } /** @@ -94,9 +94,9 @@ static inline void SEC() { -------------------------------------------- implied SED F8 1 2 **/ -static inline void SED() { +INLINE void SED() { dbgPrintf("SED "); - m6502.flags.D = 1; + m6502.D = 1; } /** @@ -109,9 +109,9 @@ static inline void SED() { -------------------------------------------- implied SEI 78 1 2 **/ -static inline void SEI() { +INLINE void SEI() { dbgPrintf("SEI "); - m6502.flags.I = 1; + m6502.I = 1; } #endif // __6502_INSTR_SET_CLR_H__ diff --git a/A2Mac/instructions/6502_instr_shift_rotate.h b/A2Mac/instructions/6502_instr_shift_rotate.h index 50fdd86..515d24f 100644 --- a/A2Mac/instructions/6502_instr_shift_rotate.h +++ b/A2Mac/instructions/6502_instr_shift_rotate.h @@ -24,16 +24,14 @@ absolute ASL oper 0E 3 6 absolute,X ASL oper,X 1E 3 7 **/ -static inline void ASL( uint8_t * dst ) { +INLINE void ASL( uint8_t * dst ) { dbgPrintf("ASL "); - m6502.flags.C = *dst >> 7; - ; + m6502.C = *dst >> 7; set_flags_NZ( *dst <<= 1 ); } -static inline void ASLA() { +INLINE void ASLA() { dbgPrintf("ASL "); - m6502.flags.C = m6502.A >> 7; - ; + m6502.C = m6502.A >> 7; set_flags_NZ( m6502.A <<= 1 ); } @@ -51,14 +49,14 @@ static inline void ASLA() { absolute LSR oper 4E 3 6 absolute,X LSR oper,X 5E 3 7 **/ -static inline void LSR( uint8_t * dst ) { +INLINE void LSR( uint8_t * dst ) { dbgPrintf("LSR "); - m6502.flags.C = *dst & 1; + m6502.C = *dst & 1; set_flags_NZ( *dst >>= 1 ); } -static inline void LSRA() { +INLINE void LSRA() { dbgPrintf("LSR "); - m6502.flags.C = m6502.A & 1; + m6502.C = m6502.A & 1; set_flags_NZ( m6502.A >>= 1 ); } @@ -76,17 +74,17 @@ static inline void LSRA() { absolute ROL oper 2E 3 6 absolute,X ROL oper,X 3E 3 7 **/ -static inline void ROL( uint8_t * dst ) { +INLINE void ROL( uint8_t * dst ) { dbgPrintf("ROL "); - uint8_t C = m6502.flags.C; - m6502.flags.C = *dst >> 7; + uint8_t C = m6502.C; + m6502.C = *dst >> 7; *dst <<= 1; set_flags_NZ( *dst |= C ); } -static inline void ROLA() { +INLINE void ROLA() { dbgPrintf("ROL "); - uint8_t C = m6502.flags.C; - m6502.flags.C = m6502.A >> 7; + uint8_t C = m6502.C; + m6502.C = m6502.A >> 7; m6502.A <<= 1; set_flags_NZ( m6502.A |= C ); } @@ -105,17 +103,17 @@ static inline void ROLA() { absolute ROR oper 6E 3 6 absolute,X ROR oper,X 7E 3 7 **/ -static inline void ROR( uint8_t * dst ) { +INLINE void ROR( uint8_t * dst ) { dbgPrintf("ROR "); - uint8_t C = m6502.flags.C << 7; - m6502.flags.C = *dst & 1; + uint8_t C = m6502.C << 7; + m6502.C = *dst & 1; *dst >>= 1; set_flags_NZ( *dst |= C ); } -static inline void RORA() { +INLINE void RORA() { dbgPrintf("ROR "); - uint8_t C = m6502.flags.C << 7; - m6502.flags.C = m6502.A & 1; + uint8_t C = m6502.C << 7; + m6502.C = m6502.A & 1; m6502.A >>= 1; set_flags_NZ( m6502.A |= C ); } diff --git a/A2Mac/instructions/6502_instr_stack.h b/A2Mac/instructions/6502_instr_stack.h index 266212d..47e3f21 100644 --- a/A2Mac/instructions/6502_instr_stack.h +++ b/A2Mac/instructions/6502_instr_stack.h @@ -12,20 +12,20 @@ static const uint16_t stack_base_addr = 0x100; -static inline void PUSH( uint8_t imm ) { - RAM[ stack_base_addr + m6502.sp-- ] = imm; +INLINE void PUSH( uint8_t src ) { + RAM[ stack_base_addr | m6502.SP-- ] = src; } -static inline uint8_t POP() { - return RAM[ ++m6502.sp + stack_base_addr ]; +INLINE uint8_t POP() { + return RAM[ stack_base_addr | ++m6502.SP ]; } -static inline void PUSH_addr( uint16_t addr ) { +INLINE void PUSH_addr( uint16_t addr ) { PUSH( (uint8_t)(addr >> 8) ); PUSH( (uint8_t)addr ); } -static inline uint16_t POP_addr() { +INLINE uint16_t POP_addr() { return POP() + ( POP() << 8 ); } @@ -40,8 +40,8 @@ static inline uint16_t POP_addr() { -------------------------------------------- implied PHA 48 1 3 **/ -static inline void PHA() { - dbgPrintf("PHA "); +INLINE void PHA() { + dbgPrintf("PHA %02X ", m6502.A); PUSH( m6502.A ); } @@ -55,10 +55,10 @@ static inline void PHA() { -------------------------------------------- implied PLA 68 1 4 **/ -static inline void PLA() { - dbgPrintf("PLA "); +INLINE void PLA() { m6502.A = POP(); - set_flags_NZ(m6502.A); + dbgPrintf("PLA %02X ", m6502.A); + set_flags_NZ( m6502.A ); } /** @@ -71,9 +71,9 @@ static inline void PLA() { -------------------------------------------- implied PHP 08 1 3 **/ -static inline void PHP() { - dbgPrintf("PHP "); - PUSH( m6502.sr ); +INLINE void PHP() { + dbgPrintf("PHP %02X ", m6502.SR); + PUSH( m6502.SR ); // res and B flag should be set } /** @@ -86,9 +86,9 @@ static inline void PHP() { -------------------------------------------- implied PLP 28 1 4 **/ -static inline void PLP() { - dbgPrintf("PLP "); - m6502.sr = POP(); +INLINE void PLP() { + m6502.SR = POP() | 0x30; // res and B flag should be set + dbgPrintf("PLP %02X ", m6502.SR); } #endif // __6502_INSTR_STACK_H__ diff --git a/A2Mac/instructions/6502_instr_transfer.h b/A2Mac/instructions/6502_instr_transfer.h index 93a538c..2ccdf4c 100644 --- a/A2Mac/instructions/6502_instr_transfer.h +++ b/A2Mac/instructions/6502_instr_transfer.h @@ -20,8 +20,8 @@ -------------------------------------------- implied TAX AA 1 2 **/ -static inline void TAX() { - dbgPrintf("TAX "); +INLINE void TAX() { + dbgPrintf("TAX(%02X) ", m6502.A); set_flags_NZ(m6502.X = m6502.A); } @@ -35,8 +35,8 @@ static inline void TAX() { -------------------------------------------- implied TXA 8A 1 2 **/ -static inline void TXA() { - dbgPrintf("TXA "); +INLINE void TXA() { + dbgPrintf("TXA(%02X) ", m6502.X); set_flags_NZ(m6502.A = m6502.X); } @@ -51,7 +51,7 @@ static inline void TXA() { -------------------------------------------- implied TAY A8 1 2 **/ -static inline void TAY() { +INLINE void TAY() { dbgPrintf("TAY "); set_flags_NZ(m6502.Y = m6502.A); } @@ -66,8 +66,8 @@ static inline void TAY() { -------------------------------------------- implied TYA 98 1 2 **/ -static inline void TYA() { - dbgPrintf("TYA "); +INLINE void TYA() { + dbgPrintf("TYA(%02X) ", m6502.Y); set_flags_NZ(m6502.A = m6502.Y); } @@ -81,9 +81,9 @@ static inline void TYA() { -------------------------------------------- implied TSX BA 1 2 **/ -static inline void TSX() { - dbgPrintf("TSX "); - set_flags_NZ(m6502.X = m6502.sp); +INLINE void TSX() { + dbgPrintf("TSX(%02X) ", m6502.SP); + set_flags_NZ(m6502.X = m6502.SP); } /** @@ -96,9 +96,9 @@ static inline void TSX() { -------------------------------------------- implied TXS 9A 1 2 **/ -static inline void TXS() { - dbgPrintf("TXS "); - m6502.sp = m6502.X; +INLINE void TXS() { + dbgPrintf("TXS(%02X) ", m6502.X); + m6502.SP = m6502.X; } #endif // __6502_INSTR_TRANSFER_H__