summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-05-04 12:57:36 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-05-04 12:57:36 -0400
commit9ccba5e624319becd9a85822e60b15b6355f19cd (patch)
treec12efdd4d15986e04edac36439668fa4843c89b7
parent1c622005c289ef1cd9feea277bd0ff46b19d15f0 (diff)
Made all address decoding, and memory reads/writes be
done with a union, in order to make it more readable.
-rw-r--r--opcode.c4
-rw-r--r--opcode.h7
-rw-r--r--sux.c239
-rw-r--r--sux.h134
4 files changed, 195 insertions, 189 deletions
diff --git a/opcode.c b/opcode.c
index 423da28..017a298 100644
--- a/opcode.c
+++ b/opcode.c
@@ -17,8 +17,8 @@ extern inline void ror(struct sux *cpu, uint64_t value, uint8_t thread);
extern inline void mul(struct sux *cpu, uint64_t value, uint8_t thread);
extern inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
extern inline void cmp(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
-extern inline void incr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
-extern inline void decr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void incr(struct sux *cpu, uint8_t opcode, uint8_t thread);
+extern inline void decr(struct sux *cpu, uint8_t opcode, uint8_t thread);
extern inline void incm(struct sux *cpu, uint64_t address, uint8_t thread);
extern inline void decm(struct sux *cpu, uint64_t address, uint8_t thread);
extern inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread);
diff --git a/opcode.h b/opcode.h
index 81bffa4..b9d1817 100644
--- a/opcode.h
+++ b/opcode.h
@@ -203,6 +203,13 @@
uint8_t *addr; /* Address Space. */
+union reg {
+ uint8_t u8[8];
+ uint16_t u16[4];
+ uint32_t u32[2];
+ uint64_t u64;
+};
+
struct sux {
uint64_t ps; /* The processor status register. */
uint64_t a[8], b[8], y[8], x[8]; /* Registers A, B, X, and Y. */
diff --git a/sux.c b/sux.c
index 1743fc0..1299432 100644
--- a/sux.c
+++ b/sux.c
@@ -40,11 +40,11 @@ void *run(void *args) {
struct suxthr *thr = (void *)args;
struct sux *cpu = &thr->sx;
uint8_t thread = thr->th;
- uint64_t address = 0;
uint8_t prefix = 0;
uint8_t opcode = 0;
uint8_t esc = 0;
- uint64_t value = 0;
+ union reg address;
+ union reg value;
#if getclk
uint64_t iclk = 0;
#endif
@@ -72,7 +72,8 @@ void *run(void *args) {
gettimeofday(&str[thread], 0);
#endif
for (;;) {
- address = 0;
+ address.u64 = 0;
+ value.u64 = 0;
prefix = addr[cpu->pc[thread]];
if ((prefix & 0x03) != 0x03) {
prefix = 0;
@@ -109,33 +110,35 @@ void *run(void *args) {
pthread_mutex_unlock(&mutex);
#endif
#endif
- address = cpu->pc[thread];
+ address.u64 = cpu->pc[thread];
++cpu->pc[thread];
#if getclk
++iclk;
#endif
- address = get_addr(cpu, &tmpaddr, opcode, prefix, thread);
- value = addr[address];
- /* Unroll Loop by implementing Duff's Device. */
- switch (1 << (prefix >> 4)) {
- case 8:
- value |= (uint64_t)addr[address+7] << 56;
- value |= (uint64_t)addr[address+6] << 48;
- value |= (uint64_t)addr[address+5] << 40;
- value |= (uint64_t)addr[address+4] << 32;
- case 4:
- value |= (uint64_t)addr[address+3] << 24;
- value |= (uint64_t)addr[address+2] << 16;
- case 2:
- value |= (uint64_t)addr[address+1] << 8;
+ if (optype[opcode] != IMPL) {
+ address.u64 = get_addr(cpu, &tmpaddr, opcode, prefix, thread);
+ /* Unroll Loop by implementing Duff's Device. */
+ value.u8[0] = addr[address.u64];
+ switch (1 << (prefix >> 4)) {
+ case 8:
+ value.u8[7] = addr[address.u64+7];
+ value.u8[6] = addr[address.u64+6];
+ value.u8[5] = addr[address.u64+5];
+ value.u8[4] = addr[address.u64+4];
+ case 4:
+ value.u8[3] = addr[address.u64+3];
+ value.u8[2] = addr[address.u64+2];
+ case 2:
+ value.u8[1] = addr[address.u64+1];
+ }
}
#if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
uint64_t operands[3];
- operands[0] = value;
- operands[1] = address;
+ operands[0] = value.u64;
+ operands[1] = address.u64;
operands[2] = tmpaddr;
disasm(cpu, operands, lines, opcode, prefix, thread);
lines+=1;
@@ -148,18 +151,18 @@ void *run(void *args) {
cpu->ps = 0;
break;
case AAB: /* Add Accumulator with carry by B register. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case ADC: /* ADC Immediate. */
case ADC_AB: /* ADC Absolute. */
case ADC_Z: /* ADC Zero Matrix. */
- adc(cpu, value, thread);
+ adc(cpu, value.u64, thread);
break;
case PHB: /* PusH B register to stack. */
case PHP: /* PusH Processor status to stack. */
case PHA: /* PusH Accumulator to stack. */
case PHY: /* PusH Y register to stack. */
case PHX: /* PusH X register to stack. */
- push(cpu, value, opcode, thread);
+ push(cpu, value.u64, opcode, thread);
break;
case TAY: /* Transfer Accumulator to Y. */
case TAX: /* Transfer Accumulator to Y. */
@@ -171,36 +174,36 @@ void *run(void *args) {
case TSX: /* Transfer Stack pointer to X. */
case TBA: /* Transfer B to Accumulator. */
case TXS: /* Transfer X to Stack pointer. */
- transfer(cpu, value, opcode, prefix, thread);
+ transfer(cpu, value.u64, opcode, prefix, thread);
break;
case JMP: /* JMP Absolute. */
case JMP_Z: /* JMP Zero Matrix. */
case JMP_IN: /* JMP Indirect. */
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
break;
case SAB: /* Subtract Accumulator with carry by B register. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case SBC: /* SBC Immediate. */
case SBC_AB: /* SBC Absolute. */
case SBC_Z: /* SBC Zero Matrix. */
- sbc(cpu, value, thread);
+ sbc(cpu, value.u64, thread);
break;
case PLB: /* PuLl B register from stack. */
case PLP: /* PuLl Processor status from stack. */
case PLA: /* PuLl Accumulator from stack. */
case PLY: /* PuLl Y register from stack. */
case PLX: /* PuLl X register from stack. */
- pull(cpu, value, opcode, thread);
+ pull(cpu, value.u64, opcode, thread);
break;
case ABA: /* bitwise And with Accumulator, and B register. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case AND: /* AND Immediate. */
case AND_AB: /* AND Absolute. */
case AND_Z: /* AND Zero Matrix. */
- and(cpu, value, thread);
+ and(cpu, value.u64, thread);
break;
case STT: /* STart Thread. */
- cpu->crt |= value;
+ /*cpu->crt |= value;
for (uint8_t i = 0; i < 7; i++) {
if ((value >> i) & 1) {
address = (uint64_t)addr[tv+(i<<3)]
@@ -213,20 +216,20 @@ void *run(void *args) {
| (uint64_t)addr[tv+7+(i<<3)] << 56;
cpu->pc[i+1] = address;
}
- }
+ }*/
break;
case BPO: /* BPO Absolute. */
case BPO_Z: /* BPO Zero Matrix. */
if (!getflag(N)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case OAB: /* bitwise Or with Accumulator, and B register. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case ORA: /* ORA Immediate. */
case ORA_AB: /* ORA Absolute. */
case ORA_Z: /* ORA Zero Matrix. */
- or(cpu, value, thread);
+ or(cpu, value.u64, thread);
break;
case SEI: /* SEt Interrupt. */
setflag(1, I);
@@ -234,15 +237,15 @@ void *run(void *args) {
case BNG: /* BNG Absolute. */
case BNG_Z: /* BNG Zero Matrix. */
if (getflag(N)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case XAB: /* bitwise Xor with Accumulator, and B register. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case XOR: /* XOR Immediate. */
case XOR_AB: /* XOR Absolute. */
case XOR_Z: /* XOR Zero Matrix. */
- xor(cpu, value, thread);
+ xor(cpu, value.u64, thread);
break;
case CLI: /* CLear Interrupt. */
setflag(0, I);
@@ -250,15 +253,15 @@ void *run(void *args) {
case BCS: /* BCS Absolute. */
case BCS_Z: /* BCS Zero Matrix. */
if (getflag(C)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case LLB: /* Logical shift Left accumulator by B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case LSL: /* LSL Immediate. */
case LSL_AB: /* LSL Absolute. */
case LSL_Z: /* LSL Zero Matrix. */
- lsl(cpu, value, thread);
+ lsl(cpu, value.u64, thread);
break;
case SEC: /* SEt Carry flag.*/
setflag(1, C);
@@ -285,28 +288,28 @@ void *run(void *args) {
case STB_IX: /* STB Indexed Indirect. */
case STA_IY: /* STA Indirect Indexed. */
case STB_IY: /* STB Indirect Indexed. */
- store(cpu, address, &esc, opcode, prefix, thread);
+ store(cpu, address.u64, &esc, opcode, prefix, thread);
step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case BCC: /* BCC Absolute. */
case BCC_Z: /* BCC Zero Matrix. */
if (!getflag(C)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case LRB: /* Logical shift Right accumulator by B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case LSR: /* LSR Immediate. */
case LSR_AB: /* LSR Absolute. */
case LSR_Z: /* LSR Zero Matrix. */
- lsr(cpu, value, thread);
+ lsr(cpu, value.u64, thread);
break;
case ARB: /* Arithmetic shift Right accumulator by B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case ASR: /* ASR Immediate. */
case ASR_AB: /* ASR Absolute. */
case ASR_Z: /* ASR Zero Matrix. */
- asr(cpu, value, thread);
+ asr(cpu, value.u64, thread);
break;
case CLC: /* CLear Carry flag. */
setflag(0, C);
@@ -337,64 +340,64 @@ void *run(void *args) {
case LDA_IX: /* LDA Indexed Indirect. */
case LDB_IY: /* LDB Indirect Indexed. */
case LDA_IY: /* LDA Indirect Indexed. */
- load(cpu, address, &esc, opcode, prefix, thread);
+ load(cpu, address.u64, &esc, opcode, prefix, thread);
break;
case BEQ: /* BEQ Absolute. */
case BEQ_Z: /* BEQ Zero Matrix. */
if (getflag(Z)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case RLB: /* Rotate Left accumulator by B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case ROL: /* ROL Immediate. */
case ROL_AB: /* ROL Absolute. */
case ROL_Z: /* ROL Zero Matrix. */
- rol(cpu, value, thread);
+ rol(cpu, value.u64, thread);
break;
case BNE: /* BNE Absolute. */
case BNE_Z: /* BNE Zero Matrix. */
if (!getflag(Z)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case RRB: /* Rotate Right accumulator by B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case ROR: /* ROR Immediate. */
case ROR_AB: /* ROR Absolute. */
case ROR_Z: /* ROR Zero Matrix. */
- ror(cpu, value, thread);
+ ror(cpu, value.u64, thread);
break;
case BVS: /* BVS Absolute. */
case BVS_Z: /* BVS Zero Matrix. */
if (getflag(V)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case MAB: /* Multiply Accumulator by B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case MUL: /* MUL Immediate. */
case MUL_AB: /* MUL Absolute. */
case MUL_Z: /* MUL Zero Matrix. */
- mul(cpu, value, thread);
+ mul(cpu, value.u64, thread);
break;
case BVC: /* BVC Absolute. */
case BVC_Z: /* BVC Zero Matrix. */
if (!getflag(V)) {
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
}
break;
case DIV: /* DIV Immediate. */
case DAB: /* Divide Accumulator by B. */
case DIV_AB: /* DIV Absolute. */
case DIV_Z: /* DIV Zero Matrix. */
- divd(cpu, value, opcode, thread);
+ divd(cpu, value.u64, opcode, thread);
break;
case CLV: /* CLear oVerflow flag. */
setflag(0, V);
break;
case CAB: /* Compare Accumulator, and B. */
- value = cpu->b[thread]; /* Falls Through. */
+ value.u64 = cpu->b[thread]; /* Falls Through. */
case CPB: /* CPB Immediate. */
case CMP: /* CMP Immediate. */
case CPY: /* CPY Immediate. */
@@ -415,74 +418,67 @@ void *run(void *args) {
case CPB_IX: /* CPB Indexed Indirect. */
case CMP_IY: /* CMP Indirect Indexed. */
case CPB_IY: /* CPB Indirect Indexed. */
- cmp(cpu, value, opcode, thread);
+ cmp(cpu, value.u64, opcode, thread);
break;
case ENT: /* ENd Thread. */
- cpu->crt &= ~value;
+ /* cpu->crt &= ~value;
for (uint8_t i = 0; i < 7; i++)
if ((value >> i) & 1)
- cpu->pc[i+1] = cpu->pc[0]+(i+1);
- break;
- case RTI: /* ReTurn from Interrupt routine. */
- cpu->sp[thread] += 9;
- cpu->ps = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] << (thread << 3);
- cpu->pc[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)];
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] << 8;
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] << 16;
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] << 24;
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] << 32;
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] << 40;
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] << 48;
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 56;
+ cpu->pc[i+1] = cpu->pc[0]+(i+1);*/
break;
case INC: /* INC Accumulator. */
case INB:
case INY:
case INX:
- incr(cpu, value, opcode, thread);
+ incr(cpu, opcode, thread);
break;
case DEC: /* DEC Accumulator. */
case DEB:
case DEY:
case DEX:
- decr(cpu, value, opcode, thread);
+ decr(cpu, opcode, thread);
break;
case JSR_IN: /* JSR Indirect. */
case JSR: /* Jump to SubRoutine. */
case JSL: /* Jump to Subroutine Long. */
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-0] = (uint64_t)cpu->pc[thread] >> (7<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-1] = (uint64_t)cpu->pc[thread] >> (6<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-2] = (uint64_t)cpu->pc[thread] >> (5<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-3] = (uint64_t)cpu->pc[thread] >> (4<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-4] = (uint64_t)cpu->pc[thread] >> (3<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-5] = (uint64_t)cpu->pc[thread] >> (2<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-6] = (uint64_t)cpu->pc[thread] >> (1<<3);
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-7] = (uint64_t)cpu->pc[thread] & (0xFF);
+ value.u64 = cpu->pc[thread];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-0] = value.u8[7];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-1] = value.u8[6];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-2] = value.u8[5];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-3] = value.u8[4];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-4] = value.u8[3];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-5] = value.u8[2];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-6] = value.u8[1];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-7] = value.u8[0];
cpu->sp[thread] -= 8;
- cpu->pc[thread] = address;
+ cpu->pc[thread] = address.u64;
break;
case INC_AB: /* INC Absolute. */
case INC_Z: /* INC Zero Matrix. */
- incm(cpu, address, thread);
+ incm(cpu, address.u64, thread);
step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case NOP: /* No OPeration. */
break;
+ case RTI: /* ReTurn from Interrupt routine. */
+ cpu->sp[thread] +=1;
+ cpu->ps = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread])] << (thread << 3); /* Falls through. */
case RTS: /* ReTurn from Subroutine. */
case RTL: /* ReTurn from subroutine Long. */
cpu->sp[thread] += 8;
- cpu->pc[thread] = (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)] & (0xFF);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] << (1<<3);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] << (2<<3);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] << (3<<3);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] << (4<<3);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] << (5<<3);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] << (6<<3);
- cpu->pc[thread] += (uint64_t)addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-0)] << (7<<3);
+ value.u8[0] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)];
+ value.u8[1] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)];
+ value.u8[2] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)];
+ value.u8[3] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)];
+ value.u8[4] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)];
+ value.u8[5] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)];
+ value.u8[6] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)];
+ value.u8[7] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread] )];
+ cpu->pc[thread] = value.u64;
break;
case DEC_AB: /* DEC Absolute. */
case DEC_Z: /* DEC Zero Matrix. */
- decm(cpu, address, thread);
+ decm(cpu, address.u64, thread);
step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case BRK: /* BReaK. */
@@ -495,38 +491,39 @@ void *run(void *args) {
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
}
- addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> 56;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] = (uint64_t)cpu->pc[thread] >> 48;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-2)] = (uint64_t)cpu->pc[thread] >> 40;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-3)] = (uint64_t)cpu->pc[thread] >> 32;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-4)] = (uint64_t)cpu->pc[thread] >> 24;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-5)] = (uint64_t)cpu->pc[thread] >> 16;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-6)] = (uint64_t)cpu->pc[thread] >> 8;
- addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-7)] = (uint64_t)cpu->pc[thread] & 0xFF;
+ value.u64 = cpu->pc[thread];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-0] = value.u8[7];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-1] = value.u8[6];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-2] = value.u8[5];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-3] = value.u8[4];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-4] = value.u8[3];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-5] = value.u8[2];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-6] = value.u8[1];
+ addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]-7] = value.u8[0];
addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-8)] = (uint64_t)cpu->ps >> (thread << 3);
cpu->sp[thread] -= 9;
setflag(1, I);
if (opcode == BRK) {
- cpu->pc[thread] = (uint64_t)addr[0xFFE0];
- cpu->pc[thread] += (uint64_t)addr[0xFFE1] << 8;
- cpu->pc[thread] += (uint64_t)addr[0xFFE2] << 16;
- cpu->pc[thread] += (uint64_t)addr[0xFFE3] << 24;
- cpu->pc[thread] += (uint64_t)addr[0xFFE4] << 32;
- cpu->pc[thread] += (uint64_t)addr[0xFFE5] << 40;
- cpu->pc[thread] += (uint64_t)addr[0xFFE6] << 48;
- cpu->pc[thread] += (uint64_t)addr[0xFFE7] << 56;
+ value.u8[0] = addr[0xFFE0];
+ value.u8[1] = addr[0xFFE1];
+ value.u8[2] = addr[0xFFE2];
+ value.u8[3] = addr[0xFFE3];
+ value.u8[4] = addr[0xFFE4];
+ value.u8[5] = addr[0xFFE5];
+ value.u8[6] = addr[0xFFE6];
+ value.u8[7] = addr[0xFFE7];
} else {
- cpu->pc[thread] = (uint64_t)addr[0xFFA0]
- | (uint64_t)addr[0xFFA1] << 8
- | (uint64_t)addr[0xFFA2] << 16
- | (uint64_t)addr[0xFFA3] << 24
- | (uint64_t)addr[0xFFA4] << 32
- | (uint64_t)addr[0xFFA5] << 40
- | (uint64_t)addr[0xFFA6] << 48
- | (uint64_t)addr[0xFFA7] << 56;
+ value.u8[0] = addr[0xFFA0];
+ value.u8[1] = addr[0xFFA1];
+ value.u8[2] = addr[0xFFA2];
+ value.u8[3] = addr[0xFFA3];
+ value.u8[4] = addr[0xFFA4];
+ value.u8[5] = addr[0xFFA5];
+ value.u8[6] = addr[0xFFA6];
+ value.u8[7] = addr[0xFFA7];
kbd_rdy &= (uint8_t)~(1 << thread);
}
- break;
+ cpu->pc[thread] = value.u64;
default:
break;
}
diff --git a/sux.h b/sux.h
index 9996ba6..aa0355e 100644
--- a/sux.h
+++ b/sux.h
@@ -37,16 +37,16 @@ extern void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t o
extern void io(uint64_t address, uint8_t *esc);
static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opcode, uint8_t prefix, uint8_t thread) {
- uint64_t address = 0;
- uint64_t value = 0;
+ union reg address;
+ union reg value;
uint8_t tmp = 0;
+ address.u64 = 0;
+ value.u64 = 0;
switch (optype[opcode]) {
case IMPL:
break;
case IMM:
switch (opcode) {
- case TXS:
- break;
case PHB:
case PHP:
case PHA:
@@ -64,12 +64,13 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
case ROR:
case ASR:
case ENT:
- address = cpu->pc[thread];
+ address.u64 = cpu->pc[thread];
++cpu->pc[thread];
break;
default:
- address = cpu->pc[thread];
+ address.u64 = cpu->pc[thread];
cpu->pc[thread]+=(1 << (prefix >> 4));
+ case TXS:
break;
}
break;
@@ -80,23 +81,23 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
case INDX:
case INDY:
tmp = 0;
- address = addr[cpu->pc[thread]];
+ address.u8[0] = addr[cpu->pc[thread]];
/* Unroll Loop by implementing Duff's Device. */
switch ((prefix & 0x0C) >> 2) {
case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
+ address.u8[5] = addr[cpu->pc[thread]+5];++tmp;
+ address.u8[4] = addr[cpu->pc[thread]+4];++tmp;
case 3:
- address |= addr[cpu->pc[thread]+3] << 24;++tmp;
+ address.u8[3] = addr[cpu->pc[thread]+3];++tmp;
case 1:
- address |= addr[cpu->pc[thread]+2] << 16;++tmp;
- address |= addr[cpu->pc[thread]+1] << 8;++tmp;
+ address.u8[2] = addr[cpu->pc[thread]+2];++tmp;
+ address.u8[1] = addr[cpu->pc[thread]+1];++tmp;
case 0:
++tmp;
}
cpu->pc[thread]+=tmp;
#if debug && !bench
- *tmpaddr = address;
+ *tmpaddr = address.u64;
#endif
#if getclk
iclk++;
@@ -104,19 +105,19 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
uint64_t reg = 0;
switch (optype[opcode]) {
case ZMX:
- address += cpu->x[thread];
+ address.u64 += cpu->x[thread];
#if getclk
iclk++;
#endif
break;
case ZMY:
- address += cpu->y[thread];
+ address.u64 += cpu->y[thread];
#if getclk
iclk++;
#endif
break;
case INDX:
- address += cpu->x[thread];
+ address.u64 += cpu->x[thread];
#if getclk
iclk++;
#endif
@@ -133,49 +134,47 @@ static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opco
}
/* Falls Through. */
case IND:
- value = addr[address];
- value |= addr[address+1] << 8;
- value |= addr[address+2] << 16;
- value |= addr[address+3] << 24;
- value |= (uint64_t)addr[address+4] << 32;
- value |= (uint64_t)addr[address+5] << 40;
- value |= (uint64_t)addr[address+6] << 48;
- value |= (uint64_t)addr[address+7] << 56;
+ value.u8[0] = addr[address.u64 ];
+ value.u8[1] = addr[address.u64+1];
+ value.u8[2] = addr[address.u64+2];
+ value.u8[3] = addr[address.u64+3];
+ value.u8[4] = addr[address.u64+4];
+ value.u8[5] = addr[address.u64+5];
+ value.u8[6] = addr[address.u64+6];
+ value.u8[7] = addr[address.u64+7];
#if getclk
iclk++;
#endif
- value += reg;
- address = value;
- value = 0;
- reg = 0;
+ value.u64 += reg;
+ address.u64 = value.u64;
break;
}
break;
case ABS:
tmp = 0;
- address = addr[cpu->pc[thread]];++tmp;
+ address.u8[0] = addr[cpu->pc[thread]];++tmp;
/* Unroll Loop by implementing Duff's Device. */
switch ((prefix & 0x0C) >> 2) {
case 3:
- address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;++tmp;
+ address.u8[7] = addr[cpu->pc[thread]+7];++tmp;
case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
+ address.u8[6] = addr[cpu->pc[thread]+6];++tmp;
+ address.u8[5] = addr[cpu->pc[thread]+5];++tmp;
#if getclk
iclk++;
#endif
case 1:
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
- address |= addr[cpu->pc[thread]+3] << 24;++tmp;
- address |= addr[cpu->pc[thread]+2] << 16;++tmp;
+ address.u8[4] = addr[cpu->pc[thread]+4];++tmp;
+ address.u8[3] = addr[cpu->pc[thread]+3];++tmp;
+ address.u8[2] = addr[cpu->pc[thread]+2];++tmp;
case 0:
- address |= addr[cpu->pc[thread]+1] << 8;++tmp;
+ address.u8[1] = addr[cpu->pc[thread]+1];++tmp;
}
cpu->pc[thread]+=tmp;
break;
}
- return address;
+ return address.u64;
}
inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) {
@@ -395,7 +394,7 @@ 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, uint64_t value, uint8_t opcode, uint8_t thread) {
+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;
@@ -407,7 +406,7 @@ inline void incr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread
setflag(reg >> 63, N);
}
-inline void decr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+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;
@@ -435,19 +434,21 @@ inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode
if (address == CTRL_ADDR) {
io(address, esc);
}
- uint64_t value = addr[address];
+ union reg value;
+ value.u64 = 0;
/* Unroll Loop by implementing Duff's Device. */
+ value.u8[0] = addr[address];
switch (1 << (prefix >> 4)) {
case 8:
- value |= (uint64_t)addr[address+7] << 56;
- value |= (uint64_t)addr[address+6] << 48;
- value |= (uint64_t)addr[address+5] << 40;
- value |= (uint64_t)addr[address+4] << 32;
+ 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 |= addr[address+3] << 24;
- value |= addr[address+2] << 16;
+ value.u8[3] = addr[address+3];
+ value.u8[2] = addr[address+2];
case 2:
- value |= addr[address+1] << 8;
+ value.u8[1] = addr[address+1];
}
switch (opcode) {
case LDB:
@@ -458,7 +459,7 @@ inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode
case LDB_IN:
case LDB_IX:
case LDB_IY:
- cpu->b[thread] = value;
+ cpu->b[thread] = value.u64;
break;
case LDA:
case LDA_AB:
@@ -468,14 +469,14 @@ inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode
case LDA_IN:
case LDA_IX:
case LDA_IY:
- cpu->a[thread] = value;
+ cpu->a[thread] = value.u64;
break;
case LDY:
case LDY_AB:
case LDY_Z:
case LDY_ZX:
case LDY_IN:
- cpu->y[thread] = value;
+ cpu->y[thread] = value.u64;
break;
case LDX:
@@ -483,15 +484,16 @@ inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode
case LDX_Z:
case LDX_ZY:
case LDX_IN:
- cpu->x[thread] = value;
+ cpu->x[thread] = value.u64;
break;
}
- setflag(value == 0, Z);
- setflag(value >> 63, N);
+ setflag(value.u64 == 0, Z);
+ setflag(value.u64 >> 63, N);
}
inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread) {
- uint64_t value;
+ union reg value;
+ value.u64 = 0;
switch (opcode) {
case STB:
case STB_Z:
@@ -500,7 +502,7 @@ inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcod
case STB_IN:
case STB_IX:
case STB_IY:
- value = cpu->b[thread];
+ value.u64 = cpu->b[thread];
break;
case STA:
case STA_Z:
@@ -509,23 +511,23 @@ inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcod
case STA_IN:
case STA_IX:
case STA_IY:
- value = cpu->a[thread];
+ value.u64 = cpu->a[thread];
break;
case STY:
case STY_Z:
case STY_ZX:
case STY_IN:
- value = cpu->y[thread];
+ value.u64 = cpu->y[thread];
break;
case STX:
case STX_Z:
case STX_ZY:
case STX_IN:
- value = cpu->x[thread];
+ value.u64 = cpu->x[thread];
break;
}
- addr[address] = value & 0xFF;
+ addr[address] = value.u8[0];
#if (IO || debug) && !branch
#if keypoll
pthread_mutex_lock(&mutex);
@@ -540,15 +542,15 @@ inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcod
/* Unroll Loop by implementing Duff's Device. */
switch (1 << (prefix >> 4)) {
case 8:
- addr[address+7] = value >> 56;
- addr[address+6] = value >> 48;
- addr[address+5] = value >> 40;
- addr[address+4] = value >> 32;
+ 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 >> 24;
- addr[address+2] = value >> 16;
+ addr[address+3] = value.u8[3];
+ addr[address+2] = value.u8[2];
case 2:
- addr[address+1] = value >> 8;
+ addr[address+1] = value.u8[1];
}
}