- Unified inline

- "breakpoints" for debugging
- BugFixes
This commit is contained in:
Tamas Rudnai 2019-09-15 04:02:22 -07:00
parent f2e5b49a6e
commit 26c413df6b
21 changed files with 600 additions and 392 deletions

View File

@ -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 = "<group>"; };
3264261023284F6F008B615F /* Apple2_mmio_8bit_ioaddr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Apple2_mmio_8bit_ioaddr.h; sourceTree = "<group>"; };
326426112328ADF4008B615F /* Apple_II_ROM.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = Apple_II_ROM.s; sourceTree = "<group>"; };
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 = "<group>"; };
32BFFB5C22EACC630003B53F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
@ -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 = "<group>"; };
32BFFB7A22EACC660003B53F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
32C45305232E3EEF0000EBA1 /* RepeatingTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatingTimer.swift; sourceTree = "<group>"; };
32EDB7A123272CA80073AF2D /* fail1.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = fail1.txt; sourceTree = "<group>"; };
/* 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;
};

View File

@ -6,20 +6,35 @@
// Copyright © 2019 GameAlloy. All rights reserved.
//
#define CLK_WAIT
#define NO_SPEED_TEST
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#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[]) {

View File

@ -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;

View File

@ -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() ];
}

View File

@ -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;
}

View File

@ -714,7 +714,7 @@
<constraint firstAttribute="width" constant="700" id="YGY-gy-pSn"/>
<constraint firstAttribute="height" constant="420" id="dWL-EL-ab7"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" enabled="NO" allowsUndo="NO" sendsActionOnEndEditing="YES" state="on" borderStyle="border" alignment="center" placeholderString="Apple ][ Emulator Virtual Monitor" drawsBackground="YES" id="5AO-Gd-Lzo">
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" enabled="NO" allowsUndo="NO" sendsActionOnEndEditing="YES" state="on" borderStyle="border" alignment="justified" placeholderString="Apple ][ Emulator Virtual Monitor" drawsBackground="YES" id="5AO-Gd-Lzo">
<font key="font" size="14" name="Courier-Bold"/>
<color key="textColor" name="systemGreenColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" red="0.12549019607843137" green="0.17933968321917809" blue="0.12549019607843137" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>

View File

@ -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()
}
}

View File

@ -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<UInt8>, 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? {

View File

@ -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);
//}

View File

@ -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__

View File

@ -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 {

View File

@ -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() );
}

View File

@ -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__

View File

@ -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);

View File

@ -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);
}

View File

@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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 );
}

View File

@ -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__

View File

@ -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__