summaryrefslogtreecommitdiff
path: root/programs/sub-suite/tmp-stuff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2021-02-13 13:59:48 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2021-02-13 13:59:48 -0500
commit8d7f27d9a0b61d3694a62f3e54be885d8073f02b (patch)
treeb505454c79dba2e691ee19f716ccfd0d0aba1430 /programs/sub-suite/tmp-stuff
parentac778a4d39ba6c80651ce20ce780dfe859c3dcff (diff)
- Reverted back one commit before the previous commit.
This is because the previous commit actually created a bug, rather than fixing one. - Added JMP, and JSR to the ortho extension, and implemented them both in the assembler, and emulator.
Diffstat (limited to 'programs/sub-suite/tmp-stuff')
-rw-r--r--programs/sub-suite/tmp-stuff/cmd_cpy.c33
-rw-r--r--programs/sub-suite/tmp-stuff/free-new.s143
-rw-r--r--programs/sub-suite/tmp-stuff/free-old.s200
-rw-r--r--programs/sub-suite/tmp-stuff/print_char.s147
-rw-r--r--programs/sub-suite/tmp-stuff/shift_line.c85
-rw-r--r--programs/sub-suite/tmp-stuff/subeditor-new.s1119
-rw-r--r--programs/sub-suite/tmp-stuff/test-size.s59
7 files changed, 1786 insertions, 0 deletions
diff --git a/programs/sub-suite/tmp-stuff/cmd_cpy.c b/programs/sub-suite/tmp-stuff/cmd_cpy.c
new file mode 100644
index 0000000..6b89e7d
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/cmd_cpy.c
@@ -0,0 +1,33 @@
+#include <stdint.h>
+
+int cmd_size = 0x400;
+int maxcol = 80;
+
+extern uint8_t scr_row;
+extern uint8_t scr_col;
+extern uint8_t scr_str;
+
+int find_end(char *str, int pos) {
+ int i;
+ for (i = pos; str[i] != '\0'; i++);
+ return i;
+}
+
+void cmd_cpy(char *scr_buf, char *cmd_buf, int pos) {
+ int end_line = (find_end(scr_buf, pos)/(maxcol+1)) - scr_str;
+ int start_line = (find_start(scr_buf, end_line) + scr_str) * (maxcol+1);
+
+ for (int i = 0, done = 0; !done; i++) {
+ uint64_t tmp = (uint64_t)scr_buf[i];
+ for (int j = 0; j < 8; j++ , tmp >>= 8) {
+ int idx = (i*8) + j;
+ uint8_t tmp2 = tmp;
+ if (idx >= cmd_size || !tmp2) {
+ done = 1;
+ cmd_buf[idx] = '\0';
+ break;
+ }
+ cmd_buf[idx] = tmp2;
+ }
+ }
+}
diff --git a/programs/sub-suite/tmp-stuff/free-new.s b/programs/sub-suite/tmp-stuff/free-new.s
new file mode 100644
index 0000000..dad19d0
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/free-new.s
@@ -0,0 +1,143 @@
+.include "declare.s"
+
+.org 0
+
+; free: Free allocated memory.
+; Input: D = Pointer to allocated memory.
+; Output: none.
+; Caller preserved registers: D.
+; Callie preserved registers: A, B, X, Y, E.
+
+free:
+ pha.q ; Preserve A.
+ phb.q ; Preserve B.
+ phx.q ; Preserve X.
+ phy.q ; Preserve Y.
+ phe.q ; Preserve E.
+ and #0 ; Reset A.
+ tab ; Reset B.
+ tax ; Reset X.
+ tay ; Reset Y.
+ mov a, d ; Get the passed pointer.
+ bne @getrealblk ; The pointer isn't NULL, so get the real block.
+ bra @end ; The pointer is NULL, so we're done.
+@getrealblk:
+ sub #8 ; Get the start of the used block.
+ mov.q a, (a) ; Get the start of the real block.
+ mov.q b, (a+ublk.size) ; Get the size of the real block.
+ lea e, (a+b) ; Add the size of the real block with the start of the real block.
+ cmp.q e, heapptr ; Is this block on top of the heap?
+ bne @heapadd ; No, so add it to the free block list.
+@dectop:
+ mov.q heapptr, (a) ; Set the top of the heap to the start of the previous real block.
+@chklastblk:
+ mov.q b, heapl ; Get the last free list entry.
+ beq @end ; The free list is empty, so we're done.
+ ldy #fblk.size ; Get the size of the block.
+ mov.q a, (b+fblk.size) ; Get the size of the block.
+ lea e, (a+b) ; Add the size of the block, with the address of the block entry.
+ cmp.q e, heapptr ; Is the last block on top of the heap?
+ bne @end ; No, so we're done.
+@delblk:
+ mov.q heapptr, b ; Yes, so remove the last block.
+@correctblk:
+ mov.q a, (b+fblk.prev) ; Get the previous block.
+ sta.q heapl ; Set the last block to the previous block.
+ bne @delnxtblk ; The previous block isn't NULL, so delete the next block.
+ sta.q heapf ; The previous block is NULL, so empty the free list.
+ bra @end ; We are done.
+@delnxtblk:
+ lea e, (a+fblk.next) ; Delete the next block.
+ stz.q (e) ;
+@end:
+ ple.q ; Restore E.
+ ply.q ; Restore Y.
+ plx.q ; Restore X.
+ plb.q ; Restore B.
+ pla.q ; Restore A.
+ rts ; End of free.
+
+
+@heapadd:
+ mov.q y, heapf ; Get the first block.
+ bne @srchflst ; The Free list isn't empty, so start searching the free list.
+@empty:
+ mov.q (a+fblk.next), y ; Clear the next block.
+ mov.q (a+fblk.prev), y ; Clear the previous block.
+ sta.q heapf ; Set the first block entry to the current block.
+ sta.q heapl ; Set the last block entry to the current block.
+ bra @end ; We are done.
+@srchflst:
+@loop:
+ cmp y, a ; Is the right pointer at, or below the current block?
+ beq @nextright ; Yes, so get the next right pointer.
+ bcs @chkrmerge ; No, so do the right block merge.
+@nextright:
+ tyx ; Set the left pointer, to the right pointer.
+ mov.q y, (y+fblk.next) ; Set the current right pointer to the next right pointer.
+ bne @loop ; The next right pointer isn't NULL, so keep looping.
+@st_lmerge2:
+ mov.q (a+fblk.next), y ; Clear the next block.
+ sta.q heapl ; Set the last free block entry to it.
+ bra @chklmerge2 ; Do the left block merge.
+@chkrmerge:
+ lea e, (a+b) ; Add the size of the current block, to the current block.
+ cmp e, y ; Is the current block the same as the right block?
+ bne @normerge ; No, so don't merge the right block.
+@rmerge:
+ mov e, b ; Get the size of the current block.
+ add.q e, (y+fblk.size) ; Add the size of the current block, with the size of the right pointer.
+ mov.q (a+fblk.size), e ; Set the size of the current block, to the new size.
+@rmerge2:
+ lea fblk.next ; Get the next right pointer.
+ mov.q (a+e), (y+e) ; Set the next block, to the next right pointer.
+ mov.q b, (y+e) ; Save the next block.
+ beq @setheapl ; The next block is NULL, so set the last block.
+@setprev:
+ mov.q (b+fblk.prev), a ; Set the previous block to the current block.
+ bra @chklmerge ; Do the left block merge.
+@setheapl:
+ sta.q heapl ; Set the last block to the current block.
+ bra @chklmerge ; Do the left block merge.
+@normerge:
+ mov.q (a+fblk.next), y ; Set the next block to the right pointer.
+ mov.q (y+fblk.prev), a ; Set the previous right pointer to the current block.
+@chklmerge:
+ and x, x ; Is the left pointer NULL?
+ bne @chklmerge2 ; No, so keep checking.
+@newstart:
+ mov.q (a+fblk.prev), x ;
+ sta.q heapf ; Set the first block, to the current block.
+ bra @end2 ; We are done.
+@chklmerge2:
+ mov.q e, (x+fblk.size) ; Get the size of the left block.
+ add e, x ; Add the size of the left block, to the left pointer.
+ cmp e, a ; Is the left block adjacent?
+ bne @nolmerge ; No, so don't merge the left block.
+@lmerge:
+ lea fblk.size ; Set the offset to the block size.
+ add.q (x+e), (a+e) ; Add the size of the left block, with the size of the current block.
+@lmerge2:
+ lea fblk.next ; Set the offset to the next block.
+ mov.q (x+e), (a+e) ; Set the next left pointer, to the next block.
+ mov.q b, (a+e) ; Get the next block.
+ beq @newlast ; The next block is NULL, so set the last block.
+@lprev:
+ mov.q (b+fblk.prev), x ; Set the next left pointer's previous pointer to the left pointer.
+ bra @end2 ; We are done.
+@newlast:
+ stx.q heapl ; Set the last block, to the left pointer.
+ bra @end2 ; We are done.
+@nolmerge:
+ mov.q (x+fblk.next), a ; Set the next left pointer, to the current block.
+@nolmerge2:
+ mov.q (a+fblk.prev), x ; Set the previous block, to the left pointer.
+@end2:
+ ple.q ; Restore E.
+ ply.q ; Restore Y.
+ plb.q ; Restore B.
+ pla.q ; Restore A.
+ rts ; End of free.
+
+a
+q
diff --git a/programs/sub-suite/tmp-stuff/free-old.s b/programs/sub-suite/tmp-stuff/free-old.s
new file mode 100644
index 0000000..7f75edd
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/free-old.s
@@ -0,0 +1,200 @@
+.include "declare.s"
+
+.org 0
+
+; free: Free allocated memory.
+; Input: A = Pointer to allocated memory.
+; Output: none.
+; Caller preserved registers: none.
+; Callie preserved registers: A, B, Y.
+
+free:
+ pha.q ; Preserve A.
+ phb.q ; Preserve B.
+ phy.q ; Preserve Y.
+ pha.q ; Push the pointer argument to the stack.
+ and #0 ; Reset A.
+ tay ; Reset Y.
+ sbs #$18 ; Allocate 3 local variables onto the stack.
+ lda.q sp+25 ; Get the passed pointer.
+ ora.d sp+29 ; Is the passed pointer NULL?
+ bne @getrealblk ; No, so get the real block.
+ bra @end ; Yes, so we're done.
+@getrealblk:
+ lda.q sp+25 ; Get the passed pointer.
+ sec ; Prepare for a non borrowing subtract.
+ sbc #8 ; Move the passed pointer back by one.
+ sta.q sp+25 ; Set the first local variable to the start of the used block.
+ lda.q (sp+25) ; Get the real block address.
+ sta.q sp+25 ; Set the passed pointer to the start of the real block.
+ ldy #ublk.size ; Get the size of the real block.
+ lda.q (sp+25), y;
+ sta.q sp+17 ; Save the size of the real block.
+ clc ; Prepare for a non carrying add.
+ adc.q sp+25 ; Add the size of the real block with the start of the real block.
+ cmp.q heapptr ; Is this block on top of the heap?
+ bne @heapadd ; No, so add it to the free block list.
+@dectop:
+ lda.q sp+25 ; Get the block.
+ sta.q heapptr ; Set the top of the heap to it.
+@chklastblk:
+ lda.q heapl ; Get the last free list entry.
+ sta.q sp+17 ; Copy it into the second local variable.
+ ora.d sp+21 ; Is the free list empty?
+ beq @end ; Yes, so we're done.
+ lda.q sp+17 ; No, so Get the last free list entry.
+ ldy #fblk.size ; Get the size of the block.
+ lda.q (sp+17), y;
+ clc ; Prepare for a non carrying add.
+ adc.q sp+17 ; Add the size of the block, with the address of the block entry.
+ cmp.q heapptr ; Is the last block on top of the heap?
+ bne @end ; No, so we're done.
+@delblk:
+ lda.q sp+17 ; Yes, so remove the last block.
+ sta.q heapptr ;
+@correctblk:
+ ldy #fblk.prev ; Get the previous block.
+ lda.q (sp+17), y;
+ sta.q sp+25 ; Save the previous block for now.
+ sta.q heapl ; Set the last block to the previous block.
+ ora.d sp+29 ; Is the previous block non NULL?
+ bne @delnxtblk ; Yes, so delete the next block.
+ sta.q heapf ; No, so empty the free list.
+ bra @end ; We are done.
+@delnxtblk:
+ and #0 ; Reset A.
+ ldy #fblk.next ; Delete the next block.
+ sta.q (sp+25), y;
+@end:
+ ads #$20 ; Clean up the stack frame.
+ ply.q ; Restore Y.
+ plb.q ; Restore B.
+ pla.q ; Restore A.
+ rts ; End of free.
+
+
+@heapadd:
+ lda.q heapf ; Get the first block.
+ sta.q sp+9 ; Copy it into the third local variable.
+ ora.d sp+13 ; Is the free list empty?
+ bne @srchflst ; No, so start searching the free list.
+@empty:
+ ldy #fblk.next ; Clear the next block.
+ sta.q (sp+25), y;
+ ldy #fblk.prev ; Clear the previous block.
+ sta.q (sp+25), y;
+ lda.q sp+25 ; Reset A.
+ sta.q heapf ; Clear the first block entry.
+ sta.q heapf ; Clear the last block entry.
+ bra @end ; We are done.
+@srchflst:
+ and #0 ; Reset A.
+ sta.q sp+1 ; Reset the left pointer.
+ ldy #fblk.next ; Setup for the loop.
+@loop:
+ lda.q sp+9 ; Get the right pointer.
+ cmp.q sp+25 ; Is the right pointer at, or below the current block?
+ beq @nextright ; Yes, so get the next right pointer.
+ bcs @chkrmerge ; No, so do the right block merge.
+@nextright:
+ sta.q sp+1 ; Set the left pointer, to the right pointer.
+ lda.q (sp+9), y ; Get the next right pointer.
+ sta.q sp+9 ; Set the current right pointer to the next right pointer.
+ ora.d sp+13 ; Is the next right pointer NULL?
+ bne @loop ; No, so keep looping.
+@st_lmerge2:
+ sta.q (sp+25), y; Clear the next block.
+ lda.q sp+25 ; Get the current block.
+ sta.q heapl ; Set the last free block entry to it.
+ bra @chklmerge2 ; Do the left block merge.
+@chkrmerge:
+ lda.q sp+25 ; Get the current block.
+ clc ; Prepare for a non carrying add.
+ adc.q sp+17 ; Add the size of the current block, to the current block.
+ cmp.q sp+9 ; Is the right pointer NULL?
+ bne @normerge ; No, so don't merge the right block.
+@rmerge:
+ ldy #fblk.size ; Get the size of the right pointer.
+ lda.q sp+17 ; Get the size of the current block.
+ clc ; Prepare for a non carrying add.
+ adc.q (sp+9), y ; Add the size of the current block, with the size of the right pointer.
+ sta.q (sp+25), y; Set the size of the current block, to the new size.
+@rmerge2:
+ ldy #fblk.next ; Get the next right pointer.
+ lda.q (sp+9), y ;
+ sta.q (sp+25), y; Set the next block, to the next right pointer.
+ sta.q sp+17 ; Save the next block in the second local variable.
+ ora.d sp+21 ; Is the next block NULL?
+ beq @setheapl ; Yes, so set the last block.
+@setprev:
+ lda.q sp+25 ; Get the current block.
+ ldy #fblk.prev ; Set the previous block to the current block.
+ sta.q (sp+17), y;
+ bra @chklmerge ; Do the left block merge.
+@setheapl:
+ lda.q sp+25 ; Get the current block.
+ sta.q heapl ; Set the last block to the current block.
+ bra @chklmerge ; Do the left block merge.
+@normerge:
+ lda.q sp+9 ; Get the right pointer.
+ ldy #fblk.next ; Set the next block to the right pointer.
+ sta.q (sp+25), y;
+ lda.q sp+25 ; Get the current block.
+ ldy #fblk.prev ; Set the previous right pointer to the current block.
+ lda.q (sp+9), y ;
+@chklmerge:
+ lda.q sp+1 ; Get the left pointer.
+ ora.d sp+5 ; Is the left pointer NULL?
+ bne @chklmerge2 ; No, so keep checking.
+@newstart:
+ ldy #fblk.prev ; Clear the previous block.
+ sta.q (sp+25), y;
+ lda.q sp+25 ; Get the current block.
+ sta.q heapf ; Set the first block, to the current block.
+ bra @end2 ; We are done.
+@chklmerge2:
+ ldy #fblk.size ; Get the size of the left block.
+ lda.q (sp+1), y ;
+ clc ; Prepare for a non carrying add.
+ adc.q sp+1 ; Add the size of the left block, to the left pointer.
+ cmp.q sp+25 ; Is the left block adjacent?
+ bne @nolmerge ; No, so don't merge the left block.
+@lmerge:
+ lda.q (sp+1), y ; Get the size of the left block.
+ clc ; Prepare for a non carrying add.
+ ldb.q (sp+25), y; Get the size of the current block.
+ adc b ; Add the size of the left block, with the size of the current block.
+ sta.q (sp+1), y ; Set the size of the left block to the new size.
+@lmerge2:
+ ldy #fblk.next ; Get the next block.
+ lda.q (sp+25), y;
+ sta.q (sp+1), y ; Set the next left pointer, to the next block.
+ sta.q sp+17 ; Set the second local variable to the next block.
+ ora.d sp+21 ; Is the next left pointer NULL?
+ beq @newlast ; Yes, so set the last block.
+@lprev:
+ lda.q sp+1 ; Get the left pointer.
+ ldy #fblk.prev ; Set the next left pointer's previous pointer to the left pointer.
+ sta.q (sp+17), y;
+ bra @end2 ; We are done.
+@newlast:
+ lda.q sp+1 ; Get the left pointer.
+ sta.q heapl ; Set the last block, to the left pointer.
+ bra @end2 ; We are done.
+@nolmerge:
+ lda.q sp+25 ; Get the current block.
+ ldy #fblk.next ; Set the next left pointer, to the current block.
+ sta.q (sp+1), y ;
+@nolmerge2:
+ lda.q sp+1 ; Get the left pointer.
+ ldy #fblk.prev ; Set the previous block, to the left pointer.
+ sta.q (sp+25), y;
+@end2:
+ ads #$20 ; Clean up the stack frame.
+ ply.q ; Restore Y.
+ plb.q ; Restore B.
+ pla.q ; Restore A.
+ rts ; End of free.
+
+a
+q
diff --git a/programs/sub-suite/tmp-stuff/print_char.s b/programs/sub-suite/tmp-stuff/print_char.s
new file mode 100644
index 0000000..e12461c
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/print_char.s
@@ -0,0 +1,147 @@
+print_char:
+; sta a ; Save the typed character for now.
+ pha ; Preserve the character.
+; ldb #2 ; Make sure that set_ptr sets the third pointer.
+ lda.d #buffer ; Set the third pointer to the start of the screen buffer.
+ pha.q ; Push the pointer onto the stack.
+ lda sp+9 ; Get the character back.
+; jsr set_ptr ;
+; ldb #0 ; Set B to zero.
+; tba ; Set the Accumulator to zero.
+; lda a ; Get back the character.
+ cmp #$1B ; Did the user type an escape character?
+ beq esc ; Yes, so go check the escape code.
+ cmp #'\n' ; No, but did the user type a newline?
+ beq nl ; Yes, so handle the newline.
+ cmp #$C ; No, but did the user type Ctrl+L?
+ beq clr_scr ; Yes, so clear the screen.
+ cmp #19 ; No, but did the user type Ctrl+S?
+ beq en_step ; Yes, so enable clock/instruction stepping.
+ cmp #18 ; No, but did the user type Ctrl+R?
+ beq dis_step ; Yes, so disable clock/instruction stepping.
+ cmp #'\b' ; No, but did the user type a backspace?
+ beq bs ; Yes, so handle the backspace.
+ cmp #$7F ; No, but did they type Delete?
+ beq bs ; Yes, so treat it as a backspace.
+printc:
+ lda #0 ; No, so start trying to print a character.
+ sta d ;
+ lda (sp+1), y ; Are we at the end of the string?
+ beq @save ; Yes, so just print the character.
+ lda b ; No, but was the flag set?
+ bne @save ; Yes, so don't shift the line.
+ sty.w scr_ptr ; No, so save the cursor index for later.
+ jsr fndend ; Find the end of the line.
+ bra @shift ; Start shifting the line right.
+@update:
+ lda scr_col ; Save the current column position for later.
+ sta scr_tcol ;
+@update1:
+ jsr findend ; Find the end of the line.
+ sta e ; Use it for redrawing the line.
+ sta scr_row ; Set the row position to to the end of the line.
+ jsr findst ; Find the start of the line.
+ lda scr_row ; Get the start of the line.
+@update2:
+ sta f ; Set the starting line, to the start of the line.
+ jsr rdrw_ln ; Redraw the line.
+ lda scr_trow ; Get the real row position back.
+ sta scr_row ;
+ lda scr_tcol ; Get the real column position back.
+ sta scr_col ;
+ jsr update_pos ; Update the cursor's position.
+ dec d ;
+ bra @save1 ;
+@shift:
+ ldy.w scr_ptr3 ;
+ inc scr_ptr3 ;
+ tyx ;
+ dey ;
+ ldb #1 ;
+ stb d ;
+ jsr shftln ;
+ ldb #1 ;
+ stb d ;
+; lda a ;
+ lda sp+9 ;
+ sta (sp+1), y ; store typed character into the input buffer.
+ lda scr_row ;
+ sta scr_trow ;
+ bra @update ;
+@save:
+ ldb d ;
+ bne @update ;
+@save1:
+; lda a ;
+ lda sp+9 ;
+ sta (sp+1), y ; store typed character into the input buffer.
+@incr:
+ inc scr_col ; Increment the cursor's x coordinate.
+ iny ;
+@wrapped:
+ ldb #1 ;
+ stb f ;
+ ldb scr_col ;
+ cpb #maxcol+1 ;
+ bcs @scrolled ;
+@print:
+ sta scr ; Echo typed character.
+ ldb f ;
+ beq @wrap ;
+ bra printc_end ;
+@scrolled:
+ ldb scr_row ;
+ cpb #maxrow ;
+ bcs @scroll ;
+@wrapped2:
+ ldb #0 ;
+ stb f ;
+ bra @print ;
+@scroll:
+ sta scr ; Echo typed character.
+ clc ;
+ lda #1 ;
+ sta wrapped ;
+ jsr scrl_down ;
+@wrap:
+ ldb #0
+ stb scr_col ;
+ ldb scr_row ;
+ cpb #maxrow ;
+ bcs @wrap2 ;
+@wrap1:
+ inc scr_row ;
+@wrap2:
+ phx.w ;
+ clc ;
+ lda scr_row ;
+ adc scr_str ;
+ tax ;
+ jsr setbit ;
+ plx.w ;
+ jsr update_pos ;
+printc_end:
+ pla.q ; Pull the pointer off the stack.
+ pla ; Pull the character off the stack.
+ and #0 ; Reset A.
+ rts ;
+
+nl:
+ lda #0 ; Reset A.
+ ldb (sp+1), y ; Is this character not a null terminator?
+ bne @scroll ; Yes, so don't overwrite it.
+ sta (sp+1), y ; No, so overwrite it.
+@scroll:
+ sta scr_col ; Move the cursor to the start of the next line.
+ lda scr_row ; Get the row position.
+ cmp #maxrow ; Are we at the bottom of the screen?
+ bcc @incr ; No, so move down one line.
+ jsr scrl_down ; Yes, so scroll down one line.
+ bra @end ; We are done.
+@incr:
+ inc scr_row ; Move the cursor down by one line.
+ jsr update_pos ; Update the cursor's position.
+@end:
+ lda #'\n' ; Print the newline.
+ sta a ;
+ rts ;
diff --git a/programs/sub-suite/tmp-stuff/shift_line.c b/programs/sub-suite/tmp-stuff/shift_line.c
new file mode 100644
index 0000000..365666b
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/shift_line.c
@@ -0,0 +1,85 @@
+#include <stdint.h>
+
+const uint8_t bits[8] = {
+ 0x80,
+ 0x40,
+ 0x20,
+ 0x10,
+ 0x08,
+ 0x04,
+ 0x02,
+ 0x01
+};
+
+int maxcol = 80;
+int scr_str = 0;
+int scr_row = 0;
+int scr_col = 0;
+uint8_t bitabl[16];
+
+uint8_t bitpos(unsigned int row, uint8_t *mask) {
+ uint8_t bit = row & 7;
+ *mask = bits[bit];
+ return row >> 3;
+
+}
+
+uint8_t getbit(unsigned int row, unsigned int offset) {
+ uint8_t mask;
+ uint8_t byte = bitpos(row+offset, &mask);
+ return (bitabl[byte] & mask);
+}
+
+void setbit(unsigned int row) {
+ uint8_t mask;
+ uint8_t byte = bitpos(row, &mask);
+ bitabl[byte] |= mask;
+}
+
+void clrbit(unsigned int row) {
+ uint8_t mask;
+ uint8_t byte = bitpos(row, &mask);
+ bitabl[byte] &= ~mask;
+}
+
+int find_end(char *str, int start) {
+ int i;
+ for (i = start; str[i]; i++);
+ return i;
+}
+
+void shift_line(char *str, int cursor, int left) {
+ /*int cursor = ((scr_row+scr_str)*maxcol)+scr_col;*/
+ int end = find_end(str, cursor);
+ if (left) {
+ int i = end-1;
+ int j = end;
+ for (; i >= cursor; i--, j--) {
+ if (i < 0) {
+ i = 0;
+ str[i] = 0;
+ break;
+ }
+ str[j] = str[i];
+ str[i] = 0;
+
+ }
+ /*str[i+1] = (!str[i+1]) ? ' ' : str[i+1];*/
+ end = find_end(str, i+2);
+ /*str[i+1] = (str[i+1] == ' ') ? 0 : str[i+1];*/
+ if ((end/maxcol) > scr_row) {
+ setbit(end/maxcol);
+ }
+ } else {
+ int i = cursor;
+ int j = cursor-1;
+ for (; str[i]; i++, j++) {
+ str[j] = str[i];
+ str[i] = 0;
+ }
+ end = find_end(str, i);
+ if (((end-1) % maxcol) == 0 && ((end-1)/maxcol) > scr_row) {
+ clrbit(end/maxcol);
+ }
+ }
+}
diff --git a/programs/sub-suite/tmp-stuff/subeditor-new.s b/programs/sub-suite/tmp-stuff/subeditor-new.s
new file mode 100644
index 0000000..6c1cfb1
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/subeditor-new.s
@@ -0,0 +1,1119 @@
+; SuBEditor.
+;
+; Writen in Sux assembly by
+; mr b0nk 500 <b0nk@b0nk.xyz>
+
+
+.org $8000
+reset:
+ cps ; Reset the processor status register.
+ ldx.w #$FFFF ; Reset the stack pointer.
+ txs ;
+ ldy #0 ; Reset the Y register.
+ sty end ;
+ tyx ; Reset the X register.
+ lda #maxrow ; Set the end of the screen to the screen's max row count.
+ sta scr_end ;
+ tya ; Reset the Accumulator.
+ sta scr_str ; Set the start of the screen back to zero.
+ sta.q bitabl ; Reset the first half of the linewrap table.
+ sta.q bitabl+8 ; Reset the second half of the linewrap table.
+ inc end ;
+ lda.w #$1FFF ; Set the clear count to $1FFF.
+ pha.w ; Push the clear count to the stack.
+ lda.d #buffer ; Set the array to be cleared to the screen buffer.
+ pha.q ; Push it on to the stack.
+ jsr clr_arr ; Clear the screen buffer.
+ pla.q ; Pull the pointer off of the stack.
+ pla.w ; Pull the clear count off of the stack.
+ and #0 ; Reset A.
+ jsr pnt_strt ; Print the starting message.
+ lda #$C ; Clear the screen.
+ sta scr ;
+ bra start ; Goto the start of the main program.
+
+clr_arr:
+ phb ; Preserve whatever was in B.
+ ldb #0 ; Clear B.
+ clc ; Prepare for a non carrying add.
+ adc #8 ; Set the second pointer to the parameter, plus eight.
+ pha.q ; Push it onto the stack.
+ tba ;
+@loop:
+ cpy.w sp+26 ; Did we clear all of the array?
+ bcs @end ; Yes, so we're done.
+ sta.q (sp+18), y; No, so clear eight bytes.
+ sta.q (sp+1), y ; Clear eight more bytes.
+ tya ; Copy the array index.
+ adc #$10 ; Increment the index by 16.
+ tay ; Update the index.
+ tba ; Reset the Accumulator.
+ sta.q (sp+18), y; Do this one more time, to clear 32 bytes.
+ sta.q (sp+1), y ;
+ tya ;
+ adc #$10 ;
+ tay ;
+ tba ;
+ bra @loop ; Keep looping.
+@end:
+ ldy.w zero ; Set the index back to zero.
+ pla.q ; Move the stack pointer back.
+ tba ; Reset A.
+ plb ; Get whatever was in the B register, back.
+ rts ; End of clr_arr.
+
+pnt_strt:
+ lda.w #ed_name ; Print the name of the editor.
+ jsr print_str ;
+ lda.w #ver_str ; Print the version text.
+ jsr print_str ;
+ lda.w #ed_ver ; Print the version number.
+ jsr print_str ;
+ lda.w #ed_sver ; Print the sub version number.
+ jsr print_str ;
+ lda #'\n' ; Print a newline.
+ jsr print_char ;
+ lda.w #made ; Print the "Created by" text.
+ jsr print_str ;
+ lda.w #author ; Print the name of the author.
+ jsr print_str ;
+ lda #'\n' ; Print a newline.
+ jsr print_char ;
+ rts ; End of pnt_strt.
+
+start:
+ lda #0 ; TODO: Update this for the Super VIA.
+ sta status ; Clear the control register of the I/O adapter.
+ tax ; Reset X.
+ phy.w ; Save the cursor index for later.
+ tay ; Reset the cursor index.
+ lda.w #$3FF ; Set the clear count to $3FF.
+ pha.w ; Push the clear count onto the stack.
+ lda.d #cmd_buf ; Set the array to be cleared to the command buffer.
+ pha.q ; Push the pointer onto the stack.
+ jsr clr_arr ; Clear the command buffer.
+ pla.q ; Pull the pointer off of the stack.
+ pla.w ; Pull the clear count off of the stack.
+ ply.w ; Get back the cursor index.
+ and #0 ; Reset the Accumulator.
+ sta end ;
+ bra read ; Start reading the keyboard.
+
+read:
+ lda #0 ; Reset the Accumulator.
+ sta end ; Disable the dummy flag.
+ inc end ; Enable the dummy flag.
+ lda status ; Did we get a key?
+ beq read ; No, so try again.
+ jsr getchar ; Yes, and was it a newline?
+ beq parse ; Yes, so start parsing the line.
+ bra read ; No, so keep looping.
+
+parse:
+ lda #0 ;
+ tax ;
+ jsr subasm ;
+ bra start ;
+
+
+print_str:
+ ldx #0 ; Reset X.
+ pha.q ; Push the parameter onto the stack.
+@loop:
+ ldb #1 ; Enable replace mode.
+ stb b ;
+ and #0 ; No, reset the accumulator.
+ phy.w ; Save the cursor index.
+ txy ; Copy the string index into Y.
+ lda (sp+3), y ; Are we at the end of the string?
+ ply.w ; Get the cursor index back.
+ beq @end ; Yes, so we're done.
+ inx ; No, so increment the string index.
+ jsr print_char ; Print the character.
+ bra @loop ; Keep looping.
+@end:
+ pla.q ; Pull the parameter off the stack.
+ ldb #0 ; Enable insert mode.
+ stb b ;
+ tba ; Reset A.
+ rts ; End of print_str.
+
+getbit:
+ clc ; Clear the carry flag.
+ lda scr_str ; Has the screen been scrolled?
+ bne getbt0 ; Yes, so add the screen offset to the current line number.
+ ldx scr_row ; No, so just use the current line number.
+ bra getbt1 ; Start getting the bit.
+getbt0:
+ lda scr_row ; Get the current line number.
+ adc scr_str ; Add the screen offset to it.
+ tax ; Use it as the wrap index.
+getbt1:
+ tab ; Save the parameter.
+ lda.d #bitabl ; Set the second pointer to the linewrap table.
+ pha.q ; Push the pointer onto the stack.
+ tba ; Get the parameter back.
+ jsr bitpos ; Get the bit, and byte position.
+ phy.w ; Save the screen index.
+ txy ; Get the byte position.
+ ldb (sp+3), y ; Get one byte of the wrap table.
+ ply.w ; Get the screen index back.
+ aba ; Mask out the bit of the current line number.
+ cmp #1 ; Set the carry flag, if true.
+ bra bitout ; We are done.
+
+clrbit:
+ tab ; Save the parameter.
+ lda.d #bitabl ; Set the second pointer to the linewrap table.
+ pha.q ; Push the pointer onto the stack.
+ tba ; Get the parameter back.
+ jsr bitpos ; Get the bit, and byte position.
+ xor #$FF ; Invert the bitmask.
+ phy.w ; Save the screen index.
+ txy ; Get the byte position.
+ ldb (sp+3), y ; Get one byte of the wrap table.
+ aba ; Clear the bit of the current line number.
+bitsav:
+ sta (sp+3), y ; Update the wrap table.
+ ply.w ; Get the screen index back.
+bitout:
+ pla.q ; Pull the pointer off the stack.
+ and #0 ; Reset A.
+ ldx bitmask ; Return the bitmask.
+ rts ; We are done.
+
+setbit:
+ tab ; Save the parameter.
+ lda.d #bitabl ; Set the second pointer to the linewrap table.
+ pha.q ; Push the pointer onto the stack.
+ tba ; Get the parameter back.
+ jsr bitpos ; Get the bit, and byte position.
+ phy.w ; Save the screen index.
+ txy ; Get the byte position.
+ ldb (sp+3), y ; Get one byte of the wrap table.
+ oab ; Set the bit of the current line number.
+ bra bitsav ; Save the bit.
+
+bitpos:
+ tab ; Save the parameter.
+ lda.w #bits ; Set the first pointer to the bitmask table.
+ pha.q ; Push the pointer onto the stack.
+ tba ; Get the parameter back.
+ stx bitmask ; Make the line number the bitmask.
+ txa ; Copy it to the Accumulator.
+ and #7 ; Get the bit position.
+ phy.w ; Save the cursor index.
+ tay ; Use the bit position as the index.
+ tax ; Copy it into X.
+ lda (sp+3), y ; Get the bitmask.
+ ply.w ; Get back the cursor index.
+ pha ; Save the bitmask.
+ lda bitmask ; Get the line number.
+ lsr #3 ; Get the byte position.
+ tax ; Copy it into X.
+ pla ; Get back the bitmask.
+ tab ; Preserve the bitmask.
+ pla.q ; Pull the pointer off the stack.
+ tba ; Get the bitmask back.
+ rts ; End of bitpos.
+
+getchar:
+ lda kbd ; Get the character that was typed from the keyboard.
+ ldb #0 ; Reset the B register.
+ stb e ; Set the temporary row position to zero, in case we get a newline.
+ stb b ; Enable insert mode.
+ pha ; Save the character.
+ phy.w ; Save the cursor index.
+ cmp #'\n' ; Was the character that was typed, a newline?
+ bne @print ; No, so just print the character.
+ jsr cmd_cpy ; Yes, so start copying the line to the command buffer.
+@print:
+ ply.w ; Get back the cursor index.
+ pla ; Get back the character.
+ ldb e ; Is the temporary row position non zero?
+ bne @row ; Yes, so reset the row positon.
+@print1:
+ jsr print_char ; No, so print the character.
+ lda a ; Get the return value.
+ cmp #'\n' ; Is the return value, a newline?
+ beq @true ; Yes, so return true.
+ bra @false ; No, so return false.
+@row:
+ ldb e ; Get the temporary row position.
+ cpb #maxrow ; Is temporary row position, at, or above the bottom of the screen?
+ beq @row2 ; Yes, so leave it as is.
+ bcs @row1 ; No, so set it to the bottom of the screen.
+ bra @row2 ; Yes, so leave it as is.
+@row1:
+ ldb #maxrow ; Set the row position to the bottom of the screen.
+@row2:
+ stb scr_row ; Set the row position.
+ bra @print1 ; Print the character.
+@true:
+ lda #0 ; Return true.
+ bra @end ; We are done.
+@false:
+ lda #1 ; Return false.
+@end:
+ rts ; End of getchar.
+
+
+cmd_cpy:
+ lda scr_row ; Get the row position.
+ sta scr_trow ; Save it for later.
+ jsr findend ; Find the end of the line.
+ ldb scr_str ; Has the screen been scrolled?
+ beq @start ; No, so don't subtract the screen's starting point from the line number.
+@offset:
+ sec ; Yes, so make sure that we don't subtract by the starting point, plus one.
+ sbc scr_str ; Offset the row position, back by the screen's starting point.
+ clc ; Clear the carry flag, so that nothing odd occurs.
+@start:
+ sta scr_row ; Set the row position to the end of the line.
+ sta e ; Save it into the temporary row posiition.
+ jsr findst ; Find the start of the line.
+ clc ; Clear the carry flag.
+ lda scr_row ; Get the row position.
+ adc scr_str ; Add it with the screen's starting row.
+ mul #maxcol+1 ; Multiply it with the width of the screen, plus one.
+ tay ; Place it into the index.
+ ldx.w #0 ; Reset the X register.
+ ldb #0 ; Make sure that set_ptr sets the first pointer.
+ lda.d #buffer ; Set the first pointer to the start of the screen buffer.
+ pha.q ; Push the pointer onto the stack.
+ lda.d #cmd_buf ; Set the second pointer to the start of the command buffer.
+ pha.q ; Push the pointer onto the stack.
+ tba ; Set the accumulator to zero.
+@loop:
+ ldb #0 ; Reset the B register.
+ lda.q (sp+9), y ; Get eight bytes from the current line.
+@loop1:
+ phy.w ; Save the screen index.
+ txy ; Get the command buffer index.
+ sta (sp+3), y ; Copy one byte from the screen buffer, to the command buffer.
+ inx ; Increment the command buffer index.
+ ply.w ; Get back the screen index.
+ cpx.w #$3FF ; Are we at the end of the command buffer?
+ bcs @end ; Yes, so we're done.
+ iny ; No, so increment the screen index.
+ inb ; Increment the byte count.
+ lsr #8 ; Shift in the next byte.
+ stb g ; Save the byte count.
+ tab ; Save the string buffer.
+ and #$FF ; Is this byte of the buffer, a null terminator?
+ beq @end1 ; Yes, so we're done.
+ tba ; No so get back the string buffer.
+ ldb g ; Get back the byte count.
+ cpb #7 ; Did we shift in eight bytes?
+ beq @loop ; Yes, so get eight more bytes.
+ bra @loop1 ; No, so keep shifting in more bytes.
+@end:
+ ldb #0 ; Reset B.
+ phy.w ; Save the screen index.
+ txy ; Get the command buffer index.
+ stb (sp+3), y ; Terminate the command buffer.
+ ply.w ; Get back the screen index.
+@end1:
+ pla.q ; Pull one of the pointers off the stack.
+ pla.q ; Pull the other pointer off the stack.
+ tba ; The B register is zero, so clear the Accumulator.
+ rts ; End of cmd_cpy.
+
+
+findst:
+ lda #0 ; Reset A.
+@loop:
+ pha ; Save the current line number.
+ jsr getbit ; Is this the start of the line?
+ pla ; Get the current line number back.
+ bcc @end ; Yes, so we're done.
+ inc ; No, so check the next physical line.
+ dec scr_row ; Are we at the top of the screen?
+ bpo @loop ; No, so keep looping.
+ dec ; Yes, so move back one line.
+ inc scr_row ; Put the row postiion back to zero.
+@end:
+ cmp #0 ; Update all the flags.
+ rts ; End of findst.
+
+
+fndend:
+ lda.d #buffer ; Set the first pointer to the start of the screen buffer.
+ pha.q ; Push the pointer onto the stack.
+ phb ; Save the contents of the B register.
+ ldb #0 ; Make sure that set_ptr sets the first pointer.
+ tba ; Set the Accumulator to zero.
+ plb ; Restore the contents of the B register.
+ phy.w ;
+@loop:
+ lda (sp+3), y ; Are we at the end of the string?
+ beq @end ; Yes, so we're done.
+ iny ; No, so increment the cursor index.
+ bra @loop ; Keep looping.
+@end:
+ sty.w scr_ptr3 ;
+ ply.w ;
+ pla.q ; Pull the pointer off the stack.
+ and #0 ; Reset A.
+ rts ; End of fndend.
+
+findend:
+ jsr fndend ;
+ lda.w scr_ptr3 ;
+ div #maxcol+1 ;
+ rts ;
+
+
+print_char:
+ sta a ; Save the typed character for now.
+ ldb #2 ; Make sure that set_ptr sets the third pointer.
+ lda.d #buffer ; Set the third pointer to the start of the screen buffer.
+ jsr set_ptr ;
+ ldb #0 ; Set B to zero.
+ tba ; Set the Accumulator to zero.
+ lda a ; Get back the character.
+ cmp #$1B ; Did the user type an escape character?
+ beq esc ; Yes, so go check the escape code.
+ cmp #'\n' ; No, but did the user type a newline?
+ beq nl ; Yes, so handle the newline.
+ cmp #$C ; No, but did the user type Ctrl+L?
+ beq clr_scr ; Yes, so clear the screen.
+ cmp #19 ; No, but did the user type Ctrl+S?
+ beq en_step ; Yes, so enable clock/instruction stepping.
+ cmp #18 ; No, but did the user type Ctrl+R?
+ beq dis_step ; Yes, so disable clock/instruction stepping.
+ cmp #'\b' ; No, but did the user type a backspace?
+ beq bs ; Yes, so handle the backspace.
+ cmp #$7F ; No, but did they type Delete?
+ beq bs ; Yes, so treat it as a backspace.
+printc:
+ lda #0 ; No, so start trying to print a character.
+ sta d ;
+ lda (ptr3), y ; Are we at the end of the string?
+ beq @save ; Yes, so just print the character.
+ lda b ; No, but was the flag set?
+ bne @save ; Yes, so don't shift the line.
+ sty.w scr_ptr ; No, so save the cursor index for later.
+ jsr fndend ; Find the end of the line.
+ bra @shift ; Start shifting the line right.
+@update:
+ lda scr_col ; Save the current column position for later.
+ sta scr_tcol ;
+@update1:
+ jsr findend ; Find the end of the line.
+ sta e ; Use it for redrawing the line.
+ sta scr_row ; Set the row position to to the end of the line.
+ jsr findst ; Find the start of the line.
+ lda scr_row ; Get the start of the line.
+@update2:
+ sta f ; Set the starting line, to the start of the line.
+ jsr rdrw_ln ; Redraw the line.
+ lda scr_trow ; Get the real row position back.
+ sta scr_row ;
+ lda scr_tcol ; Get the real column position back.
+ sta scr_col ;
+ jsr update_pos ; Update the cursor's position.
+ dec d ;
+ bra @save1 ;
+@shift:
+ ldy.w scr_ptr3 ;
+ inc scr_ptr3 ;
+ tyx ;
+ dey ;
+ ldb #1 ;
+ stb d ;
+ jsr shftln ;
+ ldb #1 ;
+ stb d ;
+ lda a ;
+ sta (ptr3), y ; store typed character into the input buffer.
+ lda scr_row ;
+ sta scr_trow ;
+ bra @update ;
+@save:
+ ldb d ;
+ bne @update ;
+@save1:
+ lda a ;
+ sta (ptr3), y ; store typed character into the input buffer.
+@incr:
+ inc scr_col ; Increment the cursor's x coordinate.
+ iny ;
+@wrapped:
+ ldb #1 ;
+ stb f ;
+ ldb scr_col ;
+ cpb #maxcol+1 ;
+ bcs @scrolled ;
+@print:
+ sta scr ; Echo typed character.
+ ldb f ;
+ beq @wrap ;
+ bra printc_end ;
+@scrolled:
+ ldb scr_row ;
+ cpb #maxrow ;
+ bcs @scroll ;
+@wrapped2:
+ ldb #0 ;
+ stb f ;
+ bra @print ;
+@scroll:
+ sta scr ; Echo typed character.
+ clc ;
+ lda #1 ;
+ sta wrapped ;
+ jsr scrl_down ;
+@wrap:
+ ldb #0
+ stb scr_col ;
+ ldb scr_row ;
+ cpb #maxrow ;
+ bcs @wrap2 ;
+@wrap1:
+ inc scr_row ;
+@wrap2:
+ phx.w ;
+ clc ;
+ lda scr_row ;
+ adc scr_str ;
+ tax ;
+ jsr setbit ;
+ plx.w ;
+ jsr update_pos ;
+printc_end:
+ rts ;
+
+nl:
+ lda #0 ; Reset A.
+ ldb (ptr3), y ; Is this character not a null terminator?
+ bne @scroll ; Yes, so don't overwrite it.
+ sta (ptr3), y ; No, so overwrite it.
+@scroll:
+ sta scr_col ; Move the cursor to the start of the next line.
+ lda scr_row ; Get the row position.
+ cmp #maxrow ; Are we at the bottom of the screen?
+ bcc @incr ; No, so move down one line.
+ jsr scrl_down ; Yes, so scroll down one line.
+ bra @end ; We are done.
+@incr:
+ inc scr_row ; Move the cursor down by one line.
+ jsr update_pos ; Update the cursor's position.
+@end:
+ lda #'\n' ; Print the newline.
+ sta a ;
+ rts ;
+
+
+clr_scr:
+ lda #maxrow ;
+ sta scr_end ;
+ lda #0 ;
+ sta scr_str ;
+ sta.q bitabl ;
+ sta.q bitabl+8 ;
+ tay ;
+ lda.w #$1FFF ; Set the clear count to $1FFF.
+ pha.w ; Push the clear count onto the stack.
+; sta.w scr_ptr ;
+ lda.d #buffer ; Set the array to be cleared to the screen buffer.
+ pha.q ; Push the pointer onto the stack.
+ jsr clr_arr ; Clear the screen buffer.
+ tay ;
+ pla.q ; Pull the pointer off of the stack.
+ pla.w ; Pull the clear count off of the stack.
+ lda.w #$3FF ; Set the clear count to $3FF.
+ pha.w ; Push the clear count onto the stack.
+; sta.w scr_ptr ;
+ lda.d #cmd_buf ; Set the array to be cleared to the command buffer.
+ pha.q ;
+ jsr clr_arr ; Clear the screen buffer.
+ pla.q ; Pull the pointer off of the stack.
+ pla.w ; Pull the clear count off of the stack.
+ and #0 ; Reset A.
+ sta scr_col ;
+ sta scr_row ;
+ jsr update_pos ;
+ lda #$C ;
+ sta scr ;
+ rts ;
+
+en_step:
+ lda step ;
+ beq step_en ;
+ rts ;
+step_en:
+ lda #1 ;
+ sta step ;
+ rts ;
+
+dis_step:
+ lda step ;
+ bne step_dis ;
+ rts ;
+step_dis:
+ lda #0 ;
+ sta step ;
+ rts ;
+
+
+bs:
+ lda scr_col ; Are we at the far left of the screen?
+ beq @wrap ; Yes, so check for a wrapped line.
+ bra back ; No, so add the backspace to the buffer.
+@wrap:
+ jsr getbit ; Is this line, a wrapped line?
+ bcs @wrap1 ; Yes, so check if the cursor is at the top.
+ rts ; No, so we're done.
+@wrap1:
+ lda scr_row ; Are we at the top of the screen?
+ beq @wrap2 ; Yes, so check if the screen is at the top of the buffer.
+ bra @wrap3 ; No, so start clearing the wrap bit.
+@wrap2:
+ lda scr_str ; Are we at the top of the buffer?
+ bne @scroll ; Yes, so scroll up.
+ rts ; No, so we're done.
+@scroll:
+ clc ; Clear the carry flag, so that we don't get odd behaviour.
+ jsr scrl_up ; Scroll up.
+ inc scr_row ; Move down by one row.
+@wrap3:
+ clc ; Clear the carry flag.
+ lda scr_row ; Add the cursor's row position,
+ adc scr_str ; and the screen's starting row.
+ tax ; Transfer that into X.
+@wrap4:
+ dec scr_row ; Move up by one row.
+ ldb #maxcol+1 ; Move the cursor to the absolute right of the screen.
+ stb scr_col ;
+ jsr update_pos ; Update the cursor's position.
+back:
+ ldb #0 ; Reset B, and some flags.
+ stb e ;
+ stb f ;
+ lda scr_row ; Save the current row position for later.
+ sta scr_trow ;
+ jsr findend ; Find the end of the line.
+ sta scr_row ; Set our row position to the end of the line.
+@find_st:
+ jsr findst ; Does this line take up more than one real line?
+ beq @shift ; No, so skip updating any other lines.
+ bcs @update ; Yes, so update the other lines.
+ lda scr_trow ; Get the real row position back.
+ sta scr_row ;
+@shift:
+ dey ; Decrement the buffer's offset.
+ lda #0 ; Place a null terminator
+ sta (ptr3), y ; into the buffer.
+ tyx ; Copy the current cursor index to X.
+ iny ; Increment cursor index.
+ ldb #0 ; Set shifting direction to left.
+ stb d ;
+ jsr shftln ; Shift line back by one character.
+ lda #$7F ; Print a backspace to the screen.
+ sta scr ;
+ lda e ; Are we updating more than one line?
+ beq @load ; No, so skip to the next step.
+@find_end:
+ jsr findend ; Yes, so find the end of the line.
+ sta e ; Set the end parameter to it.
+ lda scr_col ; Save the current column position for now.
+ sta scr_tcol ;
+ jsr rdrw_ln ; Start redrawing the line.
+ lda scr_tcol ; Get the real column position back.
+ sta scr_col ;
+@load:
+ lda scr_trow ; Get the real row position back.
+ sta scr_row ;
+ dec scr_col ; Move the cursor back by one column,
+ jsr update_pos ; and update it's position.
+ rts ; We are done.
+@update:
+ lda scr_row ; Set the line to start redrawing, to the start of the line.
+ sta f ;
+ inc e ; Set the redraw flag to true.
+ bra @shift ; Start shifting the line back.
+
+
+shftln:
+ ldb d ; Is the flag not set?
+ beq @dec_loop ; Yes, so shift, and decrement.
+ ldb #0 ; Clear the B register.
+ bra @inc_loop ; No, so shift, and increment.
+@neg:
+ ldy.w zero ; Set the source poition to 0.
+ stb (ptr3), y ; Clear the character that is in the source.
+ bra @end ; We are done.
+@inc_loop:
+ sty.w scr_ptr2 ; Save the source position for later.
+ ldy.w scr_ptr ; Get the previous cursor index.
+ cpy.w scr_ptr2 ; Is the source position, at, or below the cursor index?
+ beq @inc_loop1 ; Yes, so keep looping.
+ bcs @end ; No, so we're done.
+@inc_loop1:
+ ldy.w scr_ptr2 ; Get the source position.
+ lda (ptr3), y ; Get the character from the source position.
+ phy.w ; Save the source position for later.
+ txy ; Set our position to the destination.
+ sta (ptr3), y ; Place the character from the source position, to the destination position.
+ ply.w ; Set our position back to the source.
+ stb (ptr3), y ; Clear the character that is in the source.
+ bng @neg ; The source underflowed, so set it back to zero,
+ dey ; Decrement the source position.
+ dex ; Decrement the destination position.
+ bra @inc_loop ; Keep looping.
+@dec_loop:
+ stx.w scr_ptr2 ; Save the destination position for later.
+ lda (ptr3), y ; Is the character at the source position, a null terminator?
+ beq @end3 ; Yes, so we're done.
+ phy.w ; No, so save the source position for later.
+ txy ; Set our position to the destination.
+ sta (ptr3), y ; Place the character from the source position, to the destination position.
+ inx ; Increment the destination position.
+ ply.w ; Set our position back to the source.
+ stb (ptr3), y ; Clear the character that is in the source.
+ iny ; Increment the source position.
+ bra @dec_loop ; Keep looping.
+@wrap:
+ tax ; Use the ending line as a parameter for setbit.
+ jsr setbit ; Set the wrap bit of the ending line.
+ bra @end5 ; We are done.
+@wrap1:
+ tax ; Use the ending line as a parameter for clrbit.
+ jsr clrbit ; Clear the wrap bit of the ending line.
+ bra @end5 ; We are done.
+@end:
+ lda (ptr3), y ; Is this character a null terminator?
+ bne @end1 ; No, so just find the end of the line.
+ lda #$20 ; Yes, so convert it to a space for now.
+ sta (ptr3), y ;
+@end1:
+ jsr findend ; Find the ending line.
+ sta d ; Save ending line for later.
+ lda (ptr3), y ; Is this character a space?
+ cmp #$20 ;
+ bne @end5 ; No, so skip the conversion.
+ lda #0 ; Yes, so convert it back to zero.
+ sta (ptr3), y ;
+@end2:
+ lda d ; Get the ending line.
+ cmp scr_row ; Is the ending line greater than the starting line?
+ beq @end5 ; No, so we're done.
+ bcs @wrap ; Yes, so set the wrap bit.
+ bra @end5 ; No, so we're done.
+@end3:
+ jsr findend ; Find the ending line.
+ cpb #0 ; Is the remainder zero?
+ beq @end4 ; Yes, so check if the ending line is greater than the starting line.
+ bra @end5 ; No, so we're done.
+@end4:
+ cmp scr_row ; Is the ending line greater than the starting line?
+ beq @end5 ; No, so we're done.
+ bcs @wrap1 ; Yes, so clear the wrap bit.
+@end5:
+ rts ; End of shftln.
+
+esc:
+ lda status ; Get the next character.
+ lda kbd ;
+ cmp #$1B ; Is this character an escape character?
+ beq shftesc ; Yes, so check the other set of escape routines.
+ lda status ; No, so wait for the next character.
+ beq @end ; We have an error, so discard it, and go back to getting user input.
+ lda kbd ; Get the escape code.
+ sta c ; Store the escape code, until we need it.
+ lda #0 ; Set the D pseudo register to zero.
+ sta d ;
+ jsr isup ; Check if the user pressed up.
+ lda d ; Did the user press up?
+ bne @end ; Yes, so we're done.
+ jsr isdown ; No, so check if the user pressed down.
+ lda d ; Did the user press down?
+ bne @end ; Yes, so we're done.
+ lda #0 ; No, so check if the user pressed left.
+ jsr isleft ;
+ lda d ; Did the user press left?
+ bne @end ; Yes, so we're done.
+ jsr isright ; No, so check if the user pressed right.
+@end:
+ lda #0 ; Clear the D pseudo register.
+ sta d ;
+ rts ; We are done.
+
+shftesc:
+ lda status ; Skip the '['.
+ lda kbd ;
+ lda status ; Wait for the next character.
+ beq @end ; We have an error, so discard it, and go back to getting user input.
+ lda kbd ; Get the escape code.
+ sta c ; Store the escape code, until we need it.
+ lda #0 ; Use the D pseudo register as a skip flag.
+ sta d ;
+ jsr isshftup ; Check if the user pressed shift+up.
+ lda d ; Was it successful?
+ bne @end ; Yes, so we're done.
+ jsr isshftdown ; No, so check if the user pressed shift+down.
+@end:
+ lda #0 ; Clear the D pseudo register.
+ sta d ;
+ rts ; We are done.
+
+
+isup:
+ lda c ; Load the escape code into the accumulator.
+ cmp #'A' ; Did the user press the up arrow key?
+ bne @end ; No, so we're done.
+ lda scr_row ; Yes, but is the cursor at the top of the screen?
+ beq @scroll ; Yes, so check if we need to scroll.
+@check2:
+ lda c ; No, so load the escape code back into the accumulator.
+ cmp #'A' ; Did the user press the up arrow key?
+ beq @up ; Yes, so move the cursor up.
+ bra @end ; No, so we're done.
+@up:
+ dec scr_row ; Move the cursor up a line.
+ jsr update_pos ; Update it's position.
+ lda #1 ; Tell the escape routine that we succeded.
+ sta d ;
+ rts ; We are done.
+@scroll:
+ lda scr_str ; Are we at the top of the screen buffer?
+ beq @end ; Yes, so we're done.
+ jsr scrl_up ; No, so scroll up.
+ lda #1 ; Tell the escape routine that we were successful.
+ sta d ;
+@end:
+ rts ; End of isup.
+
+
+isdown:
+ lda c ; Load the escape code into the accumulator.
+ cmp #'B' ; Did the user press the down arrow key?
+ bne @end ; No, so we're done.
+ lda scr_row ; Yes, so start checking the y coordinate of the cursor.
+ cmp #maxrow ; Is the cursor at the bottom of the screen?
+ beq @scroll ; Yes, so scroll down.
+ lda c ; No, so load the escape code back into the accumulator.
+ cmp #'B' ; Did the user press the down arrow key?
+ beq @down ; Yes, so move the cursor down.
+ bra @end ; No, so we're done.
+@down:
+ inc scr_row ; Move the cursor down a line.
+ jsr update_pos ; Update it's position.
+ lda #1 ; Tell the escape routine that we succeded.
+ sta d ;
+ rts ; We are done.
+@scroll:
+ lda scr_row ; Save the cursor's row number.
+ sta scr_trow ;
+ lda scr_col ; Save the cursor's column number.
+ sta scr_tcol ;
+ jsr scrl_down ; Scroll down.
+ lda scr_trow ; Load the cursor's row number.
+ sta scr_row ;
+ lda scr_tcol ; Load the cursor's column number.
+ sta scr_col ;
+ lda #1 ; Tell the escape routine that we were successful.
+ sta d ;
+@end:
+ rts ; End of isdown.
+
+
+isright:
+ lda c ; Load the escape code into the accumulator.
+ cmp #'C' ; Did the user press the right arrow key?
+ bne @end2 ; No, so we're done.
+ lda scr_col ; Yes, so start checking the x coordinate of the cursor.
+ cmp #maxcol ; Is the cursor at the far right of the screen?
+ beq @wrap ; Yes, so check if this is a wrapped line.
+ bra @right ; No, so move the cursor right, like normal.
+@wrap:
+ inc scr_row ; Move down a row.
+ jsr getbit ; Is the current line, a wrapped line?
+ bcs @incr ; Yes, so leave the cursor where it is.
+ dec scr_row ; No, so move the cursor back up a row.
+ bra @end2 ; We are done.
+@scroll:
+ lda scr_str ; Are we at the top of the screen buffer?
+ beq @end ; Yes, so we're done.
+ lda #1 ; No, so scroll down.
+ sta wrapped ; Set the wrapped flag.
+ jsr scrl_down ; Scroll down.
+ bra @end ; We are done.
+@incr:
+ lda #0 ; Set the cursor to the far left of the screen.
+ sta scr_col ;
+ lda scr_row ; Get the current row number.
+ cmp #maxrow ; Are we at the bottom of the screen?
+ beq @end1 ; No, so we're done.
+ bcs @scroll ; Yes, so check if we are scrolling down.
+ bra @end1 ; No, so we're done.
+@right:
+ inc scr_col ; Move the cursor right by one character.
+ jsr update_pos ; Update it's position.
+ rts ; End of isright.
+@end:
+ dec scr_row ; Move back up a row.
+@end1:
+ jsr update_pos ; Update the cursor position.
+@end2:
+ lda #0 ; Unset the wrapped flag.
+ sta wrapped ;
+ rts ; End of isright.
+
+
+isleft:
+ lda c ; Load the escape code into the accumulator.
+ cmp #'C' ; Did the user press right?
+ beq @end1 ; Yes, so we're done
+ lda scr_col ; No, but is the cursor at the far left of the screen?
+ beq @wrap ; Yes, so start checking if this is a wrapped line.
+ lda c ; No, so load the escape code back into the accumulator.
+ cmp #'D' ; Did the user press the left arrow key?
+ beq @left ; Yes, so move the cursor left.
+ bra @end1 ; No, so we're done.
+@wrap:
+ jsr getbit ; Is the current line, a wrapped line?
+ bcs @decr ; Yes, so wrap back up a line.
+ bra @end1 ; No, so we're done.
+@decr:
+ lda scr_row ; Is the cursor at the top of the screen?
+ beq @decr1 ; Yes, so don't move up a line.
+ lda #1 ; No, so set the wrapped flag.
+ sta wrapped ;
+ dec scr_row ; Move the cursor up one line.
+@decr1:
+ lda #maxcol ; Move the Cursor to the far right of the screen.
+ sta scr_col ;
+ lda #1 ; Tell the escape routine that we were successful.
+ sta d ;
+ lda scr_row ; Are we at the top of the screen?
+ beq @scroll ; Yes, so check if we need to scroll.
+ bra @end ; No, so we're done.
+@scroll:
+ lda wrapped ; Was the wrapped flag set somewhere else?
+ bne @end ; Yes so we're done.
+ lda scr_str ; No, but are we actually at the top of the screen buffer?
+ beq @end1 ; Yes, so we're done.
+ jsr scrl_up ; No, so scroll up.
+ bra @end1 ; We are done.
+@left:
+ dec scr_col ; Move the cursor left a character.
+ jsr update_pos ; Update it's position.
+ lda #1 ; Tell the escape routine that we succeded.
+ sta d ;
+ rts ; We are done
+@end:
+ jsr update_pos ; Update the cursor position.
+@end1:
+ lda #0 ; Unset the wrapped flag.
+ sta wrapped ;
+ rts ; End of isleft.
+
+
+isshftup:
+ lda c ; Load the escape code back into the accumulator.
+ cmp #'A' ; Did the user press the up arrow key?
+ bne @end ;
+ lda #1 ;
+ sta d ;
+ lda scr_str ;
+ beq @end ;
+@shftup:
+ jsr scrl_up ;
+ lda #1 ;
+ sta d ;
+@end:
+ rts ;
+
+
+isshftdown:
+ lda c ; Load the escape code back into the accumulator.
+ cmp #'B' ; Did the user press the down arrow key?
+ bne @end ;
+ lda #1 ;
+ sta d ;
+ lda scr_end ;
+ cmp #71 ;
+ bcs @end ;
+@shftdown:
+ jsr scrl_down ;
+ lda #1 ;
+ sta d ;
+@end:
+ rts ;
+
+
+update_pos:
+ ldb #1 ; Set the F pseudo register to one, to fix some bugs.
+ stb f ;
+ clc ; Clear the carry flag.
+ lda scr_row ; Add the cursor's line number,
+ adc scr_str ; with the starting line number to get the absolute line number.
+ tay ; Place it in the Y regster for now.
+ mul #maxcol+1 ; Multiply the line number by the screen's max column count, plus 1.
+ clc ; Clear the carry flag.
+ adc scr_col ; Add the cursor's column number to get the screen index.
+ tay ; Place the index into the Y register.
+ tba ; Reset A.
+ lda #$1B ; Print an escape character
+ sta scr ; to the screen.
+ lda #'[' ; Print '['
+ sta scr ; to the screen, and start the escape sequence.
+ jsr getrow ; Start printing the row number to the screen.
+ jsr getcol ; Start printing the column number to the screen.
+ lda #'H' ; Print 'H'
+ sta scr ; to the screen.
+ rts ; End of update_pos.
+
+getrow:
+ lda scr_row ; Get the cursor's y coordinate.
+ bra bcd ; Convert it to BCD.
+getcol:
+ lda #';' ; Print ';'
+ sta scr ; to the screen.
+ lda scr_col ; Get the cursor's x coordinate.
+bcd:
+ div #10 ; Divide A by 10.
+ ora #'0' ; Convert it to ascii, and
+ sta scr ; print to the screen.
+ tba ; Get the remainder.
+ ora #'0' ; Convert it to ascii, and
+ sta scr ; print to the screen.
+ rts ; End of bcd.
+
+scrl_down:
+ inc scr_str ; Increment the starting line of the screen.
+ inc scr_end ; Increment the ending line of the screen.
+ lda #$1B ; Print an escape character
+ sta scr ; to the screen.
+ lda #'[' ; Print '['
+ sta scr ; to the screen, and start the escape sequence.
+ lda #'T' ; Print 'T'
+ sta scr ; to the screen, and end the escape sequence.
+ lda scr_row ; Get the cursor's line number.
+ pha ; Save it in the stack.
+ lda wrapped ; Was the wrapped flag set?
+ beq @save ; Yes, so save the cursor position.
+@redraw:
+ jsr rdrw_row ; No, so redraw this row.
+ lda wrapped ; Was the wrapped flag set?
+ beq @load ; Yes, so load the previous cursor position back.
+ bra @end ; No, so we're done.
+@save:
+ lda scr_col ; Get the cursor's column number.
+ pha ; Save it in the stack.
+ bra @redraw ; Start redrawing the current row.
+@load:
+ pla ; Get the cursor's previous column number back.
+ sta scr_col ;
+@end:
+ pla ; Get the cursor's previous line number back.
+ sta scr_row ;
+ jsr update_pos ; Update the cursor's position.
+ lda #0 ; Clear the wrapped flag.
+ sta wrapped ;
+@end1:
+ rts ; End of scrl_down.
+
+scrl_up:
+ dec scr_str ;
+ dec scr_end ;
+ lda #$1B ; Print an escape character
+ sta scr ; to the screen.
+ lda #'[' ; Print '['
+ sta scr ; to the screen, and start the escape sequence.
+ lda #'S' ; Print 'S'
+ sta scr ; to the screen, and end the escape sequence.
+ lda scr_row ;
+ pha ;
+ lda scr_col ;
+ pha ;
+ lda #0 ;
+ sta scr_row ;
+ jsr rdrw_row ;
+ pla ;
+ sta scr_col ;
+ pla ;
+ sta scr_row ;
+ jsr update_pos ;
+@end:
+ rts ;
+
+rdrw_row:
+ lda #0 ;
+ sta scr_col ;
+ jsr update_pos ;
+@loop:
+ lda (ptr3), y ;
+ beq @incr ;
+ sta scr ;
+@incr:
+ inc scr_col ;
+ lda (ptr3), y ;
+ beq @skip ;
+@incr1:
+ iny ;
+@incr2:
+ lda scr_col ;
+ cmp #maxcol+1 ;
+ bcs @end ;
+ bra @loop ;
+@skip:
+ lda #' ' ;
+ sta scr ; to the screen.
+ bra @incr1 ;
+@end:
+ lda #0 ;
+ sta scr_col ;
+ jsr update_pos ;
+@end1:
+ rts ;
+
+rdrw_ln:
+ lda scr_row ;
+ pha ;
+ lda f ;
+ sta scr_row ;
+ lda scr_col ;
+ pha ;
+ jsr update_pos ;
+@loop:
+ lda scr_row ;
+ cmp e ;
+ beq @loop1 ;
+ bcs @end ;
+@loop1:
+ jsr rdrw_row ;
+@incr:
+ inc scr_row ;
+ bra @loop ;
+@end:
+ pla ;
+ sta scr_col ;
+ pla ;
+ sta scr_row ;
+ jsr update_pos ;
+ lda #0 ;
+ sta e ;
+ sta f ;
+ rts ;
+
+set_ptr:
+ cpb #1 ; Are we setting the second pointer?
+ beq @ptr2 ; Yes, so start setting it.
+ cpb #2 ; No, but are we setting the third pointer?
+ beq @ptr3 ; Yes, so start setting it.
+@ptr1:
+ stb.q ptr ; Reset the first pointer.
+ sta.q ptr ; No, so set the first pointer.
+ bra @end ; We are done.
+@ptr2:
+ stb.q ptr2 ; Reset the second pointer.
+ sta.q ptr2 ; Set the second pointer.
+ bra @end ; We are done.
+@ptr3:
+ stb.q ptr3 ; Reset the third pointer.
+ sta.q ptr3 ; Set the third pointer.
+@end:
+ rts ; End of set_ptr.
diff --git a/programs/sub-suite/tmp-stuff/test-size.s b/programs/sub-suite/tmp-stuff/test-size.s
new file mode 100644
index 0000000..b543a36
--- /dev/null
+++ b/programs/sub-suite/tmp-stuff/test-size.s
@@ -0,0 +1,59 @@
+MAGIC = $AA
+
+
+.org 0
+findramend:
+ and #0 ; Reset A.
+; lda #MAGIC ; Set A to a magic number.
+@loop:
+ mov a, (d) ; Preserve the value.
+ mov (d), #MAGIC ; Write the magic number to the current end of RAM.
+ cmp (d), #MAGIC ; Is the value in RAM, the same as the magic number we wrote?
+ bne @moveback ; No, so move back until we find the last writable memory location.
+ mov (d), a ; Yes, so restore the previous value.
+ add.w d, #$4000 ; Increment the end of RAM pointer by 16K.
+ bra @loop ; Keep looping.
+@moveback:
+ dec d ; Decrement the end of RAM pointer.
+ mov a, (d) ; Preserve the value.
+ mov (d), #MAGIC ; Write the magic number to the current end of RAM.
+ cmp (d), #MAGIC ; Is the value in RAM, the same as the magic number we wrote?
+ bne @moveback ; No, so keep looping.
+ mov (d), a ; Yes, so restore the previous value.
+@end:
+ mov a, d ; Return the end of RAM pointer.
+; ple.q ; Restore E.
+ rts ; End of findramend.
+
+
+;findramend:
+; phe.q ; Preserve E.
+; phb.q ; Preserve B.
+; mov e, d ; Set E to the RAM pointer.
+; and #0 ; Reset A.
+; lda #MAGIC ; Set A to a magic number.
+;@loop:
+; ldb (e) ; Preserve the value.
+; sta (e) ; Write the magic number to the current end of RAM.
+; cmp (e) ; Is the value in RAM, the same as the magic number we wrote?
+; bne @moveback ; No, so move back until we find the last writable memory location.
+; stb (e) ; Yes, so restore the previous value.
+; ade.w #$4000 ; Increment the end of RAM pointer by 16K.
+; bra @loop ; Keep looping.
+;@moveback:
+; dee ; Decrement the end of RAM pointer.
+; ldb (e) ; Preserve the value.
+; sta (e) ; Write the magic number to the current end of RAM.
+; cmp (e) ; Is the value in RAM, the same as the magic number we wrote?
+; bne @moveback ; No, so keep looping.
+; stb (e) ; Yes, so restore the previous value.
+;@end:
+; mov a, e ; Return the end of RAM pointer.
+; ple.q ; Restore E.
+; plb.q ; Restore B.
+; rts ; End of findramend.
+
+a
+.org findramend
+v
+q