initial import
This commit is contained in:
commit
ad589d2894
26 changed files with 2241 additions and 0 deletions
13
utils/LICENSE
Normal file
13
utils/LICENSE
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright (c) 2020-2025 Devine Lu Linvega
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
19
utils/Makefile
Normal file
19
utils/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
.PHONY: all clean
|
||||
.SUFFIXES: .tal .rom
|
||||
|
||||
all: uxnmin drifloon.rom opctest.rom
|
||||
clean:
|
||||
rm -f uxnmin drifloon.rom opctest.rom
|
||||
|
||||
uxnmin: uxnmin.c
|
||||
drifloon.rom: uxnmin
|
||||
xxd -r -p drifloon.rom.txt drifloon-seed.rom
|
||||
./uxnmin drifloon-seed.rom < drifloon.tal > drifloon.rom
|
||||
cmp drifloon.rom drifloon-seed.rom
|
||||
rm drifloon-seed.rom
|
||||
|
||||
.tal.rom:
|
||||
sh assemble.sh $< $@
|
||||
|
||||
#opctest.rom: uxnmin drifloon.rom opctest.tal
|
||||
# ./uxnmin drifloon.rom < opctest.tal > opctest.rom
|
||||
4
utils/assemble.sh
Normal file
4
utils/assemble.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
make -q uxnmin
|
||||
make -q drifloon.rom
|
||||
./uxnmin drifloon.rom < $1 > $2
|
||||
82
utils/console.tal
Normal file
82
utils/console.tal
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
( usage: uxncli console.rom foo "bar baz"
|
||||
| Prints Welcome to Uxn!, and listens for incoming stdin events on enter. )
|
||||
|
||||
|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
|
||||
|
||||
|000
|
||||
|
||||
@arg $40
|
||||
@std $40
|
||||
|
||||
|100
|
||||
|
||||
@on-reset ( -> )
|
||||
;dict/hello <print-str>
|
||||
.Console/type DEI ?{
|
||||
( | no arguments )
|
||||
;on-std .Console/vector DEO2
|
||||
BRK }
|
||||
;on-arg .Console/vector DEO2
|
||||
BRK
|
||||
|
||||
@on-arg ( -> )
|
||||
[ LIT2 02 -Console/type ] DEI NEQ ?{
|
||||
.Console/read DEI [ LIT2 00 &ptr -arg ] INCk ,&ptr STR
|
||||
STZ2
|
||||
BRK }
|
||||
;arg ;dict/yousent <print-result>
|
||||
[ LIT2 -arg _&ptr ] STR
|
||||
[ LIT2 04 -Console/type ] DEI NEQ ?{ ;on-std .Console/vector DEO2 }
|
||||
BRK
|
||||
|
||||
@on-std ( -> )
|
||||
[ LIT2 0a -Console/read ] DEI EQU ?{
|
||||
.Console/read DEI [ LIT2 00 &ptr -std ] INCk ,&ptr STR
|
||||
STZ2
|
||||
BRK }
|
||||
;std DUP2 ;dict/yousaid <print-result>
|
||||
;dict/quit scmp ?{
|
||||
[ LIT2 -std _&ptr ] STR
|
||||
BRK }
|
||||
( quit ) #800f DEO
|
||||
BRK
|
||||
|
||||
@<print-result> ( buf* name* -- )
|
||||
<print-str>
|
||||
[ LIT2 "" 18 ] DEO
|
||||
<print-str>/
|
||||
[ LIT2 "" 18 ] DEO
|
||||
[ LIT2 00 -Console/type ] DEI DUP ADD ;Types ADD2 LDA2 <print-str>/
|
||||
#0a18 DEO
|
||||
JMP2r
|
||||
|
||||
@<print-str> ( str* -- )
|
||||
LDAk #18 DEO
|
||||
INC2 & LDAk ?<print-str>
|
||||
POP2 JMP2r
|
||||
|
||||
@scmp ( a* b* -- f )
|
||||
STH2
|
||||
&l ( a* b* -- f )
|
||||
LDAk LDAkr STHr NEQk ?&d
|
||||
DUP EOR EQUk ?&d
|
||||
POP2 INC2 INC2r !&l
|
||||
|
||||
&d ( a* c1 c2 b* -- f )
|
||||
NIP2 POP2r EQU JMP2r
|
||||
|
||||
(
|
||||
@|assets )
|
||||
|
||||
@Types =dict/arg-none =dict/arg-stdin =dict/arg-data =dict/arg-spacer =dict/arg-end
|
||||
|
||||
@dict
|
||||
&hello "Welcome 20 "to 20 "Uxn! 0a $1
|
||||
&yousaid "You 20 "said: 20 $1
|
||||
&yousent "You 20 "sent: 20 $1
|
||||
&quit "quit $1
|
||||
&arg-none "<none> $1
|
||||
&arg-stdin "<stdin> $1
|
||||
&arg-data "<data> $1
|
||||
&arg-spacer "<spacer> $1
|
||||
&arg-end "<end> $1
|
||||
155
utils/drifloon.rom.txt
Normal file
155
utils/drifloon.rom.txt
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
a001 6380 0637 a00a a560 0233 a001 1380
|
||||
1037 00a0 0417 1608 2000 0780 1216 6001
|
||||
cf00 6000 7a00 a093 ab38 156c a009 ff60
|
||||
08a7 a00a 0960 08a1 a008 8034 26a0 0100
|
||||
3960 089b a00a 0e60 088f a093 ab38 a094
|
||||
ab94 8018 1721 aa20 fff7 2222 6c22 6c80
|
||||
1917 6c00 4472 6966 6c6f 6f6e 0a55 786e
|
||||
7461 6c20 4173 7365 6d62 6c65 720a 4279
|
||||
2044 6576 696e 6520 4c75 204c 696e 7665
|
||||
6761 0a38 204e 6f76 2032 3032 3500 0080
|
||||
0a60 014c 8047 32a0 022c 2920 000c a00a
|
||||
9da0 0aa2 a00a 6060 07f6 8031 32a0 026e
|
||||
2920 000c a00a 9da0 0aa2 a00a 4e60 07e0
|
||||
800f 1620 0010 6005 b280 0f16 2000 07a0
|
||||
800f 1740 049d 6c90 2000 0222 6ca0 01f9
|
||||
2ca0 01f9 a001 ee35 6c60 06f6 2006 2860
|
||||
0253 2006 0d90 6001 66a1 1d20 000e 2226
|
||||
6000 a7a1 1d20 00c2 2240 01d6 2134 2c22
|
||||
a002 2ca0 01ee 35a0 0104 136c 3426 c000
|
||||
a028 0028 0f58 a029 0028 0f59 cfc0 ef53
|
||||
2000 0340 ffab 6c60 0322 6000 4d80 0060
|
||||
004e a002 5aa0 01ee 356c 34a0 7b00 2920
|
||||
000b a002 6ea0 01ee 35a0 0104 136c b426
|
||||
c000 807b 0804 807b 081d 0f58 a07d 0028
|
||||
0f59 cfc0 eb53 2000 0922 8000 6000 1140
|
||||
ff5f 6000 0580 2040 0006 a002 a040 05f7
|
||||
a00b aba1 26a0 1bab 2b20 0009 a00a 70a0
|
||||
0a47 6006 7680 e933 156c 2f80 e332 a00b
|
||||
ab26 ef60 0647 2000 0e60 0637 6006 34aa
|
||||
20ff ee22 a0ff ff23 626c 2360 0009 6006
|
||||
22a0 02f0 4005 b0a0 4024 13a0 0040 116c
|
||||
0680 200a 2000 16a0 0040 60fe ea80 0a09
|
||||
2000 07a0 0001 2180 fa33 40ff daa0 0040
|
||||
8106 807f 0b20 0009 a00a 70a0 0a54 6006
|
||||
0a80 eb13 316c a000 0081 0680 3f0b 2000
|
||||
09a0 0a70 a00a 4060 05f1 80eb 1331 6ca0
|
||||
00e5 1394 802f 0820 0009 9460 ffd8 2194
|
||||
20ff f022 80d1 1280 0313 6c21 a000 c813
|
||||
802f 60ff c1a0 0000 24a0 0326 4005 280f
|
||||
a004 1594 cf08 2000 0ca0 0003 3894 20ff
|
||||
f222 a0ff ff42 6c22 6c22 4001 c840 fe8f
|
||||
6000 7040 feb1 6000 6a60 02c7 4004 f460
|
||||
0061 6002 be40 04e7 6000 5826 60ff 9040
|
||||
020f 60ff a640 0209 8080 6004 a560 0043
|
||||
6003 a140 049c 8080 6004 9760 0035 6003
|
||||
8540 048e 80a0 6004 8960 0027 6003 7f40
|
||||
047c 6000 1e80 2040 046e 6000 1680 4040
|
||||
0466 8060 4004 6160 0009 4004 1b60 0003
|
||||
4004 0921 9480 200a 2000 09a0 0a79 a00a
|
||||
5440 0517 6c7c 0396 2403 9f40 03a8 2603
|
||||
b22c 03b8 5f03 bd2e 03c6 2d03 cb3b 03d4
|
||||
3d03 d921 03ea 3f03 e223 03f7 2203 fd7d
|
||||
0389 7e01 5d28 038d 2903 875b 0387 5d03
|
||||
8725 0390 0026 6000 0e80 0009 0f26 a005
|
||||
2f60 04a9 4f1d 6ce0 1f00 a004 cfa4 a000
|
||||
0324 6004 9f20 000f 41a0 0003 3894 20ff
|
||||
ec22 2262 8000 6c22 5cb4 a04c 4928 8070
|
||||
1f0f 5da0 0003 3894 8021 0b20 002e 9480
|
||||
3209 2000 05c0 2040 001d 9480 7209 2000
|
||||
05c0 4040 0011 9480 6b09 2000 05c0 8040
|
||||
0005 2242 8000 6c5d 2140 ffcb 224f 6c4c
|
||||
4954 494e 4350 4f50 4e49 5053 5750 524f
|
||||
5444 5550 4f56 5245 5155 4e45 5147 5448
|
||||
4c54 484a 4d50 4a43 4e4a 5352 5354 484c
|
||||
445a 5354 5a4c 4452 5354 524c 4441 5354
|
||||
4144 4549 4445 4f41 4444 5355 424d 554c
|
||||
4449 5641 4e44 4f52 4145 4f52 5346 5442
|
||||
524b 0022 8000 8180 fb13 06a0 0aab a180
|
||||
fa33 1506 8004 1f60 035d 0460 0359 8018
|
||||
33a0 0567 6c80 e432 a000 0139 9460 ffe3
|
||||
6000 5e80 d633 6cce bb2e 2e00 6003 8320
|
||||
0027 9480 7b08 2000 2094 60fd f221 1d20
|
||||
0017 2660 fd34 211d 2000 1726 6000 9721
|
||||
1d20 000e 60fe be0c 6ca0 0a79 a00a 5440
|
||||
0389 a00a 81a0 0a54 4003 8094 807b 0820
|
||||
ff81 9480 2f08 20fd a294 8026 0820 fd9b
|
||||
6c26 6000 61a1 1d20 0010 22a0 060d 3460
|
||||
0226 8002 6002 b440 001d 2326 6002 1960
|
||||
0103 2000 0860 02a3 2735 4001 1022 a00a
|
||||
81a0 0a40 4003 3404 6000 1160 000e 6000
|
||||
0b60 ff68 a006 0c60 028d 8000 a04b aba1
|
||||
26a0 93ab 2b20 0009 a00a 70a0 0a38 6003
|
||||
0a80 e933 156c 2f80 e332 a04b ab26 a000
|
||||
0338 ef60 02d7 2000 0fa0 0003 3860 02c3
|
||||
aa20 ffe9 22a0 ffff 2362 6c26 60ff d7a1
|
||||
1d20 000d 2280 b532 2480 01a0 ffff 40ff
|
||||
9623 6c60 028c 2002 6b60 ff3f 60ff b760
|
||||
006b 2000 09a0 0a79 a00a 4060 02ad 6000
|
||||
7234 6ca0 060d 34a0 4bab a820 0037 6000
|
||||
5b20 0027 b4a0 0100 2820 001f 26a0 0003
|
||||
3894 8041 1980 1a0b 2000 0fa0 0a17 6003
|
||||
2826 6003 2480 0a60 faa5 22a0 0003 3860
|
||||
0241 40ff c522 2240 fa62 26a0 0080 3802
|
||||
2000 016c a00a 8ba0 0a40 4002 4ea1 1d20
|
||||
0003 8000 6ca1 2114 8002 1c6c a121 1480
|
||||
011c 6ca1 21af 1480 011d 6f15 6c21 21af
|
||||
1480 021d 6f15 6c80 1733 60fe 9e60 ff3b
|
||||
60ff d220 001d 2660 0171 6000 1b60 0018
|
||||
a000 0060 0012 a000 0060 000c a003 0434
|
||||
6000 0560 ffbd 346c 0460 0000 a01b aba1
|
||||
26a0 4bab 2b20 0009 a00a 70a0 0a23 6001
|
||||
da80 e933 156c a007 bf60 ffab 036c a007
|
||||
c740 ffa3 a007 ce60 ff9d a11d 2000 0422
|
||||
8000 6c60 0115 6000 0e60 ff4e 036c a007
|
||||
dd60 ff83 6001 0421 2139 6c80 af32 a01b
|
||||
aba8 2000 1326 a009 7835 a6a0 0004 3834
|
||||
2ea0 000a 3840 ffe9 2222 6cb4 6000 e4a1
|
||||
2134 34a1 1d20 0006 a00a 7940 019b 6c60
|
||||
ffe9 2303 4000 9b60 ffe1 2340 0090 60ff
|
||||
da24 3460 ffb1 6000 0f03 4000 8560 ffcb
|
||||
2434 60ff a240 0076 26a0 0080 3802 2000
|
||||
016c a00a 8b40 0161 26a0 0003 3834 a0ce
|
||||
bb29 2000 0222 6ca0 0727 356c a008 6240
|
||||
0085 60fc 5240 004a 6000 ce80 0209 8050
|
||||
1f80 801d 6000 3b60 00c8 8000 0820 001e
|
||||
6000 b606 8002 0920 0008 0260 0096 0340
|
||||
0020 8004 0920 0006 6000 8940 0010 22a0
|
||||
0a79 a00a 5940 00d3 6000 0760 ff20 0460
|
||||
0000 6000 1207 2000 0b22 02a0 0a93 a00a
|
||||
6840 00b7 40f8 afa0 0100 a180 fa33 a1a0
|
||||
0100 2b20 0004 a180 f633 6c80 ea32 6c60
|
||||
fff9 3880 e233 6c2f 9406 2000 0402 2262
|
||||
6cef 2e21 40ff f180 0f1c 800a 8b20 0005
|
||||
1980 6118 6c02 8030 186c 9480 3019 0680
|
||||
090a 0c6c 8027 1906 800a 1980 050a 0c6c
|
||||
0280 ff6c e000 00c0 407f 60ff ddc0 000f
|
||||
7821 9420 fff1 226f 6ca6 6000 1624 2139
|
||||
036c 2660 ffc4 0120 0005 1480 0008 6c21
|
||||
40ff f094 2000 0221 6c21 40ff f6a6 60ff
|
||||
f224 3924 2f27 3824 a820 000c 94d4 4f09
|
||||
2000 0521 6140 fff0 6228 6c80 0f16 2000
|
||||
25a0 010f 1760 00a1 8020 60f8 2260 0099
|
||||
a00a 2060 0093 a000 4060 008d a003 0434
|
||||
a000 0040 0043 2222 6c80 0f16 2000 38a0
|
||||
010f 17a0 0a2e 6000 7080 2060 f7f1 6000
|
||||
68a0 0a20 6000 62a0 0000 a121 34a0 0003
|
||||
3860 0055 26a0 0008 3834 24a0 0006 3834
|
||||
a000 0338 4000 0222 6ca0 0a09 6000 3a60
|
||||
0037 803a 60f7 b860 0035 800a 60f7 b06c
|
||||
800f 1620 001f a001 0f17 6000 1c80 2060
|
||||
f79d 2460 0013 a00a 2060 000d 6000 0a80
|
||||
0a60 f78b 6c22 2222 6ca0 015f 40fe b8e0
|
||||
ff00 a000 0abb af3a 396f 419d 20ff f322
|
||||
0380 3018 60f7 6847 58cf 20ff f362 6c41
|
||||
7373 656d 626c 6564 0020 696e 2000 2062
|
||||
7974 6573 2e0a 002d 2d20 556e 7573 6564
|
||||
3a20 0052 6566 6572 656e 6365 7300 5265
|
||||
6665 7265 6e63 6500 5379 6d62 6f6c 7300
|
||||
5379 6d62 6f6c 004d 6163 726f 7300 4d61
|
||||
6372 6f00 4e61 6d65 004e 756d 6265 7200
|
||||
436f 6d6d 656e 7400 5772 6974 696e 6700
|
||||
6578 6365 6564 6564 0069 6e76 616c 6964
|
||||
0064 7570 6c69 6361 7465 0074 6f6f 2066
|
||||
6172 007a 6572 6f2d 7061 6765 006f 7065
|
||||
6e00 2e2e 0052 4553 4554
|
||||
732
utils/drifloon.tal
Normal file
732
utils/drifloon.tal
Normal file
|
|
@ -0,0 +1,732 @@
|
|||
( cat input.tal | uxncli drifloon.rom > output.rom )
|
||||
|
||||
|00 @System/vector $2 &expansion $2 &wst $1 &rst $1 &metadata $2 &r $2 &g $2 &b $2 &debug $1 &state $1
|
||||
|10 @Console/vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
|
||||
|
||||
|000
|
||||
|
||||
@scope/buf $3f &cap $1
|
||||
@token/buf $3f &cap $1
|
||||
|
||||
|100
|
||||
|
||||
@on-reset ( -> )
|
||||
;meta #06 DEO2
|
||||
;dict/reset scope/<set>
|
||||
;assembly/on-console .Console/vector DEO2
|
||||
BRK
|
||||
|
||||
@assembly/on-console ( -> )
|
||||
[ LIT2 04 -Console/type ] DEI EQU ?{ .Console/read DEI token/<push-byte>
|
||||
BRK }
|
||||
/<resolve>
|
||||
BRK
|
||||
|
||||
@rom/<put> ( byte addr* -- )
|
||||
;&mem ADD2 STA
|
||||
JMP2r
|
||||
|
||||
@rom/<emit> ( -- )
|
||||
;dict/assembled err/<print>
|
||||
;dict/in err/<print>
|
||||
;head/length LDA2 DUP2 #0100 SUB2 err/<pdec>
|
||||
;dict/bytes err/<print>
|
||||
( | write )
|
||||
;rom/mem ADD2 ;rom/output
|
||||
&>l
|
||||
LDAk #18 DEO
|
||||
INC2 GTH2k ?&>l
|
||||
POP2 POP2 JMP2r
|
||||
|
||||
@runes/concat ( t* -- )
|
||||
POP2 JMP2r
|
||||
|
||||
@err/<emit> ( c -- )
|
||||
#19 DEO JMP2r
|
||||
|
||||
@meta $1
|
||||
( name ) "Drifloon 0a
|
||||
( desc ) "Uxntal 20 "Assembler 0a
|
||||
( auth ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
|
||||
( date ) "8 20 "Nov 20 "2025 $2
|
||||
|
||||
|
||||
|
||||
( Core )
|
||||
|
||||
@assembly/<resolve> ( -- )
|
||||
( cap ) #0a token/<push-byte>
|
||||
,&mode LDR2 ;comment/assemble NEQ2 ?{
|
||||
( ! ) ;dict/open ;dict/trail ;dict/Comment err/<generic> }
|
||||
,&mode LDR2 ;macros/assemble NEQ2 ?{
|
||||
( ! ) ;dict/open ;dict/trail ;dict/Macro err/<generic> }
|
||||
.System/state DEI ?{
|
||||
refs/<resolve-all>
|
||||
.System/state DEI ?{
|
||||
[ LIT2 80 -System/state ] DEO !syms/<emit> } }
|
||||
JMP2r
|
||||
|
||||
@assembly/apply ( t* -- )
|
||||
LDZk ?{ POP2 JMP2r }
|
||||
[ LIT2 &mode =standard/assemble ] JMP2
|
||||
|
||||
(
|
||||
@|Standard )
|
||||
|
||||
@standard/<latch> ( -- )
|
||||
;&assemble ;assembly/mode STA2
|
||||
JMP2r
|
||||
|
||||
@standard/assemble ( t* -- )
|
||||
( hex ) str/is-hex ?rom/<write-rawhex>
|
||||
( opc ) opcodes/is-opcode ?rom/<write-opcode>
|
||||
LDZk runes/find INC2k ORA ?{
|
||||
POP2
|
||||
( mac ) DUP2 macros/find-name INC2k ORA ?macros/<write>
|
||||
POP2
|
||||
( imm ) !runes/litjsi }
|
||||
INC2 LDA2 JMP2
|
||||
|
||||
(
|
||||
@|Comment )
|
||||
|
||||
@comment/<latch> ( t* -- )
|
||||
POP2 ;&assemble ;assembly/mode STA2
|
||||
[ LIT2 01 _&depth ] STR
|
||||
JMP2r
|
||||
|
||||
@comment/assemble ( t* -- )
|
||||
LDA2 DUP2 [ LITr &depth $1 ]
|
||||
( a ) LIT2 "( $1 EQU2 [ STH ADDr ]
|
||||
( b ) LIT2 ") $1 EQU2 [ STH SUBr ]
|
||||
( . ) STHkr LITr _&depth STRr
|
||||
?{ !standard/<latch> }
|
||||
JMP2r
|
||||
|
||||
(
|
||||
@|Macros )
|
||||
|
||||
@macros/<latch> ( t* -- )
|
||||
name/<validate>
|
||||
/<push-word>
|
||||
#00 /<push-byte>
|
||||
;&walk ;assembly/mode STA2
|
||||
JMP2r
|
||||
|
||||
&walk ( t* -- )
|
||||
LDA2 [ LIT2 "{ $1 ] NEQ2 ?{
|
||||
;&assemble ;assembly/mode STA2
|
||||
[ LIT2 01 _&depth ] STR }
|
||||
JMP2r
|
||||
|
||||
@macros/assemble ( t* -- )
|
||||
LDA2k DUP2 [ LITr &depth $1 ]
|
||||
( a ) LIT "{ EQU SWP LIT "{ EQU ORA [ STH ADDr ]
|
||||
( b ) LIT2 "} $1 EQU2 [ STH SUBr ]
|
||||
( . ) STHkr LITr _&depth STRr
|
||||
?{ POP2 #00 /<push-byte> !standard/<latch> }
|
||||
/<push-word>
|
||||
#20 !/<push-byte>
|
||||
|
||||
@macros/<push-word> ( t* -- )
|
||||
;/<push-byte> !hof/<each>
|
||||
|
||||
@macros/<push-byte> ( byte -- )
|
||||
[ LIT2 &ptr =&mem ] INC2k
|
||||
( | check overflow )
|
||||
DUP2 ;&memend LTH2 ?{
|
||||
( ! ) ;dict/exceeded ;dict/Macros err/<token> }
|
||||
,&ptr STR2
|
||||
STA
|
||||
JMP2r
|
||||
|
||||
@macros/find-name ( name* -- <addr>* )
|
||||
STH2
|
||||
,&ptr LDR2 ;&mem
|
||||
&>lf
|
||||
DUP2 STH2kr str/cmp ?{
|
||||
str/cap str/cap GTH2k ?&>lf
|
||||
POP2 #ffff }
|
||||
NIP2 POP2r JMP2r
|
||||
|
||||
@macros/<write> ( t* macro* -- )
|
||||
NIP2 token/<new>
|
||||
str/cap ;token/<push-byte> !hof/<each>
|
||||
|
||||
(
|
||||
@|Token )
|
||||
|
||||
@token/<new> ( -- )
|
||||
[ LIT2 -&buf _&ptr ] STR
|
||||
[ LIT2 00 -&buf ] STZ
|
||||
JMP2r
|
||||
|
||||
@token/<push-byte> ( c -- )
|
||||
DUP #20 GTH ?{
|
||||
;&buf assembly/apply #0a NEQ ?{
|
||||
[ LIT2 &line 0001 ] INC2 ,&line STR2 }
|
||||
!/<new> }
|
||||
[ LIT2 00 &ptr -&buf ] INCk
|
||||
( | check overflow )
|
||||
DUP .&cap LTH ?{
|
||||
( ! ) ;dict/exceeded ;dict/Name err/<token> }
|
||||
,&ptr STR
|
||||
STZ2
|
||||
JMP2r
|
||||
|
||||
(
|
||||
@|Scope )
|
||||
|
||||
@scope/<push-byte> ( c -- )
|
||||
[ LIT2 00 &ptr -&buf ] INCk
|
||||
( | check overflow )
|
||||
DUP .&cap LTH ?{
|
||||
( ! ) ;dict/exceeded ;dict/Symbol err/<token> }
|
||||
,&ptr STR
|
||||
STZ2
|
||||
JMP2r
|
||||
|
||||
@scope/<set> ( name* -- )
|
||||
[ LIT2 -&buf _&ptr ] STR
|
||||
&>w
|
||||
LDAk [ LIT "/ ] EQU ?{
|
||||
LDAk /<push-byte>
|
||||
INC2 LDAk ?&>w }
|
||||
POP2 ,&ptr LDR ,&anchor STR
|
||||
JMP2r
|
||||
|
||||
@scope/make-name ( name* -- scope/label* )
|
||||
INC2 [ LIT2 &anchor $1 _&ptr ] STR
|
||||
[ LIT "/ ] /<push-byte>
|
||||
;&buf SWP2 ;/<push-byte> !hof/<each>
|
||||
|
||||
(
|
||||
@|Runes )
|
||||
|
||||
@runes/find ( char -- <addr>* )
|
||||
STH
|
||||
;&lut
|
||||
&>w
|
||||
LDAk STHkr EQU ?{
|
||||
#0003 ADD2 LDAk ?&>w
|
||||
POP2 #ffff }
|
||||
POPr JMP2r
|
||||
|
||||
@runes/ignore ( t* -- )
|
||||
POP2 JMP2r
|
||||
|
||||
&lambda ( t* -- )
|
||||
POP2 !lambda/pop
|
||||
|
||||
&coment ( t* -- )
|
||||
!comment/<latch>
|
||||
|
||||
¯os ( t* -- )
|
||||
/req-name !macros/<latch>
|
||||
|
||||
&padabs ( t* -- )
|
||||
/req-name syms/find-addr !head/<set>
|
||||
|
||||
&padrel ( t* -- )
|
||||
/req-name syms/find-addr !head/<set-rel>
|
||||
|
||||
&toplab ( t* -- )
|
||||
/req-name DUP2 scope/<set> !syms/<new>
|
||||
|
||||
&sublab ( t* -- )
|
||||
scope/make-name !syms/<new>
|
||||
|
||||
&litrel ( t* -- )
|
||||
#80 rom/<write-byte> &rawrel /req-name refs/get-rel !rom/<write-byte>
|
||||
|
||||
&litzep ( t* -- )
|
||||
#80 rom/<write-byte> &rawzep /req-name refs/get-abs !rom/<write-byte>
|
||||
|
||||
&litabs ( t* -- )
|
||||
#a0 rom/<write-byte> &rawabs /req-name refs/get-abs2 !rom/<write-short>
|
||||
|
||||
&litjci ( t* -- )
|
||||
/req-name #20 !rom/<write-call>
|
||||
|
||||
&litjmi ( t* -- )
|
||||
/req-name #40 !rom/<write-call>
|
||||
|
||||
&litjsi ( t* -- )
|
||||
#60 !rom/<write-call>
|
||||
|
||||
&lithex ( t* -- )
|
||||
/req-name !rom/<write-lithex>
|
||||
|
||||
&rawstr ( t* -- )
|
||||
/req-name !rom/<write-str>
|
||||
|
||||
@runes/req-name ( str* -- str1* )
|
||||
INC2 LDAk #20 GTH ?{ ;dict/invalid ;dict/Name !err/<token> }
|
||||
JMP2r
|
||||
|
||||
@runes/lut [
|
||||
"| =&padabs "$ =&padrel
|
||||
"@ =&toplab "& =&sublab
|
||||
", =&litrel "_ =&rawrel
|
||||
". =&litzep "- =&rawzep
|
||||
"; =&litabs "= =&rawabs
|
||||
"! =&litjmi "? =&litjci
|
||||
"# =&lithex "" =&rawstr
|
||||
"} =&lambda "~ =&concat
|
||||
"( =&coment ") =&ignore
|
||||
"[ =&ignore "] =&ignore "% =¯os ] $1
|
||||
|
||||
(
|
||||
@|Opcodes )
|
||||
|
||||
@opcodes/is-opcode ( str* -- str* bool )
|
||||
DUP2 /parse #00 NEQ STH
|
||||
DUP2 ;&brk str/cmp STHr ORA JMP2r
|
||||
|
||||
@opcodes/parse ( str* -- byte )
|
||||
[ LIT2r 1f00 ] ;&lut
|
||||
&>w1
|
||||
SWP2k #0003 SWP2 mem/cmp ?{
|
||||
INCr #0003 ADD2 LDAk ?&>w1
|
||||
POP2 POP2 POP2r #00 JMP2r }
|
||||
POP2
|
||||
( mask ) ANDr
|
||||
( litk ) LDA2k [ LIT2 "LI ] EQU2 #70 SFT [ STH ORAr ]
|
||||
( move ) #0003 ADD2
|
||||
&>w2
|
||||
LDAk #21 LTH ?{
|
||||
( | parse modes )
|
||||
LDAk [ LIT "2 ] NEQ ?{ LITr 20 !&r }
|
||||
LDAk [ LIT "r ] NEQ ?{ LITr 40 !&r }
|
||||
LDAk [ LIT "k ] NEQ ?{ LITr 80 !&r }
|
||||
POP2 POPr #00 JMP2r
|
||||
&r ORAr INC2 !&>w2 }
|
||||
POP2 STHr JMP2r
|
||||
|
||||
@opcodes/lut [
|
||||
"LIT "INC "POP "NIP "SWP "ROT "DUP "OVR
|
||||
"EQU "NEQ "GTH "LTH "JMP "JCN "JSR "STH
|
||||
"LDZ "STZ "LDR "STR "LDA "STA "DEI "DEO
|
||||
"ADD "SUB "MUL "DIV "AND "ORA "EOR "SFT ]
|
||||
&brk "BRK $1
|
||||
|
||||
(
|
||||
@|Lambda )
|
||||
|
||||
@lambda/make-name ( token* -- name* )
|
||||
POP2 [ LIT &count $1 ] INCk ,&count STR
|
||||
DUP [ LIT2 &ptr =&mem ] INC2k ,&ptr STR2
|
||||
STA
|
||||
( >> )
|
||||
|
||||
@lambda/name ( id -- str* )
|
||||
DUP #04 SFT hexc SWP hexc ,&id STR2
|
||||
;&sym JMP2r
|
||||
|
||||
@lambda/pop ( -- )
|
||||
,&ptr LDR2 #0001 SUB2 LDAk /name syms/<new>
|
||||
,&ptr STR2
|
||||
JMP2r
|
||||
&sym cebb
|
||||
&id ".. $1
|
||||
|
||||
(
|
||||
@|Name )
|
||||
|
||||
@name/<validate> ( name* -- name* )
|
||||
( not hex ) str/is-hex ?&fail
|
||||
( not lambda ) LDAk LIT "{ EQU ?&fail
|
||||
( not runic ) LDAk runes/find INC2 ORA ?&fail
|
||||
( dup macros ) DUP2 macros/find-name INC2 ORA ?&dup
|
||||
( dup symbol ) DUP2 syms/find-name INC2 ORA ?&dup
|
||||
( not opcode ) opcodes/is-opcode [ JMP JMP2r ]
|
||||
&fail ( -- )
|
||||
;dict/invalid ;dict/Name !err/<token>
|
||||
|
||||
&dup ( -- )
|
||||
;dict/duplicate ;dict/Name !err/<token>
|
||||
|
||||
@name/unpack ( name* -- name* )
|
||||
LDAk [ LIT "{ ] EQU ?lambda/make-name
|
||||
LDAk [ LIT "/ ] EQU ?scope/make-name
|
||||
LDAk [ LIT "& ] EQU ?scope/make-name
|
||||
JMP2r
|
||||
|
||||
(
|
||||
@|Syms )
|
||||
|
||||
@syms/<new> ( name* -- )
|
||||
DUP2 /find-name INC2k ORA ?{
|
||||
POP2 ;&ptr LDA2 refs/<record-scope>
|
||||
.SymType/declared head/get !/<push-sym> }
|
||||
( | name* sym* -- )
|
||||
NIP2 DUP2 refs/<record-scope>
|
||||
/is-declared ?{ head/get OVR2 STA2 !/<declare> }
|
||||
POP2
|
||||
( ! ) ;dict/duplicate ;dict/Symbol !err/<token>
|
||||
|
||||
@syms/<push-sym> ( name* type addr* -- )
|
||||
( hb ) SWP /<push-byte>
|
||||
( lb ) /<push-byte>
|
||||
( type ) /<push-byte>
|
||||
name/<validate>
|
||||
;/<push-byte> hof/<each>
|
||||
#00
|
||||
( >> )
|
||||
|
||||
@syms/<push-byte> ( byte -- )
|
||||
[ LIT2 &ptr =&mem ] INC2k
|
||||
( | check overflow )
|
||||
DUP2 ;&memend LTH2 ?{
|
||||
( ! ) ;dict/exceeded ;dict/Symbols err/<token> }
|
||||
,&ptr STR2
|
||||
STA
|
||||
JMP2r
|
||||
|
||||
@syms/find-name ( name* -- <sym>* )
|
||||
STH2
|
||||
,&ptr LDR2 ;&mem
|
||||
&>lfn
|
||||
DUP2 #0003 ADD2 STH2kr str/cmp ?{
|
||||
#0003 ADD2 str/cap GTH2k ?&>lfn
|
||||
POP2 #ffff }
|
||||
NIP2 POP2r JMP2r
|
||||
|
||||
@syms/find-alloc ( name* -- <addr>* )
|
||||
DUP2 /find-name INC2k ORA ?{
|
||||
( null* .. next* ) POP2 ,&ptr LDR2
|
||||
( alloc ) SWP2 .SymType/used #ffff !/<push-sym> }
|
||||
NIP2 JMP2r
|
||||
|
||||
@syms/find-addr ( name* -- <addr>* )
|
||||
str/is-hex ?str/hex
|
||||
name/unpack /find-name /is-defined ?{
|
||||
( ! ) ;dict/invalid ;dict/Symbol err/<token> }
|
||||
/use LDA2 JMP2r
|
||||
|
||||
@syms/<emit> ( -- )
|
||||
;&ptr LDA2 ;&mem
|
||||
&>ls
|
||||
EQU2k ?{
|
||||
/is-used ?{
|
||||
LDA2k #0100 EQU2 ?{
|
||||
DUP2 #0003 ADD2 LDAk [ LIT "A ] SUB #1a LTH ?{
|
||||
;dict/unused err/<print>
|
||||
DUP2 err/<print>
|
||||
#0a err/<emit> }
|
||||
POP2 } }
|
||||
#0003 ADD2 str/cap !&>ls }
|
||||
POP2 POP2 !rom/<emit>
|
||||
|
||||
@syms/byte-distance ( addr* -- addr* )
|
||||
DUP2 #0080 ADD2 POP ?{ JMP2r }
|
||||
( ! ) ;dict/too-far ;dict/Symbol !err/<token>
|
||||
|
||||
@syms/is-defined ( sym* -- sym* t )
|
||||
INC2k ORA ?{ #00 JMP2r }
|
||||
( >> )
|
||||
|
||||
@syms/is-declared ( sym* -- sym* t )
|
||||
INC2k INC2 LDA .SymType/declared AND JMP2r
|
||||
|
||||
@syms/is-used ( sym* -- sym* t )
|
||||
INC2k INC2 LDA .SymType/used AND JMP2r
|
||||
|
||||
@syms/use ( sym* -- sym* )
|
||||
INC2k INC2 STH2k LDA .SymType/used ORA STH2r STA
|
||||
JMP2r
|
||||
|
||||
@syms/<declare> ( sym* -- )
|
||||
INC2 INC2 STH2k LDA .SymType/declared ORA STH2r STA
|
||||
JMP2r
|
||||
|
||||
(
|
||||
@|References )
|
||||
|
||||
@refs/get-type ( token* type* -- addr* )
|
||||
,&type STR2
|
||||
name/unpack syms/find-alloc syms/is-declared ?{
|
||||
DUP2 head/get
|
||||
( addr* ) /<push-short>
|
||||
( symbol* ) /<push-short>
|
||||
( type-fn* ) [ LIT2 &type $2 ] /<push-short>
|
||||
( scope* ) [ LIT2 &scope $2 ] /<push-short>
|
||||
( line* ) ;token/line LDA2 /<push-short> }
|
||||
( | mark as used )
|
||||
syms/use LDA2 JMP2r
|
||||
|
||||
@refs/<push-short> ( value* -- )
|
||||
SWP /<push-byte>
|
||||
( >> )
|
||||
|
||||
@refs/<push-byte> ( byte -- )
|
||||
[ LIT2 &ptr =&mem ] INC2k
|
||||
( | check overflow )
|
||||
DUP2 ;&memend LTH2 ?{
|
||||
( ! ) ;dict/exceeded ;dict/References err/<token> }
|
||||
,&ptr STR2
|
||||
STA
|
||||
JMP2r
|
||||
|
||||
@refs/get-abs ( label* -- addr )
|
||||
;&handle-abs /get-type NIP JMP2r
|
||||
|
||||
@refs/get-abs2 ( label* -- addr* )
|
||||
;&handle-abs2 !/get-type
|
||||
|
||||
@refs/get-rel ( label* -- distance )
|
||||
;&handle-rel /get-type INC2k ORA ?{
|
||||
( undefined ) POP2 #00 JMP2r }
|
||||
head/get /get-distance syms/byte-distance NIP JMP2r
|
||||
|
||||
@refs/get-rel2 ( label* -- distance* )
|
||||
;&handle-rel2 /get-type head/get
|
||||
( >> )
|
||||
|
||||
@refs/get-distance ( a* b* -- distance* )
|
||||
INC2 INC2 SUB2 JMP2r
|
||||
|
||||
@refs/<resolve-all> ( -- )
|
||||
,&ptr LDR2 ;&mem
|
||||
&>l
|
||||
EQU2k ?{
|
||||
DUP2 ;err/ref STA2
|
||||
DUP2k #0004 ADD2 LDA2 JSR2
|
||||
( ) #000a ADD2 !&>l }
|
||||
POP2 POP2 JMP2r
|
||||
|
||||
@refs/resolve-sym ( ref* -- ref* sym/addr* )
|
||||
LDA2k head/<set>
|
||||
( ref* sym* ) INC2k INC2 LDA2
|
||||
( ref* sym/addr* ) LDA2
|
||||
( ref* sym/addr* ) INC2k ORA ?{
|
||||
( ! ) ;dict/invalid !err/<resolution> }
|
||||
( ref* sym/addr* ) JMP2r
|
||||
|
||||
@refs/handle-abs ( ref* -- )
|
||||
/resolve-sym NIP2 NIP !rom/<write-byte>
|
||||
|
||||
@refs/handle-abs2 ( ref* -- )
|
||||
/resolve-sym NIP2 !rom/<write-short>
|
||||
|
||||
@refs/handle-rel ( ref* -- )
|
||||
/resolve-sym SWP2 LDA2 /get-distance /byte-distance NIP !rom/<write-byte>
|
||||
|
||||
@refs/handle-rel2 ( ref* -- )
|
||||
/resolve-sym SWP2 LDA2 /get-distance !rom/<write-short>
|
||||
|
||||
@refs/byte-distance ( addr* -- addr* )
|
||||
DUP2 #0080 ADD2 POP ?{ JMP2r }
|
||||
( ! ) ;dict/too-far !err/<resolution>
|
||||
|
||||
@refs/<record-scope> ( sym* -- )
|
||||
DUP2 #0003 ADD2 LDA2 #cebb NEQ2 ?{ POP2 JMP2r }
|
||||
;refs/scope STA2
|
||||
JMP2r
|
||||
|
||||
(
|
||||
@|Rom )
|
||||
|
||||
@rom/<write-str> ( str* -- )
|
||||
;/<write-byte> !hof/<each>
|
||||
|
||||
@rom/<write-opcode> ( str* -- )
|
||||
opcodes/parse !/<write-byte>
|
||||
|
||||
@rom/<write-lithex> ( str* -- )
|
||||
str/len #02 NEQ #50 SFT #80 ORA /<write-byte>
|
||||
( >> )
|
||||
|
||||
@rom/<write-rawhex> ( str* -- )
|
||||
str/is-hex #00 EQU ?{
|
||||
str/len DUP #02 NEQ ?{ POP str/hex NIP !/<write-byte> }
|
||||
#04 NEQ ?{ str/hex !/<write-short> } }
|
||||
POP2 ;dict/invalid ;dict/Number !err/<token>
|
||||
|
||||
@rom/<write-call> ( str* opc -- )
|
||||
/<write-byte>
|
||||
refs/get-rel2
|
||||
( >> )
|
||||
|
||||
@rom/<write-short> ( short* -- )
|
||||
SWP /<write-byte>
|
||||
( >> )
|
||||
|
||||
@rom/<write-byte> ( byte -- )
|
||||
head/get-inc
|
||||
( | test zero-page )
|
||||
OVR ?{
|
||||
POP2 POP
|
||||
( ! ) ;dict/zero-page ;dict/Writing !err/<token> }
|
||||
!rom/<put>
|
||||
|
||||
@head/get-inc ( -- addr* )
|
||||
[ LIT2 &addr 0100 ] INC2k ,&addr STR2
|
||||
INC2k [ LIT2 &length 0100 ] LTH2 ?{ INC2k ,&length STR2 }
|
||||
JMP2r
|
||||
|
||||
@head/get ( -- addr* )
|
||||
,&addr LDR2 JMP2r
|
||||
|
||||
@head/<set-rel> ( addr* -- )
|
||||
/get ADD2
|
||||
( >> )
|
||||
|
||||
@head/<set> ( addr* -- )
|
||||
,&addr STR2
|
||||
JMP2r
|
||||
|
||||
(
|
||||
@|Stdlib )
|
||||
|
||||
@hof/<each> ( data* byte-fn* -- )
|
||||
STH2
|
||||
&>w
|
||||
LDAk DUP ?{ POP POP2 POP2r JMP2r }
|
||||
STH2kr JSR2 INC2 !&>w
|
||||
|
||||
@hexc ( hex -- char )
|
||||
#0f AND #0a LTHk ?{
|
||||
SUB [ LIT "a ] ADD JMP2r }
|
||||
POP [ LIT "0 ] ADD JMP2r
|
||||
|
||||
@chex ( addr* -- addr* <val> )
|
||||
LDAk
|
||||
( dec ) [ LIT "0 ] SUB DUP #09 GTH [ JMP JMP2r ]
|
||||
( hex ) #27 SUB DUP #0a SUB #05 GTH [ JMP JMP2r ]
|
||||
( nil ) POP #ff JMP2r
|
||||
|
||||
@str/hex ( str* -- value* )
|
||||
[ LIT2r 0000 ]
|
||||
&>wh
|
||||
[ LITr 40 ] SFT2r chex [ LITr 00 ] STH
|
||||
ADD2r INC2 LDAk ?&>wh
|
||||
POP2 STH2r JMP2r
|
||||
|
||||
@str/len ( str* -- str* length )
|
||||
DUP2k /cap SWP2 INC2 SUB2 NIP JMP2r
|
||||
|
||||
@str/is-hex ( str* -- str* f )
|
||||
DUP2
|
||||
&>wih
|
||||
chex INC ?{ LDA #00 EQU JMP2r }
|
||||
INC2 !&>wih
|
||||
|
||||
@str/cap ( str* -- end* )
|
||||
LDAk ?{ INC2 JMP2r }
|
||||
INC2 !/cap
|
||||
|
||||
@str/cmp ( a* b* -- bool )
|
||||
DUP2k /cap SWP2 SUB2 SWP2
|
||||
( >> )
|
||||
|
||||
@mem/cmp ( a* length* b* -- t )
|
||||
STH2
|
||||
OVR2 ADD2 SWP2
|
||||
&>l
|
||||
EQU2k ?{
|
||||
LDAk LDAkr STHr NEQ ?{ INC2 INC2r !&>l } }
|
||||
POP2r EQU2 JMP2r
|
||||
|
||||
(
|
||||
@|Error )
|
||||
|
||||
@err/<token> ( adj* topic* -- )
|
||||
.System/state DEI ?{
|
||||
[ LIT2 01 -System/state ] DEO
|
||||
/<print>
|
||||
#20 /<emit>
|
||||
/<print>
|
||||
;dict/spacer /<print>
|
||||
;token/buf /<print>
|
||||
;token/line LDA2 ;scope/buf !/<print-location> }
|
||||
POP2 POP2 JMP2r
|
||||
|
||||
@err/<resolution> ( adj* -- )
|
||||
.System/state DEI ?{
|
||||
[ LIT2 01 -System/state ] DEO
|
||||
;dict/Reference /<print>
|
||||
#20 /<emit>
|
||||
/<print>
|
||||
;dict/spacer /<print>
|
||||
[ LIT2 &ref $2 ] INC2k INC2 LDA2 #0003 ADD2 /<print>
|
||||
DUP2 #0008 ADD2 LDA2 SWP2 #0006 ADD2 LDA2 #0003 ADD2 !/<print-location> }
|
||||
POP2 JMP2r
|
||||
|
||||
@err/<print-location> ( line* scope* -- )
|
||||
;dict/in /<print>
|
||||
/<print>
|
||||
LIT ": /<emit>
|
||||
/<pdec>
|
||||
#0a /<emit>
|
||||
JMP2r
|
||||
|
||||
@err/<generic> ( adj* keyword* topic* -- )
|
||||
.System/state DEI ?{
|
||||
[ LIT2 01 -System/state ] DEO
|
||||
/<print>
|
||||
#20 /<emit>
|
||||
SWP2 /<print>
|
||||
;dict/spacer /<print>
|
||||
/<print>
|
||||
#0a /<emit>
|
||||
JMP2r }
|
||||
POP2 POP2 POP2 JMP2r
|
||||
|
||||
@err/<print> ( str* -- )
|
||||
;/<emit> !hof/<each>
|
||||
|
||||
@err/<pdec> ( short* -- )
|
||||
[ LIT2r ff00 ]
|
||||
&>read
|
||||
#000a DIV2k STH2k MUL2 SUB2 STH2r INCr ORAk ?&>read
|
||||
POP2
|
||||
&>write
|
||||
NIP #30 ADD /<emit>
|
||||
OVRr ADDr STHkr ?&>write
|
||||
POP2r JMP2r
|
||||
|
||||
@dict/assembled "Assembled $1 &in 20 "in 20 $1 &bytes 20 "bytes. 0a $1
|
||||
&unused "-- 20 "Unused
|
||||
&spacer ": 20 $1
|
||||
&References "References $1
|
||||
&Reference "Reference $1
|
||||
&Symbols "Symbols $1
|
||||
&Symbol "Symbol $1
|
||||
&Macros "Macros $1
|
||||
&Macro "Macro $1
|
||||
&Name "Name $1
|
||||
&Number "Number $1
|
||||
&Comment "Comment $1
|
||||
&Writing "Writing $1
|
||||
&exceeded "exceeded $1
|
||||
&invalid "invalid $1
|
||||
&duplicate "duplicate $1
|
||||
&too-far "too 20 "far $1
|
||||
&zero-page "zero-page $1
|
||||
&open "open $1
|
||||
&trail ".. $1
|
||||
&reset "RESET $1
|
||||
|
||||
(
|
||||
@|Buffers )
|
||||
|
||||
@lambda/mem $100
|
||||
|
||||
@macros/mem ( name\0, value\0 )
|
||||
$1000 &memend
|
||||
|
||||
@refs/mem ( addr*, symbol*, type-fn*, scope*, line* )
|
||||
$3000 &memend
|
||||
|
||||
@syms/mem ( addr*, SymType, name\0 )
|
||||
$4800 &memend
|
||||
|
||||
@rom/mem ( zeropage )
|
||||
$100
|
||||
&output
|
||||
(
|
||||
@|Enums )
|
||||
|
||||
|
||||
|00 @SymType/empty $1 &used $1 &declared
|
||||
509
utils/opctest.tal
Normal file
509
utils/opctest.tal
Normal file
|
|
@ -0,0 +1,509 @@
|
|||
|0013
|
||||
|
||||
@Zeropage &byte $1 &short $2
|
||||
@id $1
|
||||
|
||||
|100
|
||||
|
||||
@on-reset ( -> )
|
||||
|
||||
( part 1
|
||||
> LIT2: Puts a short on the stack
|
||||
> LIT: Puts a byte on the stack
|
||||
> #06 DEO: Write to metadata ports
|
||||
> #18 DEO: Write a letter in terminal )
|
||||
|
||||
;meta #06 DEO2
|
||||
[ LIT2 "kO ] #18 DEO #18 DEO
|
||||
[ LIT2 "1 18 ] DEO #0a18 DEO
|
||||
|
||||
( part 2
|
||||
> LITr: Put a byte on return stack
|
||||
> STH: Move a byte from working stack to return stack
|
||||
> STH2r: Move a short from return stack to working stack )
|
||||
|
||||
[ LITr "k ] [ LIT "O ] STH STH2r #18 DEO #18 DEO
|
||||
[ LIT2 "2 18 ] DEO #0a18 DEO
|
||||
|
||||
( part 3
|
||||
> LIT2r: Put a short on return stack
|
||||
> DUP: Duplicate byte
|
||||
> ADDr: Add bytes on return stack )
|
||||
|
||||
[ LIT2r "k 4d ] #01 DUP STH ADDr STH ADDr STH2r #18 DEO #18 DEO
|
||||
[ LIT2 "3 18 ] DEO #0a18 DEO
|
||||
|
||||
( part 4
|
||||
> JSI: Subroutine to relative short address
|
||||
> JMP2r: Jumps to absolute address on return stack )
|
||||
|
||||
subroutine
|
||||
[ LIT2 "4 18 ] DEO #0a18 DEO
|
||||
|
||||
( part 5
|
||||
> POP2: Removes a short from the stack
|
||||
> INC2: Increments short on stack
|
||||
> DUP2: Duplicate short
|
||||
> LDA: load byte from absolute address
|
||||
> JCI: Conditional subroutine to relative short address )
|
||||
|
||||
;Dict/ok pstr
|
||||
[ LIT2 "5 18 ] DEO #0a18 DEO
|
||||
|
||||
( part 6
|
||||
> JSR2: Jump to subroutine from short pointer
|
||||
> LDAk: Non-destructive load byte from absolute address )
|
||||
|
||||
{ "Ok $1 } STH2r ;pstr-jcn JSR2
|
||||
[ LIT2 "6 18 ] DEO #0a18 DEO
|
||||
|
||||
( part 7
|
||||
> Relative distance bytes )
|
||||
|
||||
rel-distance/entry SWP #18 DEO #18 DEO
|
||||
[ LIT2 "7 18 ] DEO #0a18 DEO
|
||||
|
||||
( part xx
|
||||
> GTH2k: Non-destructive greater-than short
|
||||
> LDA2k: Non-destructive load short from absolute address
|
||||
> STA2: Store short at absolute address )
|
||||
|
||||
[ LIT2r 0000 ]
|
||||
;tests/end ;tests
|
||||
&l
|
||||
run-test [ LITr 00 ] STH ADD2r
|
||||
INC2 INC2 GTH2k ?&l
|
||||
POP2 POP2
|
||||
STH2r ;tests/end ;tests SUB2 #01 SFT2
|
||||
EQU2 ;Dict/opctests test-part
|
||||
|
||||
( Part xx
|
||||
> Testing that stacks are circular and wrapping
|
||||
> Storing 12 at -1 and 34 at 0 )
|
||||
|
||||
POP #12 #34 ADD #46 EQU STH
|
||||
POP #1234 ADD #46 EQU STH
|
||||
POP2 #1111 #2222 ADD2 #3333 EQU2
|
||||
STHr AND STHr AND
|
||||
;Dict/stack-wrap test-part
|
||||
|
||||
( restore stack ) #0000 #0000
|
||||
|
||||
( Part xx
|
||||
> Testing RAM wrapping
|
||||
> Storing 12 in 0xffff, and 34 in 0x0000 )
|
||||
|
||||
#1234 #ffff STA2
|
||||
( LDA ) #0000 LDA #ffff LDA ADD #46 EQU
|
||||
( LDA2 ) #ffff LDA2 ADD #46 EQU
|
||||
AND ;Dict/ram-wrap test-part
|
||||
|
||||
( Part xx
|
||||
> Testing PC wrapping: split instruction
|
||||
> Storing 80[LIT] in 0xffff, and 55[val8] in 0x0000
|
||||
> Storing 6c[JMP2r] in 0x0001 )
|
||||
|
||||
#8055 #ffff STA2 #6c #01 STZ #ffff JSR2 #55 EQU
|
||||
;Dict/pc-wrap test-part
|
||||
|
||||
( Part xx
|
||||
> Testing PC wrapping: split value after instruction
|
||||
> Storing a0[LIT2] in 0xfffe,
|
||||
> and 0x55[hi-byte] in 0xffff, and 0xaa[lo-byte] in 0x0000
|
||||
> Storing 6c[JMP2r] in 0x0001 )
|
||||
|
||||
#a055 #fffe STA2 #aa6c #0000 STA2 #fffe JSR2 #55aa EQU2
|
||||
;Dict/pc2-wrap test-part
|
||||
|
||||
( Part xx
|
||||
> Testing that zero-page is wrapping )
|
||||
|
||||
#5678 #ff STZ2
|
||||
( LDZ ) #00 LDZ #ff LDZ ADD #ce EQU
|
||||
( LDZ2 ) #ff LDZ2 ADD #ce EQU
|
||||
AND ;Dict/zp-wrap test-part
|
||||
|
||||
( Part xx
|
||||
> Testing that device page is wrapping )
|
||||
|
||||
#1234 #ff DEO2
|
||||
( DEI ) #00 DEI #ff DEI ADD #46 EQU
|
||||
( DEI2 ) #ff DEI2 ADD #46 EQU
|
||||
AND ;Dict/dev-wrap test-part
|
||||
#0000 DEO #00ff DEO
|
||||
|
||||
( end )
|
||||
|
||||
[ LIT &fail 80 ]
|
||||
DUP #80 EQU ;Dict/result test-part
|
||||
#0f DEO
|
||||
|
||||
#0a18 DEO
|
||||
#010e DEO
|
||||
|
||||
BRK
|
||||
|
||||
(
|
||||
@|metadata )
|
||||
|
||||
@meta 00
|
||||
( name ) "Opctest 0a
|
||||
( details ) "A 20 "Testing 20 "Program 0a
|
||||
( author ) "By 20 "Devine 20 "Lu 20 "Linvega 0a
|
||||
( date ) "24 20 "Jun 20 "2025 $2
|
||||
|
||||
@test-part ( f name* -- )
|
||||
pstr ?{
|
||||
#01 ;on-reset/fail STA
|
||||
;Dict/failed !pstr }
|
||||
;Dict/passed !pstr
|
||||
|
||||
@run-test ( addr* -- addr* f )
|
||||
|
||||
LDA2k JSR2 DUP ?&pass
|
||||
;Dict/missed pstr
|
||||
[ LIT2 &name $2 ] pstr
|
||||
[ LIT2 "# 18 ] DEO
|
||||
[ LIT2 "a -id ] LDZ ADD #18 DEO
|
||||
#0a18 DEO
|
||||
#01 ;on-reset/fail STA
|
||||
&pass
|
||||
.id LDZ INC .id STZ
|
||||
|
||||
JMP2r
|
||||
|
||||
@set ( name* -- f )
|
||||
|
||||
;run-test/name STA2 #01
|
||||
[ LIT2 ff -id ] STZ
|
||||
|
||||
JMP2r
|
||||
|
||||
@pstr ( str* -- )
|
||||
DUP2 LDA
|
||||
DUP ?{ POP POP2 JMP2r }
|
||||
#18 DEO
|
||||
INC2 !pstr
|
||||
|
||||
@pstr-jcn ( str* -- )
|
||||
LDAk #18 DEO
|
||||
INC2 LDAk ,pstr-jcn JCN
|
||||
POP2
|
||||
JMP2r
|
||||
|
||||
@tests
|
||||
=op-equ [
|
||||
=op-equ/a =op-equ/b =op-equ/c =op-equ/d
|
||||
=op-equ/e =op-equ/f =op-equ/g =op-equ/h ]
|
||||
=op-neq [
|
||||
=op-neq/a =op-neq/b =op-neq/c =op-neq/d
|
||||
=op-neq/e =op-neq/f =op-neq/g =op-neq/h ]
|
||||
=op-gth [
|
||||
=op-gth/a =op-gth/b =op-gth/c =op-gth/d
|
||||
=op-gth/e =op-gth/f =op-gth/g =op-gth/h ]
|
||||
=op-lth [
|
||||
=op-lth/a =op-lth/b =op-lth/c =op-lth/d
|
||||
=op-lth/e =op-lth/f =op-lth/g =op-lth/h ]
|
||||
=op-add [
|
||||
=op-add/a =op-add/b =op-add/c =op-add/d
|
||||
=op-add/e =op-add/f =op-add/g =op-add/h ]
|
||||
=op-sub [
|
||||
=op-sub/a =op-sub/b =op-sub/c =op-sub/d
|
||||
=op-sub/e =op-sub/f =op-sub/g =op-sub/h ]
|
||||
=op-mul [
|
||||
=op-mul/a =op-mul/b =op-mul/c =op-mul/d
|
||||
=op-mul/e =op-mul/f =op-mul/g =op-mul/h ]
|
||||
=op-div [
|
||||
=op-div/a =op-div/b =op-div/c =op-div/d =op-div/e
|
||||
=op-div/f =op-div/g =op-div/h =op-div/i =op-div/j ]
|
||||
=op-inc [
|
||||
=op-inc/a =op-inc/b =op-inc/c =op-inc/d
|
||||
=op-inc/e =op-inc/f =op-inc/g =op-inc/h ]
|
||||
=op-pop [
|
||||
=op-pop/a =op-pop/b =op-pop/c =op-pop/d
|
||||
=op-pop/e =op-pop/f =op-pop/g =op-pop/h ]
|
||||
=op-dup [
|
||||
=op-dup/a =op-dup/b ]
|
||||
=op-nip [
|
||||
=op-nip/a =op-nip/b =op-nip/c =op-nip/d ]
|
||||
=op-swp [
|
||||
=op-swp/a =op-swp/b ]
|
||||
=op-ovr [
|
||||
=op-ovr/a =op-ovr/b ]
|
||||
=op-rot [
|
||||
=op-rot/a =op-rot/b ]
|
||||
=op-and [
|
||||
=op-and/a =op-and/b =op-and/c =op-and/d
|
||||
=op-and/e =op-and/f =op-and/g =op-and/h ]
|
||||
=op-ora [
|
||||
=op-ora/a =op-ora/b =op-ora/c =op-ora/d
|
||||
=op-ora/e =op-ora/f =op-ora/g =op-ora/h ]
|
||||
=op-eor [
|
||||
=op-eor/a =op-eor/b =op-eor/c =op-eor/d
|
||||
=op-eor/e =op-eor/f =op-eor/g =op-eor/h ]
|
||||
=op-sft [
|
||||
=op-sft/a =op-sft/b =op-sft/c =op-sft/d
|
||||
=op-sft/e =op-sft/f =op-sft/g =op-sft/h ]
|
||||
=op-stz [
|
||||
=op-stz/a =op-stz/b =op-stz/c =op-stz/d ]
|
||||
=op-str [
|
||||
=op-str/a =op-str/b =op-str/c =op-str/d ]
|
||||
=op-sta [
|
||||
=op-sta/a =op-sta/b =op-sta/c =op-sta/d ]
|
||||
=op-jmp [
|
||||
=op-jmp/a =op-jmp/b ]
|
||||
=op-jcn [
|
||||
=op-jcn/a =op-jcn/b =op-jcn/c =op-jcn/d ]
|
||||
=op-jsr [
|
||||
=op-jsr/a =op-jsr/b ]
|
||||
=op-sth [
|
||||
=op-sth/a =op-sth/b ]
|
||||
=op-jci [
|
||||
=op-jci/a =op-jci/b =op-jci/c ]
|
||||
=op-jmi [
|
||||
=op-jmi/a ]
|
||||
=op-jsi [
|
||||
=op-jsi/a =op-jsi/b =op-jsi/c =op-jsi/d ]
|
||||
&end
|
||||
|
||||
@op-equ ;Dict/equ !set
|
||||
&a #f8 #f8 EQU [ #01 ] EQU JMP2r
|
||||
&b #01 #01 EQU [ #01 ] EQU JMP2r
|
||||
&c #f8 #01 EQU [ #00 ] EQU JMP2r
|
||||
&d #00 #ff EQU [ #00 ] EQU JMP2r
|
||||
&e #f801 #f801 EQU2 [ #01 ] EQU JMP2r
|
||||
&f #01f8 #01f8 EQU2 [ #01 ] EQU JMP2r
|
||||
&g #f801 #01f8 EQU2 [ #00 ] EQU JMP2r
|
||||
&h #01f8 #f801 EQU2 [ #00 ] EQU JMP2r
|
||||
@op-neq ;Dict/neq !set
|
||||
&a #f8 #f8 NEQ [ #00 ] EQU JMP2r
|
||||
&b #01 #01 NEQ [ #00 ] EQU JMP2r
|
||||
&c #f8 #01 NEQ [ #01 ] EQU JMP2r
|
||||
&d #01 #f8 NEQ [ #01 ] EQU JMP2r
|
||||
&e #f801 #f801 NEQ2 [ #00 ] EQU JMP2r
|
||||
&f #01f8 #01f8 NEQ2 [ #00 ] EQU JMP2r
|
||||
&g #f801 #01f8 NEQ2 [ #01 ] EQU JMP2r
|
||||
&h #01f8 #f801 NEQ2 [ #01 ] EQU JMP2r
|
||||
@op-gth ;Dict/gth !set
|
||||
&a #f8 #f8 GTH [ #00 ] EQU JMP2r
|
||||
&b #01 #01 GTH [ #00 ] EQU JMP2r
|
||||
&c #f8 #01 GTH [ #01 ] EQU JMP2r
|
||||
&d #01 #f8 GTH [ #00 ] EQU JMP2r
|
||||
&e #f801 #f801 GTH2 [ #00 ] EQU JMP2r
|
||||
&f #01f8 #01f8 GTH2 [ #00 ] EQU JMP2r
|
||||
&g #f801 #01f8 GTH2 [ #01 ] EQU JMP2r
|
||||
&h #01f8 #f801 GTH2 [ #00 ] EQU JMP2r
|
||||
@op-lth ;Dict/lth !set
|
||||
&a #f8 #f8 LTH [ #00 ] EQU JMP2r
|
||||
&b #01 #01 LTH [ #00 ] EQU JMP2r
|
||||
&c #f8 #01 LTH [ #00 ] EQU JMP2r
|
||||
&d #01 #ff LTH [ #01 ] EQU JMP2r
|
||||
&e #f801 #f801 LTH2 [ #00 ] EQU JMP2r
|
||||
&f #01f8 #01f8 LTH2 [ #00 ] EQU JMP2r
|
||||
&g #f801 #01f8 LTH2 [ #00 ] EQU JMP2r
|
||||
&h #01f8 #f801 LTH2 [ #01 ] EQU JMP2r
|
||||
@op-add ;Dict/add !set
|
||||
&a #ff #00 ADD [ #ff ] EQU JMP2r
|
||||
&b #01 #ff ADD [ #00 ] EQU JMP2r
|
||||
&c #ff #ff ADD [ #fe ] EQU JMP2r
|
||||
&d #12 #34 ADDk ADD ADD [ #8c ] EQU JMP2r
|
||||
&e #ffff #0000 ADD2 [ #ffff ] EQU2 JMP2r
|
||||
&f #0001 #ffff ADD2 [ #0000 ] EQU2 JMP2r
|
||||
&g #ffff #ffff ADD2 [ #fffe ] EQU2 JMP2r
|
||||
&h #fffe #ffff ADD2 [ #fffd ] EQU2 JMP2r
|
||||
@op-sub ;Dict/sub !set
|
||||
&a #ff #00 SUB [ #ff ] EQU JMP2r
|
||||
&b #01 #ff SUB [ #02 ] EQU JMP2r
|
||||
&c #ff #ff SUB [ #00 ] EQU JMP2r
|
||||
&d #fe #ff SUB [ #ff ] EQU JMP2r
|
||||
&e #ffff #0000 SUB2 [ #ffff ] EQU2 JMP2r
|
||||
&f #0001 #ffff SUB2 [ #0002 ] EQU2 JMP2r
|
||||
&g #ffff #ffff SUB2 [ #0000 ] EQU2 JMP2r
|
||||
&h #fffe #ffff SUB2 [ #ffff ] EQU2 JMP2r
|
||||
@op-mul ;Dict/mul !set
|
||||
&a #00 #01 MUL [ #00 ] EQU JMP2r
|
||||
&b #3f #e7 MUL [ #d9 ] EQU JMP2r
|
||||
&c #37 #3f MUL [ #89 ] EQU JMP2r
|
||||
&d #10 #02 MUL [ #20 ] EQU JMP2r
|
||||
&e #1000 #0003 MUL2 [ #3000 ] EQU2 JMP2r
|
||||
&f #abcd #1234 MUL2 [ #4fa4 ] EQU2 JMP2r
|
||||
&g #8000 #0200 MUL2 [ #0000 ] EQU2 JMP2r
|
||||
&h #2222 #0003 MUL2 [ #6666 ] EQU2 JMP2r
|
||||
@op-div ;Dict/div !set
|
||||
&a #10 #06 DIV [ #02 ] EQU JMP2r
|
||||
&b #20 #20 DIV [ #01 ] EQU JMP2r
|
||||
&c #34 #01 DIV [ #34 ] EQU JMP2r
|
||||
&d #02 #ef DIV [ #00 ] EQU JMP2r
|
||||
&e #02 #00 DIV [ #00 ] EQU JMP2r
|
||||
&f #03e8 #0006 DIV2 [ #00a6 ] EQU2 JMP2r
|
||||
&g #abcd #1234 DIV2 [ #0009 ] EQU2 JMP2r
|
||||
&h #8000 #0200 DIV2 [ #0040 ] EQU2 JMP2r
|
||||
&i #2222 #0003 DIV2 [ #0b60 ] EQU2 JMP2r
|
||||
&j #0202 #0000 DIV2 [ #0000 ] EQU2 JMP2r
|
||||
@op-inc ;Dict/inc !set
|
||||
&a #01 INC [ #02 ] EQU JMP2r
|
||||
&b #ff INC [ #00 ] EQU JMP2r
|
||||
&c #fe INC [ #ff ] EQU JMP2r
|
||||
&d #00 INC [ #01 ] EQU JMP2r
|
||||
&e #0001 INC2 [ #0002 ] EQU2 JMP2r
|
||||
&f #ffff INC2 [ #0000 ] EQU2 JMP2r
|
||||
&g #fffe INC2 [ #ffff ] EQU2 JMP2r
|
||||
&h #0000 INC2 [ #0001 ] EQU2 JMP2r
|
||||
@op-pop ;Dict/pop !set
|
||||
&a #0a #0b POP [ #0a ] EQU JMP2r
|
||||
&b #0a #0b #0c POP POP [ #0a ] EQU JMP2r
|
||||
&c #0a #0b #0c ADD POP [ #0a ] EQU JMP2r
|
||||
&d #0a #0b #0c POP ADD [ #15 ] EQU JMP2r
|
||||
&e #0a0b #0c0d POP2 [ #0a0b ] EQU2 JMP2r
|
||||
&f #0a0b #0c0d #0e0f POP2 POP2 [ #0a0b ] EQU2 JMP2r
|
||||
&g #0a0b #0c0d #0e0f ADD2 POP2 [ #0a0b ] EQU2 JMP2r
|
||||
&h #0a0b #0c0d #0e0f POP2 ADD2 [ #1618 ] EQU2 JMP2r
|
||||
@op-dup ;Dict/dup !set
|
||||
&a #0a #0b DUP ADD ADD [ #20 ] EQU JMP2r
|
||||
&b #0a0b DUP2 ADD2 [ #1416 ] EQU2 JMP2r
|
||||
@op-nip ;Dict/nip !set
|
||||
&a #12 #34 #56 NIP ADD [ #68 ] EQU JMP2r
|
||||
&b #12 #34 #56 NIPk ADD2 ADD [ #f2 ] EQU JMP2r
|
||||
&c #1234 #5678 #9abc NIP2 ADD2 [ #acf0 ] EQU2 JMP2r
|
||||
&d #1234 #5678 #9abc NIP2k ADD2 ADD2 ADD2 [ #9e24 ] EQU2 JMP2r
|
||||
@op-swp ;Dict/swp !set
|
||||
&a #02 #10 SWP DIV [ #08 ] EQU JMP2r
|
||||
&b #0a0b #0c0d SWP2 NIP2 [ #0a0b ] EQU2 JMP2r
|
||||
@op-ovr ;Dict/ovr !set
|
||||
&a #02 #10 OVR DIV ADD [ #0a ] EQU JMP2r
|
||||
&b #0a0b #0c0d OVR2 NIP2 ADD2 [ #1416 ] EQU2 JMP2r
|
||||
@op-rot ;Dict/rot !set
|
||||
&a #02 #04 #10 ROT DIV ADD [ #0c ] EQU JMP2r
|
||||
&b #0a0b #0c0d #0c0f ROT2 ADD2 NIP2 [ #161a ] EQU2 JMP2r
|
||||
@op-and ;Dict/and !set
|
||||
&a #fc #3f AND [ #3c ] EQU JMP2r
|
||||
&b #f0 #0f AND [ #00 ] EQU JMP2r
|
||||
&c #ff #3c AND [ #3c ] EQU JMP2r
|
||||
&d #02 #03 AND [ #02 ] EQU JMP2r
|
||||
&e #f0f0 #00f0 AND2 [ #00f0 ] EQU2 JMP2r
|
||||
&f #aaaa #5555 AND2 [ #0000 ] EQU2 JMP2r
|
||||
&g #ffff #1234 AND2 [ #1234 ] EQU2 JMP2r
|
||||
&h #abcd #0a0c AND2 [ #0a0c ] EQU2 JMP2r
|
||||
@op-ora ;Dict/ora !set
|
||||
&a #0f #f0 ORA [ #ff ] EQU JMP2r
|
||||
&b #ab #cd ORA [ #ef ] EQU JMP2r
|
||||
&c #12 #34 ORA [ #36 ] EQU JMP2r
|
||||
&d #88 #10 ORA [ #98 ] EQU JMP2r
|
||||
&e #0f0f #f0f0 ORA2 [ #ffff ] EQU2 JMP2r
|
||||
&f #abab #cdcd ORA2 [ #efef ] EQU2 JMP2r
|
||||
&g #1122 #1234 ORA2 [ #1336 ] EQU2 JMP2r
|
||||
&h #8888 #1000 ORA2 [ #9888 ] EQU2 JMP2r
|
||||
@op-eor ;Dict/eor !set
|
||||
&a #00 #00 EOR [ #00 ] EQU JMP2r
|
||||
&b #ff #00 EOR [ #ff ] EQU JMP2r
|
||||
&c #aa #55 EOR [ #ff ] EQU JMP2r
|
||||
&d #ff #ff EOR [ #00 ] EQU JMP2r
|
||||
&e #ffff #ff00 EOR2 [ #00ff ] EQU2 JMP2r
|
||||
&f #aaaa #5555 EOR2 [ #ffff ] EQU2 JMP2r
|
||||
&g #1122 #1234 EOR2 [ #0316 ] EQU2 JMP2r
|
||||
&h #8888 #1000 EOR2 [ #9888 ] EQU2 JMP2r
|
||||
@op-sft ;Dict/sft !set
|
||||
&a #ff #08 SFT [ #00 ] EQU JMP2r
|
||||
&b #ff #e0 SFT [ #00 ] EQU JMP2r
|
||||
&c #ff #11 SFT [ #fe ] EQU JMP2r
|
||||
&d #ff #12 SFT [ #7e ] EQU JMP2r
|
||||
&e #ffff #01 SFT2 [ #7fff ] EQU2 JMP2r
|
||||
&f #ffff #70 SFT2 [ #ff80 ] EQU2 JMP2r
|
||||
&g #ffff #7e SFT2 [ #0180 ] EQU2 JMP2r
|
||||
&h #ffff #e3 SFT2 [ #c000 ] EQU2 JMP2r
|
||||
@op-stz ;Dict/stz !set
|
||||
&a #ab .Zeropage/byte STZ .Zeropage/byte LDZ [ #ab ] EQU JMP2r
|
||||
&b #cd .Zeropage/byte STZ .Zeropage/byte LDZ [ #cd ] EQU JMP2r
|
||||
&c #1234 .Zeropage/short STZ2 .Zeropage/short LDZ2 [ #1234 ] EQU2 JMP2r
|
||||
&d #5678 .Zeropage/short STZ2 .Zeropage/short LDZ2 [ #5678 ] EQU2 JMP2r
|
||||
@op-str ;Dict/str !set
|
||||
[ LIT &before1 $1 ] [ LIT2 &before2 $2 ]
|
||||
&a #22 ,&before1 STR ,&before1 LDR [ #22 ] EQU JMP2r
|
||||
&b #ef ,&after1 STR ,&after1 LDR [ #ef ] EQU JMP2r
|
||||
&c #1234 ,&before2 STR2 ,&before2 LDR2 [ #1234 ] EQU2 JMP2r
|
||||
&d #5678 ,&after2 STR2 ,&after2 LDR2 [ #5678 ] EQU2 JMP2r
|
||||
[ LIT &after1 $1 ] [ LIT2 &after2 $2 ]
|
||||
@op-sta ;Dict/sta !set
|
||||
&a #34 ;Absolute/byte STA ;Absolute/byte LDA [ #34 ] EQU JMP2r
|
||||
&b #56 ;Absolute/byte STA ;Absolute/byte LDA [ #56 ] EQU JMP2r
|
||||
&c #1234 ;Absolute/short STA2 ;Absolute/short LDA2 [ #1234 ] EQU2 JMP2r
|
||||
&d #5678 ;Absolute/short STA2 ;Absolute/short LDA2 [ #5678 ] EQU2 JMP2r
|
||||
@op-jmp ;Dict/jmp !set
|
||||
&a #12 #34 ,&reljmp JMP SWP &reljmp POP [ #12 ] EQU JMP2r
|
||||
&b #56 #78 ;&absjmp JMP2 SWP &absjmp POP [ #56 ] EQU JMP2r
|
||||
@op-jcn ;Dict/jcn !set
|
||||
&a #23 #01 ,&reljcn-y JCN INC &reljcn-y [ #23 ] EQU JMP2r
|
||||
&b #23 #00 ,&reljcn-n JCN INC &reljcn-n [ #24 ] EQU JMP2r
|
||||
&c #23 #01 ;&absjcn-y JCN2 INC &absjcn-y [ #23 ] EQU JMP2r
|
||||
&d #23 #00 ;&absjcn-n JCN2 INC &absjcn-n [ #24 ] EQU JMP2r
|
||||
@op-jsr ;Dict/jsr !set
|
||||
&a #1234 #5678 ,&routine JSR [ #68ac ] EQU2 JMP2r
|
||||
&b #12 #34 ;routine JSR2 [ #46 ] EQU JMP2r
|
||||
&routine ADD2 JMP2r
|
||||
@op-sth ;Dict/sth !set
|
||||
&a #0a STH #0b STH ADDr STHr [ #15 ] EQU JMP2r
|
||||
&b #000a STH2 #000b STH2 ADD2r STH2r [ #0015 ] EQU2 JMP2r
|
||||
@op-jci ;Dict/jci !set
|
||||
&before #01 JMP2r
|
||||
&a #01 ?&skip-a #00 JMP2r &skip-a #01 JMP2r
|
||||
&b #00 ?&skip-b #01 JMP2r &skip-b #00 JMP2r
|
||||
&c #01 ?&before #00 JMP2r
|
||||
@op-jmi ;Dict/jmi !set
|
||||
&a !&skip-a #00 JMP2r &skip-a #01 JMP2r
|
||||
@op-jsi ;Dict/jsi !set
|
||||
&a #02 #04 routine #06 EQU JMP2r
|
||||
&b ;&return special &return JMP2r
|
||||
&c ,&skip-c JMP &routine-c ADD JMP2r &skip-c #02 #04 op-jsi/routine-c #06 EQU JMP2r
|
||||
&d ,&skip-d JMP &routine-d ADD JMP2r &skip-d #02 #04 op-jsi-far-routine-d #06 EQU JMP2r
|
||||
|
||||
@special ( routine* -- f )
|
||||
|
||||
( test that the stack order is LIFO )
|
||||
DUP2 STH2kr EQU2
|
||||
ROT ROT DUP2r STHr STHr SWP EQU2 AND
|
||||
|
||||
JMP2r
|
||||
|
||||
@routine ( a b -- c ) ADD JMP2r
|
||||
@subroutine ( -- ) [ LIT2 "kO ] #18 DEO #18 DEO JMP2r
|
||||
@Absolute &byte $1 &short $2
|
||||
|
||||
@Dict [
|
||||
&ok "Ok $1
|
||||
&done "Tests 20 "Complete. 0a $1
|
||||
&opctests "Opcodes $1
|
||||
&stack-wrap "Stack-wrap $1
|
||||
&ram-wrap "RAM-wrap $1
|
||||
&pc-wrap "PC-wrap $1
|
||||
&pc2-wrap "PC2-wrap $1
|
||||
&zp-wrap "Zeropage-wrap $1
|
||||
&dev-wrap "Devices-wrap $1
|
||||
&result "Result: $1
|
||||
&passed 20 "passed! 0a $1
|
||||
&missed "Opcode 20 "Failed 20 "-- 20 $1
|
||||
&failed 20 "failed. 0a $1
|
||||
&equ "EQU $1 &neq "NEQ $1 >h "GTH $1 <h "LTH $1
|
||||
&add "ADD $1 &sub "SUB $1 &mul "MUL $1 &div "DIV $1
|
||||
&inc "INC $1 &pop "POP $1 &dup "DUP $1 &nip "NIP $1
|
||||
&swp "SWP $1 &ovr "OVR $1 &rot "ROT $1
|
||||
&and "AND $1 &ora "ORA $1 &eor "EOR $1 &sft "SFT $1
|
||||
&stz "STZ $1 &str "STR $1 &sta "STA $1
|
||||
&jmp "JMP $1 &jcn "JCN $1 &jsr "JSR $1 &sth "STH $1
|
||||
&jmi "JMI $1 &jci "JCI $1 &jsi "JSI $1
|
||||
]
|
||||
|
||||
(
|
||||
@|Relative Distance Bytes )
|
||||
|
||||
@rel-distance
|
||||
&back "O $7c
|
||||
&entry
|
||||
,&back LDR
|
||||
,&forw LDR
|
||||
JMP2r
|
||||
$7e
|
||||
&forw "k
|
||||
|
||||
@op-jsi-far-routine-d
|
||||
op-jsi/routine-d JMP2r
|
||||
|
||||
BIN
utils/uxnmin
Executable file
BIN
utils/uxnmin
Executable file
Binary file not shown.
135
utils/uxnmin.c
Normal file
135
utils/uxnmin.c
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#include <stdio.h>
|
||||
|
||||
static unsigned int console_vector;
|
||||
static unsigned char ram[0x10000], dev[0x100], ptr[2], stk[2][0x100];
|
||||
|
||||
static unsigned char
|
||||
emu_dei(const unsigned char port)
|
||||
{
|
||||
return dev[port];
|
||||
}
|
||||
|
||||
static void
|
||||
emu_deo(const unsigned char port, const unsigned char value)
|
||||
{
|
||||
dev[port] = value;
|
||||
switch(port) {
|
||||
case 0x11: console_vector = dev[0x10] << 8 | value; return;
|
||||
case 0x18: fputc(value, stdout); return;
|
||||
case 0x19: fputc(value, stderr); return;
|
||||
}
|
||||
}
|
||||
|
||||
#define REM ptr[_r] -= 1 + _2;
|
||||
#define DEC(m) stk[m][--ptr[m]]
|
||||
#define INC(m) stk[m][ptr[m]++]
|
||||
#define IMM(r) { r = ram[pc++] << 8, r |= ram[pc++]; }
|
||||
#define MOV(x) { if(_2) pc = x; else pc += (signed char)x; }
|
||||
#define PO1(o) o = DEC(_r);
|
||||
#define PO2(o) { PO1(o) o |= DEC(_r) << 8; }
|
||||
#define POx(o) if(_2) PO2(o) else PO1(o)
|
||||
#define GOT(o) if(_2) PO1(o[1]) PO1(o[0])
|
||||
#define DEO(o,r) emu_deo(o, r[0]); if(_2) emu_deo(o + 1, r[1]);
|
||||
#define POK(o,r,m) ram[o] = r[0]; if(_2) ram[(o + 1) & m] = r[1];
|
||||
#define RP1(i) INC(!_r) = i;
|
||||
#define PU1(i) INC(_r) = i;
|
||||
#define PUx(i) if(_2) { c = (i); PU1(c >> 8) PU1(c) } else PU1(i)
|
||||
#define PUT(i) PU1(i[0]) if(_2) PU1(i[1])
|
||||
#define DEI(i,r) r[0] = emu_dei(i); if(_2) r[1] = emu_dei(i + 1); PUT(r)
|
||||
#define PEK(i,r,m) r[0] = ram[i]; if(_2) r[1] = ram[(i + 1) & m]; PUT(r)
|
||||
|
||||
#define NEXT if(--cycles) goto step; else return 0;
|
||||
#define OPC(opc, A, B) {\
|
||||
case 0x00|opc: {const int _2=0,_r=0;A B} NEXT\
|
||||
case 0x20|opc: {const int _2=1,_r=0;A B} NEXT\
|
||||
case 0x40|opc: {const int _2=0,_r=1;A B} NEXT\
|
||||
case 0x60|opc: {const int _2=1,_r=1;A B} NEXT\
|
||||
case 0x80|opc: {const int _2=0,_r=0;int k=ptr[0];A ptr[0]=k;B} NEXT\
|
||||
case 0xa0|opc: {const int _2=1,_r=0;int k=ptr[0];A ptr[0]=k;B} NEXT\
|
||||
case 0xc0|opc: {const int _2=0,_r=1;int k=ptr[1];A ptr[1]=k;B} NEXT\
|
||||
case 0xe0|opc: {const int _2=1,_r=1;int k=ptr[1];A ptr[1]=k;B} NEXT }
|
||||
|
||||
static unsigned int
|
||||
uxn_eval(unsigned short pc)
|
||||
{
|
||||
unsigned int a, b, c, x[2], y[2], z[2], cycles = 0x80000000;
|
||||
step:
|
||||
switch(ram[pc++]) {
|
||||
/* BRK */ case 0x00: return 1;
|
||||
/* JCI */ case 0x20: if(DEC(0)) { IMM(c) pc += c; } else pc += 2; NEXT
|
||||
/* JMI */ case 0x40: IMM(c) pc += c; NEXT
|
||||
/* JSI */ case 0x60: IMM(c) INC(1) = pc >> 8, INC(1) = pc, pc += c; NEXT
|
||||
/* LI2 */ case 0xa0: INC(0) = ram[pc++]; /* fall-through */
|
||||
/* LIT */ case 0x80: INC(0) = ram[pc++]; NEXT
|
||||
/* L2r */ case 0xe0: INC(1) = ram[pc++]; /* fall-through */
|
||||
/* LIr */ case 0xc0: INC(1) = ram[pc++]; NEXT
|
||||
/* INC */ OPC(0x01,POx(a),PUx(a + 1))
|
||||
/* POP */ OPC(0x02,REM,{})
|
||||
/* NIP */ OPC(0x03,GOT(x) REM,PUT(x))
|
||||
/* SWP */ OPC(0x04,GOT(x) GOT(y),PUT(x) PUT(y))
|
||||
/* ROT */ OPC(0x05,GOT(x) GOT(y) GOT(z),PUT(y) PUT(x) PUT(z))
|
||||
/* DUP */ OPC(0x06,GOT(x),PUT(x) PUT(x))
|
||||
/* OVR */ OPC(0x07,GOT(x) GOT(y),PUT(y) PUT(x) PUT(y))
|
||||
/* EQU */ OPC(0x08,POx(a) POx(b),PU1(b == a))
|
||||
/* NEQ */ OPC(0x09,POx(a) POx(b),PU1(b != a))
|
||||
/* GTH */ OPC(0x0a,POx(a) POx(b),PU1(b > a))
|
||||
/* LTH */ OPC(0x0b,POx(a) POx(b),PU1(b < a))
|
||||
/* JMP */ OPC(0x0c,POx(a),MOV(a))
|
||||
/* JCN */ OPC(0x0d,POx(a) PO1(b),if(b) MOV(a))
|
||||
/* JSR */ OPC(0x0e,POx(a),RP1(pc >> 8) RP1(pc) MOV(a))
|
||||
/* STH */ OPC(0x0f,GOT(x),RP1(x[0]) if(_2) RP1(x[1]))
|
||||
/* LDZ */ OPC(0x10,PO1(a),PEK(a, x, 0xff))
|
||||
/* STZ */ OPC(0x11,PO1(a) GOT(y),POK(a, y, 0xff))
|
||||
/* LDR */ OPC(0x12,PO1(a),PEK(pc + (signed char)a, x, 0xffff))
|
||||
/* STR */ OPC(0x13,PO1(a) GOT(y),POK(pc + (signed char)a, y, 0xffff))
|
||||
/* LDA */ OPC(0x14,PO2(a),PEK(a, x, 0xffff))
|
||||
/* STA */ OPC(0x15,PO2(a) GOT(y),POK(a, y, 0xffff))
|
||||
/* DEI */ OPC(0x16,PO1(a),DEI(a, x))
|
||||
/* DEO */ OPC(0x17,PO1(a) GOT(y),DEO(a, y))
|
||||
/* ADD */ OPC(0x18,POx(a) POx(b),PUx(b + a))
|
||||
/* SUB */ OPC(0x19,POx(a) POx(b),PUx(b - a))
|
||||
/* MUL */ OPC(0x1a,POx(a) POx(b),PUx(b * a))
|
||||
/* DIV */ OPC(0x1b,POx(a) POx(b),PUx(a ? b / a : 0))
|
||||
/* AND */ OPC(0x1c,POx(a) POx(b),PUx(b & a))
|
||||
/* ORA */ OPC(0x1d,POx(a) POx(b),PUx(b | a))
|
||||
/* EOR */ OPC(0x1e,POx(a) POx(b),PUx(b ^ a))
|
||||
/* SFT */ OPC(0x1f,PO1(a) POx(b),PUx(b >> (a & 0xf) << (a >> 4)))
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
console_input(int c, unsigned int type)
|
||||
{
|
||||
dev[0x12] = c, dev[0x17] = type;
|
||||
if(console_vector && !dev[0x0f])
|
||||
uxn_eval(console_vector);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
if(argc < 2)
|
||||
return fprintf(stdout, "usage: %s file.rom [args..]\n", argv[0]);
|
||||
else if(!(f = fopen(argv[1], "rb")))
|
||||
return fprintf(stderr, "%s: %s not found.\n", argv[0], argv[1]);
|
||||
fread(&ram[0x100], 0xff00, 1, f), fclose(f);
|
||||
dev[0x17] = argc > 2;
|
||||
if(uxn_eval(0x100) && console_vector) {
|
||||
int i = 2;
|
||||
for(; i < argc; i++) {
|
||||
char c, *p = argv[i];
|
||||
while(!dev[0x0f] && (c = *p++))
|
||||
console_input(c, 2);
|
||||
console_input(0, 3 + (i == argc - 1));
|
||||
}
|
||||
while(!dev[0x0f]) {
|
||||
char c = fgetc(stdin);
|
||||
if(feof(stdin)) break;
|
||||
console_input(c, 1);
|
||||
}
|
||||
console_input(0, 4);
|
||||
}
|
||||
return dev[0x0f] & 0x7f;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue