summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2021-04-04 12:39:34 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2021-04-04 12:39:34 -0400
commit04cc80c19d763f6de4ef5c3baac5026e5e6969b3 (patch)
tree9407076966196a65faa786518a529f79daeefa76
parent35a18609864470b3dc49f3a9a6cb6ec93e57300d (diff)
- Fixed a bug to do with how SIB operands were parsed
in the assembler. - Rewrote more of the SuB Suite to use the new calling convention. - Fixed a bug to do with SIB operands in the emulator's disassembler. - Made the MMV instruction not require a loop prefix for copying data.
-rw-r--r--.gitignore4
-rw-r--r--assemble.c4
-rw-r--r--disasm.c10
-rw-r--r--programs/sub-suite/libc.s99
-rw-r--r--programs/sub-suite/subasm.s6
-rw-r--r--programs/sub-suite/subeditor.s47
-rw-r--r--sux.h15
7 files changed, 146 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a843a26
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.gitignore
+programs/sub-suite/tmp-stuff/
+*.o
+cisc-0.2
diff --git a/assemble.c b/assemble.c
index 713c297..b51fd5c 100644
--- a/assemble.c
+++ b/assemble.c
@@ -495,6 +495,7 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t
for (; t && i < 2; t = t->next) {
reg = (old_i != i) ? 0 : reg;
got_value = (old_i != i) ? 0 : got_value;
+ is_sib = (old_i != i) ? 0 : is_sib;
if (t->subtype == TOK_IND) {
brack_done = (t->id == TOK_REG) ? 2 : 1;
}
@@ -512,7 +513,7 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t
} else {
break;
}
- is_sib = (!stop_comma && op[i].type && op[i].id == MEM_IND);
+ is_sib = (!stop_comma && op[i].type && (op[i].id == MEM_IND || op[i].id == MEM_RIND));
got_value = 1;
} else {
if (!isvalue) {
@@ -561,6 +562,7 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t
if (!is_sib) {
op[i].id = (got_value) ? MEM_ZMR : op[i].id;
} else if (op[i].id != MEM_SIB) {
+ reg = (op[i].id == MEM_IND) ? 1 : reg;
op[i].type = 1;
op[i].id = MEM_SIB;
/* An invalid scale value was found.
diff --git a/disasm.c b/disasm.c
index 38770da..9e37646 100644
--- a/disasm.c
+++ b/disasm.c
@@ -253,7 +253,7 @@ static int is_2op(uint8_t opcode) {
static void disasm_ortho(struct sux *cpu, WINDOW *w, uint8_t opcode, uint8_t prefix, uint8_t prefix2, uint64_t *value, char *inst_name, char *postfix, operand *op, uint8_t rs, uint8_t thread) {
char opr[2][256];
- char address[2][17];
+ char address[2][18];
char *rind[2] = {"", ""};
char *sign[2] = {"", ""};
char *ind[2] = {"", ""};
@@ -313,7 +313,13 @@ static void disasm_ortho(struct sux *cpu, WINDOW *w, uint8_t opcode, uint8_t pre
}
}
}
- sprintf(idx[i], "%s%s%s%s", scale[i], rind[0], (op[i].rind[1] != 0xFF) ? "+" : "", rind[1]);
+
+ if (op[i].rind[1] == 0xFF) {
+ rind[1] = (op[i].id == MEM_SIB) ? rind[0] : rind[1];
+ rind[0] = (op[i].id == MEM_SIB) ? "" : rind[0];
+ }
+
+ sprintf(idx[i], "%s%s%s%s", rind[0], (op[i].rind[1] != 0xFF) ? "+" : "", scale[i], rind[1]);
switch (op[i].id) {
case MEM_AINDR:
case MEM_AIND :
diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s
index b34d2d3..3de1094 100644
--- a/programs/sub-suite/libc.s
+++ b/programs/sub-suite/libc.s
@@ -411,6 +411,60 @@ free:
; Caller preserved registers: D, S, F.
; Callee preserved registers: B.
+;memcpy:
+;; inc step ;
+; phb.q ; Preserve B.
+; phx.q ; Preserve X.
+; xor b, b ; Reset B.
+; mov a, f ; Get the size.
+; and #7 ; Get the size, mod 8.
+; mov x, f ; Preserve the size.
+; lsr f, #3 ; Divide the size by 8.
+; beq @rem ; The quotient is zero, so copy the remaining number of bytes.
+;@loop:
+; mov.q (d+8*b), (s+8*b) ; Copy 8 bytes from the source, into the destination.
+; inb ; Increment the counter.
+; cmp b, f ; Is the counter the same as the size?
+; bne @loop ; No, so keep looping.
+;@rem:
+; lsl f, #3 ; Multiply the quotient by 8.
+; cmp #0 ; Is the remainder zero?
+; beq @end ; Yes, so we're done.
+; lea b, 8 ; No, so set our offset to 8.
+; sub b, a ; Subtract 8 by the remainder.
+; and #0 ; Reset A.
+; dec ; Set the bitmask to -1.
+; lsl b, #3 ; Multiply the offset by 8.
+; lsr b ; Shift the bitmask right by the offset.
+; mov.q b, (s+f) ; Get 8 bytes from the source.
+; xor.q b, (d+f) ; Mask out the destination bytes.
+; and b ; Get The masked source.
+; xor.q (d+f), a ; Copy the remaining bytes from the source, into the destination.
+;@end:
+; mov f, x ; Restore the size.
+; mov a, d ; Set the return value to the destination pointer.
+; plx.q ; Restore X.
+; plb.q ; Restore B.
+; rts ; End of memcpy.
+
+
+;memcpy:
+; phb.q ; Preserve B.
+; phx.q ; Preserve X.
+; phy.q ; Preserve Y.
+; mov b, f ; Get the size.
+; mov x, d ; Get the destination.
+; mov y, s ; Get the source.
+; txa ; Set the return value to the destination pointer.
+;@copy:
+; mmv.r ; Copy the size bytes from the source, into the destination.
+;@end:
+; ply.q ; Restore Y.
+; plx.q ; Restore X.
+; plb.q ; Restore B.
+; rts ; End of memcpy.
+
+
memcpy:
phb.q ; Preserve B.
xor b, b ; Reset B.
@@ -433,6 +487,51 @@ memcpy:
; Caller preserved registers: D, S, F.
; Callee preserved registers: B.
+;memset:
+;; inc step ;
+; phb.q ; Preserve B.
+; phx.q ; Preserve X.
+; lea b, 8 ; Set the loop counter to 8.
+; psh s ; Get the constant.
+;@const_loop:
+; lsl s, #8 ; Make room for the next byte.
+; mov s, (sp+1) ; Get the next byte.
+; deb ; Decrement the loop counter.
+; bne @const_loop ; The counter is non zero, so keep looping.
+; ins ; Clean up the frame.
+;@init:
+; mov a, f ; Get the size.
+; and #7 ; Get the size, mod 8.
+; mov x, f ; Preserve the size.
+; lsr f, #3 ; Divide the size by 8.
+; beq @rem ; The quotient is zero, so copy the remaining number of bytes.
+;@loop:
+; mov.q (d+8*b), s ; Set all 8 destination bytes, to the constant value.
+; inb ; Increment the counter.
+; cmp b, f ; Is the counter the same as the size?
+; bne @loop ; No, so keep looping.
+;@rem:
+; lsl f, #3 ; Multiply the quotient by 8.
+; cmp #0 ; Is the remainder zero?
+; beq @end ; Yes, so we're done.
+; lea b, 8 ; No, so set our offset to 8.
+; sub b, a ; Subtract 8 by the remainder.
+; and #0 ; Reset A.
+; dec ; Set the bitmask to -1.
+; lsl b, #3 ; Multiply the offset by 8.
+; lsr b ; Shift the bitmask right by the offset.
+; mov.q b, s ; Get 8 bytes from the constant value.
+; xor.q b, (d+f) ; Mask out the destination bytes.
+; and b ; Get The masked source.
+; xor.q (d+f), a ; Copy the remaining bytes from the source, into the destination.
+;@end:
+; mov f, x ; Restore the size.
+; mov a, d ; Set the return value to the destination pointer.
+; plx.q ; Restore X.
+; plb.q ; Restore B.
+; rts ; End of memset.
+
+
memset:
phb.q ; Preserve B.
xor b, b ; Reset B.
diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s
index 56d13c2..ba8d2fb 100644
--- a/programs/sub-suite/subasm.s
+++ b/programs/sub-suite/subasm.s
@@ -139,8 +139,10 @@ subasm:
mov s, (s) ; Get the command ID.
cmp s, #7 ; Is the command ID greater than the command count?
bcs @end ; Yes, so we're done.
- lsl s, #1 ; No, so multiply the command ID by two.
- lea.w s, (cmd_srt+s) ; Get the pointer, from the command subroutine table.
+; lsl s, #1 ; No, so multiply the command ID by two.
+; lea.w s, (cmd_srt+s) ; Get the pointer, from the command subroutine table.
+ lea b, cmd_srt ; No, so get the address of the command subroutine table.
+ mov.w s, (b+2*s) ; Get the pointer, from the command subroutine table.
and #0 ; Reset A.
tab ; Reset B.
jsr s ; Run the command's subroutine.
diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s
index 83fe179..e44feb3 100644
--- a/programs/sub-suite/subeditor.s
+++ b/programs/sub-suite/subeditor.s
@@ -268,12 +268,11 @@ cmd_cpy:
sta scr_trow ; Save it for later.
lea d, (buffer) ; Get the screen buffer.
mov s, y ; Get the cursor index.
- lea f, 1 ; Set the decrement offset to the left flag.
- jsr find_end ; Find the end of the line.
- div #maxcol+1 ; Get the ending line.
- ldb scr_str ; Has the screen been scrolled?
- beq @start ; No, so don't subtract the screen's starting point from the line number.
-@offset:
+; jsr find_end ; Find the end of the line.
+; mov f, a ; Save the end of the line.
+; div #maxcol+1 ; Get the ending line.
+ jsr get_endrow ; Get the ending line.
+; inc step ;
sub scr_str ; Offset the row position, back by the screen's starting point.
@start:
sta scr_row ; Set the row position to the end of the line.
@@ -361,24 +360,21 @@ find_end:
phb.q ; Preserve B.
phx.q ; Preserve X.
phy.q ; Preserve Y.
- phe.q ; Preserve E.
mov a, s ; Set the loop counter.
div #maxcol+1 ; Get the row position.
tay ; Save the row position.
mov b, d ; Preserve the string pointer.
mov x, s ; Preserve the cursor position.
mov d, a ;
- xor s, s ; Reset S.
@loop:
- inc d ; Increment the line.
- mov e, d ; Save the line.
- jsr getbit ; Get the linewrap bit.
- mov d, e ; Get the line.
- cmp #1 ; Is this the end of the line?
- beq @loop ; No, so keep looping.
-@loop2_1:
- mov a, d ; Get the ending row position.
- sub a, f ; Decrement the row position by the offset.
+ xor s, s ; Reset S.
+ iny ; Increment the line.
+ mov d, y ; Get the line.
+ jsr getbit ; Is this the end of the line?
+ bne @loop ; No, so keep looping.
+@loop2_init:
+ tya ; Get the ending row position.
+ dec ; Decrement the row position.
mul #maxcol+1 ; Get the loop counter.
cmp a, x ; Is the new loop counter less than the old loop counter?
mcc a, x ; Set the loop counter to the old loop counter if so.
@@ -389,7 +385,6 @@ find_end:
cmp (d+a-1), #0 ; Did we hit the null terminator?
bne @loop2 ; No, so keep looping.
@end:
- ple.q ; Restore E.
ply.q ; Restore Y.
plx.q ; Restore X.
plb.q ; Restore B.
@@ -445,7 +440,6 @@ printc:
@update1:
lea d, (buffer) ; Get the screen buffer.
mov s, y ; Get the cursor index.
- lea f, 1 ; Set the decrement offset to one.
jsr get_endrow ; Get the ending line.
mov d, a ;
mov s, scr_trow ; Get the current row position.
@@ -635,7 +629,6 @@ back:
sta scr_trow ;
lea d, (buffer) ; Get the screen buffer.
mov s, y ; Get the cursor index.
- lea f, 0 ; Set the decrement offset to zero.
jsr get_endrow ; Get the ending line.
sta scr_row ; Set our row position to the end of the line.
@find_st:
@@ -664,7 +657,6 @@ back:
@find_end:
lea d, (buffer) ; Get the screen buffer.
mov s, y ; Get the cursor index.
- lea f, 1 ; Set the decrement offset to one.
jsr get_endrow ; Yes, so Get the ending line.
mov d, a ;
mov s, scr_trow ; Get the current row position.
@@ -890,9 +882,7 @@ shftln:
cmp s, f ; No, but is the cursor position greater than, or equal to the shift length?
bcc @end ; No, so we're done.
@find_end:
- lea f, 1 ; Set the decrement offset to the left flag.
jsr find_end ; Find the end of the line.
- mov f, e ; Get the shift length.
sub a, c ; Decrement the old end position, if the left flag is set.
tab ; Save the old end position for later.
mov a, f ; Get the shift length.
@@ -920,9 +910,13 @@ shftln:
mov a, bp ; Get the new end position.
div #maxcol+1 ; Get the new ending line.
mov e, a ; Save the ending line.
+ mov r11, f ; Get the shift length.
xor f, f ; Reset F.
and c, c ; Is the left flag set?
meq f, b ; Save the remainder of the ending line if not.
+; div #maxcol+1 ; Get the line length.
+; dec ; Decrement the line length.
+; mov bp, a ; Save the line length.
tya ; Get the cursor position.
div #maxcol+1 ; Get the cursor line.
mov bp, a ; Save the cursor line.
@@ -933,16 +927,15 @@ shftln:
div #maxcol+1 ; Get the old ending line.
cmp bp, a ; Is the cursor line greater than, or equal to the old ending line?
mcs a, bp ; Get the cursor line if so.
- inc ; Increment the line.
+ cmp r11, #maxcol+1 ; Is the shift length greater than, or equal to the max column count?
+ adc #0 ; Increment the starting line if so.
and c, c ; Is the left flag set?
mne a, e ; Set the ending line to the new ending line if so.
tab ; Save the ending line.
and c, c ; Is the left flag set?
bne @inc ; Yes, so increment the starting line.
cmp y, b ; No, but is the starting line less than the ending line?
- bcs @loop ; No, so don't increment.
- iny ; Yes, so increment the starting line.
- bra @getbit ; Get the bit.
+ bcc @inc ; Yes, so increment the starting line.
@loop:
xor s, s ; Reset S.
cmp y, b ; Is the current line greater than the ending line?
diff --git a/sux.h b/sux.h
index 44794f8..f2c4227 100644
--- a/sux.h
+++ b/sux.h
@@ -19,7 +19,7 @@
#define STEP_ADDR 0x110
#define CURSES_BACKSPACE 0x7F
-#define copy64 1
+#define copy64
extern uint8_t kbd_rdy;
extern uint8_t dbg_print_per_inst;
@@ -338,7 +338,7 @@ static int is_ind(uint8_t type) {
}
static void *memcopy(void *restrict dst, const void *restrict src, unsigned int n) {
- #if copy64
+ #ifdef copy64
uint64_t *d = dst;
const uint64_t *s = src;
unsigned int r = n % 8;
@@ -348,7 +348,7 @@ static void *memcopy(void *restrict dst, const void *restrict src, unsigned int
const uint8_t *s = src;
#endif
for (; n; *d++ = *s++, n--);
- #if copy64
+ #ifdef copy64
if (r) {
uint64_t mask = (-(uint64_t)1 >> ((8 - r) * 8));
*d = (*d & ~mask) | (*s & mask);
@@ -609,6 +609,7 @@ static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t opcode, uint8
uint64_t tmp_val = 0;
if (is_rind) {
for (int j = 0; j < 2 && op[i].rind[j] != 0xFF; j++) {
+ int is_index = ((!j && op[i].rind[1] == 0xFF) || j);
uint64_t reg;
switch (op[i].rind[j]) {
case REG_A : reg = cpu->a; break;
@@ -628,11 +629,11 @@ static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t opcode, uint8
case REG_R14: reg = cpu->r14; break;
case REG_R15: reg = cpu->r15; break;
}
+
+ reg *= (is_index && op[i].id == MEM_SIB) ? op[i].scale+1 : 1;
tmp_val += reg;
}
- if (op[i].id == MEM_SIB) {
- tmp_val *= op[i].scale+1;
- } else if (addr_size != 0xFF) {
+ if (addr_size != 0xFF) {
switch (addr_size) {
case 0: value[i] = (int8_t )value[i]; break;
case 1: value[i] = (int16_t)value[i]; break;
@@ -1361,7 +1362,7 @@ static /*inline*/ void exec_ext_inst(struct sux *cpu, uint8_t opcode, uint8_t pr
bit_test(cpu, cpu->a, value, thread);
break;
case MMV_IMP: /* Memory MoVe. */
- cpu->b = mem_move(cpu, cpu->b, cpu->x, cpu->y, 0, size, thread);
+ cpu->b = mem_move(cpu, cpu->b, cpu->x, cpu->y, 1, size, thread);
break;
case SWP_A : /* SWaP lower half, with upper half. */
cpu->a = swap(cpu, cpu->a, size, thread);