summaryrefslogtreecommitdiff
path: root/sux.h
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-09-18 14:49:07 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-09-18 14:49:07 -0400
commiteea04e3327972f052dcfb8ae0854b77f87d3d52f (patch)
treee6c65aad43cb65eb152dc55fba1eb13efffdf7f2 /sux.h
parent385a621b9487456c3167f204b02cb0ea0752191d (diff)
- Added support for structs, and unions to the
emulator's assembler. - Make the symbol table a doublely linked list, in both ways. - Optimized the memcopy() function. - Changed the benchmark timing, to now use a timer, and stops once the timer reaches zero. When the timer hits zero, it sends SIGALRM to the main function, which tells the emulator that the benchmark is done.
Diffstat (limited to 'sux.h')
-rw-r--r--sux.h159
1 files changed, 79 insertions, 80 deletions
diff --git a/sux.h b/sux.h
index 5abb29c..2432322 100644
--- a/sux.h
+++ b/sux.h
@@ -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;