summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2021-02-25 12:43:11 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2021-02-25 12:43:11 -0500
commit35a18609864470b3dc49f3a9a6cb6ec93e57300d (patch)
treec52364211b25723b2cf4595ed6c4bc2d45195062
parent8d7f27d9a0b61d3694a62f3e54be885d8073f02b (diff)
- 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.
-rw-r--r--asmmon.h1
-rw-r--r--assemble.c78
-rw-r--r--disasm.c16
-rw-r--r--lexer.c13
-rw-r--r--lexer.h2
-rw-r--r--programs/sub-suite/lexer.s48
-rw-r--r--programs/sub-suite/libc.s91
-rw-r--r--programs/sub-suite/subasm.s12
-rw-r--r--programs/sub-suite/subeditor.s429
-rw-r--r--programs/sub-suite/subsuite.s2
-rw-r--r--programs/sub-suite/tmp-stuff/cmd_cpy.c33
-rw-r--r--programs/sub-suite/tmp-stuff/free-new.s143
-rw-r--r--programs/sub-suite/tmp-stuff/free-old.s200
-rw-r--r--programs/sub-suite/tmp-stuff/print_char.s147
-rw-r--r--programs/sub-suite/tmp-stuff/shift_line.c85
-rw-r--r--programs/sub-suite/tmp-stuff/subeditor-new.s1119
-rw-r--r--programs/sub-suite/tmp-stuff/test-size.s59
-rw-r--r--programs/sub-suite/utils.s91
-rw-r--r--test/ortho.s1
19 files changed, 569 insertions, 2001 deletions
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 <stdint.h>
-
-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 <stdint.h>
-
-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 <b0nk@b0nk.xyz>
-
-
-.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)