From d31aed21b27fbda68abe088d657ba18455607cc4 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Mon, 17 Aug 2020 20:37:44 -0400 Subject: - Fixed some bugs in the emulator's assembler. - Simplified the effective address functions. - Made SuBEditor a bit faster. - JSR, and RTS now support using the RS prefix, which is used to specify the return address size, with an RS prefix of 0 being a return address size of 64 bits, rather than 8 bits. --- sux.h | 129 +++++++++++++++++++++++++----------------------------------------- 1 file changed, 49 insertions(+), 80 deletions(-) (limited to 'sux.h') diff --git a/sux.h b/sux.h index 3f53a4d..6ed0fc0 100644 --- a/sux.h +++ b/sux.h @@ -49,7 +49,7 @@ extern int get_key(WINDOW *scr); extern void io(uint64_t address, uint8_t rw); extern void init_scr(); -static inline union reg read_value(struct sux *cpu, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { +static inline uint64_t read_value(struct sux *cpu, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { union reg value; value.u64 = 0; #if (IO || debug) && !branch @@ -74,11 +74,9 @@ static inline union reg read_value(struct sux *cpu, uint64_t address, uint8_t si case 0: value.u8[0] = addr[address+0]; } #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif - return value; + return value.u64; } static inline void write_value(struct sux *cpu, union reg value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { @@ -104,32 +102,28 @@ static inline void write_value(struct sux *cpu, union reg value, uint64_t addres #endif #endif #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif } -static inline uint64_t offset_addr(struct sux *cpu, union reg offset, uint8_t size, uint8_t inc_clk, uint8_t prefix) { +static inline uint64_t offset_addr(struct sux *cpu, uint64_t offset, uint8_t size, uint8_t inc_clk, uint8_t prefix) { uint64_t of; switch (prefix >> 6) { case 1: of = ((cpu->stk_st << 16) | cpu->sp); break; case 2: of = cpu->pc ; break; } #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif switch (size) { - case 0: return of + (int8_t )offset.u8 [0]; - case 1: return of + (int16_t)offset.u16[0]; + case 0: return of + (int8_t )offset; + case 1: return of + (int16_t)offset; case 2: - case 3: return of + (int32_t)offset.u32[0]; + case 3: return of + (int32_t)offset; case 4: case 5: case 6: - case 7: return of + (int64_t)offset.u64 ; + case 7: return of + (int64_t)offset; } } @@ -137,66 +131,49 @@ static inline uint64_t imm_addr(struct sux *cpu) { return cpu->pc; } -static inline uint64_t zm_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { - union reg address = read_value(cpu, cpu->pc, get_addrsize(prefix, ZM), inc_clk, 0); +static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { + uint64_t address; + uint8_t size = get_addrsize(prefix, type); if (prefix >> 6) { - address.u64 = offset_addr(cpu, address, get_addrsize(prefix, ZM), inc_clk, prefix); + address = offset_addr(cpu, read_value(cpu, cpu->pc, size, inc_clk, 0), size, inc_clk, prefix); + } else { + address = read_value(cpu, cpu->pc, size, inc_clk, 0); } if (inc_pc) { - cpu->pc += get_addrsize(prefix, ZM)+1; + cpu->pc += size+1; } - return address.u64; + return address; } static inline uint64_t zmx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif - return zm_addr(cpu, prefix, inc_clk, inc_pc) + cpu->x; + return read_addr(cpu, prefix, inc_clk, ZM, inc_pc) + cpu->x; } static inline uint64_t zmy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif - return zm_addr(cpu, prefix, inc_clk, inc_pc) + cpu->y; + return read_addr(cpu, prefix, inc_clk, ZM, inc_pc) + cpu->y; } -static inline uint64_t abs_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { - union reg address = read_value(cpu, cpu->pc, get_addrsize(prefix, ABS), inc_clk, 0); - if (prefix >> 6) { - address.u64 = offset_addr(cpu, address, get_addrsize(prefix, ABS), inc_clk, prefix); - } - if (inc_pc) { - cpu->pc += get_addrsize(prefix, ABS)+1; - } - return address.u64; -} static inline uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { - union reg address = read_value(cpu, zm_addr(cpu, prefix, inc_clk, inc_pc), 7, inc_clk, 0); - return address.u64; + return read_value(cpu, read_addr(cpu, prefix, inc_clk, ZM, inc_pc), 7, inc_clk, 0); } static inline uint64_t indx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { - union reg address = read_value(cpu, zm_addr(cpu, prefix, inc_clk, inc_pc)+cpu->x, 7, inc_clk, 0); #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif - return address.u64; + return read_value(cpu, read_addr(cpu, prefix, inc_clk, ZM, inc_pc)+cpu->x, 7, inc_clk, 0); } static inline uint64_t indy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif return ind_addr(cpu, prefix, inc_clk, inc_pc) + cpu->y; } @@ -204,39 +181,30 @@ static inline uint64_t indy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_cl static inline uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { uint8_t rs = (prefix >> 4) & 3; uint8_t size = (1 << rs) - 1; - union reg offset = read_value(cpu, cpu->pc, size, inc_clk, 0); + uint64_t offset = read_value(cpu, cpu->pc, size, inc_clk, 0); uint64_t address; if (inc_pc) { cpu->pc += (size + 1); } - switch (rs) { - default: address = cpu->pc + (int8_t )offset.u8 [0]; break; - case 1 : address = cpu->pc + (int16_t)offset.u16[0]; break; - case 2 : address = cpu->pc + (int32_t)offset.u32[0]; break; - case 3 : address = cpu->pc + (int64_t)offset.u64 ; break; - } #if getclk - if (inc_clk) { - ++cpu->clk; - } + cpu->clk += inc_clk; #endif - return address; + switch (rs) { + default: return cpu->pc + (int8_t )offset; + case 1 : return cpu->pc + (int16_t)offset; + case 2 : return cpu->pc + (int32_t)offset; + case 3 : return cpu->pc + (int64_t)offset; + } } static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { - union reg address; - union reg value; - uint8_t tmp = 0; - uint64_t tmp2 = 0; - union reg saveaddr; - address.u64 = 0; - value.u64 = 0; + uint64_t address = 0; switch (optype[opcode]) { case BREG: case IMPL: break; case IMM: - address.u64 = imm_addr(cpu); + address = imm_addr(cpu); switch (opcode) { case LSL_IMM: case LSR_IMM: @@ -255,17 +223,17 @@ static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, case TXS_IMM: break; } break; - case ZM : address.u64 = zm_addr(cpu, prefix, inc_clk, inc_pc); break; - case ZMX : address.u64 = zmx_addr(cpu, prefix, inc_clk, inc_pc); break; - case ZMY : address.u64 = zmy_addr(cpu, prefix, inc_clk, inc_pc); break; - case IND : address.u64 = ind_addr(cpu, prefix, inc_clk, inc_pc); break; - case INDX: address.u64 = indx_addr(cpu, prefix, inc_clk, inc_pc); break; - case INDY: address.u64 = indy_addr(cpu, prefix, inc_clk, inc_pc); break; - case ABS : address.u64 = abs_addr(cpu, prefix, inc_clk, inc_pc); break; - case REL : address.u64 = rel_addr(cpu, prefix, inc_clk, inc_pc); break; + case ZM : return read_addr(cpu, prefix, inc_clk, ZM, inc_pc); + case ABS : return read_addr(cpu, prefix, inc_clk, ABS, inc_pc); + case ZMX : return zmx_addr(cpu, prefix, inc_clk, /**/ inc_pc); + case ZMY : return zmy_addr(cpu, prefix, inc_clk, /**/ inc_pc); + case IND : return ind_addr(cpu, prefix, inc_clk, /**/ inc_pc); + case INDX: return indx_addr(cpu, prefix, inc_clk, /**/ inc_pc); + case INDY: return indy_addr(cpu, prefix, inc_clk, /**/ inc_pc); + case REL : return rel_addr(cpu, prefix, inc_clk, /**/ inc_pc); } - return address.u64; + return address; } static inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) { @@ -319,9 +287,9 @@ static inline void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t t static inline uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { uint64_t sbr = (cpu->stk_st << 16); - union reg reg = read_value(cpu, sbr+cpu->sp+1, size, 1, 0); + uint64_t value = read_value(cpu, sbr+cpu->sp+1, size, 1, 0); cpu->sp += size+1; - return reg.u64; + return value; } static inline void and(struct sux *cpu, uint64_t value, uint8_t thread) { @@ -425,7 +393,8 @@ static inline uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t t /* Increment, or Decrement memory. */ static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t inc, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; - union reg value = read_value(cpu, address, size, 1, 0); + union reg value; + value.u64 = read_value(cpu, address, size, 1, 0); if (inc) { value.u64++; } else { -- cgit v1.2.3-13-gbd6f