diff options
Diffstat (limited to 'sux.h')
-rw-r--r-- | sux.h | 259 |
1 files changed, 77 insertions, 182 deletions
@@ -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 |