mirror of https://github.com/trudnai/Steve2.git
- Unified inline
- "breakpoints" for debugging - BugFixes
This commit is contained in:
parent
f2e5b49a6e
commit
26c413df6b
|
@ -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;
|
||||
};
|
||||
|
|
204
A2Mac/6502.c
204
A2Mac/6502.c
|
@ -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[]) {
|
||||
|
|
39
A2Mac/6502.h
39
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;
|
||||
|
|
|
@ -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() ];
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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? {
|
||||
|
|
|
@ -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);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
Loading…
Reference in New Issue