diff options
Diffstat (limited to 'sux.c')
-rw-r--r-- | sux.c | 239 |
1 files changed, 118 insertions, 121 deletions
@@ -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; } |