diff options
Diffstat (limited to 'sux.c')
-rw-r--r-- | sux.c | 107 |
1 files changed, 64 insertions, 43 deletions
@@ -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); |