From 756c606af68be8ccca7aced3b9c3d56fb2d5087f Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Mon, 6 Jul 2020 20:04:41 -0400 Subject: - Implemented a new opcode table. - Added a new preifx called the OF prefix, which adds the contents of a specific register to the current operand. - Added a table generator, which parses opcode table csv files. --- sux.h | 103 ++++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 62 insertions(+), 41 deletions(-) (limited to 'sux.h') diff --git a/sux.h b/sux.h index 84cc3a6..77736c4 100644 --- a/sux.h +++ b/sux.h @@ -43,6 +43,8 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco union reg address; union reg value; uint8_t tmp = 0; + uint64_t tmp2 = 0; + union reg saveaddr; address.u64 = 0; value.u64 = 0; switch (optype[opcode]) { @@ -51,25 +53,13 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco case IMM: address.u64 = cpu->pc; switch (opcode) { - case PHB: - case PHP: - case PHA: - case PHY: - case PHX: - case PLB: - case PLP: - case PLA: - case PLY: - case PLX: - case STT: - case LSL: - case LSR: - case ROL: - case ROR: - case ASR: - case ENT: ++cpu->pc; break; - default : cpu->pc+=(1 << (prefix >> 4)); /* Falls Through. */ - case TXS: break; + case LSL_IMM: + case LSR_IMM: + case ROL_IMM: + case ROR_IMM: + case ASR_IMM: ++cpu->pc; break; + default : cpu->pc+=(1 << ((prefix >> 4) & 3)); /* Falls Through. */ + case TXS_IMM: break; } break; case ZM: @@ -83,6 +73,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco /* Unroll Loop by implementing Duff's Device. */ tmp = get_addrsize(prefix, ZM)+1; setreg_sw(address.u8, 0, addr, cpu->pc, prefix, ZM, AM); + cpu->pc+=tmp; #if debug && !bench *tmpaddr = address.u64; @@ -91,6 +82,21 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco iclk++; #endif uint64_t reg = 0; + saveaddr.u64 = 0; + if (prefix >> 6) { + switch (prefix >> 6) { + case 1: tmp2 = ((cpu->stk_st << 16) | cpu->sp); break; + case 2: tmp2 = cpu->pc ; break; + } + saveaddr = address; + switch ((prefix & 0x0C) >> 2) { + case 0: saveaddr.u64 = tmp2 + (int8_t )address.u8[0] ; break; + case 2: saveaddr.u64 = tmp2 + (int64_t)address.u64 ; break; + case 1: + case 3: saveaddr.u64 = tmp2 + (int32_t)address.u32[0]; break; + } + (optype[opcode] != INDY) ? (address.u64 = saveaddr.u64) : (reg = saveaddr.u64); + } switch (optype[opcode]) { case ZMX: address.u64 += cpu->x; @@ -112,7 +118,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco iclk++; #endif } else { - reg = cpu->y; + reg += cpu->y; #if getclk iclk++; #endif @@ -134,6 +140,25 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco #if getclk iclk++; #endif + saveaddr.u64 = 0; + if (prefix >> 6) { + switch (prefix >> 6) { + case 1: tmp2 = ((cpu->stk_st << 16) | cpu->sp); break; + case 2: tmp2 = cpu->pc ; break; + } + saveaddr = address; + switch ((prefix & 0x0C) >> 2) { + case 0: saveaddr.u64 = tmp2 + (int16_t)address.u16[0]; break; + case 1: + case 2: + case 3: saveaddr.u64 = tmp2 + (int64_t)address.u64 ; break; + } + address.u64 = saveaddr.u64; + } + break; + case REL: + address.u64 = cpu->pc; + cpu->pc+=(1 << ((prefix >> 4) & 3)); break; } @@ -160,16 +185,16 @@ static inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) { static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t prefix, uint8_t thread) { uint64_t reg; switch (opcode) { - case TBA: cpu->a = cpu->b; reg = cpu->a; break; - case TXA: cpu->a = cpu->x; reg = cpu->a; break; - case TYA: cpu->a = cpu->y; reg = cpu->a; break; - case TAB: cpu->b = cpu->a; reg = cpu->b; break; - case TAY: cpu->y = cpu->a; reg = cpu->y; break; - case TXY: cpu->y = cpu->x; reg = cpu->y; break; - case TAX: cpu->x = cpu->a; reg = cpu->x; break; - case TYX: cpu->x = cpu->y; reg = cpu->x; break; - case TSX: cpu->x = cpu->sp & 0xFFFF; cpu->x = cpu->stk_st << 16; break; - case TXS: cpu->sp = cpu->x; + case TBA_IMP: cpu->a = cpu->b; reg = cpu->a; break; + case TXA_IMP: cpu->a = cpu->x; reg = cpu->a; break; + case TYA_IMP: cpu->a = cpu->y; reg = cpu->a; break; + case TAB_IMP: cpu->b = cpu->a; reg = cpu->b; break; + case TAY_IMP: cpu->y = cpu->a; reg = cpu->y; break; + case TXY_IMP: cpu->y = cpu->x; reg = cpu->y; break; + case TAX_IMP: cpu->x = cpu->a; reg = cpu->x; break; + case TYX_IMP: cpu->x = cpu->y; reg = cpu->x; break; + case TSX_IMP: cpu->x = cpu->sp & 0xFFFF; cpu->x = cpu->stk_st << 16; break; + case TXS_IMM: cpu->sp = cpu->x; if (prefix == 0x13 && (value == thread+1 || value > 8)) { cpu->stk_st = value & 0xFF; cpu->stk_st += value << 16; @@ -181,22 +206,18 @@ static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uin setflag(reg >> 63, N); } -static inline void push(struct sux *cpu, uint64_t size, uint64_t value, uint8_t thread) { +static inline void push(struct sux *cpu, uint64_t value, uint8_t prefix, uint8_t thread) { union reg reg; reg.u64 = value; - size = (size > 0) ? size-1 : 0; - uint8_t tmp = (size <= 7) ? size : 7; - setreg(addr, -, (cpu->stk_st << 16)+cpu->sp, reg.u8, +, 0, tmp); - cpu->sp -= (tmp+1); + setreg(addr, -, (cpu->stk_st << 16)+cpu->sp, reg.u8, +, 0, (1 << ((prefix >> 4) & 3))-1); + cpu->sp -= (1 << ((prefix >> 4) & 3)); } -static inline uint64_t pull(struct sux *cpu, uint64_t size, uint8_t thread) { +static inline uint64_t pull(struct sux *cpu, uint8_t prefix, uint8_t thread) { union reg reg; reg.u64 = 0; - size = (size > 0) ? size-1 : 0; - uint8_t tmp = (size <= 7) ? size : 7; - cpu->sp += (tmp+1); - setreg(reg.u8, +, 0, addr, -, (cpu->stk_st << 16)+cpu->sp, tmp); + cpu->sp += (1 << ((prefix >> 4) & 3)); + setreg(reg.u8, +, 0, addr, -, (cpu->stk_st << 16)+cpu->sp, (1 << ((prefix >> 4) & 3))-1); return reg.u64; } @@ -268,7 +289,7 @@ static inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) { static inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) { uint64_t sum = cpu->a/value; - if (opcode != DAB) { + if (opcode != DAB_IMP) { cpu->b = cpu->a % value; } else { value = cpu->b; -- cgit v1.2.3-13-gbd6f