Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
7dc1b62b7b
10
femto.tal
10
femto.tal
|
@ -22,10 +22,10 @@
|
|||
%cr { #0d18 DEO }
|
||||
%crlf { cr nl }
|
||||
%ansi { #1b18 DEO #5b18 DEO }
|
||||
%alternate-buffer-on { ( \e[?1049h )
|
||||
ansi #3f18 DEO #3118 DEO #3018 DEO #3418 DEO #3918 DEO #6818 DEO }
|
||||
%alternate-buffer-off { ( \e[?1049l )
|
||||
ansi #3f18 DEO #3118 DEO #3018 DEO #3418 DEO #3918 DEO #6c18 DEO }
|
||||
( \e[?1049h )
|
||||
%alternate-buffer-on { ansi #3f18 DEO #3118 DEO #3018 DEO #3418 DEO #3918 DEO #6818 DEO }
|
||||
( \e[?1049l )
|
||||
%alternate-buffer-off { ansi #3f18 DEO #3118 DEO #3018 DEO #3418 DEO #3918 DEO #6c18 DEO }
|
||||
|
||||
( emit macros )
|
||||
( )
|
||||
|
@ -732,6 +732,7 @@
|
|||
|
||||
( execute a search, using the given search string )
|
||||
@do-search ( -> )
|
||||
;tmp LDA ?{ !return } ( ensure non-empty search string )
|
||||
.cursor/row LDZ2 .searching/orig-row STZ2
|
||||
.cursor/col LDZ2 .searching/orig-col STZ2
|
||||
#0000 .searching/regex STZ2
|
||||
|
@ -752,6 +753,7 @@
|
|||
( )
|
||||
( TODO: handle invalid regular expressions that fail to compile )
|
||||
@do-regex-search ( -> )
|
||||
;tmp LDA ?{ !return } ( ensure non-empty search string )
|
||||
cur-pos DUP2 .searching/start STZ2 .searching/end STZ2
|
||||
.cursor/row LDZ2 .searching/orig-row STZ2
|
||||
.cursor/col LDZ2 .searching/orig-col STZ2
|
||||
|
|
251
tar.tal
251
tar.tal
|
@ -10,7 +10,6 @@
|
|||
( - handle 'L' entries )
|
||||
( - support creating archives )
|
||||
( - arg validation should depend on mode )
|
||||
( - validate checksums )
|
||||
( - better error messages on unsupported files, e.g. symlinks )
|
||||
( - better usage message )
|
||||
( - support using "-" for stdin/stdout? )
|
||||
|
@ -28,24 +27,33 @@
|
|||
@panic ( -> $exit )
|
||||
#010e DEO #010f DEO BRK
|
||||
|
||||
@print-usage ( -> )
|
||||
;usage1 print ;usage2 !print
|
||||
|
||||
( handle all provided command-line arguments )
|
||||
@arg-callback ( -> )
|
||||
;arg/count LDA
|
||||
DUP #00 EQU ?&missing-mode
|
||||
DUP #01 EQU ?&missing-file
|
||||
#02 GTH ?&toomany !run
|
||||
&missing-mode ;missing-mode !&error
|
||||
&missing-file ;missing-filename !&error
|
||||
&toomany ;too-many-arguments
|
||||
&error print ;usage print #01 !exit
|
||||
DUP #00 GTH ?{ POP ;missing-mode !handle-error }
|
||||
DUP #01 GTH ?{ POP ;missing-filename !handle-error }
|
||||
POP !run
|
||||
|
||||
@error-toomany ( -> BRK )
|
||||
;too-many-arguments !handle-error
|
||||
|
||||
@error-noinput ( -> BRK )
|
||||
;no-input-arguments !handle-error
|
||||
|
||||
@handle-error ( ;msg -> BRK )
|
||||
print print-usage #01 !exit
|
||||
|
||||
( run the program )
|
||||
@run ( -> BRK )
|
||||
#01 arg/read .File1/name DEO2
|
||||
#00 arg/read LDA
|
||||
DUP LIT "t NEQ ?{ list-entries #00 !exit }
|
||||
DUP LIT "x NEQ ?{ expand-entries #00 !exit }
|
||||
POP ;invalid-mode print ;usage print #00 !exit
|
||||
DUP LIT "c NEQ ?{ POP create-archive #00 !exit }
|
||||
DUP LIT "t NEQ ?{ POP list-entries #00 !exit }
|
||||
DUP LIT "x NEQ ?{ POP expand-entries #00 !exit }
|
||||
POP ;invalid-mode print print-usage #00 !exit
|
||||
|
||||
( exit normally )
|
||||
@exit ( code^ -> BRK )
|
||||
|
@ -67,20 +75,72 @@
|
|||
LDAk #18 DEO INC2 GTH2k ?&loop ( limit* s+1* )
|
||||
&done POP2 POP2 JMP2r ( )
|
||||
|
||||
@print-filename ( -> )
|
||||
;header/filename sanitize-path #0064 lprint #0a18 DEO JMP2r
|
||||
|
||||
@print-long ( hi* lo* -> )
|
||||
dump-long #0a18 DEO JMP2r
|
||||
|
||||
( read 512 bytes of header for the next tar entry. )
|
||||
( assumes .File1/name is already set. )
|
||||
@read-header ( -> ok^ )
|
||||
#0200 .File1/len DEO2
|
||||
;header .File1/r DEO2
|
||||
( TODO validate checksum )
|
||||
.File1/ok DEI2 #0200 EQU2 JMP2r
|
||||
|
||||
@validate-checksum ( -> ok^ )
|
||||
;header/checksum load-octal6 ( chi* clo* )
|
||||
STH2k SWP2 STH2k SWP2 ( chi* clo* [clo* chi*] )
|
||||
;u-sum compute-sum ( chi* clo* uhi* ulo* [clo* chi*] )
|
||||
u32-eq ?&ok1 ( [clo* chi*] )
|
||||
STH2r STH2r ;s-sum compute-sum ( chi* clo* shi* slo* )
|
||||
u32-eq ?&ok2 ( )
|
||||
;invalid-checksum print ( ; error message )
|
||||
print-filename ( ; filename of affected entry )
|
||||
;expected print ( ; "expected: " )
|
||||
;header/checksum load-octal6 print-long ( ; expected checksum )
|
||||
;found print ( ; "found: " )
|
||||
;u-sum compute-sum print-long ( ; found checksum )
|
||||
#00 JMP2r ( 0^ )
|
||||
&ok1 POP2r POP2r &ok2 #01 JMP2r ( 1^ )
|
||||
|
||||
( maximum checksum is 0001fe00 but in practice )
|
||||
( almost all checksums will fit in 16-bits )
|
||||
@compute-sum ( fn* -> sum0* sum1* )
|
||||
STH2 ;header/checksum ;header STH2kr JSR2 ( n0* [fn*] )
|
||||
#0100 ADD2 ;uheader/end ;header/type STH2r JSR2 ( n1* n2* )
|
||||
OVR2 ADD2 GTH2k #00 SWP ( n1* sum* carry* )
|
||||
ROT2 POP2 SWP2 JMP2r ( carry* sum* )
|
||||
|
||||
@u32-eq ( xhi* xlo* yhi* ylo* -> bool^ )
|
||||
ROT2 EQU2 STH EQU2 STHr AND JMP2r
|
||||
|
||||
( return 16-bit checksum )
|
||||
( technically it should be 17-bit. for simplicity we'll )
|
||||
( just check the lower 16-bits. )
|
||||
@u-sum ( limit* start* -> sum* )
|
||||
LIT2r 0000 ( limit* start* [sum*] )
|
||||
&loop LDAk LITr 00 STH ( limit* start* [sum* n*] )
|
||||
ADD2r INC2 GTH2k ?&loop ( limit* pos+1* [sum+n*] )
|
||||
POP2 POP2 STH2r JMP2r ( sum* )
|
||||
|
||||
( similar to unsigned-sum but treats 8-bit ascii differently )
|
||||
( mostly only used for compatibility with old tar files )
|
||||
@s-sum ( limit* start* -> sum* )
|
||||
LIT2r 0000 ( limit* start* [sum*] )
|
||||
&loop LDAk ( limit* start* c^ [sum*] )
|
||||
DUP #07 SFT #ff MUL SWP STH2 ( limit* start* [sum* n*] )
|
||||
ADD2r INC2 GTH2k ?&loop ( limit* pos+1* [sum+n*] )
|
||||
POP2 POP2 STH2r JMP2r ( sum* )
|
||||
|
||||
( list all the entries in the tar archive )
|
||||
@list-entries ( -> )
|
||||
;arg/count LDA #02 GTH ?error-toomany
|
||||
read-header ?{ JMP2r }
|
||||
;header/filename LDA ?&non-null
|
||||
#800f DEO BRK
|
||||
&non-null
|
||||
validate-checksum ( )
|
||||
;header/type LDA ( type^ )
|
||||
DUP #00 EQU ?list-file ( type^ )
|
||||
DUP LIT "0 EQU ?list-file ( type^ )
|
||||
|
@ -104,8 +164,7 @@
|
|||
;unsupported print
|
||||
#18 DEO #2018 DEO
|
||||
;header/size load-octal11 dump-longer #2018 DEO
|
||||
;header/filename sanitize-path
|
||||
#0064 lprint #0a18 DEO
|
||||
print-filename
|
||||
;header/size load-octal11 round-up-to-512 skip !list-entries
|
||||
|
||||
( verbose file entry listing )
|
||||
|
@ -113,7 +172,7 @@
|
|||
POP
|
||||
LIT "f #18 DEO #2018 DEO
|
||||
;header/size load-octal11 dump-longer #2018 DEO
|
||||
;header/filename #0064 lprint #0a18 DEO
|
||||
print-filename
|
||||
;header/size load-octal11 round-up-to-512 skip !list-entries
|
||||
|
||||
( verbose directory entry listing )
|
||||
|
@ -121,11 +180,12 @@
|
|||
POP
|
||||
LIT "d #18 DEO #2018 DEO
|
||||
;header/size load-octal11 dump-longer #2018 DEO
|
||||
;header/filename #0064 lprint #0a18 DEO
|
||||
print-filename
|
||||
!list-entries
|
||||
|
||||
( expand a .tar archive in the current working directory )
|
||||
@expand-entries ( -> )
|
||||
;arg/count LDA #02 GTH ?error-toomany
|
||||
read-header ?{ JMP2r }
|
||||
;header/filename LDA ?&non-null
|
||||
#800f DEO BRK
|
||||
|
@ -146,16 +206,14 @@
|
|||
|
||||
@expand-file ( type^ -> )
|
||||
POP
|
||||
;header/filename sanitize-path
|
||||
DUP2 #0064 lprint #0a18 DEO
|
||||
print-filename
|
||||
.File2/name DEO2
|
||||
;header/size load-octal11 STH2k write
|
||||
STH2r remainder-512 skip-lo !expand-entries
|
||||
|
||||
@expand-dir ( type^ -> )
|
||||
POP
|
||||
;header/filename sanitize-path
|
||||
DUP2 #0064 lprint #0a18 DEO
|
||||
print-filename
|
||||
.File2/name DEO2
|
||||
#0004 .File2/len DEO2
|
||||
#0001 .File2/w DEO2
|
||||
|
@ -164,13 +222,130 @@
|
|||
@expand-unsupported ( type^ -> )
|
||||
;unsupported print
|
||||
#18 DEO LIT2 ": 18 DEO #2018 DEO
|
||||
;header/filename sanitize-path
|
||||
#0064 lprint #0a18 DEO
|
||||
print-filename
|
||||
;header/size load-octal11 round-up-to-512 skip !expand-entries
|
||||
|
||||
( src and dst should be paths )
|
||||
@compress-entries ( src* dst* -> )
|
||||
POP2 POP2 JMP2r
|
||||
@create-archive ( -> )
|
||||
;arg/count LDA #03 LTH ?error-noinput
|
||||
validate-inputs ?{ print-usage #01 !exit }
|
||||
( ; we know that all input files exist )
|
||||
#01 arg/read DUP2 path-exists ?&dest-exists
|
||||
|
||||
.File1/name DEO2
|
||||
#00 .File1/append DEO
|
||||
;arg/count LDA #02
|
||||
&loop DUP arg/read archive-path INC GTHk ?&loop
|
||||
POP2 JMP2r
|
||||
|
||||
&dest-exists ;destination-exists print
|
||||
print #0a18 DEO print-usage #01 !exit
|
||||
|
||||
@validate-inputs ( -> ok^ )
|
||||
;arg/count LDA #02 LITr 01 ( count^ 2^ [1^] )
|
||||
&loop DUP validate-input ( count^ i^ ok1^ [ok0^] )
|
||||
STH ANDr INC GTHk ?&loop ( count^ i+1^ [ok2^] )
|
||||
POP2 STHr JMP2r ( ok^ )
|
||||
|
||||
@validate-input ( i^ -> ok^ )
|
||||
arg/read DUP2 path-exists ?&ok1
|
||||
;missing-input print print #0a18 DEO #00 JMP2r
|
||||
&ok1 ;long-size LDA LIT "? NEQ ?&ok2
|
||||
;input-toobig print print #0a18 DEO #00 JMP2r
|
||||
&ok2 POP2 #01 JMP2r
|
||||
|
||||
@path-exists ( path* -> )
|
||||
path-read-size ;long-size LDA LIT "! NEQ JMP2r
|
||||
|
||||
@path-read-size ( path* -> )
|
||||
.File2/name DEO2
|
||||
#0008 .File2/len DEO2
|
||||
;long-size .File2/stat DEO2
|
||||
JMP2r
|
||||
|
||||
@archive-dir ( path* -> )
|
||||
POP2 JMP2r
|
||||
|
||||
@archive-path ( path* -> )
|
||||
zero-header DUP2 path-read-size ( path* )
|
||||
;long-size LDA LIT "- EQU ?archive-dir ( path* )
|
||||
LIT2r =header ( path* [h*] )
|
||||
STH2kr LDA LIT "/ NEQ ?&rel-path ( path* [h*] )
|
||||
LIT ". STH2kr STA INC2r ( path* [h+1*] )
|
||||
&rel-path STH2r copy-str ( ; write file name )
|
||||
;default-mode ;header/mode copy-str ( ; write file permissions )
|
||||
;default-id ;header/owner copy-str ( ; write file owner )
|
||||
;default-id ;header/group copy-str ( ; write file group )
|
||||
size-to-octal ( ; write file size )
|
||||
#010e DEO
|
||||
;default-mtime ;header/mtime copy-str ( ; write mtime )
|
||||
LIT "0 ;header/type STA ( ; write '0' for normal file )
|
||||
;u-sum compute-sum ( checksum* )
|
||||
|
||||
@ascii-to-short ( s* -> n* )
|
||||
#0000 SWP2 LITr c0 ( sum* s* [shift^] )
|
||||
&loop LDAk #30 SUB ( sum0* s* digit^ [shift^] )
|
||||
#00 SWP ( sum0* s* digit* [shift^] )
|
||||
STHkr SFT2 ( sum0* s* digit<<shift* [shift^] )
|
||||
ROT2 ADD2 SWP2 ( sum0+digit<<shift* s* [shift^] )
|
||||
STHkr #00 EQU ?&done ( sum1* s* [shift^] )
|
||||
INC2 LITr 40 SUBr !&loop ( sum1* s+1* [shift-64^] )
|
||||
&done POP2 POPr JMP2r ( sum1* )
|
||||
|
||||
@size-to-octal ( -> )
|
||||
;long-size ascii-to-short ( hi* )
|
||||
;long-size/mid ascii-to-short ( hi* lo* )
|
||||
;scratch ( hi* lo* addr* )
|
||||
render-octal32 ( )
|
||||
#000b ;header/size save-octal ( )
|
||||
JMP2r ( )
|
||||
|
||||
@render-octal32 ( hi* lo* addr* -> )
|
||||
short-to-octal STH2 STH ( aaaaaaaa bbbbbbbb [addr+5* 0000000x] )
|
||||
#0000 ROT ( aaaaaaaa 00000000 00000000 bbbbbbbb [addr+5* 0000000x] )
|
||||
#10 SFT2 ( aaaaaaaa 00000000 0000000b bbbbbbb0 [addr+5* 0000000x] )
|
||||
SWP2 #07 SFT2 ( 0000000b bbbbbbb0 0000000a aaaaaaa0 [addr+5* 0000000x] )
|
||||
SWP2 STH ( 0000000a aaaaaaa0 0000000b [addr+5* 0000000x bbbbbbb0] )
|
||||
ORA ORAr STHr ( 0000000a aaaaaaab bbbbbbbx [addr+5*] )
|
||||
STH2r short-to-octal ( 0000000a 0000000z addr+10* )
|
||||
STH2 SWP #10 SFT ORA ( 000000az [addr+10*] )
|
||||
LIT "0 ADD STH2kr STA ( [addr+10*] )
|
||||
STH2r INC2 JMP2r ( addr+11* )
|
||||
|
||||
@short-to-octal ( n* addr* -> n>>15^ addr+5* )
|
||||
byte-to-octal STH2 SWP ( lo>>6^ hi^ [addr+2*] )
|
||||
DUP #01 AND #20 SFT ROT ORA ( hi^ [[hi&1]<<2]|lo>>6 [addr+2*] )
|
||||
LIT "0 ADD STH2kr STA ( hi^ [addr+2*] )
|
||||
#01 SFT INC2r ( hi>>1^ [addr+3*] )
|
||||
STH2r !byte-to-octal ( hi>>7^ addr+5* )
|
||||
|
||||
@byte-to-octal ( n^ addr* -> n>>6^ addr+2* )
|
||||
STH2 DUP #07 AND LIT "0 ADD ( n^ digit1^ [addr*] )
|
||||
STH2kr STA #03 SFT INC2r ( n>>3^ [addr+1*] )
|
||||
DUP #07 AND LIT "0 ADD ( n>>3^ digit2^ [addr+1*] )
|
||||
STH2kr STA #03 SFT INC2r ( n>>6^ [addr+2*] )
|
||||
STH2r JMP2r ( n>>6^ addr+2* )
|
||||
|
||||
@save-octal ( count* addr* -> )
|
||||
LIT2r ffff ( count* addr* [ffff*] )
|
||||
OVR2 ADD2 ( count* addr+count* [ffff*] )
|
||||
STH2 ( count* [ffff* addr+count*] )
|
||||
OVR2r ADD2r ( count* [ffff* h=addr+count-1*] )
|
||||
;scratch SWP2 ( s* count* [ffff* h*] )
|
||||
OVR2 ADD2 SWP2 ( limit=count+s* s* [ffff* h*] )
|
||||
&loop LDAk STH2kr STA ( limit* s* [ffff* h*] ; h<-s )
|
||||
INC2 OVR2r ADD2r GTH2k ?&loop ( limit* s+1* [ffff* h-1*] )
|
||||
POP2 POP2 POP2r POP2r #010e DEO JMP2r ( )
|
||||
|
||||
@copy-str ( s* addr* -> )
|
||||
STH2
|
||||
&loop LDAk DUP ?&next POP POP2 POP2r JMP2r
|
||||
&next STH2kr STA INC2 INC2r !&loop
|
||||
|
||||
( we know header is exactly 512 bytes, an even number )
|
||||
@zero-header ( -> )
|
||||
;uheader/end ;header LIT2r 0000
|
||||
&loop STH2kr OVR2 STA2 INC2 INC2 GTH2k ?&loop
|
||||
POP2r POP2 POP2 JMP2r
|
||||
|
||||
( writes `n` bytes from File1 to File2 )
|
||||
( uses a 32k internal buffer )
|
||||
|
@ -275,6 +450,14 @@
|
|||
#10 SFT #01 SFT2 STH2r ( hi* lo* )
|
||||
JMP2r ( hi* lo* )
|
||||
|
||||
( returns values between #0000 #0000 and #0003 #ffff )
|
||||
@load-octal6 ( addr* -> hi* lo* )
|
||||
STH2k LDA octal-digit ( o^ [addr*] )
|
||||
#0001 SFT2 ( o1^ o2^ [addr*] )
|
||||
#0000 ROT SWP2 SWP SWP2 ( o1* o2* [addr*] )
|
||||
STH2r INC2 load-octal5 ( o1* o2* n* )
|
||||
ORA2 JMP2r ( o1* o2|n* )
|
||||
|
||||
( returns values between #0000 and #7fff )
|
||||
( )
|
||||
( octal5 of 77777 = #7fff, max value )
|
||||
|
@ -350,15 +533,26 @@
|
|||
JMP2r
|
||||
|
||||
( some handy string constants )
|
||||
@usage "usage: 20 "uxncli 20 "tar.rom 20 "t|x 20 "FILENAME 0a 00
|
||||
@usage1 "usage: 20 "uxncli 20 "tar.rom 20 "t|x 20 "TARFILE 0a 00
|
||||
@usage2 20 20 20 20 20 20 20 "uxncli 20 "tar.rom 20 "c 20 "TARFILE 20 "FILE1 20 "... 0a 00
|
||||
@missing-mode "error: 20 "missing 20 "mode 0a 00
|
||||
@missing-filename "error: 20 "missing 20 "filename 0a 00
|
||||
@too-many-arguments "error: 20 "too 20 "many 20 "arguments 0a 00
|
||||
@no-input-arguments "error: 20 "no 20 "input 20 "files 0a 00
|
||||
@invalid-mode "error: 20 "invalid 20 "mode 0a 00
|
||||
@read-error "error 20 "reading 20 "data 0a 00
|
||||
@write-error "error 20 "writing 20 "data 0a 00
|
||||
@unsupported "skipped 20 "unsupported 20 "type 20 00
|
||||
@meta-too-big "extended 20 "metadata 20 "field 20 "too 20 "big: 20 00
|
||||
@invalid-checksum "error: 20 "invalid 20 "checksum 0a 00
|
||||
@expected "expected: 20 00
|
||||
@found "found: 20 20 20 20 00
|
||||
@missing-input "error: 20 "missing 20 "input 20 "file: 20 00
|
||||
@input-toobig "error: 20 "input 20 "file 20 "too 20 "large: 20 00
|
||||
@destination-exists "error: 20 "destination 20 "already 20 "exists: 20 00
|
||||
@default-mode "0000755 00
|
||||
@default-id "0000000 00
|
||||
@default-mtime "07033241577 00
|
||||
|
||||
( load argument parser )
|
||||
~arg.tal
|
||||
|
@ -429,8 +623,11 @@
|
|||
&pad $c ( 0x1f4: padding, 12 bytes )
|
||||
&end ( 0x200: end of header )
|
||||
|
||||
( small scratch buffer )
|
||||
|77e8 @scratch $10
|
||||
|
||||
( up to 8 bytes for long size )
|
||||
|77f8 @long-size $8
|
||||
|77f8 @long-size $4 &mid $4
|
||||
|
||||
( buffer for up to 2048 characters of long names/paths )
|
||||
|7800 @long-buf $800
|
||||
|
|
124
test-regex.tal
124
test-regex.tal
|
@ -1,45 +1,43 @@
|
|||
%dbg { #ff #0e DEO }
|
||||
%sp { #20 #18 DEO }
|
||||
%nl { #0a #18 DEO }
|
||||
%exit { #01 #0f DEO BRK }
|
||||
%sp { #2018 DEO }
|
||||
%nl { #0a18 DEO }
|
||||
|
||||
|0100
|
||||
;expr1 ;compile JSR2 dbg nl
|
||||
;emit-stack JSR2 nl
|
||||
;emit-arena JSR2 nl
|
||||
;expr1 compile #010e DEO nl
|
||||
emit-stack nl
|
||||
emit-arena nl
|
||||
|
||||
LIT '= ;emit JSR2 sp
|
||||
#01 ;emit-bool JSR2 sp
|
||||
#01 ;emit-bool JSR2 sp
|
||||
#00 ;emit-bool JSR2 sp
|
||||
#01 ;emit-bool JSR2 sp
|
||||
#01 ;emit-bool JSR2 sp
|
||||
#00 ;emit-bool JSR2 sp
|
||||
#00 ;emit-bool JSR2 sp
|
||||
#00 ;emit-bool JSR2 nl
|
||||
LIT "= emit sp
|
||||
#01 emit-bool sp
|
||||
#01 emit-bool sp
|
||||
#00 emit-bool sp
|
||||
#01 emit-bool sp
|
||||
#01 emit-bool sp
|
||||
#00 emit-bool sp
|
||||
#00 emit-bool sp
|
||||
#00 emit-bool nl
|
||||
|
||||
LIT 'A ;emit JSR2 sp
|
||||
;test1 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test2 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test3 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test4 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test5 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test6 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test7 OVR2k ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test8 OVR2k ;match JSR2 ;emit-bool JSR2 nl
|
||||
LIT "A emit sp
|
||||
;test1 OVR2k rx-match emit-bool sp
|
||||
;test2 OVR2k rx-match emit-bool sp
|
||||
;test3 OVR2k rx-match emit-bool sp
|
||||
;test4 OVR2k rx-match emit-bool sp
|
||||
;test5 OVR2k rx-match emit-bool sp
|
||||
;test6 OVR2k rx-match emit-bool sp
|
||||
;test7 OVR2k rx-match emit-bool sp
|
||||
;test8 OVR2k rx-match emit-bool nl
|
||||
|
||||
LIT 'B ;emit JSR2 sp
|
||||
;test1 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test2 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test3 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test4 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test5 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test6 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test7 ;graph1 ;match JSR2 ;emit-bool JSR2 sp
|
||||
;test8 ;graph1 ;match JSR2 ;emit-bool JSR2 nl
|
||||
LIT "B emit sp
|
||||
;test1 ;graph1 rx-match emit-bool sp
|
||||
;test2 ;graph1 rx-match emit-bool sp
|
||||
;test3 ;graph1 rx-match emit-bool sp
|
||||
;test4 ;graph1 rx-match emit-bool sp
|
||||
;test5 ;graph1 rx-match emit-bool sp
|
||||
;test6 ;graph1 rx-match emit-bool sp
|
||||
;test7 ;graph1 rx-match emit-bool sp
|
||||
;test8 ;graph1 rx-match emit-bool nl
|
||||
|
||||
;reset-arena JSR2
|
||||
exit
|
||||
reset-arena
|
||||
#010f DEO BRK
|
||||
|
||||
( corresponds to regex: a(b|c)d* )
|
||||
@expr1 "a(b|c)d* 00
|
||||
|
@ -47,12 +45,12 @@
|
|||
( corresponds to regex: a(b|c)d* )
|
||||
( accepts "ab" or "ac" followd by any number of d's )
|
||||
@graph1
|
||||
03 'a :x1
|
||||
@x1 04 :x2 :x3
|
||||
@x2 03 'b :x4
|
||||
@x3 03 'c :x4
|
||||
@x4 05 :x5 0000
|
||||
@x5 03 'd :x4
|
||||
03 "a =x1
|
||||
@x1 04 =x2 =x3
|
||||
@x2 03 "b =x4
|
||||
@x3 03 "c =x4
|
||||
@x4 05 =x5 0000
|
||||
@x5 03 "d =x4
|
||||
|
||||
( test case strings to try matching )
|
||||
@test1 "ab 00 ( yes )
|
||||
|
@ -67,50 +65,50 @@
|
|||
~regex.tal
|
||||
|
||||
@emit ( c^ -- )
|
||||
emit JMP2r
|
||||
#18 DEO JMP2r
|
||||
|
||||
@emit-short ( short* -- )
|
||||
SWP ;emit-byte JSR2 ;emit-byte JSR2 JMP2r
|
||||
SWP emit-byte emit-byte JMP2r
|
||||
|
||||
@emit-byte ( byte^ -- )
|
||||
DUP #04 SFT ,&hex JSR #0f AND ,&hex JMP
|
||||
DUP #04 SFT ,&hex JSR #0f AND !&hex
|
||||
&hex #30 ADD DUP #39 GTH #27 MUL ADD emit
|
||||
JMP2r
|
||||
|
||||
@emit-bool ( byte^ -- )
|
||||
LIT '0 ADD emit JMP2r
|
||||
LIT "0 ADD emit JMP2r
|
||||
|
||||
( print stack size, followed by contents )
|
||||
@emit-stack ( -> )
|
||||
space LIT 'n emit LIT '= emit ;stack-pos LDA2 ;stack-bot SUB2 #0004 DIV2 ;emit-short JSR2 LIT ': emit
|
||||
sp LIT "n emit LIT "= emit ;stack-pos LDA2 ;stack-bot SUB2 #0004 DIV2 emit-short LIT ": emit
|
||||
;stack-bot
|
||||
&loop
|
||||
DUP2 ;stack-pos LDA2 LTH2 ,&ok JCN
|
||||
POP2 newline JMP2r
|
||||
DUP2 ;stack-pos LDA2 LTH2 ?&ok
|
||||
POP2 nl JMP2r
|
||||
&ok
|
||||
space LDA2k ;emit-short JSR2
|
||||
#0002 ADD2 ,&loop JMP
|
||||
sp LDA2k emit-short
|
||||
#0002 ADD2 !&loop
|
||||
|
||||
( emit n bytes from the given address )
|
||||
@emit-n ( addr* count^ -> addr2* )
|
||||
DUP #00 GTH ( addr count count>0? ) ,&ok JCN ( addr count ) POP newline JMP2r
|
||||
DUP #00 GTH ( addr count count>0? ) ?&ok ( addr count ) POP nl JMP2r
|
||||
&ok
|
||||
STH ( addr [count] ) space LDAk ;emit-byte JSR2 INC2 ( addr+1 [count] )
|
||||
STH ( addr [count] ) sp LDAk emit-byte INC2 ( addr+1 [count] )
|
||||
STHr #01 SUB ( addr+1 count-1 )
|
||||
;emit-n JMP2
|
||||
!emit-n
|
||||
|
||||
( emit the arena, with one line per node )
|
||||
( parses node type, since node size is dynamic (3-5). )
|
||||
@emit-arena ( -> )
|
||||
;arena-bot
|
||||
&loop
|
||||
DUP2 ;arena-pos LDA2 LTH2 ,&ok JCN POP2 JMP2r
|
||||
DUP2 ;arena-pos LDA2 LTH2 ?&ok POP2 JMP2r
|
||||
&ok
|
||||
DUP2 ;emit-short JSR2
|
||||
LIT ': emit space
|
||||
LDAk #01 NEQ ,&!1 JCN #03 ;emit-n JSR2 ,&loop JMP
|
||||
&!1 LDAk #02 NEQ ,&!2 JCN #03 ;emit-n JSR2 ,&loop JMP
|
||||
&!2 LDAk #03 NEQ ,&!3 JCN #04 ;emit-n JSR2 ,&loop JMP
|
||||
&!3 LDAk #04 NEQ ,&!4 JCN #05 ;emit-n JSR2 ,&loop JMP
|
||||
&!4 LDAk #05 NEQ ,&!5 JCN #05 ;emit-n JSR2 ,&loop JMP
|
||||
&!5 ;unknown-node-type ;error! JSR2
|
||||
DUP2 emit-short
|
||||
LIT ": emit sp
|
||||
LDAk #01 NEQ ?&c1 #03 emit-n !&loop
|
||||
&c1 LDAk #02 NEQ ?&c2 #03 emit-n !&loop
|
||||
&c2 LDAk #03 NEQ ?&c3 #04 emit-n !&loop
|
||||
&c3 LDAk #04 NEQ ?&c4 #05 emit-n !&loop
|
||||
&c4 LDAk #05 NEQ ?&c5 #05 emit-n !&loop
|
||||
&c5 ;unknown-node-type errorm
|
||||
|
|
|
@ -21,7 +21,7 @@ template = '''
|
|||
;wst print
|
||||
|
||||
@dump-wst
|
||||
#04 DEI #01 GTH ?&next !emit-wst &next STH !dump-wst
|
||||
#04 DEI #00 GTH ?&next !emit-wst &next STH !dump-wst
|
||||
|
||||
@emit-wst
|
||||
#05 DEI LIT [ &n $1 ] GTH ?&next #0a18 DEO !start-rst
|
||||
|
@ -34,7 +34,7 @@ template = '''
|
|||
#05 DEI #00 GTH ?&next !emit-rst &next STHr !dump-rst
|
||||
|
||||
@emit-rst
|
||||
#04 DEI #01 GTH ?&next #0a18 DEO #800f DEO BRK
|
||||
#04 DEI #00 GTH ?&next #0a18 DEO #800f DEO BRK
|
||||
&next emit #2018 DEO !emit-rst
|
||||
|
||||
@print ( addr* -> )
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
.\" Manpage reference for varvara.
|
||||
.\" by Eiríkr Åsheim
|
||||
.\" Contact d_m@plastic-idolatry.com to correct errors or typos.
|
||||
.TH varvara 7 "14 Nov 2024" "1.0" "Varvara Reference Guide"
|
||||
.SH NAME
|
||||
varvara \- virtual machine for the Uxn CPU
|
||||
.SH DESCRIPTION
|
||||
Varvara is a virtual machine for the Uxn CPU. It provides devices that allow
|
||||
ROMs to perform effects such as I/O, drawing to the screen, playing sounds,
|
||||
and more.
|
||||
|
||||
.SH DEVICES
|
||||
Each device consists of 16 ports, each of which are one byte of device memory. Data can be read from ports with \fBDEI\fP and written to them with \fBDEO\fP.
|
||||
|
||||
.SH TERMS
|
||||
|
||||
.SS Devices
|
||||
|
||||
.SS Ports
|
||||
|
||||
.SS Vectors
|
||||
|
||||
.SS Banks
|
||||
|
||||
.SH DEVICE LAYOUT
|
||||
0x00 \fBSystem\fP 0x80 \fBController\fP
|
||||
0x10 \fBConsole\fP 0x90 \fBMouse\fP
|
||||
0x20 \fBScreen\fP 0xa0 \fBFile 0\fP
|
||||
0x30 \fBAudio 0\fP 0xb0 \fBFile 1\fP
|
||||
0x40 \fBAudio 1\fP 0xc0 \fBDateTime\fP
|
||||
0x50 \fBAudio 2\fP 0xd0 \fB(reserved)\fP
|
||||
0x60 \fBAudio 3\fP 0xe0 \fB(reserved)\fP
|
||||
0x70 \fB(unused)\fP 0xf0 \fB(unused)\fP
|
||||
|
||||
.SH SYSTEM (0x00)
|
||||
|
||||
0x00 \fBvector*\fP 0x08 \fBred*\fP
|
||||
0x01 0x09
|
||||
0x02 \fBexpansion*\fP 0x0a \fBgreen*\fP
|
||||
0x03 0x0b
|
||||
0x04 \fBwst\fP 0x0c \fBblue*\fP
|
||||
0x05 \fBrst\fP 0x0d
|
||||
0x06 \fBmetadata*\fP 0x0e \fBdebug\fP
|
||||
0x07 0x0f \fBstate\fP
|
||||
|
||||
.SS System/vector
|
||||
Currently unused.
|
||||
|
||||
.SS System/expansion
|
||||
Values written to the expansion port will be interpreted as an absolute address pointing to memory containing an expansion command.
|
||||
|
||||
\fBCODE NAME DATA\fP
|
||||
00 \fBfill\fP 00 length* bank* addr* const
|
||||
01 \fBcpyl\fP 01 length* src-bank* src-addr* dst-bank* dst-addr*
|
||||
02 \fBcpyr\fP 02 length* src-bank* src-addr* dst-bank* dst-addr*
|
||||
|
||||
\fBCODE NAME DESC\fP
|
||||
00 \fBfill\fP fill a range of memory with a constant value.
|
||||
01 \fBcpyl\fP copy a range of memory starting from the first byte.
|
||||
02 \fBcpyr\fP copy a range of memory starting from the last byte.
|
||||
|
||||
Each bank contains 64k (65536 bytes) of data. Bank 0 is main memory. Banks are optional but emulators are encouraged to support at least 16 of them when possible.
|
||||
|
||||
.SH CONSOLE (0x10)
|
||||
|
||||
.SH SCREEN (0x20)
|
||||
|
||||
.SH AUDIO (0x30, 0x40, 0x50, 0x60)
|
||||
|
||||
.SH CONTROLLER (0x80)
|
||||
|
||||
.SH MOUSE (0x90)
|
||||
|
||||
.SH FILE (0xa0, 0xb0)
|
||||
|
||||
.SH DATETIME (0xc0)
|
||||
|
||||
.SH RESERVED (0xd0, 0xe0)
|
||||
|
||||
.SH UNUSED (0x70, 0xf0)
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
https://wiki.xxiivv.com/site/uxntal_opcodes.html \fIUxntal Opcodes\fP
|
||||
https://wiki.xxiivv.com/site/uxntal_syntax.html \fIUxntal Syntax\fP
|
||||
https://wiki.xxiivv.com/site/uxntal_modes.html \fIUxntal Modes\fP
|
||||
https://wiki.xxiivv.com/site/uxntal_immediate.html \fIImmediate opcodes\fP
|
||||
https://wiki.xxiivv.com/site/varvara.html \fIVarvara\fP
|
Loading…
Reference in New Issue