diff options
-rw-r--r-- | opcode.c | 4 | ||||
-rw-r--r-- | opcode.h | 7 | ||||
-rw-r--r-- | sux.c | 239 | ||||
-rw-r--r-- | sux.h | 134 |
4 files changed, 195 insertions, 189 deletions
@@ -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); @@ -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. */ @@ -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; } @@ -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]; } } |