... | ... |
@@ -1,60 +1,106 @@ |
1 |
+( |
|
2 |
+ tests/opcodes : automated testing of opcodes |
|
3 |
+ |
|
4 |
+ This file generates a lot of stack underflows on purpose: |
|
5 |
+ it's handy to supress all the warning by piping through grep |
|
6 |
+ |
|
7 |
+ | grep -vF 'Halted: Working-stack underflow' |
|
8 |
+) |
|
9 |
+ |
|
10 |
+;test { code 2 label 2 status 1 } |
|
11 |
+;counts { failed 2 passed 2 unknown 2 } |
|
12 |
+;number { started 1 } |
|
13 |
+ |
|
1 | 14 |
|0100 ;Console { pad 8 char 1 byte 1 short 2 } |
2 |
-|0110 ;Screen { width 2 height 2 pad 4 x 2 y 2 color 1 } |
|
3 |
-|0120 ;Sprite { pad 8 x 2 y 2 addr 2 color 1 } |
|
4 |
-|0130 ;Controller { buttons 1 } |
|
5 |
-|0140 ;Keys { key 1 } |
|
6 |
-|0150 ;Mouse { x 2 y 2 state 1 chord 1 } |
|
7 |
-|0160 ;File { pad 8 name 2 length 2 load 2 save 2 } |
|
8 |
-|01E0 ;Debug { pad 8 stack 1 snapshot 1 exit 1 pad 4 test_mode 1 } |
|
9 | 15 |
|01F0 .RESET .FRAME .ERROR ( vectors ) |
10 |
-|01F8 [ f07c f0e2 f0c2 ] ( palette ) |
|
11 | 16 |
|
12 |
-%TEST { BRK2?r LITr EOR2? DUP? } |
|
13 |
- |
|
14 |
-%PASS { #01 ,result JSR2 } |
|
15 |
-%FAIL { #00 ,result JSR2 } |
|
16 |
-%PASS? { ,result JSR2 } |
|
17 |
+%PASS? { ,result JMP2 BRK2?r LITr EOR2? DUP? } |
|
18 |
+%PASS { #01 PASS? } |
|
19 |
+%FAIL { #00 PASS? } |
|
17 | 20 |
|
18 | 21 |
|0200 |
19 | 22 |
|
20 | 23 |
@tests |
21 |
- TEST ADD FAIL [ add-needs-two ] |
|
22 |
- TEST #01 ADD FAIL [ add-needs-two ] |
|
23 |
- TEST #01 #02 ADD #03 EQU PASS? [ add-result ] |
|
24 |
- TEST #01 #02 ADD #ff EQU PASS? [ this-test-fails ] |
|
24 |
+ ADD FAIL [ add-needs-two 00 ] |
|
25 |
+ #01 ADD FAIL [ add-needs-two 00 ] |
|
26 |
+ #01 #02 ADD #03 EQU PASS? [ add-result 00 ] |
|
27 |
+ #01 #02 ADD #ff EQU PASS? [ this-test-fails 00 ] |
|
25 | 28 |
|
26 |
- TEST #00 =Debug.exit |
|
29 |
+ ,finish JMP2 |
|
27 | 30 |
|
28 | 31 |
@RESET |
29 |
- #01 =Debug.test_mode |
|
30 |
- ,tests #0001 SUB2 =current-test |
|
32 |
+ ,tests =test.code |
|
33 |
+ ,strings-start ,print-string JSR2 |
|
31 | 34 |
BRK |
32 | 35 |
|
33 | 36 |
@ERROR BRK |
34 | 37 |
|
35 | 38 |
@FRAME |
36 |
- ~current-test |
|
39 |
+ ,recover ~test.status JMP2? |
|
40 |
+ #01 =test.status |
|
41 |
+ ~test.code |
|
42 |
+ DUP2 ,find-label JSR2 |
|
43 |
+ DUP2 =test.label |
|
44 |
+ ,find-code JSR2 =test.code |
|
45 |
+ JMP2 |
|
46 |
+ |
|
47 |
+@find-label ( ptr₂ -- following-label-ptr₂ ) |
|
48 |
+ DUP2 PEK2 LIT BRK2?r NEQ ^$next-minus-1 SWP JMP? |
|
49 |
+ DUP2 #0001 ADD2 PEK2 LIT LITr NEQ ^$next-minus-1 SWP JMP? |
|
50 |
+ DUP2 #0002 ADD2 PEK2 LIT EOR2? NEQ ^$next-minus-1 SWP JMP? |
|
51 |
+ DUP2 #0003 ADD2 PEK2 LIT DUP? NEQ ^$next-minus-1 SWP JMP? |
|
52 |
+ #0004 ADD2 $next-minus-1 JMP2r |
|
37 | 53 |
|
38 |
- $search |
|
54 |
+ ( next ) |
|
55 |
+ #0001 ADD2 ^find-label JMP |
|
56 |
+ |
|
57 |
+@find-code ( label-ptr₂ -- following-code-ptr₂ ) |
|
58 |
+ DUP2 PEK2 |
|
59 |
+ ,$not-end ROT JMP2? |
|
60 |
+ |
|
61 |
+ $end |
|
39 | 62 |
#0001 ADD2 |
40 |
- DUP2 LDR LIT BRK2?r NEQ ,$search ROT JMP2? |
|
41 |
- DUP2 #0001 ADD2 LDR LIT LITr NEQ ,$search ROT JMP2? |
|
42 |
- DUP2 #0002 ADD2 LDR LIT EOR2? NEQ ,$search ROT JMP2? |
|
43 |
- DUP2 #0003 ADD2 LDR LIT DUP? NEQ ,$search ROT JMP2? |
|
44 |
- #0004 ADD2 DUP2 =current-test |
|
45 |
- JMP2 |
|
63 |
+ JMP2r |
|
64 |
+ |
|
65 |
+ $not-end |
|
66 |
+ #0001 ADD2 ^find-code JMP |
|
67 |
+ |
|
68 |
+@recover |
|
69 |
+ ( would it have been a PASS or FAIL? ) |
|
70 |
+ ,$clear ~test.label #000a SUB2 PEK2 LIT LIT EQU JMP2? |
|
71 |
+ #02 ^result JMP |
|
72 |
+ |
|
73 |
+ $clear |
|
74 |
+ ( I would have executed a PASS or FAIL, so invert the result ) |
|
75 |
+ ~test.label #0009 SUB2 PEK2 #00 EQU ^result JMP |
|
46 | 76 |
|
47 | 77 |
@result |
78 |
+ DUP #02 MUL #00 SWP ,counts ADD2 |
|
79 |
+ DUP2 LDR2 #0001 ADD2 SWP2 STR2 |
|
80 |
+ #00 =test.status |
|
48 | 81 |
,strings-test ^print-string JSR |
49 | 82 |
#00 SWP ,strings-pass ,strings-fail SUB2 MUL2 ,strings-fail ADD2 ^print-string JSR |
50 |
- STH2r DUP2 ^print-short JSR |
|
51 | 83 |
,strings-colon ^print-string JSR |
52 |
- ^print-string JSR |
|
84 |
+ ~test.label ^print-string JSR |
|
53 | 85 |
#0a =Console.char |
86 |
+ POP #fc JMP |
|
87 |
+ BRK |
|
88 |
+ |
|
89 |
+@finish |
|
90 |
+ ,strings-finish ^print-string JSR |
|
91 |
+ ~counts.passed ^print-decimal JSR |
|
92 |
+ ,strings-passed ^print-string JSR |
|
93 |
+ ~counts.failed ^print-decimal JSR |
|
94 |
+ ,strings-failed ^print-string JSR |
|
95 |
+ ~counts.unknown ^print-decimal JSR |
|
96 |
+ ,strings-unknown ^print-string JSR |
|
97 |
+ |
|
98 |
+ ( stop executing tests ) |
|
99 |
+ LIT BRK ,FRAME POK2 |
|
54 | 100 |
BRK |
55 | 101 |
|
56 | 102 |
@print-string ( string₂ -- ) |
57 |
- DUP2 LDR DUP |
|
103 |
+ DUP2 PEK2 DUP |
|
58 | 104 |
,$not-end ROT JMP2? |
59 | 105 |
|
60 | 106 |
$end |
... | ... |
@@ -65,6 +111,25 @@ |
65 | 111 |
=Console.char |
66 | 112 |
#0001 ADD2 ^print-string JMP |
67 | 113 |
|
114 |
+@print-decimal ( short₂ -- ) |
|
115 |
+ #00 =number.started |
|
116 |
+ DUP2 #2710 DIV2 DUP2 ^$digit JSR #2710 MUL2 SUB2 |
|
117 |
+ DUP2 #03e8 DIV2 DUP2 ^$digit JSR #03e8 MUL2 SUB2 |
|
118 |
+ DUP2 #0064 DIV2 DUP2 ^$digit JSR #0064 MUL2 SUB2 |
|
119 |
+ DUP2 #000a DIV2 DUP2 ^$digit JSR #000a MUL2 SUB2 |
|
120 |
+ ^$digit JSR |
|
121 |
+ ~number.started JMP2r? |
|
122 |
+ #30 =Console.char |
|
123 |
+ JMP2r |
|
124 |
+ |
|
125 |
+ $digit |
|
126 |
+ SWP POP |
|
127 |
+ #02 OVR ~number.started ORA JMP? |
|
128 |
+ POP JMP2r |
|
129 |
+ #30 ADD =Console.char |
|
130 |
+ #01 =number.started |
|
131 |
+ JMP2r |
|
132 |
+ |
|
68 | 133 |
@print-short ( short₂ -- ) |
69 | 134 |
#30 =Console.char |
70 | 135 |
#78 =Console.char |
... | ... |
@@ -82,10 +147,15 @@ |
82 | 147 |
JMP2r |
83 | 148 |
|
84 | 149 |
@strings |
150 |
+ $start [ 0a Testing 20 started. 0a 0a 00 ] |
|
85 | 151 |
$test [ Test 20 00 ] |
86 |
- $fail [ FAIL 20 at 20 00 ] |
|
87 |
- $pass [ pass 20 at 20 00 ] |
|
152 |
+ $fail [ FAIL 00 ] |
|
153 |
+ $pass [ pass 00 ] |
|
154 |
+ [ UNKNOWN 00 ] |
|
155 |
+ $at [ at 20 00 ] |
|
88 | 156 |
$colon [ : 20 00 ] |
89 |
- |
|
90 |
-;current-test { short 2 } |
|
157 |
+ $finish [ 0a Testing 20 complete. 0a 00 ] |
|
158 |
+ $passed [ 20 passed, 20 00 ] |
|
159 |
+ $failed [ 20 failed, 20 00 ] |
|
160 |
+ $unknown [ 20 were 20 unknown. 0a 00 ] |
|
91 | 161 |
|
... | ... |
@@ -48,8 +48,8 @@ void op_lts(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, (S |
48 | 48 |
void op_jmp(Uxn *u) { Uint8 a = pop8(u->src); u->ram.ptr += (Sint8)a; } |
49 | 49 |
void op_jsr(Uxn *u) { Uint8 a = pop8(u->src); push16(u->dst, u->ram.ptr); u->ram.ptr += (Sint8)a; } |
50 | 50 |
/* Memory */ |
51 |
-void op_pek(Uxn *u) { Uint16 a = pop8(u->src); push8(u->src, mempeek8(u, a)); } |
|
52 |
-void op_pok(Uxn *u) { Uint16 a = pop8(u->src); Uint8 b = pop8(u->src); mempoke8(u, a, b); } |
|
51 |
+void op_pek(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, mempeek8(u, a)); } |
|
52 |
+void op_pok(Uxn *u) { Uint8 a = pop8(u->src); Uint8 b = pop8(u->src); mempoke8(u, a, b); } |
|
53 | 53 |
void op_ldr(Uxn *u) { Uint8 a = pop8(u->src); push16(u->src, mempeek16(u, a)); } |
54 | 54 |
void op_str(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); mempoke16(u, a, b); } |
55 | 55 |
void op_cln(Uxn *u) { push8(u->src, peek8(u->dst, 0)); } |