diff options
Diffstat (limited to 'sux.h')
-rw-r--r-- | sux.h | 159 |
1 files changed, 79 insertions, 80 deletions
@@ -6,6 +6,8 @@ #if bench #include <sys/time.h> +#include <signal.h> +#include <math.h> #endif #include <curses.h> @@ -17,6 +19,8 @@ #define STEP_ADDR 0x110 #define CURSES_BACKSPACE 0x7F +#define copy64 1 + extern uint8_t kbd_rdy; extern WINDOW *scr; @@ -50,9 +54,21 @@ extern void io(uint64_t address, uint8_t rw); extern void init_scr(); -static inline void *memcopy(void *dst, void *src, size_t n) { +static void *memcopy(void *dst, void *src, unsigned int n) { + #if copy64 + uint64_t *d = dst, *s = src; + unsigned int r = n % 8; + n /= 8; + #else uint8_t *d = dst, *s = src; + #endif for (; n; *d++ = *s++, n--); + #if copy64 + if (r) { + uint64_t mask = (-(uint64_t)1 >> ((8 - r) * 8)); + *d = (*d & ~mask) | (*s & mask); + } + #endif return dst; } @@ -242,45 +258,37 @@ static inline uint64_t get_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, return address; } -static inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = cpu->a+value+getflag(C); + +static inline uint64_t adc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = reg+value+getflag(C); setflag(sum == 0, Z); setflag((sum >> 63), N); - setflag(((cpu->a^value) >> 63) && ((cpu->a^sum) >> 63), V); + setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V); setflag((sum < value), C); - cpu->a = sum; + return sum; } -static inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = cpu->a-value-!getflag(C); +static inline uint64_t sbc(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = reg-value-!getflag(C); setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(((cpu->a^value) >> 63) && ((cpu->a^sum) >> 63), V); + setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V); setflag((sum > value), C); - cpu->a = sum; + return sum; } -static inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t prefix, uint8_t thread) { - uint64_t reg; +static inline uint64_t transfer(struct sux *cpu, uint64_t src, uint64_t value, uint8_t opcode, uint8_t prefix, uint8_t thread) { switch (opcode) { - case TBA_IMP: cpu->a = cpu->b; reg = cpu->a; break; - case TXA_IMP: cpu->a = cpu->x; reg = cpu->a; break; - case TYA_IMP: cpu->a = cpu->y; reg = cpu->a; break; - case TAB_IMP: cpu->b = cpu->a; reg = cpu->b; break; - case TAY_IMP: cpu->y = cpu->a; reg = cpu->y; break; - case TXY_IMP: cpu->y = cpu->x; reg = cpu->y; break; - case TAX_IMP: cpu->x = cpu->a; reg = cpu->x; break; - case TYX_IMP: cpu->x = cpu->y; reg = cpu->x; break; - case TSX_IMP: cpu->x = cpu->sp & 0xFFFF; cpu->x = cpu->stk_st << 16; break; - case TXS_IMM: cpu->sp = cpu->x; + case TXS_IMM: if (prefix == 0x13 && (value == thread+1 || value > 8)) { cpu->stk_st = value & 0xFF; cpu->stk_st += value << 16; cpu->pc+=2; } - break; + default: break; } - setflag(reg == 0, Z); - setflag(reg >> 63, N); + setflag(src == 0, Z); + setflag(src >> 63, N); + return src; } static inline void push(struct sux *cpu, uint64_t value, uint8_t size, uint8_t thread) { @@ -296,83 +304,82 @@ static inline uint64_t pull(struct sux *cpu, uint8_t size, uint8_t thread) { return value; } -static inline void and(struct sux *cpu, uint64_t value, uint8_t thread) { - cpu->a &= value; - setflag(cpu->a == 0, Z); - setflag(cpu->a >> 63, N); +static inline uint64_t and(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + reg &= value; + setflag(reg == 0, Z); + setflag(reg >> 63, N); + return reg; } -static inline void or(struct sux *cpu, uint64_t value, uint8_t thread) { - cpu->a |= value; - setflag(cpu->a == 0, Z); - setflag(cpu->a >> 63, N); +static inline uint64_t or(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + reg |= value; + setflag(reg == 0, Z); + setflag(reg >> 63, N); + return reg; } -static inline void xor(struct sux *cpu, uint64_t value, uint8_t thread) { - cpu->a ^= value; - setflag(cpu->a == 0, Z); - setflag(cpu->a >> 63, N); +static inline uint64_t xor(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + reg ^= value; + setflag(reg == 0, Z); + setflag(reg >> 63, N); + return reg; } -static inline void lsl(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = (value < 64) ? cpu->a << value : 0; +static inline uint64_t lsl(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = (value < 64) ? reg << value : 0; setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(cpu->a >> (64-value), C); - cpu->a = sum; + setflag(reg >> (64-value), C); + return sum; } -static inline void lsr(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = (value < 64) ? cpu->a >> value : 0; +static inline uint64_t lsr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = (value < 64) ? reg >> value : 0; setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(cpu->a & 1, C); - cpu->a = sum; + setflag(reg & 1, C); + return sum; } -static inline void asr(struct sux *cpu, uint64_t value, uint8_t thread) { - uint8_t sign = cpu->a >> 63; - uint64_t sum = (value < 64) ? (cpu->a >> value) | ((uint64_t)sign << 63) : 0; +static inline uint64_t asr(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint8_t sign = reg >> 63; + uint64_t sum = (value < 64) ? (reg >> value) | ((uint64_t)sign << 63) : 0; setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(cpu->a & 1, C); - cpu->a = sum; + setflag(reg & 1, C); + return sum; } -static inline void rol(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = cpu->a << value; +static inline uint64_t rol(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = reg << value; sum |= getflag(C); setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(cpu->a >> (uint64_t)(64-value), C); - cpu->a = sum; + setflag(reg >> (uint64_t)(64-value), C); + return sum; } -static inline void ror(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = cpu->a >> value; +static inline uint64_t ror(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = reg >> value; sum |= (uint64_t)getflag(C) << (uint64_t)(64-value); setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(cpu->a & 1, C); - cpu->a = sum; + setflag(reg & 1, C); + return sum; } -static inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) { - uint64_t sum = cpu->a*value; - cpu->a = sum; + +static inline uint64_t mul(struct sux *cpu, uint64_t reg, uint64_t value, uint8_t thread) { + uint64_t sum = reg*value; setflag(sum == 0, Z); setflag(sum >> 63, N); - setflag(!((cpu->a^value) >> 63) && ((cpu->a^sum) >> 63), V); + setflag(!((reg^value) >> 63) && ((reg^sum) >> 63), V); + return sum; } -static inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) { - uint64_t sum = cpu->a/value; - if (opcode != DIV_B) { - cpu->b = cpu->a % value; - } else { - value = cpu->b; - cpu->x = cpu->a % value; - } - cpu->a = sum; +static inline uint64_t divd(struct sux *cpu, uint64_t reg, uint64_t value, uint64_t *rem, uint8_t thread) { + uint64_t sum = reg/value; + *rem = reg % value; setflag(sum == 0, Z); setflag((sum >> 63), N); + return sum; } static inline void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t thread) { uint64_t sum = reg-value; @@ -384,11 +391,7 @@ static inline void cmp(struct sux *cpu, uint64_t value, uint64_t reg, uint8_t th /* 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--; - } + reg += (inc) ? 1 : -1; setflag(reg == 0, Z); setflag(reg >> 63, N); return reg; @@ -399,11 +402,7 @@ static inline void idm(struct sux *cpu, uint64_t address, uint8_t prefix, uint8_ uint8_t size = (1 << ((prefix >> 4) & 3))-1; uint64_t value; value = read_value(cpu, 0, address, size, 1, 0); - if (inc) { - value++; - } else { - value--; - } + value += (inc) ? 1 : -1; uint8_t sign = 0; switch ((prefix >> 4) & 3) { default: sign = 7; break; |