From 80d6190fa1e2d051e3b2fddc1b83b65a22dfb73b Mon Sep 17 00:00:00 2001 From: Tamas Rudnai Date: Wed, 11 Sep 2019 18:36:30 -0700 Subject: [PATCH] - Address mode adjustments - Some fine tunings - Stack PUSH/POP address fix - DispatchWorkItem to be able to kill emulator thread --- A2Mac/6502.c | 4 +- A2Mac/Apple2_mmio.h | 84 ++++++++++---------- A2Mac/ViewController.swift | 14 +++- A2Mac/common.h | 19 +++-- A2Mac/instructions/6502_instr_arithmetic.h | 3 +- A2Mac/instructions/6502_instr_compare_test.h | 5 +- A2Mac/instructions/6502_instr_logic.h | 9 +-- A2Mac/instructions/6502_instr_shift_rotate.h | 6 -- A2Mac/instructions/6502_instr_stack.h | 12 +-- A2Mac/instructions/6502_instr_transfer.h | 15 ++-- 10 files changed, 86 insertions(+), 85 deletions(-) diff --git a/A2Mac/6502.c b/A2Mac/6502.c index cc3169f..2e469e8 100644 --- a/A2Mac/6502.c +++ b/A2Mac/6502.c @@ -330,9 +330,9 @@ static inline void m6502_run() { // unsigned long long s = rdtsc(); unsigned long long e = (unsigned long long)-1LL; - for ( unsigned long long int i = 0; i < iterations ; i++ ) { +// for ( unsigned long long int i = 0; i < iterations ; i++ ) { // for ( ; m6502.pc ; ) { -// for ( ; ; ) { + for ( ; ; ) { if ( m6502.interrupt_flag ) { switch (m6502.interrupt) { case NMI: diff --git a/A2Mac/Apple2_mmio.h b/A2Mac/Apple2_mmio.h index 62cabb4..862a015 100644 --- a/A2Mac/Apple2_mmio.h +++ b/A2Mac/Apple2_mmio.h @@ -204,45 +204,6 @@ static inline uint16_t fetch16() { return word; } -/** - get a 16 bit address from the zp:zp+1 - **/ -static inline uint16_t addr_zp_ind( uint8_t addr ) { - return memread16(addr); -} - -/** - X,ind .... X-indexed, indirect OPC ($LL,X) - 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() { - return addr_zp_ind( fetch() + m6502.X ); -} -static inline uint8_t src_X_ind() { - return memread( addr_X_ind() ); -} -static inline uint8_t * dest_X_ind() { - return & RAM[ addr_X_ind() ]; -} - -/** - ind,Y .... indirect, Y-indexed OPC ($LL),Y - 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() { -// 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( fetch() ) + m6502.Y; -} -static inline uint8_t src_ind_Y() { - return memread( addr_ind_Y() ); -} -static inline uint8_t * dest_ind_Y() { - return & RAM[ addr_ind_Y() ]; -} - /** abs .... absolute OPC $LLHH,X operand is address; effective address is address incremented by X with carry ** @@ -306,7 +267,7 @@ static inline uint16_t imm() { zpg .... zeropage OPC $LL operand is zeropage address (hi-byte is zero, address = $00LL) **/ -static inline uint16_t addr_zp() { +static inline uint8_t addr_zp() { return fetch(); } static inline uint8_t src_zp() { @@ -316,12 +277,51 @@ static 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 ) { + return memread16(addr); +} + +/** + X,ind .... X-indexed, indirect OPC ($LL,X) + 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() { + return addr_zp_ind( addr_zp() + m6502.X ); +} +static inline uint8_t src_X_ind() { + return memread( addr_X_ind() ); +} +static inline uint8_t * dest_X_ind() { + return & RAM[ addr_X_ind() ]; +} + +/** + ind,Y .... indirect, Y-indexed OPC ($LL),Y + 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() { + // 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() { + return memread( addr_ind_Y() ); +} +static inline uint8_t * dest_ind_Y() { + return & RAM[ addr_ind_Y() ]; +} + /** zpg,X .... zeropage, X-indexed OPC $LL,X operand is zeropage address; effective address is address incremented by X without carry ** **/ -static inline uint16_t addr_zp_X() { +static inline uint8_t addr_zp_X() { return addr_zp() + m6502.X; } static inline uint8_t src_zp_X() { @@ -336,7 +336,7 @@ static inline uint8_t * dest_zp_X() { operand is zeropage address; effective address is address incremented by Y without carry ** **/ -static inline uint16_t addr_zp_Y() { +static inline uint8_t addr_zp_Y() { return addr_zp() + m6502.Y; } static inline uint8_t src_zp_Y() { diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift index 61dbb3b..74032ac 100644 --- a/A2Mac/ViewController.swift +++ b/A2Mac/ViewController.swift @@ -31,9 +31,19 @@ class ViewController: NSViewController { 0x228, 0x2A8, 0x328, 0x3A8, 0x050, 0x0D0, 0x150, 0x1D0, 0x250, 0x2D0, 0x350, 0x3D0 ] + var workItem : DispatchWorkItem? = nil; @IBAction func Power(_ sender: Any) { - DispatchQueue.global(qos: .userInitiated).async { - tst6502() + if ( workItem != nil ) { + workItem!.cancel(); + workItem = nil; + } + else { + workItem = DispatchWorkItem { + DispatchQueue.global(qos: .userInitiated).async { + tst6502() + } + } + DispatchQueue.global().async(execute: workItem!); } } diff --git a/A2Mac/common.h b/A2Mac/common.h index ad887cb..436de28 100644 --- a/A2Mac/common.h +++ b/A2Mac/common.h @@ -41,37 +41,42 @@ union { #define BITTEST(n,x) ((bits_t)(n)).b##x -static inline void set_flags_N( uint8_t test ) { +static inline void set_flags_N( const uint8_t test ) { m6502.flags.N = BITTEST(test, 7); dbgPrintf("%c", m6502.flags.N ? 'N' : 'n'); } -static inline void set_flags_V( uint8_t test ) { +static inline void set_flags_V( const uint8_t test ) { m6502.flags.V = BITTEST(test, 6); dbgPrintf("%c", m6502.flags.V ? 'V' : 'v'); } -static inline void set_flags_Z( uint8_t test ) { +static inline void set_flags_Z( const uint8_t test ) { m6502.flags.Z = test == 0; dbgPrintf("%c", m6502.flags.Z ? 'Z' : 'z'); } -static inline void set_flags_C( int test ) { +static inline void set_flags_C( const int test ) { m6502.flags.C = test >= 0; dbgPrintf("%c", m6502.flags.C ? 'C' : 'c'); } -static inline void set_flags_NZ( uint8_t test ) { +static inline void set_flags_NZ( const uint8_t test ) { set_flags_N(test); set_flags_Z(test); } -static inline void set_flags_NVZ( uint8_t test ) { +static 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 ) { set_flags_NZ(test); set_flags_V(test); } -static inline void set_flags_NZC( int test ) { +static inline void set_flags_NZC( const int test ) { set_flags_NZ(test); set_flags_C(test); } diff --git a/A2Mac/instructions/6502_instr_arithmetic.h b/A2Mac/instructions/6502_instr_arithmetic.h index 5a9af8b..425edcf 100644 --- a/A2Mac/instructions/6502_instr_arithmetic.h +++ b/A2Mac/instructions/6502_instr_arithmetic.h @@ -31,8 +31,7 @@ **/ static inline void ADC( uint8_t imm ) { dbgPrintf("ADC(%02X) A:%02X + %02X ", imm, m6502.A, imm); - m6502.A += imm + m6502.flags.C; - set_flags_NZCV( m6502.A ); + set_flags_NZCV( m6502.A += imm + m6502.flags.C ); dbgPrintf("-> A:%02X ", m6502.A); } diff --git a/A2Mac/instructions/6502_instr_compare_test.h b/A2Mac/instructions/6502_instr_compare_test.h index 1a8b214..ff6fb05 100644 --- a/A2Mac/instructions/6502_instr_compare_test.h +++ b/A2Mac/instructions/6502_instr_compare_test.h @@ -26,9 +26,8 @@ **/ static inline void BIT( uint8_t imm ) { dbgPrintf("BIT(%02X) ", imm); - m6502.flags.N = BITTEST(imm, 7); - m6502.flags.V = BITTEST(imm, 6); - m6502.flags.Z = (imm & m6502.A) == 0; + set_flags_NV(imm); + set_flags_Z(m6502.A & imm); } /** diff --git a/A2Mac/instructions/6502_instr_logic.h b/A2Mac/instructions/6502_instr_logic.h index 0dc5f70..544608e 100644 --- a/A2Mac/instructions/6502_instr_logic.h +++ b/A2Mac/instructions/6502_instr_logic.h @@ -29,8 +29,7 @@ **/ static inline void ORA( uint8_t imm ) { dbgPrintf("ORA(%02X) ", imm); - m6502.A |= imm; - set_flags_NZ( m6502.A ); + set_flags_NZ( m6502.A |= imm ); } /** @@ -52,8 +51,7 @@ static inline void ORA( uint8_t imm ) { **/ static inline void AND( uint8_t imm ) { dbgPrintf("AND(%02X) ", imm); - m6502.A &= imm; - set_flags_NZ( m6502.A ); + set_flags_NZ( m6502.A &= imm ); } /** @@ -75,8 +73,7 @@ static inline void AND( uint8_t imm ) { **/ static inline void EOR( uint8_t imm ) { dbgPrintf("EOR(%02X) ", imm); - m6502.A ^= imm; - set_flags_NZ( m6502.A ); + set_flags_NZ( m6502.A ^= imm ); } #endif // __6502_INSTR_LOGIC_H__ diff --git a/A2Mac/instructions/6502_instr_shift_rotate.h b/A2Mac/instructions/6502_instr_shift_rotate.h index 2f07598..50fdd86 100644 --- a/A2Mac/instructions/6502_instr_shift_rotate.h +++ b/A2Mac/instructions/6502_instr_shift_rotate.h @@ -54,13 +54,11 @@ static inline void ASLA() { static inline void LSR( uint8_t * dst ) { dbgPrintf("LSR "); m6502.flags.C = *dst & 1; - ; set_flags_NZ( *dst >>= 1 ); } static inline void LSRA() { dbgPrintf("LSR "); m6502.flags.C = m6502.A & 1; - ; set_flags_NZ( m6502.A >>= 1 ); } @@ -83,7 +81,6 @@ static inline void ROL( uint8_t * dst ) { uint8_t C = m6502.flags.C; m6502.flags.C = *dst >> 7; *dst <<= 1; - ; set_flags_NZ( *dst |= C ); } static inline void ROLA() { @@ -91,7 +88,6 @@ static inline void ROLA() { uint8_t C = m6502.flags.C; m6502.flags.C = m6502.A >> 7; m6502.A <<= 1; - ; set_flags_NZ( m6502.A |= C ); } @@ -114,7 +110,6 @@ static inline void ROR( uint8_t * dst ) { uint8_t C = m6502.flags.C << 7; m6502.flags.C = *dst & 1; *dst >>= 1; - ; set_flags_NZ( *dst |= C ); } static inline void RORA() { @@ -122,7 +117,6 @@ static inline void RORA() { uint8_t C = m6502.flags.C << 7; m6502.flags.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 f5efa01..266212d 100644 --- a/A2Mac/instructions/6502_instr_stack.h +++ b/A2Mac/instructions/6502_instr_stack.h @@ -9,22 +9,24 @@ #ifndef __6502_INSTR_STACK_H__ #define __6502_INSTR_STACK_H__ +static const uint16_t stack_base_addr = 0x100; -static inline void PUSH( uint8_t n ) { - RAM[ 0x100 + m6502.sp-- ] = n; + +static inline void PUSH( uint8_t imm ) { + RAM[ stack_base_addr + m6502.sp-- ] = imm; } static inline uint8_t POP() { - return RAM[ 0x100 + (++m6502.sp) ]; + return RAM[ ++m6502.sp + stack_base_addr ]; } static inline void PUSH_addr( uint16_t addr ) { - PUSH( (uint8_t)addr ); PUSH( (uint8_t)(addr >> 8) ); + PUSH( (uint8_t)addr ); } static inline uint16_t POP_addr() { - return ( POP() << 8 ) + POP(); + return POP() + ( POP() << 8 ); } diff --git a/A2Mac/instructions/6502_instr_transfer.h b/A2Mac/instructions/6502_instr_transfer.h index e2a750c..93a538c 100644 --- a/A2Mac/instructions/6502_instr_transfer.h +++ b/A2Mac/instructions/6502_instr_transfer.h @@ -22,8 +22,7 @@ **/ static inline void TAX() { dbgPrintf("TAX "); - m6502.X = m6502.A; - set_flags_NZ(m6502.X); + set_flags_NZ(m6502.X = m6502.A); } /** @@ -38,8 +37,7 @@ static inline void TAX() { **/ static inline void TXA() { dbgPrintf("TXA "); - m6502.A = m6502.X; - set_flags_NZ(m6502.A); + set_flags_NZ(m6502.A = m6502.X); } @@ -55,8 +53,7 @@ static inline void TXA() { **/ static inline void TAY() { dbgPrintf("TAY "); - m6502.Y = m6502.A; - set_flags_NZ(m6502.Y); + set_flags_NZ(m6502.Y = m6502.A); } /** @@ -71,8 +68,7 @@ static inline void TAY() { **/ static inline void TYA() { dbgPrintf("TYA "); - m6502.A = m6502.Y; - set_flags_NZ(m6502.A); + set_flags_NZ(m6502.A = m6502.Y); } /** @@ -87,8 +83,7 @@ static inline void TYA() { **/ static inline void TSX() { dbgPrintf("TSX "); - m6502.X = m6502.sp; - set_flags_NZ(m6502.X); + set_flags_NZ(m6502.X = m6502.sp); } /**