From 35a18609864470b3dc49f3a9a6cb6ec93e57300d Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 25 Feb 2021 12:43:11 -0500 Subject: - Implemented the multiply expression into the assembler. - Implemented support for the SIB addressing mode into the assembler. SIB is short for "Scale Index, and Base", and works much like x86's version of SIB (scale*index+base), although my version supports any scale value between 1, and 256. - Redid the line shifting routine in SuBEditor. It now uses memcpy, and memset to do that, and also supports shifting the line left, or right by any number of characters. --- asmmon.h | 1 + assemble.c | 78 +- disasm.c | 16 +- lexer.c | 13 +- lexer.h | 2 + programs/sub-suite/lexer.s | 48 +- programs/sub-suite/libc.s | 91 ++- programs/sub-suite/subasm.s | 12 +- programs/sub-suite/subeditor.s | 429 ++++++++-- programs/sub-suite/subsuite.s | 2 +- programs/sub-suite/tmp-stuff/cmd_cpy.c | 33 - programs/sub-suite/tmp-stuff/free-new.s | 143 ---- programs/sub-suite/tmp-stuff/free-old.s | 200 ----- programs/sub-suite/tmp-stuff/print_char.s | 147 ---- programs/sub-suite/tmp-stuff/shift_line.c | 85 -- programs/sub-suite/tmp-stuff/subeditor-new.s | 1119 -------------------------- programs/sub-suite/tmp-stuff/test-size.s | 59 -- programs/sub-suite/utils.s | 91 +-- test/ortho.s | 1 + 19 files changed, 569 insertions(+), 2001 deletions(-) delete mode 100644 programs/sub-suite/tmp-stuff/cmd_cpy.c delete mode 100644 programs/sub-suite/tmp-stuff/free-new.s delete mode 100644 programs/sub-suite/tmp-stuff/free-old.s delete mode 100644 programs/sub-suite/tmp-stuff/print_char.s delete mode 100644 programs/sub-suite/tmp-stuff/shift_line.c delete mode 100644 programs/sub-suite/tmp-stuff/subeditor-new.s delete mode 100644 programs/sub-suite/tmp-stuff/test-size.s diff --git a/asmmon.h b/asmmon.h index 29697e5..beda687 100644 --- a/asmmon.h +++ b/asmmon.h @@ -159,6 +159,7 @@ enum pre_token { PTOK_EQU, PTOK_PLUS, PTOK_MINUS, + PTOK_ASTRSK, PTOK_GT, PTOK_LT, PTOK_PIPE, diff --git a/assemble.c b/assemble.c index a3791d3..713c297 100644 --- a/assemble.c +++ b/assemble.c @@ -120,13 +120,20 @@ uint64_t get_val(expr *tree, uint64_t addr, uint8_t size, int depth, uint8_t dbg uint64_t expr_val = 0; int type; - int is_start = (!depth && tree->left && tree->right == NULL); + int has_lvalue = (tree && tree->left != NULL); + int has_rvalue = (tree && tree->right != NULL); - if (tree->left) { + int is_start = (!depth && has_lvalue && !has_rvalue); + + if (tree == NULL) { + return 0; + } + + if (has_lvalue) { lvalue = get_val(tree->left, addr, size, depth+1, dbg); } - if (tree->right) { + if (has_rvalue) { rvalue = get_val(tree->right, addr, size, depth+1, dbg); } @@ -141,9 +148,10 @@ uint64_t get_val(expr *tree, uint64_t addr, uint8_t size, int depth, uint8_t dbg case EXPR_SYM: value = (tree->value.sym) ? tree->value.sym->val : addr; break; case EXPR_PLUS: value = lvalue + rvalue; break; case EXPR_MINUS: (is_start) ? (value = -lvalue) : (value = lvalue - rvalue); break; - case EXPR_OR: value = lvalue | rvalue; break; - case EXPR_LSHFT: value = lvalue << rvalue; break; - case EXPR_RSHFT: value = lvalue >> rvalue; break; + case EXPR_MUL : value = (has_rvalue) ? lvalue * rvalue : lvalue; break; + case EXPR_OR : value = (has_rvalue) ? lvalue | rvalue : lvalue; break; + case EXPR_LSHFT : value = (has_rvalue) ? lvalue << rvalue : lvalue; break; + case EXPR_RSHFT : value = (has_rvalue) ? lvalue >> rvalue : lvalue; break; case EXPR_LOW: case EXPR_HIGH: value = lvalue; @@ -403,6 +411,7 @@ int is_value(expr *e, expr **found) { if (e == NULL) { return 0; } + switch (e->type) { case EXPR_HEX : case EXPR_DEC : @@ -414,11 +423,8 @@ int is_value(expr *e, expr **found) { } return 1; default: - if (e->left) { - return is_value(e->left, found); - } - if (e->right) { - return is_value(e->right, found); + if ((e->left && is_value(e->left, found)) || (e->right && is_value(e->right, found))) { + return 1; } break; } @@ -428,6 +434,27 @@ int is_value(expr *e, expr **found) { return 0; } +expr *find_expr(expr *tree, int type) { + if (tree != NULL) { + expr *left = NULL; + expr *right = NULL; + + if (tree->type == type) { + return tree; + } + if (tree->left) { + left = find_expr(tree->left, type); + } + if (tree->right) { + right = find_expr(tree->right, type); + } + if (left || right) { + return (left) ? left : right; + } + } + return NULL; +} + token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t dbg) { uint8_t op_type; uint8_t op_inst; @@ -475,13 +502,13 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t case TOK_EXPR: isvalue = is_value(t->expr, NULL); if (!got_value) { - expr *e = t->expr; + expr *e = find_expr(t->expr, EXPR_MUL); if (isvalue) { if (expr_type == 0xFF && e) { - expr_type = (e->right) ? e->right->type : e->type; + expr_type = e->type; } stop_comma = (expr_type != EXPR_MUL); - value = get_val(e, address, (rs != 0xFF) ? rs : 0, 0, dbg); + value = get_val(t->expr, address, (rs != 0xFF) ? rs : 0, 0, dbg); } else { break; } @@ -507,8 +534,6 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t if (old_i != i) { op[i].type = 1; /* Set type to memory. */ op[i].id = (t->id == TOK_MEM) ? t->type : 0xFF; - op[i].id = (is_sib) ? MEM_SIB : op[i].id; - op[i].scale = (is_sib) ? value : op[i].scale; old_i = i; } else { if (!op[i].type && !is_sib) { @@ -528,12 +553,26 @@ token *get_operands(token *t, operand *op, uint64_t address, uint8_t rs, uint8_t old_i = i; } else { if (op[i].type == 1) { - if (op[i].id == MEM_IND) { + if (op[i].id == MEM_IND && !is_sib) { op[i].id = ((!brack_done || brack_done == 2) && got_value) ? MEM_ZRIND : MEM_RIND; op[i].id = (brack_done == 1 && got_value) ? MEM_ZINDR : op[i].id; brack_done = 0; } else { - op[i].id = (got_value) ? MEM_ZMR : op[i].id; + if (!is_sib) { + op[i].id = (got_value) ? MEM_ZMR : op[i].id; + } else if (op[i].id != MEM_SIB) { + op[i].type = 1; + op[i].id = MEM_SIB; + /* An invalid scale value was found. + * If we're doing error checking, print an error here. + * If not, clamp it to either the minimum, or maximum scale value. + */ + if (!value || value > 256) { + value = (!value) ? 1 : 256; + } + op[i].scale = value-1; + op[i].value = 0; + } } op[i].rind[reg] = t->type; reg++; @@ -904,6 +943,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, if (op[i].type == 1 && (am & (AM_ORTHO|AM_ORTHO2))) { switch (op[i].id) { + case MEM_SIB : break; case MEM_RIND: break; case MEM_IMM: rs = (rs != 0xFF) ? rs : 0; @@ -936,6 +976,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, } } } + switch (opsize-1) { case 0: case 2: case 5: case 3: type = ZM ; break; case 1: case 4: case 6: case 7: type = ABS; break; @@ -947,6 +988,7 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, case MEM_ZINDR: op[i].id = (type == ABS) ? MEM_AINDR : op[i].id; break; case 0xFF : op[i].id = (type == ABS) ? MEM_ABS : MEM_ZM; break; } + if (opsize) { uint8_t is_abs = (type == ABS); /*if (!is_abs) { diff --git a/disasm.c b/disasm.c index 645d17e..38770da 100644 --- a/disasm.c +++ b/disasm.c @@ -486,6 +486,20 @@ void disasm(struct sux *cpu, WINDOW *w, uint8_t lines, uint8_t opcode, uint8_t p case 7 : sign = ((int64_t)value < 0) ? "-" : "+"; break; } value = (sign[0] == '-') ? (~value + 1) & mask.u64 : value; + if (inst_type == REL) { + value = (sign[0] == '-') ? -value : value; + value += (cpu->pc + 1); + sign = ""; + } + + addrsize = 0; + uint64_t max_val = 0; + for (int i = 0; i <= 64; i += 8, addrsize++) { + max_val |= (0xFF << i); + if (value <= max_val) { + break; + } + } } switch (inst_type) { case BREG : @@ -498,13 +512,13 @@ void disasm(struct sux *cpu, WINDOW *w, uint8_t lines, uint8_t opcode, uint8_t p case IND : case INDX : case INDY : ind = "("; /* Falls through. */ + case REL : case ZMX : case ZMY : case ABSX : case ABSY : case ZM : case ABS : wprintw(w, "%s%s %s%s%s$%0*" PRIX64"%s" , op, postfix, ind, of, sign, (addrsize+1) << 1, value, idx); break; - case REL : wprintw(w, "%s%s %s$%0*"PRIX64 , op, postfix, sign, (addrsize+1) << 1, value); break; } } else { inst_name = ortho_opname[opcode]; diff --git a/lexer.c b/lexer.c index f12feb3..2c618d2 100644 --- a/lexer.c +++ b/lexer.c @@ -700,11 +700,12 @@ int get_expr_type(char **p, uint64_t address, void *val, int *found_reg, char st char *scope_name = NULL; switch (ptok) { - case PTOK_PLUS : type = EXPR_PLUS ; str++; break; - case PTOK_MINUS: type = EXPR_MINUS; str++; break; - case PTOK_PIPE : type = EXPR_OR ; str++; break; - case PTOK_GT : type = (get_ptok(str[1], dbg) == PTOK_GT) ? (EXPR_RSHFT) : (EXPR_LOW) ; str += 2; break; - case PTOK_LT : type = (get_ptok(str[1], dbg) == PTOK_LT) ? (EXPR_LSHFT) : (EXPR_HIGH); str += 2; break; + case PTOK_PLUS : type = EXPR_PLUS ; str++; break; + case PTOK_MINUS : type = EXPR_MINUS ; str++; break; + case PTOK_ASTRSK: type = EXPR_MUL ; str++; break; + case PTOK_PIPE : type = EXPR_OR ; str++; break; + case PTOK_GT : type = (get_ptok(str[1], dbg) == PTOK_GT) ? (EXPR_RSHFT) : (EXPR_LOW) ; str += 2; break; + case PTOK_LT : type = (get_ptok(str[1], dbg) == PTOK_LT) ? (EXPR_LSHFT) : (EXPR_HIGH); str += 2; break; case PTOK_DOLLAR: case PTOK_PERCENT: case PTOK_NUMBER: @@ -815,6 +816,7 @@ expr *parse_expr(char **line, uint64_t address, int *found_reg, int is_left, cha break; case EXPR_HIGH : case EXPR_LOW : expr_type = 1; break; + case EXPR_MUL : case EXPR_OR : case EXPR_LSHFT : case EXPR_RSHFT : expr_type = 2; break; @@ -1062,6 +1064,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { break; case PTOK_PLUS: case PTOK_MINUS: + case PTOK_ASTRSK: case PTOK_GT: case PTOK_LT: case PTOK_PIPE: diff --git a/lexer.h b/lexer.h index 8775187..5096f74 100644 --- a/lexer.h +++ b/lexer.h @@ -18,6 +18,7 @@ static uint8_t isdelm2(char c, uint8_t dbg) { case ',' : case '.' : case '+' : + case '*' : case '<' : case '|' : case '>' : @@ -40,6 +41,7 @@ static uint8_t get_ptok(char c, uint8_t dbg) { case '=' : return PTOK_EQU ; case '+' : return PTOK_PLUS ; case '-' : return PTOK_MINUS ; + case '*' : return PTOK_ASTRSK ; case '>' : return PTOK_GT ; case '<' : return PTOK_LT ; case '|' : return PTOK_PIPE ; diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s index 0d712ff..320a582 100644 --- a/programs/sub-suite/lexer.s +++ b/programs/sub-suite/lexer.s @@ -310,21 +310,7 @@ ptok_dqu: lda #TOK_DQUOT ; Set the lexeme type to TOK_DQUOT. sta lex_type ; sta t_id ; Also set the token ID to TOK_DQUOT. -; lda.d ptr3 ; Get the address of the lexeme buffer. - lda.q idx1 ; Get the index of the lexeme buffer. - inc ; Increment it by one to get the size. - jsr malloc ; Make a new string. - ldb.q ptr3 ; Get the address of the lexeme buffer. - ldy.q idx1 ; Get the size of the lexeme buffer + 1. - iny ; - jsr memcpy ; Copy the string in the lexeme buffer into the new string. - sta.q t_str ; Save it in the token string. - and #0 ; Reset A. - tab ; Reset B. - ldy.q idx0 ; Get the string index back. -@end: - jsr make_tok ; Create the token. - rts ; End of parse_ptok. + bra copy_str ; Copy the string. ptok_squ: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. @@ -337,23 +323,7 @@ ptok_squ: lda #TOK_SQUOT ; Set the lexeme type to TOK_SQUOT. sta lex_type ; sta t_id ; Also set the token ID to TOK_SQUOT. - lda.q idx1 ; Get the index of the lexeme buffer. - inc ; Increment it by one to get the size. - jsr malloc ; Make a new string. - ldb.q ptr3 ; Get the address of the lexeme buffer. - ldy.q idx1 ; Get the size of the lexeme buffer + 1. - iny ; - jsr memcpy ; Copy the string in the lexeme buffer into the new string. - sta.q t_str ; Save it in the token string. - and #0 ; Reset A. - tab ; Reset B. - ldy.q idx0 ; Get the string index back. -@end: - jsr make_tok ; Create the token. - rts ; End of parse_ptok. -ptok_hash: - inc.w idx0 ; - rts ; End of parse_ptok. + bra copy_str ; Copy the string. ptok_scol: ldb #1 ; Make init_lex increment the string index. jsr init_lex ; Initialize the lexeme buffer for copying. @@ -365,12 +335,13 @@ ptok_scol: lda #TOK_SCOLN ; Set the lexeme type to TOK_SCOLN. sta lex_type ; sta t_id ; Also set the token ID to TOK_SCOLN. - lda.q idx1 ; Get the index of the lexeme buffer. - inc ; Increment it by one to get the size. +copy_str: + lea d, (idx1) ; Get the index of the lexeme buffer. + inc d ; Increment it by one to get the size. + mov f, d ; Get the size of the lexeme buffer + 1. jsr malloc ; Make a new string. - ldb.q ptr3 ; Get the address of the lexeme buffer. - ldy.q idx1 ; Get the size of the lexeme buffer + 1. - iny ; + lea s, (ptr3) ; Get the address of the lexeme buffer. + mov d, a ; Get the pointer of the new string. jsr memcpy ; Copy the string in the lexeme buffer into the new string. sta.q t_str ; Save it in the token string. and #0 ; Reset A. @@ -379,6 +350,9 @@ ptok_scol: @end: jsr make_tok ; Create the token. rts ; End of parse_ptok. +ptok_hash: + inc.w idx0 ; + rts ; End of parse_ptok. ptok_dolr: lda #TOK_HEX ; Set the lexeme type to TOK_HEX. sta lex_type ; diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s index 53e936a..b34d2d3 100644 --- a/programs/sub-suite/libc.s +++ b/programs/sub-suite/libc.s @@ -187,7 +187,7 @@ toupper: ; Input: D = size in bytes to allocate. ; Output: A = Pointer to allocated memory. ; Caller preserved registers: D. -; Callie preserved registers: B, X, Y. +; Callee preserved registers: B, X, Y. malloc: phb.q ; Preserve B. @@ -272,7 +272,7 @@ malloc: ; Input: D = Pointer to allocated memory. ; Output: none. ; Caller preserved registers: D. -; Callie preserved registers: A, B, X, Y, E. +; Callee preserved registers: A, B, X, Y, E. free: pha.q ; Preserve A. @@ -405,31 +405,74 @@ free: pla.q ; Restore A. rts ; End of free. - ; memcpy: memory to memory copy. -; Input: A = Destination pointer. B = Source pointer. Y = Number of bytes to copy. +; Input: D = Destination pointer. S = Source pointer. F = Number of bytes to copy. ; Output: A = Destination pointer. -; Caller preserved registers: none. -; Callie preserved registers: none. +; Caller preserved registers: D, S, F. +; Callee preserved registers: B. memcpy: - pha.q ; Preserve the return value. - pha.q ; Push the destination pointer on the stack. - phb.q ; Push the source pointer on the stack. - phy.q ; Push the size on the stack. - and #0 ; Reset A. - tab ; Reset B. - cpy #0 ; Is the size zero? - beq @end ; Yes, so we're done. + phb.q ; Preserve B. + xor b, b ; Reset B. + mov a, d ; Set the return value to the destination pointer. + cmp f, #0 ; Is the size zero? + beq @end ; Yes, so we're done. @loop: - lda (sp+9) ; Get a byte from the source. - sta (sp+17) ; Copy it to the destination. - inc.q sp+9 ; Increment the source pointer. - inc.q sp+17 ; Increment the destination pointer. - dey ; Decrement the size. - beq @end ; The size is zero, so we're done. - bra @loop ; Keep looping. + mov (d+b), (s+b) ; Copy a byte 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. +@end: + plb.q ; Restore B. + rts ; End of memcpy. + + +; memset: Set memory to some value. +; Input: D = Destination pointer. S = Constant value. F = Number of bytes to set. +; Output: A = Destination pointer. +; Caller preserved registers: D, S, F. +; Callee preserved registers: B. + +memset: + phb.q ; Preserve B. + xor b, b ; Reset B. + mov a, d ; Set the return value to the destination pointer. + cmp f, #0 ; Is the size zero? + beq @end ; Yes, so we're done. +@loop: + mov (d+b), s ; Set the destination byte, 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. +@end: + plb.q ; Restore B. + rts ; End of memset. + + +; max: Get the largest of two integers. +; Input: D = First value, S = Second value. +; Output: A = Largest of the two values. +; Caller preserved registers: D, S. +; Callee preserved registers: None. + +max: + mov a, s ; Set the return value to the second value. + cmp d, s ; Is the first value greater than the second value? + beq @end ; No, so we're done. + mcs a, d ; Set the return value to the first value if so. +@end: + rts ; End of max. + + +; min: Get the smallest of two integers. +; Input: D = First value, S = Second value. +; Output: A = Smallest of the two values. +; Caller preserved registers: D, S. +; Callee preserved registers: None. + +min: + mov a, s ; Set the return value to the second value. + cmp d, s ; Is the first value less than the second value? + mcc a, d ; Set the return value to the first value if so. @end: - ads #$18 ; Clean up the stack frame. - pla.q ; Restore the return value. - rts ; End of memcpy. + rts ; End of min. diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s index f22ee60..56d13c2 100644 --- a/programs/sub-suite/subasm.s +++ b/programs/sub-suite/subasm.s @@ -118,7 +118,6 @@ subasm: pha.q ; Preserve A. - phe.q ; Preserve E. des ; Make room for the command id. and #0 ; Reset A. lea d, (cmd_buf) ; Get the command buffer. @@ -128,23 +127,28 @@ subasm: jsr chk_cmd ; No, but did we get a full command? bne @cmd ; Yes, so skip everything else. mov.q ptr, d ; + psh d ; Preserve D. + psh s ; Preserve S. + psh f ; Preserve F. jsr lex ; No, so start lexing this line. + pul d ; Restore D. + pul s ; Restore S. + pul f ; Restore F. bra @end ; We are done. @cmd: 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 e, (cmd_srt+s) ; Get the pointer, from the command subroutine table. + lea.w s, (cmd_srt+s) ; Get the pointer, from the command subroutine table. and #0 ; Reset A. tab ; Reset B. - jsr (e) ; Run the command's subroutine. + jsr s ; Run the command's subroutine. @end: and #0 ; Reset A. jsr update_ptr ; Get the screen buffer index. tay ; Save it in Y. ins ; Cleanup the stack frame. - ple.q ; Restore E. pla.q ; Restore A. rts ; End of subasm. diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index f6b647f..83fe179 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -196,11 +196,22 @@ clrbit: setbit: pha.q ; Preserve A. + phb.q ; Preserve B. + mov b, s ; Save the bit. des ; Create the stack frame. lea s, (sp+1) ; Get the address of the bitmask. jsr bitpos ; Get the bit, and byte position. ins ; Cleanup the stack frame. + cpb #1 ; Is the bit set? + bne @clear ; No, so clear the bit. +@set: or (bitabl)+a, (s) ; Set the bit of the current row number to one. + bra @end ; We are done. +@clear: + not (s) ; Invert the bitmask. + and (bitabl)+a, (s) ; Set the bit of the current row number to zero. +@end: + plb.q ; Restore B. pla.q ; Restore A. rts ; End of setbit. @@ -257,21 +268,19 @@ 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: - sec ; Yes, so make sure that we don't subtract by the starting point, plus one. - sbc scr_str ; Offset the row position, back by the screen's starting point. - clc ; Clear the carry flag, so that nothing odd occurs. + 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. sta rege ; Save it into the temporary row posiition. jsr findst ; Find the start of the line. - clc ; Clear the carry flag. lda scr_row ; Get the row position. - adc scr_str ; Add it with the screen's starting row. + add scr_str ; Add it with the screen's starting row. mul #maxcol+1 ; Multiply it with the width of the screen, plus one. tay ; Place it into the index. ldx.w #0 ; Reset the X register. @@ -338,13 +347,52 @@ findst: rts ; End of findst. +;find_end: +; mov a, s ; Set the loop counter. +;@loop: +; inc ; Increment the loop counter. +; cmp (d+a-1), #0 ; Did we hit the null terminator? +; bne @loop ; No, so keep looping. +;@end: +; rts ; End of find_end2. + + 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. + 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. + mov d, b ; Restore the string pointer. + mov s, x ; Restore the cursor position. +@loop2: inc ; Increment the loop counter. cmp (d+a-1), #0 ; Did we hit the null terminator? - bne @loop ; No, so keep looping. + bne @loop2 ; No, so keep looping. @end: + ple.q ; Restore E. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. rts ; End of find_end. @@ -353,6 +401,11 @@ get_endrow: div #maxcol+1 ; Get the ending row. rts ; End of get_endrow +;get_endrow2: +; jsr find_end2 ; Find the end of the line. +; div #maxcol+1 ; Get the ending row. +; rts ; End of get_endrow + print_char: phb.q ; Preserve B. @@ -392,6 +445,7 @@ 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. @@ -414,7 +468,8 @@ printc: ; stb regd ; lea d, (buffer) ; Get the screen buffer. mov.w s, scr_ptr; Get the cursor index. - mov f, #1 ; Set the left flag to true. + lea f, 1 ; Set the shift length to one. + lea c, 1 ; Set the left flag to true. jsr shftln ; ldb #1 ; stb regd ; @@ -454,7 +509,7 @@ printc: bra @print ; @scroll: sta scr ; Echo typed character. - clc ; +; clc ; lda #1 ; sta wrapped ; jsr scrl_down ; @@ -474,6 +529,7 @@ printc: ; tax ; mov d, scr_row ; Get the row position. add d, scr_str ; Add the row offset to the row position. + lea s, 1 ; Set the bit to one. jsr setbit ; Set the bit of that row. ; plx.w ; jsr update_pos ; @@ -560,13 +616,11 @@ bs: bne @scroll ; Yes, so scroll up. rts ; No, so we're done. @scroll: - clc ; Clear the carry flag, so that we don't get odd behaviour. jsr scrl_up ; Scroll up. inc scr_row ; Move down by one row. @wrap3: - clc ; Clear the carry flag. lda scr_row ; Add the cursor's row position, - adc scr_str ; and the screen's starting row. + add scr_str ; and the screen's starting row. tax ; Transfer that into X. @wrap4: dec scr_row ; Move up by one row. @@ -581,6 +635,7 @@ 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: @@ -599,7 +654,8 @@ back: stb regd ; lea d, (buffer) ; Get the screen buffer. mov s, y ; Get the cursor index. - mov f, #0 ; Set the left flag to false. + lea f, 1 ; Set the shift length to one. + lea c, 0 ; Set the left flag to false. jsr shftln ; Shift line back by one character. lda #$7F ; Print a backspace to the screen. sta scr ; @@ -608,6 +664,7 @@ 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. @@ -630,66 +687,288 @@ back: bra @shift ; Start shifting the line back. +;shftln: +; pha.q ; Preserve A. +; phb.q ; Preserve B. +; and f, f ; Is the left flag not set? +; beq @right ; Yes, so shift the line to the right. +;; txa ; Get the end of the line. +; jsr find_end ; Find the end of the line. +; dec ; Decrement the source position. +; bra @left ; No, so shift the line to the left. +;@minus: +; and #0 ; Set the source poition to 0. +; mov (d), a ; Clear the character that is in the source. +; bra @lend ; We are done. +;@left: +; cmp s, a ; Is the cursor index, at, or below the source position? +; beq @left1 ; Yes, so keep looping. +; bcs @lend ; No, so we're done. +;@left1: +; cmp #0 ; Is the source position less than 0? +; bcc @minus ; Yes, so set the source position to zero. +; mov (d+a+1), (d+a) ; No, so shift the current character to the left by one. +; mov (d+a), #0 ; Clear the current character. +; dec ; Decrement the source position. +; bra @left ; Keep looping. +;@right: +; cmp (d+s), #0 ; Is this character a null terminator? +; beq @rend ; Yes, so we're done. +; mov (d+s-1), (d+s) ; No, so shift the current character to the right by one. +; mov (d+s), #0 ; Clear the current character. +; inc s ; Increment the source position. +; bra @right ; Keep looping. +;@wrap: +; mov d, a ; Get the ending line. +; lea s, f ; Set the bit to the left flag. +; jsr setbit ; Set the wrap bit of the ending line. +; bra @end ; We are done. +;@lend: +; lea s, (a+2) ; Add 2 to the source position. +; jsr find_end ; Find the end of the line. +; dec ; Decrement the end of line position. +; div #maxcol+1 ; Get the ending line. +;@lend2: +; cmp scr_row ; Is the ending line greater than the starting line? +; beq @end ; No, so we're done. +; bcs @wrap ; Yes, so set the wrap bit. +; bra @end ; No, so we're done. +;@rend: +; lea f, 0 ; Set the decrement offset to one. +; jsr find_end ; Find the end of the line. +; dec ; Decrement the end of line position. +; div #maxcol+1 ; Get the ending line. +; cpb #0 ; Is the remainder zero? +; bne @end ; No, so we're done. +;@rend2: +; cmp scr_row ; Is the ending line greater than the starting line? +; beq @end ; No, so we're done. +; bcs @wrap ; Yes, so clear the wrap bit. +;@end: +; plb.q ; Restore B. +; pla.q ; Restore A. +; rts ; End of shftln. + + +;minmax: +; psh.q d ; Preserve D. +; psh.q s ; Preserve S. +; mov d, e ; Get the shift length. +; mov s, b ; Get the ending position. +; jsr max ; Get the largest value. +; mov f, a ; Save the largest value. +; jsr min ; Get the smallest value. +; pul.q s ; Restore S. +; pul.q d ; Restore D. +; rts ; End of minmax. + + +;shftln: +; pha.q ; Preserve A. +; phb.q ; Preserve B. +; phx.q ; Preserve X. +; phy.q ; Preserve Y. +; phe.q ; Preserve E. +; mov x, d ; Get the string pointer. +; mov y, s ; Get the cursor position. +; mov e, f ; Get the shift length. +;@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. +; tab ; Save the end position for later. +; and #0 ; Reset A. +; dec ; Set our offset to -1. +; and c, c ; Is the left flag set? +; mne a, f ; Set our offset to the length argument if so. +;@copy: +; add a, s ; Add the cursor position with the offset. +; lea s, (d+s) ; Get the address of the string pointer, at the cursor position. +; lea d, (d+a) ; Get the address of the string pointer, at the cursor position, plus the offset. +; jsr minmax ; Get the minimum, and maximum values. +;@check_length: +; cpe #2 ; Is the shift length greater than one? +; bcc @offset0 ; No, so skip the subtraction below. +; cmp f, y ; Yes, and is the end position greater than, or equal to the the cursor position? +; bcc @offset ; No, so skip the subtraction below. +; and c, c ; Yes, and is the left flag set? +; beq @offset0 ; No, so skip the subtraction below. +;@sub: +; tya ; Set the offset to the cursor position. +; bra @offset ; Subtract the offset. +;@offset0: +; sub f, a ; Subtract the end position by the shift length. +; bra @sub ; Subtract the cursor position. +;@offset: +; sub f, a ; Subtract the offset. +;@copy2: +; jsr memcpy ; Copy the string from the cursor, to the cursor plus the offset. +;@clear: +; jsr minmax ; Get the minimum, and maximum values. +; cmp #1 ; Is the smallest value equal to one? +; bne @clear2 ; No, so skip incrementing the value. +; inc ; Increment the smallest value. +;@clear2: +; sub f, a ; Subtract the end position by the shift length. +; mov d, y ; Get the cursor position. +; and c, c ; Is the left flag set? +; meq d, f ; Get the end position, minus the shift length if so. +; lea d, (x+d) ; Get the address of the string pointer, at the offset. +; xor s, s ; Reset S. +; mov f, e ; Restore the shift length. +; jsr memset ; Clear shift length bytes of the string, from the offset. +;@neg: +; and c, c ; Is the left flag set? +; bne @get_rows ; Yes, so don't negate the shift length. +; neg f ; Negate the shift length. +;@get_rows: +; mov x, b ; Save the end position. +; lea a, (b+f) ; Add, or subtract the end position, by the shift length. +; div #maxcol+1 ; Get the new ending line. +; mov e, a ; Save the ending line. +; 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. +; tya ; Get the cursor position. +; div #maxcol+1 ; Get the cursor line. +; and c, c ; Is the left flag set? +; meq a, e ; Set the starting line to the new ending line if not. +; tay ; Save the starting line. +; txa ; Get the end position. +; div #maxcol+1 ; Get the old ending line. +; 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. +;@loop: +; xor s, s ; Reset S. +; cmp y, b ; Is the current line greater than the ending line? +; beq @rem ; The current line is equal to the ending line, so check the remainder. +; bcs @end ; Yes, so we're done. +; bra @getbit ; No, so get the bit. +;@rem: +; and f, f ; Is the remainder zero? +; bne @end ; No, so we're done. +;@getbit: +; mov d, y ; Get the current line. +; jsr getbit ; Get the linewrap bit of that line. +; cmp a, c ; Is the linewrap bit the opposite value of the left flag? +; beq @inc ; No, so keep looping. +;@setbit: +; mov d, y ; Get the current line. +; mov s, c ; Get the left flag. +; jsr setbit ; Set the linewrap bit to the left flag. +;@inc: +; iny ; Increment the current line. +; bra @loop ; Keep looping. +;@end: +; ple.q ; Restore E. +; ply.q ; Restore Y. +; plx.q ; Restore X. +; plb.q ; Restore B. +; pla.q ; Restore A. +; rts ; End of shftln. + + shftln: pha.q ; Preserve A. phb.q ; Preserve B. - and f, f ; Is the left flag not set? - beq @right ; Yes, so shift the line to the right. -; txa ; Get the end of the line. - jsr find_end ; Find the end of the line. - dec ; Decrement the source position. - bra @left ; No, so shift the line to the left. -@minus: - and #0 ; Set the source poition to 0. - mov (d), a ; Clear the character that is in the source. - bra @lend ; We are done. -@left: - cmp s, a ; Is the cursor index, at, or below the source position? - beq @left1 ; Yes, so keep looping. - bcs @lend ; No, so we're done. -@left1: - cmp #0 ; Is the source position less than 0? - bcc @minus ; Yes, so set the source position to zero. - mov (d+a+1), (d+a) ; No, so shift the current character to the left by one. - mov (d+a), #0 ; Clear the current character. - dec ; Decrement the source position. - bra @left ; Keep looping. -@right: - cmp (d+s), #0 ; Is this character a null terminator? - beq @rend ; Yes, so we're done. - mov (d+s-1), (d+s) ; No, so shift the current character to the right by one. - mov (d+s), #0 ; Clear the current character. - inc s ; Increment the source position. - bra @right ; Keep looping. -@wrap: - mov d, a ; Get the ending line. - jsr setbit ; Set the wrap bit of the ending line. - bra @end ; We are done. -@wrap1: - mov d, a ; Get the ending line. - jsr clrbit ; Clear the wrap bit of the ending line. - bra @end ; We are done. -@lend: - lea s, (a+2) ; Add 2 to the source position. - jsr find_end ; Find the end of the line. - dec ; Decrement the end of line position. - div #maxcol+1 ; Get the ending line. -@lend2: - cmp scr_row ; Is the ending line greater than the starting line? - beq @end ; No, so we're done. - bcs @wrap ; Yes, so set the wrap bit. - bra @end ; No, so we're done. -@rend: + phx.q ; Preserve X. + phy.q ; Preserve Y. + phe.q ; Preserve E. + psh.q bp ; Preserve BP. + mov x, d ; Get the string pointer. + mov y, s ; Get the cursor position. + mov e, f ; Get the shift length. + and c, c ; Is the left flag set? + bne @find_end ; Yes, so find the end of the line. + 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. - dec ; Decrement the end of line position. - div #maxcol+1 ; Get the ending line. - cpb #0 ; Is the remainder zero? + 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. + neg a ; Negate the shift length. + and c, c ; Is the left flag set? + mne a, f ; Set our offset to the shift length if so. + lea bp, (b+a) ; Add the old end position, with the offset to get the new end position. +@copy: + add a, y ; Add the cursor position with the offset. + lea s, (x+y) ; Get the address of the string pointer, at the cursor position. + lea d, (x+a) ; Get the address of the string pointer, at the cursor position, plus the offset. + mov f, b ; Get the old end position. + sub f, y ; Subtract the old end position, by the cursor position. + jsr memcpy ; Copy the string from the cursor, to the cursor plus the offset. +@clear: + tya ; Get the cursor position. + and c, c ; Is the left flag set? + meq a, bp ; Set our offset to the new end position if not. + lea d, (x+a) ; Get the address of the string pointer, at the offset position. + xor s, s ; Reset S. + mov f, e ; Get the shift length. + jsr memset ; Clear shift length bytes of the string, from the offset. +@get_rows: + mov x, b ; Save the old end position. + mov a, bp ; Get the new end position. + div #maxcol+1 ; Get the new ending line. + mov e, a ; Save the ending line. + 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. + tya ; Get the cursor position. + div #maxcol+1 ; Get the cursor line. + mov bp, a ; Save the cursor line. + and c, c ; Is the left flag set? + meq a, e ; Set the starting line to the new ending line if not. + tay ; Save the starting line. + txa ; Get the old end position. + 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. + 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. +@loop: + xor s, s ; Reset S. + cmp y, b ; Is the current line greater than the ending line? + beq @rem ; The current line is equal to the ending line, so check the remainder. + bcs @end ; Yes, so we're done. + bra @getbit ; No, so get the bit. +@rem: + and f, f ; Is the remainder zero? bne @end ; No, so we're done. -@rend2: - cmp scr_row ; Is the ending line greater than the starting line? - beq @end ; No, so we're done. - bcs @wrap1 ; Yes, so clear the wrap bit. +@getbit: + mov d, y ; Get the current line. + jsr getbit ; Get the linewrap bit of that line. + cmp a, c ; Is the linewrap bit the opposite value of the left flag? + beq @inc ; No, so keep looping. +@setbit: + mov d, y ; Get the current line. + mov s, c ; Get the left flag. + jsr setbit ; Set the linewrap bit to the left flag. +@inc: + iny ; Increment the current line. + bra @loop ; Keep looping. @end: + pul.q bp ; Restore BP. + ple.q ; Restore E. + ply.q ; Restore Y. + plx.q ; Restore X. plb.q ; Restore B. pla.q ; Restore A. rts ; End of shftln. @@ -987,12 +1266,9 @@ bcd: scrl_down: inc scr_str ; Increment the starting line of the screen. inc scr_end ; Increment the ending line of the screen. - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'T' ; Print 'T' - sta scr ; to the screen, and end the escape sequence. + mov scr, #'\e' ; Print an escape character to the screen. + mov scr, #'[' ; Print '[' to the screen, and start the escape sequence. + mov scr, #'T' ; Print 'T' to the screen, and end the escape sequence. lda scr_row ; Get the cursor's line number. pha ; Save it in the stack. lda wrapped ; Was the wrapped flag set? @@ -1022,12 +1298,9 @@ scrl_down: scrl_up: dec scr_str ; dec scr_end ; - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'S' ; Print 'S' - sta scr ; to the screen, and end the escape sequence. + mov scr, #'\e' ; Print an escape character to the screen. + mov scr, #'[' ; Print '[' to the screen, and start the escape sequence. + mov scr, #'S' ; Print 'S' to the screen, and end the escape sequence. lda scr_row ; pha ; lda scr_col ; diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s index 3fc025d..7b31c31 100644 --- a/programs/sub-suite/subsuite.s +++ b/programs/sub-suite/subsuite.s @@ -20,5 +20,5 @@ a ;.org reset ;v ;f "subsuite.bin" $8000 -q +;q d diff --git a/programs/sub-suite/tmp-stuff/cmd_cpy.c b/programs/sub-suite/tmp-stuff/cmd_cpy.c deleted file mode 100644 index 6b89e7d..0000000 --- a/programs/sub-suite/tmp-stuff/cmd_cpy.c +++ /dev/null @@ -1,33 +0,0 @@ -#include - -int cmd_size = 0x400; -int maxcol = 80; - -extern uint8_t scr_row; -extern uint8_t scr_col; -extern uint8_t scr_str; - -int find_end(char *str, int pos) { - int i; - for (i = pos; str[i] != '\0'; i++); - return i; -} - -void cmd_cpy(char *scr_buf, char *cmd_buf, int pos) { - int end_line = (find_end(scr_buf, pos)/(maxcol+1)) - scr_str; - int start_line = (find_start(scr_buf, end_line) + scr_str) * (maxcol+1); - - for (int i = 0, done = 0; !done; i++) { - uint64_t tmp = (uint64_t)scr_buf[i]; - for (int j = 0; j < 8; j++ , tmp >>= 8) { - int idx = (i*8) + j; - uint8_t tmp2 = tmp; - if (idx >= cmd_size || !tmp2) { - done = 1; - cmd_buf[idx] = '\0'; - break; - } - cmd_buf[idx] = tmp2; - } - } -} diff --git a/programs/sub-suite/tmp-stuff/free-new.s b/programs/sub-suite/tmp-stuff/free-new.s deleted file mode 100644 index dad19d0..0000000 --- a/programs/sub-suite/tmp-stuff/free-new.s +++ /dev/null @@ -1,143 +0,0 @@ -.include "declare.s" - -.org 0 - -; free: Free allocated memory. -; Input: D = Pointer to allocated memory. -; Output: none. -; Caller preserved registers: D. -; Callie preserved registers: A, B, X, Y, E. - -free: - pha.q ; Preserve A. - phb.q ; Preserve B. - phx.q ; Preserve X. - phy.q ; Preserve Y. - phe.q ; Preserve E. - and #0 ; Reset A. - tab ; Reset B. - tax ; Reset X. - tay ; Reset Y. - mov a, d ; Get the passed pointer. - bne @getrealblk ; The pointer isn't NULL, so get the real block. - bra @end ; The pointer is NULL, so we're done. -@getrealblk: - sub #8 ; Get the start of the used block. - mov.q a, (a) ; Get the start of the real block. - mov.q b, (a+ublk.size) ; Get the size of the real block. - lea e, (a+b) ; Add the size of the real block with the start of the real block. - cmp.q e, heapptr ; Is this block on top of the heap? - bne @heapadd ; No, so add it to the free block list. -@dectop: - mov.q heapptr, (a) ; Set the top of the heap to the start of the previous real block. -@chklastblk: - mov.q b, heapl ; Get the last free list entry. - beq @end ; The free list is empty, so we're done. - ldy #fblk.size ; Get the size of the block. - mov.q a, (b+fblk.size) ; Get the size of the block. - lea e, (a+b) ; Add the size of the block, with the address of the block entry. - cmp.q e, heapptr ; Is the last block on top of the heap? - bne @end ; No, so we're done. -@delblk: - mov.q heapptr, b ; Yes, so remove the last block. -@correctblk: - mov.q a, (b+fblk.prev) ; Get the previous block. - sta.q heapl ; Set the last block to the previous block. - bne @delnxtblk ; The previous block isn't NULL, so delete the next block. - sta.q heapf ; The previous block is NULL, so empty the free list. - bra @end ; We are done. -@delnxtblk: - lea e, (a+fblk.next) ; Delete the next block. - stz.q (e) ; -@end: - ple.q ; Restore E. - ply.q ; Restore Y. - plx.q ; Restore X. - plb.q ; Restore B. - pla.q ; Restore A. - rts ; End of free. - - -@heapadd: - mov.q y, heapf ; Get the first block. - bne @srchflst ; The Free list isn't empty, so start searching the free list. -@empty: - mov.q (a+fblk.next), y ; Clear the next block. - mov.q (a+fblk.prev), y ; Clear the previous block. - sta.q heapf ; Set the first block entry to the current block. - sta.q heapl ; Set the last block entry to the current block. - bra @end ; We are done. -@srchflst: -@loop: - cmp y, a ; Is the right pointer at, or below the current block? - beq @nextright ; Yes, so get the next right pointer. - bcs @chkrmerge ; No, so do the right block merge. -@nextright: - tyx ; Set the left pointer, to the right pointer. - mov.q y, (y+fblk.next) ; Set the current right pointer to the next right pointer. - bne @loop ; The next right pointer isn't NULL, so keep looping. -@st_lmerge2: - mov.q (a+fblk.next), y ; Clear the next block. - sta.q heapl ; Set the last free block entry to it. - bra @chklmerge2 ; Do the left block merge. -@chkrmerge: - lea e, (a+b) ; Add the size of the current block, to the current block. - cmp e, y ; Is the current block the same as the right block? - bne @normerge ; No, so don't merge the right block. -@rmerge: - mov e, b ; Get the size of the current block. - add.q e, (y+fblk.size) ; Add the size of the current block, with the size of the right pointer. - mov.q (a+fblk.size), e ; Set the size of the current block, to the new size. -@rmerge2: - lea fblk.next ; Get the next right pointer. - mov.q (a+e), (y+e) ; Set the next block, to the next right pointer. - mov.q b, (y+e) ; Save the next block. - beq @setheapl ; The next block is NULL, so set the last block. -@setprev: - mov.q (b+fblk.prev), a ; Set the previous block to the current block. - bra @chklmerge ; Do the left block merge. -@setheapl: - sta.q heapl ; Set the last block to the current block. - bra @chklmerge ; Do the left block merge. -@normerge: - mov.q (a+fblk.next), y ; Set the next block to the right pointer. - mov.q (y+fblk.prev), a ; Set the previous right pointer to the current block. -@chklmerge: - and x, x ; Is the left pointer NULL? - bne @chklmerge2 ; No, so keep checking. -@newstart: - mov.q (a+fblk.prev), x ; - sta.q heapf ; Set the first block, to the current block. - bra @end2 ; We are done. -@chklmerge2: - mov.q e, (x+fblk.size) ; Get the size of the left block. - add e, x ; Add the size of the left block, to the left pointer. - cmp e, a ; Is the left block adjacent? - bne @nolmerge ; No, so don't merge the left block. -@lmerge: - lea fblk.size ; Set the offset to the block size. - add.q (x+e), (a+e) ; Add the size of the left block, with the size of the current block. -@lmerge2: - lea fblk.next ; Set the offset to the next block. - mov.q (x+e), (a+e) ; Set the next left pointer, to the next block. - mov.q b, (a+e) ; Get the next block. - beq @newlast ; The next block is NULL, so set the last block. -@lprev: - mov.q (b+fblk.prev), x ; Set the next left pointer's previous pointer to the left pointer. - bra @end2 ; We are done. -@newlast: - stx.q heapl ; Set the last block, to the left pointer. - bra @end2 ; We are done. -@nolmerge: - mov.q (x+fblk.next), a ; Set the next left pointer, to the current block. -@nolmerge2: - mov.q (a+fblk.prev), x ; Set the previous block, to the left pointer. -@end2: - ple.q ; Restore E. - ply.q ; Restore Y. - plb.q ; Restore B. - pla.q ; Restore A. - rts ; End of free. - -a -q diff --git a/programs/sub-suite/tmp-stuff/free-old.s b/programs/sub-suite/tmp-stuff/free-old.s deleted file mode 100644 index 7f75edd..0000000 --- a/programs/sub-suite/tmp-stuff/free-old.s +++ /dev/null @@ -1,200 +0,0 @@ -.include "declare.s" - -.org 0 - -; free: Free allocated memory. -; Input: A = Pointer to allocated memory. -; Output: none. -; Caller preserved registers: none. -; Callie preserved registers: A, B, Y. - -free: - pha.q ; Preserve A. - phb.q ; Preserve B. - phy.q ; Preserve Y. - pha.q ; Push the pointer argument to the stack. - and #0 ; Reset A. - tay ; Reset Y. - sbs #$18 ; Allocate 3 local variables onto the stack. - lda.q sp+25 ; Get the passed pointer. - ora.d sp+29 ; Is the passed pointer NULL? - bne @getrealblk ; No, so get the real block. - bra @end ; Yes, so we're done. -@getrealblk: - lda.q sp+25 ; Get the passed pointer. - sec ; Prepare for a non borrowing subtract. - sbc #8 ; Move the passed pointer back by one. - sta.q sp+25 ; Set the first local variable to the start of the used block. - lda.q (sp+25) ; Get the real block address. - sta.q sp+25 ; Set the passed pointer to the start of the real block. - ldy #ublk.size ; Get the size of the real block. - lda.q (sp+25), y; - sta.q sp+17 ; Save the size of the real block. - clc ; Prepare for a non carrying add. - adc.q sp+25 ; Add the size of the real block with the start of the real block. - cmp.q heapptr ; Is this block on top of the heap? - bne @heapadd ; No, so add it to the free block list. -@dectop: - lda.q sp+25 ; Get the block. - sta.q heapptr ; Set the top of the heap to it. -@chklastblk: - lda.q heapl ; Get the last free list entry. - sta.q sp+17 ; Copy it into the second local variable. - ora.d sp+21 ; Is the free list empty? - beq @end ; Yes, so we're done. - lda.q sp+17 ; No, so Get the last free list entry. - ldy #fblk.size ; Get the size of the block. - lda.q (sp+17), y; - clc ; Prepare for a non carrying add. - adc.q sp+17 ; Add the size of the block, with the address of the block entry. - cmp.q heapptr ; Is the last block on top of the heap? - bne @end ; No, so we're done. -@delblk: - lda.q sp+17 ; Yes, so remove the last block. - sta.q heapptr ; -@correctblk: - ldy #fblk.prev ; Get the previous block. - lda.q (sp+17), y; - sta.q sp+25 ; Save the previous block for now. - sta.q heapl ; Set the last block to the previous block. - ora.d sp+29 ; Is the previous block non NULL? - bne @delnxtblk ; Yes, so delete the next block. - sta.q heapf ; No, so empty the free list. - bra @end ; We are done. -@delnxtblk: - and #0 ; Reset A. - ldy #fblk.next ; Delete the next block. - sta.q (sp+25), y; -@end: - ads #$20 ; Clean up the stack frame. - ply.q ; Restore Y. - plb.q ; Restore B. - pla.q ; Restore A. - rts ; End of free. - - -@heapadd: - lda.q heapf ; Get the first block. - sta.q sp+9 ; Copy it into the third local variable. - ora.d sp+13 ; Is the free list empty? - bne @srchflst ; No, so start searching the free list. -@empty: - ldy #fblk.next ; Clear the next block. - sta.q (sp+25), y; - ldy #fblk.prev ; Clear the previous block. - sta.q (sp+25), y; - lda.q sp+25 ; Reset A. - sta.q heapf ; Clear the first block entry. - sta.q heapf ; Clear the last block entry. - bra @end ; We are done. -@srchflst: - and #0 ; Reset A. - sta.q sp+1 ; Reset the left pointer. - ldy #fblk.next ; Setup for the loop. -@loop: - lda.q sp+9 ; Get the right pointer. - cmp.q sp+25 ; Is the right pointer at, or below the current block? - beq @nextright ; Yes, so get the next right pointer. - bcs @chkrmerge ; No, so do the right block merge. -@nextright: - sta.q sp+1 ; Set the left pointer, to the right pointer. - lda.q (sp+9), y ; Get the next right pointer. - sta.q sp+9 ; Set the current right pointer to the next right pointer. - ora.d sp+13 ; Is the next right pointer NULL? - bne @loop ; No, so keep looping. -@st_lmerge2: - sta.q (sp+25), y; Clear the next block. - lda.q sp+25 ; Get the current block. - sta.q heapl ; Set the last free block entry to it. - bra @chklmerge2 ; Do the left block merge. -@chkrmerge: - lda.q sp+25 ; Get the current block. - clc ; Prepare for a non carrying add. - adc.q sp+17 ; Add the size of the current block, to the current block. - cmp.q sp+9 ; Is the right pointer NULL? - bne @normerge ; No, so don't merge the right block. -@rmerge: - ldy #fblk.size ; Get the size of the right pointer. - lda.q sp+17 ; Get the size of the current block. - clc ; Prepare for a non carrying add. - adc.q (sp+9), y ; Add the size of the current block, with the size of the right pointer. - sta.q (sp+25), y; Set the size of the current block, to the new size. -@rmerge2: - ldy #fblk.next ; Get the next right pointer. - lda.q (sp+9), y ; - sta.q (sp+25), y; Set the next block, to the next right pointer. - sta.q sp+17 ; Save the next block in the second local variable. - ora.d sp+21 ; Is the next block NULL? - beq @setheapl ; Yes, so set the last block. -@setprev: - lda.q sp+25 ; Get the current block. - ldy #fblk.prev ; Set the previous block to the current block. - sta.q (sp+17), y; - bra @chklmerge ; Do the left block merge. -@setheapl: - lda.q sp+25 ; Get the current block. - sta.q heapl ; Set the last block to the current block. - bra @chklmerge ; Do the left block merge. -@normerge: - lda.q sp+9 ; Get the right pointer. - ldy #fblk.next ; Set the next block to the right pointer. - sta.q (sp+25), y; - lda.q sp+25 ; Get the current block. - ldy #fblk.prev ; Set the previous right pointer to the current block. - lda.q (sp+9), y ; -@chklmerge: - lda.q sp+1 ; Get the left pointer. - ora.d sp+5 ; Is the left pointer NULL? - bne @chklmerge2 ; No, so keep checking. -@newstart: - ldy #fblk.prev ; Clear the previous block. - sta.q (sp+25), y; - lda.q sp+25 ; Get the current block. - sta.q heapf ; Set the first block, to the current block. - bra @end2 ; We are done. -@chklmerge2: - ldy #fblk.size ; Get the size of the left block. - lda.q (sp+1), y ; - clc ; Prepare for a non carrying add. - adc.q sp+1 ; Add the size of the left block, to the left pointer. - cmp.q sp+25 ; Is the left block adjacent? - bne @nolmerge ; No, so don't merge the left block. -@lmerge: - lda.q (sp+1), y ; Get the size of the left block. - clc ; Prepare for a non carrying add. - ldb.q (sp+25), y; Get the size of the current block. - adc b ; Add the size of the left block, with the size of the current block. - sta.q (sp+1), y ; Set the size of the left block to the new size. -@lmerge2: - ldy #fblk.next ; Get the next block. - lda.q (sp+25), y; - sta.q (sp+1), y ; Set the next left pointer, to the next block. - sta.q sp+17 ; Set the second local variable to the next block. - ora.d sp+21 ; Is the next left pointer NULL? - beq @newlast ; Yes, so set the last block. -@lprev: - lda.q sp+1 ; Get the left pointer. - ldy #fblk.prev ; Set the next left pointer's previous pointer to the left pointer. - sta.q (sp+17), y; - bra @end2 ; We are done. -@newlast: - lda.q sp+1 ; Get the left pointer. - sta.q heapl ; Set the last block, to the left pointer. - bra @end2 ; We are done. -@nolmerge: - lda.q sp+25 ; Get the current block. - ldy #fblk.next ; Set the next left pointer, to the current block. - sta.q (sp+1), y ; -@nolmerge2: - lda.q sp+1 ; Get the left pointer. - ldy #fblk.prev ; Set the previous block, to the left pointer. - sta.q (sp+25), y; -@end2: - ads #$20 ; Clean up the stack frame. - ply.q ; Restore Y. - plb.q ; Restore B. - pla.q ; Restore A. - rts ; End of free. - -a -q diff --git a/programs/sub-suite/tmp-stuff/print_char.s b/programs/sub-suite/tmp-stuff/print_char.s deleted file mode 100644 index e12461c..0000000 --- a/programs/sub-suite/tmp-stuff/print_char.s +++ /dev/null @@ -1,147 +0,0 @@ -print_char: -; sta a ; Save the typed character for now. - pha ; Preserve the character. -; ldb #2 ; Make sure that set_ptr sets the third pointer. - lda.d #buffer ; Set the third pointer to the start of the screen buffer. - pha.q ; Push the pointer onto the stack. - lda sp+9 ; Get the character back. -; jsr set_ptr ; -; ldb #0 ; Set B to zero. -; tba ; Set the Accumulator to zero. -; lda a ; Get back the character. - cmp #$1B ; Did the user type an escape character? - beq esc ; Yes, so go check the escape code. - cmp #'\n' ; No, but did the user type a newline? - beq nl ; Yes, so handle the newline. - cmp #$C ; No, but did the user type Ctrl+L? - beq clr_scr ; Yes, so clear the screen. - cmp #19 ; No, but did the user type Ctrl+S? - beq en_step ; Yes, so enable clock/instruction stepping. - cmp #18 ; No, but did the user type Ctrl+R? - beq dis_step ; Yes, so disable clock/instruction stepping. - cmp #'\b' ; No, but did the user type a backspace? - beq bs ; Yes, so handle the backspace. - cmp #$7F ; No, but did they type Delete? - beq bs ; Yes, so treat it as a backspace. -printc: - lda #0 ; No, so start trying to print a character. - sta d ; - lda (sp+1), y ; Are we at the end of the string? - beq @save ; Yes, so just print the character. - lda b ; No, but was the flag set? - bne @save ; Yes, so don't shift the line. - sty.w scr_ptr ; No, so save the cursor index for later. - jsr fndend ; Find the end of the line. - bra @shift ; Start shifting the line right. -@update: - lda scr_col ; Save the current column position for later. - sta scr_tcol ; -@update1: - jsr findend ; Find the end of the line. - sta e ; Use it for redrawing the line. - sta scr_row ; Set the row position to to the end of the line. - jsr findst ; Find the start of the line. - lda scr_row ; Get the start of the line. -@update2: - sta f ; Set the starting line, to the start of the line. - jsr rdrw_ln ; Redraw the line. - lda scr_trow ; Get the real row position back. - sta scr_row ; - lda scr_tcol ; Get the real column position back. - sta scr_col ; - jsr update_pos ; Update the cursor's position. - dec d ; - bra @save1 ; -@shift: - ldy.w scr_ptr3 ; - inc scr_ptr3 ; - tyx ; - dey ; - ldb #1 ; - stb d ; - jsr shftln ; - ldb #1 ; - stb d ; -; lda a ; - lda sp+9 ; - sta (sp+1), y ; store typed character into the input buffer. - lda scr_row ; - sta scr_trow ; - bra @update ; -@save: - ldb d ; - bne @update ; -@save1: -; lda a ; - lda sp+9 ; - sta (sp+1), y ; store typed character into the input buffer. -@incr: - inc scr_col ; Increment the cursor's x coordinate. - iny ; -@wrapped: - ldb #1 ; - stb f ; - ldb scr_col ; - cpb #maxcol+1 ; - bcs @scrolled ; -@print: - sta scr ; Echo typed character. - ldb f ; - beq @wrap ; - bra printc_end ; -@scrolled: - ldb scr_row ; - cpb #maxrow ; - bcs @scroll ; -@wrapped2: - ldb #0 ; - stb f ; - bra @print ; -@scroll: - sta scr ; Echo typed character. - clc ; - lda #1 ; - sta wrapped ; - jsr scrl_down ; -@wrap: - ldb #0 - stb scr_col ; - ldb scr_row ; - cpb #maxrow ; - bcs @wrap2 ; -@wrap1: - inc scr_row ; -@wrap2: - phx.w ; - clc ; - lda scr_row ; - adc scr_str ; - tax ; - jsr setbit ; - plx.w ; - jsr update_pos ; -printc_end: - pla.q ; Pull the pointer off the stack. - pla ; Pull the character off the stack. - and #0 ; Reset A. - rts ; - -nl: - lda #0 ; Reset A. - ldb (sp+1), y ; Is this character not a null terminator? - bne @scroll ; Yes, so don't overwrite it. - sta (sp+1), y ; No, so overwrite it. -@scroll: - sta scr_col ; Move the cursor to the start of the next line. - lda scr_row ; Get the row position. - cmp #maxrow ; Are we at the bottom of the screen? - bcc @incr ; No, so move down one line. - jsr scrl_down ; Yes, so scroll down one line. - bra @end ; We are done. -@incr: - inc scr_row ; Move the cursor down by one line. - jsr update_pos ; Update the cursor's position. -@end: - lda #'\n' ; Print the newline. - sta a ; - rts ; diff --git a/programs/sub-suite/tmp-stuff/shift_line.c b/programs/sub-suite/tmp-stuff/shift_line.c deleted file mode 100644 index 365666b..0000000 --- a/programs/sub-suite/tmp-stuff/shift_line.c +++ /dev/null @@ -1,85 +0,0 @@ -#include - -const uint8_t bits[8] = { - 0x80, - 0x40, - 0x20, - 0x10, - 0x08, - 0x04, - 0x02, - 0x01 -}; - -int maxcol = 80; -int scr_str = 0; -int scr_row = 0; -int scr_col = 0; -uint8_t bitabl[16]; - -uint8_t bitpos(unsigned int row, uint8_t *mask) { - uint8_t bit = row & 7; - *mask = bits[bit]; - return row >> 3; - -} - -uint8_t getbit(unsigned int row, unsigned int offset) { - uint8_t mask; - uint8_t byte = bitpos(row+offset, &mask); - return (bitabl[byte] & mask); -} - -void setbit(unsigned int row) { - uint8_t mask; - uint8_t byte = bitpos(row, &mask); - bitabl[byte] |= mask; -} - -void clrbit(unsigned int row) { - uint8_t mask; - uint8_t byte = bitpos(row, &mask); - bitabl[byte] &= ~mask; -} - -int find_end(char *str, int start) { - int i; - for (i = start; str[i]; i++); - return i; -} - -void shift_line(char *str, int cursor, int left) { - /*int cursor = ((scr_row+scr_str)*maxcol)+scr_col;*/ - int end = find_end(str, cursor); - if (left) { - int i = end-1; - int j = end; - for (; i >= cursor; i--, j--) { - if (i < 0) { - i = 0; - str[i] = 0; - break; - } - str[j] = str[i]; - str[i] = 0; - - } - /*str[i+1] = (!str[i+1]) ? ' ' : str[i+1];*/ - end = find_end(str, i+2); - /*str[i+1] = (str[i+1] == ' ') ? 0 : str[i+1];*/ - if ((end/maxcol) > scr_row) { - setbit(end/maxcol); - } - } else { - int i = cursor; - int j = cursor-1; - for (; str[i]; i++, j++) { - str[j] = str[i]; - str[i] = 0; - } - end = find_end(str, i); - if (((end-1) % maxcol) == 0 && ((end-1)/maxcol) > scr_row) { - clrbit(end/maxcol); - } - } -} diff --git a/programs/sub-suite/tmp-stuff/subeditor-new.s b/programs/sub-suite/tmp-stuff/subeditor-new.s deleted file mode 100644 index 6c1cfb1..0000000 --- a/programs/sub-suite/tmp-stuff/subeditor-new.s +++ /dev/null @@ -1,1119 +0,0 @@ -; SuBEditor. -; -; Writen in Sux assembly by -; mr b0nk 500 - - -.org $8000 -reset: - cps ; Reset the processor status register. - ldx.w #$FFFF ; Reset the stack pointer. - txs ; - ldy #0 ; Reset the Y register. - sty end ; - tyx ; Reset the X register. - lda #maxrow ; Set the end of the screen to the screen's max row count. - sta scr_end ; - tya ; Reset the Accumulator. - sta scr_str ; Set the start of the screen back to zero. - sta.q bitabl ; Reset the first half of the linewrap table. - sta.q bitabl+8 ; Reset the second half of the linewrap table. - inc end ; - lda.w #$1FFF ; Set the clear count to $1FFF. - pha.w ; Push the clear count to the stack. - lda.d #buffer ; Set the array to be cleared to the screen buffer. - pha.q ; Push it on to the stack. - jsr clr_arr ; Clear the screen buffer. - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - and #0 ; Reset A. - jsr pnt_strt ; Print the starting message. - lda #$C ; Clear the screen. - sta scr ; - bra start ; Goto the start of the main program. - -clr_arr: - phb ; Preserve whatever was in B. - ldb #0 ; Clear B. - clc ; Prepare for a non carrying add. - adc #8 ; Set the second pointer to the parameter, plus eight. - pha.q ; Push it onto the stack. - tba ; -@loop: - cpy.w sp+26 ; Did we clear all of the array? - bcs @end ; Yes, so we're done. - sta.q (sp+18), y; No, so clear eight bytes. - sta.q (sp+1), y ; Clear eight more bytes. - tya ; Copy the array index. - adc #$10 ; Increment the index by 16. - tay ; Update the index. - tba ; Reset the Accumulator. - sta.q (sp+18), y; Do this one more time, to clear 32 bytes. - sta.q (sp+1), y ; - tya ; - adc #$10 ; - tay ; - tba ; - bra @loop ; Keep looping. -@end: - ldy.w zero ; Set the index back to zero. - pla.q ; Move the stack pointer back. - tba ; Reset A. - plb ; Get whatever was in the B register, back. - rts ; End of clr_arr. - -pnt_strt: - lda.w #ed_name ; Print the name of the editor. - jsr print_str ; - lda.w #ver_str ; Print the version text. - jsr print_str ; - lda.w #ed_ver ; Print the version number. - jsr print_str ; - lda.w #ed_sver ; Print the sub version number. - jsr print_str ; - lda #'\n' ; Print a newline. - jsr print_char ; - lda.w #made ; Print the "Created by" text. - jsr print_str ; - lda.w #author ; Print the name of the author. - jsr print_str ; - lda #'\n' ; Print a newline. - jsr print_char ; - rts ; End of pnt_strt. - -start: - lda #0 ; TODO: Update this for the Super VIA. - sta status ; Clear the control register of the I/O adapter. - tax ; Reset X. - phy.w ; Save the cursor index for later. - tay ; Reset the cursor index. - lda.w #$3FF ; Set the clear count to $3FF. - pha.w ; Push the clear count onto the stack. - lda.d #cmd_buf ; Set the array to be cleared to the command buffer. - pha.q ; Push the pointer onto the stack. - jsr clr_arr ; Clear the command buffer. - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - ply.w ; Get back the cursor index. - and #0 ; Reset the Accumulator. - sta end ; - bra read ; Start reading the keyboard. - -read: - lda #0 ; Reset the Accumulator. - sta end ; Disable the dummy flag. - inc end ; Enable the dummy flag. - lda status ; Did we get a key? - beq read ; No, so try again. - jsr getchar ; Yes, and was it a newline? - beq parse ; Yes, so start parsing the line. - bra read ; No, so keep looping. - -parse: - lda #0 ; - tax ; - jsr subasm ; - bra start ; - - -print_str: - ldx #0 ; Reset X. - pha.q ; Push the parameter onto the stack. -@loop: - ldb #1 ; Enable replace mode. - stb b ; - and #0 ; No, reset the accumulator. - phy.w ; Save the cursor index. - txy ; Copy the string index into Y. - lda (sp+3), y ; Are we at the end of the string? - ply.w ; Get the cursor index back. - beq @end ; Yes, so we're done. - inx ; No, so increment the string index. - jsr print_char ; Print the character. - bra @loop ; Keep looping. -@end: - pla.q ; Pull the parameter off the stack. - ldb #0 ; Enable insert mode. - stb b ; - tba ; Reset A. - rts ; End of print_str. - -getbit: - clc ; Clear the carry flag. - lda scr_str ; Has the screen been scrolled? - bne getbt0 ; Yes, so add the screen offset to the current line number. - ldx scr_row ; No, so just use the current line number. - bra getbt1 ; Start getting the bit. -getbt0: - lda scr_row ; Get the current line number. - adc scr_str ; Add the screen offset to it. - tax ; Use it as the wrap index. -getbt1: - tab ; Save the parameter. - lda.d #bitabl ; Set the second pointer to the linewrap table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - jsr bitpos ; Get the bit, and byte position. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (sp+3), y ; Get one byte of the wrap table. - ply.w ; Get the screen index back. - aba ; Mask out the bit of the current line number. - cmp #1 ; Set the carry flag, if true. - bra bitout ; We are done. - -clrbit: - tab ; Save the parameter. - lda.d #bitabl ; Set the second pointer to the linewrap table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - jsr bitpos ; Get the bit, and byte position. - xor #$FF ; Invert the bitmask. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (sp+3), y ; Get one byte of the wrap table. - aba ; Clear the bit of the current line number. -bitsav: - sta (sp+3), y ; Update the wrap table. - ply.w ; Get the screen index back. -bitout: - pla.q ; Pull the pointer off the stack. - and #0 ; Reset A. - ldx bitmask ; Return the bitmask. - rts ; We are done. - -setbit: - tab ; Save the parameter. - lda.d #bitabl ; Set the second pointer to the linewrap table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - jsr bitpos ; Get the bit, and byte position. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (sp+3), y ; Get one byte of the wrap table. - oab ; Set the bit of the current line number. - bra bitsav ; Save the bit. - -bitpos: - tab ; Save the parameter. - lda.w #bits ; Set the first pointer to the bitmask table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - stx bitmask ; Make the line number the bitmask. - txa ; Copy it to the Accumulator. - and #7 ; Get the bit position. - phy.w ; Save the cursor index. - tay ; Use the bit position as the index. - tax ; Copy it into X. - lda (sp+3), y ; Get the bitmask. - ply.w ; Get back the cursor index. - pha ; Save the bitmask. - lda bitmask ; Get the line number. - lsr #3 ; Get the byte position. - tax ; Copy it into X. - pla ; Get back the bitmask. - tab ; Preserve the bitmask. - pla.q ; Pull the pointer off the stack. - tba ; Get the bitmask back. - rts ; End of bitpos. - -getchar: - lda kbd ; Get the character that was typed from the keyboard. - ldb #0 ; Reset the B register. - stb e ; Set the temporary row position to zero, in case we get a newline. - stb b ; Enable insert mode. - pha ; Save the character. - phy.w ; Save the cursor index. - cmp #'\n' ; Was the character that was typed, a newline? - bne @print ; No, so just print the character. - jsr cmd_cpy ; Yes, so start copying the line to the command buffer. -@print: - ply.w ; Get back the cursor index. - pla ; Get back the character. - ldb e ; Is the temporary row position non zero? - bne @row ; Yes, so reset the row positon. -@print1: - jsr print_char ; No, so print the character. - lda a ; Get the return value. - cmp #'\n' ; Is the return value, a newline? - beq @true ; Yes, so return true. - bra @false ; No, so return false. -@row: - ldb e ; Get the temporary row position. - cpb #maxrow ; Is temporary row position, at, or above the bottom of the screen? - beq @row2 ; Yes, so leave it as is. - bcs @row1 ; No, so set it to the bottom of the screen. - bra @row2 ; Yes, so leave it as is. -@row1: - ldb #maxrow ; Set the row position to the bottom of the screen. -@row2: - stb scr_row ; Set the row position. - bra @print1 ; Print the character. -@true: - lda #0 ; Return true. - bra @end ; We are done. -@false: - lda #1 ; Return false. -@end: - rts ; End of getchar. - - -cmd_cpy: - lda scr_row ; Get the row position. - sta scr_trow ; Save it for later. - jsr findend ; Find the end of the 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: - sec ; Yes, so make sure that we don't subtract by the starting point, plus one. - sbc scr_str ; Offset the row position, back by the screen's starting point. - clc ; Clear the carry flag, so that nothing odd occurs. -@start: - sta scr_row ; Set the row position to the end of the line. - sta e ; Save it into the temporary row posiition. - jsr findst ; Find the start of the line. - clc ; Clear the carry flag. - lda scr_row ; Get the row position. - adc scr_str ; Add it with the screen's starting row. - mul #maxcol+1 ; Multiply it with the width of the screen, plus one. - tay ; Place it into the index. - ldx.w #0 ; Reset the X register. - ldb #0 ; Make sure that set_ptr sets the first pointer. - lda.d #buffer ; Set the first pointer to the start of the screen buffer. - pha.q ; Push the pointer onto the stack. - lda.d #cmd_buf ; Set the second pointer to the start of the command buffer. - pha.q ; Push the pointer onto the stack. - tba ; Set the accumulator to zero. -@loop: - ldb #0 ; Reset the B register. - lda.q (sp+9), y ; Get eight bytes from the current line. -@loop1: - phy.w ; Save the screen index. - txy ; Get the command buffer index. - sta (sp+3), y ; Copy one byte from the screen buffer, to the command buffer. - inx ; Increment the command buffer index. - ply.w ; Get back the screen index. - cpx.w #$3FF ; Are we at the end of the command buffer? - bcs @end ; Yes, so we're done. - iny ; No, so increment the screen index. - inb ; Increment the byte count. - lsr #8 ; Shift in the next byte. - stb g ; Save the byte count. - tab ; Save the string buffer. - and #$FF ; Is this byte of the buffer, a null terminator? - beq @end1 ; Yes, so we're done. - tba ; No so get back the string buffer. - ldb g ; Get back the byte count. - cpb #7 ; Did we shift in eight bytes? - beq @loop ; Yes, so get eight more bytes. - bra @loop1 ; No, so keep shifting in more bytes. -@end: - ldb #0 ; Reset B. - phy.w ; Save the screen index. - txy ; Get the command buffer index. - stb (sp+3), y ; Terminate the command buffer. - ply.w ; Get back the screen index. -@end1: - pla.q ; Pull one of the pointers off the stack. - pla.q ; Pull the other pointer off the stack. - tba ; The B register is zero, so clear the Accumulator. - rts ; End of cmd_cpy. - - -findst: - lda #0 ; Reset A. -@loop: - pha ; Save the current line number. - jsr getbit ; Is this the start of the line? - pla ; Get the current line number back. - bcc @end ; Yes, so we're done. - inc ; No, so check the next physical line. - dec scr_row ; Are we at the top of the screen? - bpo @loop ; No, so keep looping. - dec ; Yes, so move back one line. - inc scr_row ; Put the row postiion back to zero. -@end: - cmp #0 ; Update all the flags. - rts ; End of findst. - - -fndend: - lda.d #buffer ; Set the first pointer to the start of the screen buffer. - pha.q ; Push the pointer onto the stack. - phb ; Save the contents of the B register. - ldb #0 ; Make sure that set_ptr sets the first pointer. - tba ; Set the Accumulator to zero. - plb ; Restore the contents of the B register. - phy.w ; -@loop: - lda (sp+3), y ; Are we at the end of the string? - beq @end ; Yes, so we're done. - iny ; No, so increment the cursor index. - bra @loop ; Keep looping. -@end: - sty.w scr_ptr3 ; - ply.w ; - pla.q ; Pull the pointer off the stack. - and #0 ; Reset A. - rts ; End of fndend. - -findend: - jsr fndend ; - lda.w scr_ptr3 ; - div #maxcol+1 ; - rts ; - - -print_char: - sta a ; Save the typed character for now. - ldb #2 ; Make sure that set_ptr sets the third pointer. - lda.d #buffer ; Set the third pointer to the start of the screen buffer. - jsr set_ptr ; - ldb #0 ; Set B to zero. - tba ; Set the Accumulator to zero. - lda a ; Get back the character. - cmp #$1B ; Did the user type an escape character? - beq esc ; Yes, so go check the escape code. - cmp #'\n' ; No, but did the user type a newline? - beq nl ; Yes, so handle the newline. - cmp #$C ; No, but did the user type Ctrl+L? - beq clr_scr ; Yes, so clear the screen. - cmp #19 ; No, but did the user type Ctrl+S? - beq en_step ; Yes, so enable clock/instruction stepping. - cmp #18 ; No, but did the user type Ctrl+R? - beq dis_step ; Yes, so disable clock/instruction stepping. - cmp #'\b' ; No, but did the user type a backspace? - beq bs ; Yes, so handle the backspace. - cmp #$7F ; No, but did they type Delete? - beq bs ; Yes, so treat it as a backspace. -printc: - lda #0 ; No, so start trying to print a character. - sta d ; - lda (ptr3), y ; Are we at the end of the string? - beq @save ; Yes, so just print the character. - lda b ; No, but was the flag set? - bne @save ; Yes, so don't shift the line. - sty.w scr_ptr ; No, so save the cursor index for later. - jsr fndend ; Find the end of the line. - bra @shift ; Start shifting the line right. -@update: - lda scr_col ; Save the current column position for later. - sta scr_tcol ; -@update1: - jsr findend ; Find the end of the line. - sta e ; Use it for redrawing the line. - sta scr_row ; Set the row position to to the end of the line. - jsr findst ; Find the start of the line. - lda scr_row ; Get the start of the line. -@update2: - sta f ; Set the starting line, to the start of the line. - jsr rdrw_ln ; Redraw the line. - lda scr_trow ; Get the real row position back. - sta scr_row ; - lda scr_tcol ; Get the real column position back. - sta scr_col ; - jsr update_pos ; Update the cursor's position. - dec d ; - bra @save1 ; -@shift: - ldy.w scr_ptr3 ; - inc scr_ptr3 ; - tyx ; - dey ; - ldb #1 ; - stb d ; - jsr shftln ; - ldb #1 ; - stb d ; - lda a ; - sta (ptr3), y ; store typed character into the input buffer. - lda scr_row ; - sta scr_trow ; - bra @update ; -@save: - ldb d ; - bne @update ; -@save1: - lda a ; - sta (ptr3), y ; store typed character into the input buffer. -@incr: - inc scr_col ; Increment the cursor's x coordinate. - iny ; -@wrapped: - ldb #1 ; - stb f ; - ldb scr_col ; - cpb #maxcol+1 ; - bcs @scrolled ; -@print: - sta scr ; Echo typed character. - ldb f ; - beq @wrap ; - bra printc_end ; -@scrolled: - ldb scr_row ; - cpb #maxrow ; - bcs @scroll ; -@wrapped2: - ldb #0 ; - stb f ; - bra @print ; -@scroll: - sta scr ; Echo typed character. - clc ; - lda #1 ; - sta wrapped ; - jsr scrl_down ; -@wrap: - ldb #0 - stb scr_col ; - ldb scr_row ; - cpb #maxrow ; - bcs @wrap2 ; -@wrap1: - inc scr_row ; -@wrap2: - phx.w ; - clc ; - lda scr_row ; - adc scr_str ; - tax ; - jsr setbit ; - plx.w ; - jsr update_pos ; -printc_end: - rts ; - -nl: - lda #0 ; Reset A. - ldb (ptr3), y ; Is this character not a null terminator? - bne @scroll ; Yes, so don't overwrite it. - sta (ptr3), y ; No, so overwrite it. -@scroll: - sta scr_col ; Move the cursor to the start of the next line. - lda scr_row ; Get the row position. - cmp #maxrow ; Are we at the bottom of the screen? - bcc @incr ; No, so move down one line. - jsr scrl_down ; Yes, so scroll down one line. - bra @end ; We are done. -@incr: - inc scr_row ; Move the cursor down by one line. - jsr update_pos ; Update the cursor's position. -@end: - lda #'\n' ; Print the newline. - sta a ; - rts ; - - -clr_scr: - lda #maxrow ; - sta scr_end ; - lda #0 ; - sta scr_str ; - sta.q bitabl ; - sta.q bitabl+8 ; - tay ; - lda.w #$1FFF ; Set the clear count to $1FFF. - pha.w ; Push the clear count onto the stack. -; sta.w scr_ptr ; - lda.d #buffer ; Set the array to be cleared to the screen buffer. - pha.q ; Push the pointer onto the stack. - jsr clr_arr ; Clear the screen buffer. - tay ; - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - lda.w #$3FF ; Set the clear count to $3FF. - pha.w ; Push the clear count onto the stack. -; sta.w scr_ptr ; - lda.d #cmd_buf ; Set the array to be cleared to the command buffer. - pha.q ; - jsr clr_arr ; Clear the screen buffer. - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - and #0 ; Reset A. - sta scr_col ; - sta scr_row ; - jsr update_pos ; - lda #$C ; - sta scr ; - rts ; - -en_step: - lda step ; - beq step_en ; - rts ; -step_en: - lda #1 ; - sta step ; - rts ; - -dis_step: - lda step ; - bne step_dis ; - rts ; -step_dis: - lda #0 ; - sta step ; - rts ; - - -bs: - lda scr_col ; Are we at the far left of the screen? - beq @wrap ; Yes, so check for a wrapped line. - bra back ; No, so add the backspace to the buffer. -@wrap: - jsr getbit ; Is this line, a wrapped line? - bcs @wrap1 ; Yes, so check if the cursor is at the top. - rts ; No, so we're done. -@wrap1: - lda scr_row ; Are we at the top of the screen? - beq @wrap2 ; Yes, so check if the screen is at the top of the buffer. - bra @wrap3 ; No, so start clearing the wrap bit. -@wrap2: - lda scr_str ; Are we at the top of the buffer? - bne @scroll ; Yes, so scroll up. - rts ; No, so we're done. -@scroll: - clc ; Clear the carry flag, so that we don't get odd behaviour. - jsr scrl_up ; Scroll up. - inc scr_row ; Move down by one row. -@wrap3: - clc ; Clear the carry flag. - lda scr_row ; Add the cursor's row position, - adc scr_str ; and the screen's starting row. - tax ; Transfer that into X. -@wrap4: - dec scr_row ; Move up by one row. - ldb #maxcol+1 ; Move the cursor to the absolute right of the screen. - stb scr_col ; - jsr update_pos ; Update the cursor's position. -back: - ldb #0 ; Reset B, and some flags. - stb e ; - stb f ; - lda scr_row ; Save the current row position for later. - sta scr_trow ; - jsr findend ; Find the end of the line. - sta scr_row ; Set our row position to the end of the line. -@find_st: - jsr findst ; Does this line take up more than one real line? - beq @shift ; No, so skip updating any other lines. - bcs @update ; Yes, so update the other lines. - lda scr_trow ; Get the real row position back. - sta scr_row ; -@shift: - dey ; Decrement the buffer's offset. - lda #0 ; Place a null terminator - sta (ptr3), y ; into the buffer. - tyx ; Copy the current cursor index to X. - iny ; Increment cursor index. - ldb #0 ; Set shifting direction to left. - stb d ; - jsr shftln ; Shift line back by one character. - lda #$7F ; Print a backspace to the screen. - sta scr ; - lda e ; Are we updating more than one line? - beq @load ; No, so skip to the next step. -@find_end: - jsr findend ; Yes, so find the end of the line. - sta e ; Set the end parameter to it. - lda scr_col ; Save the current column position for now. - sta scr_tcol ; - jsr rdrw_ln ; Start redrawing the line. - lda scr_tcol ; Get the real column position back. - sta scr_col ; -@load: - lda scr_trow ; Get the real row position back. - sta scr_row ; - dec scr_col ; Move the cursor back by one column, - jsr update_pos ; and update it's position. - rts ; We are done. -@update: - lda scr_row ; Set the line to start redrawing, to the start of the line. - sta f ; - inc e ; Set the redraw flag to true. - bra @shift ; Start shifting the line back. - - -shftln: - ldb d ; Is the flag not set? - beq @dec_loop ; Yes, so shift, and decrement. - ldb #0 ; Clear the B register. - bra @inc_loop ; No, so shift, and increment. -@neg: - ldy.w zero ; Set the source poition to 0. - stb (ptr3), y ; Clear the character that is in the source. - bra @end ; We are done. -@inc_loop: - sty.w scr_ptr2 ; Save the source position for later. - ldy.w scr_ptr ; Get the previous cursor index. - cpy.w scr_ptr2 ; Is the source position, at, or below the cursor index? - beq @inc_loop1 ; Yes, so keep looping. - bcs @end ; No, so we're done. -@inc_loop1: - ldy.w scr_ptr2 ; Get the source position. - lda (ptr3), y ; Get the character from the source position. - phy.w ; Save the source position for later. - txy ; Set our position to the destination. - sta (ptr3), y ; Place the character from the source position, to the destination position. - ply.w ; Set our position back to the source. - stb (ptr3), y ; Clear the character that is in the source. - bng @neg ; The source underflowed, so set it back to zero, - dey ; Decrement the source position. - dex ; Decrement the destination position. - bra @inc_loop ; Keep looping. -@dec_loop: - stx.w scr_ptr2 ; Save the destination position for later. - lda (ptr3), y ; Is the character at the source position, a null terminator? - beq @end3 ; Yes, so we're done. - phy.w ; No, so save the source position for later. - txy ; Set our position to the destination. - sta (ptr3), y ; Place the character from the source position, to the destination position. - inx ; Increment the destination position. - ply.w ; Set our position back to the source. - stb (ptr3), y ; Clear the character that is in the source. - iny ; Increment the source position. - bra @dec_loop ; Keep looping. -@wrap: - tax ; Use the ending line as a parameter for setbit. - jsr setbit ; Set the wrap bit of the ending line. - bra @end5 ; We are done. -@wrap1: - tax ; Use the ending line as a parameter for clrbit. - jsr clrbit ; Clear the wrap bit of the ending line. - bra @end5 ; We are done. -@end: - lda (ptr3), y ; Is this character a null terminator? - bne @end1 ; No, so just find the end of the line. - lda #$20 ; Yes, so convert it to a space for now. - sta (ptr3), y ; -@end1: - jsr findend ; Find the ending line. - sta d ; Save ending line for later. - lda (ptr3), y ; Is this character a space? - cmp #$20 ; - bne @end5 ; No, so skip the conversion. - lda #0 ; Yes, so convert it back to zero. - sta (ptr3), y ; -@end2: - lda d ; Get the ending line. - cmp scr_row ; Is the ending line greater than the starting line? - beq @end5 ; No, so we're done. - bcs @wrap ; Yes, so set the wrap bit. - bra @end5 ; No, so we're done. -@end3: - jsr findend ; Find the ending line. - cpb #0 ; Is the remainder zero? - beq @end4 ; Yes, so check if the ending line is greater than the starting line. - bra @end5 ; No, so we're done. -@end4: - cmp scr_row ; Is the ending line greater than the starting line? - beq @end5 ; No, so we're done. - bcs @wrap1 ; Yes, so clear the wrap bit. -@end5: - rts ; End of shftln. - -esc: - lda status ; Get the next character. - lda kbd ; - cmp #$1B ; Is this character an escape character? - beq shftesc ; Yes, so check the other set of escape routines. - lda status ; No, so wait for the next character. - beq @end ; We have an error, so discard it, and go back to getting user input. - lda kbd ; Get the escape code. - sta c ; Store the escape code, until we need it. - lda #0 ; Set the D pseudo register to zero. - sta d ; - jsr isup ; Check if the user pressed up. - lda d ; Did the user press up? - bne @end ; Yes, so we're done. - jsr isdown ; No, so check if the user pressed down. - lda d ; Did the user press down? - bne @end ; Yes, so we're done. - lda #0 ; No, so check if the user pressed left. - jsr isleft ; - lda d ; Did the user press left? - bne @end ; Yes, so we're done. - jsr isright ; No, so check if the user pressed right. -@end: - lda #0 ; Clear the D pseudo register. - sta d ; - rts ; We are done. - -shftesc: - lda status ; Skip the '['. - lda kbd ; - lda status ; Wait for the next character. - beq @end ; We have an error, so discard it, and go back to getting user input. - lda kbd ; Get the escape code. - sta c ; Store the escape code, until we need it. - lda #0 ; Use the D pseudo register as a skip flag. - sta d ; - jsr isshftup ; Check if the user pressed shift+up. - lda d ; Was it successful? - bne @end ; Yes, so we're done. - jsr isshftdown ; No, so check if the user pressed shift+down. -@end: - lda #0 ; Clear the D pseudo register. - sta d ; - rts ; We are done. - - -isup: - lda c ; Load the escape code into the accumulator. - cmp #'A' ; Did the user press the up arrow key? - bne @end ; No, so we're done. - lda scr_row ; Yes, but is the cursor at the top of the screen? - beq @scroll ; Yes, so check if we need to scroll. -@check2: - lda c ; No, so load the escape code back into the accumulator. - cmp #'A' ; Did the user press the up arrow key? - beq @up ; Yes, so move the cursor up. - bra @end ; No, so we're done. -@up: - dec scr_row ; Move the cursor up a line. - jsr update_pos ; Update it's position. - lda #1 ; Tell the escape routine that we succeded. - sta d ; - rts ; We are done. -@scroll: - lda scr_str ; Are we at the top of the screen buffer? - beq @end ; Yes, so we're done. - jsr scrl_up ; No, so scroll up. - lda #1 ; Tell the escape routine that we were successful. - sta d ; -@end: - rts ; End of isup. - - -isdown: - lda c ; Load the escape code into the accumulator. - cmp #'B' ; Did the user press the down arrow key? - bne @end ; No, so we're done. - lda scr_row ; Yes, so start checking the y coordinate of the cursor. - cmp #maxrow ; Is the cursor at the bottom of the screen? - beq @scroll ; Yes, so scroll down. - lda c ; No, so load the escape code back into the accumulator. - cmp #'B' ; Did the user press the down arrow key? - beq @down ; Yes, so move the cursor down. - bra @end ; No, so we're done. -@down: - inc scr_row ; Move the cursor down a line. - jsr update_pos ; Update it's position. - lda #1 ; Tell the escape routine that we succeded. - sta d ; - rts ; We are done. -@scroll: - lda scr_row ; Save the cursor's row number. - sta scr_trow ; - lda scr_col ; Save the cursor's column number. - sta scr_tcol ; - jsr scrl_down ; Scroll down. - lda scr_trow ; Load the cursor's row number. - sta scr_row ; - lda scr_tcol ; Load the cursor's column number. - sta scr_col ; - lda #1 ; Tell the escape routine that we were successful. - sta d ; -@end: - rts ; End of isdown. - - -isright: - lda c ; Load the escape code into the accumulator. - cmp #'C' ; Did the user press the right arrow key? - bne @end2 ; No, so we're done. - lda scr_col ; Yes, so start checking the x coordinate of the cursor. - cmp #maxcol ; Is the cursor at the far right of the screen? - beq @wrap ; Yes, so check if this is a wrapped line. - bra @right ; No, so move the cursor right, like normal. -@wrap: - inc scr_row ; Move down a row. - jsr getbit ; Is the current line, a wrapped line? - bcs @incr ; Yes, so leave the cursor where it is. - dec scr_row ; No, so move the cursor back up a row. - bra @end2 ; We are done. -@scroll: - lda scr_str ; Are we at the top of the screen buffer? - beq @end ; Yes, so we're done. - lda #1 ; No, so scroll down. - sta wrapped ; Set the wrapped flag. - jsr scrl_down ; Scroll down. - bra @end ; We are done. -@incr: - lda #0 ; Set the cursor to the far left of the screen. - sta scr_col ; - lda scr_row ; Get the current row number. - cmp #maxrow ; Are we at the bottom of the screen? - beq @end1 ; No, so we're done. - bcs @scroll ; Yes, so check if we are scrolling down. - bra @end1 ; No, so we're done. -@right: - inc scr_col ; Move the cursor right by one character. - jsr update_pos ; Update it's position. - rts ; End of isright. -@end: - dec scr_row ; Move back up a row. -@end1: - jsr update_pos ; Update the cursor position. -@end2: - lda #0 ; Unset the wrapped flag. - sta wrapped ; - rts ; End of isright. - - -isleft: - lda c ; Load the escape code into the accumulator. - cmp #'C' ; Did the user press right? - beq @end1 ; Yes, so we're done - lda scr_col ; No, but is the cursor at the far left of the screen? - beq @wrap ; Yes, so start checking if this is a wrapped line. - lda c ; No, so load the escape code back into the accumulator. - cmp #'D' ; Did the user press the left arrow key? - beq @left ; Yes, so move the cursor left. - bra @end1 ; No, so we're done. -@wrap: - jsr getbit ; Is the current line, a wrapped line? - bcs @decr ; Yes, so wrap back up a line. - bra @end1 ; No, so we're done. -@decr: - lda scr_row ; Is the cursor at the top of the screen? - beq @decr1 ; Yes, so don't move up a line. - lda #1 ; No, so set the wrapped flag. - sta wrapped ; - dec scr_row ; Move the cursor up one line. -@decr1: - lda #maxcol ; Move the Cursor to the far right of the screen. - sta scr_col ; - lda #1 ; Tell the escape routine that we were successful. - sta d ; - lda scr_row ; Are we at the top of the screen? - beq @scroll ; Yes, so check if we need to scroll. - bra @end ; No, so we're done. -@scroll: - lda wrapped ; Was the wrapped flag set somewhere else? - bne @end ; Yes so we're done. - lda scr_str ; No, but are we actually at the top of the screen buffer? - beq @end1 ; Yes, so we're done. - jsr scrl_up ; No, so scroll up. - bra @end1 ; We are done. -@left: - dec scr_col ; Move the cursor left a character. - jsr update_pos ; Update it's position. - lda #1 ; Tell the escape routine that we succeded. - sta d ; - rts ; We are done -@end: - jsr update_pos ; Update the cursor position. -@end1: - lda #0 ; Unset the wrapped flag. - sta wrapped ; - rts ; End of isleft. - - -isshftup: - lda c ; Load the escape code back into the accumulator. - cmp #'A' ; Did the user press the up arrow key? - bne @end ; - lda #1 ; - sta d ; - lda scr_str ; - beq @end ; -@shftup: - jsr scrl_up ; - lda #1 ; - sta d ; -@end: - rts ; - - -isshftdown: - lda c ; Load the escape code back into the accumulator. - cmp #'B' ; Did the user press the down arrow key? - bne @end ; - lda #1 ; - sta d ; - lda scr_end ; - cmp #71 ; - bcs @end ; -@shftdown: - jsr scrl_down ; - lda #1 ; - sta d ; -@end: - rts ; - - -update_pos: - ldb #1 ; Set the F pseudo register to one, to fix some bugs. - stb f ; - clc ; Clear the carry flag. - lda scr_row ; Add the cursor's line number, - adc scr_str ; with the starting line number to get the absolute line number. - tay ; Place it in the Y regster for now. - mul #maxcol+1 ; Multiply the line number by the screen's max column count, plus 1. - clc ; Clear the carry flag. - adc scr_col ; Add the cursor's column number to get the screen index. - tay ; Place the index into the Y register. - tba ; Reset A. - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - jsr getrow ; Start printing the row number to the screen. - jsr getcol ; Start printing the column number to the screen. - lda #'H' ; Print 'H' - sta scr ; to the screen. - rts ; End of update_pos. - -getrow: - lda scr_row ; Get the cursor's y coordinate. - bra bcd ; Convert it to BCD. -getcol: - lda #';' ; Print ';' - sta scr ; to the screen. - lda scr_col ; Get the cursor's x coordinate. -bcd: - div #10 ; Divide A by 10. - ora #'0' ; Convert it to ascii, and - sta scr ; print to the screen. - tba ; Get the remainder. - ora #'0' ; Convert it to ascii, and - sta scr ; print to the screen. - rts ; End of bcd. - -scrl_down: - inc scr_str ; Increment the starting line of the screen. - inc scr_end ; Increment the ending line of the screen. - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'T' ; Print 'T' - sta scr ; to the screen, and end the escape sequence. - lda scr_row ; Get the cursor's line number. - pha ; Save it in the stack. - lda wrapped ; Was the wrapped flag set? - beq @save ; Yes, so save the cursor position. -@redraw: - jsr rdrw_row ; No, so redraw this row. - lda wrapped ; Was the wrapped flag set? - beq @load ; Yes, so load the previous cursor position back. - bra @end ; No, so we're done. -@save: - lda scr_col ; Get the cursor's column number. - pha ; Save it in the stack. - bra @redraw ; Start redrawing the current row. -@load: - pla ; Get the cursor's previous column number back. - sta scr_col ; -@end: - pla ; Get the cursor's previous line number back. - sta scr_row ; - jsr update_pos ; Update the cursor's position. - lda #0 ; Clear the wrapped flag. - sta wrapped ; -@end1: - rts ; End of scrl_down. - -scrl_up: - dec scr_str ; - dec scr_end ; - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'S' ; Print 'S' - sta scr ; to the screen, and end the escape sequence. - lda scr_row ; - pha ; - lda scr_col ; - pha ; - lda #0 ; - sta scr_row ; - jsr rdrw_row ; - pla ; - sta scr_col ; - pla ; - sta scr_row ; - jsr update_pos ; -@end: - rts ; - -rdrw_row: - lda #0 ; - sta scr_col ; - jsr update_pos ; -@loop: - lda (ptr3), y ; - beq @incr ; - sta scr ; -@incr: - inc scr_col ; - lda (ptr3), y ; - beq @skip ; -@incr1: - iny ; -@incr2: - lda scr_col ; - cmp #maxcol+1 ; - bcs @end ; - bra @loop ; -@skip: - lda #' ' ; - sta scr ; to the screen. - bra @incr1 ; -@end: - lda #0 ; - sta scr_col ; - jsr update_pos ; -@end1: - rts ; - -rdrw_ln: - lda scr_row ; - pha ; - lda f ; - sta scr_row ; - lda scr_col ; - pha ; - jsr update_pos ; -@loop: - lda scr_row ; - cmp e ; - beq @loop1 ; - bcs @end ; -@loop1: - jsr rdrw_row ; -@incr: - inc scr_row ; - bra @loop ; -@end: - pla ; - sta scr_col ; - pla ; - sta scr_row ; - jsr update_pos ; - lda #0 ; - sta e ; - sta f ; - rts ; - -set_ptr: - cpb #1 ; Are we setting the second pointer? - beq @ptr2 ; Yes, so start setting it. - cpb #2 ; No, but are we setting the third pointer? - beq @ptr3 ; Yes, so start setting it. -@ptr1: - stb.q ptr ; Reset the first pointer. - sta.q ptr ; No, so set the first pointer. - bra @end ; We are done. -@ptr2: - stb.q ptr2 ; Reset the second pointer. - sta.q ptr2 ; Set the second pointer. - bra @end ; We are done. -@ptr3: - stb.q ptr3 ; Reset the third pointer. - sta.q ptr3 ; Set the third pointer. -@end: - rts ; End of set_ptr. diff --git a/programs/sub-suite/tmp-stuff/test-size.s b/programs/sub-suite/tmp-stuff/test-size.s deleted file mode 100644 index b543a36..0000000 --- a/programs/sub-suite/tmp-stuff/test-size.s +++ /dev/null @@ -1,59 +0,0 @@ -MAGIC = $AA - - -.org 0 -findramend: - and #0 ; Reset A. -; lda #MAGIC ; Set A to a magic number. -@loop: - mov a, (d) ; Preserve the value. - mov (d), #MAGIC ; Write the magic number to the current end of RAM. - cmp (d), #MAGIC ; Is the value in RAM, the same as the magic number we wrote? - bne @moveback ; No, so move back until we find the last writable memory location. - mov (d), a ; Yes, so restore the previous value. - add.w d, #$4000 ; Increment the end of RAM pointer by 16K. - bra @loop ; Keep looping. -@moveback: - dec d ; Decrement the end of RAM pointer. - mov a, (d) ; Preserve the value. - mov (d), #MAGIC ; Write the magic number to the current end of RAM. - cmp (d), #MAGIC ; Is the value in RAM, the same as the magic number we wrote? - bne @moveback ; No, so keep looping. - mov (d), a ; Yes, so restore the previous value. -@end: - mov a, d ; Return the end of RAM pointer. -; ple.q ; Restore E. - rts ; End of findramend. - - -;findramend: -; phe.q ; Preserve E. -; phb.q ; Preserve B. -; mov e, d ; Set E to the RAM pointer. -; and #0 ; Reset A. -; lda #MAGIC ; Set A to a magic number. -;@loop: -; ldb (e) ; Preserve the value. -; sta (e) ; Write the magic number to the current end of RAM. -; cmp (e) ; Is the value in RAM, the same as the magic number we wrote? -; bne @moveback ; No, so move back until we find the last writable memory location. -; stb (e) ; Yes, so restore the previous value. -; ade.w #$4000 ; Increment the end of RAM pointer by 16K. -; bra @loop ; Keep looping. -;@moveback: -; dee ; Decrement the end of RAM pointer. -; ldb (e) ; Preserve the value. -; sta (e) ; Write the magic number to the current end of RAM. -; cmp (e) ; Is the value in RAM, the same as the magic number we wrote? -; bne @moveback ; No, so keep looping. -; stb (e) ; Yes, so restore the previous value. -;@end: -; mov a, e ; Return the end of RAM pointer. -; ple.q ; Restore E. -; plb.q ; Restore B. -; rts ; End of findramend. - -a -.org findramend -v -q diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s index 6479099..8f4a643 100644 --- a/programs/sub-suite/utils.s +++ b/programs/sub-suite/utils.s @@ -10,12 +10,12 @@ print_hi: lea d, (sp+1) ; Get the address of the hex string buffer. mov f, #$10 ; Set digit count to 16. jsr print_hex ; Print the address. - mov.q (b), (a) ; Print the lower half of the hex string to the string buffer. - mov.q (b+8), (a+8) ; Print the upper half of the hex string to the string buffer. + mov.q (b), (d) ; Print the lower half of the hex string to the string buffer. + mov.q (b+8), (d+8) ; Print the upper half of the hex string to the string buffer. add b, #$10 ; Add 16 to the index. mov.w (b), #': ' ; Print a colon, and space to the string buffer. add b, #2 ; Add two to the string buffer pointer. - tba a ; Return the string buffer pointer after the printed string. + tba ; Return the string buffer pointer after the printed string. ads #$10 ; Cleanup the stack frame. plb.q ; Restore B. rts ; End of print_hi. @@ -34,7 +34,7 @@ print_lo: lea f, 2 ; Set the digit count to two. mov s, b ; Get the low nibble offset. jsr print_hex ; Print the low nibble offset. - mov.w (x), (a) ; Place the hex digits in the string buffer. + mov.w (x), (d) ; Place the hex digits in the string buffer. add x, #2 ; Add two to the string buffer pointer. inb ; Increment the nibble offset. cpb #$10 ; Are we at the last offset? @@ -55,34 +55,38 @@ print_lo: pla.q ; Restore A. rts ; End of print_lo. - print_chunk: pha.q ; Preserve A. phb.q ; Preserve B. phx.q ; Preserve X. phy.q ; Preserve Y. - sbs #2 ; Make room for the hex string buffer. + sbs #16 ; Make room for the hex string buffer. and #0 ; Reset A. - tab ; Reset B. + tay ; Reset Y. + ldy #2 ; Set the number of 8 byte chunks to read to 2. mov x, d ; Get the address of the string buffer. - mov y, s ; Get the starting address. + mov b, s ; Get the starting address. lea d, (sp+1) ; Get the address of the hex string buffer. - xor s, s ; Reset S. +; xor s, s ; Reset S. +@print_hex: + lda #16 ; Set the hex string index to 16. + mov f, a ; Set the digit count to 16. + dey ; Decrement the chunk count. + bng @end ; The chunk count is negative, so we're done. + mov.q s, (b) ; Read 8 bytes from that address. + jsr print_hex ; Print 8 bytes. + add b, #8 ; Add 8 to the address. @loop: - lea f, 2 ; Set the digit count to two. - mov s, (y+b) ; Get the byte at that address. - jsr print_hex ; Print the byte. - mov.w (x), (a) ; Print the hex string to the string buffer. - add x, #2 ; Add two to the string buffer pointer. - inb ; Increment the byte index. - cpb #$10 ; Have we read 16 bytes? - beq @end ; Yes, so we're done. - mov (x), #' ' ; No, so print a space to the string buffer. - inx ; Increment the string buffer pointer. - bra @loop ; Keep looping. + sub #2 ; Subtract two from the hex string index. + mov.w (x), (d+a) ; Print the hex string to the string buffer. + mov (x+2), #' ' ; Print a space to the string buffer. + add x, #3 ; Add three to the string buffer pointer. + cmp #0 ; Did we print 8 bytes? + beq @print_hex ; Yes, so read 8 more bytes. + bra @loop ; No, so keep looping. @end: - mov (x), #0 ; Null terminate the string. - ads #2 ; Cleanup the stack frame. + mov (x-1), #0 ; Null terminate the string. + ads #16 ; Cleanup the stack frame. ply.q ; Restore Y. plx.q ; Restore X. plb.q ; Restore B. @@ -91,45 +95,38 @@ print_chunk: print_hex: + pha.q ; Preserve A. phb.q ; Preserve B. phx.q ; Preserve X. phy.q ; Preserve Y. lea b, hex_char ; Get the address of the hex character table. - and f, f ; Is the digit count zero? - set x, eq ; Set the auto digit count flag if so. - mne f, #$10 ; Also set the digit count to 16 if the digit count is zero. mov a, f ; Get the digit count. - add a, d ; Add the string pointer with the digit count. + set x, eq ; Set the auto digit count flag if so. + lne #16 ; Also set the digit count to 16 if so. + cmp #17 ; Is the digit count greater than 16? + lcs #16 ; Set the digit count to 16 if so. + add d, a ; Add the string pointer with the digit count. @loop: mov y, s ; No, so mask the low nibble of the value. and y, #$F ; - dec ; Decrement the string pointer. - mov (a), (b+y) ; Place the hex digit character in the string. - lsr s, #4 ; Is the next nibble zero? + dec d ; Decrement the string pointer. + mov (d), (b+y) ; Place the hex digit character in the string. + lsr s, #4 ; Get the next nibble. bne @loop1 ; No, so decrement the digit count. @isauto: - and x, x ; Is the auto digit count flag set? - bne @end ; Yes, so we're done. -@loop1: cpx #1 ; Is the auto digit count flag set? - sbc f, #0 ; Decrement the digit count if not. - mov y, f ; Get the digit count. - or y, x ; Are both the digit count, and the auto digit count flag zero? - bne @loop ; No, so keep looping. + beq @end ; Yes, so we're done. +@loop1: + dec ; Decrement the digit count. + bne @loop ; The digit count is non zero, so keep looping. @end: ply.q ; Restore Y. plx.q ; Restore X. plb.q ; Restore B. + pla.q ; Restore A. rts ; End of print_hex. -charcpy: - ldx idx3 ; Get the string index. - sta strbuf, x ; Save it in the string buffer. - inc idx3 ; Increment the string index. - rts ; End of charcpy. - - strcmpg: lea strcmp ; Get the address of strcmp. mov.q d, ptr ; Get the first pointer. @@ -324,11 +321,11 @@ print_sfast: pha.q ; Preserve A. and #0 ; Reset A. @loop: - inc ; Increment the index. - cmp (d+a-1), #0 ; Did we hit the end of the string? + cmp (d+a), #0 ; Did we hit the end of the string? beq @end ; Yes, so we're done. - mov (s+a-1), (d+a-1) ; No, so print the character to the buffer. - mov scr, (d+a-1) ; Print the character to the screen. + mov (s+a), (d+a) ; No, so print the character to the buffer. + mov scr, (d+a) ; Print the character to the screen. + inc ; Increment the index. bra @loop ; Keep looping. @end: pla.q ; Restore A. diff --git a/test/ortho.s b/test/ortho.s index 6499d6e..b4be3d4 100644 --- a/test/ortho.s +++ b/test/ortho.s @@ -29,6 +29,7 @@ reset: lea bitabl, mem ; mov (bitabl)+a, 0 mov (d-128), #0 + lea d, (8*a+e) lea s, count mov (e), #0 mov a, (e) -- cgit v1.2.3-13-gbd6f