make better use of the zero page

This commit is contained in:
~d6 2022-03-07 22:38:02 -05:00
parent 9d0ffdfb1d
commit 77bc06332a
1 changed files with 183 additions and 167 deletions

346
femto.tal
View File

@ -69,11 +69,72 @@
( zero page ) ( zero page )
|0000 |0000
@term [
&cols $2 ( zzz )
&rows $2 ( zzz )
&lmargin $2 ( zzz )
]
@config [
&tab-width $2 ( how many spaces to display tab chars )
&insert-tabs $1 ( tab key inserts tabs when true )
&color $2 ( digits of highlight color in reverse order )
]
@buffer [
&limit $2 ( last byte of actual data (not including \0) + 1 )
&offset $2 ( first byte of data visible in terminal )
&line-count $2 ( total number of lines in file )
&line-offset $2 ( first line of text visible in terminal )
]
( relative cursor positions, e.g. 0 to cols-1 )
@cursor [
&col $2 ( current column value 0-n (may exceed lenght of row) )
&row $2 ( current relative row value, 0-(height-1) )
]
@state [
&saw-esc $1 ( did we just see ESC? )
]
( prompt uses .tmp/pos and .tmp/data to track user input )
@prompt [
&active $1 ( is prompt currently active? )
&vector $2 ( what code to run when user responds )
&string $20 ( string to print for the prompt )
]
@tmp [
&pos $2 ( temporary pointer to address when reading data )
&data $40 ( small scratch pad when reading data )
]
( startup ) ( startup )
|0100 ;startup JMP2 |0100
;init-zero-page JSR2
;startup JMP2
( intialize zero page variables )
( )
( everything not specified starts as zero )
@init-zero-page ( -> )
#0050 .term/cols STZ2
#0018 .term/rows STZ2
#0006 .term/lmargin STZ2
#0004 .config/tab-width STZ2
#01 .config/insert-tabs STZ
#3333 .config/color STZ2
;data .buffer/offset STZ2
JMP2r
( code to run on startup ) ( code to run on startup )
@startup ;read-filename .Console/vector DEO2 BRK @startup
;filename .tmp/pos STZ2
;read-filename .Console/vector DEO2
BRK
( ERROR HANDLING ) ( ERROR HANDLING )
@ -93,93 +154,91 @@
@open-file ( filename* -> ) @open-file ( filename* -> )
.File/name DEO2 .File/name DEO2
#f000 .File/length DEO2 #f000 .File/length DEO2
;buffer/data .File/read DEO2 ;data .File/read DEO2
.File/success DEI2 #0000 GTH2 ,&ok JCN .File/success DEI2 #0000 GTH2 ,&ok JCN
;messages/input-error ;print JSR2 nl quit! ;messages/input-error ;print JSR2 nl quit!
( calculate buffer limit address using start + size ) ( calculate buffer limit address using start + size )
&ok .File/success DEI2 ;buffer/data ADD2 ;buffer/limit STA2 &ok .File/success DEI2 ;data ADD2 .buffer/limit STZ2
JMP2r JMP2r
@setup-terminal-size ( -> ) @setup-terminal-size ( -> )
( ;setup-80x24 JMP2 ) ( ;setup-80x24 JMP2 )
#03e7 #03e7 ;term-move-cursor JSR2 #03e7 #03e7 ;term-move-cursor JSR2
;term-get-cursor-position JSR2 ;term-get-cursor-position JSR2
;tmp/data ;tmp/pos STA2 ;tmp/data .tmp/pos STZ2
;receive-terminal-size .Console/vector DEO2 ;receive-terminal-size .Console/vector DEO2
JMP2r JMP2r
@receive-terminal-size ( -> ) @receive-terminal-size ( -> )
.Console/read DEI ;tmp/pos LDA2 STA .Console/read DEI .tmp/pos LDZ2 STA
;tmp/pos LDA2 INC2 ;tmp/pos STA2 .tmp/pos LDZ2 INC2 .tmp/pos STZ2
.Console/read DEI LIT 'R EQU ;parse-terminal-size JCN2 .Console/read DEI LIT 'R EQU ;parse-terminal-size JCN2
BRK BRK
@parse-terminal-size ( -> ) @parse-terminal-size ( -> )
LIT2r 0000 LIT2r 0000 LIT2r 0000 LIT2r 0000
;tmp/data LDAk #1b NEQ ,&parse-error JCN ( i ) INC2 .tmp/data LDZk #1b NEQ ,&parse-error JCN ( i ) INC
LDAk LIT '[ NEQ ,&parse-error JCN ( i ) INC2 LDZk LIT '[ NEQ ,&parse-error JCN ( i ) INC
&loop &loop
LDAk LIT '; EQU ,&parse-col JCN LDZk LIT '; EQU ,&parse-col JCN
LIT2r 000a MUL2r LIT2r 000a MUL2r
LDAk LIT '0 SUB #00 SWP STH2 ADD2r LDZk LIT '0 SUB #00 SWP STH2 ADD2r
INC2 ,&loop JMP INC ,&loop JMP
&parse-col &parse-col
INC2 STH2r #0002 SUB2 ;term/rows STA2 INC STH2r #0002 SUB2 .term/rows STZ2
&loop2 &loop2
LDAk LIT 'R EQU ,&done JCN LDZk LIT 'R EQU ,&done JCN
LIT2r 000a MUL2r LIT2r 000a MUL2r
LDAk LIT '0 SUB #00 SWP STH2 ADD2r LDZk LIT '0 SUB #00 SWP STH2 ADD2r
INC2 ,&loop2 JMP INC ,&loop2 JMP
&done &done
STH2r ;term/cols STA2 POP2 STH2r .term/cols STZ2 POP
;on-key .Console/vector DEO2 ;on-key .Console/vector DEO2
;draw-all JSR2 ;draw-all JSR2
BRK BRK
&parse-error POP2 ;tmp/data LDA2 &parse-error POP .tmp/data LDZ2
;term-size-parse-error ;error! JMP2 ;term-size-parse-error ;error! JMP2
@setup-linecount ( -> ) @setup-linecount ( -> )
;buffer/data LIT2r 0001 ;data LIT2r 0001
&loop DUP2 ;buffer/limit LDA2 EQU2 ,&done JCN &loop DUP2 .buffer/limit LDZ2 EQU2 ,&done JCN
LDAk #00 EQU ,&done JCN LDAk #00 EQU ,&done JCN
LDAk #0a NEQ JMP INC2r LDAk #0a NEQ JMP INC2r
INC2 ,&loop JMP INC2 ,&loop JMP
&done POP2 &done POP2
STH2r ;buffer/line-count STA2 STH2r .buffer/line-count STZ2
JMP2r JMP2r
@setup-80x24 ( -> ) @setup-80x24 ( -> )
#0050 ;term/cols STA2 #0050 .term/cols STZ2
#0014 ;term/rows STA2 #0014 .term/rows STZ2
;on-key .Console/vector DEO2 ;on-key .Console/vector DEO2
;draw-all JSR2 ;draw-all JSR2
JMP2r JMP2r
@read-filename ( -> ) @read-filename ( -> )
#12 DEI #0a EQU ,&execute JCN ( did we read \n ? ) #12 DEI #0a EQU ,&execute JCN ( did we read \n ? )
#12 DEI ;tmp/pos LDA2 STA ( no, so save in buffer ) #12 DEI .tmp/pos LDZ2 STA ( no, so save in buffer )
;tmp/pos LDA2 INC2 ;tmp/pos STA2 ( pos++ ) .tmp/pos LDZ2 INC2 .tmp/pos STZ2 ( pos++ )
BRK ( return ) BRK ( return )
&execute ( we saw a newline, so do something ) &execute ( we saw a newline, so do something )
#00 ;tmp/pos LDA2 STA ( null terminate str ) #00 .tmp/pos LDZ2 STA ( null terminate str )
;tmp/data ;tmp/pos STA2 ( reset pos )
;tmp/data ;filename ;str-copy JSR2 ( open file )
;filename ;open-file JSR2 ( open file ) ;filename ;open-file JSR2 ( open file )
;setup-linecount JSR2 ( determine # of lines ) ;setup-linecount JSR2 ( determine # of lines )
;setup-terminal-size JSR2 ( detect terminal dimensions ) ;setup-terminal-size JSR2 ( detect terminal dimensions )
BRK BRK
@bol ( -> ) @bol ( -> )
#0000 ;cursor/col STA2 #0000 .cursor/col STZ2
;draw-statusbar JSR2 ;draw-statusbar JSR2
;draw-cursor JSR2 BRK ;draw-cursor JSR2 BRK
( FIXME: handle long lines ) ( FIXME: handle long lines )
@eol ( -> ) @eol ( -> )
;cur-line JSR2 ;line-len JSR2 ;cursor/col STA2 ;cur-line JSR2 ;line-len JSR2 .cursor/col STZ2
;draw-statusbar JSR2 ;draw-statusbar JSR2
;draw-cursor JSR2 BRK ;draw-cursor JSR2 BRK
@ -187,10 +246,10 @@
@forward ( -> ) @forward ( -> )
;cur-pos JSR2 ;last-pos JSR2 GTH2 ,&skip JCN ;cur-pos JSR2 ;last-pos JSR2 GTH2 ,&skip JCN
;cur-col JSR2 ;cur-last JSR2 GTH2 ,&next-line JCN ;cur-col JSR2 ;cur-last JSR2 GTH2 ,&next-line JCN
;cur-col JSR2 INC2 ;cursor/col STA2 ;cur-col JSR2 INC2 .cursor/col STZ2
;draw-statusbar JSR2 ;draw-cursor JSR2 ;draw-statusbar JSR2 ;draw-cursor JSR2
,&skip JMP ,&skip JMP
&next-line #0000 ;cursor/col STA2 &next-line #0000 .cursor/col STZ2
;inc-row JSR2 ;inc-row JSR2
;ensure-visible-cursor JSR2 ;ensure-visible-cursor JSR2
;draw-cursor JSR2 ;draw-cursor JSR2
@ -199,7 +258,7 @@
( FIXME: handle long lines ) ( FIXME: handle long lines )
@back ( -> ) @back ( -> )
;cur-col JSR2 #01 LTH ,&skip JCN ;cur-col JSR2 #01 LTH ,&skip JCN
;cur-col JSR2 #0001 SUB2 ;cursor/col STA2 ;cur-col JSR2 #0001 SUB2 .cursor/col STZ2
;draw-statusbar JSR2 ;draw-statusbar JSR2
;draw-cursor JSR2 ;draw-cursor JSR2
&skip BRK &skip BRK
@ -226,33 +285,33 @@
@page-up ( -> ) @page-up ( -> )
;bof-is-visible JSR2 ,&at-bof JCN ;bof-is-visible JSR2 ,&at-bof JCN
;buffer/line-offset LDA2 .buffer/line-offset LDZ2
;term/rows LDA2 #0003 SUB2 .term/rows LDZ2 #0003 SUB2
LTH2k ,&near-bof JCN LTH2k ,&near-bof JCN
SUB2 DUP2 ;abs-line JSR2 ;buffer/offset STA2 SUB2 DUP2 ;abs-line JSR2 .buffer/offset STZ2
;buffer/line-offset STA2 .buffer/line-offset STZ2
;ensure-visible-cursor JSR2 ;ensure-visible-cursor JSR2
;draw-all JSR2 BRK ;draw-all JSR2 BRK
&near-bof POP2 POP2 &near-bof POP2 POP2
;zero-row JSR2 ;zero-row JSR2
#0000 ;cursor/col STA2 #0000 .cursor/col STZ2
;draw-all JSR2 BRK ;draw-all JSR2 BRK
&at-bof &at-bof
;zero-row JSR2 ;zero-row JSR2
#0000 ;cursor/col STA2 #0000 .cursor/col STZ2
;draw-cursor JSR2 BRK ;draw-cursor JSR2 BRK
@page-down @page-down
;eof-is-visible JSR2 ,&near-eof JCN ;eof-is-visible JSR2 ,&near-eof JCN
;buffer/line-offset LDA2 .buffer/line-offset LDZ2
;term/rows LDA2 ADD2 #0003 SUB2 .term/rows LDZ2 ADD2 #0003 SUB2
DUP2 ;abs-line JSR2 ;buffer/offset STA2 DUP2 ;abs-line JSR2 .buffer/offset STZ2
;buffer/line-offset STA2 .buffer/line-offset STZ2
;ensure-visible-cursor JSR2 ;ensure-visible-cursor JSR2
;draw-all JSR2 BRK ;draw-all JSR2 BRK
&near-eof &near-eof
;buffer/line-count LDA2 #0001 SUB2 ;set-abs-row JSR2 .buffer/line-count LDZ2 #0001 SUB2 ;set-abs-row JSR2
;cur-len JSR2 ;cursor/col STA2 ;cur-len JSR2 .cursor/col STZ2
;draw-cursor JSR2 BRK ;draw-cursor JSR2 BRK
@quit quit! @quit quit!
@ -261,19 +320,19 @@
@insert ( c^ -> ) @insert ( c^ -> )
;cur-pos JSR2 ;shift-right JSR2 ;cur-pos JSR2 ;shift-right JSR2
;cur-col JSR2 INC2 ;cursor/col STA2 ;cur-col JSR2 INC2 .cursor/col STZ2
;draw-all JSR2 ;draw-all JSR2
BRK BRK
@insert-tab ( -> ) @insert-tab ( -> )
;config/insert-tabs LDA ,&use-tabs JCN .config/insert-tabs LDZ ,&use-tabs JCN
#0000 ;config/tab-width LDA2 SUB2 #0000 .config/tab-width LDZ2 SUB2
&loop &loop
DUP2 #0000 EQU2 ,&done JCN DUP2 #0000 EQU2 ,&done JCN
#20 ;cur-pos JSR2 ;shift-right JSR2 #20 ;cur-pos JSR2 ;shift-right JSR2
INC2 ,&loop JMP INC2 ,&loop JMP
&done &done
;cur-col JSR2 ;config/tab-width LDA2 ADD2 ;cursor/col STA2 ;cur-col JSR2 .config/tab-width LDZ2 ADD2 .cursor/col STZ2
;draw-all JSR2 BRK ;draw-all JSR2 BRK
&use-tabs &use-tabs
#09 ;insert JMP2 #09 ;insert JMP2
@ -281,37 +340,37 @@
( TODO: handle last line ) ( TODO: handle last line )
@newline ( c^ -> ) @newline ( c^ -> )
#0a ;cur-pos JSR2 ;shift-right JSR2 #0a ;cur-pos JSR2 ;shift-right JSR2
#0000 ;cursor/col STA2 #0000 .cursor/col STZ2
;inc-row JSR2 ;inc-row JSR2
;buffer/line-count LDA2k INC2 SWP2 STA2 .buffer/line-count LDZ2k INC2 SWP2 STA2
;ensure-visible-cursor JSR2 ;ensure-visible-cursor JSR2
;draw-all JSR2 ;draw-all JSR2
BRK BRK
@at-buffer-start ( -> bool^ ) @at-buffer-start ( -> bool^ )
;cur-pos JSR2 ;buffer/data EQU2 JMP2r ;cur-pos JSR2 ;data EQU2 JMP2r
@at-line-start ( -> bool^ ) @at-line-start ( -> bool^ )
;cursor/col LDA2 #0000 EQU2 JMP2r .cursor/col LDZ2 #0000 EQU2 JMP2r
@bof-is-visible ( -> bool^ ) @bof-is-visible ( -> bool^ )
;buffer/line-offset LDA2 #0000 EQU2 JMP2r .buffer/line-offset LDZ2 #0000 EQU2 JMP2r
@eof-is-visible ( -> bool^ ) @eof-is-visible ( -> bool^ )
;buffer/line-offset LDA2 ;term/rows LDA2 ADD2 INC2 .buffer/line-offset LDZ2 .term/rows LDZ2 ADD2 INC2
;buffer/line-count LDA2 .buffer/line-count LDZ2
GTH2 JMP2r GTH2 JMP2r
@backspace ( -> ) @backspace ( -> )
;at-buffer-start JSR2 ,&skip JCN ;at-buffer-start JSR2 ,&skip JCN
;at-line-start JSR2 ,&prev-line JCN ;at-line-start JSR2 ,&prev-line JCN
;cur-col JSR2 #0001 SUB2 ;cursor/col STA2 ;cur-col JSR2 #0001 SUB2 .cursor/col STZ2
,&finish JMP ,&finish JMP
&prev-line &prev-line
;cur-abs-row JSR2 #0001 SUB2 ;cur-abs-row JSR2 #0001 SUB2
;jump-to-line JSR2 ( TODO: fix weird eof behavior ) ;jump-to-line JSR2 ( TODO: fix weird eof behavior )
;cur-len JSR2 ;cursor/col STA2 ;cur-len JSR2 .cursor/col STZ2
;buffer/line-count LDA2k #0001 SUB2 SWP2 STA2 .buffer/line-count LDZ2k #0001 SUB2 SWP2 STA2
&finish &finish
;cur-pos JSR2 ;shift-left JSR2 ;cur-pos JSR2 ;shift-left JSR2
;draw-all JSR2 ;draw-all JSR2
@ -323,29 +382,29 @@
;cur-pos JSR2 LDAk STH ( cur [c] ) ;cur-pos JSR2 LDAk STH ( cur [c] )
;shift-left JSR2 ( [c] ) ;shift-left JSR2 ( [c] )
STHr #0a NEQ ,&not-newline JCN STHr #0a NEQ ,&not-newline JCN
;buffer/line-count LDA2k #0001 SUB2 SWP2 STA2 .buffer/line-count LDZ2k #0001 SUB2 SWP2 STA2
&not-newline ;draw-all JSR2 &not-newline ;draw-all JSR2
&skip BRK &skip BRK
@escape ( -> ) @escape ( -> )
#01 ;saw-esc STA BRK #01 .state/saw-esc STZ BRK
@goto-end ( -> ) @goto-end ( -> )
;more-than-one-screen JSR2 ,&large JCN ;more-than-one-screen JSR2 ,&large JCN
;buffer/line-count LDA2 #0001 SUB2 ;cursor/row STA2 .buffer/line-count LDZ2 #0001 SUB2 .cursor/row STZ2
#0000 ,&continue JMP #0000 ,&continue JMP
&large &large
;term/rows LDA2 #0001 SUB2 ;cursor/row STA2 .term/rows LDZ2 #0001 SUB2 .cursor/row STZ2
;buffer/line-count LDA2 ;term/rows LDA2 SUB2 .buffer/line-count LDZ2 .term/rows LDZ2 SUB2
&continue &continue
DUP2 ;buffer/line-offset STA2 DUP2 .buffer/line-offset STZ2
;abs-line JSR2 ;buffer/offset STA2 ;abs-line JSR2 .buffer/offset STZ2
;cur-len JSR2 ;cursor/col STA2 ;cur-len JSR2 .cursor/col STZ2
;draw-all JSR2 BRK ;draw-all JSR2 BRK
@goto-start ( -> ) @goto-start ( -> )
;zero-row JSR2 ;zero-row JSR2
#0000 ;cursor/col STA2 #0000 .cursor/col STZ2
;draw-all JSR2 ;draw-all JSR2
BRK BRK
@ -354,10 +413,10 @@
;draw-all JSR2 BRK ;draw-all JSR2 BRK
@jump-to-line ( n* -> ) @jump-to-line ( n* -> )
;term/rows LDA2 #0002 DIV2 LTH2k ( n rows/2 n<rows/2? ) ,&early JCN .term/rows LDZ2 #0002 DIV2 LTH2k ( n rows/2 n<rows/2? ) ,&early JCN
OVR2 SWP2 SUB2 ( n n-rows/2 ) OVR2 SWP2 SUB2 ( n n-rows/2 )
;buffer/line-count LDA2 ( n n-rows/2 lines ) .buffer/line-count LDZ2 ( n n-rows/2 lines )
;term/rows LDA2 SUB2 ( n n-rows/2 lines-rows ) .term/rows LDZ2 SUB2 ( n n-rows/2 lines-rows )
GTH2k ( n n-rows/2 lines-rows n-rows/2>lines-rows? ) GTH2k ( n n-rows/2 lines-rows n-rows/2>lines-rows? )
,&late JCN ( n n-rows/2 lines-rows ) ,&late JCN ( n n-rows/2 lines-rows )
POP2 ,&finish JMP POP2 ,&finish JMP
@ -367,14 +426,14 @@
NIP2 NIP2
&finish ( n o ) &finish ( n o )
SUB2k STH2 DUP2 ( n o o [n-o] ) SUB2k STH2 DUP2 ( n o o [n-o] )
;buffer/line-offset STA2 ( n o [n-o] ) .buffer/line-offset STZ2 ( n o [n-o] )
;abs-line JSR2 ;buffer/offset STA2 ( n [n-o] ) ;abs-line JSR2 .buffer/offset STZ2 ( n [n-o] )
#0000 ;cursor/col STA2 ( n [n-o] ) #0000 .cursor/col STZ2 ( n [n-o] )
POP2 STH2r ;cursor/row STA2 POP2 STH2r .cursor/row STZ2
JMP2r JMP2r
@ensure-visible-cursor @ensure-visible-cursor
;cur-rel-row JSR2 ;term/rows LDA2 LTH2 ,&noop JCN ;cur-rel-row JSR2 .term/rows LDZ2 LTH2 ,&noop JCN
;cur-abs-row JSR2 ;jump-to-line JSR2 ;cur-abs-row JSR2 ;jump-to-line JSR2
;draw-all JSR2 ;draw-all JSR2
&noop JMP2r &noop JMP2r
@ -389,7 +448,7 @@
( M-n and M-p for next/previous paragraph ) ( M-n and M-p for next/previous paragraph )
( maybe M-% for search&replace ) ( maybe M-% for search&replace )
@on-key-escaped ( -> ) @on-key-escaped ( -> )
#00 ;saw-esc STA #00 .state/saw-esc STZ
.Console/read DEI LIT '< EQU ( M-< ) ;goto-start JCN2 .Console/read DEI LIT '< EQU ( M-< ) ;goto-start JCN2
.Console/read DEI LIT '> EQU ( M-> ) ;goto-end JCN2 .Console/read DEI LIT '> EQU ( M-> ) ;goto-end JCN2
.Console/read DEI LIT 'g EQU ( M-g ) ;goto-line JCN2 .Console/read DEI LIT 'g EQU ( M-g ) ;goto-line JCN2
@ -397,14 +456,14 @@
BRK BRK
@move-to-message-line ( -> ) @move-to-message-line ( -> )
#0002 ;term/rows LDA2 #0002 ADD2 ;term-move-cursor JMP2 #0002 .term/rows LDZ2 #0002 ADD2 ;term-move-cursor JMP2
( TODO: filename prmopt ) ( TODO: filename prmopt )
@save ( -> ) @save ( -> )
;buffer/limit LDA2 ;buffer/data SUB2 STH2 ( [size] ) .buffer/limit LDZ2 ;data SUB2 STH2 ( [size] )
;tmp-file-name .File/name DEO2 ;tmp-file-name .File/name DEO2
STH2kr .File/length DEO2 STH2kr .File/length DEO2
;buffer/data .File/write DEO2 ;data .File/write DEO2
;move-to-message-line JSR2 ;move-to-message-line JSR2
.File/success DEI2 STH2r EQU2 ( ok? ) ,&ok JCN .File/success DEI2 STH2r EQU2 ( ok? ) ,&ok JCN
@ -418,7 +477,7 @@
( TODO: C-s for search ) ( TODO: C-s for search )
( TODO: tab input? ) ( TODO: tab input? )
@on-key @on-key
;saw-esc LDA ;on-key-escaped JCN2 .state/saw-esc LDZ ;on-key-escaped JCN2
.Console/read DEI #01 EQU ( C-a ) ;bol JCN2 .Console/read DEI #01 EQU ( C-a ) ;bol JCN2
.Console/read DEI #02 EQU ( C-b ) ;back JCN2 .Console/read DEI #02 EQU ( C-b ) ;back JCN2
.Console/read DEI #04 EQU ( C-d ) ;delete JCN2 .Console/read DEI #04 EQU ( C-d ) ;delete JCN2
@ -461,28 +520,28 @@
ansi LIT '2 emit LIT 'J emit JMP2r ansi LIT '2 emit LIT 'J emit JMP2r
@draw-cursor ( -> ) @draw-cursor ( -> )
;cur-w-col JSR2 ;term/lmargin LDA2 ADD2 ;cur-w-col JSR2 .term/lmargin LDZ2 ADD2
;cur-rel-row JSR2 ;cur-rel-row JSR2
;term-move-cursor JMP2 ;term-move-cursor JMP2
@draw-statusbar ( -> ) @draw-statusbar ( -> )
#0000 ;term/rows LDA2 ;term-move-cursor JSR2 #0000 .term/rows LDZ2 ;term-move-cursor JSR2
;emit-color-reverse JSR2 ;emit-color-reverse JSR2
LIT2r 2018 LIT2r 2018
;term/cols LDA2 #0000 .term/cols LDZ2 #0000
&loop GTH2k ,&continue JCN ,&done JMP &loop GTH2k ,&continue JCN ,&done JMP
&continue DEOkr INC2 ,&loop JMP &continue DEOkr INC2 ,&loop JMP
&done POP2 POP2 POP2r &done POP2 POP2 POP2r
#0000 ;term/rows LDA2 ;term-move-cursor JSR2 #0000 .term/rows LDZ2 ;term-move-cursor JSR2
;messages/saved ;print JSR2 ;messages/saved ;print JSR2
;filename ;print JSR2 ;filename ;print JSR2
#20 emit #20 emit
LIT '[ emit LIT '[ emit
;buffer/limit LDA2 ;buffer/data SUB2 ;emit-dec2 JSR2 .buffer/limit LDZ2 ;data SUB2 ;emit-dec2 JSR2
;messages/bytes ;print JSR2 ;messages/bytes ;print JSR2
#20 emit #20 emit
;buffer/line-count LDA2 ;emit-dec2 JSR2 .buffer/line-count LDZ2 ;emit-dec2 JSR2
;messages/lines ;print JSR2 ;messages/lines ;print JSR2
#20 emit #20 emit
LIT '( emit LIT '( emit
@ -496,12 +555,12 @@
@draw-linenum ( n* -> ) @draw-linenum ( n* -> )
;emit-reset JSR2 ;emit-reset JSR2
ansi ;config/color LDA2 emit emit LIT 'm emit ansi .config/color LDZ2 emit emit LIT 'm emit
;emit-dec2-pad JSR2 ;emit-dec2-pad JSR2
ansi LIT2 'm '0 emit emit JMP2r ansi LIT2 'm '0 emit emit JMP2r
@emit-tab ( -> ) @emit-tab ( -> )
#0000 ;config/tab-width LDA2 SUB2 #0000 .config/tab-width LDZ2 SUB2
LIT2r 2018 LIT2r 2018
&loop ORAk ,&next JCN POP2 POP2r JMP2r &loop ORAk ,&next JCN POP2 POP2r JMP2r
&next DEOkr INC2 ,&loop JMP &next DEOkr INC2 ,&loop JMP
@ -516,23 +575,23 @@
;emit-red JSR2 LIT '$ emit ;emit-reset JMP2 ;emit-red JSR2 LIT '$ emit ;emit-reset JMP2
@emit-color-reverse ( -> ) @emit-color-reverse ( -> )
ansi ;config/color LDA2 emit emit LIT2 '7 '; emit emit LIT 'm emit JMP2r ansi .config/color LDZ2 emit emit LIT2 '7 '; emit emit LIT 'm emit JMP2r
@draw-all ( -> ) @draw-all ( -> )
;term-erase-all JSR2 ;term-erase-all JSR2
#0000 #0000 ;term-move-cursor JSR2 #0000 #0000 ;term-move-cursor JSR2
;buffer/line-offset LDA2 STH2 LIT2r 0001 ( [k line-offset] ) .buffer/line-offset LDZ2 STH2 LIT2r 0001 ( [k line-offset] )
;buffer/offset LDA2 .buffer/offset LDZ2
&bol &bol
ADD2kr STH2r ;draw-linenum JSR2 ADD2kr STH2r ;draw-linenum JSR2
;term/lmargin LDA2 INC2 ,&x STR2 .term/lmargin LDZ2 INC2 ,&x STR2
( TODO: use this for cursor-line highlighting and long line support ) ( TODO: use this for cursor-line highlighting and long line support )
( STH2kr ;cursor/row LDA2 INC2 NEQ2 ,&loop JCN ( STH2kr .cursor/row LDZ2 INC2 NEQ2 ,&loop JCN
;emit-color-reverse JSR2 ) ;emit-color-reverse JSR2 )
&loop ( offset [k line-offset] ) &loop ( offset [k line-offset] )
LDAk #00 EQU ,&eof JCN LDAk #00 EQU ,&eof JCN
LDAk #0a EQU ,&eol JCN LDAk #0a EQU ,&eol JCN
,&x LDR2 ;term/cols LDA2 ,&x LDR2 .term/cols LDZ2
LTH2k ,&ok JCN LTH2k ,&ok JCN
GTH2 ,&skip JCN GTH2 ,&skip JCN
;emit-red-dollar JSR2 ,&x LDR2 INC2 ,&x STR2 ;emit-red-dollar JSR2 ,&x LDR2 INC2 ,&x STR2
@ -543,18 +602,18 @@
LDAk emit INC2 ,&x LDR2 INC2 ,&x STR2 LDAk emit INC2 ,&x LDR2 INC2 ,&x STR2
,&loop JMP ,&loop JMP
&eol INC2r &eol INC2r
STH2kr ;term/rows LDA2 GTH2 ,&done JCN STH2kr .term/rows LDZ2 GTH2 ,&done JCN
cr nl INC2 ,&bol JMP cr nl INC2 ,&bol JMP
&do-tab ;emit-tab JSR2 INC2 &do-tab ;emit-tab JSR2 INC2
;config/tab-width LDA2 ,&x LDR2 ADD2 ,&x STR2 .config/tab-width LDZ2 ,&x LDR2 ADD2 ,&x STR2
,&loop JMP ,&loop JMP
[ &x $2 ] [ &x $2 ]
&eof &eof
;emit-red JSR2 ;emit-red JSR2
&eof-loop &eof-loop
STH2kr ;term/rows LDA2 GTH2 ,&done JCN STH2kr .term/rows LDZ2 GTH2 ,&done JCN
cr nl cr nl
;term/lmargin LDA2 ;term-move-right JSR2 .term/lmargin LDZ2 ;term-move-right JSR2
LIT '~ emit INC2r LIT '~ emit INC2r
,&eof-loop JMP ,&eof-loop JMP
&done POP2 POP2r POP2r &done POP2 POP2r POP2r
@ -606,7 +665,7 @@
@abs-line ( y* -> s* ) @abs-line ( y* -> s* )
#0000 SWP2 SUB2 STH2 ( [-y] ) #0000 SWP2 SUB2 STH2 ( [-y] )
;buffer/data ( addr ) ;data ( addr )
&newline ( addr [-y] ) &newline ( addr [-y] )
STH2kr ORA ,&loop JCN ,&done JMP STH2kr ORA ,&loop JCN ,&done JMP
&loop ( addr [-y] ) &loop ( addr [-y] )
@ -620,7 +679,7 @@
( line number relative to the offset, starting at 0 ) ( line number relative to the offset, starting at 0 )
@rel-line ( y* -> s* ) @rel-line ( y* -> s* )
#0000 SWP2 SUB2 STH2 ( [-y] ) #0000 SWP2 SUB2 STH2 ( [-y] )
;buffer/offset LDA2 ( addr* ) .buffer/offset LDZ2 ( addr* )
STH2kr #0000 EQU2 ,&done JCN ( addr [-y] ) STH2kr #0000 EQU2 ,&done JCN ( addr [-y] )
&newline ( addr [-y] ) &newline ( addr [-y] )
STH2kr ORA ,&loop JCN ,&done JMP STH2kr ORA ,&loop JCN ,&done JMP
@ -639,10 +698,10 @@
;cur-line JSR2 ;cur-col JSR2 ADD2 JMP2r ;cur-line JSR2 ;cur-col JSR2 ADD2 JMP2r
@cur-abs-row ( -> n* ) @cur-abs-row ( -> n* )
;cur-rel-row JSR2 ;buffer/line-offset LDA2 ADD2 JMP2r ;cur-rel-row JSR2 .buffer/line-offset LDZ2 ADD2 JMP2r
@last-abs-row ( -> n* ) @last-abs-row ( -> n* )
;buffer/line-count LDA2 #0001 SUB2 JMP2r .buffer/line-count LDZ2 #0001 SUB2 JMP2r
@shift-right ( c^ addr* -> ) @shift-right ( c^ addr* -> )
ROT STH ( addr [prev^] ) ROT STH ( addr [prev^] )
@ -655,7 +714,7 @@
&done NIP2 DUP2 ( addr addr [prev^] ) &done NIP2 DUP2 ( addr addr [prev^] )
STHr ROT ROT ( addr prev^ addr ) STHr ROT ROT ( addr prev^ addr )
STA INC2 ( addr+1 ) STA INC2 ( addr+1 )
;buffer/limit STA2 ( ) .buffer/limit STZ2 ( )
JMP2r JMP2r
( TODO: change last/addr order and GTH -> LTH to remove hack ) ( TODO: change last/addr order and GTH -> LTH to remove hack )
@ -668,12 +727,12 @@
ROT ROT ( last addr+1 c1^ addr ) ROT ROT ( last addr+1 c1^ addr )
STA ,&loop JMP ( last addr+1 ) STA ,&loop JMP ( last addr+1 )
&done POP2 ( last ) &done POP2 ( last )
;buffer/limit STA2 ( ) .buffer/limit STZ2 ( )
#00 ;buffer/limit LDA2 STA ( ensure null termination ) #00 .buffer/limit LDZ2 STA ( ensure null termination )
JMP2r JMP2r
@cur-col ( -> col* ) @cur-col ( -> col* )
;cursor/col LDA2 ;cur-len JSR2 ;min2 JMP2 .cursor/col LDZ2 ;cur-len JSR2 ;min2 JMP2
@cur-w-col ( -> col* ) @cur-w-col ( -> col* )
LIT2r 0000 ( [0] ) LIT2r 0000 ( [0] )
@ -681,37 +740,37 @@
&loop GTH2k ,&next JCN &loop GTH2k ,&next JCN
POP2 POP2 STH2r JMP2r POP2 POP2 STH2r JMP2r
&next LDAk #09 EQU ,&tabs JCN INC2 INC2r ,&loop JMP &next LDAk #09 EQU ,&tabs JCN INC2 INC2r ,&loop JMP
&tabs INC2 ;config/tab-width LDA2 STH2 ADD2r ,&loop JMP &tabs INC2 .config/tab-width LDZ2 STH2 ADD2r ,&loop JMP
@cur-rel-row ( -> row* ) @cur-rel-row ( -> row* )
;cursor/row LDA2 JMP2r .cursor/row LDZ2 JMP2r
@set-abs-row ( n* -> ) @set-abs-row ( n* -> )
;buffer/line-offset LDA2 SUB2 ;cursor/row STA2 JMP2r .buffer/line-offset LDZ2 SUB2 .cursor/row STZ2 JMP2r
@set-rel-row ( n* -> ) @set-rel-row ( n* -> )
;cursor/row STA2 JMP2r .cursor/row STZ2 JMP2r
@zero-row ( -> ) @zero-row ( -> )
;buffer/data ;buffer/offset STA2 ;data .buffer/offset STZ2
#0000 ;buffer/line-offset STA2 #0000 .buffer/line-offset STZ2
#0000 ;cursor/row STA2 #0000 .cursor/row STZ2
JMP2r JMP2r
@inc-row ( -> ) @inc-row ( -> )
;cursor/row LDA2k INC2 SWP2 STA2 JMP2r .cursor/row LDZ2k INC2 SWP2 STA2 JMP2r
@dec-row ( -> ) @dec-row ( -> )
;cursor/row LDA2k #0001 SUB2 SWP2 STA2 .cursor/row LDZ2k #0001 SUB2 SWP2 STA2
@last-pos ( -> addr* ) @last-pos ( -> addr* )
;buffer/limit LDA2 #0001 SUB2 JMP2r .buffer/limit LDZ2 #0001 SUB2 JMP2r
@more-than-one-screen ( -> bool^ ) @more-than-one-screen ( -> bool^ )
;buffer/line-count LDA2 ;term/rows LDA2 GTH2 JMP2r .buffer/line-count LDZ2 .term/rows LDZ2 GTH2 JMP2r
@fits-in-one-screen ( -> bool^ ) @fits-in-one-screen ( -> bool^ )
;buffer/line-count LDA2 ;term/rows LDA2 INC2 LTH2 JMP2r .buffer/line-count LDZ2 .term/rows LDZ2 INC2 LTH2 JMP2r
@mod-div ( x^ y^ -> x%d x/y ) @mod-div ( x^ y^ -> x%d x/y )
DIVk STHk MUL SUB STHr JMP2r DIVk STHk MUL SUB STHr JMP2r
@ -765,6 +824,7 @@
&do1 NIP ;emit-digit JSR2 &do1 NIP ;emit-digit JSR2
DEOr JMP2r DEOr JMP2r
( various string constants used as messages for the user )
@messages [ &input-error "input 20 "error 00 @messages [ &input-error "input 20 "error 00
&bytes 20 "bytes, 00 &bytes 20 "bytes, 00
&save-ok "saved 00 &save-ok "saved 00
@ -773,50 +833,6 @@
&saved "-- 20 00 &saved "-- 20 00
&unsaved "** 20 00 ] &unsaved "** 20 00 ]
@tmp [ &pos :tmp/data @filename $80 ( path to file being edited )
&data $100 ]
@term [ &cols 0050 @data $f000 ( actual file data to be edited )
&rows 0018
&lmargin 0006 ]
@prompt [ &vector $2
&string $40 ]
( COLORS )
( )
( SHORT STRING NAME )
( 3033 "30" black )
( 3133 "31" red )
( 3233 "32" green )
( 3333 "33" yellow )
( 3433 "34" blue )
( 3533 "35" magenta )
( 3633 "36" cyan )
( 3733 "37" white )
( 3030 "00" default )
( )
( digits are reversed )
( to emit from stack in )
( last-in-first-out order )
@config [ &tab-width 0004
&insert-tabs 01
&color 3333 ]
( relative cursor positions, e.g. 0 to cols-1 )
@cursor [ &col 0000 &row 0000 ]
( did we just see ESC? )
@saw-esc 00
( )
@filename $80
( |1ffc )
( offset is address of the first visible line )
( size is total size of data in bytes )
@buffer [ &limit 0000
&offset :buffer/data
&line-count 0000
&line-offset 0000
&data $f000 ]