From 8d7f27d9a0b61d3694a62f3e54be885d8073f02b Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sat, 13 Feb 2021 13:59:48 -0500 Subject: - Reverted back one commit before the previous commit. This is because the previous commit actually created a bug, rather than fixing one. - Added JMP, and JSR to the ortho extension, and implemented them both in the assembler, and emulator. --- asmmon.h | 8 +- assemble.c | 6 +- disasm.c | 32 +- disasm.h | 10 +- enums.h | 10 +- lexer.c | 8 +- programs/sub-suite/free-new.s | 143 ---- programs/sub-suite/free-old.s | 200 ----- programs/sub-suite/print_char.s | 147 ---- programs/sub-suite/shift_line.c | 85 -- programs/sub-suite/subeditor-new.s | 1119 -------------------------- programs/sub-suite/subsuite.s | 2 +- programs/sub-suite/test-size.s | 59 -- programs/sub-suite/tmp-stuff/cmd_cpy.c | 33 + programs/sub-suite/tmp-stuff/free-new.s | 143 ++++ programs/sub-suite/tmp-stuff/free-old.s | 200 +++++ programs/sub-suite/tmp-stuff/print_char.s | 147 ++++ programs/sub-suite/tmp-stuff/shift_line.c | 85 ++ programs/sub-suite/tmp-stuff/subeditor-new.s | 1119 ++++++++++++++++++++++++++ programs/sub-suite/tmp-stuff/test-size.s | 59 ++ sux.c | 2 +- sux.h | 43 +- test/ortho.s | 2 + 23 files changed, 1856 insertions(+), 1806 deletions(-) delete mode 100644 programs/sub-suite/free-new.s delete mode 100644 programs/sub-suite/free-old.s delete mode 100644 programs/sub-suite/print_char.s delete mode 100644 programs/sub-suite/shift_line.c delete mode 100644 programs/sub-suite/subeditor-new.s delete mode 100644 programs/sub-suite/test-size.s create mode 100644 programs/sub-suite/tmp-stuff/cmd_cpy.c create mode 100644 programs/sub-suite/tmp-stuff/free-new.s create mode 100644 programs/sub-suite/tmp-stuff/free-old.s create mode 100644 programs/sub-suite/tmp-stuff/print_char.s create mode 100644 programs/sub-suite/tmp-stuff/shift_line.c create mode 100644 programs/sub-suite/tmp-stuff/subeditor-new.s create mode 100644 programs/sub-suite/tmp-stuff/test-size.s diff --git a/asmmon.h b/asmmon.h index e98afff..29697e5 100644 --- a/asmmon.h +++ b/asmmon.h @@ -280,13 +280,13 @@ enum baseext_ortho { static const uint8_t ext_ortho_ops[9] = { [OP_LEA] = 0x63, - [OP_PEA] = 0x0C, + [OP_PEA] = 0x4C, [OP_ADD] = 0x03, [OP_SUB] = 0x23, [OP_NOT] = 0x44, [OP_CLZ] = 0xC4, [OP_CLO] = 0xE4, - [OP_SWP] = 0x2C, + [OP_SWP] = 0x6C, [OP_PCN] = 0x43 }; @@ -357,8 +357,8 @@ static const instruction inst[OPNUM] = { [INC] = {(AM_IMPL|AM_ZM|AM_ABS|AM_EIND2|AM_ORTHO2), 0xA4}, [INX] = {(AM_IMPL), 0xC9}, [INY] = {(AM_IMPL), 0x89}, - [JMP] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND), 0x00}, - [JSR] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND), 0x20}, + [JMP] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND|AM_ORTHO|AM_ORTHO2), 0x00}, + [JSR] = {(AM_ABS|AM_IND|AM_ZM2|AM_EIND|AM_ORTHO|AM_ORTHO2), 0x20}, [LDA] = {(AM_IMM|AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_EIND), 0xC2}, [LDB] = {(AM_IMM|AM_ZM|AM_ZMX|AM_ZMY|AM_IND|AM_INDX|AM_INDY|AM_ABS|AM_EIND), 0xE2}, [LDX] = {(AM_IMM|AM_ZM|AM_IND|AM_ABS|AM_EIND2), 0x64}, diff --git a/assemble.c b/assemble.c index ce35e78..a3791d3 100644 --- a/assemble.c +++ b/assemble.c @@ -898,7 +898,11 @@ uint64_t handle_opcode(token *t, bytecount *bc, uint8_t isasm, uint64_t address, int i2 = 0; int j = 0; (op[i].type == 1) ? (opcode |= (1 << (3+!i))) : (opcode &= ~(1 << (3+!i))); - if (op[i].type == 1 && (am & AM_ORTHO|AM_ORTHO2)) { + if ((am & (AM_ORTHO|AM_ORTHO2)) == (AM_ORTHO|AM_ORTHO2)) { + opcode |= 0x0C; + } + + if (op[i].type == 1 && (am & (AM_ORTHO|AM_ORTHO2))) { switch (op[i].id) { case MEM_RIND: break; case MEM_IMM: diff --git a/disasm.c b/disasm.c index 1982c17..645d17e 100644 --- a/disasm.c +++ b/disasm.c @@ -217,36 +217,6 @@ static int is_os(uint8_t opcode, operand *op) { return 0; } -static int is_1cc(uint8_t opcode) { - switch (opcode) { - case ORTHO_1CC(SET, NG): - case ORTHO_1CC(SET, PO): - case ORTHO_1CC(SET, CS): - case ORTHO_1CC(SET, CC): - case ORTHO_1CC(SET, EQ): - case ORTHO_1CC(SET, NE): - case ORTHO_1CC(SET, VS): - case ORTHO_1CC(SET, VC): return 1; - } - return 0; -} - -static int is_1op(uint8_t opcode) { - switch (opcode) { - case ORTHO_1OP(PSH): - case ORTHO_1OP(PEA): - case ORTHO_1OP(PUL): - case ORTHO_1OP(SWP): - case ORTHO_1OP(NOT): - case ORTHO_1OP(NEG): - case ORTHO_1OP(DEC): - case ORTHO_1OP(INC): - case ORTHO_1OP(CLZ): - case ORTHO_1OP(CLO): return 1; - } - return 0; -} - static int is_2op(uint8_t opcode) { switch (opcode) { case ORTHO_2OP(MNG): @@ -437,7 +407,7 @@ void disasm(struct sux *cpu, WINDOW *w, uint8_t lines, uint8_t opcode, uint8_t p if (ext_prefix != 0x1D) { address = get_addr(cpu, opcode, prefix, ext_prefix, 0, 0, thread); } else { - get_ortho_addr(cpu, prefix, cpu->pc, ortho_op, ortho_addr, op_type, op_id, 0, 0, thread); + get_ortho_addr(cpu, opcode, prefix, cpu->pc, ortho_op, ortho_addr, op_type, op_id, 0, 0, thread); } uint8_t rs = (prefix >> 4) & 3; char *postfix; diff --git a/disasm.h b/disasm.h index 2b65d12..446cc77 100644 --- a/disasm.h +++ b/disasm.h @@ -365,7 +365,7 @@ static const char *ortho_opname[] = { ORTHO_2OP(ADD/**/), /* ADD Ortho. */ ORTHO_1OP(PSH/**/), /* PuSH operand onto the stack. */ ORTHO_1CC(SET, NG), /* SET if NeGative. */ - ORTHO_1OP(PEA/**/), /* PEA Ortho. */ + ORTHO_1OP(JMP/**/), /* JMP Ortho. */ /* 0x20-0x3C */ ORTHO_2OP(MPO/**/), /* Move if POsitive. */ ORTHO_2OP(SBC/**/), /* SBC Ortho. */ @@ -373,21 +373,23 @@ static const char *ortho_opname[] = { ORTHO_2OP(SUB/**/), /* SUB Ortho. */ ORTHO_1OP(PUL/**/), /* PuLl operand off of the stack. */ ORTHO_1CC(SET, PO), /* SET if POsitive. */ - ORTHO_1OP(SWP/**/), /* SWP Ortho. */ - /* 0x40-0x55 */ + ORTHO_1OP(JSR/**/), /* JSR Ortho. */ + /* 0x40-0x5C */ ORTHO_2OP(MCS/**/), /* Move if Carry Set. */ ORTHO_2OP(AND/**/), /* AND Ortho. */ ORTHO_2OP(DIV/**/), /* DIV Ortho. */ ORTHO_2OP(PCN/**/), /* PCN Ortho. */ ORTHO_1OP(NOT/**/), /* NOT Ortho. */ ORTHO_1CC(SET, CS), /* SET if Carry Set. */ - /* 0x60-0x75 */ + ORTHO_1OP(PEA/**/), /* PEA Ortho. */ + /* 0x60-0x7C */ ORTHO_2OP(MCC/**/), /* Move if Carry Clear. */ ORTHO_2OP(OR /**/), /* Bitwise OR. */ ORTHO_2OP(ASR/**/), /* ASR Ortho. */ ORTHO_2OP(LEA/**/), /* LEA Ortho. */ ORTHO_1OP(NEG/**/), /* NEGate operand. */ ORTHO_1CC(SET, CC), /* SET if Carry Clear. */ + ORTHO_1OP(SWP/**/), /* SWP Ortho. */ /* 0x80-0x95 */ ORTHO_2OP(MEQ/**/), /* Move if EQual. */ ORTHO_2OP(XOR/**/), /* XOR Ortho. */ diff --git a/enums.h b/enums.h index 1658c35..71a52f1 100644 --- a/enums.h +++ b/enums.h @@ -560,7 +560,7 @@ enum ortho { ORTHO_2OP(ADD, 0x03/**/), /* ADD Ortho. */ ORTHO_1OP(PSH, 0x04/**/), /* PuSH operand onto the stack. */ ORTHO_1CC(SET, 0x05, NG), /* SET if NeGative. */ - ORTHO_1OP(PEA, 0x0C/**/), /* PEA Ortho. */ + ORTHO_1OP(JMP, 0x0C/**/), /* JMP Ortho. */ /* 0x20-0x3C */ ORTHO_2OP(MPO, 0x20/**/), /* Move if POsitive. */ ORTHO_2OP(SBC, 0x21/**/), /* SBC Ortho. */ @@ -568,21 +568,23 @@ enum ortho { ORTHO_2OP(SUB, 0x23/**/), /* SUB Ortho. */ ORTHO_1OP(PUL, 0x24/**/), /* PuLl operand off of the stack. */ ORTHO_1CC(SET, 0x25, PO), /* SET if POsitive. */ - ORTHO_1OP(SWP, 0x2C/**/), /* SWP Ortho. */ - /* 0x40-0x55 */ + ORTHO_1OP(JSR, 0x2C/**/), /* JSR Ortho. */ + /* 0x40-0x5C */ ORTHO_2OP(MCS, 0x40/**/), /* Move if Carry Set. */ ORTHO_2OP(AND, 0x41/**/), /* AND Ortho. */ ORTHO_2OP(DIV, 0x42/**/), /* DIV Ortho. */ ORTHO_2OP(PCN, 0x43/**/), /* PCN Ortho. */ ORTHO_1OP(NOT, 0x44/**/), /* NOT Ortho. */ ORTHO_1CC(SET, 0x45, CS), /* SET if Carry Set. */ - /* 0x60-0x75 */ + ORTHO_1OP(PEA, 0x4C/**/), /* PEA Ortho. */ + /* 0x60-0x7C */ ORTHO_2OP(MCC, 0x60/**/), /* Move if Carry Clear. */ ORTHO_2OP(OR , 0x61/**/), /* Bitwise OR. */ ORTHO_2OP(ASR, 0x62/**/), /* ASR Ortho. */ ORTHO_2OP(LEA, 0x63/**/), /* LEA Ortho. */ ORTHO_1OP(NEG, 0x64/**/), /* NEGate operand. */ ORTHO_1CC(SET, 0x65, CC), /* SET if Carry Clear. */ + ORTHO_1OP(SWP, 0x6C/**/), /* SWP Ortho. */ /* 0x80-0x95 */ ORTHO_2OP(MEQ, 0x80/**/), /* Move if EQual. */ ORTHO_2OP(XOR, 0x81/**/), /* XOR Ortho. */ diff --git a/lexer.c b/lexer.c index b46396d..f12feb3 100644 --- a/lexer.c +++ b/lexer.c @@ -773,6 +773,7 @@ int get_expr_type(char **p, uint64_t address, void *val, int *found_reg, char st expr *parse_expr(char **line, uint64_t address, int *found_reg, int is_left, char stop, uint8_t dbg) { char *str = *line; + char *start = *line; int dummy = 0; found_reg = (found_reg == NULL) ? &dummy : found_reg; @@ -833,7 +834,6 @@ expr *parse_expr(char **line, uint64_t address, int *found_reg, int is_left, cha left = new; } } - *line = str; return left; } @@ -1035,7 +1035,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { lex_type = TOK_EXPR; memset(lexeme, 0, strlen(lexeme)+1); char *tmp = &str[i]; - expr *e = parse_expr(&tmp, address, NULL, 1, delm, dbg); + expr *e = parse_expr(&tmp, address, NULL, 0, delm, dbg); t = make_token(lex_type, 0, space, tab, 0, "", NULL, e); j = tmp - &str[i]; memcpy(lexeme, &str[i], j); @@ -1070,7 +1070,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { memset(lexeme, 0, strlen(lexeme)+1); do { char *tmp = &str[i]; - expr *e = parse_expr(&tmp, address, NULL, 1, delm, dbg); + expr *e = parse_expr(&tmp, address, NULL, 0, delm, dbg); t = make_token(lex_type, 0, space, tab, 0, "", NULL, e); j = tmp - &str[i]; memcpy(lexeme, &str[i], j); @@ -1296,7 +1296,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { lex_type = TOK_EXPR; memset(lexeme, 0, strlen(lexeme)+1); char *tmp = &str[i]; - expr *e = parse_expr(&tmp, address, NULL, 1, delm, dbg); + expr *e = parse_expr(&tmp, address, NULL, 0, delm, dbg); j = tmp - &str[i]; memcpy(lexeme, &str[i], j); /*i += j;*/ diff --git a/programs/sub-suite/free-new.s b/programs/sub-suite/free-new.s deleted file mode 100644 index dad19d0..0000000 --- a/programs/sub-suite/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/free-old.s b/programs/sub-suite/free-old.s deleted file mode 100644 index 7f75edd..0000000 --- a/programs/sub-suite/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/print_char.s b/programs/sub-suite/print_char.s deleted file mode 100644 index e12461c..0000000 --- a/programs/sub-suite/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/shift_line.c b/programs/sub-suite/shift_line.c deleted file mode 100644 index 365666b..0000000 --- a/programs/sub-suite/shift_line.c +++ /dev/null @@ -1,85 +0,0 @@ -#include - -const uint8_t bits[8] = { - 0x80, - 0x40, - 0x20, - 0x10, - 0x08, - 0x04, - 0x02, - 0x01 -}; - -int maxcol = 80; -int scr_str = 0; -int scr_row = 0; -int scr_col = 0; -uint8_t bitabl[16]; - -uint8_t bitpos(unsigned int row, uint8_t *mask) { - uint8_t bit = row & 7; - *mask = bits[bit]; - return row >> 3; - -} - -uint8_t getbit(unsigned int row, unsigned int offset) { - uint8_t mask; - uint8_t byte = bitpos(row+offset, &mask); - return (bitabl[byte] & mask); -} - -void setbit(unsigned int row) { - uint8_t mask; - uint8_t byte = bitpos(row, &mask); - bitabl[byte] |= mask; -} - -void clrbit(unsigned int row) { - uint8_t mask; - uint8_t byte = bitpos(row, &mask); - bitabl[byte] &= ~mask; -} - -int find_end(char *str, int start) { - int i; - for (i = start; str[i]; i++); - return i; -} - -void shift_line(char *str, int cursor, int left) { - /*int cursor = ((scr_row+scr_str)*maxcol)+scr_col;*/ - int end = find_end(str, cursor); - if (left) { - int i = end-1; - int j = end; - for (; i >= cursor; i--, j--) { - if (i < 0) { - i = 0; - str[i] = 0; - break; - } - str[j] = str[i]; - str[i] = 0; - - } - /*str[i+1] = (!str[i+1]) ? ' ' : str[i+1];*/ - end = find_end(str, i+2); - /*str[i+1] = (str[i+1] == ' ') ? 0 : str[i+1];*/ - if ((end/maxcol) > scr_row) { - setbit(end/maxcol); - } - } else { - int i = cursor; - int j = cursor-1; - for (; str[i]; i++, j++) { - str[j] = str[i]; - str[i] = 0; - } - end = find_end(str, i); - if (((end-1) % maxcol) == 0 && ((end-1)/maxcol) > scr_row) { - clrbit(end/maxcol); - } - } -} diff --git a/programs/sub-suite/subeditor-new.s b/programs/sub-suite/subeditor-new.s deleted file mode 100644 index 6c1cfb1..0000000 --- a/programs/sub-suite/subeditor-new.s +++ /dev/null @@ -1,1119 +0,0 @@ -; SuBEditor. -; -; Writen in Sux assembly by -; mr b0nk 500 - - -.org $8000 -reset: - cps ; Reset the processor status register. - ldx.w #$FFFF ; Reset the stack pointer. - txs ; - ldy #0 ; Reset the Y register. - sty end ; - tyx ; Reset the X register. - lda #maxrow ; Set the end of the screen to the screen's max row count. - sta scr_end ; - tya ; Reset the Accumulator. - sta scr_str ; Set the start of the screen back to zero. - sta.q bitabl ; Reset the first half of the linewrap table. - sta.q bitabl+8 ; Reset the second half of the linewrap table. - inc end ; - lda.w #$1FFF ; Set the clear count to $1FFF. - pha.w ; Push the clear count to the stack. - lda.d #buffer ; Set the array to be cleared to the screen buffer. - pha.q ; Push it on to the stack. - jsr clr_arr ; Clear the screen buffer. - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - and #0 ; Reset A. - jsr pnt_strt ; Print the starting message. - lda #$C ; Clear the screen. - sta scr ; - bra start ; Goto the start of the main program. - -clr_arr: - phb ; Preserve whatever was in B. - ldb #0 ; Clear B. - clc ; Prepare for a non carrying add. - adc #8 ; Set the second pointer to the parameter, plus eight. - pha.q ; Push it onto the stack. - tba ; -@loop: - cpy.w sp+26 ; Did we clear all of the array? - bcs @end ; Yes, so we're done. - sta.q (sp+18), y; No, so clear eight bytes. - sta.q (sp+1), y ; Clear eight more bytes. - tya ; Copy the array index. - adc #$10 ; Increment the index by 16. - tay ; Update the index. - tba ; Reset the Accumulator. - sta.q (sp+18), y; Do this one more time, to clear 32 bytes. - sta.q (sp+1), y ; - tya ; - adc #$10 ; - tay ; - tba ; - bra @loop ; Keep looping. -@end: - ldy.w zero ; Set the index back to zero. - pla.q ; Move the stack pointer back. - tba ; Reset A. - plb ; Get whatever was in the B register, back. - rts ; End of clr_arr. - -pnt_strt: - lda.w #ed_name ; Print the name of the editor. - jsr print_str ; - lda.w #ver_str ; Print the version text. - jsr print_str ; - lda.w #ed_ver ; Print the version number. - jsr print_str ; - lda.w #ed_sver ; Print the sub version number. - jsr print_str ; - lda #'\n' ; Print a newline. - jsr print_char ; - lda.w #made ; Print the "Created by" text. - jsr print_str ; - lda.w #author ; Print the name of the author. - jsr print_str ; - lda #'\n' ; Print a newline. - jsr print_char ; - rts ; End of pnt_strt. - -start: - lda #0 ; TODO: Update this for the Super VIA. - sta status ; Clear the control register of the I/O adapter. - tax ; Reset X. - phy.w ; Save the cursor index for later. - tay ; Reset the cursor index. - lda.w #$3FF ; Set the clear count to $3FF. - pha.w ; Push the clear count onto the stack. - lda.d #cmd_buf ; Set the array to be cleared to the command buffer. - pha.q ; Push the pointer onto the stack. - jsr clr_arr ; Clear the command buffer. - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - ply.w ; Get back the cursor index. - and #0 ; Reset the Accumulator. - sta end ; - bra read ; Start reading the keyboard. - -read: - lda #0 ; Reset the Accumulator. - sta end ; Disable the dummy flag. - inc end ; Enable the dummy flag. - lda status ; Did we get a key? - beq read ; No, so try again. - jsr getchar ; Yes, and was it a newline? - beq parse ; Yes, so start parsing the line. - bra read ; No, so keep looping. - -parse: - lda #0 ; - tax ; - jsr subasm ; - bra start ; - - -print_str: - ldx #0 ; Reset X. - pha.q ; Push the parameter onto the stack. -@loop: - ldb #1 ; Enable replace mode. - stb b ; - and #0 ; No, reset the accumulator. - phy.w ; Save the cursor index. - txy ; Copy the string index into Y. - lda (sp+3), y ; Are we at the end of the string? - ply.w ; Get the cursor index back. - beq @end ; Yes, so we're done. - inx ; No, so increment the string index. - jsr print_char ; Print the character. - bra @loop ; Keep looping. -@end: - pla.q ; Pull the parameter off the stack. - ldb #0 ; Enable insert mode. - stb b ; - tba ; Reset A. - rts ; End of print_str. - -getbit: - clc ; Clear the carry flag. - lda scr_str ; Has the screen been scrolled? - bne getbt0 ; Yes, so add the screen offset to the current line number. - ldx scr_row ; No, so just use the current line number. - bra getbt1 ; Start getting the bit. -getbt0: - lda scr_row ; Get the current line number. - adc scr_str ; Add the screen offset to it. - tax ; Use it as the wrap index. -getbt1: - tab ; Save the parameter. - lda.d #bitabl ; Set the second pointer to the linewrap table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - jsr bitpos ; Get the bit, and byte position. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (sp+3), y ; Get one byte of the wrap table. - ply.w ; Get the screen index back. - aba ; Mask out the bit of the current line number. - cmp #1 ; Set the carry flag, if true. - bra bitout ; We are done. - -clrbit: - tab ; Save the parameter. - lda.d #bitabl ; Set the second pointer to the linewrap table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - jsr bitpos ; Get the bit, and byte position. - xor #$FF ; Invert the bitmask. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (sp+3), y ; Get one byte of the wrap table. - aba ; Clear the bit of the current line number. -bitsav: - sta (sp+3), y ; Update the wrap table. - ply.w ; Get the screen index back. -bitout: - pla.q ; Pull the pointer off the stack. - and #0 ; Reset A. - ldx bitmask ; Return the bitmask. - rts ; We are done. - -setbit: - tab ; Save the parameter. - lda.d #bitabl ; Set the second pointer to the linewrap table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - jsr bitpos ; Get the bit, and byte position. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (sp+3), y ; Get one byte of the wrap table. - oab ; Set the bit of the current line number. - bra bitsav ; Save the bit. - -bitpos: - tab ; Save the parameter. - lda.w #bits ; Set the first pointer to the bitmask table. - pha.q ; Push the pointer onto the stack. - tba ; Get the parameter back. - stx bitmask ; Make the line number the bitmask. - txa ; Copy it to the Accumulator. - and #7 ; Get the bit position. - phy.w ; Save the cursor index. - tay ; Use the bit position as the index. - tax ; Copy it into X. - lda (sp+3), y ; Get the bitmask. - ply.w ; Get back the cursor index. - pha ; Save the bitmask. - lda bitmask ; Get the line number. - lsr #3 ; Get the byte position. - tax ; Copy it into X. - pla ; Get back the bitmask. - tab ; Preserve the bitmask. - pla.q ; Pull the pointer off the stack. - tba ; Get the bitmask back. - rts ; End of bitpos. - -getchar: - lda kbd ; Get the character that was typed from the keyboard. - ldb #0 ; Reset the B register. - stb e ; Set the temporary row position to zero, in case we get a newline. - stb b ; Enable insert mode. - pha ; Save the character. - phy.w ; Save the cursor index. - cmp #'\n' ; Was the character that was typed, a newline? - bne @print ; No, so just print the character. - jsr cmd_cpy ; Yes, so start copying the line to the command buffer. -@print: - ply.w ; Get back the cursor index. - pla ; Get back the character. - ldb e ; Is the temporary row position non zero? - bne @row ; Yes, so reset the row positon. -@print1: - jsr print_char ; No, so print the character. - lda a ; Get the return value. - cmp #'\n' ; Is the return value, a newline? - beq @true ; Yes, so return true. - bra @false ; No, so return false. -@row: - ldb e ; Get the temporary row position. - cpb #maxrow ; Is temporary row position, at, or above the bottom of the screen? - beq @row2 ; Yes, so leave it as is. - bcs @row1 ; No, so set it to the bottom of the screen. - bra @row2 ; Yes, so leave it as is. -@row1: - ldb #maxrow ; Set the row position to the bottom of the screen. -@row2: - stb scr_row ; Set the row position. - bra @print1 ; Print the character. -@true: - lda #0 ; Return true. - bra @end ; We are done. -@false: - lda #1 ; Return false. -@end: - rts ; End of getchar. - - -cmd_cpy: - lda scr_row ; Get the row position. - sta scr_trow ; Save it for later. - jsr findend ; Find the end of the line. - ldb scr_str ; Has the screen been scrolled? - beq @start ; No, so don't subtract the screen's starting point from the line number. -@offset: - sec ; Yes, so make sure that we don't subtract by the starting point, plus one. - sbc scr_str ; Offset the row position, back by the screen's starting point. - clc ; Clear the carry flag, so that nothing odd occurs. -@start: - sta scr_row ; Set the row position to the end of the line. - sta e ; Save it into the temporary row posiition. - jsr findst ; Find the start of the line. - clc ; Clear the carry flag. - lda scr_row ; Get the row position. - adc scr_str ; Add it with the screen's starting row. - mul #maxcol+1 ; Multiply it with the width of the screen, plus one. - tay ; Place it into the index. - ldx.w #0 ; Reset the X register. - ldb #0 ; Make sure that set_ptr sets the first pointer. - lda.d #buffer ; Set the first pointer to the start of the screen buffer. - pha.q ; Push the pointer onto the stack. - lda.d #cmd_buf ; Set the second pointer to the start of the command buffer. - pha.q ; Push the pointer onto the stack. - tba ; Set the accumulator to zero. -@loop: - ldb #0 ; Reset the B register. - lda.q (sp+9), y ; Get eight bytes from the current line. -@loop1: - phy.w ; Save the screen index. - txy ; Get the command buffer index. - sta (sp+3), y ; Copy one byte from the screen buffer, to the command buffer. - inx ; Increment the command buffer index. - ply.w ; Get back the screen index. - cpx.w #$3FF ; Are we at the end of the command buffer? - bcs @end ; Yes, so we're done. - iny ; No, so increment the screen index. - inb ; Increment the byte count. - lsr #8 ; Shift in the next byte. - stb g ; Save the byte count. - tab ; Save the string buffer. - and #$FF ; Is this byte of the buffer, a null terminator? - beq @end1 ; Yes, so we're done. - tba ; No so get back the string buffer. - ldb g ; Get back the byte count. - cpb #7 ; Did we shift in eight bytes? - beq @loop ; Yes, so get eight more bytes. - bra @loop1 ; No, so keep shifting in more bytes. -@end: - ldb #0 ; Reset B. - phy.w ; Save the screen index. - txy ; Get the command buffer index. - stb (sp+3), y ; Terminate the command buffer. - ply.w ; Get back the screen index. -@end1: - pla.q ; Pull one of the pointers off the stack. - pla.q ; Pull the other pointer off the stack. - tba ; The B register is zero, so clear the Accumulator. - rts ; End of cmd_cpy. - - -findst: - lda #0 ; Reset A. -@loop: - pha ; Save the current line number. - jsr getbit ; Is this the start of the line? - pla ; Get the current line number back. - bcc @end ; Yes, so we're done. - inc ; No, so check the next physical line. - dec scr_row ; Are we at the top of the screen? - bpo @loop ; No, so keep looping. - dec ; Yes, so move back one line. - inc scr_row ; Put the row postiion back to zero. -@end: - cmp #0 ; Update all the flags. - rts ; End of findst. - - -fndend: - lda.d #buffer ; Set the first pointer to the start of the screen buffer. - pha.q ; Push the pointer onto the stack. - phb ; Save the contents of the B register. - ldb #0 ; Make sure that set_ptr sets the first pointer. - tba ; Set the Accumulator to zero. - plb ; Restore the contents of the B register. - phy.w ; -@loop: - lda (sp+3), y ; Are we at the end of the string? - beq @end ; Yes, so we're done. - iny ; No, so increment the cursor index. - bra @loop ; Keep looping. -@end: - sty.w scr_ptr3 ; - ply.w ; - pla.q ; Pull the pointer off the stack. - and #0 ; Reset A. - rts ; End of fndend. - -findend: - jsr fndend ; - lda.w scr_ptr3 ; - div #maxcol+1 ; - rts ; - - -print_char: - sta a ; Save the typed character for now. - ldb #2 ; Make sure that set_ptr sets the third pointer. - lda.d #buffer ; Set the third pointer to the start of the screen buffer. - jsr set_ptr ; - ldb #0 ; Set B to zero. - tba ; Set the Accumulator to zero. - lda a ; Get back the character. - cmp #$1B ; Did the user type an escape character? - beq esc ; Yes, so go check the escape code. - cmp #'\n' ; No, but did the user type a newline? - beq nl ; Yes, so handle the newline. - cmp #$C ; No, but did the user type Ctrl+L? - beq clr_scr ; Yes, so clear the screen. - cmp #19 ; No, but did the user type Ctrl+S? - beq en_step ; Yes, so enable clock/instruction stepping. - cmp #18 ; No, but did the user type Ctrl+R? - beq dis_step ; Yes, so disable clock/instruction stepping. - cmp #'\b' ; No, but did the user type a backspace? - beq bs ; Yes, so handle the backspace. - cmp #$7F ; No, but did they type Delete? - beq bs ; Yes, so treat it as a backspace. -printc: - lda #0 ; No, so start trying to print a character. - sta d ; - lda (ptr3), y ; Are we at the end of the string? - beq @save ; Yes, so just print the character. - lda b ; No, but was the flag set? - bne @save ; Yes, so don't shift the line. - sty.w scr_ptr ; No, so save the cursor index for later. - jsr fndend ; Find the end of the line. - bra @shift ; Start shifting the line right. -@update: - lda scr_col ; Save the current column position for later. - sta scr_tcol ; -@update1: - jsr findend ; Find the end of the line. - sta e ; Use it for redrawing the line. - sta scr_row ; Set the row position to to the end of the line. - jsr findst ; Find the start of the line. - lda scr_row ; Get the start of the line. -@update2: - sta f ; Set the starting line, to the start of the line. - jsr rdrw_ln ; Redraw the line. - lda scr_trow ; Get the real row position back. - sta scr_row ; - lda scr_tcol ; Get the real column position back. - sta scr_col ; - jsr update_pos ; Update the cursor's position. - dec d ; - bra @save1 ; -@shift: - ldy.w scr_ptr3 ; - inc scr_ptr3 ; - tyx ; - dey ; - ldb #1 ; - stb d ; - jsr shftln ; - ldb #1 ; - stb d ; - lda a ; - sta (ptr3), y ; store typed character into the input buffer. - lda scr_row ; - sta scr_trow ; - bra @update ; -@save: - ldb d ; - bne @update ; -@save1: - lda a ; - sta (ptr3), y ; store typed character into the input buffer. -@incr: - inc scr_col ; Increment the cursor's x coordinate. - iny ; -@wrapped: - ldb #1 ; - stb f ; - ldb scr_col ; - cpb #maxcol+1 ; - bcs @scrolled ; -@print: - sta scr ; Echo typed character. - ldb f ; - beq @wrap ; - bra printc_end ; -@scrolled: - ldb scr_row ; - cpb #maxrow ; - bcs @scroll ; -@wrapped2: - ldb #0 ; - stb f ; - bra @print ; -@scroll: - sta scr ; Echo typed character. - clc ; - lda #1 ; - sta wrapped ; - jsr scrl_down ; -@wrap: - ldb #0 - stb scr_col ; - ldb scr_row ; - cpb #maxrow ; - bcs @wrap2 ; -@wrap1: - inc scr_row ; -@wrap2: - phx.w ; - clc ; - lda scr_row ; - adc scr_str ; - tax ; - jsr setbit ; - plx.w ; - jsr update_pos ; -printc_end: - rts ; - -nl: - lda #0 ; Reset A. - ldb (ptr3), y ; Is this character not a null terminator? - bne @scroll ; Yes, so don't overwrite it. - sta (ptr3), y ; No, so overwrite it. -@scroll: - sta scr_col ; Move the cursor to the start of the next line. - lda scr_row ; Get the row position. - cmp #maxrow ; Are we at the bottom of the screen? - bcc @incr ; No, so move down one line. - jsr scrl_down ; Yes, so scroll down one line. - bra @end ; We are done. -@incr: - inc scr_row ; Move the cursor down by one line. - jsr update_pos ; Update the cursor's position. -@end: - lda #'\n' ; Print the newline. - sta a ; - rts ; - - -clr_scr: - lda #maxrow ; - sta scr_end ; - lda #0 ; - sta scr_str ; - sta.q bitabl ; - sta.q bitabl+8 ; - tay ; - lda.w #$1FFF ; Set the clear count to $1FFF. - pha.w ; Push the clear count onto the stack. -; sta.w scr_ptr ; - lda.d #buffer ; Set the array to be cleared to the screen buffer. - pha.q ; Push the pointer onto the stack. - jsr clr_arr ; Clear the screen buffer. - tay ; - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - lda.w #$3FF ; Set the clear count to $3FF. - pha.w ; Push the clear count onto the stack. -; sta.w scr_ptr ; - lda.d #cmd_buf ; Set the array to be cleared to the command buffer. - pha.q ; - jsr clr_arr ; Clear the screen buffer. - pla.q ; Pull the pointer off of the stack. - pla.w ; Pull the clear count off of the stack. - and #0 ; Reset A. - sta scr_col ; - sta scr_row ; - jsr update_pos ; - lda #$C ; - sta scr ; - rts ; - -en_step: - lda step ; - beq step_en ; - rts ; -step_en: - lda #1 ; - sta step ; - rts ; - -dis_step: - lda step ; - bne step_dis ; - rts ; -step_dis: - lda #0 ; - sta step ; - rts ; - - -bs: - lda scr_col ; Are we at the far left of the screen? - beq @wrap ; Yes, so check for a wrapped line. - bra back ; No, so add the backspace to the buffer. -@wrap: - jsr getbit ; Is this line, a wrapped line? - bcs @wrap1 ; Yes, so check if the cursor is at the top. - rts ; No, so we're done. -@wrap1: - lda scr_row ; Are we at the top of the screen? - beq @wrap2 ; Yes, so check if the screen is at the top of the buffer. - bra @wrap3 ; No, so start clearing the wrap bit. -@wrap2: - lda scr_str ; Are we at the top of the buffer? - bne @scroll ; Yes, so scroll up. - rts ; No, so we're done. -@scroll: - clc ; Clear the carry flag, so that we don't get odd behaviour. - jsr scrl_up ; Scroll up. - inc scr_row ; Move down by one row. -@wrap3: - clc ; Clear the carry flag. - lda scr_row ; Add the cursor's row position, - adc scr_str ; and the screen's starting row. - tax ; Transfer that into X. -@wrap4: - dec scr_row ; Move up by one row. - ldb #maxcol+1 ; Move the cursor to the absolute right of the screen. - stb scr_col ; - jsr update_pos ; Update the cursor's position. -back: - ldb #0 ; Reset B, and some flags. - stb e ; - stb f ; - lda scr_row ; Save the current row position for later. - sta scr_trow ; - jsr findend ; Find the end of the line. - sta scr_row ; Set our row position to the end of the line. -@find_st: - jsr findst ; Does this line take up more than one real line? - beq @shift ; No, so skip updating any other lines. - bcs @update ; Yes, so update the other lines. - lda scr_trow ; Get the real row position back. - sta scr_row ; -@shift: - dey ; Decrement the buffer's offset. - lda #0 ; Place a null terminator - sta (ptr3), y ; into the buffer. - tyx ; Copy the current cursor index to X. - iny ; Increment cursor index. - ldb #0 ; Set shifting direction to left. - stb d ; - jsr shftln ; Shift line back by one character. - lda #$7F ; Print a backspace to the screen. - sta scr ; - lda e ; Are we updating more than one line? - beq @load ; No, so skip to the next step. -@find_end: - jsr findend ; Yes, so find the end of the line. - sta e ; Set the end parameter to it. - lda scr_col ; Save the current column position for now. - sta scr_tcol ; - jsr rdrw_ln ; Start redrawing the line. - lda scr_tcol ; Get the real column position back. - sta scr_col ; -@load: - lda scr_trow ; Get the real row position back. - sta scr_row ; - dec scr_col ; Move the cursor back by one column, - jsr update_pos ; and update it's position. - rts ; We are done. -@update: - lda scr_row ; Set the line to start redrawing, to the start of the line. - sta f ; - inc e ; Set the redraw flag to true. - bra @shift ; Start shifting the line back. - - -shftln: - ldb d ; Is the flag not set? - beq @dec_loop ; Yes, so shift, and decrement. - ldb #0 ; Clear the B register. - bra @inc_loop ; No, so shift, and increment. -@neg: - ldy.w zero ; Set the source poition to 0. - stb (ptr3), y ; Clear the character that is in the source. - bra @end ; We are done. -@inc_loop: - sty.w scr_ptr2 ; Save the source position for later. - ldy.w scr_ptr ; Get the previous cursor index. - cpy.w scr_ptr2 ; Is the source position, at, or below the cursor index? - beq @inc_loop1 ; Yes, so keep looping. - bcs @end ; No, so we're done. -@inc_loop1: - ldy.w scr_ptr2 ; Get the source position. - lda (ptr3), y ; Get the character from the source position. - phy.w ; Save the source position for later. - txy ; Set our position to the destination. - sta (ptr3), y ; Place the character from the source position, to the destination position. - ply.w ; Set our position back to the source. - stb (ptr3), y ; Clear the character that is in the source. - bng @neg ; The source underflowed, so set it back to zero, - dey ; Decrement the source position. - dex ; Decrement the destination position. - bra @inc_loop ; Keep looping. -@dec_loop: - stx.w scr_ptr2 ; Save the destination position for later. - lda (ptr3), y ; Is the character at the source position, a null terminator? - beq @end3 ; Yes, so we're done. - phy.w ; No, so save the source position for later. - txy ; Set our position to the destination. - sta (ptr3), y ; Place the character from the source position, to the destination position. - inx ; Increment the destination position. - ply.w ; Set our position back to the source. - stb (ptr3), y ; Clear the character that is in the source. - iny ; Increment the source position. - bra @dec_loop ; Keep looping. -@wrap: - tax ; Use the ending line as a parameter for setbit. - jsr setbit ; Set the wrap bit of the ending line. - bra @end5 ; We are done. -@wrap1: - tax ; Use the ending line as a parameter for clrbit. - jsr clrbit ; Clear the wrap bit of the ending line. - bra @end5 ; We are done. -@end: - lda (ptr3), y ; Is this character a null terminator? - bne @end1 ; No, so just find the end of the line. - lda #$20 ; Yes, so convert it to a space for now. - sta (ptr3), y ; -@end1: - jsr findend ; Find the ending line. - sta d ; Save ending line for later. - lda (ptr3), y ; Is this character a space? - cmp #$20 ; - bne @end5 ; No, so skip the conversion. - lda #0 ; Yes, so convert it back to zero. - sta (ptr3), y ; -@end2: - lda d ; Get the ending line. - cmp scr_row ; Is the ending line greater than the starting line? - beq @end5 ; No, so we're done. - bcs @wrap ; Yes, so set the wrap bit. - bra @end5 ; No, so we're done. -@end3: - jsr findend ; Find the ending line. - cpb #0 ; Is the remainder zero? - beq @end4 ; Yes, so check if the ending line is greater than the starting line. - bra @end5 ; No, so we're done. -@end4: - cmp scr_row ; Is the ending line greater than the starting line? - beq @end5 ; No, so we're done. - bcs @wrap1 ; Yes, so clear the wrap bit. -@end5: - rts ; End of shftln. - -esc: - lda status ; Get the next character. - lda kbd ; - cmp #$1B ; Is this character an escape character? - beq shftesc ; Yes, so check the other set of escape routines. - lda status ; No, so wait for the next character. - beq @end ; We have an error, so discard it, and go back to getting user input. - lda kbd ; Get the escape code. - sta c ; Store the escape code, until we need it. - lda #0 ; Set the D pseudo register to zero. - sta d ; - jsr isup ; Check if the user pressed up. - lda d ; Did the user press up? - bne @end ; Yes, so we're done. - jsr isdown ; No, so check if the user pressed down. - lda d ; Did the user press down? - bne @end ; Yes, so we're done. - lda #0 ; No, so check if the user pressed left. - jsr isleft ; - lda d ; Did the user press left? - bne @end ; Yes, so we're done. - jsr isright ; No, so check if the user pressed right. -@end: - lda #0 ; Clear the D pseudo register. - sta d ; - rts ; We are done. - -shftesc: - lda status ; Skip the '['. - lda kbd ; - lda status ; Wait for the next character. - beq @end ; We have an error, so discard it, and go back to getting user input. - lda kbd ; Get the escape code. - sta c ; Store the escape code, until we need it. - lda #0 ; Use the D pseudo register as a skip flag. - sta d ; - jsr isshftup ; Check if the user pressed shift+up. - lda d ; Was it successful? - bne @end ; Yes, so we're done. - jsr isshftdown ; No, so check if the user pressed shift+down. -@end: - lda #0 ; Clear the D pseudo register. - sta d ; - rts ; We are done. - - -isup: - lda c ; Load the escape code into the accumulator. - cmp #'A' ; Did the user press the up arrow key? - bne @end ; No, so we're done. - lda scr_row ; Yes, but is the cursor at the top of the screen? - beq @scroll ; Yes, so check if we need to scroll. -@check2: - lda c ; No, so load the escape code back into the accumulator. - cmp #'A' ; Did the user press the up arrow key? - beq @up ; Yes, so move the cursor up. - bra @end ; No, so we're done. -@up: - dec scr_row ; Move the cursor up a line. - jsr update_pos ; Update it's position. - lda #1 ; Tell the escape routine that we succeded. - sta d ; - rts ; We are done. -@scroll: - lda scr_str ; Are we at the top of the screen buffer? - beq @end ; Yes, so we're done. - jsr scrl_up ; No, so scroll up. - lda #1 ; Tell the escape routine that we were successful. - sta d ; -@end: - rts ; End of isup. - - -isdown: - lda c ; Load the escape code into the accumulator. - cmp #'B' ; Did the user press the down arrow key? - bne @end ; No, so we're done. - lda scr_row ; Yes, so start checking the y coordinate of the cursor. - cmp #maxrow ; Is the cursor at the bottom of the screen? - beq @scroll ; Yes, so scroll down. - lda c ; No, so load the escape code back into the accumulator. - cmp #'B' ; Did the user press the down arrow key? - beq @down ; Yes, so move the cursor down. - bra @end ; No, so we're done. -@down: - inc scr_row ; Move the cursor down a line. - jsr update_pos ; Update it's position. - lda #1 ; Tell the escape routine that we succeded. - sta d ; - rts ; We are done. -@scroll: - lda scr_row ; Save the cursor's row number. - sta scr_trow ; - lda scr_col ; Save the cursor's column number. - sta scr_tcol ; - jsr scrl_down ; Scroll down. - lda scr_trow ; Load the cursor's row number. - sta scr_row ; - lda scr_tcol ; Load the cursor's column number. - sta scr_col ; - lda #1 ; Tell the escape routine that we were successful. - sta d ; -@end: - rts ; End of isdown. - - -isright: - lda c ; Load the escape code into the accumulator. - cmp #'C' ; Did the user press the right arrow key? - bne @end2 ; No, so we're done. - lda scr_col ; Yes, so start checking the x coordinate of the cursor. - cmp #maxcol ; Is the cursor at the far right of the screen? - beq @wrap ; Yes, so check if this is a wrapped line. - bra @right ; No, so move the cursor right, like normal. -@wrap: - inc scr_row ; Move down a row. - jsr getbit ; Is the current line, a wrapped line? - bcs @incr ; Yes, so leave the cursor where it is. - dec scr_row ; No, so move the cursor back up a row. - bra @end2 ; We are done. -@scroll: - lda scr_str ; Are we at the top of the screen buffer? - beq @end ; Yes, so we're done. - lda #1 ; No, so scroll down. - sta wrapped ; Set the wrapped flag. - jsr scrl_down ; Scroll down. - bra @end ; We are done. -@incr: - lda #0 ; Set the cursor to the far left of the screen. - sta scr_col ; - lda scr_row ; Get the current row number. - cmp #maxrow ; Are we at the bottom of the screen? - beq @end1 ; No, so we're done. - bcs @scroll ; Yes, so check if we are scrolling down. - bra @end1 ; No, so we're done. -@right: - inc scr_col ; Move the cursor right by one character. - jsr update_pos ; Update it's position. - rts ; End of isright. -@end: - dec scr_row ; Move back up a row. -@end1: - jsr update_pos ; Update the cursor position. -@end2: - lda #0 ; Unset the wrapped flag. - sta wrapped ; - rts ; End of isright. - - -isleft: - lda c ; Load the escape code into the accumulator. - cmp #'C' ; Did the user press right? - beq @end1 ; Yes, so we're done - lda scr_col ; No, but is the cursor at the far left of the screen? - beq @wrap ; Yes, so start checking if this is a wrapped line. - lda c ; No, so load the escape code back into the accumulator. - cmp #'D' ; Did the user press the left arrow key? - beq @left ; Yes, so move the cursor left. - bra @end1 ; No, so we're done. -@wrap: - jsr getbit ; Is the current line, a wrapped line? - bcs @decr ; Yes, so wrap back up a line. - bra @end1 ; No, so we're done. -@decr: - lda scr_row ; Is the cursor at the top of the screen? - beq @decr1 ; Yes, so don't move up a line. - lda #1 ; No, so set the wrapped flag. - sta wrapped ; - dec scr_row ; Move the cursor up one line. -@decr1: - lda #maxcol ; Move the Cursor to the far right of the screen. - sta scr_col ; - lda #1 ; Tell the escape routine that we were successful. - sta d ; - lda scr_row ; Are we at the top of the screen? - beq @scroll ; Yes, so check if we need to scroll. - bra @end ; No, so we're done. -@scroll: - lda wrapped ; Was the wrapped flag set somewhere else? - bne @end ; Yes so we're done. - lda scr_str ; No, but are we actually at the top of the screen buffer? - beq @end1 ; Yes, so we're done. - jsr scrl_up ; No, so scroll up. - bra @end1 ; We are done. -@left: - dec scr_col ; Move the cursor left a character. - jsr update_pos ; Update it's position. - lda #1 ; Tell the escape routine that we succeded. - sta d ; - rts ; We are done -@end: - jsr update_pos ; Update the cursor position. -@end1: - lda #0 ; Unset the wrapped flag. - sta wrapped ; - rts ; End of isleft. - - -isshftup: - lda c ; Load the escape code back into the accumulator. - cmp #'A' ; Did the user press the up arrow key? - bne @end ; - lda #1 ; - sta d ; - lda scr_str ; - beq @end ; -@shftup: - jsr scrl_up ; - lda #1 ; - sta d ; -@end: - rts ; - - -isshftdown: - lda c ; Load the escape code back into the accumulator. - cmp #'B' ; Did the user press the down arrow key? - bne @end ; - lda #1 ; - sta d ; - lda scr_end ; - cmp #71 ; - bcs @end ; -@shftdown: - jsr scrl_down ; - lda #1 ; - sta d ; -@end: - rts ; - - -update_pos: - ldb #1 ; Set the F pseudo register to one, to fix some bugs. - stb f ; - clc ; Clear the carry flag. - lda scr_row ; Add the cursor's line number, - adc scr_str ; with the starting line number to get the absolute line number. - tay ; Place it in the Y regster for now. - mul #maxcol+1 ; Multiply the line number by the screen's max column count, plus 1. - clc ; Clear the carry flag. - adc scr_col ; Add the cursor's column number to get the screen index. - tay ; Place the index into the Y register. - tba ; Reset A. - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - jsr getrow ; Start printing the row number to the screen. - jsr getcol ; Start printing the column number to the screen. - lda #'H' ; Print 'H' - sta scr ; to the screen. - rts ; End of update_pos. - -getrow: - lda scr_row ; Get the cursor's y coordinate. - bra bcd ; Convert it to BCD. -getcol: - lda #';' ; Print ';' - sta scr ; to the screen. - lda scr_col ; Get the cursor's x coordinate. -bcd: - div #10 ; Divide A by 10. - ora #'0' ; Convert it to ascii, and - sta scr ; print to the screen. - tba ; Get the remainder. - ora #'0' ; Convert it to ascii, and - sta scr ; print to the screen. - rts ; End of bcd. - -scrl_down: - inc scr_str ; Increment the starting line of the screen. - inc scr_end ; Increment the ending line of the screen. - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'T' ; Print 'T' - sta scr ; to the screen, and end the escape sequence. - lda scr_row ; Get the cursor's line number. - pha ; Save it in the stack. - lda wrapped ; Was the wrapped flag set? - beq @save ; Yes, so save the cursor position. -@redraw: - jsr rdrw_row ; No, so redraw this row. - lda wrapped ; Was the wrapped flag set? - beq @load ; Yes, so load the previous cursor position back. - bra @end ; No, so we're done. -@save: - lda scr_col ; Get the cursor's column number. - pha ; Save it in the stack. - bra @redraw ; Start redrawing the current row. -@load: - pla ; Get the cursor's previous column number back. - sta scr_col ; -@end: - pla ; Get the cursor's previous line number back. - sta scr_row ; - jsr update_pos ; Update the cursor's position. - lda #0 ; Clear the wrapped flag. - sta wrapped ; -@end1: - rts ; End of scrl_down. - -scrl_up: - dec scr_str ; - dec scr_end ; - lda #$1B ; Print an escape character - sta scr ; to the screen. - lda #'[' ; Print '[' - sta scr ; to the screen, and start the escape sequence. - lda #'S' ; Print 'S' - sta scr ; to the screen, and end the escape sequence. - lda scr_row ; - pha ; - lda scr_col ; - pha ; - lda #0 ; - sta scr_row ; - jsr rdrw_row ; - pla ; - sta scr_col ; - pla ; - sta scr_row ; - jsr update_pos ; -@end: - rts ; - -rdrw_row: - lda #0 ; - sta scr_col ; - jsr update_pos ; -@loop: - lda (ptr3), y ; - beq @incr ; - sta scr ; -@incr: - inc scr_col ; - lda (ptr3), y ; - beq @skip ; -@incr1: - iny ; -@incr2: - lda scr_col ; - cmp #maxcol+1 ; - bcs @end ; - bra @loop ; -@skip: - lda #' ' ; - sta scr ; to the screen. - bra @incr1 ; -@end: - lda #0 ; - sta scr_col ; - jsr update_pos ; -@end1: - rts ; - -rdrw_ln: - lda scr_row ; - pha ; - lda f ; - sta scr_row ; - lda scr_col ; - pha ; - jsr update_pos ; -@loop: - lda scr_row ; - cmp e ; - beq @loop1 ; - bcs @end ; -@loop1: - jsr rdrw_row ; -@incr: - inc scr_row ; - bra @loop ; -@end: - pla ; - sta scr_col ; - pla ; - sta scr_row ; - jsr update_pos ; - lda #0 ; - sta e ; - sta f ; - rts ; - -set_ptr: - cpb #1 ; Are we setting the second pointer? - beq @ptr2 ; Yes, so start setting it. - cpb #2 ; No, but are we setting the third pointer? - beq @ptr3 ; Yes, so start setting it. -@ptr1: - stb.q ptr ; Reset the first pointer. - sta.q ptr ; No, so set the first pointer. - bra @end ; We are done. -@ptr2: - stb.q ptr2 ; Reset the second pointer. - sta.q ptr2 ; Set the second pointer. - bra @end ; We are done. -@ptr3: - stb.q ptr3 ; Reset the third pointer. - sta.q ptr3 ; Set the third pointer. -@end: - rts ; End of set_ptr. diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s index 7b31c31..3fc025d 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/test-size.s b/programs/sub-suite/test-size.s deleted file mode 100644 index b543a36..0000000 --- a/programs/sub-suite/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/tmp-stuff/cmd_cpy.c b/programs/sub-suite/tmp-stuff/cmd_cpy.c new file mode 100644 index 0000000..6b89e7d --- /dev/null +++ b/programs/sub-suite/tmp-stuff/cmd_cpy.c @@ -0,0 +1,33 @@ +#include + +int cmd_size = 0x400; +int maxcol = 80; + +extern uint8_t scr_row; +extern uint8_t scr_col; +extern uint8_t scr_str; + +int find_end(char *str, int pos) { + int i; + for (i = pos; str[i] != '\0'; i++); + return i; +} + +void cmd_cpy(char *scr_buf, char *cmd_buf, int pos) { + int end_line = (find_end(scr_buf, pos)/(maxcol+1)) - scr_str; + int start_line = (find_start(scr_buf, end_line) + scr_str) * (maxcol+1); + + for (int i = 0, done = 0; !done; i++) { + uint64_t tmp = (uint64_t)scr_buf[i]; + for (int j = 0; j < 8; j++ , tmp >>= 8) { + int idx = (i*8) + j; + uint8_t tmp2 = tmp; + if (idx >= cmd_size || !tmp2) { + done = 1; + cmd_buf[idx] = '\0'; + break; + } + cmd_buf[idx] = tmp2; + } + } +} diff --git a/programs/sub-suite/tmp-stuff/free-new.s b/programs/sub-suite/tmp-stuff/free-new.s new file mode 100644 index 0000000..dad19d0 --- /dev/null +++ b/programs/sub-suite/tmp-stuff/free-new.s @@ -0,0 +1,143 @@ +.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 new file mode 100644 index 0000000..7f75edd --- /dev/null +++ b/programs/sub-suite/tmp-stuff/free-old.s @@ -0,0 +1,200 @@ +.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 new file mode 100644 index 0000000..e12461c --- /dev/null +++ b/programs/sub-suite/tmp-stuff/print_char.s @@ -0,0 +1,147 @@ +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 new file mode 100644 index 0000000..365666b --- /dev/null +++ b/programs/sub-suite/tmp-stuff/shift_line.c @@ -0,0 +1,85 @@ +#include + +const uint8_t bits[8] = { + 0x80, + 0x40, + 0x20, + 0x10, + 0x08, + 0x04, + 0x02, + 0x01 +}; + +int maxcol = 80; +int scr_str = 0; +int scr_row = 0; +int scr_col = 0; +uint8_t bitabl[16]; + +uint8_t bitpos(unsigned int row, uint8_t *mask) { + uint8_t bit = row & 7; + *mask = bits[bit]; + return row >> 3; + +} + +uint8_t getbit(unsigned int row, unsigned int offset) { + uint8_t mask; + uint8_t byte = bitpos(row+offset, &mask); + return (bitabl[byte] & mask); +} + +void setbit(unsigned int row) { + uint8_t mask; + uint8_t byte = bitpos(row, &mask); + bitabl[byte] |= mask; +} + +void clrbit(unsigned int row) { + uint8_t mask; + uint8_t byte = bitpos(row, &mask); + bitabl[byte] &= ~mask; +} + +int find_end(char *str, int start) { + int i; + for (i = start; str[i]; i++); + return i; +} + +void shift_line(char *str, int cursor, int left) { + /*int cursor = ((scr_row+scr_str)*maxcol)+scr_col;*/ + int end = find_end(str, cursor); + if (left) { + int i = end-1; + int j = end; + for (; i >= cursor; i--, j--) { + if (i < 0) { + i = 0; + str[i] = 0; + break; + } + str[j] = str[i]; + str[i] = 0; + + } + /*str[i+1] = (!str[i+1]) ? ' ' : str[i+1];*/ + end = find_end(str, i+2); + /*str[i+1] = (str[i+1] == ' ') ? 0 : str[i+1];*/ + if ((end/maxcol) > scr_row) { + setbit(end/maxcol); + } + } else { + int i = cursor; + int j = cursor-1; + for (; str[i]; i++, j++) { + str[j] = str[i]; + str[i] = 0; + } + end = find_end(str, i); + if (((end-1) % maxcol) == 0 && ((end-1)/maxcol) > scr_row) { + clrbit(end/maxcol); + } + } +} diff --git a/programs/sub-suite/tmp-stuff/subeditor-new.s b/programs/sub-suite/tmp-stuff/subeditor-new.s new file mode 100644 index 0000000..6c1cfb1 --- /dev/null +++ b/programs/sub-suite/tmp-stuff/subeditor-new.s @@ -0,0 +1,1119 @@ +; SuBEditor. +; +; Writen in Sux assembly by +; mr b0nk 500 + + +.org $8000 +reset: + cps ; Reset the processor status register. + ldx.w #$FFFF ; Reset the stack pointer. + txs ; + ldy #0 ; Reset the Y register. + sty end ; + tyx ; Reset the X register. + lda #maxrow ; Set the end of the screen to the screen's max row count. + sta scr_end ; + tya ; Reset the Accumulator. + sta scr_str ; Set the start of the screen back to zero. + sta.q bitabl ; Reset the first half of the linewrap table. + sta.q bitabl+8 ; Reset the second half of the linewrap table. + inc end ; + lda.w #$1FFF ; Set the clear count to $1FFF. + pha.w ; Push the clear count to the stack. + lda.d #buffer ; Set the array to be cleared to the screen buffer. + pha.q ; Push it on to the stack. + jsr clr_arr ; Clear the screen buffer. + pla.q ; Pull the pointer off of the stack. + pla.w ; Pull the clear count off of the stack. + and #0 ; Reset A. + jsr pnt_strt ; Print the starting message. + lda #$C ; Clear the screen. + sta scr ; + bra start ; Goto the start of the main program. + +clr_arr: + phb ; Preserve whatever was in B. + ldb #0 ; Clear B. + clc ; Prepare for a non carrying add. + adc #8 ; Set the second pointer to the parameter, plus eight. + pha.q ; Push it onto the stack. + tba ; +@loop: + cpy.w sp+26 ; Did we clear all of the array? + bcs @end ; Yes, so we're done. + sta.q (sp+18), y; No, so clear eight bytes. + sta.q (sp+1), y ; Clear eight more bytes. + tya ; Copy the array index. + adc #$10 ; Increment the index by 16. + tay ; Update the index. + tba ; Reset the Accumulator. + sta.q (sp+18), y; Do this one more time, to clear 32 bytes. + sta.q (sp+1), y ; + tya ; + adc #$10 ; + tay ; + tba ; + bra @loop ; Keep looping. +@end: + ldy.w zero ; Set the index back to zero. + pla.q ; Move the stack pointer back. + tba ; Reset A. + plb ; Get whatever was in the B register, back. + rts ; End of clr_arr. + +pnt_strt: + lda.w #ed_name ; Print the name of the editor. + jsr print_str ; + lda.w #ver_str ; Print the version text. + jsr print_str ; + lda.w #ed_ver ; Print the version number. + jsr print_str ; + lda.w #ed_sver ; Print the sub version number. + jsr print_str ; + lda #'\n' ; Print a newline. + jsr print_char ; + lda.w #made ; Print the "Created by" text. + jsr print_str ; + lda.w #author ; Print the name of the author. + jsr print_str ; + lda #'\n' ; Print a newline. + jsr print_char ; + rts ; End of pnt_strt. + +start: + lda #0 ; TODO: Update this for the Super VIA. + sta status ; Clear the control register of the I/O adapter. + tax ; Reset X. + phy.w ; Save the cursor index for later. + tay ; Reset the cursor index. + lda.w #$3FF ; Set the clear count to $3FF. + pha.w ; Push the clear count onto the stack. + lda.d #cmd_buf ; Set the array to be cleared to the command buffer. + pha.q ; Push the pointer onto the stack. + jsr clr_arr ; Clear the command buffer. + pla.q ; Pull the pointer off of the stack. + pla.w ; Pull the clear count off of the stack. + ply.w ; Get back the cursor index. + and #0 ; Reset the Accumulator. + sta end ; + bra read ; Start reading the keyboard. + +read: + lda #0 ; Reset the Accumulator. + sta end ; Disable the dummy flag. + inc end ; Enable the dummy flag. + lda status ; Did we get a key? + beq read ; No, so try again. + jsr getchar ; Yes, and was it a newline? + beq parse ; Yes, so start parsing the line. + bra read ; No, so keep looping. + +parse: + lda #0 ; + tax ; + jsr subasm ; + bra start ; + + +print_str: + ldx #0 ; Reset X. + pha.q ; Push the parameter onto the stack. +@loop: + ldb #1 ; Enable replace mode. + stb b ; + and #0 ; No, reset the accumulator. + phy.w ; Save the cursor index. + txy ; Copy the string index into Y. + lda (sp+3), y ; Are we at the end of the string? + ply.w ; Get the cursor index back. + beq @end ; Yes, so we're done. + inx ; No, so increment the string index. + jsr print_char ; Print the character. + bra @loop ; Keep looping. +@end: + pla.q ; Pull the parameter off the stack. + ldb #0 ; Enable insert mode. + stb b ; + tba ; Reset A. + rts ; End of print_str. + +getbit: + clc ; Clear the carry flag. + lda scr_str ; Has the screen been scrolled? + bne getbt0 ; Yes, so add the screen offset to the current line number. + ldx scr_row ; No, so just use the current line number. + bra getbt1 ; Start getting the bit. +getbt0: + lda scr_row ; Get the current line number. + adc scr_str ; Add the screen offset to it. + tax ; Use it as the wrap index. +getbt1: + tab ; Save the parameter. + lda.d #bitabl ; Set the second pointer to the linewrap table. + pha.q ; Push the pointer onto the stack. + tba ; Get the parameter back. + jsr bitpos ; Get the bit, and byte position. + phy.w ; Save the screen index. + txy ; Get the byte position. + ldb (sp+3), y ; Get one byte of the wrap table. + ply.w ; Get the screen index back. + aba ; Mask out the bit of the current line number. + cmp #1 ; Set the carry flag, if true. + bra bitout ; We are done. + +clrbit: + tab ; Save the parameter. + lda.d #bitabl ; Set the second pointer to the linewrap table. + pha.q ; Push the pointer onto the stack. + tba ; Get the parameter back. + jsr bitpos ; Get the bit, and byte position. + xor #$FF ; Invert the bitmask. + phy.w ; Save the screen index. + txy ; Get the byte position. + ldb (sp+3), y ; Get one byte of the wrap table. + aba ; Clear the bit of the current line number. +bitsav: + sta (sp+3), y ; Update the wrap table. + ply.w ; Get the screen index back. +bitout: + pla.q ; Pull the pointer off the stack. + and #0 ; Reset A. + ldx bitmask ; Return the bitmask. + rts ; We are done. + +setbit: + tab ; Save the parameter. + lda.d #bitabl ; Set the second pointer to the linewrap table. + pha.q ; Push the pointer onto the stack. + tba ; Get the parameter back. + jsr bitpos ; Get the bit, and byte position. + phy.w ; Save the screen index. + txy ; Get the byte position. + ldb (sp+3), y ; Get one byte of the wrap table. + oab ; Set the bit of the current line number. + bra bitsav ; Save the bit. + +bitpos: + tab ; Save the parameter. + lda.w #bits ; Set the first pointer to the bitmask table. + pha.q ; Push the pointer onto the stack. + tba ; Get the parameter back. + stx bitmask ; Make the line number the bitmask. + txa ; Copy it to the Accumulator. + and #7 ; Get the bit position. + phy.w ; Save the cursor index. + tay ; Use the bit position as the index. + tax ; Copy it into X. + lda (sp+3), y ; Get the bitmask. + ply.w ; Get back the cursor index. + pha ; Save the bitmask. + lda bitmask ; Get the line number. + lsr #3 ; Get the byte position. + tax ; Copy it into X. + pla ; Get back the bitmask. + tab ; Preserve the bitmask. + pla.q ; Pull the pointer off the stack. + tba ; Get the bitmask back. + rts ; End of bitpos. + +getchar: + lda kbd ; Get the character that was typed from the keyboard. + ldb #0 ; Reset the B register. + stb e ; Set the temporary row position to zero, in case we get a newline. + stb b ; Enable insert mode. + pha ; Save the character. + phy.w ; Save the cursor index. + cmp #'\n' ; Was the character that was typed, a newline? + bne @print ; No, so just print the character. + jsr cmd_cpy ; Yes, so start copying the line to the command buffer. +@print: + ply.w ; Get back the cursor index. + pla ; Get back the character. + ldb e ; Is the temporary row position non zero? + bne @row ; Yes, so reset the row positon. +@print1: + jsr print_char ; No, so print the character. + lda a ; Get the return value. + cmp #'\n' ; Is the return value, a newline? + beq @true ; Yes, so return true. + bra @false ; No, so return false. +@row: + ldb e ; Get the temporary row position. + cpb #maxrow ; Is temporary row position, at, or above the bottom of the screen? + beq @row2 ; Yes, so leave it as is. + bcs @row1 ; No, so set it to the bottom of the screen. + bra @row2 ; Yes, so leave it as is. +@row1: + ldb #maxrow ; Set the row position to the bottom of the screen. +@row2: + stb scr_row ; Set the row position. + bra @print1 ; Print the character. +@true: + lda #0 ; Return true. + bra @end ; We are done. +@false: + lda #1 ; Return false. +@end: + rts ; End of getchar. + + +cmd_cpy: + lda scr_row ; Get the row position. + sta scr_trow ; Save it for later. + jsr findend ; Find the end of the line. + ldb scr_str ; Has the screen been scrolled? + beq @start ; No, so don't subtract the screen's starting point from the line number. +@offset: + sec ; Yes, so make sure that we don't subtract by the starting point, plus one. + sbc scr_str ; Offset the row position, back by the screen's starting point. + clc ; Clear the carry flag, so that nothing odd occurs. +@start: + sta scr_row ; Set the row position to the end of the line. + sta e ; Save it into the temporary row posiition. + jsr findst ; Find the start of the line. + clc ; Clear the carry flag. + lda scr_row ; Get the row position. + adc scr_str ; Add it with the screen's starting row. + mul #maxcol+1 ; Multiply it with the width of the screen, plus one. + tay ; Place it into the index. + ldx.w #0 ; Reset the X register. + ldb #0 ; Make sure that set_ptr sets the first pointer. + lda.d #buffer ; Set the first pointer to the start of the screen buffer. + pha.q ; Push the pointer onto the stack. + lda.d #cmd_buf ; Set the second pointer to the start of the command buffer. + pha.q ; Push the pointer onto the stack. + tba ; Set the accumulator to zero. +@loop: + ldb #0 ; Reset the B register. + lda.q (sp+9), y ; Get eight bytes from the current line. +@loop1: + phy.w ; Save the screen index. + txy ; Get the command buffer index. + sta (sp+3), y ; Copy one byte from the screen buffer, to the command buffer. + inx ; Increment the command buffer index. + ply.w ; Get back the screen index. + cpx.w #$3FF ; Are we at the end of the command buffer? + bcs @end ; Yes, so we're done. + iny ; No, so increment the screen index. + inb ; Increment the byte count. + lsr #8 ; Shift in the next byte. + stb g ; Save the byte count. + tab ; Save the string buffer. + and #$FF ; Is this byte of the buffer, a null terminator? + beq @end1 ; Yes, so we're done. + tba ; No so get back the string buffer. + ldb g ; Get back the byte count. + cpb #7 ; Did we shift in eight bytes? + beq @loop ; Yes, so get eight more bytes. + bra @loop1 ; No, so keep shifting in more bytes. +@end: + ldb #0 ; Reset B. + phy.w ; Save the screen index. + txy ; Get the command buffer index. + stb (sp+3), y ; Terminate the command buffer. + ply.w ; Get back the screen index. +@end1: + pla.q ; Pull one of the pointers off the stack. + pla.q ; Pull the other pointer off the stack. + tba ; The B register is zero, so clear the Accumulator. + rts ; End of cmd_cpy. + + +findst: + lda #0 ; Reset A. +@loop: + pha ; Save the current line number. + jsr getbit ; Is this the start of the line? + pla ; Get the current line number back. + bcc @end ; Yes, so we're done. + inc ; No, so check the next physical line. + dec scr_row ; Are we at the top of the screen? + bpo @loop ; No, so keep looping. + dec ; Yes, so move back one line. + inc scr_row ; Put the row postiion back to zero. +@end: + cmp #0 ; Update all the flags. + rts ; End of findst. + + +fndend: + lda.d #buffer ; Set the first pointer to the start of the screen buffer. + pha.q ; Push the pointer onto the stack. + phb ; Save the contents of the B register. + ldb #0 ; Make sure that set_ptr sets the first pointer. + tba ; Set the Accumulator to zero. + plb ; Restore the contents of the B register. + phy.w ; +@loop: + lda (sp+3), y ; Are we at the end of the string? + beq @end ; Yes, so we're done. + iny ; No, so increment the cursor index. + bra @loop ; Keep looping. +@end: + sty.w scr_ptr3 ; + ply.w ; + pla.q ; Pull the pointer off the stack. + and #0 ; Reset A. + rts ; End of fndend. + +findend: + jsr fndend ; + lda.w scr_ptr3 ; + div #maxcol+1 ; + rts ; + + +print_char: + sta a ; Save the typed character for now. + ldb #2 ; Make sure that set_ptr sets the third pointer. + lda.d #buffer ; Set the third pointer to the start of the screen buffer. + jsr set_ptr ; + ldb #0 ; Set B to zero. + tba ; Set the Accumulator to zero. + lda a ; Get back the character. + cmp #$1B ; Did the user type an escape character? + beq esc ; Yes, so go check the escape code. + cmp #'\n' ; No, but did the user type a newline? + beq nl ; Yes, so handle the newline. + cmp #$C ; No, but did the user type Ctrl+L? + beq clr_scr ; Yes, so clear the screen. + cmp #19 ; No, but did the user type Ctrl+S? + beq en_step ; Yes, so enable clock/instruction stepping. + cmp #18 ; No, but did the user type Ctrl+R? + beq dis_step ; Yes, so disable clock/instruction stepping. + cmp #'\b' ; No, but did the user type a backspace? + beq bs ; Yes, so handle the backspace. + cmp #$7F ; No, but did they type Delete? + beq bs ; Yes, so treat it as a backspace. +printc: + lda #0 ; No, so start trying to print a character. + sta d ; + lda (ptr3), y ; Are we at the end of the string? + beq @save ; Yes, so just print the character. + lda b ; No, but was the flag set? + bne @save ; Yes, so don't shift the line. + sty.w scr_ptr ; No, so save the cursor index for later. + jsr fndend ; Find the end of the line. + bra @shift ; Start shifting the line right. +@update: + lda scr_col ; Save the current column position for later. + sta scr_tcol ; +@update1: + jsr findend ; Find the end of the line. + sta e ; Use it for redrawing the line. + sta scr_row ; Set the row position to to the end of the line. + jsr findst ; Find the start of the line. + lda scr_row ; Get the start of the line. +@update2: + sta f ; Set the starting line, to the start of the line. + jsr rdrw_ln ; Redraw the line. + lda scr_trow ; Get the real row position back. + sta scr_row ; + lda scr_tcol ; Get the real column position back. + sta scr_col ; + jsr update_pos ; Update the cursor's position. + dec d ; + bra @save1 ; +@shift: + ldy.w scr_ptr3 ; + inc scr_ptr3 ; + tyx ; + dey ; + ldb #1 ; + stb d ; + jsr shftln ; + ldb #1 ; + stb d ; + lda a ; + sta (ptr3), y ; store typed character into the input buffer. + lda scr_row ; + sta scr_trow ; + bra @update ; +@save: + ldb d ; + bne @update ; +@save1: + lda a ; + sta (ptr3), y ; store typed character into the input buffer. +@incr: + inc scr_col ; Increment the cursor's x coordinate. + iny ; +@wrapped: + ldb #1 ; + stb f ; + ldb scr_col ; + cpb #maxcol+1 ; + bcs @scrolled ; +@print: + sta scr ; Echo typed character. + ldb f ; + beq @wrap ; + bra printc_end ; +@scrolled: + ldb scr_row ; + cpb #maxrow ; + bcs @scroll ; +@wrapped2: + ldb #0 ; + stb f ; + bra @print ; +@scroll: + sta scr ; Echo typed character. + clc ; + lda #1 ; + sta wrapped ; + jsr scrl_down ; +@wrap: + ldb #0 + stb scr_col ; + ldb scr_row ; + cpb #maxrow ; + bcs @wrap2 ; +@wrap1: + inc scr_row ; +@wrap2: + phx.w ; + clc ; + lda scr_row ; + adc scr_str ; + tax ; + jsr setbit ; + plx.w ; + jsr update_pos ; +printc_end: + rts ; + +nl: + lda #0 ; Reset A. + ldb (ptr3), y ; Is this character not a null terminator? + bne @scroll ; Yes, so don't overwrite it. + sta (ptr3), y ; No, so overwrite it. +@scroll: + sta scr_col ; Move the cursor to the start of the next line. + lda scr_row ; Get the row position. + cmp #maxrow ; Are we at the bottom of the screen? + bcc @incr ; No, so move down one line. + jsr scrl_down ; Yes, so scroll down one line. + bra @end ; We are done. +@incr: + inc scr_row ; Move the cursor down by one line. + jsr update_pos ; Update the cursor's position. +@end: + lda #'\n' ; Print the newline. + sta a ; + rts ; + + +clr_scr: + lda #maxrow ; + sta scr_end ; + lda #0 ; + sta scr_str ; + sta.q bitabl ; + sta.q bitabl+8 ; + tay ; + lda.w #$1FFF ; Set the clear count to $1FFF. + pha.w ; Push the clear count onto the stack. +; sta.w scr_ptr ; + lda.d #buffer ; Set the array to be cleared to the screen buffer. + pha.q ; Push the pointer onto the stack. + jsr clr_arr ; Clear the screen buffer. + tay ; + pla.q ; Pull the pointer off of the stack. + pla.w ; Pull the clear count off of the stack. + lda.w #$3FF ; Set the clear count to $3FF. + pha.w ; Push the clear count onto the stack. +; sta.w scr_ptr ; + lda.d #cmd_buf ; Set the array to be cleared to the command buffer. + pha.q ; + jsr clr_arr ; Clear the screen buffer. + pla.q ; Pull the pointer off of the stack. + pla.w ; Pull the clear count off of the stack. + and #0 ; Reset A. + sta scr_col ; + sta scr_row ; + jsr update_pos ; + lda #$C ; + sta scr ; + rts ; + +en_step: + lda step ; + beq step_en ; + rts ; +step_en: + lda #1 ; + sta step ; + rts ; + +dis_step: + lda step ; + bne step_dis ; + rts ; +step_dis: + lda #0 ; + sta step ; + rts ; + + +bs: + lda scr_col ; Are we at the far left of the screen? + beq @wrap ; Yes, so check for a wrapped line. + bra back ; No, so add the backspace to the buffer. +@wrap: + jsr getbit ; Is this line, a wrapped line? + bcs @wrap1 ; Yes, so check if the cursor is at the top. + rts ; No, so we're done. +@wrap1: + lda scr_row ; Are we at the top of the screen? + beq @wrap2 ; Yes, so check if the screen is at the top of the buffer. + bra @wrap3 ; No, so start clearing the wrap bit. +@wrap2: + lda scr_str ; Are we at the top of the buffer? + bne @scroll ; Yes, so scroll up. + rts ; No, so we're done. +@scroll: + clc ; Clear the carry flag, so that we don't get odd behaviour. + jsr scrl_up ; Scroll up. + inc scr_row ; Move down by one row. +@wrap3: + clc ; Clear the carry flag. + lda scr_row ; Add the cursor's row position, + adc scr_str ; and the screen's starting row. + tax ; Transfer that into X. +@wrap4: + dec scr_row ; Move up by one row. + ldb #maxcol+1 ; Move the cursor to the absolute right of the screen. + stb scr_col ; + jsr update_pos ; Update the cursor's position. +back: + ldb #0 ; Reset B, and some flags. + stb e ; + stb f ; + lda scr_row ; Save the current row position for later. + sta scr_trow ; + jsr findend ; Find the end of the line. + sta scr_row ; Set our row position to the end of the line. +@find_st: + jsr findst ; Does this line take up more than one real line? + beq @shift ; No, so skip updating any other lines. + bcs @update ; Yes, so update the other lines. + lda scr_trow ; Get the real row position back. + sta scr_row ; +@shift: + dey ; Decrement the buffer's offset. + lda #0 ; Place a null terminator + sta (ptr3), y ; into the buffer. + tyx ; Copy the current cursor index to X. + iny ; Increment cursor index. + ldb #0 ; Set shifting direction to left. + stb d ; + jsr shftln ; Shift line back by one character. + lda #$7F ; Print a backspace to the screen. + sta scr ; + lda e ; Are we updating more than one line? + beq @load ; No, so skip to the next step. +@find_end: + jsr findend ; Yes, so find the end of the line. + sta e ; Set the end parameter to it. + lda scr_col ; Save the current column position for now. + sta scr_tcol ; + jsr rdrw_ln ; Start redrawing the line. + lda scr_tcol ; Get the real column position back. + sta scr_col ; +@load: + lda scr_trow ; Get the real row position back. + sta scr_row ; + dec scr_col ; Move the cursor back by one column, + jsr update_pos ; and update it's position. + rts ; We are done. +@update: + lda scr_row ; Set the line to start redrawing, to the start of the line. + sta f ; + inc e ; Set the redraw flag to true. + bra @shift ; Start shifting the line back. + + +shftln: + ldb d ; Is the flag not set? + beq @dec_loop ; Yes, so shift, and decrement. + ldb #0 ; Clear the B register. + bra @inc_loop ; No, so shift, and increment. +@neg: + ldy.w zero ; Set the source poition to 0. + stb (ptr3), y ; Clear the character that is in the source. + bra @end ; We are done. +@inc_loop: + sty.w scr_ptr2 ; Save the source position for later. + ldy.w scr_ptr ; Get the previous cursor index. + cpy.w scr_ptr2 ; Is the source position, at, or below the cursor index? + beq @inc_loop1 ; Yes, so keep looping. + bcs @end ; No, so we're done. +@inc_loop1: + ldy.w scr_ptr2 ; Get the source position. + lda (ptr3), y ; Get the character from the source position. + phy.w ; Save the source position for later. + txy ; Set our position to the destination. + sta (ptr3), y ; Place the character from the source position, to the destination position. + ply.w ; Set our position back to the source. + stb (ptr3), y ; Clear the character that is in the source. + bng @neg ; The source underflowed, so set it back to zero, + dey ; Decrement the source position. + dex ; Decrement the destination position. + bra @inc_loop ; Keep looping. +@dec_loop: + stx.w scr_ptr2 ; Save the destination position for later. + lda (ptr3), y ; Is the character at the source position, a null terminator? + beq @end3 ; Yes, so we're done. + phy.w ; No, so save the source position for later. + txy ; Set our position to the destination. + sta (ptr3), y ; Place the character from the source position, to the destination position. + inx ; Increment the destination position. + ply.w ; Set our position back to the source. + stb (ptr3), y ; Clear the character that is in the source. + iny ; Increment the source position. + bra @dec_loop ; Keep looping. +@wrap: + tax ; Use the ending line as a parameter for setbit. + jsr setbit ; Set the wrap bit of the ending line. + bra @end5 ; We are done. +@wrap1: + tax ; Use the ending line as a parameter for clrbit. + jsr clrbit ; Clear the wrap bit of the ending line. + bra @end5 ; We are done. +@end: + lda (ptr3), y ; Is this character a null terminator? + bne @end1 ; No, so just find the end of the line. + lda #$20 ; Yes, so convert it to a space for now. + sta (ptr3), y ; +@end1: + jsr findend ; Find the ending line. + sta d ; Save ending line for later. + lda (ptr3), y ; Is this character a space? + cmp #$20 ; + bne @end5 ; No, so skip the conversion. + lda #0 ; Yes, so convert it back to zero. + sta (ptr3), y ; +@end2: + lda d ; Get the ending line. + cmp scr_row ; Is the ending line greater than the starting line? + beq @end5 ; No, so we're done. + bcs @wrap ; Yes, so set the wrap bit. + bra @end5 ; No, so we're done. +@end3: + jsr findend ; Find the ending line. + cpb #0 ; Is the remainder zero? + beq @end4 ; Yes, so check if the ending line is greater than the starting line. + bra @end5 ; No, so we're done. +@end4: + cmp scr_row ; Is the ending line greater than the starting line? + beq @end5 ; No, so we're done. + bcs @wrap1 ; Yes, so clear the wrap bit. +@end5: + rts ; End of shftln. + +esc: + lda status ; Get the next character. + lda kbd ; + cmp #$1B ; Is this character an escape character? + beq shftesc ; Yes, so check the other set of escape routines. + lda status ; No, so wait for the next character. + beq @end ; We have an error, so discard it, and go back to getting user input. + lda kbd ; Get the escape code. + sta c ; Store the escape code, until we need it. + lda #0 ; Set the D pseudo register to zero. + sta d ; + jsr isup ; Check if the user pressed up. + lda d ; Did the user press up? + bne @end ; Yes, so we're done. + jsr isdown ; No, so check if the user pressed down. + lda d ; Did the user press down? + bne @end ; Yes, so we're done. + lda #0 ; No, so check if the user pressed left. + jsr isleft ; + lda d ; Did the user press left? + bne @end ; Yes, so we're done. + jsr isright ; No, so check if the user pressed right. +@end: + lda #0 ; Clear the D pseudo register. + sta d ; + rts ; We are done. + +shftesc: + lda status ; Skip the '['. + lda kbd ; + lda status ; Wait for the next character. + beq @end ; We have an error, so discard it, and go back to getting user input. + lda kbd ; Get the escape code. + sta c ; Store the escape code, until we need it. + lda #0 ; Use the D pseudo register as a skip flag. + sta d ; + jsr isshftup ; Check if the user pressed shift+up. + lda d ; Was it successful? + bne @end ; Yes, so we're done. + jsr isshftdown ; No, so check if the user pressed shift+down. +@end: + lda #0 ; Clear the D pseudo register. + sta d ; + rts ; We are done. + + +isup: + lda c ; Load the escape code into the accumulator. + cmp #'A' ; Did the user press the up arrow key? + bne @end ; No, so we're done. + lda scr_row ; Yes, but is the cursor at the top of the screen? + beq @scroll ; Yes, so check if we need to scroll. +@check2: + lda c ; No, so load the escape code back into the accumulator. + cmp #'A' ; Did the user press the up arrow key? + beq @up ; Yes, so move the cursor up. + bra @end ; No, so we're done. +@up: + dec scr_row ; Move the cursor up a line. + jsr update_pos ; Update it's position. + lda #1 ; Tell the escape routine that we succeded. + sta d ; + rts ; We are done. +@scroll: + lda scr_str ; Are we at the top of the screen buffer? + beq @end ; Yes, so we're done. + jsr scrl_up ; No, so scroll up. + lda #1 ; Tell the escape routine that we were successful. + sta d ; +@end: + rts ; End of isup. + + +isdown: + lda c ; Load the escape code into the accumulator. + cmp #'B' ; Did the user press the down arrow key? + bne @end ; No, so we're done. + lda scr_row ; Yes, so start checking the y coordinate of the cursor. + cmp #maxrow ; Is the cursor at the bottom of the screen? + beq @scroll ; Yes, so scroll down. + lda c ; No, so load the escape code back into the accumulator. + cmp #'B' ; Did the user press the down arrow key? + beq @down ; Yes, so move the cursor down. + bra @end ; No, so we're done. +@down: + inc scr_row ; Move the cursor down a line. + jsr update_pos ; Update it's position. + lda #1 ; Tell the escape routine that we succeded. + sta d ; + rts ; We are done. +@scroll: + lda scr_row ; Save the cursor's row number. + sta scr_trow ; + lda scr_col ; Save the cursor's column number. + sta scr_tcol ; + jsr scrl_down ; Scroll down. + lda scr_trow ; Load the cursor's row number. + sta scr_row ; + lda scr_tcol ; Load the cursor's column number. + sta scr_col ; + lda #1 ; Tell the escape routine that we were successful. + sta d ; +@end: + rts ; End of isdown. + + +isright: + lda c ; Load the escape code into the accumulator. + cmp #'C' ; Did the user press the right arrow key? + bne @end2 ; No, so we're done. + lda scr_col ; Yes, so start checking the x coordinate of the cursor. + cmp #maxcol ; Is the cursor at the far right of the screen? + beq @wrap ; Yes, so check if this is a wrapped line. + bra @right ; No, so move the cursor right, like normal. +@wrap: + inc scr_row ; Move down a row. + jsr getbit ; Is the current line, a wrapped line? + bcs @incr ; Yes, so leave the cursor where it is. + dec scr_row ; No, so move the cursor back up a row. + bra @end2 ; We are done. +@scroll: + lda scr_str ; Are we at the top of the screen buffer? + beq @end ; Yes, so we're done. + lda #1 ; No, so scroll down. + sta wrapped ; Set the wrapped flag. + jsr scrl_down ; Scroll down. + bra @end ; We are done. +@incr: + lda #0 ; Set the cursor to the far left of the screen. + sta scr_col ; + lda scr_row ; Get the current row number. + cmp #maxrow ; Are we at the bottom of the screen? + beq @end1 ; No, so we're done. + bcs @scroll ; Yes, so check if we are scrolling down. + bra @end1 ; No, so we're done. +@right: + inc scr_col ; Move the cursor right by one character. + jsr update_pos ; Update it's position. + rts ; End of isright. +@end: + dec scr_row ; Move back up a row. +@end1: + jsr update_pos ; Update the cursor position. +@end2: + lda #0 ; Unset the wrapped flag. + sta wrapped ; + rts ; End of isright. + + +isleft: + lda c ; Load the escape code into the accumulator. + cmp #'C' ; Did the user press right? + beq @end1 ; Yes, so we're done + lda scr_col ; No, but is the cursor at the far left of the screen? + beq @wrap ; Yes, so start checking if this is a wrapped line. + lda c ; No, so load the escape code back into the accumulator. + cmp #'D' ; Did the user press the left arrow key? + beq @left ; Yes, so move the cursor left. + bra @end1 ; No, so we're done. +@wrap: + jsr getbit ; Is the current line, a wrapped line? + bcs @decr ; Yes, so wrap back up a line. + bra @end1 ; No, so we're done. +@decr: + lda scr_row ; Is the cursor at the top of the screen? + beq @decr1 ; Yes, so don't move up a line. + lda #1 ; No, so set the wrapped flag. + sta wrapped ; + dec scr_row ; Move the cursor up one line. +@decr1: + lda #maxcol ; Move the Cursor to the far right of the screen. + sta scr_col ; + lda #1 ; Tell the escape routine that we were successful. + sta d ; + lda scr_row ; Are we at the top of the screen? + beq @scroll ; Yes, so check if we need to scroll. + bra @end ; No, so we're done. +@scroll: + lda wrapped ; Was the wrapped flag set somewhere else? + bne @end ; Yes so we're done. + lda scr_str ; No, but are we actually at the top of the screen buffer? + beq @end1 ; Yes, so we're done. + jsr scrl_up ; No, so scroll up. + bra @end1 ; We are done. +@left: + dec scr_col ; Move the cursor left a character. + jsr update_pos ; Update it's position. + lda #1 ; Tell the escape routine that we succeded. + sta d ; + rts ; We are done +@end: + jsr update_pos ; Update the cursor position. +@end1: + lda #0 ; Unset the wrapped flag. + sta wrapped ; + rts ; End of isleft. + + +isshftup: + lda c ; Load the escape code back into the accumulator. + cmp #'A' ; Did the user press the up arrow key? + bne @end ; + lda #1 ; + sta d ; + lda scr_str ; + beq @end ; +@shftup: + jsr scrl_up ; + lda #1 ; + sta d ; +@end: + rts ; + + +isshftdown: + lda c ; Load the escape code back into the accumulator. + cmp #'B' ; Did the user press the down arrow key? + bne @end ; + lda #1 ; + sta d ; + lda scr_end ; + cmp #71 ; + bcs @end ; +@shftdown: + jsr scrl_down ; + lda #1 ; + sta d ; +@end: + rts ; + + +update_pos: + ldb #1 ; Set the F pseudo register to one, to fix some bugs. + stb f ; + clc ; Clear the carry flag. + lda scr_row ; Add the cursor's line number, + adc scr_str ; with the starting line number to get the absolute line number. + tay ; Place it in the Y regster for now. + mul #maxcol+1 ; Multiply the line number by the screen's max column count, plus 1. + clc ; Clear the carry flag. + adc scr_col ; Add the cursor's column number to get the screen index. + tay ; Place the index into the Y register. + tba ; Reset A. + lda #$1B ; Print an escape character + sta scr ; to the screen. + lda #'[' ; Print '[' + sta scr ; to the screen, and start the escape sequence. + jsr getrow ; Start printing the row number to the screen. + jsr getcol ; Start printing the column number to the screen. + lda #'H' ; Print 'H' + sta scr ; to the screen. + rts ; End of update_pos. + +getrow: + lda scr_row ; Get the cursor's y coordinate. + bra bcd ; Convert it to BCD. +getcol: + lda #';' ; Print ';' + sta scr ; to the screen. + lda scr_col ; Get the cursor's x coordinate. +bcd: + div #10 ; Divide A by 10. + ora #'0' ; Convert it to ascii, and + sta scr ; print to the screen. + tba ; Get the remainder. + ora #'0' ; Convert it to ascii, and + sta scr ; print to the screen. + rts ; End of bcd. + +scrl_down: + inc scr_str ; Increment the starting line of the screen. + inc scr_end ; Increment the ending line of the screen. + lda #$1B ; Print an escape character + sta scr ; to the screen. + lda #'[' ; Print '[' + sta scr ; to the screen, and start the escape sequence. + lda #'T' ; Print 'T' + sta scr ; to the screen, and end the escape sequence. + lda scr_row ; Get the cursor's line number. + pha ; Save it in the stack. + lda wrapped ; Was the wrapped flag set? + beq @save ; Yes, so save the cursor position. +@redraw: + jsr rdrw_row ; No, so redraw this row. + lda wrapped ; Was the wrapped flag set? + beq @load ; Yes, so load the previous cursor position back. + bra @end ; No, so we're done. +@save: + lda scr_col ; Get the cursor's column number. + pha ; Save it in the stack. + bra @redraw ; Start redrawing the current row. +@load: + pla ; Get the cursor's previous column number back. + sta scr_col ; +@end: + pla ; Get the cursor's previous line number back. + sta scr_row ; + jsr update_pos ; Update the cursor's position. + lda #0 ; Clear the wrapped flag. + sta wrapped ; +@end1: + rts ; End of scrl_down. + +scrl_up: + dec scr_str ; + dec scr_end ; + lda #$1B ; Print an escape character + sta scr ; to the screen. + lda #'[' ; Print '[' + sta scr ; to the screen, and start the escape sequence. + lda #'S' ; Print 'S' + sta scr ; to the screen, and end the escape sequence. + lda scr_row ; + pha ; + lda scr_col ; + pha ; + lda #0 ; + sta scr_row ; + jsr rdrw_row ; + pla ; + sta scr_col ; + pla ; + sta scr_row ; + jsr update_pos ; +@end: + rts ; + +rdrw_row: + lda #0 ; + sta scr_col ; + jsr update_pos ; +@loop: + lda (ptr3), y ; + beq @incr ; + sta scr ; +@incr: + inc scr_col ; + lda (ptr3), y ; + beq @skip ; +@incr1: + iny ; +@incr2: + lda scr_col ; + cmp #maxcol+1 ; + bcs @end ; + bra @loop ; +@skip: + lda #' ' ; + sta scr ; to the screen. + bra @incr1 ; +@end: + lda #0 ; + sta scr_col ; + jsr update_pos ; +@end1: + rts ; + +rdrw_ln: + lda scr_row ; + pha ; + lda f ; + sta scr_row ; + lda scr_col ; + pha ; + jsr update_pos ; +@loop: + lda scr_row ; + cmp e ; + beq @loop1 ; + bcs @end ; +@loop1: + jsr rdrw_row ; +@incr: + inc scr_row ; + bra @loop ; +@end: + pla ; + sta scr_col ; + pla ; + sta scr_row ; + jsr update_pos ; + lda #0 ; + sta e ; + sta f ; + rts ; + +set_ptr: + cpb #1 ; Are we setting the second pointer? + beq @ptr2 ; Yes, so start setting it. + cpb #2 ; No, but are we setting the third pointer? + beq @ptr3 ; Yes, so start setting it. +@ptr1: + stb.q ptr ; Reset the first pointer. + sta.q ptr ; No, so set the first pointer. + bra @end ; We are done. +@ptr2: + stb.q ptr2 ; Reset the second pointer. + sta.q ptr2 ; Set the second pointer. + bra @end ; We are done. +@ptr3: + stb.q ptr3 ; Reset the third pointer. + sta.q ptr3 ; Set the third pointer. +@end: + rts ; End of set_ptr. diff --git a/programs/sub-suite/tmp-stuff/test-size.s b/programs/sub-suite/tmp-stuff/test-size.s new file mode 100644 index 0000000..b543a36 --- /dev/null +++ b/programs/sub-suite/tmp-stuff/test-size.s @@ -0,0 +1,59 @@ +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/sux.c b/sux.c index 59c2168..dce4d29 100644 --- a/sux.c +++ b/sux.c @@ -117,7 +117,7 @@ int is_wait_kbd(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint8_t ext_pre if (ext_prefix != 0x1D) { address = get_addr(cpu, opcode, prefix, ext_prefix, 0, 0, thread); } else { - get_ortho_addr(cpu, prefix, cpu->pc, ortho_op, ortho_addr, op_type, op_id, 0, 0, thread); + get_ortho_addr(cpu, opcode, prefix, cpu->pc, ortho_op, ortho_addr, op_type, op_id, 0, 0, thread); } cpu->pc = tmp_pc; return (address == CTRL_ADDR || ortho_addr[0] == CTRL_ADDR || ortho_addr[1] == CTRL_ADDR); diff --git a/sux.h b/sux.h index c028b84..44794f8 100644 --- a/sux.h +++ b/sux.h @@ -119,6 +119,38 @@ static /*inline*/ uint8_t get_ortho_addrsize(uint8_t prefix, uint8_t addrmode) { return get_addrsize(prefix, type); } +static int is_1op(uint8_t opcode) { + switch (opcode) { + case ORTHO_1OP(JMP): + case ORTHO_1OP(JSR): + case ORTHO_1OP(PSH): + case ORTHO_1OP(PEA): + case ORTHO_1OP(PUL): + case ORTHO_1OP(SWP): + case ORTHO_1OP(NOT): + case ORTHO_1OP(NEG): + case ORTHO_1OP(DEC): + case ORTHO_1OP(INC): + case ORTHO_1OP(CLZ): + case ORTHO_1OP(CLO): return 1; + } + return 0; +} + +static int is_1cc(uint8_t opcode) { + switch (opcode) { + case ORTHO_1CC(SET, NG): + case ORTHO_1CC(SET, PO): + case ORTHO_1CC(SET, CS): + case ORTHO_1CC(SET, CC): + case ORTHO_1CC(SET, EQ): + case ORTHO_1CC(SET, NE): + case ORTHO_1CC(SET, VS): + case ORTHO_1CC(SET, VC): return 1; + } + return 0; +} + static /*inline*/ uint8_t isrw(uint8_t opcode, uint8_t ext_prefix) { if ((ext_prefix & 0xD) == 0xD) { switch (ext_prefix >> 4) { @@ -535,9 +567,12 @@ static /*inline*/ uint64_t ortho_ind_idx_addr(struct sux *cpu, uint8_t prefix, u } } -static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t prefix, uint64_t address, operand *op, uint64_t *value, uint8_t *op_type, uint8_t *op_id, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { +static /*inline*/ uint64_t get_ortho_addr(struct sux *cpu, uint8_t opcode, uint8_t prefix, uint64_t address, operand *op, uint64_t *value, uint8_t *op_type, uint8_t *op_id, uint8_t inc_pc, uint8_t inc_clk, uint8_t thread) { uint64_t tmp_addr = address; - for (int i = 0; i < 2; i++) { + + int num_ops = 1 + !(is_1op(opcode) || is_1cc(opcode)); + + for (int i = 0; i < num_ops; i++) { union reg tmp; tmp.u64 = 0; op[i].type = op_type[i]; @@ -963,7 +998,7 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t int is_lea = ((opcode & ~0x18) == LEA_RR); int is_write = 1; operand op[2]; - cpu->pc = get_ortho_addr(cpu, prefix, cpu->pc, op, address, op_type, op_id, 1, 1, thread); + cpu->pc = get_ortho_addr(cpu, opcode, prefix, cpu->pc, op, address, op_type, op_id, 1, 1, thread); for (int i = 0; i < 2; i++) { if (op[i].type) { if (is_lea) { @@ -1077,6 +1112,8 @@ static /*inline*/ void exec_ortho_inst(struct sux *cpu, uint8_t opcode, uint8_t is_write = 0; } while (0); break; + case ORTHO_1OP(JSR): push(cpu, cpu->pc, (size) ? size : 7, thread); /* Falls Through. */ + case ORTHO_1OP(JMP): cpu->pc = (op[0].type) ? address[0] : dst; break; case ORTHO_1OP(INC): dst = inc_dec(cpu, dst, (op[0].type) ? size+1 : 8, 1, thread); break; case ORTHO_1OP(DEC): dst = inc_dec(cpu, dst, (op[0].type) ? size+1 : 8, 0, thread); break; case ORTHO_1OP(PSH): push(cpu, dst, size, thread); is_write = 0; break; diff --git a/test/ortho.s b/test/ortho.s index c7cdd83..6499d6e 100644 --- a/test/ortho.s +++ b/test/ortho.s @@ -32,6 +32,8 @@ reset: lea s, count mov (e), #0 mov a, (e) + lea d, loop + jmp (d) loop: inc b inc.q count -- cgit v1.2.3-13-gbd6f