This commit is contained in:
~d6 2022-11-06 21:49:02 -05:00
parent ae3b2c3051
commit 9f72ee4490
10 changed files with 727 additions and 99 deletions

BIN
chr/ascii.chr Normal file

Binary file not shown.

64
chr/ascii.tal Normal file
View File

@ -0,0 +1,64 @@
7f 71 75 75 75 71 7f 00 7f 7d 7d 7d 7d 7d 7f 00
7f 71 7d 71 77 71 7f 00 7f 71 7d 71 7d 71 7f 00
7f 75 75 71 7d 7d 7f 00 7f 71 77 71 7d 71 7f 00
7f 71 77 71 75 71 7f 00 7f 71 7d 7d 7d 7d 7f 00
7f 71 75 71 75 71 7f 00 7f 71 75 71 7d 7d 7f 00
7f 7b 75 71 75 75 7f 00 7f 73 75 73 75 73 7f 00
7f 79 77 77 77 79 7f 00 7f 73 75 75 75 73 7f 00
7f 71 77 73 77 71 7f 00 7f 71 77 73 77 77 7f 00
7f 51 55 55 55 51 7f 00 7f 5d 5d 5d 5d 5d 7f 00
7f 51 5d 51 57 51 7f 00 7f 51 5d 51 5d 51 7f 00
7f 55 55 51 5d 5d 7f 00 7f 51 57 51 5d 51 7f 00
7f 51 57 51 55 51 7f 00 7f 51 5d 5d 5d 5d 7f 00
7f 51 55 51 55 51 7f 00 7f 51 55 51 5d 5d 7f 00
7f 5b 55 51 55 55 7f 00 7f 53 55 53 55 53 7f 00
7f 59 57 57 57 59 7f 00 7f 53 55 55 55 53 7f 00
7f 51 57 53 57 51 7f 00 7f 51 57 53 57 57 7f 00
00 00 00 00 00 00 00 00 18 18 18 18 18 00 18 00
66 66 66 00 00 00 00 00 66 66 ff 66 ff 66 66 00
18 3e 40 3c 02 7c 18 00 62 66 0c 18 30 66 46 00
3c 66 3c 38 67 66 3f 00 0c 18 30 00 00 00 00 00
0c 18 30 30 30 18 0c 00 30 18 0c 0c 0c 18 30 00
00 66 3c ff 3c 66 00 00 00 18 18 7e 18 18 00 00
00 00 00 00 18 18 30 00 00 00 00 7e 00 00 00 00
00 00 00 00 00 18 18 00 03 06 0c 18 30 60 c0 00
3c 66 6e 76 66 66 3c 00 18 18 38 18 18 18 7e 00
3c 66 06 0c 30 60 7e 00 3c 66 06 1c 06 66 3c 00
0c 1c 3c cc fe 0c 0c 00 7e 60 7c 06 06 66 3c 00
3c 66 60 7c 66 66 3c 00 7e 66 0c 18 18 18 18 00
3c 66 66 3c 66 66 3c 00 3c 66 66 3e 06 66 3c 00
00 00 18 00 18 00 00 00 00 00 18 00 18 18 30 00
0c 18 30 60 30 18 0c 00 00 00 7e 00 7e 00 00 00
30 18 0c 06 0c 18 30 00 3c 66 06 0c 18 00 18 00
3c 66 6e 6e 60 62 3c 00 18 3c 66 7e 66 66 66 00
7c 66 66 7c 66 66 7c 00 3c 66 60 60 60 66 3c 00
78 6c 66 66 66 6c 78 00 7e 60 60 78 60 60 7e 00
7e 60 60 78 60 60 60 00 3c 66 60 6e 66 66 3c 00
66 66 66 7e 66 66 66 00 3c 18 18 18 18 18 3c 00
1e 0c 0c 0c 0c 6c 38 00 66 6c 78 70 78 6c 66 00
60 60 60 60 60 60 7e 00 63 77 7f 6b 63 63 63 00
66 76 7e 7e 6e 66 66 00 3c 66 66 66 66 66 3c 00
7c 66 66 7c 60 60 60 00 3c 66 66 66 66 3c 0e 00
7c 66 66 7c 78 6c 66 00 3c 66 60 3c 06 66 3c 00
7e 18 18 18 18 18 18 00 66 66 66 66 66 66 3c 00
66 66 66 66 66 3c 18 00 63 63 63 6b 7f 77 63 00
66 66 3c 18 3c 66 66 00 66 66 66 3c 18 18 18 00
7e 06 0c 18 30 60 7e 00 3c 30 30 30 30 30 3c 00
c0 60 30 18 0c 06 03 00 3c 0c 0c 0c 0c 0c 3c 00
00 18 3c 66 00 00 00 00 00 00 00 00 00 00 ff ff
30 18 0c 00 00 00 00 00 00 00 3c 06 3e 46 3e 00
00 60 60 7c 66 66 7c 00 00 00 3c 60 60 60 3c 00
00 06 06 3e 66 66 3e 00 00 00 3c 66 7e 60 3c 00
00 0e 18 3e 18 18 18 00 00 00 3e 66 66 3e 06 7c
00 60 60 7c 66 66 66 00 00 18 00 38 18 18 3c 00
00 06 00 06 06 06 06 3c 00 60 60 6c 78 6c 66 00
00 38 18 18 18 18 3c 00 00 00 66 7f 7f 6b 63 00
00 00 7c 66 66 66 66 00 00 00 3c 66 66 66 3c 00
00 00 7c 66 66 7c 60 60 00 00 3e 66 66 3e 06 06
00 00 7c 66 60 60 60 00 00 00 3e 60 3c 06 7c 00
00 18 7e 18 18 18 0e 00 00 00 66 66 66 66 3e 00
00 00 66 66 66 3c 18 00 00 00 63 6b 7f 3e 36 00
00 00 66 3c 18 3c 66 00 00 00 66 66 66 3e 0c 78
00 00 7e 0c 18 30 7e 00 1c 30 30 60 30 30 1c 00
18 18 18 18 18 18 18 18 38 0c 0c 06 0c 0c 38 00
3b 6e 00 00 00 00 00 00 7f 77 67 41 67 77 7f 00

BIN
chr/cyber.chr Normal file

Binary file not shown.

61
chr/cyber.tal Normal file
View File

@ -0,0 +1,61 @@
80 40 20 10 08 04 02 01 80 40 20 10 08 04 02 01
80 40 20 10 08 04 02 01 01 02 04 08 10 20 40 80
01 02 04 08 10 20 40 80 01 02 04 08 10 20 40 80
80 80 80 80 80 80 80 80 01 01 01 01 01 01 01 01
ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 c0 c0 20 10 08 04 02 01
80 40 20 10 08 04 03 03 01 02 04 08 10 20 40 80
03 03 04 08 10 20 40 80 01 02 04 08 10 20 c0 c0
40 40 40 40 40 40 40 40 02 02 02 02 02 02 02 02
00 ff 00 00 00 00 00 00 00 00 00 00 00 00 ff 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 a0 60 e0 10 08 04 02 01
80 40 20 10 08 07 06 05 01 02 04 08 10 20 40 80
05 06 07 08 10 20 40 80 01 02 04 08 10 e0 60 a0
20 20 20 20 20 20 20 20 04 04 04 04 04 04 04 04
00 00 ff 00 00 00 00 00 00 00 00 00 00 ff 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 90 50 30 f0 08 04 02 01
80 40 20 10 0f 0c 0a 09 01 02 04 08 10 20 40 80
09 0a 0c 0f 10 20 40 80 01 02 04 08 f0 30 50 90
10 10 10 10 10 10 10 10 08 08 08 08 08 08 08 08
00 00 00 ff 00 00 00 00 00 00 00 00 ff 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 88 48 28 18 f8 04 02 01
80 40 20 1f 18 14 12 11 01 02 04 08 10 20 40 80
11 12 14 18 1f 20 40 80 01 02 04 f8 18 28 48 88
08 08 08 08 08 08 08 08 10 10 10 10 10 10 10 10
00 00 00 00 ff 00 00 00 00 00 00 ff 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 84 44 24 14 0c fc 02 01
80 40 3f 30 28 24 22 21 01 02 04 08 10 20 40 80
21 22 24 28 30 3f 40 80 01 02 fc 0c 14 24 44 84
04 04 04 04 04 04 04 04 20 20 20 20 20 20 20 20
00 00 00 00 00 ff 00 00 00 00 ff 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 82 42 22 12 0a 06 fe 01
80 7f 60 50 48 44 42 41 01 02 04 08 10 20 40 80
41 42 44 48 50 60 7f 80 01 fe 06 0a 12 22 42 82
02 02 02 02 02 02 02 02 40 40 40 40 40 40 40 40
00 00 00 00 00 00 ff 00 00 ff 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 40 20 10 08 04 02 01 81 41 21 11 09 05 03 ff
ff c0 a0 90 88 84 82 81 01 02 04 08 10 20 40 80
81 82 84 88 90 a0 c0 ff ff 03 05 09 11 21 41 81
01 01 01 01 01 01 01 01 80 80 80 80 80 80 80 80
00 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 00

1
ff.tal
View File

@ -36,7 +36,6 @@
#0cd5 .System/g DEO2
#0b66 .System/b DEO2
;draw-scene JSR2
;draw-party-info JSR2
;draw-menu JSR2

164
fix16.tal
View File

@ -10,23 +10,23 @@
( )
( 16-bit fixed point can represent fractional values )
( in the range -128 <= x < 128. the smallest fraction it )
( can represent is 1/256, which is about 0.004. )
( can represent is 1/256, which is about 0.0039. )
( )
( SHORT FRACTION DECIMAL )
( #0000 0/256 0.000 )
( #0001 1/256 0.004 )
( #0002 2/256 0.008 )
( #0040 64/256 0.250 )
( #0080 128/256 0.500 )
( #0100 256/256 1.000 )
( #0700 1792/256 7.000 )
( #7f00 32512/256 127.000 )
( #7fff 32767/256 127.996 )
( #8000 -32768/256 -128.000 )
( #8001 -32767/256 -127.996 )
( #8100 -32767/256 -127.000 )
( #ff00 -256/256 -1.000 )
( #ffff -1/256 -0.004 )
( #0000 0/256 0.0000 )
( #0001 1/256 0.0039 )
( #0002 2/256 0.0078 )
( #0040 64/256 0.2500 )
( #0080 128/256 0.5000 )
( #0100 256/256 1.0000 )
( #0700 1792/256 7.0000 )
( #7f00 32512/256 127.0000 )
( #7fff 32767/256 127.9961 )
( #8000 -32768/256 -128.0000 )
( #8001 -32767/256 -127.9961 )
( #8100 -32767/256 -127.0000 )
( #ff00 -256/256 -1.0000 )
( #ffff -1/256 -0.0039 )
( )
( many 8.8 operations are equivalent to unsigned int16: )
( * addition )
@ -60,6 +60,7 @@
( useful constants )
( )
( to generate your own: )
( )
( 1. take true value, e.g. 3.14159... )
( 2. multiply by 256 )
( 3. round to nearest whole number )
@ -80,9 +81,10 @@
%x16-phi { #019e } ( 1.61803... )
%x16-sqrt-2 { #016a } ( 1.41421... )
%x16-sqrt-3 { #01bb } ( 1.73205... )
%x16-epsilon { #0001 } ( 0.00390625 )
%x16-epsilon { #0001 } ( 0.00390... )
%x16-minimum { #8000 } ( -128.0 )
%x16-maximum { #7fff } ( 127.99609375 )
%x16-maximum { #7fff } ( 127.99609... )
%x16-max-whole { #7f00 } ( 127.0 )
( useful macros )
%x16-is-non-neg { x16-minimum LTH2 }
@ -90,7 +92,7 @@
%x16-emit-dec { #30 ADD #18 DEO }
|0100
( |0100
x16-zero xyz
x16-one xyz
x16-two xyz
@ -104,12 +106,27 @@
x16-sqrt-2 xyz
x16-sqrt-3 xyz
x16-epsilon xyz
#0002 xyz
#1234 xyz
#7fff xyz
#8000 xyz
#8001 xyz
#ffff xyz
BRK
#0200 xyz
#0834 #0000 ;x16-add JSR2 xyz
#0834 #0834 ;x16-add JSR2 xyz
#0834 #0834 ;x16-mul JSR2 xyz
#0834 #0200 ;x16-div JSR2 xyz
#0100 xyz
#0003 xyz
#0100 #0003 ;x16-div JSR2 xyz
#0834 xyz
#0080 xyz
#0834 #0080 ;x16-div JSR2 xyz
#0834 xyz
#0300 xyz
#0834 #0300 ;x16-div JSR2 xyz
BRK )
@x16-emit ( x* -> )
DUP2 #8000 EQU2 ,&is-min JCN
@ -130,6 +147,7 @@
#00 SWP ( lo* )
#000a MUL2 #0100 DIV2k DUP2 NIP x16-emit-dec MUL2 SUB2
#000a MUL2 #0100 DIV2k DUP2 NIP x16-emit-dec MUL2 SUB2
#000a MUL2 #0100 DIV2k DUP2 NIP x16-emit-dec MUL2 SUB2
#000a MUL2 #0100 DIV2k STH2k MUL2 SUB2 #0080 LTH2 ,&no-round JCN INC2r
&no-round STH2r NIP x16-emit-dec JMP2r
@ -138,13 +156,12 @@
( - 00: x = y )
( - 01: x > y )
@x16-cmp ( x* y* -> c^ )
STH2k x16-is-neg ,&yn JMP
x16-is-non-neg ,&ypxp ( y>=0 )
POP2 POP2r #ff JMP2r ( x<0 y>=0 )
&ypxp ;x16-ucmp JMP2 ( x>=0 y>=0 )
&yn x16-is-neg ,&ynxn ( y<0 )
POP2 POP2r #01 JMP2r ( x>=0 y<0 )
&ynxn SWP2 ;x16-ucmp JMP2 ( x<0 y<0 )
STH2k x16-is-neg ,&yn JCN ( x* [y*] ; ? )
DUP2 x16-is-non-neg ,&same JCN ( x* [y*] ; y>=0 )
POP2 POP2r #ff JMP2r ( -1 ; x<0 y>=0 )
&yn DUP2 x16-is-neg ,&same JCN ( x* [y*] ; y<0 )
POP2 POP2r #01 JMP2r ( 1 ; x>=0 y<0 )
&same STH2r ;x16-ucmp JMP2 ( res ; x<0 y<0 b )
( unsigned comparison between x and y. )
( - ff: x < y )
@ -180,79 +197,32 @@
LIT2 &x2 00 &x3 00 LIT2 &y2 00 &y3 00 MUL2 #08 SFT2
LIT2 &x0 00 &x1 00 ,&y2 LDR2 MUL2 ADD2
,&x2 LDR2 LIT2 &y0 00 &y1 00 MUL2 ADD2
,&x0 LDR2 ,&x0 LDR2 MUL2 #80 SFT2 ADD2 JMP2r
,&x0 LDR2 ,&y0 LDR2 MUL2 #80 SFT2 ADD2 JMP2r
&rhs-whole #08 SFT2 MUL2 JMP2r
@x16-div ( x* y* -> x/y* )
SWP2 DUP2 x16-is-non-neg ,&non-negative ( y x )
;x16-negate JSR2 SWP2 DIV2 ;x16-negate JMP2
&non-negative
SWP2 DIV2 JMP2r
( DUP ,&not-whole JCN
#08 SFT2 DIV2 JMP2r ( since y is whole, x/(y>>8) is correct )
&not-whole )
DIV2k STH2k ( x y x/y {x/y} )
LITr 80 SFT2r ( x y x/y {div=(x/y)<<8 )
OVR2 STH2 ( x y x/y {y div} )
MUL2 SUB2 ( x%y {y div} )
STH2r LIT2r 0100 ( x%y y {0100 div} )
( we know x%y < y, so start right-shifting y )
&loop
DUP2 #0000 EQU2 ,&done JCN
#01 SFT2 LITr 01 SFT2r ( rem yi {shifti div} )
LTH2k ,&loop JCN ( rem yi {shifti div} )
SWP2 OVR2 SUB2 SWP2 ( rem-yi yi {shifti div} )
DUP2r ROT2r ADD2r SWP2r ( rem-yi yi {shifti div+shifti} )
,&loop JMP ( rem-yi yi {shifti div+shifti} )
&done
POP2 POP2 ( {shiftk div} )
POP2r STH2r JMP2r ( div )
@x16-mod ( x* y* -> x%y* )
;x16-div JSR2 ;x16-mul JSR2 SUB2 JMP2r
@x16-quotient ( x* y* -> x//y* )
DIV2 #80 SFT2 JMP2r
@x16-mod-div ( x* y* -> x%y* x/y* )
;x16-div JSR2 STH2k ;x16-mul JSR2 SUB2 STH2r JMP2r
@x16-div-mod ( x* y* -> x/y* x%y* )
;x16-mod-div JSR2 SWP2 JMP2r
( trigonometry )
( )
( this uses there different angle representations: )
( )
( 1. angle representation (#0080 = pi, #0100 = 2pi) )
( 2. fix16 representation (#0324 = pi, #0648 = 2pi) )
( 3. degrees (#00b4 = pi, #0168 = 2pi) )
( )
( angles are the most precise, but may require some )
( conversion. )
( calculate the sin of the given angle. )
( )
( the input should be an angle and the )
( result will be 16-bit fixed point. )
( )
( cos(x) = sin(x + pi/2) )
@cos-angle ( x* -> cos(x)* )
#0080 ADD2 ;sin-angle JMP2
( calculate the sin of the given angle. )
( )
( the input should be an angle and the )
( result will be 16-bit fixed point. )
( )
( sin table offset math: )
( 0 <= x < 64 -> table[x] )
( 64 <= x < 128 -> table[127 - x] )
( 128 <= x < 192 -> -table[x - 128] )
( 192 <= x < 256 -> -table[255 - x] )
@sin-angle ( x* -> sin(x)* )
NIP DUP #7f GTH ,&d180+ JCN
#0001 STH2
DUP #3f GTH ,&d90 ,&load JMP
&d90 #7f SWP SUB ,&load JMP
&d180+
#ffff STH2
DUP #bf GTH ,&d270 #80 SUB ,&load JMP
&d270 #ff SWP SUB ,&load JMP
&load ,sin-table ADD LDR2 STH2r MUL2 JMP2r
( sin table with 64 entries for 1/4 of a unit circle. )
( )
( there is no need for interpolation when using )
( angle values, since 256 distinct values can be )
( produced using reflection. )
( )
( these table values go from 0 until pi/2 (i.e. from )
( angles #00 until #80). )
@sin-table ( 0 - pi/2: 64 steps )
0000 0006 000d 0013 0019 001f 0026 002c
0032 0038 003e 0044 004a 0050 0056 005c
0062 0068 006d 0073 0079 007e 0084 0089
008e 0093 0098 009d 00a2 00a7 00ac 00b1
00b5 00b9 00be 00c2 00c6 00ca 00ce 00d1
00d5 00d8 00dc 00df 00e2 00e5 00e7 00ea
00ed 00ef 00f1 00f3 00f5 00f7 00f8 00fa
00fb 00fc 00fd 00fe 00ff 00ff 0100 0100
@x16-remainder ( x* y* -> x%y* )
DIV2k MUL2 SUB2 JMP2r

254
term.tal Normal file
View File

@ -0,0 +1,254 @@
|00 @System [ &vect $2 &pad $6 &r $2 &g $2 &b $2 ]
|10 @Console [ &vect $2 &r $1 &pad $5 &w $1 ]
|20 @Screen [ &vect $2 &w $2 &h $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
|80 @Controller [ &vect $2 &button $1 &key $1 ]
|0000
@dirty $1 ( screen needs redraw? )
@tint $1 ( draw mode. 01=regular, 04=inverted )
@rows $2 ( height in characters )
@cols $2 ( width in characters )
@cur-x $2 ( cursor x: 0 <= cur-x < cols )
@cur-y $2 ( cursor y: 0 <= cur-y < rows )
@bg-frame $2
@bg-counter $1
|0100
( 32 characters = 256 pixels )
#0020 .rows STZ2
#0040 .cols STZ2
( set screen height/width based on rows/cols )
.rows LDZ2 #30 SFT2 .Screen/h DEO2
.cols LDZ2 #30 SFT2 .Screen/w DEO2
( set colors )
#0ff3 .System/r DEO2
#0fd5 .System/g DEO2
#2f66 .System/b DEO2
( #08f3 .System/r DEO2
#0cd5 .System/g DEO2
#0b66 .System/b DEO2 )
( clear screen for initial draw )
;clear-screen JSR2
( draw background )
#0000 .bg-frame STZ2
#00 .bg-counter STZ
( #0000 ;draw-background JSR2 )
( set up interrupts )
;redraw .Screen/vect DEO2 ( set up screen )
;on-key .Controller/vect DEO2 ( set up keyboard )
( return )
BRK
@draw-background ( frame* -> )
STH2
STH2kr #70 SFT2 ;cyber ADD2 #0048 ADD2 .Screen/addr DEO2
LIT2r 000f LIT2 0000
&loop1
DUP2 #30 SFT2 .Screen/y DEO2
DUP2 .cols LDZ2 OVR2 SUB2 ,hline JSR
INC2 DUP2 STH2kr LTH2 ,&loop1 JCN
POP2 POP2r
STH2kr #70 SFT2 ;cyber ADD2 #0040 ADD2 .Screen/addr DEO2
LIT2r 0020 LIT2 0011
&loop2
DUP2 #30 SFT2 .Screen/y DEO2
.rows LDZ2 OVR2 INC2 SUB2 .cols LDZ2 OVR2 SUB2 ,hline JSR
INC2 DUP2 STH2kr LTH2 ,&loop2 JCN
POP2 POP2r
POP2r JMP2r
@dline ( n -> )
#0000 SWP2 SUB2 STH2
&loop
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
.Screen/y DEI2 #0008 ADD2 .Screen/y DEO2
#02 .Screen/sprite DEO
INC2r STH2kr ORA ,&loop JCN
POP2r JMP2r
@hline ( x1 x2 -> )
STH2 &loop
DUP2 #30 SFT2 .Screen/x DEO2
#02 .Screen/sprite DEO
INC2 DUP2 STH2kr LTH2 ,&loop JCN
POP2 POP2r JMP2r
@vline ( y1 y2 -> )
STH2 &loop
DUP2 #30 SFT2 .Screen/y DEO2
#02 .Screen/sprite DEO
INC2 DUP2 STH2kr LTH2 ,&loop JCN
POP2 POP2r JMP2r
@clear-screen
#01 .dirty STZ
;screen STH2
#0000 &yloop
#0000 &xloop
#20 STH2kr STA INC2r
INC2 DUP2 .cols LDZ2 LTH2 ,&xloop JCN
POP2
INC2 DUP2 .rows LDZ2 LTH2 ,&yloop JCN
POP2 POP2r
JMP2r
@redraw
.bg-counter LDZ DUP ,&done-bg JCN
.bg-frame LDZ2
( DUP2 NIP LIT "a ADD #18 DEO #0a #18 DEO )
DUP2 ;draw-background JSR2
INC2 #0007 AND2 .bg-frame STZ2
&done-bg
INC #03 AND .bg-counter STZ
#41 .tint STZ
.dirty LDZ #00 EQU ,&done JCN
;screen STH2
#0000 DUP2 .Screen/y DEO2
&yloop
#0000 DUP2 .Screen/x DEO2
&xloop
STH2kr LDA ;draw-tile JSR2
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
INC2 INC2r
DUP2 .cols LDZ2 LTH2 ,&xloop JCN
POP2
.Screen/y DEI2 #0008 ADD2 .Screen/y DEO2
INC2
DUP2 .rows LDZ2 LTH2 ,&yloop JCN
POP2 POP2r
;show-cursor JSR2
#00 .dirty STZ
&done BRK
@hide-cursor
#41 .tint STZ
;draw-cursor JMP2
@show-cursor
#44 .tint STZ
;draw-cursor JMP2
@draw-cursor
.cur-x LDZ2 #30 SFT2 .Screen/x DEO2
.cur-y LDZ2 #30 SFT2 .Screen/y DEO2
.cur-y LDZ2 .cols LDZ2 MUL2 .cur-x LDZ2 ADD2 ;screen ADD2 LDA
;draw-tile JMP2
@on-key
.Controller/key DEI #00 EQU ,&skip JCN
.Controller/key DEI ;read JSR2
&skip BRK
@read ( byte^ -> )
DUP #07 EQU ;read-bel JCN2
DUP #08 EQU ;read-bs JCN2
DUP #09 EQU ;read-tab JCN2
DUP #0a EQU ;read-nl JCN2
DUP #0d EQU ;read-cr JCN2
DUP #1b EQU ;read-esc JCN2
DUP #7f EQU ;read-del JCN2
;read-normal JMP2
@read-bel JMP2r
@read-bs POP ;scroll JMP2
@read-tab POP POP2r #0000 DIV
@read-esc JMP2r
@read-del JMP2r
@read-cr ( 0d -> )
POP
;hide-cursor JSR2
#0000 .cur-x STZ2
;down JMP2
@read-nl ( 0a -> )
,read-cr JMP
@forward ( -> )
.cur-x LDZ2 INC2 DUP2 .cols LDZ2 LTH2 ,&ok JCN
POP2 #0000 .cur-x STZ2 ;down JMP2
&ok .cur-x STZ2
;show-cursor JMP2
@down ( -> )
.cur-y LDZ2 INC2 DUP2 .rows LDZ2 LTH2 ,&ok JCN
POP2 ;scroll JMP2
&ok .cur-y STZ2
;show-cursor JMP2
@scroll
;end-screen STH2
;screen .cols LDZ2 ADD2 STH2
&loop
STH2kr LDA #20 STH2kr STA
STH2kr .cols LDZ2 SUB2 STA
INC2r GTH2kr STHr ,&loop JCN
POP2r POP2r
#01 .dirty STZ
;show-cursor JMP2
@cursor-addr ( -> addr* )
.cur-y LDZ2 .cols LDZ2 MUL2
.cur-x LDZ2 ADD2 ;screen ADD2
JMP2r
@read-normal ( c -> )
;hide-cursor JSR2
DUP ;cursor-addr JSR2 STA
;draw-tile JSR2
;forward JMP2
( 0 <= c < 256 )
@draw-tile ( c^ -> )
DUP #80 LTH
,draw-7bit JCN
,draw-8bit JMP
( 0 <= index < 128 )
@load-tile ( index^ -> )
#00 SWP #30 SFT2
;ascii ADD2 .Screen/addr DEO2
JMP2r
( 0 <= c < 128 )
@draw-7bit ( c^ -> )
;load-tile JSR2
.tint LDZ .Screen/sprite DEO
JMP2r
( 128 <= c < 256 )
@draw-8bit ( 8bit^ -> )
#80 SUB ;load-tile JSR2
.tint LDZ #05 EOR .Screen/sprite DEO
JMP2r
( 128 1-bit 8x8 tiles for ASCII 7-bit characters )
@ascii
~chr/ascii.tal
( cyber background )
@cyber
~chr/cyber.tal
( screen to store characters for redraw, etc. )
@screen $0800 ( 64 x 32 )
@end-screen
( northwest=10 north=40 northeast=28 )
( west=30 center=56 east=38 )
( southwest=20 south=48 southeast=08 )
@bg-layout $0800

124
test-fix16.py Normal file
View File

@ -0,0 +1,124 @@
#!/usr/bin/python
from math import floor, log
from os import environ
from random import randint
from subprocess import Popen, PIPE, run
u8 = {'sz': 1 << 8, 'fmt': b'%02x'}
u16 = {'sz': 1 << 16, 'fmt': b'%04x'}
z16 = {'sz': 1 << 16, 'fmt': b'%04x'}
def eq(got, expected):
return got == expected
def booleq(got, expected):
return bool(got) == bool(expected)
def releq(got, expected):
if (expected - 1) <= got and got <= (expected + 1):
return True
else:
error = abs(got - expected) / (abs(expected) + 0.001)
return error < 0.01
def testcase(p, sym, args, out, f, eq):
vals = []
for name, g in args:
val = randint(0, g['sz'] - 1)
while val == 0 and g is z16:
val = randint(0, g['sz'] - 1)
vals.append((name, g, val))
#vals = [(name, g, randint(0, g['sz'] - 1)) for (name, g) in args]
p.stdin.write(sym)
for _, g, x in vals:
p.stdin.write(g['fmt'] % x)
p.stdin.write(b'\n')
p.stdin.flush()
got = int(p.stdout.readline().strip().decode('utf-8'), 16)
xs = [x for _, _, x in vals]
z = f(*xs)
expected = z
if eq(got, expected):
return None
else:
res = {'got': got, 'expected': expected}
for name, _, x in vals:
res[name] = x
return res
def test(p, trials, sym, args, out, f, eq=eq):
fails = 0
cases = []
for i in range(0, trials):
case1 = testcase(p, sym, args, out, f, eq)
if case1 is not None:
fails += 1
cases.append(case1)
name = sym.decode('utf-8')
if fails == 0:
print('%s passed %d trials' % (name, trials))
else:
print('%s failed %d/%d trials (%r)' % (name, fails, trials, cases))
def pipe():
return Popen(['uxncli', 'run.rom'], stdin=PIPE, stdout=PIPE)
def x16_add(x, y):
return (x + y) % 65536
def x16_sub(x, y):
return (x - y) % 65536
def x16_mul(x, y):
return ((x * y) // 256) % 65536
def x16_div(x, y):
return ((x * 256) // y) % 65536
def x16_quot(x, y):
return x16_div(x, y) & 0xff00
def x16_rem(x, y):
return x % y
def x16_is_whole(x):
return int((x & 0xff) == 0)
def x16_negate(x):
if x == 32768 or x == 0:
return x
else:
return 65536 - x
def x16_eq(x, y):
return x == y
def x16_ne(x, y):
return x != y
def tosigned(x):
return x if x < 32768 else x - 65536
def x16_lt(x, y):
return int(tosigned(x) < tosigned(y))
def x16_gt(x, y):
return int(tosigned(x) > tosigned(y))
def x16_lteq(x, y):
return int(tosigned(x) <= tosigned(y))
def x16_gteq(x, y):
return int(tosigned(x) >= tosigned(y))
def main():
trials = 100000
run(['uxnasm', 'test-fix16.tal', 'run.rom'])
p = pipe()
test(p, trials, b'+', [('x', u16), ('y', u16)], u16, x16_add)
test(p, trials, b'-', [('x', u16), ('y', u16)], u16, x16_sub)
test(p, trials, b'*', [('x', u16), ('y', u16)], u16, x16_mul)
test(p, trials, b'/', [('x', u16), ('y', z16)], u16, x16_div, eq=releq)
test(p, trials, b'\\', [('x', u16), ('y', z16)], u16, x16_quot)
test(p, trials, b'%', [('x', u16), ('y', z16)], u16, x16_rem)
test(p, trials, b'w', [('x', u16)], u8, x16_is_whole, eq=booleq)
test(p, trials, b'N', [('x', u16)], u16, x16_negate)
test(p, trials, b'=', [('x', u16), ('y', u16)], u8, x16_eq)
test(p, trials, b'!', [('x', u16), ('y', u16)], u8, x16_ne)
test(p, trials, b'<', [('x', u16), ('y', u16)], u8, x16_lt)
test(p, trials, b'>', [('x', u16), ('y', u16)], u8, x16_gt)
test(p, trials, b'{', [('x', u16), ('y', u16)], u8, x16_lteq)
test(p, trials, b'}', [('x', u16), ('y', u16)], u8, x16_gteq)
p.stdin.write(b'\n\n')
p.stdin.flush()
p.stdin.close()
p.stdout.close()
p.kill()
if __name__ == "__main__":
main()

156
test-fix16.tal Normal file
View File

@ -0,0 +1,156 @@
( test-fix16.tal )
( )
( testing uxntal words based on input/output bytes. )
( )
( this harness works best testing words that are "pure" )
( in the sense that they read from the data stack and )
( write results back onto the data stack. words which )
( manipulate the return stack or read/write from devices )
( may require something else. )
( )
( the model is as follows: )
( )
( - each test case is a line of text ending in a newline )
( - lines starts with a character that selects a test )
( - after that, 0 or more hexadecimal bytes are provided )
( - the test runs )
( - result is 0 or more hexadecimal bytes (or an error) )
( - an empty line ends the test )
( )
( for example, the input "+12345678\n" would run a test )
( selected by "+" with 4 input bytes on the stack: )
( )
( wst: 12 34 56 78 )
( )
( each case should be added to @interact, along with the )
( number of bytes it expects to read and write. )
( program )
|0100 ;interact #10 DEO2 BRK
( include the code being tested )
~fix16.tal
( testing )
@buf $33 ( line buffer, not including trailing newline )
@pos $2 ( next position in buffer to write to )
( save character input and execute tests )
( )
( tests always start with a single character then )
( additional arguments are passed as bytes before )
( a terminating newline. )
( )
( the last byte read will be on the top of the stack )
( and the earliest on the bottom. )
@interact
#12 DEI ( read c )
DUP #0a EQU ,&exec JCN ( exec if c is a newline )
;pos LDA2 ;buf ADD2 STA ( else write c to buf+pos )
;pos LDA2k INC2 SWP2 STA2 BRK ( increment pos )
&exec POP ( )
;pos LDA2 #0000 EQU2 ;exit JCN2 ( exit on an empty line )
;buf LDA LIT "+ EQU ;test-x16-add JCN2
;buf LDA LIT "* EQU ;test-x16-mul JCN2
;buf LDA LIT "- EQU ;test-x16-sub JCN2
;buf LDA LIT "/ EQU ;test-x16-div JCN2
;buf LDA LIT "\ EQU ;test-x16-quotient JCN2
;buf LDA LIT "% EQU ;test-x16-remainder JCN2
;buf LDA LIT "w EQU ;test-x16-is-whole JCN2
;buf LDA LIT "N EQU ;test-x16-negate JCN2
;buf LDA LIT "= EQU ;test-x16-eq JCN2
;buf LDA LIT "! EQU ;test-x16-ne JCN2
;buf LDA LIT "< EQU ;test-x16-lt JCN2
;buf LDA LIT "> EQU ;test-x16-gt JCN2
;buf LDA LIT "{ EQU ;test-x16-lteq JCN2
;buf LDA LIT "} EQU ;test-x16-gteq JCN2
LIT "? #18 DEO #0a #18 DEO ;reset JSR2 BRK
( set the interpreter to exit now )
@exit
#01 #0f DEO BRK
( reads j bytes, emits k bytes )
@test ( j^ k^ word* -> )
STH2 STH STH ( {j k word} )
;buf INC2 STHr ( buf+1 j {k word} )
;read-bytes JSR2 ( <j-bytes> {k word} )
ROTr ROTr STH2r ( <j-bytes> word {k} )
JSR2 STHr ( <k-bytes> k )
;emit-bytes JSR2 ( )
#0a #18 DEO ( )
;reset JSR2 BRK ( )
( reset the interpreter to read another line )
@reset ( -> )
#0000 ;pos STA2
#00 ;buf STA
JMP2r
( different test executors )
( )
( TEST-NAME #IN #OUT WORD-TO-TEST HARNESS )
@test-x16-add #04 #02 ;x16-add ;test JMP2
@test-x16-mul #04 #02 ;x16-mul ;test JMP2
@test-x16-sub #04 #02 ;x16-sub ;test JMP2
@test-x16-div #04 #02 ;x16-div ;test JMP2
@test-x16-quotient #04 #02 ;x16-quotient ;test JMP2
@test-x16-remainder #04 #02 ;x16-remainder ;test JMP2
@test-x16-is-whole #02 #01 ;x16-is-whole ;test JMP2
@test-x16-negate #02 #02 ;x16-negate ;test JMP2
@test-x16-eq #04 #01 ;x16-eq ;test JMP2
@test-x16-ne #04 #01 ;x16-ne ;test JMP2
@test-x16-lt #04 #01 ;x16-lt ;test JMP2
@test-x16-lteq #04 #01 ;x16-lteq ;test JMP2
@test-x16-gt #04 #01 ;x16-gt ;test JMP2
@test-x16-gteq #04 #01 ;x16-gteq ;test JMP2
( reads one byte from ASCII: "13" -> 0x13 )
@read-byte ( c0^ c1^ -> n^ )
( lower char )
DUP #3a LTH ,&lo-digit JCN
#57 ,&lo JMP &lo-digit #30
&lo SUB SWP
( higher char )
DUP #3a LTH ,&hi-digit JCN
#57 ,&hi JMP &hi-digit #30
&hi SUB #40 SFT ORA
JMP2r
( read k bytes from the buffer )
@read-bytes ( addr* k^ -> <k bytes> )
DUP ,&non-zero JCN ( addr k )
POP POP2 JMP2r ( )
&non-zero
STH STH2k ( addr {addr k} )
LDA2 ;read-byte JSR2 ( byte {addr k} )
STH2r #0002 ADD2 ( byte addr+2 {k} )
STHr #01 SUB ( byte addr+2 k-1 )
,read-bytes JMP ( byte addr+2 k-1 )
( emit n bytes from the stack, earliest first )
( )
( examples: )
( - #aa #bb #cc #03 will emit "aabbcc" )
( - #aa #bb #01 will emit "bb" leaving aa on wst )
( - #00 will emit nothing )
@emit-bytes ( <n bytes> n -> )
DUP
&loop ( <b0..bk> n k {<bk+1..bn>} )
DUP #00 EQU ,&next JCN
ROT STH #01 SUB ( <b0..bk-1> n k-1 <bk..bn> )
,&loop JMP
&next ( n 0 {<b0..bn>} )
POP
&while ( n-i {<bi..bn>} )
DUP #00 EQU ,&done JCN
STHr ;emit JSR2 #01 SUB
,&while JMP
&done
POP JMP2r
( emit a single byte in hexadecimal notation )
@emit
DUP #04 SFT ,&char JSR
&char #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO
JMP2r

View File

@ -60,7 +60,7 @@ def bitcount(x):
def gcd(a, b):
return a if b == 0 else gcd(b, a % b)
def main():
trials = 100
run(['uxnasm', 'test-math32.tal', 'run.rom'])