summaryrefslogtreecommitdiff
path: root/sux.h
diff options
context:
space:
mode:
Diffstat (limited to 'sux.h')
-rw-r--r--sux.h103
1 files changed, 62 insertions, 41 deletions
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;