diff --git a/A2Mac.xcodeproj/project.pbxproj b/A2Mac.xcodeproj/project.pbxproj
index 8dcdff1..d6784b1 100644
--- a/A2Mac.xcodeproj/project.pbxproj
+++ b/A2Mac.xcodeproj/project.pbxproj
@@ -501,8 +501,11 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
+ OTHER_CFLAGS = "-DFUNCTIONTEST";
+ OTHER_SWIFT_FLAGS = "-DFUNCTIONTEST";
PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = "A2Mac/A2Mac-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -525,6 +528,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
+ OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.gamealloy.A2Mac;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "A2Mac/A2Mac-Bridging-Header.h";
diff --git a/A2Mac/6502.c b/A2Mac/6502.c
index df27a98..95ac9d6 100644
--- a/A2Mac/6502.c
+++ b/A2Mac/6502.c
@@ -43,21 +43,10 @@
/////
unsigned long long int clktime = 0;
-m6502_t m6502 = {0};
+m6502_t m6502 = { 0, 0, 0, 0, 0, 0, 0, HLT };
-INLINE int m6502_step() {
-
-// switch ( fetch16() ) {
-// case 0xFCD0: // D0 FC BNE
-// BNE( 0xFC ); return 2;
-//
-// case 0x01E9: // E9 01 SBC
-// SBC( 0x01 ) ; return 6;
-//
-// default:
-// m6502.pc -= 2;
-//
+INLINE int m6502_Step() {
#ifdef DEBUG
switch ( m6502.PC ) {
@@ -65,13 +54,180 @@ INLINE int m6502_step() {
dbgPrintf("START...\n");
break;
- case 0x9D1:
- dbgPrintf("BREAK POINT...\n");
+ case 0x0438:
+ dbgPrintf2("*** TEST 1 (%04X)\n", m6502.PC);
break;
-
- case 0x35BD:
- if ( ( m6502.A == 0x35 ) && ( m6502.C ) )
- dbgPrintf("BREAK POINT...\n");
+
+ case 0x0581:
+ dbgPrintf2("*** TEST 2 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x05C8:
+ dbgPrintf2("*** TEST 3 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x05FC:
+ dbgPrintf2("*** TEST 4 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0776:
+ dbgPrintf2("*** TEST 5 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0872:
+ dbgPrintf2("*** TEST 6 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x08A6:
+ dbgPrintf2("*** TEST 7 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x08F0:
+ dbgPrintf2("*** TEST 8 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0946:
+ dbgPrintf2("*** TEST 9 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0982:
+ dbgPrintf2("*** TEST 10 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x09B9:
+ dbgPrintf2("*** TEST 11 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0A11:
+ dbgPrintf2("*** TEST 12 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0AB7:
+ dbgPrintf2("*** TEST 13 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0D7D:
+ dbgPrintf2("*** TEST 14 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0E46:
+ dbgPrintf2("*** TEST 15 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0F01:
+ dbgPrintf2("*** TEST 16 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0F43:
+ dbgPrintf2("*** TEST 17 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x0FFA:
+ dbgPrintf2("*** TEST 18 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x103A:
+ dbgPrintf2("*** TEST 19 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x1330:
+ dbgPrintf2("*** TEST 20 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x162A:
+ dbgPrintf2("*** TEST 21 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x16DB:
+ dbgPrintf2("*** TEST 22 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x17FA:
+ dbgPrintf2("*** TEST 23 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x1899:
+ dbgPrintf2("*** TEST 24 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x1B63:
+ dbgPrintf2("*** TEST 25 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x1CB7:
+ dbgPrintf2("*** TEST 26 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x1DC5:
+ dbgPrintf("*** TEST 27 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x1ED3:
+ dbgPrintf2("*** TEST 28 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x22B7:
+ dbgPrintf2("*** TEST 29 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x23FB:
+ dbgPrintf2("*** TEST 30 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x257B:
+ dbgPrintf2("*** TEST 31 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x271F:
+ dbgPrintf2("*** TEST 32 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x289F:
+ dbgPrintf2("*** TEST 33 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x2A43:
+ dbgPrintf2("*** TEST 34 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x2AED:
+ dbgPrintf2("*** TEST 35 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x2BA7:
+ dbgPrintf2("*** TEST 36 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x2C55:
+ dbgPrintf2("*** TEST 37 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x2D13:
+ dbgPrintf2("*** TEST 38 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x3103:
+ dbgPrintf2("*** TEST 40 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x32FC:
+ dbgPrintf2("*** TEST 41 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x3361:
+ dbgPrintf2("*** TEST 42 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x3405:
+ dbgPrintf2("*** TEST 43 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x345D:
+ dbgPrintf2("*** TEST 44 (%04X)\n", m6502.PC);
+ break;
+
+ case 0x3469:
+ dbgPrintf2("*** TEST PASSED (%04X)\n", m6502.PC);
break;
default:
@@ -346,41 +502,56 @@ INLINE int m6502_step() {
}
const unsigned long long int iterations = G;
+unsigned long long int inst_cnt = 0;
+
+const unsigned int fps = 30;
+const unsigned int MHz_6502 = 1.023 * M;
+const unsigned int clk_6502_per_frm = MHz_6502 / fps;
unsigned long long tick_per_sec = G;
unsigned long long tick_6502_per_sec = 0;
-unsigned long long MHz_6502 = 1.023 * M;
-static __attribute__((always_inline)) unsigned long long rdtsc(void)
+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;
+unsigned long long ee = 0;
+unsigned long long dd = 0;
-INLINE void m6502_run() {
+// nanosec does not work very well for some reason
+struct timespec tim = { 0, 400L };
+
+double mips = 0;
+double mhz = 0;
+unsigned long long epoch = 0;
+
+void m6502_Run() {
+ unsigned int clk = 0;
+ unsigned int clkfrm = 0;
+
// init time
#ifdef CLK_WAIT
- unsigned long long s = rdtsc();
- unsigned long long e = (unsigned long long)-1LL;
+ unsigned long long elpased = (unsigned long long)-1LL;
#endif
#ifdef SPEED_TEST
for ( unsigned long long int i = 0; i < iterations ; i++ )
+#elif defined( CLK_WAIT )
+ for ( clkfrm = 0; clkfrm < clk_6502_per_frm ; clkfrm += clk )
#else
// for ( ; m6502.pc ; )
-
- tim.tv_sec = 0;
- tim.tv_nsec = 500L;
-
for ( ; ; )
#endif
{
if ( m6502.IF ) {
switch (m6502.interrupt) {
+ case HLT:
+ // CPU is haletd, nothing to do here...
+ return;
+
case NMI:
break;
@@ -397,55 +568,84 @@ INLINE void m6502_run() {
m6502.IF = 0;
}
-
- dbgPrintf("%llu %04X: ", clktime, m6502.PC);
- clktime += m6502_step();
+ dbgPrintf("%llu %04X: ", clktime, m6502.PC);
+ clktime += clk = m6502_Step();
+
+ dbgPrintf("\nA:%02X X:%02X Y:%02X SP:%02X %c%c%c%c%c%c%c%c\n",
+ m6502.A,
+ m6502.X,
+ m6502.Y,
+ m6502.SP,
+ m6502.N ? 'N' : 'n',
+ m6502.V ? 'V' : 'v',
+ m6502.res ? 'R' : 'r',
+ m6502.B ? 'B' : 'b',
+ m6502.D ? 'D' : 'd',
+ m6502.I ? 'I' : 'i',
+ m6502.Z ? 'Z' : 'z',
+ m6502.C ? 'C' : 'c'
+ );
+
#ifdef CLK_WAIT
- e = tick_6502_per_sec * clktime;
+// ee += tick_6502_per_sec * clk;
+// ee /= 2;
+// dd += rdtsc() - epoch - elpased;
+// dd /= 2;
+
+ // get the new time in ticks needed to simulate exact 6502 clock
+ elpased = tick_6502_per_sec * clktime;
+
// query time + wait
// TODO: We should use nanosleep
- usleep(1); // this is good enough for debugging
+// usleep(1); // this is good enough for debugging
-// nanosleep(&tim, &tim2);
+// nanosleep(&tim, NULL);
+
+// printf(" tps:%llu s:%llu t:%llu d:%llu e:%llu n:%llu\n", tick_6502_per_sec, s, t, t - s, e, e - (t - s));
// tight loop gives us the most precise wait time
-// while ( rdtsc() - s < e ) {}
+// while ( rdtsc() - epoch < elpased ) {}
#endif
- dbgPrintf("\n");
}
+
+ // clock_t end = clock();
+ // double execution_time = ((double) (end - start)) / CLOCKS_PER_SEC;
+// unsigned long long e = rdtsc();
+// unsigned long long t = e - epoch;
+// double execution_time = (double)t / tick_per_sec;
+//
+// mips = inst_cnt / (execution_time * M);
+// mhz = clktime / (execution_time * M);
}
-void init() {
- unsigned long long s = rdtsc();
+void m6502_Reset() {
+ inst_cnt = 0;
+ mhz = (double)MHz_6502 / M;
+
+ epoch = rdtsc();
sleep(1);
unsigned long long e = rdtsc();
- tick_per_sec = e - s;
+ tick_per_sec = e - epoch;
tick_6502_per_sec = tick_per_sec / MHz_6502;
memset( RAM, 0, sizeof(RAM) );
-
-
-// RAM[ 0 ] = 0x4C;
-// RAM[ 1 ] = 0;
-// RAM[ 2 ] = 0;
-//
-// RAM[ 0xBFFD ] = 0x4C;
-// RAM[ 0xBFFE ] = 0;
-// RAM[ 0xBFFF ] = 0;
m6502.A = m6502.X = m6502.Y = 0xFF;
// reset vector
m6502.SP = 0xFF -3;
- m6502.SR = 0x30;
+
+ // N V - B D I Z C
+ // 0 0 1 1 0 1 0 0
+ m6502.SR = 0x34;
+
+ m6502.IF = 0;
// 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) {
@@ -582,20 +782,22 @@ void tst6502() {
// insert code here...
printf("6502\n");
- init();
+ m6502_Reset();
// clock_t start = clock();
- unsigned long long s = rdtsc();
- m6502_run();
+ epoch = rdtsc();
+ m6502_Run();
// clock_t end = clock();
// double execution_time = ((double) (end - start)) / CLOCKS_PER_SEC;
unsigned long long e = rdtsc();
- unsigned long long t = e - s;
+ unsigned long long t = e - epoch;
double execution_time = (double)t / tick_per_sec;
- double mips = iterations / (execution_time * M);
+ double mips = inst_cnt / (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(" dd:%llu ee:%llu nn:%llu\n", dd, ee, ee - dd);
+
}
int ___main(int argc, const char * argv[]) {
diff --git a/A2Mac/6502.h b/A2Mac/6502.h
index a92ec2a..1f537be 100644
--- a/A2Mac/6502.h
+++ b/A2Mac/6502.h
@@ -12,12 +12,16 @@
#import "stdint.h"
#ifdef DEBUG
-#define dbgPrintf(format, ...) printf (format, ## __VA_ARGS__)
+#define dbgPrintf(format, ...)
+#define dbgPrintf2(format, ...) printf (format, ## __VA_ARGS__)
#else
#define dbgPrintf(format, ...)
+#define dbgPrintf2(format, ...)
#endif
typedef enum {
+ NO_INT,
+ HLT,
NMI,
HARDRESET,
SOFTRESET,
@@ -53,7 +57,7 @@ typedef struct m6502_s {
unsigned clk; // Clock Counter
union {
- int IF; // interrut flag
+ unsigned int IF; // interrut flag
interrupt_t interrupt;
};
} m6502_t;
@@ -62,7 +66,11 @@ typedef struct m6502_s {
extern m6502_t m6502;
extern uint8_t RAM[ 64 * 1024 ];
-extern void tst6502();
+extern double mips;
+extern double mhz;
+extern void tst6502();
+extern void m6502_Reset();
+extern void m6502_Run();
#endif /* __6502_H__ */
diff --git a/A2Mac/Base.lproj/Main.storyboard b/A2Mac/Base.lproj/Main.storyboard
index c4b8024..d9a6173 100644
--- a/A2Mac/Base.lproj/Main.storyboard
+++ b/A2Mac/Base.lproj/Main.storyboard
@@ -714,7 +714,7 @@
-
+
@@ -746,12 +746,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -762,6 +776,7 @@
+
diff --git a/A2Mac/ViewController.swift b/A2Mac/ViewController.swift
index 29b90af..46f3dd4 100644
--- a/A2Mac/ViewController.swift
+++ b/A2Mac/ViewController.swift
@@ -11,7 +11,8 @@ import Cocoa
class ViewController: NSViewController {
@IBOutlet weak var display: NSTextFieldCell!
-
+ @IBOutlet weak var speedometer: NSTextFieldCell!
+
// static let charConvStr : String =
// "@π°π±π²π³π΄π΅πΆπ·πΈπΉπΊπ»πΌπ½πΎπΏπ
π
π
π
π
π
π
π
π
π
[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?" +
// "@π
°π
±π
²π
³π
΄π
΅π
Άπ
·π
Έπ
Ήπ
Ίπ
»π
Όπ
½π
Ύπ
Ώππππππ
ππππ[\\]^_β¬οΈ!\"#$%&'()*+,-./0123456789:;<=>?" + // FL
@@ -33,20 +34,22 @@ class ViewController: NSViewController {
var workItem : DispatchWorkItem? = nil;
@IBAction func Power(_ sender: Any) {
- if ( workItem != nil ) {
- workItem!.cancel();
- workItem = nil;
- }
- else {
- workItem = DispatchWorkItem {
+// if ( workItem != nil ) {
+// workItem!.cancel();
+// workItem = nil;
+// }
+// else {
+// workItem = DispatchWorkItem {
// DispatchQueue.global(qos: .userInteractive).async {
-// DispatchQueue.global(qos: .userInitiated).async {
- DispatchQueue.global(qos: .background).async {
- tst6502()
- }
- }
- DispatchQueue.global().async(execute: workItem!);
- }
+//// DispatchQueue.global(qos: .userInitiated).async {
+//// DispatchQueue.global(qos: .background).async {
+// tst6502()
+// }
+// }
+// DispatchQueue.global().async(execute: workItem!);
+// }
+
+ m6502_Reset()
}
@IBAction func Reset(_ sender: Any) {
@@ -89,7 +92,7 @@ class ViewController: NSViewController {
default:
break
}
- print("keycode: \(code) --> \(A2code)")
+// print("keycode: \(code) --> \(A2code)")
let kbdPointer = UnsafeMutableRawBufferPointer(start: &RAM + 0xC000, count: 1)
kbdPointer[0] = A2code
@@ -137,37 +140,74 @@ class ViewController: NSViewController {
}
- func update() {
+ let textBaseAddr = 0x400
+ let textBufferSize = 0x400
+ let textLines = 24
+ let textCols = 40
+
+ var frameCnt = 0
+ let spaceChar : Character = " "
+ let blockChar : Character = "β"
+ var flashingSpace : Character = " "
+
+ let textBufferPointer = UnsafeRawBufferPointer(start: &RAM + 0x400, count: 0x400)
+ var txtArr = [Character](repeating: " ", count: 0x400)
+
+ var s = String()
+
+ func Update() {
-// while true {
-// usleep(33333) // 1/30 sec
+ m6502_Run()
+
+ frameCnt += 1
+ if ( frameCnt == 15 ) {
+ flashingSpace = blockChar
+ }
+ else if ( frameCnt >= 30 ) {
+ flashingSpace = spaceChar
+ frameCnt = 0
+ }
+
+ var txt : String = ""
- let textBaseAddr = 0x400
- let textLines = 24
- let textCols = 40
-
- var txt : String = ""
-
- for y in 0...textLines-1 {
- let textAddr = textBaseAddr + textLineOfs[y]
- let textBufferPointer = UnsafeRawBufferPointer(start: &RAM + textAddr, count: textCols)
-
- for (_, byte) in textBufferPointer.enumerated() {
- let idx = Int(byte);
- let chr = ViewController.charConvTbl[idx]
- // print("byte \(index): \(chr)")
- txt = txt + "\(chr)"
+ for y in 0...textLines-1 {
+// let textAddr = textBaseAddr + textLineOfs[y]
+ for x in 0...textCols-1 {
+ let byte = textBufferPointer[ textLineOfs[y] + x ]
+ let idx = Int(byte);
+ var chr = ViewController.charConvTbl[idx]
+ // is it a cursor? (slashing space)
+ if ( chr == blockChar ) {
+ chr = flashingSpace
}
-
- txt = txt + "\n"
+ // print("byte \(index): \(chr)")
+// txt = txt + "\(chr)"
+ txtArr[ y * (textCols+1) + x ] = chr
}
+
+// for (_, byte) in textBufferPointer.enumerated() {
+// let idx = Int(byte);
+// var chr = ViewController.charConvTbl[idx]
+// // is it a cursor? (slashing space)
+// if ( chr == blockChar ) {
+// chr = flashingSpace
+// }
+// // print("byte \(index): \(chr)")
+// txt = txt + "\(chr)"
+// }
- DispatchQueue.main.async {
- self.display.stringValue = txt;
- }
-// }
+// txt = txt + "\n"
+ txtArr[ y * (textCols+1) + textCols ] = "\n"
+ }
+// txtArr[ textLines * (textCols+1) + textCols ] = "\0"
+ txt = String(txtArr)
+
+ DispatchQueue.main.async {
+ self.display.stringValue = txt;
+ self.speedometer.stringValue = String(format: "%0.3lf MHz", mhz);
+ }
}
@@ -190,17 +230,17 @@ class ViewController: NSViewController {
// self.update()
// })
- #if FUNCTIONTEST
- #else
+// #if FUNCTIONTEST
+// #else
// DispatchQueue.global(qos: .background).async {
// self.update()
// }
upd.eventHandler = {
- self.update()
+ self.Update()
}
upd.resume()
- #endif
+// #endif
}
override var representedObject: Any? {
diff --git a/A2Mac/common.h b/A2Mac/common.h
index e1978c6..483c1d1 100644
--- a/A2Mac/common.h
+++ b/A2Mac/common.h
@@ -43,22 +43,18 @@ union {
INLINE void set_flags_N( const uint8_t test ) {
m6502.N = BITTEST(test, 7);
- dbgPrintf("%c", m6502.N ? 'N' : 'n');
}
INLINE void set_flags_V( const uint8_t test ) {
m6502.V = BITTEST(test, 6);
- dbgPrintf("%c", m6502.V ? 'V' : 'v');
}
INLINE void set_flags_Z( const uint8_t test ) {
m6502.Z = test == 0;
- dbgPrintf("%c", m6502.Z ? 'Z' : 'z');
}
INLINE void set_flags_C( const int16_t test ) {
m6502.C = test >= 0;
- dbgPrintf("%c", m6502.C ? 'C' : 'c');
}
INLINE void set_flags_NZ( const uint8_t test ) {
diff --git a/A2Mac/instructions/6502_instr_arithmetic.h b/A2Mac/instructions/6502_instr_arithmetic.h
index 1e79fb0..849fd77 100644
--- a/A2Mac/instructions/6502_instr_arithmetic.h
+++ b/A2Mac/instructions/6502_instr_arithmetic.h
@@ -30,14 +30,50 @@
(indirect),Y ADC (oper),Y 71 2 5*
**/
INLINE void ADC( uint8_t src ) {
- dbgPrintf("ADC(%02X) A:%02X + %02X ", src, m6502.A, src);
-
+ dbgPrintf("ADC(%02X) ", src);
+
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;
+
+ // V = C7 != C6
+ m6502.V = ((m6502.A & 0x7F) + (src & 0x7F) + m6502.C) > 0x7F;
+
+ if ( m6502.D ) {
+ if ( (tmp = (m6502.A & 0x0F) + (src & 0x0F) + m6502.C) > 0x09 ) {
+ tmp += 0x06;
+ }
+ if ( (tmp += (m6502.A & 0xF0) + (src & 0xF0)) > 0x99 ) {
+ tmp += 0x60;
+ }
+
+// tmp = m6502.A + src + m6502.C;
+//
+// if ( (tmp & 0x0F) > 0x09 ) {
+// tmp += 0x06;
+// }
+// if ( tmp > 0x99 ) {
+// tmp += 0x60;
+// }
+ }
+ else {
+ tmp = (uint16_t)m6502.A + src + m6502.C;
+ }
+
+ set_flags_NZ( m6502.A = tmp );
+ m6502.C = tmp > 0xFF;
+ m6502.V ^= m6502.C;
+
+// // this is good but slow:
+// uint16_t tmp = (uint16_t)m6502.A + src + m6502.C;
+// m6502.V = ( !((m6502.A ^ src) & 0x80)) && ( (m6502.A ^ tmp) & 0x80);
+// m6502.C = tmp > 0xFF;
+// set_flags_NZ( m6502.A = tmp );
+
+// // this is good but slow:
+// uint16_t tmp = (uint16_t)m6502.A + src + m6502.C;
+// m6502.V = ( ((m6502.A ^ src) ^ (m6502.A ^ tmp)) & 0x80 ) != 0;
+// m6502.C = tmp > 0xFF;
+// set_flags_NZ( m6502.A = tmp );
- dbgPrintf("-> A:%02X ", m6502.A);
}
/**
@@ -59,7 +95,32 @@ INLINE void ADC( uint8_t src ) {
**/
INLINE void SBC( uint8_t src ) {
dbgPrintf("SBC(%02X) ", src);
- ADC( ~src );
+// ADC( ~src );
+
+ uint16_t tmp;
+
+ if( m6502.D ) {
+ tmp = (m6502.A & 0x0F) - ( src & 0x0F ) - !m6502.C;
+ if( (tmp & 0x10) != 0) {
+ tmp = ( (tmp - 0x06 ) & 0x0F ) | ( (m6502.A & 0xF0) - (src & 0xF0) - 0x10 );
+ }
+ else {
+ tmp = (tmp & 0x0F) | ( (m6502.A & 0xF0) - (src & 0xF0) );
+ }
+
+ if(( tmp & 0x100 ) != 0) {
+ tmp -= 0x60;
+ }
+ }
+ else
+ {
+ tmp = m6502.A - src - !m6502.C;
+ }
+
+ m6502.C = tmp < 0x100;
+
+ m6502.V = ( (m6502.A ^ tmp) & 0x80 ) && ( (m6502.A ^ src) & 0x80 );
+ set_flags_NZ( m6502.A = tmp );
}
#endif // __6502_INSTR_ARITHMETIC_H__
diff --git a/A2Mac/instructions/6502_instr_branch.h b/A2Mac/instructions/6502_instr_branch.h
index 0b84efb..070b780 100644
--- a/A2Mac/instructions/6502_instr_branch.h
+++ b/A2Mac/instructions/6502_instr_branch.h
@@ -13,7 +13,7 @@ INLINE void BRA( int8_t reladdr ) {
m6502.PC += reladdr;
#ifdef DEBUG
if ( reladdr == -2 ) {
- dbgPrintf("Infinite Loop at %04X!\n", m6502.PC);
+ dbgPrintf2("Infinite Loop at %04X!\n", m6502.PC);
}
#endif
dbgPrintf("BRA %04X ", m6502.PC);
diff --git a/A2Mac/instructions/6502_instr_load_store.h b/A2Mac/instructions/6502_instr_load_store.h
index 653edbb..e384776 100644
--- a/A2Mac/instructions/6502_instr_load_store.h
+++ b/A2Mac/instructions/6502_instr_load_store.h
@@ -31,8 +31,7 @@
**/
INLINE void LDA( uint8_t src ) {
dbgPrintf("LDA(%02X) ", src);
- m6502.A = src;
- set_flags_NZ(src);
+ set_flags_NZ(m6502.A = src);
}
/**
@@ -51,8 +50,7 @@ INLINE void LDA( uint8_t src ) {
**/
INLINE void LDX( uint8_t src ) {
dbgPrintf("LDX(%02X) ", src);
- m6502.X = src;
- set_flags_NZ(src);
+ set_flags_NZ(m6502.X = src);
}
/**
@@ -71,8 +69,7 @@ INLINE void LDX( uint8_t src ) {
**/
INLINE void LDY( uint8_t src ) {
dbgPrintf("LDY(%02X) ", src);
- m6502.Y = src;
- set_flags_NZ(src);
+ set_flags_NZ(m6502.Y = src);
}
@@ -90,7 +87,7 @@ char * charConv =
(not a real instruction, only a helper function)
**/
INLINE void STR( uint8_t * dst, uint8_t src ) {
- dbgPrintf("STR %02X -> %04X ", src, (int)(dst - RAM));
+ dbgPrintf("STR [%04X], %02X ", (int)(dst - RAM), src );
*dst = src;
// uint16_t addr = dst - RAM;