From cd6982e5da1f5facdc1e0154b3a27c01e8b076c9 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Wed, 27 Jan 2021 13:42:57 -0500 Subject: - Fixed some bugs in the emulator. - Started work on implementing the Super VIA emulation. - Added support for disabling disassembly per instruction, when in debug mode. - Did some more work on rewriting the SuB Suite to work with the new calling convention. - Rewrote the symbol handling code in the emulator's assembler, to make it both simpler, and to add support for arbitrarily deep symbol scopes. - Added support for arbitrarily deep local symbol scopes. For example, to declare a symbol of depth 2, you add two '@' characters to the start of the symbol name. In other words, the number of '@' characters before the symbol name is what determines the scope of that symbol. And to use a symbol thats outside the current scope, you would use the same syntax as using a struct member, so you would do `global.local`. --- programs/sub-suite/declare.s | 4 +- programs/sub-suite/free-new.s | 143 +++++++++ programs/sub-suite/free-old.s | 200 +++++++++++++ programs/sub-suite/lexer.s | 18 +- programs/sub-suite/libc.s | 499 +++++++++++++------------------- programs/sub-suite/shift_line.c | 10 +- programs/sub-suite/subasm-syntax | 56 ++++ programs/sub-suite/subasm.s | 361 +++++++++++++++-------- programs/sub-suite/subeditor.s | 604 +++++++++++++++++---------------------- programs/sub-suite/test-size.s | 59 ++++ programs/sub-suite/utils.s | 312 +++++++++----------- 11 files changed, 1309 insertions(+), 957 deletions(-) create mode 100644 programs/sub-suite/free-new.s create mode 100644 programs/sub-suite/free-old.s create mode 100644 programs/sub-suite/subasm-syntax create mode 100644 programs/sub-suite/test-size.s (limited to 'programs/sub-suite') diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s index 550228d..36a4f15 100644 --- a/programs/sub-suite/declare.s +++ b/programs/sub-suite/declare.s @@ -2,7 +2,7 @@ ; Structs, and unions. ; Line struct. -.struct ln +.struct line next .qword ; Pointer to next line. tok .qword ; The tokens for this line. @@ -852,7 +852,7 @@ cmd_srt: .word list .word asm .word help - .word inst + .word instruction .word run .word set_val diff --git a/programs/sub-suite/free-new.s b/programs/sub-suite/free-new.s new file mode 100644 index 0000000..dad19d0 --- /dev/null +++ b/programs/sub-suite/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/free-old.s b/programs/sub-suite/free-old.s new file mode 100644 index 0000000..7f75edd --- /dev/null +++ b/programs/sub-suite/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/lexer.s b/programs/sub-suite/lexer.s index b2850aa..0d712ff 100644 --- a/programs/sub-suite/lexer.s +++ b/programs/sub-suite/lexer.s @@ -65,7 +65,7 @@ lex: ;@nextlline: ; ldb #1 ; No, so set the second pointer to the last line. ; jsr set_ptr ; -; ldy #ln.next ; Set the next last line to the current line. +; ldy #line.next ; Set the next last line to the current line. ; lda.q cline ; ; sta.q (ptr2), y ; ; bra @initline ; Initialize the line. @@ -76,11 +76,11 @@ lex: ; ldb #1 ; Set the second pointer to the current line. ; jsr set_ptr ; ; and #0 ; Reset A. -; ldy #ln.next ; Reset the next line. +; ldy #line.next ; Reset the next line. ; sta.q (ptr2), y ; -; ldy #ln.tok ; Reset the token. +; ldy #line.tok ; Reset the token. ; sta.q (ptr2), y ; -; ldy #ln.bline ; Reset the number of blank lines. +; ldy #line.bline ; Reset the number of blank lines. ; sta.w (ptr2), y ; ; tay ; Reset Y. @loop: @@ -225,11 +225,10 @@ ptok_dot: beq @found ; Yes, so create a new token. inc idx1 ; No, so increment the directive ID. @getlen: + mov d, a ; Get the string. jsr strlen ; Get the string's length. inc ; Add one to the length. - clc ; Prepare for a non carrying add. - adc.w idx2 ; Add the string offset to the current length - sta.w idx2 ; Save the offset in the third index. + add.w idx2, a ; Add the string offset to the current length bra @dir_loop ; Keep looping. @found: lda #TOK_DIR ; Set the lexeme type to TOK_DIR. @@ -443,11 +442,10 @@ ptok_alph: beq @found ; Yes, so create a new token. inc idx1 ; No, so increment the instruction ID. @offset: + mov d, a ; Get the string. jsr strlen ; Get the string's length. inc ; Add one to the length. - clc ; Prepare for a non carrying add. - adc.w idx2 ; Add the string offset to the current length - sta.w idx2 ; Save the offset in the third index. + add.w idx2, a ; Add the string offset to the current length bra @isop_loop ; Keep looping. @found: lda #TOK_MNE ; Set the lexeme type to TOK_MNE. diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s index ae35146..53e936a 100644 --- a/programs/sub-suite/libc.s +++ b/programs/sub-suite/libc.s @@ -17,12 +17,10 @@ strtoull: pla ; Get the character back. beq @end ; No, so we're done. @alpha: - sec ; Yes, so prepare for a non borrowing subtract. - sbc #'a'-10 ; Get the numeric value from this digit. + sub #'a'-10 ; Yes, so get the numeric value from this digit. bra @chkbase ; Check if the value matches the base. @digit: - sec ; Prepare for a non borrowing subtract. - sbc #'0' ; Get the numeric value from this digit. + sub #'0' ; Get the numeric value from this digit. @chkbase: cmp sp+25 ; Does the value match the base? bcs @end ; No, so we're done. @@ -30,8 +28,7 @@ strtoull: tab ; Save the digit value. lda.q sp+1 ; Get the value from the value buffer. mul sp+25 ; Multiply the value by the base. - clc ; Prepare for a non carrying add. - adc b ; Add the digit value to the total value. + add a, b ; Add the digit value to the total value. sta.q sp+1 ; Place the value in the value buffer. iny ; Increment the string index. and #0 ; Reset A. @@ -44,80 +41,72 @@ strtoull: strlen: - phy.q ; Preserve Y. - pha.q ; Set the temp variable to the argument. and #0 ; Reset A. - tay ; Reset Y. @loop: - lda (sp+1), y ; Are we at the end of the string? - beq @end ; Yes, so we're done. - iny ; No, so increment the index. - bra @loop ; Keep looping. + inc ; Increment the index. + cmp (d+a-1), #0 ; Are we at the end of the string? + bne @loop ; No, so keep looping. @end: - pla.q ; Get the argument back. - tya ; Get the return value. - ply.q ; Get the preserved value back. + dec ; Decrement the length to not include the terminator. rts ; End of strlen. strcmp: - ldb #0 ; Reset B. - tba ; Reset A. + phb.q ; Preserve B. + phx.q ; Preserve X. phy.q ; Preserve Y. + and #0 ; Reset A. + tab ; Reset B. + tax ; Reset X. tay ; Reset Y. @loop: - ldb #0 ; Set the islong flag to false. - lda (sp+25), y ; Are we at the end of the first string? + ldx #0 ; Set the islong flag to false. + mov a, (d+y) ; Are we at the end of the first string? beq cmpr ; Yes, so check if we're too short, or too long. - ldb #1 ; No, so set the islong flag to true. - cmp (sp+19), y ; Is the character of both strings, the same? + ldx #1 ; No, so set the islong flag to true. + cmp a, (s+y) ; Is the character of both strings, the same? bne cmpr ; No, so check if we're too short, or too long. iny ; Yes, so increment the index. bra @loop ; Keep looping. -strccmp: strcasecmp: - ldb #0 ; Reset B. - tba ; Reset A. + phb.q ; Preserve B. + phx.q ; Preserve X. phy.q ; Preserve Y. + and #0 ; Reset A. + tab ; Reset B. + tax ; Reset X. + inx ; Set X to 1. tay ; Reset Y. @loop: - ldb #0 ; Set the islong flag to false. - lda (sp+25), y ; Are we at the end of the first string? + dex ; Set the islong flag to false. + mov a, (d+y) ; Are we at the end of the first string? beq cmpr ; Yes, so check if we're too short, or too long. - ldb #1 ; No, so set the islong flag to true. + inx ; No, so set the islong flag to true. jsr tolower ; Convert the character of string 1 to lowercase. - phb ; Preserve the islong flag. - pha ; Preserve the converted character. - lda (sp+19), y ; Get the character of the second string. + tab ; Save the converted character. + mov a, (s+y) ; Get the character of the second string. jsr tolower ; Convert the character of string 2 to lowercase. - tab ; Place it in B. - pla ; Get the character of string 1 back. cmp b ; Is the character of both strings, the same? - plb ; Get the islong flag back. bne cmpr ; No, so check if we're too short, or too long. iny ; Yes, so increment the index. bra @loop ; Keep looping. cmpr: - lda (sp+17), y ; Are we at the end of the second string? + mov a, (s+y) ; Are we at the end of the second string? beq @islong ; Yes, so check the islong flag. @isshort: - lda (sp+25), y ; No, but are we at the end of the first string? - beq @short ; Yes, so return -1. -@islong: - cpb #1 ; Is the islong flag true? - bne @equ ; No, so return 0. -@long: - lda #1 ; Yes, so return 1. + mov a, (d+y) ; No, but are we at the end of the first string? + bne @islong ; No, so check if the islong flag is true. + lda #$FF ; Yes, so return -1. bra @end ; We are done. -@equ: - lda #0 ; Return 0. - bra @end ; We are done. -@short: - lda #$FF ; Return -1. +@islong: + cpx #1 ; Is the islong flag true? + set a, eq ; Return true if it is. @end: - ply.q ; Get the preserved value back. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. rts ; End of cmpr. @@ -195,304 +184,226 @@ toupper: ; malloc: Dynamically allocate memory. -; Input: A = size in bytes to allocate. +; Input: D = size in bytes to allocate. ; Output: A = Pointer to allocated memory. -; Caller preserved registers: none. -; Callie preserved registers: Y. +; Caller preserved registers: D. +; Callie preserved registers: B, X, Y. malloc: - phy.q ; Preserve Y. - pha.q ; Preserve the size. - and #0 ; Reset A. - tay ; Reset Y. - sbs #$10 ; Allocate 2 local variables onto the stack. - lda.q sp+17 ; Get the size. - ora.d sp+21 ; Is the size zero? - beq @end ; Yes, so we're done. - lda.q sp+17 ; No, so get back the size. - clc ; Prepare for a non carrying add. - adc #ublk ; Add the size of a used block struct, to the size. - sta.q sp+17 ; Set the actual size. - lda.q heapf ; Get the first heap entry. - sta.q sp+9 ; Save it in the second local variable. - bra @checkblk ; Check the block. + phb.q ; Preserve B. + phx.q ; Preserve X. + phy.q ; Preserve Y. + xor b, b ; Reset B. + mov x, b ; Reset X. + txy ; Reset Y. + mov a, d ; Get the size. + beq @end ; The size is zero, so we're done. + add #ublk ; Add the size of a used block struct, to the size. + cmp #ublk ; Is the total size smaller than the size of a used block struct? + bcs @getheapf ; No, so get the first heap entry. +@toosmall: + lda #ublk ; Yes, so set the total size to the size of a used block struct. +@getheapf: + mov d, a ; Place the new size into the passed size. + ldb.q heapf ; Get the first heap entry. + bra @checkblk ; Check the block. @findfblk: - ldy #fblk.size ; Get the size of this free block. - lda.q (sp+9), y ; - sec ; Prepare for a non borrowing subtract. - sbc.q sp+17 ; Subtract the size of this free block, with the passed size. - bcs @blkfound ; The result is less than, or equal to the free size, so return the found block. - ldy #fblk.next ; Get the next free block. - lda.q (sp+9), y ; - sta.q sp+9 ; Set the current free block, to the next free block. + mov.q a, (b+fblk.size) ; Get the size of this free block. + sub a, d ; Subtract the size of this free block, with the passed size. + bcs @blkfound ; The result is less than, or equal to the free size, so return the found block. + mov.q b, (b+fblk.next) ; Set the current free block, to the next free block. @checkblk: - ora.d sp+13 ; Is the address of this block, zero? - bne @findfblk ; No, so keep looping. - lda.q heapptr ; Yes, so get the current top of the heap. - clc ; Prepare for a non carrying add. - adc.q sp+17 ; Add the top of the heap, with the passed size. - bcs @outofspace ; The result overflowed, so return zero. - cmp.q heapend ; Is the top of the heap, less than, or equal to the max heap size? - bcc @inctop ; Yes, so increase the current top of the heap. - beq @inctop ; + bne @findfblk ; The address of this block is non NULL, so keep looping. + mov a, d ; Get the passed size. + add.q heapptr ; Add the top of the heap, with the passed size. +; mov d, a ; Save the new size. + bcs @outofspace ; The result overflowed, so return zero. + cmp.q heapend ; Is the top of the heap, less than, or equal to the max heap size? + bcc @inctop ; Yes, so increase the current top of the heap. + beq @inctop ; @outofspace: - and #0 ; Return zero. - bra @end ; We are done. + and #0 ; Return zero. + bra @end ; We are done. @inctop: - pha.q ; Preserve heapptr + size. - lda.q heapptr ; Get the previous top of the heap. - sta.q sp+17 ; Set the current free block to the previous top of the heap. - pla.q ; Restore heapptr + size. - sta.q heapptr ; Increment the current top of the heap by the passed size. - bra @setsize ; Set the size, and start address into the used space of the block. + + ldb.q heapptr ; Set the current free block to the previous top of the heap. + sta.q heapptr ; Increment the current top of the heap by the passed size. + bra @setsize ; Set the size, and start address into the used space of the block. @blkfound: - bne @sliceblk ; The block is big enough to slice. - cmp #fblk ; Is the block big enough to slice? - bcs @sliceblk ; Yes, so slice the block. - ldy #fblk.prev ; No, so get the previous free block. - lda.q (sp+9), y ; - sta.q sp+1 ; Set the third local variable, to the previous free block. - ora.d sp+5 ; Is the previous block, set to zero? - beq @setheapf ; Yes, so set the first block. - ldy #fblk.next ; No, so get the next free block. - lda.q (sp+9), y ; - sta.q (sp+1), y ; Set the previous block's next block, to the next block. - bra @chknxtblk ; Check the next block. + bne @sliceblk ; The block is big enough to slice. + cmp #fblk ; Is the block big enough to slice? + bcs @sliceblk ; Yes, so slice the block. + mov.q x, (b+fblk.prev) ; Get the previous free block. + beq @setheapf ; The previous block is NULL, so set the first block. + ldy #fblk.next ; No, so set the offset to the next free block. + mov.q (x+y), (b+y) ; Set the previous block's next block, to the next block. + bra @chknxtblk ; Check the next block. @setheapf: - lda.q (sp+9), y ; Get the next block. - sta.q heapf ; Set the first heap entry to it. + ldy #fblk.next ; Set the offset to the next block. + mov.q heapf, (b+y) ; Set the first heap entry to the next block. @chknxtblk: - lda.q (sp+9), y ; Get the next free block. - sta.q sp+1 ; Set the third local variable to the next free block. - ora.d sp+5 ; Is the next block, zero? - beq @setheapl ; Yes, so set the least heap entry. - ldy #fblk.prev ; No, so get the current previous block. - lda.q (sp+9), y ; - sta.q (sp+1), y ; Set the next block's previous block to the current previous block. - bra @retptr ; Return the pointer. + mov.q x, (b+y) ; Get the next free block. + beq @setheapl ; The next block is NULL, so set the least heap entry. + ldy #fblk.prev ; Get the current previous block. + mov.q (x+y), (b+y) ; Set the next block's previous block to the current previous block. + bra @retptr ; Return the pointer. @setheapl: - ldy #fblk.prev ; Get the current previous block. - lda.q (sp+9), y ; - sta.q heapl ; Set the last heap entry to the current previous block. - bra @retptr ; Return the pointer. + ldy #fblk.prev ; Get the current previous block. + mov.q heapl, (b+y) ; Set the last heap entry to the current previous block. + bra @retptr ; Return the pointer. @sliceblk: - ldy #fblk.size ; Get the size of the current block. - lda.q (sp+9), y ; - sec ; Prepare for a non borrowing subtract. - sbc.q sp+17 ; Subtract the current block's size from the passed size. - sta.q (sp+9), y ; Set the current block's size to the subtracted size. - clc ; Prepare for a non carrying add. - adc.q sp+9 ; Add the current block's size to the pointer of the current block. - sta.q sp+9 ; Set the current block to the space above it (return value). + ldy #fblk.size ; Get the size of the current block. + sub.q (b+y), d ; Subtract the current block's size from the passed size. + add.q b, (b+y) ; Add the current block's size to the pointer of the current block. @setsize: - ldy #ublk.size ; Start setting the used block's size, to the passed size. - lda.q sp+17 ; Get the passed size. - sta.q (sp+9), y ; Set the used block's size to the passed size. + mov.q (b+ublk.size), d ; Set the used block's size to the passed size. @retptr: - ldy #ublk.start ; Start setting the used block's starting address, to the used block. - lda.q sp+9 ; Get the used block. - sta.q (sp+9), y ; Set the used block's starting address, to the used block. - clc ; Prepare for a non carrying add. - adc #ublk ; Return the pointer to the real memory block. + mov.q (b+ublk.start), b ; Set the used block's starting address, to the used block. + add b, #ublk ; Get the pointer to the real memory block. + tba ; Return the pointer to the real memory block. @end: - ads #$18 ; Clean up the stack frame. - ply.q ; Restore Y. - rts ; End of malloc. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. + rts ; End of malloc. ; free: Free allocated memory. -; Input: A = Pointer to allocated memory. +; Input: D = Pointer to allocated memory. ; Output: none. -; Caller preserved registers: none. -; Callie preserved registers: A, B, Y. +; Caller preserved registers: D. +; Callie preserved registers: A, B, X, Y, E. 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. + 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: - 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. + 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. + cpe.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. + sta.q heapptr ; Set the top of the heap to the start of the current real block. @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. + ldb.q 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. + cpe.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 ; + stb.q heapptr ; Yes, so remove the last block. @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. + 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: - and #0 ; Reset A. - ldy #fblk.next ; Delete the next block. - sta.q (sp+25), y; + lea e, (a+fblk.next) ; Delete the next block. + stz.q (e) ; @end: - ads #$20 ; Clean up the stack frame. - ply.q ; Restore Y. - plb.q ; Restore B. - pla.q ; Restore A. - rts ; End of free. + 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: - 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. + ldy.q heapf ; Get the first block. + bne @srchflst ; The Free list isn't empty, 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. + 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: - 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. + 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: - 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. + 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: - 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. + 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: - 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. + 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: - 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. + 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: - 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. + 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: - 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. + mov.q (b+fblk.prev), a ; Set the previous block to the current block. + 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. + 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 ; + 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: - lda.q sp+1 ; Get the left pointer. - ora.d sp+5 ; Is the left pointer NULL? - bne @chklmerge2 ; No, so keep checking. + and x, x ; 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. + mov.q (a+fblk.prev), x ; + 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. + 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: - 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. + 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: - 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. + 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: - 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. + mov.q (b+fblk.prev), x ; Set the next left pointer's previous pointer to the left pointer. + 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. + stx.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 ; + mov.q (x+fblk.next), a ; Set the next left pointer, to the current block. @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; + mov.q (a+fblk.prev), x ; Set the previous block, to the left pointer. @end2: - ads #$20 ; Clean up the stack frame. - ply.q ; Restore Y. - plb.q ; Restore B. - pla.q ; Restore A. - rts ; End of free. + ple.q ; Restore E. + ply.q ; Restore Y. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of free. ; memcpy: memory to memory copy. diff --git a/programs/sub-suite/shift_line.c b/programs/sub-suite/shift_line.c index 255d21b..365666b 100644 --- a/programs/sub-suite/shift_line.c +++ b/programs/sub-suite/shift_line.c @@ -24,6 +24,12 @@ uint8_t bitpos(unsigned int row, uint8_t *mask) { } +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); @@ -48,7 +54,7 @@ void shift_line(char *str, int cursor, int left) { if (left) { int i = end-1; int j = end; - for (; i > cursor; i--, j--) { + for (; i >= cursor; i--, j--) { if (i < 0) { i = 0; str[i] = 0; @@ -72,7 +78,7 @@ void shift_line(char *str, int cursor, int left) { str[i] = 0; } end = find_end(str, i); - if ((end % maxcol) == 0 && (end/maxcol) > scr_row) { + if (((end-1) % maxcol) == 0 && ((end-1)/maxcol) > scr_row) { clrbit(end/maxcol); } } diff --git a/programs/sub-suite/subasm-syntax b/programs/sub-suite/subasm-syntax new file mode 100644 index 0000000..1337914 --- /dev/null +++ b/programs/sub-suite/subasm-syntax @@ -0,0 +1,56 @@ +/* Assembly language syntax for SuBAsm. */ + +/* Comments begin with "/*", and end with "*/". + * Directives begin with a `\`. + */ + +/* mnemonic is the instruction name/mnemonic. + * expr is an expression. + * Indirect Indexed means applying the index after the indirection. + * Indexed Indirect means applying the index before the indirection. + */ + +Expression syntax: + /* TODO */ +Instruction syntax: + Base ISA, and Base Extension: + Implied: + + B register: + b + Absolute/Zero Matrix: + /* [, ] means Indexed with x, or y. */ + [, ] + Immediate Data: + # + Absolute/Zero Matrix Indirect: + /* Indexing with x means Indexed Indirect. + * Indexing with y means Indirect Indexed. + */ + ([, x])[, y] + E Indirect: + (e) + Orthogonal Extension: + [, operand] + Operand syntax: + <\( + /* The operand starts with a register. + * If the statment is inside brackets, then + * it's a register indirect mode. + */ + [(]reg[+][\(+|-\)][)] + /* The operand starts with an expression. + * If the statment is inside brackets, then + * it's an indirect mode. + */ + |[(]expr + /* Is the operand using Indirect, or Indirect Indexed? */ + \if (ind || ind_indexed) { + [)] + \} + [\(+|-\)]>] + /* Is the operand using Indexed Indirect? */ + \if (indexed_ind) { + [)] + \} + \)> diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s index 80aaa47..f22ee60 100644 --- a/programs/sub-suite/subasm.s +++ b/programs/sub-suite/subasm.s @@ -3,153 +3,260 @@ ; ; by mr b0nk 500 +;subasm: +; ldb #0 ; Set the first pointer +; lda.q cmd_buf ; to the command buffer. +; jsr set_ptr ; +; tba ; Reset A. +; tax ; Reset X. +; jsr chk_shcmd ; Did we get a shortend command? +; bne @cmd ; Yes, so skip everything else. +; jsr chk_cmd ; No, but did we get a full command? +; bne @cmd ; Yes, so skip everything else. +; jsr lex ; No, so start lexing this line. +; bra @end ; We are done. +;@cmd: +; lda regf ; Get the command ID. +; cmp #8 ; Is the command ID greater than the command count? +; bcs @end ; Yes, so we're done. +; lsl #1 ; No, so multiply the command ID by two. +; phx.q ; Preserve X. +; tax ; Set the index to the offset that we just calculated. +; lea.w (cmd_srt, x); Get the pointer, from the command subroutine table. +; plx.q ; Restore X. +; and #0 ; Reset A. +; tab ; Reset B. +; jsr (e) ; Run the command's subroutine. +;@end: +; and #0 ; Reset A. +; jsr update_ptr ; Get the screen buffer index. +; tay ; Save it in Y. +; and #0 ; Reset A. +; rts ; End of subasm. +; +;chk_shcmd: +; and #0 ; Reset A. +; tab ; Reset B. +;; inb ; Set the second pointer +;; lda.w #sh_cmds ; to the shortend command table. +;; jsr set_ptr ; +;; deb ; Reset B. +;; tba ; Reset A. +; lea sh_cmds ; Get the address of the short command table. +; phy.w ; Preserve the screen buffer position. +; txy ; Set our index to zero. +; lda (ptr), y ; Is there nothing in the command buffer? +; beq @false ; Yes, so return that we failed. +; cmp #' ' ; No, but is this character, a space? +; beq @false ; Yes, so return that we failed. +; jsr tolower ; No, so convert it to lowercase. +;@loop: +;; ldb (ptr2), y ; Are we at the end of the table? +; ldb (e) ; Are we at the end of the table? +; beq @false ; Yes, so return that we failed. +; cmp b ; No, so did the character match? +; beq @found ; Yes, so check if there are any arguments. +; ine ; No, so check the next command. +; iny ; +; bra @loop ; Keep looping. +;@found: +; sty regf ; Save the command ID. +; lea (ptr) ; Get the address of the next character. +; ine ; +;; ldy #1 ; Check the next character in the command buffer. +;; lda (ptr), y ; Is this the end of the buffer? +; lda (e) ; Is this the end of the buffer? +; beq @true ; Yes, so return true. +; cmp #' ' ; No, but is this a space? +; beq @true ; Yes, so return true. +;@false: +; ldb #0 ; Reset B. +; tba ; Return false. +; tax ; Reset X. +; bra @end ; We are done. +;@true: +; lda #1 ; Return true. +;@end: +; ply.w ; Get back the screen buffer position. +; rts ; End of chk_shcmd. +; +; +;chk_cmd: +; and #0 ; Reset A. +; tab ; Reset B. +; tax ; Reset X. +; sta.q idx0 ; Reset the first index. +; sta.q idx1 ; Reset the second index. +; mov.q ptr, d ; Set the first pointer to the command buffer. +;@loop: +; lda.w #cmds ; Get pointer to the start of the command table. +; add.w idx0 ; Offset the pointer, by the length of the previous string. +; pha.q ; Preserve the command string pointer. +; jsr strcaseg ; Is the command buffer, the same as the command string? +; pla.q ; Get the command string pointer back. +; beq @true ; Yes, so return true. +; ldb idx1 ; No, so Get the command ID. +; cpb #7 ; Have we reached the end of the command table? +; beq @false ; Yes, so return false. +; inc idx1 ; No, so increment the command ID. +;@getlen: +; mov d, a ; Get the string. +; jsr strlen ; Get the string's length. +; inc ; Add one to the length. +; add.w idx0, a ; Add the string offset to the current length +; bra @loop ; Keep looping. +;@true: +; ldb idx1 ; Get the command ID. +; stb regf ; Return the command ID. +; ldb #1 ; Return true. +; bra @end ; We are done. +;@false: +; ldb #0 ; Return false. +;@end: +; rts ; End of chk_cmd. + + subasm: - ldb #0 ; Set the first pointer - lda.q cmd_buf ; to the command buffer. - jsr set_ptr ; - tba ; Reset A. - tax ; Reset X. - jsr chk_shcmd ; Did we get a shortend command? - bne @cmd ; Yes, so skip everything else. - jsr chk_cmd ; No, but did we get a full command? - bne @cmd ; Yes, so skip everything else. - jsr lex ; No, so start lexing this line. - bra @end ; We are done. + pha.q ; Preserve A. + phe.q ; Preserve E. + des ; Make room for the command id. + and #0 ; Reset A. + lea d, (cmd_buf) ; Get the command buffer. + lea s, (sp+1) ; Get the pointer to the command id. + jsr chk_shcmd ; Did we get a shortend command? + bne @cmd ; Yes, so skip everything else. + jsr chk_cmd ; No, but did we get a full command? + bne @cmd ; Yes, so skip everything else. + mov.q ptr, d ; + jsr lex ; No, so start lexing this line. + bra @end ; We are done. @cmd: - lda regf ; Get the command ID. - cmp #8 ; Is the command ID greater than the command count? - bcs @end ; Yes, so we're done. - lsl #1 ; No, so multiply the command ID by two. - phx.q ; Preserve X. - tax ; Set the index to the offset that we just calculated. - lea.w (cmd_srt, x); Get the pointer, from the command subroutine table. - plx.q ; Restore X. - and #0 ; Reset A. - tab ; Reset B. - jsr (e) ; Run the command's subroutine. + mov s, (s) ; Get the command ID. + cmp s, #7 ; Is the command ID greater than the command count? + bcs @end ; Yes, so we're done. + lsl s, #1 ; No, so multiply the command ID by two. + lea.w e, (cmd_srt+s) ; Get the pointer, from the command subroutine table. + and #0 ; Reset A. + tab ; Reset B. + jsr (e) ; Run the command's subroutine. @end: - and #0 ; Reset A. - jsr update_ptr ; Get the screen buffer index. - tay ; Save it in Y. - and #0 ; Reset A. - rts ; End of subasm. + and #0 ; Reset A. + jsr update_ptr ; Get the screen buffer index. + tay ; Save it in Y. + ins ; Cleanup the stack frame. + ple.q ; Restore E. + pla.q ; Restore A. + rts ; End of subasm. + chk_shcmd: - and #0 ; Reset A. - tab ; Reset B. -; inb ; Set the second pointer -; lda.w #sh_cmds ; to the shortend command table. -; jsr set_ptr ; -; deb ; Reset B. -; tba ; Reset A. - lea sh_cmds ; Get the address of the short command table. - phy.w ; Preserve the screen buffer position. - txy ; Set our index to zero. - lda (ptr), y ; Is there nothing in the command buffer? - beq @false ; Yes, so return that we failed. - cmp #' ' ; No, but is this character, a space? - beq @false ; Yes, so return that we failed. - jsr tolower ; No, so convert it to lowercase. + phb.q ; Preserve B. + lea b, sh_cmds ; Get the address of the short command table. + mov a, (d) ; Is the string empty? + beq @false ; Yes, so return that we failed. + cmp #' ' ; No, but is this character, a space? + beq @false ; Yes, so return that we failed. + jsr tolower ; No, so convert it to lowercase. @loop: -; ldb (ptr2), y ; Are we at the end of the table? - ldb (e) ; Are we at the end of the table? - beq @false ; Yes, so return that we failed. - cmp b ; No, so did the character match? - beq @found ; Yes, so check if there are any arguments. - ine ; No, so check the next command. - iny ; - bra @loop ; Keep looping. + cmp (b), #0 ; Are we at the end of the table? + beq @false ; Yes, so return that we failed. + cmp a, (b) ; No, so did the character match? + beq @found ; Yes, so check if there are any arguments. + inb ; No, so check the next command. + bra @loop ; Keep looping. @found: - sty regf ; Save the command ID. - lea (ptr) ; Get the address of the next character. - ine ; -; ldy #1 ; Check the next character in the command buffer. -; lda (ptr), y ; Is this the end of the buffer? - lda (e) ; Is this the end of the buffer? - beq @true ; Yes, so return true. - cmp #' ' ; No, but is this a space? - beq @true ; Yes, so return true. + sub.w b, #sh_cmds ; Get the command ID. + mov (s), b ; Save the command ID. + mov a, (d+1) ; Is this the end of the string? + beq @true ; Yes, so return true. + cmp #' ' ; No, but is this a space? + beq @true ; Yes, so return true. @false: - ldb #0 ; Reset B. - tba ; Return false. - tax ; Reset X. - bra @end ; We are done. + and #0 ; Return false. + bra @end ; We are done. @true: - lda #1 ; Return true. + lda #1 ; Return true. @end: - ply.w ; Get back the screen buffer position. - rts ; End of chk_shcmd. + plb.q ; Restore B. + rts ; End of chk_shcmd. chk_cmd: - tba ; Reset A. - tax ; Reset X. - sta.q idx0 ; Reset the first index. - sta.q idx1 ; Reset the second index. + phb.q ; Preserve B. + phx.q ; Preserve X. + phy.q ; Preserve Y. + and #0 ; Reset A. + tab ; Reset B. + mov x, s ; Preserve the command ID pointer. + mov y, d ; Preserve the string pointer. + lea s, cmds ; Get pointer to the start of the command table. @loop: - lda.w #cmds ; Get pointer to the start of the command table. - clc ; Prepare for a non carrying add. - adc.w idx0 ; Offset the pointer, by the length of the previous string. - pha.q ; Preserve the command string pointer. - jsr strcaseg ; Is the command buffer, the same as the command string? - pla.q ; Get the command string pointer back. - beq @true ; Yes, so return true. - ldb idx1 ; No, so Get the command ID. - cpb #7 ; Have we reached the end of the command table? - beq @false ; Yes, so return false. - inc idx1 ; No, so increment the command ID. + jsr strcasecmp ; Is the command buffer, the same as the command string? + beq @true ; Yes, so return true. + inb ; No, so increment the command ID. + cpb #7 ; Have we reached the end of the command table? + bcs @false ; Yes, so return false. @getlen: - jsr strlen ; Get the string's length. - inc ; Add one to the length. - clc ; Prepare for a non carrying add. - adc.w idx0 ; Add the string offset to the current length - sta.w idx0 ; Save the offset in the first index. - bra @loop ; Keep looping. + mov d, s ; Get the command table string. + jsr strlen ; Get the string's length. + mov d, y ; Restore the string pointer. + inc ; Add one to the length. + add s, a ; Add the string offset to the current length + bra @loop ; Keep looping. @true: - ldb idx1 ; Get the command ID. - stb regf ; Return the command ID. - ldb #1 ; Return true. - bra @end ; We are done. + lda #1 ; Return true. + bra @end ; We are done. @false: - ldb #0 ; Return false. + lda #0 ; Return false. @end: - rts ; End of chk_cmd. + mov s, x ; Restore the command ID pointer. + mov (s), b ; Save the command ID. + and a, a ; Set the flags accordingly. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. + rts ; End of chk_cmd. + viewmem: - lda.q prg_cnt ; Get the program counter. - sta.q idx0 ; Save the address in the first index. - and #$F0 ; Clear the first four bits of the address. - sta idx0 ; Overwrite the first byte, with the masked byte. - lda #19 ; Move the cursor to the right, by 19 columns. - sta scr_col ; - jsr update_pos ; - jsr print_lo ; Print the low nibble offsets. - ldx #0 ; Reset X. - ldb #0 ; Reset B. - stb idx1 ; Reset the byte count. + pha.q ; Preserve A. + phb.q ; Preserve B. + phx.q ; Preserve X. + sbs #$50 ; Make room for the string buffer. + and #0 ; Reset A. + tab ; Reset B. + ldx.q prg_cnt ; Get the program counter. + lda #19 ; Move the cursor to the right, by 19 columns. + sta scr_col ; + jsr update_pos ; + jsr print_lo ; Print the low nibble offsets. @loop: - lda #'\n' ; Print a newline. - jsr print_char ; - jsr print_hi ; Place the address in the string buffer. - jsr print_chunk ; Place the next 16 bytes in the string buffer. - lea strbuf ; Print the string buffer. -; jsr print_str ; - jsr print_sfast ; - inc idx1 ; Increment the chunk count. - ldb idx1 ; Get the chunk count. - cpb #$10 ; Did we print 16 chunks? - beq @end ; Yes, so we're done. - lda.q idx0 ; No, so get the address index. - clc ; Prepare for a non carrying add. - adc #$10 ; Add 16 to the address. - sta.q idx0 ; Put it back into the address. - and #0 ; Reset A. - bra @loop ; Keep looping. + lda #'\n' ; Print a newline. + jsr print_char ; + lea d, (sp+1) ; Get the address of the string buffer. + mov s, x ; Get the program counter. + jsr print_hi ; Print the address to the string buffer. + mov d, a ; Get the string buffer pointer after the printed address. + mov s, x ; Get the program counter. + jsr print_chunk ; Print the next 16 bytes to the string buffer. + lea d, (sp+1) ; Get the address of the string buffer. + lea s, (buffer)+y ; Get the address of the screen buffer, at the current cursor position. +; jsr print_str ; Print the string buffer. + jsr print_sfast ; + inb ; Increment the chunk count. + cpb #$10 ; Did we print 16 chunks? + beq @end ; Yes, so we're done. + add x, #$10 ; No, so add 16 to the address. + and #0 ; Reset A. + bra @loop ; Keep looping. @end: - lda #'\n' ; Print a newline. - jsr print_char ; - and #0 ; Reset A. - rts ; End of viewmem. + lda #'\n' ; Print a newline. + jsr print_char ; + ads #$50 ; Cleanup the stack frame. + plx.q ; Restore X. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of viewmem. list: @@ -164,10 +271,10 @@ help: nop ; @end: rts ; End of help. -inst: +instruction: nop ; @end: - rts ; End of inst. + rts ; End of instruction. run: nop ; @end: diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s index 387b5db..f6b647f 100644 --- a/programs/sub-suite/subeditor.s +++ b/programs/sub-suite/subeditor.s @@ -11,8 +11,8 @@ reset: ldy #0 ; Reset Y. tyx ; Reset X. jsr init_heap ; Initialize the heap. - tax ; Set the stack pointer to the end of RAM. - txs ; + mov sp, a ; Set the stack pointer to the end of RAM. +; txs ; sub.d #STKSIZE ; Subtract the stack size, from the end of RAM. sta.q heapend ; Save the end of the heap. and #0 ; Reset A. @@ -28,45 +28,39 @@ reset: init_heap: lea HEAPORG ; Get the heap's starting point. ste.q heapptr ; + mov d, e ; jsr findramend ; Find the end of the heap. rts ; End of init_heap. init_tables: - and #0 ; Reset A. - lda.w #SCRSIZE ; Allocate SCRSIZE bytes of RAM for the screen buffer. + lea d, SCRSIZE ; Allocate SCRSIZE bytes of RAM for the screen buffer. jsr malloc ; sta.q buffer ; - and #0 ; Reset A. - lda.w #CMDSIZE ; Allocate CMDSIZE bytes of RAM for the command buffer. + lea d, CMDSIZE ; Allocate CMDSIZE bytes of RAM for the command buffer. jsr malloc ; sta.q cmd_buf ; - and #0 ; Reset A. - lda.w #LWSIZE ; Allocate LWSIZE bytes of RAM for the linewrap table. + lea d, LWSIZE ; Allocate LWSIZE bytes of RAM for the linewrap table. jsr malloc ; sta.q bitabl ; - and #0 ; Reset A. rts ; End of init_tables. ;test_free: ; inc step ; -; lda.q bitabl ; +; mov.q d, bitabl ; ; jsr free ; -; lda.q buffer ; +; mov.q d, buffer ; ; jsr free ; -; and #0 ; Reset A. -; lda.w #LWSIZE ; Allocate LWSIZE bytes of RAM for the linewrap table. +; lea d, LWSIZE ; Allocate LWSIZE bytes of RAM for the linewrap table. ; jsr malloc ; ; sta.q bitabl ; -; lda.q cmd_buf ; +; mov.q d, cmd_buf; ; jsr free ; -; and #0 ; Reset A. -; lda.w #SCRSIZE ; Allocate SCRSIZE bytes of RAM for the screen buffer. +; lea d, SCRSIZE ; Allocate SCRSIZE bytes of RAM for the screen buffer. ; jsr malloc ; ; sta.q buffer ; -; and #0 ; Reset A. -; lda.w #CMDSIZE ; Allocate CMDSIZE bytes of RAM for the command buffer. +; lea d, CMDSIZE ; Allocate CMDSIZE bytes of RAM for the command buffer. ; jsr malloc ; ; sta.q cmd_buf ; ; and #0 ; Reset A. @@ -74,33 +68,38 @@ init_tables: clr_arr: - stz.q (e) ; Clear eight bytes. - ade #8 ; Increment the pointer by 8. - stz.q (e) ; Clear eight bytes. - ade #8 ; Increment the pointer by 8. - sub #$10 ; Subtract 16 from the size. + pha.q ; Preserve A. + and #0 ; Reset A. +@loop: + mov.q (d), a ; Clear 16 bytes. + mov.q (d+8), a ; + add d, #$10 ; Increment the pointer by 16. + sub s, #$10 ; Subtract 16 from the size. bcc @end ; We've reached the end of the array, so we're done. beq @end ; - bra clr_arr ; Keep looping. + bra @loop ; Keep looping. @end: + pla.q ; Restore A. rts ; End of clr_arr. pnt_strt: - lea ed_name ; Print the name of the editor. + lea d, ed_name ; Print the name of the editor. jsr print_str ; - lea ver_str ; Print the version text. + lea d, ver_str ; Print the version text. jsr print_str ; - lea ed_ver ; Print the version number. + lea d, ed_ver ; Print the version number. jsr print_str ; - lea ed_sver ; Print the sub version number. + lea d, ed_sver ; Print the sub version number. jsr print_str ; + lea d, '\n' ; Print a newline. lda #'\n' ; Print a newline. jsr print_char ; - lea made ; Print the "Created by" text. + lea d, made ; Print the "Created by" text. jsr print_str ; - lea author ; Print the name of the author. + lea d, author ; Print the name of the author. jsr print_str ; + lea d, '\n' ; Print a newline. lda #'\n' ; Print a newline. jsr print_char ; rts ; End of pnt_strt. @@ -109,8 +108,8 @@ pnt_strt: clr_cmd: and #0 ; Reset A. tay ; Reset Y. - lda.w #CMDSIZE ; Set the clear count to CMDSIZE. - lea (cmd_buf) ; Set the array to be cleared to the command buffer. + lea s, CMDSIZE ; Set the clear count to CMDSIZE. + lea d, (cmd_buf); Set the array to be cleared to the command buffer. jsr clr_arr ; Clear the command buffer. rts ; End of clr_cmd. @@ -149,140 +148,68 @@ getchar: print_str: + pha.q ; Preserve A. + phb.q ; Preserve B. and #0 ; Reset A. tba ; Reset B. @loop: - ldb #1 ; Enable replace mode. - stb regb ; - and #0 ; No, reset the accumulator. - ldb (e) ; Are we at the end of the string? + mov regb, #1 ; Enable replace mode. + and #0 ; Reset A. + mov b, (d) ; Are we at the end of the string? beq @end ; Yes, so we're done. jsr update_ptr ; No, so get the screen buffer index. tay ; Save it in Y. tba ; Get the character back. - ine ; Increment the string pointer. + inc d ; Increment the string pointer. jsr print_char ; Print the character. bra @loop ; Keep looping. @end: stz regb ; Enable insert mode. and #0 ; Reset A. tab ; Reset B. + pla.q ; Restore A. + plb.q ; Restore B. rts ; End of print_str. -;print_str: -; ldx #0 ; Reset X. -; sta.q end ; Save the parameter. -;@reset: -; lda.q end ; Get the parameter. -; ldb #0 ; Clear the B register. -; jsr set_ptr ; Set the first pointer to the parameter. -; tba ; Clear the Accumulator. -;@loop: -; ldb #1 ; Enable replace mode. -; stb regb ; -; lda.q ptr ; Get the first pointer. -; cmp.q end ; Did the pointer change? -; bne @reset ; Yes, so set it back. -; and #0 ; No, reset the accumulator. -; txy ; Copy the string index into Y. -; ldb (ptr), y ; Are we at the end of the string? -; beq @end ; Yes, so we're done. -; jsr update_ptr ; No, so get the screen buffer index. -; tay ; Save it in Y. -; tba ; Get the character back. -; inx ; Increment the string index. -; phx ; Preserve the string index. -; jsr print_char ; Print the character. -; plx ; Get the string index back. -; bra @loop ; Keep looping. -;@end: -; stz regb ; Enable insert mode. -; and #0 ; Reset A. -; tab ; Reset B. -; 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: - pha ; Save the parameter. - ldb #1 ; Make sure that set_ptr sets the second pointer. - lda.q bitabl ; Set the second pointer to the linewrap table. - jsr set_ptr ; - lsr #$10 ; Clear the Accumulator. - pla ; Get the return byte back. - jsr bitpos ; Get the bit, and byte position. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (ptr2), y ; Get one byte of the wrap table. - ply.w ; Get the screen index back. - and b ; Mask out the bit of the current line number. - cmp #1 ; Set the carry flag, if true. - bra bitout ; We are done. + des ; Create the stack frame. + add d, s ; Add the row position with the row offset position. + lea s, (sp+1) ; Get the address of the bitmask. + jsr bitpos ; Get the bit, and byte position. + ins ; Cleanup the stack frame. + mov a, (bitabl)+a ; Get the bit of the row position. + and a, (s) ; Return the masked bit. + rts ; End of getbit. + clrbit: - pha ; Save the parameter. - ldb #1 ; Make sure that set_ptr sets the second pointer. - lda.q bitabl ; Set the second pointer to the linewrap table. - jsr set_ptr ; - and #0 ; Clear the Accumulator. - pla ; Get the return byte 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 (ptr2), y ; Get one byte of the wrap table. - and b ; Clear the bit of the current line number. -bitsav: - sta (ptr2), y ; Update the wrap table. - ply.w ; Get the screen index back. -bitout: - ldx bitmask ; Return the bitmask. - rts ; We are done. + pha.q ; Preserve A. + des ; Create the stack frame. + lea s, (sp+1) ; Get the address of the bitmask. + jsr bitpos ; Get the bit, and byte position. + ins ; Cleanup the stack frame. + not (s) ; Invert the bitmask. + and (bitabl)+a, (s) ; Set the bit of the current row number to zero. + pla.q ; Restore A. + rts ; End of clrbit. setbit: - pha ; Save the parameter. - ldb #1 ; Make sure that set_ptr sets the second pointer. - lda.q bitabl ; Set the second pointer to the linewrap table. - jsr set_ptr ; - and #0 ; Clear the Accumulator. - pla ; Get the return byte back. - jsr bitpos ; Get the bit, and byte position. - phy.w ; Save the screen index. - txy ; Get the byte position. - ldb (ptr2), y ; Get one byte of the wrap table. - ora b ; Set the bit of the current line number. - bra bitsav ; Save the bit. + pha.q ; Preserve A. + des ; Create the stack frame. + lea s, (sp+1) ; Get the address of the bitmask. + jsr bitpos ; Get the bit, and byte position. + ins ; Cleanup the stack frame. + or (bitabl)+a, (s) ; Set the bit of the current row number to one. + pla.q ; Restore A. + rts ; End of setbit. bitpos: - pha ; Save the parameter. - ldb #0 ; Make sure that set_ptr sets the first pointer. - lda.w #bits ; Set the first pointer to the bitmask table. - jsr set_ptr ; - and #0 ; Clear the Accumulator. - pla ; 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 (ptr), 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. - rts ; End of bitpos. + mov a, d ; Preserve the row number. + and d, #7 ; Get the bit position. + lsr #3 ; Return the byte position. + mov (s), (d+bits) ; Place the bitmask into the mask argument. + rts ; End of bitpos. handle_char: @@ -328,7 +255,10 @@ handle_char: cmd_cpy: lda scr_row ; Get the row position. sta scr_trow ; Save it for later. - jsr findend ; Find the end of the line. + lea d, (buffer) ; Get the screen buffer. + mov s, y ; Get the cursor index. + jsr find_end ; Find the end of the line. + div #maxcol+1 ; Get the ending line. ldb scr_str ; Has the screen been scrolled? beq @start ; No, so don't subtract the screen's starting point from the line number. @offset: @@ -388,48 +318,45 @@ cmd_cpy: findst: - lda #0 ; Reset A. +; lda #0 ; Reset A. +; xor d, d ; Reset D. +; xor s, s ; Reset S. + mov d, scr_row ; Get the row position. + mov s, scr_str ; Get the row offset. @loop: - pha ; Save the current line number. +; 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. +; pla ; Get the current line number back. + beq @end ; Yes, so we're done. + inc d ; 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. + dec d ; Yes, so move back one line. inc scr_row ; Put the row postiion back to zero. @end: - cmp #0 ; Update all the flags. + cmp d, #0 ; Update all the flags. rts ; End of findst. -fndend: - phb ; Save the contents of the B register. - ldb #0 ; Make sure that set_ptr sets the first pointer. - lda.q buffer ; Set the first pointer to the start of the screen buffer. - jsr set_ptr ; - tba ; Set the Accumulator to zero. - plb ; Restore the contents of the B register. - phy.w ; +find_end: + mov a, s ; Set the loop counter. @loop: - lda (ptr), 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. + inc ; Increment the loop counter. + cmp (d+a-1), #0 ; Did we hit the null terminator? + bne @loop ; No, so keep looping. @end: - sty.w scr_ptr3 ; - ply.w ; - rts ; End of fndend. - -findend: - jsr fndend ; - lda.w scr_ptr3 ; - div #maxcol+1 ; - rts ; + rts ; End of find_end. + + +get_endrow: + jsr find_end ; Find the end of the line. + div #maxcol+1 ; Get the ending row. + rts ; End of get_endrow print_char: + phb.q ; Preserve B. + phx.q ; Preserve X. phe.q ; Preserve E. sta rega ; Preserve the character. ldb #2 ; Make sure that set_ptr sets the third pointer. @@ -441,15 +368,13 @@ print_char: lda rega ; Get the character back. jsr get_ctrlidx ; Get the control code jump table index. lsl #1 ; Multiply the return value by two, to get the index. - tax ; - lea.w (ct_jtb, x); Get the address of the control code handler. -; pha.q ; -; ple.q ; -; jsr set_ptr ; Set the second pointer to the control code handler. + lea.w e, (ct_jtb+a); Get the address of the control code handler. deb ; Reset B. tba ; Reset A. jsr (e) ; Jump to the handler for that control code. ple.q ; Restore E. + plx.q ; Restore X. + plb.q ; Restore B. rts printc: lda #0 ; start trying to print a character. @@ -458,18 +383,20 @@ printc: beq @save ; Yes, so just print the character. lda regb ; 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. +; 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 rege ; Use it for redrawing the line. + lea d, (buffer) ; Get the screen buffer. + mov s, y ; Get the cursor index. + jsr get_endrow ; Get the ending line. + mov d, a ; + mov s, scr_trow ; Get the current row position. lda scr_trow ; Get the current row position. @update2: - sta regf ; Set the starting line, to the current row position. jsr rdrw_ln ; Redraw the line. lda scr_trow ; Get the real row position back. sta scr_row ; @@ -479,12 +406,15 @@ printc: dec regd ; bra @save1 ; @shift: - ldy.w scr_ptr3 ; - inc scr_ptr3 ; - tyx ; - dey ; - ldb #1 ; - stb regd ; +; ldy.w scr_ptr3 ; +; inc scr_ptr3 ; +; tyx ; +; dey ; +; ldb #1 ; +; stb regd ; + lea d, (buffer) ; Get the screen buffer. + mov.w s, scr_ptr; Get the cursor index. + mov f, #1 ; Set the left flag to true. jsr shftln ; ldb #1 ; stb regd ; @@ -501,6 +431,7 @@ printc: sta (ptr3), y ; store typed character into the input buffer. @incr: inc scr_col ; Increment the cursor's x coordinate. + inc.w scr_ptr ; Increment the screen index. iny ; @wrapped: ldb #1 ; @@ -536,13 +467,15 @@ printc: @wrap1: inc scr_row ; @wrap2: - phx.w ; - clc ; - lda scr_row ; - adc scr_str ; - tax ; - jsr setbit ; - plx.w ; +; phx.w ; +; clc ; +; lda scr_row ; +; adc scr_str ; +; tax ; + mov d, scr_row ; Get the row position. + add d, scr_str ; Add the row offset to the row position. + jsr setbit ; Set the bit of that row. +; plx.w ; jsr update_pos ; printc_end: rts ; @@ -573,11 +506,11 @@ clr_scr: sta scr_end ; stz scr_str ; tay ; - lda.w #LWSIZE ; Set the clear count to LWSIZE. - lea (bitabl) ; Set the array to be cleared to the linewrap table. + lea s, LWSIZE ; Set the clear count to LWSIZE. + lea d, (bitabl) ; Set the array to be cleared to the linewrap table. jsr clr_arr ; Clear the linewrap table. - lda.w #SCRSIZE ; Set the clear count to SCRSIZE. - lea (buffer) ; Set the array to be cleared to the screen buffer. + lea s, SCRSIZE ; Set the clear count to SCRSIZE. + lea d, (buffer) ; Set the array to be cleared to the screen buffer. jsr clr_arr ; Clear the screen buffer. ; lda.w #CMDSIZE ; Set the clear count to CMDSIZE. ; lea (cmd_buf) ; Set the array to be cleared to the command buffer. @@ -613,8 +546,10 @@ bs: beq @wrap ; Yes, so check for a wrapped line. bra back ; No, so add the backspace to the buffer. @wrap: + mov d, scr_row ; Get the row position. + mov s, scr_str ; Get the row offset. jsr getbit ; Is this line, a wrapped line? - bcs @wrap1 ; Yes, so check if the cursor is at the top. + bne @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? @@ -644,7 +579,9 @@ back: stb regf ; lda scr_row ; Save the current row position for later. sta scr_trow ; - jsr findend ; Find the end of the line. + lea d, (buffer) ; Get the screen buffer. + mov s, y ; Get the cursor index. + jsr get_endrow ; Get the ending 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? @@ -660,14 +597,20 @@ back: iny ; Increment cursor index. ldb #0 ; Set shifting direction to left. stb regd ; + lea d, (buffer) ; Get the screen buffer. + mov s, y ; Get the cursor index. + mov f, #0 ; Set the left flag to false. jsr shftln ; Shift line back by one character. lda #$7F ; Print a backspace to the screen. sta scr ; lda rege ; 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 rege ; Set the end parameter to it. + lea d, (buffer) ; Get the screen buffer. + mov s, y ; Get the cursor index. + jsr get_endrow ; Yes, so Get the ending line. + mov d, a ; + mov s, scr_trow ; Get the current row position. lda scr_col ; Save the current column position for now. sta scr_tcol ; jsr rdrw_ln ; Start redrawing the line. @@ -683,88 +626,73 @@ back: lda (ptr3), y ; Are we at the end of the line? beq @shift ; Yes, so skip redrawing. lda scr_trow ; No, so set the line to start redrawing, to the line that the cursor is on. - sta regf ; inc rege ; Set the redraw flag to true. bra @shift ; Start shifting the line back. shftln: - ldb regd ; 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. + pha.q ; Preserve A. + phb.q ; Preserve B. + and f, f ; Is the left flag not set? + beq @right ; Yes, so shift the line to the right. +; txa ; Get the end of the line. + jsr find_end ; Find the end of the line. + dec ; Decrement the source position. + bra @left ; No, so shift the line to the left. @minus: - 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 @minus ; 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. + and #0 ; Set the source poition to 0. + mov (d), a ; Clear the character that is in the source. + bra @lend ; We are done. +@left: + cmp s, a ; Is the cursor index, at, or below the source position? + beq @left1 ; Yes, so keep looping. + bcs @lend ; No, so we're done. +@left1: + cmp #0 ; Is the source position less than 0? + bcc @minus ; Yes, so set the source position to zero. + mov (d+a+1), (d+a) ; No, so shift the current character to the left by one. + mov (d+a), #0 ; Clear the current character. + dec ; Decrement the source position. + bra @left ; Keep looping. +@right: + cmp (d+s), #0 ; Is this character a null terminator? + beq @rend ; Yes, so we're done. + mov (d+s-1), (d+s) ; No, so shift the current character to the right by one. + mov (d+s), #0 ; Clear the current character. + inc s ; Increment the source position. + bra @right ; Keep looping. @wrap: - 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. + mov d, a ; Get the ending line. + jsr setbit ; Set the wrap bit of the ending line. + bra @end ; 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. + mov d, a ; Get the ending line. + jsr clrbit ; Clear the wrap bit of the ending line. + bra @end ; We are done. +@lend: + lea s, (a+2) ; Add 2 to the source position. + jsr find_end ; Find the end of the line. + dec ; Decrement the end of line position. + div #maxcol+1 ; Get the ending line. +@lend2: + cmp scr_row ; Is the ending line greater than the starting line? + beq @end ; No, so we're done. + bcs @wrap ; Yes, so set the wrap bit. + bra @end ; No, so we're done. +@rend: + jsr find_end ; Find the end of the line. + dec ; Decrement the end of line position. + div #maxcol+1 ; Get the ending line. + cpb #0 ; Is the remainder zero? + bne @end ; No, so we're done. +@rend2: + cmp scr_row ; Is the ending line greater than the starting line? + beq @end ; No, so we're done. + bcs @wrap1 ; Yes, so clear the wrap bit. @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 regd ; 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 regd ; 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. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of shftln. esc: @@ -883,8 +811,10 @@ isright: bra @right ; No, so move the cursor right, like normal. @wrap: inc scr_row ; Move down a row. + mov d, scr_row ; Get the row position. + mov s, scr_str ; Get the row offset. jsr getbit ; Is the current line, a wrapped line? - bcs @incr ; Yes, so leave the cursor where it is. + bne @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: @@ -927,8 +857,10 @@ isleft: beq @left ; Yes, so move the cursor left. bra @end1 ; No, so we're done. @wrap: + mov d, scr_row ; Get the row position. + mov s, scr_str ; Get the row offset. jsr getbit ; Is the current line, a wrapped line? - bcs @decr ; Yes, so wrap back up a line. + bne @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? @@ -999,12 +931,11 @@ isshftdown: update_ptr: - 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. + add scr_str ; with the starting line number to get the absolute line number. 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. + add scr_col ; Add the cursor's column number to get the screen index. + sta.w scr_ptr ; Save the screen index. ; cmp.w #$2000 ; Is the index greater than, or equal to the end of the screen buffer? ; bcc @end ; No, so we're done. ;@wrap: @@ -1021,22 +952,21 @@ update_ptr: update_pos: + phb.q ; Preserve B. + and #0 ; Reset A. + tab ; Reset B. ldb #1 ; Set the F pseudo register to one, to fix some bugs. stb regf ; jsr update_ptr ; Update the screen buffer 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. + mov scr, #$1B ; Print an escape character to the screen. + mov scr, #'[' ; Print '[' to the screen, and start the escape sequence. jsr getrow ; Start printing the row number to the screen. - lda #';' ; Print ';' - sta scr ; to the screen. + mov scr, #';' ; Print ';' to the screen. jsr getcol ; Start printing the column number to the screen. - lda #'H' ; Print 'H' - sta scr ; to the screen. - ;inc step ; + mov scr, #'H' ; Print 'H' to the screen. + plb.q ; Restore B. rts ; End of update_pos. getrow: @@ -1068,6 +998,7 @@ scrl_down: lda wrapped ; Was the wrapped flag set? beq @save ; Yes, so save the cursor position. @redraw: + lea d, (buffer) ; Get the screen buffer. 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. @@ -1103,6 +1034,7 @@ scrl_up: pha ; lda #0 ; sta scr_row ; + lea d, (buffer) ; Get the screen buffer. jsr rdrw_row ; pla ; sta scr_col ; @@ -1112,64 +1044,54 @@ scrl_up: @end: rts ; + rdrw_row: - lda #0 ; - sta scr_col ; - jsr update_pos ; + pha.q ; Preserve A. + phb.q ; Preserve B. + stz scr_col ; Reset the column position. + jsr update_pos ; Update the cursor position. + xor b, b ; Reset B. + tya ; Get the screen index. + tab ; + add b, #maxcol+1; Get the end of the row plus one. @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 ; + cmp (d+a), #0 ; Is this a null terminator? + mne scr, (d+a) ; No, so print the character. + meq scr, #' ' ; Yes, so print a space. + inc ; Increment the screen index. + cmp b ; Is the column position at, or above the maximum column count? + bcc @loop ; No, so keep looping. @end: - lda #0 ; - sta scr_col ; - jsr update_pos ; -@end1: - rts ; + stz scr_col ; Reset the column position. + jsr update_pos ; Update the cursor position. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of rdrw_row. + rdrw_ln: - lda scr_row ; - pha ; - lda regf ; - sta scr_row ; - lda scr_col ; - pha ; - jsr update_pos ; + pha.q ; Preserve A. + psh scr_row ; Preserve the row position. + psh scr_col ; Preserve the column position. + mov scr_row, s ; Set the row position to the starting position. + jsr update_pos ; Update the cursor position. + mov a, d ; Get the ending position. + lea d, (buffer) ; Get the address of the screen buffer. @loop: - lda scr_row ; - cmp rege ; - beq @loop1 ; - bcs @end ; -@loop1: - jsr rdrw_row ; + cmp scr_row, a ; Is the row position at, or below the ending position? + beq @redraw ; Yes, so redraw the row. + bcs @end ; No, so we're done. +@redraw: + jsr rdrw_row ; Redraw the line. @incr: - inc scr_row ; - bra @loop ; + inc scr_row ; Increment the row position. + bra @loop ; Keep looping @end: - pla ; - sta scr_col ; - pla ; - sta scr_row ; - jsr update_pos ; - lda #0 ; - sta rege ; - sta regf ; - rts ; + pul scr_col ; Restore the column position. + pul scr_row ; Restore the row position. + jsr update_pos ; Update the cursor position. + pla.q ; Restore A. + rts ; End of rdrw_ln. set_ptr: diff --git a/programs/sub-suite/test-size.s b/programs/sub-suite/test-size.s new file mode 100644 index 0000000..b543a36 --- /dev/null +++ b/programs/sub-suite/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/programs/sub-suite/utils.s b/programs/sub-suite/utils.s index 3813a05..6479099 100644 --- a/programs/sub-suite/utils.s +++ b/programs/sub-suite/utils.s @@ -1,141 +1,125 @@ ; Utility subroutines for SuBAsm. print_hi: - and #0 ; Reset A. - sta idx3 ; Clear the string index. - tax ; Reset X. - lda #'$' ; Print the hex delimiter. - sta strbuf, x ; Save it in the string buffer. - lda.q idx0 ; Get the masked address. - ldx #$10 ; Set digit count to 16. - jsr print_hex ; Print the address. - lda.q hex_str ; Get the lower half of the string. - sta.q strbuf+1 ; Save it in the string buffer. - lda.q hex_str+8 ; Get the upper half of the string. - sta.q strbuf+9 ; Save it in the string buffer. - ldx #$11 ; Add 16 to the index. - stx idx3 ; - lda.w #': ' ; Print a space. - sta.w strbuf, x ; Save it in the string buffer. - inc idx3 ; Increment the string index twice. - inc idx3 ; - and #0 ; Reset A. - rts ; End of print_hi. + phb.q ; Preserve B. + sbs #$10 ; Make room for the hex string buffer. + and #0 ; Reset A. + mov b, d ; Get the string buffer pointer. + mov (b), #'$' ; Print the hex delimiter to the string buffer. + inb ; Increment the string buffer pointer. + lea d, (sp+1) ; Get the address of the hex string buffer. + mov f, #$10 ; Set digit count to 16. + jsr print_hex ; Print the address. + mov.q (b), (a) ; Print the lower half of the hex string to the string buffer. + mov.q (b+8), (a+8) ; Print the upper half of the hex string to the string buffer. + add b, #$10 ; Add 16 to the index. + mov.w (b), #': ' ; Print a colon, and space to the string buffer. + add b, #2 ; Add two to the string buffer pointer. + tba a ; Return the string buffer pointer after the printed string. + ads #$10 ; Cleanup the stack frame. + plb.q ; Restore B. + rts ; End of print_hi. print_lo: - and #0 ; Reset A. - sta idx3 ; Clear the string index. + pha.q ; Preserve A. + phb.q ; Preserve B. + phx.q ; Preserve X. + sbs #$33 ; Make room for the hex string buffer, and the normal string buffer. + and #0 ; Reset A. + tab ; Reset B. + lea d, (sp+1) ; Get the address of the hex string buffer. + lea x, (sp+3) ; Get the address of the string buffer. @loop: - ldx #2 ; Set digit count to 2. - pha ; Preserve the nibble offset. - jsr print_hex ; Print the low nibble offset. - lda.w (ptr3) ; Get the two digits. - ldx idx3 ; Get the string index. - sta.w strbuf, x ; Save it in the string buffer. - inc idx3 ; Increment the string index twice. - inc idx3 ; - ldx idx3 ; Get the string index. - pla ; Get the nibble offset back. - inc ; Increment the offset. - cmp #$10 ; Are we at the last offset? - bcs @end ; Yes, so we're done. + lea f, 2 ; Set the digit count to two. + mov s, b ; Get the low nibble offset. + jsr print_hex ; Print the low nibble offset. + mov.w (x), (a) ; Place the hex digits in the string buffer. + add x, #2 ; Add two to the string buffer pointer. + inb ; Increment the nibble offset. + cpb #$10 ; Are we at the last offset? + bcs @end ; Yes, so we're done. @loop1: - pha ; No, so preserve the nibble offset. - lda #' ' ; Add a space to the string buffer. - sta strbuf, x ; Save it in the string buffer. - inc idx3 ; Increment the string index. - pla ; Get the nibble offset back. - bra @loop ; Keep looping. + mov (x), #' ' ; No, so add a space to the string buffer. + inx ; Increment the string buffer pointer. + bra @loop ; Keep looping. @end: - and #0 ; Reset A. - sta strbuf, x ; Null terminate the string buffer. - tax ; Reset X. - lea strbuf ; Print the string buffer. -; jsr print_str ; - jsr print_sfast ; Use the faster, but less robust print string routine. - rts ; End of print_lo. -;@end: -; lda #0 ; Null terminate the string buffer. -; sta strbuf, x ; -; tax ; Reset X. -; lea strbuf ; Print the string buffer. -; jsr print_str ; -; rts ; End of print_lo. + mov (x), #0 ; Null terminate the string buffer. + lea d, (sp+3) ; Get the address of the string buffer. + lea s, (buffer)+y ; Get the address of the screen buffer, at the current cursor position. +; jsr print_str ; Print the string buffer. + jsr print_sfast ; Use the faster, but less robust print string routine. + ads #$33 ; Cleanup the stack frame. + plx.q ; Restore X. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of print_lo. print_chunk: - ldx #0 ; Reset X. - phy.w ; Preserve the screen buffer index. - txy ; Copy the byte index to it. + pha.q ; Preserve A. + phb.q ; Preserve B. + phx.q ; Preserve X. + phy.q ; Preserve Y. + sbs #2 ; Make room for the hex string buffer. + and #0 ; Reset A. + tab ; Reset B. + mov x, d ; Get the address of the string buffer. + mov y, s ; Get the starting address. + lea d, (sp+1) ; Get the address of the hex string buffer. + xor s, s ; Reset S. @loop: - and #0 ; Reset A. - ldx #2 ; Set the digit count to 2. - lda (idx0), y ; Get the byte at that address. - jsr print_hex ; Print the byte. - lda.w (ptr3) ; Get the two digits. - ldx idx3 ; Get the string index. - sta.w strbuf, x ; Save it in the string buffer. - inc idx3 ; Increment the string index twice. - inc idx3 ; - ldx idx3 ; Get the string index. - iny ; Increment the byte index. - cpy #$10 ; Have we read 16 bytes? - beq @end ; Yes, so we're done. - lda #' ' ; No, so add a soace to the string buffer. - sta strbuf, x ; Save it in the string buffer. - inc idx3 ; Increment the string index. - bra @loop ; Keep looping. + lea f, 2 ; Set the digit count to two. + mov s, (y+b) ; Get the byte at that address. + jsr print_hex ; Print the byte. + mov.w (x), (a) ; Print the hex string to the string buffer. + add x, #2 ; Add two to the string buffer pointer. + inb ; Increment the byte index. + cpb #$10 ; Have we read 16 bytes? + beq @end ; Yes, so we're done. + mov (x), #' ' ; No, so print a space to the string buffer. + inx ; Increment the string buffer pointer. + bra @loop ; Keep looping. @end: - ply.w ; Get the screen buffer index back. - inx ; Increment the index by one. - and #0 ; Null terminate the string. - sta strbuf, x ; - tax ; Reset X. - sta idx3 ; Clear the string index. - rts ; End of print_chunk. + mov (x), #0 ; Null terminate the string. + ads #2 ; Cleanup the stack frame. + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. + pla.q ; Restore A. + rts ; End of print_chunk. print_hex: - pha.q ; Preserve the hex value. - and #0 ; Reset A. - ldb #1 ; Set the second pointer - lda.w #hex_char ; to the start of hex character table. - jsr set_ptr ; - inb ; Set the third pointer - lda.d #hex_str ; to the end of hex string buffer. - clc ; Do a non carrying add. - adc #$10 ; - jsr set_ptr ; - ldb #0 ; Reset B. - pla.q ; Get the hex value back. + phb.q ; Preserve B. + phx.q ; Preserve X. + phy.q ; Preserve Y. + lea b, hex_char ; Get the address of the hex character table. + and f, f ; Is the digit count zero? + set x, eq ; Set the auto digit count flag if so. + mne f, #$10 ; Also set the digit count to 16 if the digit count is zero. + mov a, f ; Get the digit count. + add a, d ; Add the string pointer with the digit count. @loop: - pha.q ; Preserve the hex value. - and #$F ; Mask the lowest nibble. - phy.w ; Preserve the screen buffer position. - tay ; Get the index for the hex digit. - lda (ptr2), y ; Get the hex digit. - dec ptr3 ; Decrement the string pointer. - sta (ptr3) ; Save the hex digit character in the string. - ply.w ; Get back the screen buffer position. - pla.q ; Get the hex value back. + mov y, s ; No, so mask the low nibble of the value. + and y, #$F ; + dec ; Decrement the string pointer. + mov (a), (b+y) ; Place the hex digit character in the string. + lsr s, #4 ; Is the next nibble zero? + bne @loop1 ; No, so decrement the digit count. @isauto: - cpx #1 ; Is the digit count less than one? - bcc @auto ; Yes, so don't decrement the digit count. - dex ; No, but was the digit count zero, when decremented? - beq @end ; Yes, so we're done. - bra @next ; No, so get the next nibble. -@auto: - ldb #1 ; Enable auto digit count. -@next: - lsr #4 ; Is the next nibble, a zero? - beq @isauto1 ; Yes, so check if auto digit count is enabled. - bra @loop ; No, so print the next digit. -@isauto1: - cpb #1 ; Is auto digit count enabled? - beq @end ; Yes, so we're done. - bra @loop ; No, so keep printing more digits. + and x, x ; Is the auto digit count flag set? + bne @end ; Yes, so we're done. +@loop1: + cpx #1 ; Is the auto digit count flag set? + sbc f, #0 ; Decrement the digit count if not. + mov y, f ; Get the digit count. + or y, x ; Are both the digit count, and the auto digit count flag zero? + bne @loop ; No, so keep looping. @end: + ply.q ; Restore Y. + plx.q ; Restore X. + plb.q ; Restore B. rts ; End of print_hex. @@ -147,26 +131,18 @@ charcpy: strcmpg: - ldb.w #strcmp ; Get the address of strcmp. - phb.q ; Use it for an indirect call. - ldb.q ptr ; Get the first pointer. + lea strcmp ; Get the address of strcmp. + mov.q d, ptr ; Get the first pointer. bra gargs ; Jump to the argument handler. strcaseg: - ldb.w #strccmp ; Get the address of strcasecmp. - phb.q ; Use it for an indirect call. - ldb.q ptr ; Get the first pointer. + lea strcasecmp ; Get the address of strcasecmp. + mov.q d, ptr ; Get the first pointer. bra gargs ; Jump to the argument handler. gargs: - phb.q ; Use the pointer in B as the first arg. - pha.q ; Use the value in A as the second arg. - and #0 ; reset a. - tab ; reset b. - jsr (sp+17) ; call the pushed routine. - tab ; Preserve the return value. - pla.q ; Get the second arg back. - pla.q ; Get the first arg back. - pla.q ; Get the pushed routine back. - tba ; Get the return value back. + mov s, a ; Use the value in A as the second arg. + and #0 ; Reset a. + tab ; Reset b. + jsr (e) ; Call the pushed routine. rts ; End of gargs. @@ -310,11 +286,6 @@ get_ptok: get_ctrlidx: -; phe.q ; Preserve E. -; cmp #$7F ; Is this a delete character? -; beq @del ; Yes, so return the same value as backspace. -; sec ; Do a non borrowing subtract. -; sbc #8 ; Subtract 8 from the character, to get the index. sub #8 ; Subtract 8 from the character, to get the index. tax ; Copy the index to X. and #0 ; Reset A. @@ -324,62 +295,41 @@ get_ctrlidx: leq (e) ; cmp #$7F ; Is this a delete character? leq #2 ; Return 2 if this is the delete character. -; bcc @get_rtval ; Yes, so get the return value from the table. -; beq @get_rtval ; -; ple.q ; Restore E. rts ; End of get_ctrlidx. -;@get_rtval: -; lda ct_rtb, x ; Get the return value from the table. -; rts ; End of get_ctrlidx. -;@del: -; lda #2 ; Return 2. -; rts ; End of get_ctrlidx. findramend: - phx.q ; Preserve X. and #0 ; Reset A. - lda #MAGIC ; Set A to a magic number. @loop: - ldx (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? + 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. - stx (e) ; Yes, so restore the previous value. - ade.w #$4000 ; Increment the end of RAM pointer by 16K. + 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: - dee ; Decrement the end of RAM pointer. - ldx (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? + 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. - stx (e) ; Yes, so restore the previous value. + mov (d), a ; Yes, so restore the previous value. @end: - phe.q ; Return the end of RAM pointer. - pla.q ; - plx.q ; Restore X. + mov a, d ; Return the end of RAM pointer. rts ; End of findramend. print_sfast: -; inc step ; - pea (buffer), y ; Push the address of the cursor's postion in the screen buffer to the stack. + pha.q ; Preserve A. + and #0 ; Reset A. @loop: - lda (e) ; Get the character. - beq @end ; We've hit the end of the string, so we're done. - cmp #'\n' ; Did we get a newline? - beq @nl ; Yes, so move the cursor to the next line. - sta (sp+1) ; Print the character to the screen buffer. - sta scr ; Print the character to the screen. - inc scr_col ; Move the cursor left by one character. - ine ; Increment the string pointer. - inc.q sp+1 ; Increment the screen buffer pointer. - bra @loop ; Keep looping. -@nl: - stz scr_col ; Move the cursor to the start of the line. - inc scr_row ; Move the cursor down by one line. - bra @loop ; Keep looping. + inc ; Increment the index. + cmp (d+a-1), #0 ; Did we hit the end of the string? + beq @end ; Yes, so we're done. + mov (s+a-1), (d+a-1) ; No, so print the character to the buffer. + mov scr, (d+a-1) ; Print the character to the screen. + bra @loop ; Keep looping. @end: - ads #8 ; Cleanup the stack frame. - rts ; End of print_sfast. + pla.q ; Restore A. + rts ; End of print_sfast. -- cgit v1.2.3-13-gbd6f