summaryrefslogtreecommitdiff
path: root/sux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sux.c')
-rw-r--r--sux.c107
1 files changed, 64 insertions, 43 deletions
diff --git a/sux.c b/sux.c
index d26118d..9442cd4 100644
--- a/sux.c
+++ b/sux.c
@@ -69,6 +69,38 @@ inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) {
return 0;
}
+static inline uint8_t isrw(uint8_t opcode) {
+ switch (opcode) {
+ case STA_AB: /* STA Absolute. */
+ case STA_Z: /* STA Zero Matrix. */
+ case STA_ZX: /* STA Zero Matrix, Indexed with X. */
+ case STA_ZY: /* STA Zero Matrix, Indexed with Y. */
+ case STA_IN: /* STA Indirect. */
+ case STA_IX: /* STA Indexed Indirect. */
+ case STA_IY: /* STA Indirect Indexed. */
+ case STY_AB: /* STY Absolute. */
+ case STY_Z: /* STY Zero Matrix. */
+ case STY_IN: /* STY Indirect. */
+ case STX_AB: /* STX Absolute. */
+ case STX_Z: /* STX Zero Matrix. */
+ case STX_IN: /* STX Indirect. */
+ case STB_AB: /* STB Absolute. */
+ case STB_Z: /* STB Zero Matrix. */
+ case STB_ZX: /* STB Zero Matrix, Indexed with X. */
+ case STB_ZY: /* STB Zero Matrix, Indexed with Y. */
+ case STB_IN: /* STB Indirect. */
+ case STB_IX: /* STB Indexed Indirect. */
+ case STB_IY: /* STB Indirect Indexed. */
+ case INC_AB: /* INC Absolute. */
+ case INC_Z: /* INC Zero Matrix. */
+ case DEC_AB: /* DEC Absolute. */
+ case DEC_Z: /* DEC Zero Matrix. */
+ return 0; /* Writing. */
+ default:
+ return 1; /* Reading. */
+ }
+}
+
void *run(void *args) {
struct suxthr *thr = (void *)args;
struct sux *cpu = &thr->sx;
@@ -77,9 +109,7 @@ void *run(void *args) {
uint8_t opcode = 0;
union reg address;
union reg value;
- #if getclk
- uint64_t iclk = 0;
- #endif
+ cpu->clk = 0;
#if !IO
uint64_t ins = 0;
#endif
@@ -104,6 +134,14 @@ void *run(void *args) {
gettimeofday(&str[thread], 0);
#endif
for (;;) {
+ #if !bench
+ if (end) {
+ pthread_mutex_lock(&main_mutex);
+ pthread_cond_signal(&main_cond);
+ pthread_mutex_unlock(&main_mutex);
+ return NULL;
+ }
+ #endif
address.u64 = 0;
value.u64 = 0;
#if debug && !bench
@@ -137,46 +175,35 @@ void *run(void *args) {
}
cpu->pc += ((prefix & 0x03) == 0x03);
opcode = addr[cpu->pc];
- address.u64 = cpu->pc;
++cpu->pc;
+ address.u64 = cpu->pc;
#if getclk
- ++iclk;
+ ++cpu->clk;
#endif
- if (optype[opcode] != IMPL) {
- address.u64 = get_addr(cpu, &tmpaddr, opcode, prefix, thread);
-
- if (address.u64 > mem_size-1) {
- addr[STEP_ADDR] = 1;
- step = 1;
- }
- setreg_sw(value.u8, 0, addr, address.u64, prefix, 0, RS);
- if (optype[opcode] == REL) {
- switch ((prefix >> 4) & 3) {
- default: address.u64 = cpu->pc + (int8_t )value.u8[0] ; break;
- case 1 : address.u64 = cpu->pc + (int16_t)value.u16[0]; break;
- case 2 : address.u64 = cpu->pc + (int32_t)value.u32[0]; break;
- case 3 : address.u64 = cpu->pc + (int64_t)value.u64 ; break;
- }
- }
- #if getclk
- ++iclk;
- #endif
- }
+ uint8_t am = optype[opcode];
+ uint8_t rs = (prefix >> 4) & 3;
+ uint8_t size = (/***/1 << rs) - 1;
+ uint8_t check_io = (am != IMM);
#if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
- uint64_t operands[3];
- operands[0] = value.u64;
- operands[1] = address.u64;
- operands[2] = tmpaddr;
- disasm(cpu, operands, lines, opcode, prefix, thread);
+ disasm(cpu, lines, opcode, prefix, thread);
lines+=1;
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
#endif
- uint8_t size = (1 << ((prefix >> 4) & 3))-1;
+ if (am != IMPL && am != BREG) {
+ address.u64 = get_addr(cpu, opcode, prefix, 1, 1, thread);
+ if (address.u64 > mem_size-1) {
+ addr[STEP_ADDR] = 1;
+ step = 1;
+ }
+ if (isrw(opcode) && am != REL) {
+ value = read_value(cpu, address.u64, size, 1, check_io);
+ }
+ }
switch(opcode) {
case CPS_IMP: /* Clear Processor Status. */
cpu->ps.u64 = 0;
@@ -334,7 +361,7 @@ void *run(void *args) {
case LDB_IN: /* LDB Indirect. */
case LDB_IX: /* LDB Indexed Indirect. */
case LDB_IY: /* LDB Indirect Indexed. */
- cpu->b = load(cpu, address.u64, cpu->b, prefix, thread);
+ cpu->b = load(cpu, value.u64, thread);
break;
case LDA_IMM: /* LDA Immediate. */
case LDA_AB: /* LDA Absolute. */
@@ -344,19 +371,19 @@ void *run(void *args) {
case LDA_IN: /* LDA Indirect. */
case LDA_IX: /* LDA Indexed Indirect. */
case LDA_IY: /* LDA Indirect Indexed. */
- cpu->a = load(cpu, address.u64, cpu->a, prefix, thread);
+ cpu->a = load(cpu, value.u64, thread);
break;
case LDY_IMM: /* LDY Immediate. */
case LDY_AB: /* LDY Absolute. */
case LDY_Z: /* LDY Zero Matrix. */
case LDY_IN: /* LDY Indirect. */
- cpu->y = load(cpu, address.u64, cpu->y, prefix, thread);
+ cpu->y = load(cpu, value.u64, thread);
break;
case LDX_IMM: /* LDX Immediate. */
case LDX_AB: /* LDX Absolute. */
case LDX_Z: /* LDX Zero Matrix. */
case LDX_IN: /* LDX Indirect. */
- cpu->x = load(cpu, address.u64, cpu->x, prefix, thread);
+ cpu->x = load(cpu, value.u64, thread);
break;
case BEQ_REL: /* BEQ Relative. */
if (getflag(Z)) {
@@ -490,12 +517,6 @@ void *run(void *args) {
ins++;
#endif
#if !bench
- if (end) {
- pthread_mutex_lock(&main_mutex);
- pthread_cond_signal(&main_cond);
- pthread_mutex_unlock(&main_mutex);
- return NULL;
- }
if (step) {
int c = 0;;
for (; step && c != 19 && !end; c = get_key(scr));
@@ -511,7 +532,7 @@ void *run(void *args) {
wmove(scr, (6*thread)+1, 0);
wprintw(scr, "Instructions executed: %"PRIu64, ins);
#if getclk
- wprintw(scr, ", Clock cycles: %"PRIu64, iclk);
+ wprintw(scr, ", Clock cycles: %"PRIu64, cpu->clk);
#endif
if (step && !subdbg) {
wrefresh(scr);
@@ -525,7 +546,7 @@ void *run(void *args) {
threads_done++;
inst[thread] = ins;
#if getclk
- clk[thread] = iclk;
+ clk[thread] = cpu->clk;
#endif
pthread_cond_signal(&main_cond);
pthread_mutex_unlock(&main_mutex);