From 04cc80c19d763f6de4ef5c3baac5026e5e6969b3 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sun, 4 Apr 2021 12:39:34 -0400 Subject: - 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. --- .gitignore | 4 ++ assemble.c | 4 +- disasm.c | 10 ++++- programs/sub-suite/libc.s | 99 ++++++++++++++++++++++++++++++++++++++++++ programs/sub-suite/subasm.s | 6 ++- programs/sub-suite/subeditor.s | 47 +++++++++----------- sux.h | 15 ++++--- 7 files changed, 146 insertions(+), 39 deletions(-) create mode 100644 .gitignore 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); -- cgit v1.2.3-13-gbd6f