summaryrefslogtreecommitdiff
path: root/sux.h
diff options
context:
space:
mode:
Diffstat (limited to 'sux.h')
-rw-r--r--sux.h259
1 files changed, 77 insertions, 182 deletions
diff --git a/sux.h b/sux.h
index 241362b..4678eb9 100644
--- a/sux.h
+++ b/sux.h
@@ -22,6 +22,8 @@ extern WINDOW *scr;
extern uint8_t subdbg;
#endif
+extern uint8_t step;
+extern uint8_t esc;
#define setflag(flag, bit) ((flag)) ? (cpu->ps.u8[thread] |= bit) : (cpu->ps.u8[thread] &= ~bit)
#define getflag(bit) (cpu->ps.u8[thread] & bit)
@@ -35,7 +37,7 @@ extern pthread_cond_t main_cond;
extern void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread);
#endif
-extern void io(uint64_t address, uint8_t *esc);
+extern void io(uint64_t address, uint8_t rw);
static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opcode, uint8_t prefix, uint8_t thread) {
union reg address;
@@ -47,6 +49,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
case IMPL:
break;
case IMM:
+ address.u64 = cpu->pc[thread];
switch (opcode) {
case PHB:
case PHP:
@@ -64,15 +67,9 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
case ROL:
case ROR:
case ASR:
- case ENT:
- address.u64 = cpu->pc[thread];
- ++cpu->pc[thread];
- break;
- default:
- address.u64 = cpu->pc[thread];
- cpu->pc[thread]+=(1 << (prefix >> 4));
- case TXS:
- break;
+ case ENT: ++cpu->pc[thread]; break;
+ default : cpu->pc[thread]+=(1 << (prefix >> 4));
+ case TXS: break;
}
break;
case ZM:
@@ -181,7 +178,7 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
return address.u64;
}
-inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = cpu->a[thread]+value+getflag(C);
setflag(sum == 0, Z);
setflag((sum >> 63), N);
@@ -189,7 +186,7 @@ inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) {
setflag((sum < value), C);
cpu->a[thread] = sum;
}
-inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = cpu->a[thread]-value-!getflag(C);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -198,7 +195,7 @@ inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] = sum;
}
-inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t prefix, 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[thread] = cpu->b[thread]; reg = cpu->a[thread]; break;
@@ -222,21 +219,14 @@ inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t pr
setflag(reg >> 63, N);
}
-inline void push(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+static inline void push(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t thread) {
union {
uint64_t reg;
uint8_t byte[8];
} r;
- r.reg = 0;
+ r.reg = reg;
uint8_t size = (value > 0) ? value-1 : 0;
uint8_t tmp = (size <= 7) ? size : 7;
- switch (opcode) {
- case PHA: r.reg = cpu->a[thread]; break;
- case PHB: r.reg = cpu->b[thread]; break;
- case PHX: r.reg = cpu->x[thread]; break;
- case PHY: r.reg = cpu->y[thread]; break;
- case PHP: r.reg = cpu->ps.u64; break;
- }
/* Unroll Loop by implementing Duff's Device. */
switch (tmp) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[7];cpu->sp[thread]--;
@@ -250,7 +240,7 @@ inline void push(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread
}
}
-inline void pull(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+static inline uint64_t pull(struct sux *cpu, uint64_t value, uint8_t thread) {
union {
uint64_t reg;
uint8_t byte[8];
@@ -270,32 +260,26 @@ inline void pull(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread
case 2: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
case 1: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
}
- switch (opcode) {
- case PLA: cpu->a[thread] = r.reg; break;
- case PLB: cpu->b[thread] = r.reg; break;
- case PLX: cpu->x[thread] = r.reg; break;
- case PLY: cpu->y[thread] = r.reg; break;
- case PLP: cpu->ps.u64 = r.reg; break;
- }
+ return r.reg;
}
-inline void and(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void and(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] &= value;
setflag(cpu->a[thread] == 0, Z);
setflag(cpu->a[thread] >> 63, N);
}
-inline void or(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void or(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] |= value;
setflag(cpu->a[thread] == 0, Z);
setflag(cpu->a[thread] >> 63, N);
}
-inline void xor(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void xor(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] ^= value;
setflag(cpu->a[thread] == 0, Z);
setflag(cpu->a[thread] >> 63, N);
}
-inline void lsl(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void lsl(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = (value < 64) ? cpu->a[thread] << value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -303,7 +287,7 @@ inline void lsl(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] = sum;
}
-inline void lsr(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void lsr(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = (value < 64) ? cpu->a[thread] >> value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -311,7 +295,7 @@ inline void lsr(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] = sum;
}
-inline void asr(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void asr(struct sux *cpu, uint64_t value, uint8_t thread) {
uint8_t sign = cpu->a[thread] >> 63;
uint64_t sum = (value < 64) ? (cpu->a[thread] >> value) | ((uint64_t)sign << 63) : 0;
setflag(sum == 0, Z);
@@ -320,7 +304,7 @@ inline void asr(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] = sum;
}
-inline void rol(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void rol(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = cpu->a[thread] << value;
sum |= getflag(C);
setflag(sum == 0, Z);
@@ -329,7 +313,7 @@ inline void rol(struct sux *cpu, uint64_t value, uint8_t thread) {
cpu->a[thread] = sum;
}
-inline void ror(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void ror(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = cpu->a[thread] >> value;
sum |= (uint64_t)getflag(C) << (uint64_t)(64-value);
setflag(sum == 0, Z);
@@ -337,7 +321,7 @@ inline void ror(struct sux *cpu, uint64_t value, uint8_t thread) {
setflag(cpu->a[thread] & 1, C);
cpu->a[thread] = sum;
}
-inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) {
+static inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) {
uint64_t sum = cpu->a[thread]*value;
cpu->a[thread] = sum;
setflag(sum == 0, Z);
@@ -345,7 +329,7 @@ inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) {
setflag(!((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
}
-inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+static inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
uint64_t sum = cpu->a[thread]/value;
if (opcode != DAB) {
cpu->b[thread] = cpu->a[thread] % value;
@@ -357,40 +341,7 @@ inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread
setflag(sum == 0, Z);
setflag((sum >> 63), N);
}
-inline void cmp(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
- uint64_t reg;
- switch (opcode) {
- case CPB:
- case CPB_AB:
- case CPB_Z:
- case CPB_IN:
- case CPB_IX:
- case CPB_IY:
- reg = cpu->b[thread];
- break;
- case CMP:
- case CAB:
- case CMP_AB:
- case CMP_Z:
- case CMP_IN:
- case CMP_IX:
- case CMP_IY:
- reg = cpu->a[thread];
- break;
- case CPY:
- case CPY_AB:
- case CPY_Z:
- case CPY_IN:
- reg = cpu->y[thread];
- break;
-
- case CPX:
- case CPX_AB:
- case CPX_Z:
- case CPX_IN:
- reg = cpu->x[thread];
- break;
- }
+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);
@@ -398,46 +349,20 @@ inline void cmp(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread)
setflag(reg >= value, C);
}
-inline void incr(struct sux *cpu, uint8_t opcode, uint8_t thread) {
- uint64_t reg;
- switch (opcode) {
- case INC: cpu->a[thread]+=1; reg = cpu->a[thread]; break;
- case INB: cpu->b[thread]+=1; reg = cpu->b[thread]; break;
- case INY: cpu->y[thread]+=1; reg = cpu->y[thread]; break;
- case INX: cpu->x[thread]+=1; reg = cpu->x[thread]; break;
- }
- setflag(reg == 0, Z);
- setflag(reg >> 63, N);
-}
-
-inline void decr(struct sux *cpu, uint8_t opcode, uint8_t thread) {
- uint64_t reg;
- switch (opcode) {
- case DEC: cpu->a[thread]-=1; reg = cpu->a[thread]; break;
- case DEB: cpu->b[thread]-=1; reg = cpu->b[thread]; break;
- case DEY: cpu->y[thread]-=1; reg = cpu->y[thread]; break;
- case DEX: cpu->x[thread]-=1; reg = cpu->x[thread]; break;
+/* Increment, or Decrement register. */
+static inline uint64_t idr(struct sux *cpu, uint64_t reg, uint8_t inc, uint8_t thread) {
+ if (inc) {
+ reg++;
+ } else {
+ reg--;
}
setflag(reg == 0, Z);
setflag(reg >> 63, N);
+ return reg;
}
-inline void incm(struct sux *cpu, uint64_t address, uint8_t thread) {
- addr[address]++;
- setflag(addr[address] == 0, Z);
- setflag(addr[address] >> 7, N);
-}
-
-inline void decm(struct sux *cpu, uint64_t address, uint8_t thread) {
- addr[address]--;
- setflag(addr[address] == 0, Z);
- setflag(addr[address] >> 7, N);
-}
-
-inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread) {
- if (address == CTRL_ADDR) {
- io(address, esc);
- }
+/* Increment, or Decrement memory. */
+static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_t inc, uint8_t thread) {
union reg value;
value.u64 = 0;
/* Unroll Loop by implementing Duff's Device. */
@@ -454,91 +379,61 @@ inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode
case 2:
value.u8[1] = addr[address+1];
}
- switch (opcode) {
- case LDB:
- case LDB_AB:
- case LDB_Z:
- case LDB_ZX:
- case LDB_ZY:
- case LDB_IN:
- case LDB_IX:
- case LDB_IY:
- cpu->b[thread] = value.u64;
- break;
- case LDA:
- case LDA_AB:
- case LDA_Z:
- case LDA_ZX:
- case LDA_ZY:
- case LDA_IN:
- case LDA_IX:
- case LDA_IY:
- cpu->a[thread] = value.u64;
- break;
- case LDY:
- case LDY_AB:
- case LDY_Z:
- case LDY_ZX:
- case LDY_IN:
- cpu->y[thread] = value.u64;
- break;
+ if (inc) {
+ value.u64++;
+ } else {
+ value.u64--;
+ }
+ setflag(value.u64 == 0, Z);
+ setflag(value.u64 >> 7, N);
+ addr[address] = value.u8[0];
+ io(address, 0);
+ switch (1 << (prefix >> 4)) {
+ case 8:
+ addr[address+7] = value.u8[7];
+ addr[address+6] = value.u8[6];
+ addr[address+5] = value.u8[5];
+ addr[address+4] = value.u8[4];
+ case 4:
+ addr[address+3] = value.u8[3];
+ addr[address+2] = value.u8[2];
+ case 2:
+ addr[address+1] = value.u8[1];
+ }
+}
- case LDX:
- case LDX_AB:
- case LDX_Z:
- case LDX_ZY:
- case LDX_IN:
- cpu->x[thread] = value.u64;
- break;
+static inline uint64_t load(struct sux *cpu, uint64_t address, uint64_t reg, uint8_t prefix, uint8_t thread) {
+ io(address, 1);
+ union reg value;
+ value.u64 = reg;
+ /* Unroll Loop by implementing Duff's Device. */
+ value.u8[0] = addr[address];
+ switch (1 << (prefix >> 4)) {
+ case 8:
+ value.u8[7] = addr[address+7];
+ value.u8[6] = addr[address+6];
+ value.u8[5] = addr[address+5];
+ value.u8[4] = addr[address+4];
+ case 4:
+ value.u8[3] = addr[address+3];
+ value.u8[2] = addr[address+2];
+ case 2:
+ value.u8[1] = addr[address+1];
}
setflag(value.u64 == 0, Z);
setflag(value.u64 >> 63, N);
+ return value.u64;
}
-inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, 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) {
union reg value;
- value.u64 = 0;
- switch (opcode) {
- case STB:
- case STB_Z:
- case STB_ZX:
- case STB_ZY:
- case STB_IN:
- case STB_IX:
- case STB_IY:
- value.u64 = cpu->b[thread];
- break;
- case STA:
- case STA_Z:
- case STA_ZX:
- case STA_ZY:
- case STA_IN:
- case STA_IX:
- case STA_IY:
- value.u64 = cpu->a[thread];
- break;
- case STY:
- case STY_Z:
- case STY_ZX:
- case STY_IN:
- value.u64 = cpu->y[thread];
- break;
-
- case STX:
- case STX_Z:
- case STX_ZY:
- case STX_IN:
- value.u64 = cpu->x[thread];
- break;
- }
+ value.u64 = reg;
addr[address] = value.u8[0];
#if (IO || debug) && !branch
#if keypoll
pthread_mutex_lock(&mutex);
#endif
- if (address != CTRL_ADDR && address == TX_ADDR) {
- io(address, esc);
- }
+ io(address, 0);
#if keypoll
pthread_mutex_unlock(&mutex);
#endif