diff options
Diffstat (limited to 'sux.h')
-rw-r--r-- | sux.h | 68 |
1 files changed, 24 insertions, 44 deletions
@@ -49,9 +49,7 @@ extern int get_key(WINDOW *scr); extern void io(uint64_t address, uint8_t rw); extern void init_scr(); -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; +static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { #if (IO || debug) && !branch #if keypoll pthread_mutex_lock(&mutex); @@ -63,33 +61,18 @@ static inline uint64_t read_value(struct sux *cpu, uint64_t address, uint8_t siz pthread_mutex_unlock(&mutex); #endif #endif - switch (size) { - case 7: value.u8[7] = addr[address+7]; - case 6: value.u8[6] = addr[address+6]; - case 5: value.u8[5] = addr[address+5]; - case 4: value.u8[4] = addr[address+4]; - case 3: value.u8[3] = addr[address+3]; - case 2: value.u8[2] = addr[address+2]; - case 1: value.u8[1] = addr[address+1]; - case 0: value.u8[0] = addr[address+0]; - } + size = (size > 7) ? 7 : size; + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); #if getclk cpu->clk += inc_clk; #endif - return value.u64; + return (reg & ~mask) | (*(uint64_t *)(addr+address) & mask); } -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) { - switch (size) { - case 7: addr[address+7] = value.u8[7]; - case 6: addr[address+6] = value.u8[6]; - case 5: addr[address+5] = value.u8[5]; - case 4: addr[address+4] = value.u8[4]; - case 3: addr[address+3] = value.u8[3]; - case 2: addr[address+2] = value.u8[2]; - case 1: addr[address+1] = value.u8[1]; - case 0: addr[address+0] = value.u8[0]; - } +static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) { + size = (size > 7) ? 7 : size; + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask); #if (IO || debug) && !branch #if keypoll pthread_mutex_lock(&mutex); @@ -135,9 +118,9 @@ static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_cl uint64_t address; uint8_t size = get_addrsize(prefix, type); if (prefix >> 6) { - address = offset_addr(cpu, read_value(cpu, cpu->pc, size, inc_clk, 0), size, inc_clk, prefix); + address = offset_addr(cpu, read_value(cpu, 0, cpu->pc, size, inc_clk, 0), size, inc_clk, prefix); } else { - address = read_value(cpu, cpu->pc, size, inc_clk, 0); + address = read_value(cpu, 0, cpu->pc, size, inc_clk, 0); } if (inc_pc) { cpu->pc += size+1; @@ -161,14 +144,14 @@ static inline uint64_t zmy_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk static inline uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { - return read_value(cpu, read_addr(cpu, prefix, inc_clk, ZM, inc_pc), 7, inc_clk, 0); + return read_value(cpu, 0, 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) { #if getclk cpu->clk += inc_clk; #endif - return read_value(cpu, read_addr(cpu, prefix, inc_clk, ZM, inc_pc)+cpu->x, 7, inc_clk, 0); + return read_value(cpu, 0, 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) { @@ -181,7 +164,7 @@ 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; - uint64_t offset = read_value(cpu, cpu->pc, size, inc_clk, 0); + uint64_t offset = read_value(cpu, 0, cpu->pc, size, inc_clk, 0); uint64_t address; if (inc_pc) { cpu->pc += (size + 1); @@ -278,16 +261,14 @@ static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uin } static inline void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { - union reg reg; - reg.u64 = value; uint64_t sbr = (cpu->stk_st << 16); - write_value(cpu, reg, (sbr+cpu->sp)-size, size, 1, 0); + write_value(cpu, value, (sbr+cpu->sp)-size, size, 1, 0); cpu->sp -= size+1; } static inline uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { uint64_t sbr = (cpu->stk_st << 16); - uint64_t value = read_value(cpu, sbr+cpu->sp+1, size, 1, 0); + uint64_t value = read_value(cpu, 0, sbr+cpu->sp+1, size, 1, 0); cpu->sp += size+1; return value; } @@ -393,12 +374,12 @@ 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; - value.u64 = read_value(cpu, address, size, 1, 0); + uint64_t value; + value = read_value(cpu, 0, address, size, 1, 0); if (inc) { - value.u64++; + value++; } else { - value.u64--; + value--; } uint8_t sign = 0; switch ((prefix >> 4) & 3) { @@ -407,12 +388,13 @@ static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_ case 2: sign = 31; break; case 3: sign = 63; break; } - setflag(value.u64 == 0, Z); - setflag(value.u64 >> sign, N); + setflag(value == 0, Z); + setflag(value >> sign, N); write_value(cpu, value, address, size, 1, 1); } -static inline uint64_t load(struct sux *cpu, uint64_t value, uint8_t thread) { +static inline uint64_t load(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t thread) { + uint64_t value = read_value(cpu, reg, address, size, 1, 1); setflag(value == 0, Z); setflag(value >> 63, N); return value; @@ -420,7 +402,5 @@ static inline uint64_t load(struct sux *cpu, uint64_t value, uint8_t thread) { static inline void store(struct sux *cpu, uint64_t address, uint64_t reg, uint8_t prefix, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; - union reg value; - value.u64 = reg; - write_value(cpu, value, address, size, 1, 1); + write_value(cpu, reg, address, size, 1, 1); } |