From a769f65a13db5546e427989d85f9646303f4fa32 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Tue, 8 Dec 2020 10:42:10 -0500 Subject: - Implemented support for the Orthogonal extension into both the assembler, and the emulator. I finally figured out how I could get support for the Ortho extension implemented into the old assembler. The only reason for doing this, is to buy me some while I start work on the new assembler, and to help me get an idea for how to do the same in the new assembler. --- sux.h | 904 ++++++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 692 insertions(+), 212 deletions(-) (limited to 'sux.h') diff --git a/sux.h b/sux.h index 9d7bcb3..6b8a7f6 100644 --- a/sux.h +++ b/sux.h @@ -37,6 +37,15 @@ extern uint8_t end; #define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= bit) : (cpu->ps.u8[thread] &= ~bit) #define getflag(bit) (cpu->ps.u8[thread] & bit) +#define ORTHO_1CC(mne, cc) \ + mne##_R##cc: case mne##_M##cc + +#define ORTHO_1OP(mne) \ + mne##_R: case mne##_M + +#define ORTHO_2OP(mne) \ + mne##_RR: case mne##_RM: case mne##_MR: case mne##_MM + extern pthread_mutex_t mutex; extern pthread_mutex_t main_mutex; extern pthread_cond_t cond; @@ -44,7 +53,7 @@ extern pthread_cond_t main_cond; #if debug extern void print_regs(struct sux *cpu, uint8_t lines, uint8_t thread); -extern void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t prefix2, uint8_t thread); +extern void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t prefix2, uint8_t *op_type, uint8_t *op_id, uint8_t thread); #endif /*#define KEYBUF_SIZE 0x40 @@ -55,7 +64,7 @@ extern void io(uint64_t address, uint8_t rw); extern void init_scr(); -static inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { +static /*inline*/ uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { uint8_t id = (prefix & 0x0C) >> 2; switch (addrmode) { case ZM: @@ -88,72 +97,194 @@ static inline uint8_t get_addrsize(uint8_t prefix, uint8_t addrmode) { return 0xFF; } -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. */ +static /*inline*/ uint8_t get_ortho_addrsize(uint8_t prefix, uint8_t addrmode) { + uint8_t type = IMM; + switch (addrmode) { + case MEM_ABS : + case MEM_ABSR : + case MEM_AIND : + case MEM_AINDR: + case MEM_ARIND: type = ABS; break; + case MEM_ZM : + case MEM_ZMR : + case MEM_IND : + case MEM_ZINDR: + case MEM_ZRIND: type = ZM; break; } + return get_addrsize(prefix, type); } -static inline uint8_t isread(uint8_t opcode) { - switch (opcode) { - case LDA_IMM: /* LDA Immediate. */ - case LDA_AB: /* LDA Absolute. */ - case LDA_Z: /* LDA Zero Matrix. */ - case LDA_ZX: /* LDA Zero Matrix, Indexed with X. */ - case LDA_ZY: /* LDA Zero Matrix, Indexed with Y. */ - case LDA_IN: /* LDA Indirect. */ - case LDA_IX: /* LDA Indexed Indirect. */ - case LDA_IY: /* LDA Indirect Indexed. */ - case LDB_IMM: /* LDB Immediate. */ - case LDB_AB: /* LDB Absolute. */ - case LDB_Z: /* LDB Zero Matrix. */ - case LDB_ZX: /* LDB Zero Matrix, Indexed with X. */ - case LDB_ZY: /* LDB Zero Matrix, Indexed with Y. */ - case LDB_IN: /* LDB Indirect. */ - case LDB_IX: /* LDB Indexed Indirect. */ - case LDB_IY: /* LDB Indirect Indexed. */ - case LDY_IMM: /* LDY Immediate. */ - case LDY_AB: /* LDY Absolute. */ - case LDY_Z: /* LDY Zero Matrix. */ - case LDY_IN: /* LDY Indirect. */ - case LDX_IMM: /* LDX Immediate. */ - case LDX_AB: /* LDX Absolute. */ - case LDX_Z: /* LDX Zero Matrix. */ - case LDX_IN: /* LDX Indirect. */ - case JMP_AB: /* JMP Absolute. */ - case JMP_Z: /* JMP Zero Matrix. */ - case JMP_IN: /* JMP Indirect. */ - case JSR_IN: /* JSR Indirect. */ - case JSR_AB: /* Jump to SubRoutine. */ - case JSR_Z: /* JSR Zero Matrix. */ - return 0; - default: - return 1; + +static /*inline*/ uint8_t isrw(uint8_t opcode, uint8_t ext_prefix) { + if ((ext_prefix & 0xD) == 0xD) { + switch (ext_prefix >> 4) { + case 0x0: + switch (opcode) { + case STA_E : + case STB_E : + case STX_E : + case STY_E : + case STE_AB: + case STE_Z : + case STS_AB: + case STS_Z : + case STS_E : + case STZ_AB: + case STZ_Z : + case STZ_E : + case SNG_E : + case SPO_E : + case SCC_E : + case SCS_E : + case SEQ_E : + case SNE_E : + case INC_E : + case DEC_E : + case NOT_AB: + case NOT_Z : + case NOT_E : + case SWP_AB: + case SWP_Z : + case SWP_E : + case LLM_AB: + case LLM_Z : + case LLM_E : + case LRM_AB: + case LRM_Z : + case LRM_E : + case RLM_AB: + case RLM_Z : + case RLM_E : + case RRM_AB: + case RRM_Z : + case RRM_E : + case ARM_AB: + case ARM_Z : + case ARM_E : return 0; + default : return 1; + } + } + } else { + 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. */ + } + } +} +static /*inline*/ uint8_t isread(uint8_t opcode, uint8_t ext_prefix) { + if ((ext_prefix & 0xD) == 0xD) { + switch (ext_prefix >> 4) { + case 0x0: + switch (opcode) { + case LEA_AB : + case LEA_AX : + case LEA_AY : + case LEA_AI : + case LEA_AIX: + case LEA_AIY: + case LEA_Z : + case LEA_ZX : + case LEA_ZY : + case LEA_IN : + case LEA_IX : + case LEA_IY : + case PEA_AB : + case PEA_AX : + case PEA_AY : + case PEA_AI : + case PEA_AIX: + case PEA_AIY: + case PEA_Z : + case PEA_ZX : + case PEA_ZY : + case PEA_IN : + case PEA_IX : + case PEA_IY : + case LDS_IMM: + case LDS_AB : + case LDS_Z : + case LDS_E : + case LNG_IMM: + case LNG_E : + case LPO_IMM: + case LPO_E : + case LCC_IMM: + case LCC_E : + case LCS_IMM: + case LCS_E : + case LEQ_IMM: + case LEQ_E : + case LNE_IMM: + case LNE_E : + case LDA_E : + case LDB_E : + case LDX_E : + case LDY_E : + case JMP_E : + case JSR_E : return 0; + default : return 1; + } + } + } else { + switch (opcode) { + case LDA_IMM: /* LDA Immediate. */ + case LDA_AB: /* LDA Absolute. */ + case LDA_Z: /* LDA Zero Matrix. */ + case LDA_ZX: /* LDA Zero Matrix, Indexed with X. */ + case LDA_ZY: /* LDA Zero Matrix, Indexed with Y. */ + case LDA_IN: /* LDA Indirect. */ + case LDA_IX: /* LDA Indexed Indirect. */ + case LDA_IY: /* LDA Indirect Indexed. */ + case LDB_IMM: /* LDB Immediate. */ + case LDB_AB: /* LDB Absolute. */ + case LDB_Z: /* LDB Zero Matrix. */ + case LDB_ZX: /* LDB Zero Matrix, Indexed with X. */ + case LDB_ZY: /* LDB Zero Matrix, Indexed with Y. */ + case LDB_IN: /* LDB Indirect. */ + case LDB_IX: /* LDB Indexed Indirect. */ + case LDB_IY: /* LDB Indirect Indexed. */ + case LDY_IMM: /* LDY Immediate. */ + case LDY_AB: /* LDY Absolute. */ + case LDY_Z: /* LDY Zero Matrix. */ + case LDY_IN: /* LDY Indirect. */ + case LDX_IMM: /* LDX Immediate. */ + case LDX_AB: /* LDX Absolute. */ + case LDX_Z: /* LDX Zero Matrix. */ + case LDX_IN: /* LDX Indirect. */ + case JMP_AB: /* JMP Absolute. */ + case JMP_Z: /* JMP Zero Matrix. */ + case JMP_IN: /* JMP Indirect. */ + case JSR_IN: /* JSR Indirect. */ + case JSR_AB: /* Jump to SubRoutine. */ + case JSR_Z: /* JSR Zero Matrix. */ + return 0; + default: + return 1; + } } } @@ -178,7 +309,7 @@ static void *memcopy(void *restrict dst, const void *restrict src, unsigned int } -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) { +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 getclk cpu->clk += inc_clk; #endif @@ -210,7 +341,7 @@ static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t addres } } -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) { +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) { if (address < mem_size) { size = (size > 7) ? 7 : size; #if 1 @@ -240,7 +371,7 @@ static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address #endif } -static inline uint64_t offset_addr(struct sux *cpu, uint64_t 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->sp; break; @@ -261,11 +392,11 @@ static inline uint64_t offset_addr(struct sux *cpu, uint64_t offset, uint8_t siz } } -static inline uint64_t imm_addr(struct sux *cpu) { +static /*inline*/ uint64_t imm_addr(struct sux *cpu) { return cpu->pc; } -static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { +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) { @@ -279,18 +410,18 @@ static inline uint64_t read_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_cl return address; } -static inline uint64_t idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg) { +static /*inline*/ uint64_t idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg) { #if getclk cpu->clk += inc_clk; #endif return read_addr(cpu, prefix, inc_clk, type, inc_pc) + idx_reg; } -static inline uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { +static /*inline*/ uint64_t ind_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc) { return read_value(cpu, 0, read_addr(cpu, prefix, inc_clk, type, inc_pc), 7, inc_clk, 0); } -static inline uint64_t ind_idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg, uint8_t pre_idx) { +static /*inline*/ uint64_t ind_idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t type, uint8_t inc_pc, uint64_t idx_reg, uint8_t pre_idx) { #if getclk cpu->clk += inc_clk; #endif @@ -301,7 +432,7 @@ static inline uint64_t ind_idx_addr(struct sux *cpu, uint8_t prefix, uint8_t inc } } -static inline uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk, uint8_t inc_pc) { +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, 0, cpu->pc, size, inc_clk, 0); @@ -320,10 +451,10 @@ static inline uint64_t rel_addr(struct sux *cpu, uint8_t prefix, uint8_t inc_clk } } -static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { +static /*inline*/ uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t ext_prefix, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { uint64_t address = 0; uint8_t type; - if ((ext_prefix & 0xD) == 0xD) { + if ((ext_prefix & 0xF) == 0xD) { switch (ext_prefix >> 4) { case 0x0: type = ext_optype[opcode]; break; } @@ -375,53 +506,131 @@ static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, return address; } +static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t prefix, uint64_t address, operand *op, uint64_t *value, uint8_t *op_type, uint8_t *op_id, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { + for (int i = 0; i < 2; i++) { + union reg tmp; + tmp.u64 = 0; + op[i].type = op_type[i]; + op[i].id = op_id[i]; + op[i].value = 0; + op[i].rind[0] = 0xFF; + op[i].rind[1] = 0xFF; + if (op[i].type) { + int inst_size = 0; + int addr_size = get_ortho_addrsize(prefix, op[i].id); + int rs = (1 << (prefix >> 4)); + int is_rind = (op[i].id != MEM_ABS && op[i].id != MEM_ZM && op[i].id != MEM_AIND && op[i].id != MEM_IND && op[i].id != MEM_IMM); + if (is_rind) { + inst_size = (op[i].id == MEM_SIB)+1; + tmp.u64 = read_value(cpu, 0, address, inst_size-1, 0, 0); + if (inc_pc) { + address += inst_size; + } + op[i].rind[0] = (tmp.u8[inst_size-1] & 0x0F); + op[i].rind[1] = (tmp.u8[inst_size-1] >> 4); + if (op[i].rind[1] == op[i].rind[0]) { + op[i].rind[1] = 0xFF; + } + op[i].scale = (inst_size == 2) ? tmp.u8[0] : 0; + } + if (addr_size != 0xFF || (rs && op[i].id == MEM_IMM)) { + inst_size = (addr_size != 0xFF) ? addr_size+1 : rs; + op[i].value = read_value(cpu, 0, address, inst_size-1, inc_clk, 0); + value[i] = op[i].value; + if (inc_pc) { + address += inst_size; + } + } + if (is_rind) { + for (int j = 0; j < 2 && op[i].rind[j] != 0xFF; j++) { + uint64_t reg; + switch (op[i].rind[j]) { + case REG_A : reg = cpu->a; break; + case REG_B : reg = cpu->b; break; + case REG_X : reg = cpu->x; break; + case REG_Y : reg = cpu->y; break; + case REG_E : reg = cpu->e; break; + case REG_C : reg = cpu->c; break; + case REG_D : reg = cpu->d; break; + case REG_S : reg = cpu->s; break; + case REG_F : reg = cpu->f; break; + case REG_SP : reg = cpu->sp; break; + case REG_BP : reg = cpu->bp; break; + case REG_R11: reg = cpu->r11; break; + case REG_R12: reg = cpu->r12; break; + case REG_R13: reg = cpu->r13; break; + case REG_R14: reg = cpu->r14; break; + case REG_R15: reg = cpu->r15; break; + } + value[i] += reg; + } + if (op[i].id == MEM_SIB) { + value[i] *= op[i].scale+1; + } + #if getclk + cpu->clk += inc_clk; + #endif + } + } + } + return address; +} + -static inline uint64_t adc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t carry, uint8_t thread) { +static /*inline*/ uint64_t adc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t carry, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; uint64_t sum = reg+value+carry; setflag(sum == 0, Z); - setflag((sum >> 63), N); - setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V); + setflag(sum >> (msb-1), N); + setflag(((reg^value) >> (msb-1)) && ((reg^sum) >> (msb-1)), V); setflag((sum < value), C); return sum; } -static inline uint64_t transfer(struct sux *cpu, uint64_t src, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t transfer(struct sux *cpu, uint64_t src, uint64_t value, uint8_t thread) { setflag(src == 0, Z); setflag(src >> 63, N); return src; } -static inline void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { write_value(cpu, value, cpu->sp-size, size, 1, 0); cpu->sp -= size+1; } -static inline uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, 0, cpu->sp+1, size, 1, 0); cpu->sp += size+1; return value; } -static inline uint64_t and(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t and(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; reg &= value; setflag(reg == 0, Z); - setflag(reg >> 63, N); + setflag(reg >> (msb-1), N); return reg; } -static inline uint64_t or(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t or(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; reg |= value; setflag(reg == 0, Z); - setflag(reg >> 63, N); + setflag(reg >> (msb-1), N); return reg; } -static inline uint64_t xor(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t xor(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; reg ^= value; setflag(reg == 0, Z); - setflag(reg >> 63, N); + setflag(reg >> (msb-1), N); return reg; } -static inline uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum = (value < msb) ? reg << value : 0; @@ -431,7 +640,7 @@ static inline uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum = (value < msb) ? reg >> value : 0; @@ -441,7 +650,7 @@ static inline uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint8_t sign = reg >> (msb-1); @@ -452,7 +661,7 @@ static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum; @@ -468,7 +677,7 @@ static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; uint64_t sum; @@ -484,23 +693,27 @@ static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_ return sum; } -static inline uint64_t mul(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t mul(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; uint64_t sum = reg*value; setflag(sum == 0, Z); - setflag(sum >> 63, N); - setflag(!((reg^value) >> 63) && ((reg^sum) >> 63), V); + setflag(sum >> (msb-1), N); + setflag(!((reg^value) >> (msb-1)) && ((reg^sum) >> (msb-1)), V); return sum; } -static inline uint64_t divd(struct sux *cpu, uint64_t reg, uint64_t value, uint64_t *rem, uint8_t thread) { +static /*inline*/ uint64_t divd(struct sux *cpu, uint64_t reg, uint64_t value, uint64_t *rem, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; uint64_t sum = reg/value; *rem = reg % value; setflag(sum == 0, Z); - setflag((sum >> 63), N); + setflag(sum >> (msb-1), N); return sum; } -static inline void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t thread) { +static /*inline*/ void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t thread) { uint64_t sum = reg-value; setflag(sum >> 63, N); setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V); @@ -509,14 +722,14 @@ static inline void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t th } /* Increment, or Decrement register. */ -static inline uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t thread) { +static /*inline*/ uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t thread) { reg += (inc) ? 1 : -1; setflag(reg == 0, Z); setflag(reg >> 63, N); return reg; } -static inline uint64_t lbcnt(struct sux *cpu, uint64_t value, uint8_t bit, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t lbcnt(struct sux *cpu, uint64_t value, uint8_t bit, uint8_t size, uint8_t thread) { size = (size > 8) ? 8 : size; uint8_t msb = size*8; if ((!bit && !value) || (bit && value == -1)) { @@ -528,13 +741,13 @@ static inline uint64_t lbcnt(struct sux *cpu, uint64_t value, uint8_t bit, uint8 return j; } -static inline void bit_test(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { +static /*inline*/ void bit_test(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { setflag((value >> 7) & 1, N); setflag((value >> 6) & 1, V); setflag((value & reg) == 0, Z); } -static inline uint64_t swap(struct sux *cpu, uint64_t reg, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t swap(struct sux *cpu, uint64_t reg, uint8_t size, uint8_t thread) { size = (size > 7) ? 7 : size; uint8_t half = ((size-1)*8) >> 1; uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); @@ -544,14 +757,14 @@ static inline uint64_t swap(struct sux *cpu, uint64_t reg, uint8_t size, uint8_t } -static inline uint64_t popcnt(struct sux *cpu, uint64_t value, uint8_t thread) { +static /*inline*/ uint64_t popcnt(struct sux *cpu, uint64_t value, uint8_t thread) { uint64_t count = 0; for (; value; count++, value &= value - 1); return count; } /* Increment, or Decrement memory. */ -static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t inc, uint8_t thread) { +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; uint64_t value; value = read_value(cpu, 0, address, size, 1, 0); @@ -568,7 +781,7 @@ static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_ write_value(cpu, value, address, size, 1, 1); } -static inline void bitshft_mem(struct sux *cpu, uint8_t shft_type, uint64_t shft_cnt, uint64_t address, uint8_t prefix, uint8_t thread) { +static /*inline*/ void bitshft_mem(struct sux *cpu, uint8_t shft_type, uint64_t shft_cnt, uint64_t address, uint8_t prefix, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; uint64_t value = read_value(cpu, 0, address, size, 1, 0); switch (shft_type) { @@ -581,22 +794,22 @@ static inline void bitshft_mem(struct sux *cpu, uint8_t shft_type, uint64_t shft write_value(cpu, value, address, size, 1, 1); } -static inline void not_mem(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t thread) { +static /*inline*/ void not_mem(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t thread) { uint8_t size = (1 << ((prefix >> 4) & 3))-1; write_value(cpu, ~read_value(cpu, 0, address, size, 1, 0), address, size, 1, 1); } -static inline void lbcnt_mem(struct sux *cpu, uint64_t address, uint8_t bit, uint8_t size, uint8_t thread) { +static /*inline*/ void lbcnt_mem(struct sux *cpu, uint64_t address, uint8_t bit, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, 0, address, size, 1, 0); write_value(cpu, lbcnt(cpu, value, bit, size, thread), address, size, 1, 1); } -static inline void swap_mem(struct sux *cpu, uint64_t address, uint8_t size, uint8_t thread) { +static /*inline*/ void swap_mem(struct sux *cpu, uint64_t address, uint8_t size, uint8_t thread) { uint64_t value = read_value(cpu, 0, address, size, 1, 0); write_value(cpu, swap(cpu, value, size, thread), address, size, 1, 1); } -static inline uint64_t mem_move(struct sux *cpu, uint64_t n, uint64_t dst, uint64_t src, uint8_t rep, uint8_t size, uint8_t thread) { +static /*inline*/ uint64_t mem_move(struct sux *cpu, uint64_t n, uint64_t dst, uint64_t src, uint8_t rep, uint8_t size, uint8_t thread) { if (!rep) { uint64_t value = read_value(cpu, 0, src, size, 1, 1); write_value(cpu, value, dst, size, 1, 1); @@ -609,20 +822,278 @@ static inline uint64_t mem_move(struct sux *cpu, uint64_t n, uint64_t dst, uint6 } } -static inline uint64_t load(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, 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; } -static inline void store(struct sux *cpu, uint64_t address, uint64_t reg, uint8_t prefix, 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; write_value(cpu, reg, address, size, 1, 1); } -static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, union reg value, union reg address, uint8_t size, uint8_t thread) { - uint8_t addr_size = get_addrsize(ext_optype[opcode], prefix); +static /*inline*/ uint64_t mov(struct sux *cpu, uint64_t src, uint64_t size, uint8_t thread) { + size = (size > 7) ? 7 : size; + uint8_t msb = (size+1)*8; + uint64_t dst = 0; + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + if (size < 7) { + dst = (dst & ~mask) | (src & mask); + } else { + dst = src; + } + setflag(dst == 0, Z); + setflag(dst >> (msb-1), N); + return dst; +} + +static /*inline*/ uint64_t set(struct sux *cpu, uint8_t flag, uint8_t thread) { + return flag; +} + +static /*inline*/ uint64_t inc_dec(struct sux *cpu, uint64_t value, uint8_t size, uint8_t inc, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; + value += (inc) ? 1 : -1; + setflag(value == 0, Z); + setflag(value >> (msb-1), N); + return value; +} + +static /*inline*/ uint64_t imul(struct sux *cpu, uint64_t dst, uint64_t value, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; + int64_t sum = dst*value; + setflag(sum == 0, Z); + setflag(sum >> (msb-1), N); + setflag(!((dst^value) >> (msb-1)) && ((dst^sum) >> (msb-1)), V); + return sum; +} + +static /*inline*/ uint64_t idiv(struct sux *cpu, uint64_t dst, uint64_t value, uint64_t *rem, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; + int64_t sum = dst/value; + *rem = dst % value; + setflag(sum == 0, Z); + setflag(sum >> (msb-1), N); + return sum; +} + +static /*inline*/ uint64_t neg(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { + size = (size > 8) ? 8 : size; + uint8_t msb = size*8; + value = -value; + setflag(value == 0, Z); + setflag(value >> (msb-1), N); + return value; +} + +static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t size, uint8_t *op_type, uint8_t *op_id, uint8_t thread) { + uint64_t dst = 0; + uint64_t src = 0; + uint64_t rem = 0; + uint64_t address[2] = {0, 0}; + int isdiv = 0; + operand op[2]; + cpu->pc = get_ortho_addr(cpu, prefix, cpu->pc, op, address, op_type, op_id, 1, 1, thread); + if (op[1].type) { + src = read_value(cpu, 0, op[1].value, size, 1, 1); + } else { + switch (op[1].id) { + case REG_A : src = cpu->a; break; + case REG_B : src = cpu->b; break; + case REG_X : src = cpu->x; break; + case REG_Y : src = cpu->y; break; + case REG_E : src = cpu->e; break; + case REG_C : src = cpu->c; break; + case REG_D : src = cpu->d; break; + case REG_S : src = cpu->s; break; + case REG_F : src = cpu->f; break; + case REG_SP : src = cpu->sp; break; + case REG_BP : src = cpu->bp; break; + case REG_R11: src = cpu->r11; break; + case REG_R12: src = cpu->r12; break; + case REG_R13: src = cpu->r13; break; + case REG_R14: src = cpu->r14; break; + case REG_R15: src = cpu->r15; break; + } + } + if (op[0].type) { + dst = read_value(cpu, 0, op[0].value, size, 1, 1); + } else { + switch (op[0].id) { + case REG_A : dst = cpu->a; break; + case REG_B : dst = cpu->b; break; + case REG_X : dst = cpu->x; break; + case REG_Y : dst = cpu->y; break; + case REG_E : dst = cpu->e; break; + case REG_C : dst = cpu->c; break; + case REG_D : dst = cpu->d; break; + case REG_S : dst = cpu->s; break; + case REG_F : dst = cpu->f; break; + case REG_SP : dst = cpu->sp; break; + case REG_BP : dst = cpu->bp; break; + case REG_R11: dst = cpu->r11; break; + case REG_R12: dst = cpu->r12; break; + case REG_R13: dst = cpu->r13; break; + case REG_R14: dst = cpu->r14; break; + case REG_R15: dst = cpu->r15; break; + } + } + switch (opcode) { + case ORTHO_2OP(MNG): + if (getflag(N)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MPO): + if (!getflag(N)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MCS): + if (getflag(C)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MCC): + if (!getflag(C)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MEQ): + if (getflag(Z)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MNE): + if (!getflag(Z)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MVS): + if (getflag(V)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MVC): + if (!getflag(V)) { + dst = mov(cpu, src, size, thread); + } + break; + case ORTHO_2OP(MOV): dst = mov(cpu, src, size, thread); break; + case ORTHO_2OP(ADC): dst = adc(cpu, dst, src, getflag(C), (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(SBC): dst = adc(cpu, dst, ~src, getflag(C), (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(ADD): dst = adc(cpu, dst, src, 0, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(SUB): dst = adc(cpu, dst, ~src, 1, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(AND): dst = and(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(OR ): dst = or(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(XOR): dst = xor(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(LSL): dst = lsl(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(LSR): dst = lsr(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(ROL): dst = rol(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(ROR): dst = ror(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(ASR): dst = asr(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(MUL): dst = mul(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(DIV): dst = divd(cpu, dst, src, &rem, (op[0].type) ? size+1 : 8, thread); isdiv = 1; break; + case ORTHO_2OP(CMP): adc(cpu, dst, ~src, 1, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(PCN): dst = popcnt(cpu, src, thread); break; + case ORTHO_2OP(IML): dst = imul(cpu, dst, src, (op[0].type) ? size+1 : 8, thread); break; + case ORTHO_2OP(IDV): dst = idiv(cpu, dst, src, &rem, (op[0].type) ? size+1 : 8, thread); isdiv = 1; break; + case ORTHO_2OP(LEA): + do { + uint64_t address; + uint64_t mask; + if (op[1].type) { + uint8_t addr_size = get_ortho_addrsize(prefix, op[1].id); + size = (!size) ? addr_size : size; + address = op[1].value; + } else { + address = src; + } + mask = (-(uint64_t)1 >> ((7 - size) * 8)); + dst = (address & mask); + } while (0); + break; + case ORTHO_1OP(PEA): + do { + uint64_t address = (op[0].type) ? op[0].value : dst; + push(cpu, address, 7, thread); + } while (0); + break; + case ORTHO_1OP(INC): dst = inc_dec(cpu, dst, size, 1, thread); break; + case ORTHO_1OP(DEC): dst = inc_dec(cpu, dst, size, 0, thread); break; + case ORTHO_1OP(PSH): push(cpu, dst, size, thread); break; + case ORTHO_1OP(PUL): dst = pull(cpu, size, thread); break; + case ORTHO_1OP(NOT): dst = ~dst; break; + case ORTHO_1OP(CLZ): dst = lbcnt(cpu, src, 0, size, thread); break; + case ORTHO_1OP(CLO): dst = lbcnt(cpu, src, 1, size, thread); break; + case ORTHO_1OP(SWP): dst = swap(cpu, dst, size, thread); break; + case ORTHO_1OP(NEG): dst = neg(cpu, dst, size, thread); break; + case ORTHO_1CC(SET, NG): dst = set(cpu, getflag(N), thread); break; + case ORTHO_1CC(SET, PO): dst = set(cpu, !getflag(N), thread); break; + case ORTHO_1CC(SET, CS): dst = set(cpu, getflag(C), thread); break; + case ORTHO_1CC(SET, CC): dst = set(cpu, !getflag(C), thread); break; + case ORTHO_1CC(SET, EQ): dst = set(cpu, getflag(Z), thread); break; + case ORTHO_1CC(SET, NE): dst = set(cpu, !getflag(Z), thread); break; + case ORTHO_1CC(SET, VS): dst = set(cpu, getflag(V), thread); break; + case ORTHO_1CC(SET, VC): dst = set(cpu, !getflag(V), thread); break; + + } + + if (op[0].type) { + write_value(cpu, dst, op[0].value, size, 1, 1); + } else { + switch (op[0].id) { + case REG_A : cpu->a = dst; break; + case REG_B : cpu->b = dst; break; + case REG_X : cpu->x = dst; break; + case REG_Y : cpu->y = dst; break; + case REG_E : cpu->e = dst; break; + case REG_C : cpu->c = dst; break; + case REG_D : cpu->d = dst; break; + case REG_S : cpu->s = dst; break; + case REG_F : cpu->f = dst; break; + case REG_SP : cpu->sp = dst; break; + case REG_BP : cpu->bp = dst; break; + case REG_R11: cpu->r11 = dst; break; + case REG_R12: cpu->r12 = dst; break; + case REG_R13: cpu->r13 = dst; break; + case REG_R14: cpu->r14 = dst; break; + case REG_R15: cpu->r15 = dst; break; + } + } + if (isdiv) { + if (op[1].type) { + write_value(cpu, rem, op[1].value, size, 1, 1); + } else { + switch (op[1].id) { + case REG_A : cpu->a = rem; break; + case REG_B : cpu->b = rem; break; + case REG_X : cpu->x = rem; break; + case REG_Y : cpu->y = rem; break; + case REG_E : cpu->e = rem; break; + case REG_C : cpu->c = rem; break; + case REG_D : cpu->d = rem; break; + case REG_S : cpu->s = rem; break; + case REG_F : cpu->f = rem; break; + case REG_SP : cpu->sp = rem; break; + case REG_BP : cpu->bp = rem; break; + case REG_R11: cpu->r11 = rem; break; + case REG_R12: cpu->r12 = rem; break; + case REG_R13: cpu->r13 = rem; break; + case REG_R14: cpu->r14 = rem; break; + case REG_R15: cpu->r15 = rem; break; + } + } + } +} + +static /*inline*/ void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint64_t value, uint64_t address, uint8_t size, uint8_t thread) { + uint8_t addr_size = get_addrsize(prefix, ext_optype[opcode]); uint8_t tmp = 0; switch (opcode) { case LEA_AB : /* LEA Absolute. */ @@ -637,7 +1108,12 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case LEA_IN : /* LEA Indirect. */ case LEA_IX : /* LEA Indexed Idirect. */ case LEA_IY : /* LEA Indirect Indexed. */ - cpu->e = address.u64; + do { + size = (!size) ? addr_size : size; + uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8)); + cpu->e = (address & mask); + //cpu->e = load(cpu, address, 0, size, thread); + } while (0); break; case PEA_AB : /* PEA Absolute. */ case PEA_AX : /* PEA Absolute, Indexed with X. */ @@ -651,41 +1127,41 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case PEA_IN : /* PEA Indirect. */ case PEA_IX : /* PEA Indexed Idirect. */ case PEA_IY : /* PEA Indirect Indexed. */ - push(cpu, address.u64, 7, thread); + push(cpu, address, 7, thread); break; case ADD_IMM: /* ADD Immediate. */ case ADD_AB : /* ADD Absolute. */ case ADD_Z : /* ADD Zero Matrix. */ case ADD_E : /* ADD E Indirect. */ - cpu->a = adc(cpu, cpu->a, value.u64, 0, thread); + cpu->a = adc(cpu, cpu->a, value, 0, 8, thread); break; case SUB_IMM: /* SUB Immediate. */ case SUB_AB : /* SUB Absolute. */ case SUB_Z : /* SUB Zero Matrix. */ case SUB_E : /* SUB E Indirect. */ - cpu->a = adc(cpu, cpu->a, ~value.u64, 1, thread); + cpu->a = adc(cpu, cpu->a, ~value, 1, 8, thread); break; case ADE_IMM: /* ADE Immediate. */ case ADE_AB : /* ADE Absolute. */ case ADE_Z : /* ADE Zero Matrix. */ - cpu->e = adc(cpu, cpu->e, value.u64, 0, thread); + cpu->e = adc(cpu, cpu->e, value, 0, 8, thread); break; case SBE_IMM: /* SBE Immediate. */ case SBE_AB : /* SBE Absolute. */ case SBE_Z : /* SBE Zero Matrix. */ - cpu->e = adc(cpu, cpu->e, ~value.u64, 1, thread); + cpu->e = adc(cpu, cpu->e, ~value, 1, 8, thread); break; case ADS_IMM: /* ADS Immediate. */ case ADS_AB : /* ADS Absolute. */ case ADS_Z : /* ADS Zero Matrix. */ case ADS_E : /* ADS E Indirect. */ - cpu->sp = adc(cpu, cpu->sp, value.u64, 0, thread); + cpu->sp = adc(cpu, cpu->sp, value, 0, 8, thread); break; case SBS_IMM: /* SBS Immediate. */ case SBS_AB : /* SBS Absolute. */ case SBS_Z : /* SBS Zero Matrix. */ case SBS_E : /* SBS E Indirect. */ - cpu->sp = adc(cpu, cpu->sp, ~value.u64, 1, thread); + cpu->sp = adc(cpu, cpu->sp, ~value, 1, 8, thread); break; case NOT_A : /* NOT Accumulator. */ cpu->a = ~cpu->a; @@ -693,7 +1169,7 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case NOT_AB: /* NOT Absolute. */ case NOT_Z : /* NOT Zero Matrix. */ case NOT_E : /* NOT E Indirect. */ - not_mem(cpu, address.u64, prefix, thread); + not_mem(cpu, address, prefix, thread); break; case LLM_AB: /* LLM Absolute. */ case LLM_Z : /* LLM Zero Matrix. */ @@ -727,14 +1203,14 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case ARM_Z : case ARM_E : tmp = 4; break; } - bitshft_mem(cpu, tmp, cpu->b, address.u64, prefix, thread); + bitshft_mem(cpu, tmp, cpu->b, address, prefix, thread); break; case PHE_IMP: push(cpu, cpu->e, size, thread); break; /* PusH E register. */ - case PLE_IMP: pull(cpu, size, thread); break; /* PuLl E register. */ + case PLE_IMP: cpu->e = pull(cpu, size, thread); break; /* PuLl E register. */ case CPE_IMM: /* CPE Immediate. */ case CPE_AB : /* CPE Absolute. */ case CPE_Z : /* CPE Zero Matrix. */ - adc(cpu, cpu->e, ~value.u64, 1, thread); + adc(cpu, cpu->e, ~value, 1, 8, thread); break; case ICE_AB : /* ICE Absolute. */ case ICE_Z : /* ICE Zero Matrix. */ @@ -744,7 +1220,7 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case LDS_AB : /* LDS Absolute. */ case LDS_Z : /* LDS Zero Matrix. */ case LDS_E : /* LDS E Indirect. */ - cpu->sp = load(cpu, cpu->sp, address.u64, size, thread); + cpu->sp = load(cpu, cpu->sp, address, size, thread); break; case DEE_IMP: cpu->e = idr(cpu, cpu->e, 0, thread); break; /* DEcrement E register. */ case INE_IMP: cpu->e = idr(cpu, cpu->e, 1, thread); break; /* INcrement E register. */ @@ -753,16 +1229,16 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case STS_AB: /* STS Absolute. */ case STS_Z : /* STS Zero Matrix. */ case STS_E : /* STS E Indirect. */ - store(cpu, address.u64, cpu->sp, prefix, thread); + store(cpu, address, cpu->sp, prefix, thread); break; case STE_AB: /* STE Absolute. */ case STE_Z : /* STE Zero Matrix. */ - store(cpu, address.u64, cpu->sp, prefix, thread); + store(cpu, address, cpu->sp, prefix, thread); break; case STZ_AB: /* STZ Absolute. */ case STZ_Z : /* STZ Zero Matrix. */ case STZ_E : /* STZ E Indirect. */ - store(cpu, address.u64, 0, prefix, thread); + store(cpu, address, 0, prefix, thread); break; case SCO_IMM: /* SCO Immediate. */ case SCO_AB : /* SCO Absolute. */ @@ -777,17 +1253,17 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case CLZ_AB: /* CLZ Absolute. */ case CLZ_Z : /* CLZ Zero Matrix. */ case CLZ_E : /* CLZ E Indirect. */ - cpu->a = lbcnt(cpu, value.u64, 0, size, thread); + cpu->a = lbcnt(cpu, value, 0, size, thread); break; case CLO_AB: /* CLO Absolute. */ case CLO_Z : /* CLO Zero Matrix. */ case CLO_E : /* CLO E Indirect. */ - cpu->a = lbcnt(cpu, value.u64, 1, size, thread); + cpu->a = lbcnt(cpu, value, 1, size, thread); break; case BIT_AB: /* BIT Absolute. */ case BIT_Z : /* BIT Zero Matrix. */ case BIT_E : /* BIT E Indirect. */ - bit_test(cpu, cpu->a, value.u64, thread); + bit_test(cpu, cpu->a, value, thread); break; case MMV_IMP: /* Memory MoVe. */ cpu->b = mem_move(cpu, cpu->b, cpu->x, cpu->y, 0, size, thread); @@ -798,141 +1274,141 @@ static inline void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix case SWP_AB: /* SWP Absolute. */ case SWP_Z : /* SWP Zero Matrix. */ case SWP_E : /* SWP E Indirect. */ - swap_mem(cpu, address.u64, size, thread); + swap_mem(cpu, address, size, thread); break; case PCN_AB: /* PCN Absolute. */ case PCN_Z : /* PCN Zero Matrix. */ case PCN_E : /* PCN E Indirect. */ - cpu->a = popcnt(cpu, value.u64, thread); + cpu->a = popcnt(cpu, value, thread); break; case REP_REL: /* REP Relative. */ if (cpu->b != 0) { cpu->b--; - cpu->pc = address.u64; + cpu->pc = address; } break; case REQ_REL: /* REQ Relative. */ if (cpu->b != 0 && getflag(Z)) { cpu->b--; - cpu->pc = address.u64; + cpu->pc = address; } break; case RNE_REL: /* RNE Relative. */ if (cpu->b != 0 && !getflag(Z)) { cpu->b--; - cpu->pc = address.u64; + cpu->pc = address; } break; case LNG_IMM: /* LNG Immediate. */ case LNG_E : /* LNG E Indirect. */ if (getflag(N)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LPO_IMM: /* LPO Immediate. */ case LPO_E : /* LPO E Indirect. */ if (!getflag(N)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LCS_IMM: /* LCS Immediate. */ case LCS_E : /* LCS E Indirect. */ if (getflag(C)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LCC_IMM: /* LCC Immediate. */ case LCC_E : /* LCC E Indirect. */ if (!getflag(C)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LEQ_IMM: /* LEQ Immediate. */ case LEQ_E : /* LEQ E Indirect. */ if (getflag(Z)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case LNE_IMM: /* LNE Immediate. */ case LNE_E : /* LNE E Indirect. */ if (!getflag(Z)) { - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, thread); } break; case SNG_E : /* SNG E Indirect. */ if (getflag(N)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SPO_E : /* SPO E Indirect. */ if (!getflag(N)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SCS_E : /* SCS E Indirect. */ if (getflag(C)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SCC_E : /* SCC E Indirect. */ if (!getflag(C)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SEQ_E : /* SEQ E Indirect. */ if (getflag(Z)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; case SNE_E : /* SNE E Indirect. */ if (!getflag(Z)) { - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); } break; } } -static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, union reg value, union reg address, uint8_t size, uint8_t thread) { +static /*inline*/ void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint64_t value, uint64_t address, uint8_t size, uint8_t thread) { uint64_t *rem = 0; switch (opcode) { case CPS_IMP: /* Clear Processor Status. */ cpu->ps.u8[thread] = 0; break; case ADC_B: /* ADC B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ADC_IMM: /* ADC Immediate. */ case ADC_AB: /* ADC Absolute. */ case ADC_Z: /* ADC Zero Matrix. */ - cpu->a = adc(cpu, cpu->a, value.u64, getflag(C), thread); + cpu->a = adc(cpu, cpu->a, value, 8, getflag(C), thread); break; case PHP_IMP: push(cpu, cpu->ps.u8[thread], 0, thread); break; /* PusH Processor status to stack. */ case PHA_IMP: push(cpu, cpu->a , size, thread); break; /* PusH Accumulator to stack. */ case PHB_IMP: push(cpu, cpu->b , size, thread); break; /* PusH B register to stack. */ case PHY_IMP: push(cpu, cpu->y , size, thread); break; /* PusH Y register to stack. */ case PHX_IMP: push(cpu, cpu->x , size, thread); break; /* PusH X register to stack. */ - case TAY_IMP: cpu->y = transfer(cpu, cpu->a , value.u64, thread); break; /* Transfer Accumulator to Y. */ - case TAX_IMP: cpu->x = transfer(cpu, cpu->a , value.u64, thread); break; /* Transfer Accumulator to Y. */ - case TYX_IMP: cpu->x = transfer(cpu, cpu->y , value.u64, thread); break; /* Transfer Y to X. */ - case TYA_IMP: cpu->a = transfer(cpu, cpu->y , value.u64, thread); break; /* Transfer Y to Accumulator. */ - case TXA_IMP: cpu->a = transfer(cpu, cpu->x , value.u64, thread); break; /* Transfer X to Accumulator. */ - case TXY_IMP: cpu->y = transfer(cpu, cpu->x , value.u64, thread); break; /* Transfer X to Y. */ - case TAB_IMP: cpu->b = transfer(cpu, cpu->a , value.u64, thread); break; /* Transfer Accumulator to B. */ - case TSX_IMP: cpu->x = transfer(cpu, cpu->sp, value.u64, thread); break; /* Transfer Stack pointer to X. */ - case TBA_IMP: cpu->a = transfer(cpu, cpu->b , value.u64, thread); break; /* Transfer B to Accumulator. */ - case TXS_IMP: cpu->sp = transfer(cpu, cpu->x , value.u64, thread); break; /* Transfer X to Stack pointer. */ + case TAY_IMP: cpu->y = transfer(cpu, cpu->a , value, thread); break; /* Transfer Accumulator to Y. */ + case TAX_IMP: cpu->x = transfer(cpu, cpu->a , value, thread); break; /* Transfer Accumulator to Y. */ + case TYX_IMP: cpu->x = transfer(cpu, cpu->y , value, thread); break; /* Transfer Y to X. */ + case TYA_IMP: cpu->a = transfer(cpu, cpu->y , value, thread); break; /* Transfer Y to Accumulator. */ + case TXA_IMP: cpu->a = transfer(cpu, cpu->x , value, thread); break; /* Transfer X to Accumulator. */ + case TXY_IMP: cpu->y = transfer(cpu, cpu->x , value, thread); break; /* Transfer X to Y. */ + case TAB_IMP: cpu->b = transfer(cpu, cpu->a , value, thread); break; /* Transfer Accumulator to B. */ + case TSX_IMP: cpu->x = transfer(cpu, cpu->sp, value, thread); break; /* Transfer Stack pointer to X. */ + case TBA_IMP: cpu->a = transfer(cpu, cpu->b , value, thread); break; /* Transfer B to Accumulator. */ + case TXS_IMP: cpu->sp = transfer(cpu, cpu->x , value, thread); break; /* Transfer X to Stack pointer. */ case BRA_REL: /* BRA Relative. */ case JMP_AB: /* JMP Absolute. */ case JMP_Z: /* JMP Zero Matrix. */ case JMP_IN: /* JMP Indirect. */ - cpu->pc = address.u64; + cpu->pc = address; break; case SBC_B: /* SBC B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case SBC_IMM: /* SBC Immediate. */ case SBC_AB: /* SBC Absolute. */ case SBC_Z: /* SBC Zero Matrix. */ - cpu->a = adc(cpu, cpu->a, ~value.u64, getflag(C), thread); + cpu->a = adc(cpu, cpu->a, ~value, 8, getflag(C), thread); break; case PLP_IMP: cpu->ps.u8[thread] = pull(cpu, 0, thread); break; /* PuLl Processor status from stack. */ case PLA_IMP: cpu->a = pull(cpu, size, thread); break; /* PuLl Accumulator from stack. */ @@ -941,53 +1417,53 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case PLX_IMP: cpu->x = pull(cpu, size, thread); break; /* PuLl X register from stack. */ break; case AND_B: /* AND B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case AND_IMM: /* AND Immediate. */ case AND_AB: /* AND Absolute. */ case AND_Z: /* AND Zero Matrix. */ - cpu->a = and(cpu, cpu->a, value.u64, thread); + cpu->a = and(cpu, cpu->a, value, 8, thread); break; case BPO_REL: /* BPO Relative. */ if (!getflag(N)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case ORA_B: /* ORA B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ORA_IMM: /* ORA Immediate. */ case ORA_AB: /* ORA Absolute. */ case ORA_Z: /* ORA Zero Matrix. */ - cpu->a = or(cpu, cpu->a, value.u64, thread); + cpu->a = or(cpu, cpu->a, value, 8, thread); break; case SEI_IMP: /* SEt Interrupt. */ setflag(1, I); break; case BNG_REL: /* BNG Relative. */ if (getflag(N)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case XOR_B: /* XOR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case XOR_IMM: /* XOR Immediate. */ case XOR_AB: /* XOR Absolute. */ case XOR_Z: /* XOR Zero Matrix. */ - cpu->a = xor(cpu, cpu->a, value.u64, thread); + cpu->a = xor(cpu, cpu->a, value, 8, thread); break; case CLI_IMP: /* CLear Interrupt. */ setflag(0, I); break; case BCS_REL: /* BCS Relative. */ if (getflag(C)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case LSL_B: /* LSL B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case LSL_IMM: /* LSL Immediate. */ case LSL_AB: /* LSL Absolute. */ case LSL_Z: /* LSL Zero Matrix. */ - cpu->a = lsl(cpu, cpu->a, value.u64, 8, thread); + cpu->a = lsl(cpu, cpu->a, value, 8, thread); break; case SEC_IMP: /* SEt Carry flag.*/ setflag(1, C); @@ -999,17 +1475,17 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case STA_IN: /* STA Indirect. */ case STA_IX: /* STA Indexed Indirect. */ case STA_IY: /* STA Indirect Indexed. */ - store(cpu, address.u64, cpu->a, prefix, thread); + store(cpu, address, cpu->a, prefix, thread); break; case STY_AB: /* STY Absolute. */ case STY_Z: /* STY Zero Matrix. */ case STY_IN: /* STY Indirect. */ - store(cpu, address.u64, cpu->y, prefix, thread); + store(cpu, address, cpu->y, prefix, thread); break; case STX_AB: /* STX Absolute. */ case STX_Z: /* STX Zero Matrix. */ case STX_IN: /* STX Indirect. */ - store(cpu, address.u64, cpu->x, prefix, thread); + store(cpu, address, cpu->x, prefix, thread); break; case STB_AB: /* STB Absolute. */ case STB_Z: /* STB Zero Matrix. */ @@ -1018,26 +1494,26 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case STB_IN: /* STB Indirect. */ case STB_IX: /* STB Indexed Indirect. */ case STB_IY: /* STB Indirect Indexed. */ - store(cpu, address.u64, cpu->b, prefix, thread); + store(cpu, address, cpu->b, prefix, thread); break; case BCC_REL: /* BCC Relative. */ if (!getflag(C)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case LSR_B: /* LSR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case LSR_IMM: /* LSR Immediate. */ case LSR_AB: /* LSR Absolute. */ case LSR_Z: /* LSR Zero Matrix. */ - cpu->a = lsr(cpu, cpu->a, value.u64, 8, thread); + cpu->a = lsr(cpu, cpu->a, value, 8, thread); break; case ASR_B: /* ASR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ASR_IMM: /* ASR Immediate. */ case ASR_AB: /* ASR Absolute. */ case ASR_Z: /* ASR Zero Matrix. */ - cpu->a = asr(cpu, cpu->a, value.u64, 8, thread); + cpu->a = asr(cpu, cpu->a, value, 8, thread); break; case CLC_IMP: /* CLear Carry flag. */ setflag(0, C); @@ -1050,7 +1526,7 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case LDB_IN: /* LDB Indirect. */ case LDB_IX: /* LDB Indexed Indirect. */ case LDB_IY: /* LDB Indirect Indexed. */ - cpu->b = load(cpu, cpu->b, address.u64, size, thread); + cpu->b = load(cpu, cpu->b, address, size, thread); break; case LDA_IMM: /* LDA Immediate. */ case LDA_AB: /* LDA Absolute. */ @@ -1060,59 +1536,59 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case LDA_IN: /* LDA Indirect. */ case LDA_IX: /* LDA Indexed Indirect. */ case LDA_IY: /* LDA Indirect Indexed. */ - cpu->a = load(cpu, cpu->a, address.u64, size, thread); + cpu->a = load(cpu, cpu->a, address, size, 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, cpu->y, address.u64, size, thread); + cpu->y = load(cpu, cpu->y, address, size, 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, cpu->x, address.u64, size, thread); + cpu->x = load(cpu, cpu->x, address, size, thread); break; case BEQ_REL: /* BEQ Relative. */ if (getflag(Z)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case ROL_B: /* ROL B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ROL_IMM: /* ROL Immediate. */ case ROL_AB: /* ROL Absolute. */ case ROL_Z: /* ROL Zero Matrix. */ - cpu->a = rol(cpu, cpu->a, value.u64, 8, thread); + cpu->a = rol(cpu, cpu->a, value, 8, thread); break; case BNE_REL: /* BNE Relative. */ if (!getflag(Z)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case ROR_B: /* ROR B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case ROR_IMM: /* ROR Immediate. */ case ROR_AB: /* ROR Absolute. */ case ROR_Z: /* ROR Zero Matrix. */ - cpu->a = ror(cpu, cpu->a, value.u64, 8, thread); + cpu->a = ror(cpu, cpu->a, value, 8, thread); break; case BVS_REL: /* BVS Relative. */ if (getflag(V)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case MUL_B: /* MUL B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case MUL_IMM: /* MUL Immediate. */ case MUL_AB: /* MUL Absolute. */ case MUL_Z: /* MUL Zero Matrix. */ - cpu->a = mul(cpu, cpu->a, value.u64, thread); + cpu->a = mul(cpu, cpu->a, value, 8, thread); break; case BVC_REL: /* BVC Relative. */ if (!getflag(V)) { - cpu->pc = address.u64; + cpu->pc = address; } break; case DIV_B: /* DIV B register. */ @@ -1120,7 +1596,7 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case DIV_AB: /* DIV Absolute. */ case DIV_Z: /* DIV Zero Matrix. */ rem = (opcode != DIV_B) ? &cpu->b : &cpu->x; - cpu->a = divd(cpu, cpu->a, value.u64, rem, thread); + cpu->a = divd(cpu, cpu->a, value, rem, 8, thread); break; case CLV_IMP: /* CLear oVerflow flag. */ setflag(0, V); @@ -1131,27 +1607,27 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case CPB_IN: /* CPB Indirect. */ case CPB_IX: /* CPB Indexed Indirect. */ case CPB_IY: /* CPB Indirect Indexed. */ - adc(cpu, cpu->b, ~value.u64, 1, thread); + adc(cpu, cpu->b, ~value, 1, 8, thread); break; case CMP_B: /* CMP B register. */ - value.u64 = cpu->b; /* Falls Through. */ + value = cpu->b; /* Falls Through. */ case CMP_IMM: /* CMP Immediate. */ case CMP_AB: /* CMP Absolute. */ case CMP_Z: /* CMP Zero Matrix. */ case CMP_IN: /* CMP Indirect. */ case CMP_IX: /* CMP Indexed Indirect. */ case CMP_IY: /* CMP Indirect Indexed. */ - adc(cpu, cpu->a, ~value.u64, 1, thread); + adc(cpu, cpu->a, ~value, 1, 8, thread); break; case CPY_IMM: /* CPY Immediate. */ case CPY_AB: /* CPY Absolute. */ case CPY_Z: /* CPY Zero Matrix. */ - adc(cpu, cpu->y, ~value.u64, 1, thread); + adc(cpu, cpu->y, ~value, 1, 8, thread); break; case CPX_IMM: /* CPX Immediate. */ case CPX_AB: /* CPX Absolute. */ case CPX_Z: /* CPX Zero Matrix. */ - adc(cpu, cpu->x, ~value.u64, 1, thread); + adc(cpu, cpu->x, ~value, 1, 8, thread); break; case INC_IMP: cpu->a = idr(cpu, cpu->a, 1, thread); break; case INB_IMP: cpu->b = idr(cpu, cpu->b, 1, thread); break; @@ -1165,11 +1641,11 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi case JSR_AB: /* Jump to SubRoutine. */ case JSR_Z: /* JSR Zero Matrix. */ push(cpu, cpu->pc, (size) ? size : 7, thread); - cpu->pc = address.u64; + cpu->pc = address; break; case INC_AB: /* INC Absolute. */ case INC_Z: /* INC Zero Matrix. */ - idm(cpu, address.u64, prefix, 1, thread); + idm(cpu, address, prefix, 1, thread); break; case NOP_IMP: /* No OPeration. */ break; @@ -1181,7 +1657,7 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi break; case DEC_AB: /* DEC Absolute. */ case DEC_Z: /* DEC Zero Matrix. */ - idm(cpu, address.u64, prefix, 0, thread); + idm(cpu, address, prefix, 0, thread); break; case BRK_IMP: /* BReaK. */ case WAI_IMP: /* WAit for Interrupt. */ @@ -1196,12 +1672,16 @@ static inline void exec_base_inst(struct sux *cpu, uint8_t opcode, uint8_t prefi push(cpu, cpu->pc, 7, thread); push(cpu, cpu->ps.u8[thread], 0, thread); setflag(1, I); - value.u64 = read_value(cpu, 0, (opcode == BRK) ? 0xFFE0 : 0xFFA0, 7, 1, 0); + value = read_value(cpu, 0, (opcode == BRK) ? 0xFFE0 : 0xFFA0, 7, 1, 0); if (opcode == WAI_IMP) { kbd_rdy &= (uint8_t)~(1 << thread); } - cpu->pc = value.u64; + cpu->pc = value; default: break; } } + +#undef ORTHO_1CC +#undef ORTHO_1OP +#undef ORTHO_2OP -- cgit v1.2.3-13-gbd6f