diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj index ba915e7..1c0691a 100644 --- a/A2Mac.xcodeproj/project.pbxproj +++ b/A2Mac.xcodeproj/project.pbxproj @@ -32,12 +32,15 @@ 32C453242331FED90000EBA1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB5E22EACC660003B53F /* Assets.xcassets */; }; 32C453252331FED90000EBA1 /* apple.rom in Resources */ = {isa = PBXBuildFile; fileRef = 32439F8422ECD8AD0077AAE0 /* apple.rom */; }; 32C453272331FED90000EBA1 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */; }; - 32C4532E233345430000EBA1 /* QuietView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* QuietView.swift */; }; - 32C4532F233345820000EBA1 /* QuietView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* QuietView.swift */; }; - 32C45330233345820000EBA1 /* QuietView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* QuietView.swift */; }; + 32C4532E233345430000EBA1 /* MonitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* MonitorView.swift */; }; + 32C4532F233345820000EBA1 /* MonitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* MonitorView.swift */; }; + 32C45330233345820000EBA1 /* MonitorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C4532D233345420000EBA1 /* MonitorView.swift */; }; 32C4533123335E560000EBA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; 32C4533223335E570000EBA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; 32C4533323335E570000EBA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32BFFB6022EACC660003B53F /* Main.storyboard */; }; + 32DBF7642334657900DD50E7 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; + 32DBF7652334657900DD50E7 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; + 32DBF7662334657900DD50E7 /* HiRes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DBF7632334657900DD50E7 /* HiRes.swift */; }; 32EDB7A223272CA80073AF2D /* fail1.txt in Resources */ = {isa = PBXBuildFile; fileRef = 32EDB7A123272CA80073AF2D /* fail1.txt */; }; /* End PBXBuildFile section */ @@ -101,7 +104,9 @@ 32C4531A2331F7220000EBA1 /* A2Mac copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "A2Mac copy-Info.plist"; path = "/Users/trudnai/Projects/A2Mac/A2Mac copy-Info.plist"; sourceTree = ""; }; 32C4532B2331FED90000EBA1 /* Functiontest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Functiontest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32C4532C2331FEDA0000EBA1 /* A2Mac copy2-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "A2Mac copy2-Info.plist"; path = "/Users/trudnai/Projects/A2Mac/A2Mac copy2-Info.plist"; sourceTree = ""; }; - 32C4532D233345420000EBA1 /* QuietView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuietView.swift; sourceTree = ""; }; + 32C4532D233345420000EBA1 /* MonitorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonitorView.swift; sourceTree = ""; }; + 32DBF7632334657900DD50E7 /* HiRes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HiRes.swift; sourceTree = ""; }; + 32DBF76723373FB400DD50E7 /* disassembler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = disassembler.h; sourceTree = ""; }; 32EDB7A123272CA80073AF2D /* fail1.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = fail1.txt; sourceTree = ""; }; /* End PBXFileReference section */ @@ -194,8 +199,9 @@ isa = PBXGroup; children = ( 32439F7522ECD8AD0077AAE0 /* instructions */, - 32439F7422ECD8AD0077AAE0 /* 6502.c */, 32439F8522ECD8AD0077AAE0 /* 6502.h */, + 32439F7422ECD8AD0077AAE0 /* 6502.c */, + 32DBF76723373FB400DD50E7 /* disassembler.h */, 32439F8422ECD8AD0077AAE0 /* apple.rom */, 326ED2EE232D7A0000A41337 /* 6502_functional_test.bin */, 32439F7322ECD8AD0077AAE0 /* Apple2_mmio.h */, @@ -203,7 +209,8 @@ 32439F8622ECD8AD0077AAE0 /* common.h */, 32BFFB5A22EACC630003B53F /* AppDelegate.swift */, 32BFFB5C22EACC630003B53F /* ViewController.swift */, - 32C4532D233345420000EBA1 /* QuietView.swift */, + 32C4532D233345420000EBA1 /* MonitorView.swift */, + 32DBF7632334657900DD50E7 /* HiRes.swift */, 32C453072331C0910000EBA1 /* NSLayoutManager-Extension.swift */, 32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */, 32EDB7A123272CA80073AF2D /* fail1.txt */, @@ -429,8 +436,9 @@ buildActionMask = 2147483647; files = ( 32439F8722ECD8AD0077AAE0 /* 6502.c in Sources */, + 32DBF7642334657900DD50E7 /* HiRes.swift in Sources */, 32BFFB5D22EACC630003B53F /* ViewController.swift in Sources */, - 32C4532E233345430000EBA1 /* QuietView.swift in Sources */, + 32C4532E233345430000EBA1 /* MonitorView.swift in Sources */, 32BFFB5B22EACC630003B53F /* AppDelegate.swift in Sources */, 32C45306232E3EEF0000EBA1 /* RepeatingTimer.swift in Sources */, ); @@ -457,8 +465,9 @@ buildActionMask = 2147483647; files = ( 32C4530B2331F7220000EBA1 /* 6502.c in Sources */, + 32DBF7652334657900DD50E7 /* HiRes.swift in Sources */, 32C4530C2331F7220000EBA1 /* ViewController.swift in Sources */, - 32C4532F233345820000EBA1 /* QuietView.swift in Sources */, + 32C4532F233345820000EBA1 /* MonitorView.swift in Sources */, 32C4530D2331F7220000EBA1 /* AppDelegate.swift in Sources */, 32C4530E2331F7220000EBA1 /* RepeatingTimer.swift in Sources */, ); @@ -469,8 +478,9 @@ buildActionMask = 2147483647; files = ( 32C4531D2331FED90000EBA1 /* 6502.c in Sources */, + 32DBF7662334657900DD50E7 /* HiRes.swift in Sources */, 32C4531E2331FED90000EBA1 /* ViewController.swift in Sources */, - 32C45330233345820000EBA1 /* QuietView.swift in Sources */, + 32C45330233345820000EBA1 /* MonitorView.swift in Sources */, 32C4531F2331FED90000EBA1 /* AppDelegate.swift in Sources */, 32C453202331FED90000EBA1 /* RepeatingTimer.swift in Sources */, ); diff --git a/A2Mac/6502.c b/A2Mac/6502.c index f9eedc2..1c085ed 100644 --- a/A2Mac/6502.c +++ b/A2Mac/6502.c @@ -20,7 +20,6 @@ #endif #include "common.h" -#include "Apple2_mmio.h" #define SOFTRESET_VECTOR 0x3F2 @@ -47,6 +46,13 @@ INLINE unsigned long long rdtsc(void) } +m6502_t m6502 = { 0, 0, 0, 0, 0, 0, 0, NO_DEBUG, HLT }; + +disassembly_t disassembly; + +#include "disassembler.h" +#include "Apple2_mmio.h" + /** Instruction Implementations @@ -56,12 +62,9 @@ INLINE unsigned long long rdtsc(void) **/ #include "6502_instructions.h" - ///// unsigned long long int clktime = 0; -m6502_t m6502 = { 0, 0, 0, 0, 0, 0, 0, HLT }; - INLINE int m6502_Step() { @@ -274,8 +277,11 @@ INLINE int m6502_Step() { break; } #endif + + disNewInstruction(); + switch ( fetch() ) { - case 0x00: BRK(); return 2; // BRK + case 0x00: BRK(); return 7; // BRK case 0x01: ORA( src_X_ind() ); return 6; // ORA X,ind // case 0x02: // t jams // case 0x03: // SLO* (undocumented) @@ -387,7 +393,7 @@ INLINE int m6502_Step() { case 0x6D: ADC( src_abs() ); return 4; // ADC abs case 0x6E: ROR( dest_abs() ); return 6; // ROR abs // case 0x6F: RRA abs 6 - case 0x70: BVS( rel_addr() ); break; // BVS rel + case 0x70: BVS( rel_addr() ); return 2; // BVS rel case 0x71: ADC( src_ind_Y() ); return 5; // ADC ind,Y // case 0x72: // case 0x73: @@ -523,7 +529,7 @@ INLINE int m6502_Step() { case 0xF5: SBC( src_zp_X() ); return 4; // SBC zpg,X case 0xF6: INC( dest_zp_X() ); return 6; // INC zpg,X // case 0xF7: - case 0xF8: SED(); break; // SED + case 0xF8: SED(); return 2; // SED case 0xF9: SBC( src_abs_Y() ); return 4; // SBC abs,Y // case 0xFA: // case 0xFB: @@ -538,7 +544,7 @@ INLINE int m6502_Step() { } // } // fetch16 - return 4; + return 2; } unsigned long long ee = 0; @@ -594,7 +600,8 @@ void m6502_Run() { dbgPrintf("%llu %04X: ", clktime, m6502.PC); clktime += clk = m6502_Step(); - + printDisassembly(); + dbgPrintf("\nA:%02X X:%02X Y:%02X SP:%02X %c%c%c%c%c%c%c%c\n", m6502.A, m6502.X, @@ -796,8 +803,7 @@ void m6502_Reset() { // memcpy( RAM + 0x1000, counter_fast, sizeof(counter)); - -// m6502.pc = 0x1000; +// m6502.PC = 0x1000; } diff --git a/A2Mac/6502.h b/A2Mac/6502.h index 11a7ec4..6eff18c 100644 --- a/A2Mac/6502.h +++ b/A2Mac/6502.h @@ -12,7 +12,8 @@ #import "stdint.h" #ifdef DEBUG -#define dbgPrintf(format, ...) printf (format, ## __VA_ARGS__) +//#define dbgPrintf(format, ...) printf (format, ## __VA_ARGS__) +#define dbgPrintf(format, ...) #define dbgPrintf2(format, ...) printf (format, ## __VA_ARGS__) #else #define dbgPrintf(format, ...) @@ -27,6 +28,13 @@ typedef enum { SOFTRESET, } interrupt_t; +typedef enum { + NO_DEBUG, + DISASSEMBLY, + DEBUGBRK, + STEPBYSTEP, +} debugLevel_t; + typedef struct m6502_s { uint8_t A; // Accumulator uint8_t X; // X index register @@ -55,6 +63,7 @@ typedef struct m6502_s { uint16_t PC; // Program Counter uint8_t SP; // Stack Pointer ( stack addr = 0x01 + sp ) unsigned clk; // Clock Counter + debugLevel_t dbgLevel; // 0: No Debug, 1: Disassembly Only, 2: Run till BRK, 3: StepByStep union { unsigned int IF; // interrut flag @@ -63,14 +72,26 @@ typedef struct m6502_s { } m6502_t; +typedef struct disassembly_s { + char codeAddr[5]; // 4 digits + \0 + char hex[4 * 3 + 1]; // max 4 bytes * (2 digits + 1 space) + \0 + char * pHex; + char inst[6 + 1]; // 3 char (unknown instr? -- give it 6 chars) + \0 + char addr[4 + 2 + 1 + 1 + 1]; // 4 digits + 2 brackets + 1 comma + 1 index + \0 + char comment[256]; // to be able to add some comments +} disassembly_t; + + extern m6502_t m6502; extern uint8_t RAM[ 64 * 1024 ]; extern double mips; extern double mhz; +extern const unsigned int fps; extern void tst6502(); extern void m6502_Reset(); extern void m6502_Run(); +extern void kbdInput ( uint8_t code ); #endif /* __6502_H__ */ diff --git a/A2Mac/Apple2_mmio.h b/A2Mac/Apple2_mmio.h index 075bb0f..1debd31 100644 --- a/A2Mac/Apple2_mmio.h +++ b/A2Mac/Apple2_mmio.h @@ -75,11 +75,12 @@ INLINE uint8_t ioRead( uint16_t addr ) { // printf("mmio read:%04X\n", addr); switch (addr) { case io_KBD: +// if ( RAM[io_KBD] > 0x7F ) printf("io_KBD:%04X\n", addr); return RAM[io_KBD]; - + case io_KBDSTRB: // TODO: This is very slow! - dbgPrintf("io_KBDSTRB\n"); +// printf("io_KBDSTRB\n"); return RAM[io_KBD] &= 0x7F; default: @@ -88,7 +89,33 @@ INLINE uint8_t ioRead( uint16_t addr ) { return 0; } -INLINE void ioWrite( uint16_t addr ) { + +void kbdInput ( uint8_t code ) { +// printf("kbdInput: %02X ('%c')\n", code, isprint(code) ? code : ' '); + switch ( code ) { +// case '\n': +// code = 0x0D; +// break; +// + case 0x7F: // BackSlash + code = 0x08; + break; + + default: + break; + } + + code |= 0x80; + + while ( RAM[io_KBD] > 0x7F ) { + usleep(10); + } + + RAM[io_KBD] = code; +} + + +INLINE void ioWrite( uint16_t addr, uint8_t val ) { // printf("mmio:%04X\n", addr); switch (addr) { case io_KBD: @@ -133,7 +160,7 @@ INLINE uint8_t memread( uint16_t addr ) { // } if ( (addr >= 0xC000) && (addr < 0xD000) ) { - ioRead(addr); + return ioRead(addr); } return RAM[ addr ]; @@ -195,7 +222,7 @@ static void memwrite( uint16_t addr, uint8_t byte ) { increase pc by one **/ INLINE uint8_t fetch() { - dbgPrintf("%02X ", RAM[m6502.PC]); + disHexB( disassembly.pHex, RAM[m6502.PC] ); return memread( m6502.PC++ ); } @@ -204,9 +231,9 @@ INLINE uint8_t fetch() { increase pc by one **/ INLINE uint16_t fetch16() { - dbgPrintf("%04X ", memread16(m6502.PC)); uint16_t word = memread16( m6502.PC ); m6502.PC += 2; + disHexW( disassembly.pHex, word ); return word; } @@ -216,6 +243,7 @@ INLINE uint16_t fetch16() { **/ INLINE uint16_t addr_abs() { dbgPrintf("abs:%04X(%02X) ", *((uint16_t*)&RAM[m6502.PC]), RAM[*((uint16_t*)&RAM[m6502.PC])]); + disPrintf(disassembly.addr, "$%04X", memread16(m6502.PC)) return fetch16(); } INLINE uint8_t src_abs() { @@ -227,12 +255,15 @@ INLINE uint8_t * dest_abs() { INLINE int8_t rel_addr() { + disPrintf(disassembly.addr, "$%04X", m6502.PC + 1 + (int)memread8(m6502.PC)) return fetch(); } INLINE uint16_t abs_addr() { + disPrintf(disassembly.addr, "$%04X", memread16(m6502.PC)) return fetch16(); } INLINE uint16_t ind_addr() { + disPrintf(disassembly.addr, "($%04X)", memread16(m6502.PC)) return memread16( fetch16() ); } @@ -242,6 +273,7 @@ INLINE uint16_t ind_addr() { **/ 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]); + disPrintf(disassembly.addr, "$%04X,X", memread16(m6502.PC)) return fetch16() + m6502.X; } INLINE uint8_t src_abs_X() { @@ -258,6 +290,7 @@ INLINE uint8_t * dest_abs_X() { **/ 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]); + disPrintf(disassembly.addr, "$%04X,Y", memread16(m6502.PC)) return abs_addr() + m6502.Y; } INLINE uint8_t src_abs_Y() { @@ -268,6 +301,7 @@ INLINE uint8_t * dest_abs_Y() { } INLINE uint16_t imm() { + disPrintf(disassembly.addr, "#$%02X", memread8(m6502.PC)) return fetch(); } @@ -278,6 +312,7 @@ INLINE uint16_t imm() { **/ INLINE uint8_t addr_zp() { dbgPrintf("zp:%02X(%02X) ", RAM[m6502.PC], RAM[ RAM[m6502.PC]] ); + disPrintf(disassembly.addr, "$%02X", memread8(m6502.PC)) return fetch(); } INLINE uint8_t src_zp() { @@ -292,6 +327,7 @@ INLINE uint8_t * dest_zp() { **/ 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])]); + disPrintf(disassembly.addr, "($%02X)", memread8(m6502.PC)) return memread16(addr); } @@ -302,7 +338,8 @@ INLINE uint16_t addr_zp_ind( uint8_t addr ) { **/ 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 ); + disPrintf(disassembly.addr, "($%02X,X)", memread8(m6502.PC)) + return addr_zp_ind( fetch() + m6502.X ); } INLINE uint8_t src_X_ind() { return memread8( addr_X_ind() ); @@ -319,7 +356,8 @@ INLINE uint8_t * dest_X_ind() { 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; + disPrintf(disassembly.addr, "($%02X),Y", memread8(m6502.PC)) + return addr_zp_ind( fetch() ) + m6502.Y; } INLINE uint8_t src_ind_Y() { return memread8( addr_ind_Y() ); @@ -340,7 +378,8 @@ INLINE uint8_t * dest_ind_Y() { effective address is address incremented by X without carry ** **/ INLINE uint8_t addr_zp_X() { - return addr_zp() + m6502.X; + disPrintf(disassembly.addr, "$%02X,X", memread8(m6502.PC)) + return fetch() + m6502.X; } INLINE uint8_t src_zp_X() { return memread_zp(addr_zp_X()); @@ -355,7 +394,8 @@ INLINE uint8_t * dest_zp_X() { effective address is address incremented by Y without carry ** **/ INLINE uint8_t addr_zp_Y() { - return addr_zp() + m6502.Y; + disPrintf(disassembly.addr, "$%02X,Y", memread8(m6502.PC)) + return fetch() + m6502.Y; } INLINE uint8_t src_zp_Y() { return memread_zp(addr_zp_Y()); diff --git a/A2Mac/Base.lproj/Main.storyboard b/A2Mac/Base.lproj/Main.storyboard index a3eefdb..f7d781d 100644 --- a/A2Mac/Base.lproj/Main.storyboard +++ b/A2Mac/Base.lproj/Main.storyboard @@ -2,6 +2,7 @@ + @@ -709,25 +710,25 @@ - - + + - - + + NSAllRomanInputSourcesLocaleIdentifier - + - + - 1234567890123456789012345678901234567890 + 1234567890123456789012345678901234567890 @@@@@@@@@1@@@@@@@@@2@@@@@@@@@3@@@@@@@@@4 @@@@@@@@@@@@@@@@@@@3@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@4@@@@@@@@@@@@@@@@@@@@ @@ -750,16 +751,16 @@ @@@@@@@@@@@@@@@@@@21@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@22@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@23@@@@@@@@@@@@@@@@@@@@ -@@@@@@@@@@@@@@@@@@24@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@24@@@@@@@@@@@@@@@@@@@@ - + NSAllRomanInputSourcesLocaleIdentifier