summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--disasm.c7
-rw-r--r--sux.h33
-rw-r--r--test/fib.s3
-rw-r--r--test/nop.s8
4 files changed, 40 insertions, 11 deletions
diff --git a/disasm.c b/disasm.c
index 4a39c4f..43f78db 100644
--- a/disasm.c
+++ b/disasm.c
@@ -51,10 +51,7 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint
case IMM :
case REL : addrsize = (1 << rs)-1; break;
}
-
- for (uint8_t i = 0; i < addrsize+1; i++) {
- mask.u8[i] = (i == addrsize && addrsize != 0xFF) ? 0x7F : 0xFF;
- }
+ mask.u64 = (-(uint64_t)1 >> ((7 - addrsize) * 8));
value = read_value(cpu, 0, cpu->pc, addrsize, 0, 0);
if ((prefix >> 6) == 1 || (prefix >> 6) == 2 || optype[opcode] == REL) {
switch (addrsize) {
@@ -67,7 +64,7 @@ void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint
case 6 :
case 7 : sign = ((int64_t)value < 0) ? "-" : "+"; break;
}
- value &= mask.u64;
+ value = (sign[0] == '-') ? (~value + 1) & mask.u64 : value;
}
switch (optype[opcode]) {
case BREG:
diff --git a/sux.h b/sux.h
index f3eb222..5abb29c 100644
--- a/sux.h
+++ b/sux.h
@@ -49,6 +49,13 @@ extern int get_key(WINDOW *scr);
extern void io(uint64_t address, uint8_t rw);
extern void init_scr();
+
+static inline void *memcopy(void *dst, void *src, size_t n) {
+ uint8_t *d = dst, *s = src;
+ for (; n; *d++ = *s++, n--);
+ return dst;
+}
+
static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
#if (IO || debug) && !branch
#if keypoll
@@ -61,18 +68,34 @@ static inline uint64_t read_value(struct sux *cpu, uint64_t reg, uint64_t addres
pthread_mutex_unlock(&mutex);
#endif
#endif
- size = (size > 7) ? 7 : size;
- uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8));
#if getclk
cpu->clk += inc_clk;
#endif
- return (reg & ~mask) | (*(uint64_t *)(addr+address) & mask);
+ size = (size > 7) ? 7 : size;
+ #if 1
+ if (size < 7) {
+ uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8));
+ return (reg & ~mask) | (*(uint64_t *)(addr+address) & mask);
+ } else {
+ return *(uint64_t *)(addr+address);
+ }
+ #else
+ return *(uint64_t *)memcopy(&reg, addr+address, size+1);
+ #endif
}
static inline void write_value(struct sux *cpu, uint64_t value, uint64_t address, uint8_t size, uint8_t inc_clk, uint8_t check_io) {
size = (size > 7) ? 7 : size;
- uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8));
- *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask);
+ #if 1
+ if (size < 7) {
+ uint64_t mask = (-(uint64_t)1 >> ((7 - size) * 8));
+ *(uint64_t *)(addr+address) = (*(uint64_t *)(addr+address) & ~mask) | (value & mask);
+ } else {
+ *(uint64_t *)(addr+address) = value;
+ }
+ #else
+ memcopy(addr+address, &value, size+1);
+ #endif
#if (IO || debug) && !branch
#if keypoll
pthread_mutex_lock(&mutex);
diff --git a/test/fib.s b/test/fib.s
index 65912ad..e2c2e0f 100644
--- a/test/fib.s
+++ b/test/fib.s
@@ -63,6 +63,9 @@ fib2:
bcs start2 ; Start all over again, if the carry flag was set.
bra fib2 ; Otherwise, keep looping.
+
+.org $FFC0
+.qword init
; Set up the thread vectors.
.org $FF50
.qword init2
diff --git a/test/nop.s b/test/nop.s
index 8d0d75d..948fd02 100644
--- a/test/nop.s
+++ b/test/nop.s
@@ -1,3 +1,4 @@
+.org $8000
reset:
cps
nop_loop:
@@ -7,6 +8,11 @@ nop_loop:
nop
nop
nop
+ nop
+ nop
bra nop_loop
+
+.org $FFC0
+.qword reset
a
-done
+d