summaryrefslogtreecommitdiff
path: root/programs/sub-suite
diff options
context:
space:
mode:
Diffstat (limited to 'programs/sub-suite')
-rw-r--r--programs/sub-suite/declare.s88
-rw-r--r--programs/sub-suite/lexer.s22
-rw-r--r--programs/sub-suite/libc.s355
-rw-r--r--programs/sub-suite/subasm.s2
-rw-r--r--programs/sub-suite/subeditor.s62
-rw-r--r--programs/sub-suite/subsuite.s2
-rw-r--r--programs/sub-suite/utils.s30
7 files changed, 491 insertions, 70 deletions
diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s
index 183d09d..6a8c90f 100644
--- a/programs/sub-suite/declare.s
+++ b/programs/sub-suite/declare.s
@@ -68,6 +68,19 @@
op .byte ; Base value used to get the actual opcode.
.endstruct
+; Free memory block struct, used by malloc.
+.struct fblk
+ size .qword ; Size of free memory block.
+ next .qword ; Pointer to next free block.
+ prev .qword ; Pointer to previous free block.
+.endstruct
+
+; Used memory block struct, used by malloc.
+.struct ublk
+ size .qword ; Size of used memory block.
+ start .qword ; Starting address of memory block.
+.endstruct
+
; Enums.
@@ -81,8 +94,17 @@ step = $110 ; Enables clock stepping, when set.
maxrow = 23 ; Screen's row count.
maxcol = 79 ; Screen's column count.
-MAX_SYM = $800 ; Max symbol size.
-OPNUM = 74 ; Instruction count.
+; Table sizes.
+SCRSIZE = $2000 ; Screen buffer size, in bytes.
+CMDSIZE = $400 ; Command buffer size, in bytes.
+LWSIZE = $1000 ; Linewrap table size, in bytes.
+
+; Magic number used by findramend.
+MAGIC = $AA
+
+; Heap related values.
+HEAPORG = $30000 ; Starting point of the heap.
+
; Directives.
DIR_ORG = 0 ; Origin.
@@ -164,23 +186,10 @@ IMPL = 1 << 10 ; Implied.
INDX2 = 1 << 11 ; Special case of INDX that uses the indirect table.
ZM2 = 1 << 12 ; Special case of Zero Matrix used by JMP, and JSR.
-
+OPNUM = 74 ; Instruction count.
; RAM declarations.
-; Linewrap table.
-.org $30000
-bitabl:
- .res $1000
-
-; Screen buffer.
-buffer:
- .res $2000
-
-; Command buffer.
-cmd_buf:
- .res $400
-
; Screen variables.
.org 0
scr_row:
@@ -238,10 +247,7 @@ ptr3:
.res 8
-; Token table.
.org $20000
-tokline:
- .res $400
; Program Counter.
prg_cnt:
@@ -327,14 +333,54 @@ lex_type:
lexeme:
.res $100
+; Size of the heap.
+heapsize:
+ .res 8
+
+; Start of the heap.
+heapstr:
+ .res 8
+
+; End of the heap.
+heapend:
+ .res 8
+
+; Current top of the heap.
+heapptr:
+ .res 8
+
+; First heap entry.
+heapf:
+ .res 8
+
+; Last heap entry.
+heapl:
+ .res 8
+
+; Linewrap table.
+bitabl:
+ .res 8
+
+; Screen buffer.
+buffer:
+ .res 8
+
+; Command buffer.
+cmd_buf:
+ .res 8
+
+; Token table.
+tokline:
+ .res 8
+
; Symbol table.
symbol:
- .res $8000
+ .res 8
; Fixup table.
; Fixups are unresolved symbols.
fixup:
- .res $2000
+ .res 8
; ROM data declarations.
diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s
index 50bf21e..fc47f10 100644
--- a/programs/sub-suite/lexer.s
+++ b/programs/sub-suite/lexer.s
@@ -17,16 +17,16 @@ lex:
; pha ; Preserve the character.
; jsr isdigit ; Is this character a digit?
; pla ; Get the character back.
-@getline:
- ldb #1 ; Set the second pointer
- lda.q lline ; to the last line.
- jsr set_ptr ;
- ldy #ln.next ; Set the index to the next line pointer.
- lda.q (ptr2), y ; Get the next line.
- jsr set_ptr ; Set the second pointer to the next line.
- sta.q cline ; Make it the current line.
- and #0 ; Reset A.
- tay ; Reset Y.
+;@getline:
+; ldb #1 ; Set the second pointer
+; lda.q lline ; to the last line.
+; jsr set_ptr ;
+; ldy #ln.next ; Set the index to the next line pointer.
+; lda.q (ptr2), y ; Get the next line.
+; jsr set_ptr ; Set the second pointer to the next line.
+; sta.q cline ; Make it the current line.
+; and #0 ; Reset A.
+; tay ; Reset Y.
@loop:
ldy.w idx0 ; Get the string index.
lda (ptr), y ; Get a character from the line.
@@ -396,7 +396,7 @@ set_lexptr:
set_cmdbuf:
and #0 ; Reset A.
tab ; Reset B.
- lda.d #cmd_buf ; to the command buffer.
+ lda.q cmd_buf ; Set the first pointer to the command buffer.
jsr set_ptr ;
and #0 ; Reset A.
tab ; Reset B.
diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s
index d13d983..18c10db 100644
--- a/programs/sub-suite/libc.s
+++ b/programs/sub-suite/libc.s
@@ -1,12 +1,12 @@
; Simple libc implementation for the SuB Suite
strtoull:
- phy.w ; Preserve Y.
+ phy.q ; Preserve Y.
and #0 ; Reset A.
tay ; Reset Y.
pha.q ; Reset the value buffer.
@loop:
- lda (sp+20), y ; Get a character from the string.
+ lda (sp+26), y ; Get a character from the string.
pha ; Preserve the character.
jsr isdigit ; Is this character, a digit?
pla ; Get the character back.
@@ -24,12 +24,12 @@ strtoull:
sec ; Prepare for a non borrowing subtract.
sbc #'0' ; Get the numeric value from this digit.
@chkbase:
- cmp sp+19 ; Does the value match the base?
+ cmp sp+25 ; Does the value match the base?
bcs @end ; No, so we're done.
@addval:
tab ; Save the digit value.
lda.q sp+1 ; Get the value from the value buffer.
- mul sp+19 ; Multiply the value by the base.
+ 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.
sta.q sp+1 ; Place the value in the value buffer.
@@ -38,42 +38,39 @@ strtoull:
bra @loop ; Keep looping.
@end:
pla.q ; Get the value buffer back.
- ply.w ; Get Y back.
+ ply.q ; Get Y back.
ldb #0 ; Reset B.
rts ; End of strtoull.
strlen:
+ phy.q ; Preserve Y.
pha.q ; Set the temp variable to the argument.
- ldb #0 ; Reset B.
- tba ; Reset A.
- tax ; Reset X.
- phy.w ; Preserve Y.
- txy ; Reset Y.
+ and #0 ; Reset A.
+ tay ; Reset Y.
@loop:
- lda (sp+3), y ; Are we at the end of the string?
+ 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.
@end:
- tyx ; Return the length in X.
- ply.w ; Get the preserved value back.
pla.q ; Get the argument back.
- txa ; Get the return value.
+ tya ; Get the return value.
+ ply.q ; Get the preserved value back.
rts ; End of strlen.
strcmp:
ldb #0 ; Reset B.
tba ; Reset A.
- phy.w ; Preserve Y.
+ phy.q ; Preserve Y.
tay ; Reset Y.
@loop:
ldb #0 ; Set the islong flag to false.
- lda (sp+19), y ; Are we at the end of the first string?
+ lda (sp+25), 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+11), y ; Is the character of both strings, the same?
+ cmp (sp+19), 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.
@@ -82,17 +79,17 @@ strccmp:
strcasecmp:
ldb #0 ; Reset B.
tba ; Reset A.
- phy.w ; Preserve Y.
+ phy.q ; Preserve Y.
tay ; Reset Y.
@loop:
ldb #0 ; Set the islong flag to false.
- lda (sp+19), y ; Are we at the end of the first string?
+ lda (sp+25), 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.
jsr tolower ; Convert the character of string 1 to lowercase.
phb ; Preserve the islong flag.
pha ; Preserve the converted character.
- lda (sp+13), y ; Get the character of the second string.
+ lda (sp+19), 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.
@@ -103,10 +100,10 @@ strcasecmp:
bra @loop ; Keep looping.
cmpr:
- lda (sp+11), y ; Are we at the end of the second string?
+ lda (sp+17), y ; Are we at the end of the second string?
beq @islong ; Yes, so check the islong flag.
@isshort:
- lda (sp+19), y ; No, but are we at the end of the first string?
+ 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?
@@ -120,7 +117,7 @@ cmpr:
@short:
lda #$FF ; Return -1.
@end:
- ply.w ; Get the preserved value back.
+ ply.q ; Get the preserved value back.
rts ; End of cmpr.
@@ -199,3 +196,315 @@ toupper:
and #$5F ; Yes, so convert it to uppercase.
@end:
rts ; End of toupper.
+
+
+; malloc: Dynamically allocate memory.
+; Input: A = size in bytes to allocate.
+; Output: A = Pointer to allocated memory.
+; Caller preserved registers: none.
+; Callie preserved registers: Y.
+
+malloc:
+ phy.q ; Preserve Y.
+ pha.q ; Preserve the size.
+ and #0 ; Reset A.
+ tay ; Reset Y.
+ pha.q ; Create two more local variables.
+ pha.q ;
+ 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.
+@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.
+@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 ;
+@outofspace:
+ 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.
+@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.
+@setheapf:
+ lda.q (sp+9), y ; Get the next block.
+ sta.q heapf ; Set the first heap entry to it.
+@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.
+@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.
+@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).
+@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.
+@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.
+@end:
+ ply.q ; Clean up the stack frame.
+ ply.q ;
+ ply.q ;
+ ply.q ; Restore Y.
+ rts ; End of malloc.
+
+
+; 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.
+ pha.q ; Add 3 more local variables.
+ pha.q ;
+ pha.q ;
+ 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:
+ pla.q ; Clean up the stack frame.
+ pla.q ;
+ pla.q ;
+ pla.q ;
+ 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:
+ pla.q ; Clean up the stack frame.
+ pla.q ;
+ pla.q ;
+ pla.q ;
+ ply.q ; Restore Y.
+ plb.q ; Restore B.
+ pla.q ; Restore A.
+ rts ; End of free.
diff --git a/programs/sub-suite/subasm.s b/programs/sub-suite/subasm.s
index 3957caa..0a3ee80 100644
--- a/programs/sub-suite/subasm.s
+++ b/programs/sub-suite/subasm.s
@@ -5,7 +5,7 @@
subasm:
ldb #0 ; Set the first pointer
- lda.d #cmd_buf ; to the command buffer.
+ lda.q cmd_buf ; to the command buffer.
jsr set_ptr ;
tba ; Reset A.
tax ; Reset X.
diff --git a/programs/sub-suite/subeditor.s b/programs/sub-suite/subeditor.s
index fdf1e4b..7e124a2 100644
--- a/programs/sub-suite/subeditor.s
+++ b/programs/sub-suite/subeditor.s
@@ -10,10 +10,44 @@ reset:
txs ;
ldy #0 ; Reset Y.
tyx ; Reset X.
+ jsr init_heap ; Initialize the heap.
+ jsr init_tables ; Initialize the main tables.
jsr clr_scr ; Clear the screen.
jsr pnt_strt ; Print the starting message.
bra start ; Goto the start of the main program.
+
+init_heap:
+ and #0 ; Reset A.
+ lda.d #HEAPORG ; Get the heap's starting point.
+ sta.q heapptr ;
+ phb.q ; Preserve the value in B.
+ phx.q ; Preserve the value in X.
+ jsr findramend ; Find the end of the heap.
+ plb.q ; Restore the value in B.
+ plx.q ; Restore the value in X.
+ sta.q heapend ; Save the end of the heap.
+ and #0 ; Reset A.
+ rts ; End of init_heap.
+
+
+init_tables:
+ and #0 ; Reset A.
+ lda.w #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.
+ jsr malloc ;
+ sta.q cmd_buf ;
+ and #0 ; Reset A.
+ lda.w #LWSIZE ; Allocate LWSIZE bytes of RAM for the linewrap table.
+ jsr malloc ;
+ sta.q bitabl ;
+ and #0 ; Reset A.
+ rts ; End of init_tables.
+
+
clr_arr:
phb ; Preserve whatever was in B.
ldb #0 ; Clear B.
@@ -67,9 +101,9 @@ pnt_strt:
clr_cmd:
and #0 ; Reset A.
tay ; Reset Y.
- lda.w #$3FF ; Set the clear count to $3FF.
+ lda.w #CMDSIZE ; Set the clear count to CMDSIZE.
sta.w scr_ptr ;
- lda.d #cmd_buf ; Set the array to be cleared to the command buffer.
+ lda.q cmd_buf ; Set the array to be cleared to the command buffer.
jsr clr_arr ; Clear the command buffer.
rts ; End of clr_cmd.
@@ -152,7 +186,7 @@ getbt0:
getbt1:
pha ; Save the parameter.
ldb #1 ; Make sure that set_ptr sets the second pointer.
- lda.d #bitabl ; Set the second pointer to the linewrap table.
+ 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.
@@ -168,7 +202,7 @@ getbt1:
clrbit:
pha ; Save the parameter.
ldb #1 ; Make sure that set_ptr sets the second pointer.
- lda.d #bitabl ; Set the second pointer to the linewrap table.
+ 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.
@@ -188,7 +222,7 @@ bitout:
setbit:
pha ; Save the parameter.
ldb #1 ; Make sure that set_ptr sets the second pointer.
- lda.d #bitabl ; Set the second pointer to the linewrap table.
+ 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.
@@ -283,10 +317,10 @@ cmd_cpy:
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.
+ lda.q buffer ; Set the first pointer to the start of the screen buffer.
jsr set_ptr ;
inb ; Make sure that set_ptr sets the second pointer.
- lda.d #cmd_buf ; Set the second pointer to the start of the command buffer.
+ lda.q cmd_buf ; Set the second pointer to the start of the command buffer.
jsr set_ptr ;
deb ; Set B back to zero.
tba ; Set the accumulator to zero.
@@ -344,7 +378,7 @@ findst:
fndend:
phb ; Save the contents of the B 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.
+ 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.
@@ -369,7 +403,7 @@ findend:
print_char:
sta rega ; 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.
+ lda.q buffer ; Set the third pointer to the start of the screen buffer.
jsr set_ptr ;
deb ; Set B to one.
tba ; Reset A.
@@ -504,12 +538,14 @@ clr_scr:
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.
+ lda.w #LWSIZE ; Set the clear count to LWSIZE.
+ sta.w scr_ptr ;
+ lda.q 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.
sta.w scr_ptr ;
- lda.d #buffer ; Set the array to be cleared to the screen buffer.
+ lda.q buffer ; Set the array to be cleared to the screen buffer.
jsr clr_arr ; Clear the screen buffer.
; tay ;
; lda.w #$3FF ; Set the clear count to $3FF.
diff --git a/programs/sub-suite/subsuite.s b/programs/sub-suite/subsuite.s
index d28b4f2..0cfad1e 100644
--- a/programs/sub-suite/subsuite.s
+++ b/programs/sub-suite/subsuite.s
@@ -17,7 +17,7 @@
.qword reset
a
;l a
-;.org reset
+;.org $8FA0
;v
;q
d
diff --git a/programs/sub-suite/utils.s b/programs/sub-suite/utils.s
index 7e7469c..21539eb 100644
--- a/programs/sub-suite/utils.s
+++ b/programs/sub-suite/utils.s
@@ -318,3 +318,33 @@ get_ctrlidx:
@del:
lda #2 ; Return 2.
rts ; End of get_ctrlidx.
+
+
+findramend:
+ pha.q ; Set the end of RAM pointer to the argument.
+ and #0 ; Reset A.
+ tab ; Reset B.
+ lda #MAGIC ; Set A to a magic number.
+@loop:
+ ldx (sp+1) ; Preserve the value.
+ sta (sp+1) ; Write the magic number to the current end of RAM.
+ cmp (sp+1) ; 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 (sp+1) ; Yes, so restore the previous value.
+ pha.q ; Preserve the magic number.
+ lda.q sp+9 ; Get the end of RAM pointer.
+ clc ; Prepare for a non carrying add.
+ adc.w #$4000 ; Increment the end of RAM pointer by 16K.
+ sta.q sp+9 ; Save the new end of RAM pointer.
+ pla.q ; Restore the magic number.
+ bra @loop ; Keep looping.
+@moveback:
+ dec.q sp+1 ; Decrement the end of RAM pointer.
+ ldx (sp+1) ; Preserve the value.
+ sta (sp+1) ; Write the magic number to the current end of RAM.
+ cmp (sp+1) ; Is the value in RAM, the same as the magic number we wrote?
+ bne @moveback ; No, so keep looping.
+ stx (sp+1) ; Yes, so restore the previous value.
+@end:
+ pla.q ; Restore the argument.
+ rts ; End of findramend.