jaoswald / cl-comfy-6502

Baker's COMFY compiler for the 6502 ported to Common Lisp

This URL has Read+Write access

cl-comfy-6502 / 6502-tests.lisp
100644 265 lines (233 sloc) 8.588 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
;;;; -*- mode: Lisp; Syntax: ANSI-Common-Lisp; Package: ("6502-TESTS" ("CL" "6502" "RT")); -*-
;;;;
;;;; 6502-tests.lisp
;;;;
;;;; Uses RT regression test framework
 
(cl:defpackage "6502-TESTS"
  (:use "COMMON-LISP" "6502" #+sbcl "SB-RT" #-sbcl "RT"))
 
(in-package "6502-TESTS")
 
(defmacro def-branch-test (instruction opcode)
  "Define a test for a branch instruction (a symbol) which has
the specified numeric opcode."
  (let ((base-name (symbol-name instruction))
(sym instruction)
(code opcode))
    `(progn
       (deftest ,(make-symbol (concatenate 'string base-name "-test-1"))
(opcode-to-byte (make-symbolic-opcode ',sym :BRANCH-RELATIVE))
,code)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-2"))
(opcode-to-byte (make-symbolic-opcode ',sym nil))
,code)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-3"))
(handler-case
(opcode-to-byte (make-symbolic-opcode ',sym :IMMEDIATE))
(bad-address-mode () :pass)
(error () :unexpected-error)
(:no-error () :no-error))
:pass)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-4"))
(handler-case
(opcode-to-byte (make-symbolic-opcode ',sym :BOGUS))
(bad-address-mode () :pass)
(error () :unexpected-error)
(:no-error () :no-error))
:pass))))
 
 
(def-branch-test BCC 144)
(def-branch-test BCS 176)
(def-branch-test BEQ 240)
(def-branch-test BNE 208)
(def-branch-test BVS 112)
(def-branch-test BVC 80)
(def-branch-test BMI 48)
(def-branch-test BPL 16)
 
;;; RT apparently doesn't support "suites" of tests
 
#||
(build-suite "branch-suite"
"BCC-test" "BCS-test"
"BEQ-test" "BNE-test"
"BVS-test" "BVC-test"
"BMI-test" "BPL-test")
||#
 
(defmacro def-implied-test (instruction opcode)
  "Define a test for an implied-address-mode instruction (a symbol) which has
the specified numeric opcode."
  (let ((base-name (symbol-name instruction))
(sym instruction)
(code opcode))
    `(progn
       (deftest ,(make-symbol (concatenate 'string base-name "-test-1"))
(opcode-to-byte (make-symbolic-opcode ',sym :IMPLIED))
,code)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-2"))
(opcode-to-byte (make-symbolic-opcode ',sym nil))
,code)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-3"))
(handler-case
(opcode-to-byte (make-symbolic-opcode ',sym :BRANCH-RELATIVE))
(bad-address-mode () :pass)
(error () :unexpected-error)
(:no-error () :no-error))
:pass)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-4"))
(handler-case
(opcode-to-byte (make-symbolic-opcode ',sym :IMMEDIATE))
(bad-address-mode () :pass)
(error () :unexpected-error)
(:no-error () :no-error))
:pass)
       (deftest ,(make-symbol (concatenate 'string base-name "-test-5"))
(handler-case
(opcode-to-byte (make-symbolic-opcode ',sym :BOGUS))
(bad-address-mode () :pass)
(error () :unexpected-error)
(:no-error () :no-error))
:pass))))
 
(def-implied-test BRK 0)
(def-implied-test NOP 234)
(def-implied-test PHP 8)
(def-implied-test PLP 40)
(def-implied-test PHA 72)
(def-implied-test PLA 104)
(def-implied-test CLC 24)
(def-implied-test SEC 56)
(def-implied-test CLV 184)
(def-implied-test CLI 88)
(def-implied-test SEI 120)
(def-implied-test CLD 216)
(def-implied-test SED 248)
(def-implied-test DEX 202)
(def-implied-test DEY 136)
(def-implied-test INX 232)
(def-implied-test INY 200)
(def-implied-test RTS 96)
(def-implied-test RTI 64)
(def-implied-test TAX 170)
(def-implied-test TXA 138)
(def-implied-test TAY 168)
(def-implied-test TYA 152)
(def-implied-test TXS 154)
(def-implied-test TSX 186)
 
#||
(build-suite "implied-suite"
"NOP-test" "BRK-test"
"PHP-test" "PLP-test"
"PHA-test" "PLA-test"
"CLC-test" "SEC-test"
"CLI-test" "SEI-test"
"CLD-test" "SED-test"
"CLV-test"
"INX-test" "DEX-test"
"INY-test" "DEY-test"
"RTS-test" "RTI-test"
"TXA-test" "TAX-test"
"TYA-test" "TAY-test"
"TXS-test" "TSX-test")
||#
 
;;; opcodes with multiple valid address modes
;;; define arbitrary order
;;; accumulator, immediate, absolute absolute-x absolute-y
;;; zero-page, zero-page-x, zp-x-indirect, zp-indirect-y
;;; absolute-indirect
;;; numeric means valid opcode, nil means address-mode disallowed
 
;;; FIXME: add assert-error for BRANCH-RELATIVE, IMPLIED, nil address-mode
 
(defmacro def-opcode-test (instruction acc imm abs abs-x abs-y
zp zp-x zp-x-ind zp-y zp-ind-y
abs-ind)
  (let ((base-name (symbol-name instruction))
(sym instruction)
(test-counter 0))
    `(progn
       ,@(mapcar (function (lambda (opcode am)
`(deftest ,(make-symbol
(concatenate 'string
base-name "-test"
(princ-to-string
(incf test-counter))))
,@(if opcode
(list
`(opcode-to-byte (make-symbolic-opcode
',sym ,am))
opcode)
(list
`(handler-case
(opcode-to-byte (make-symbolic-opcode
',sym ,am))
(bad-address-mode () :pass)
(error () :unexpected-error)
(:no-error () :no-error))
:pass)))))
(list acc imm
abs abs-x abs-y
zp zp-x zp-x-ind zp-y zp-ind-y
abs-ind)
'(:ACCUMULATOR :IMMEDIATE
:ABSOLUTE :ABSOLUTE-X :ABSOLUTE-Y
:ZERO-PAGE :ZERO-PAGE-X
:ZP-X-INDIRECT
:ZERO-PAGE-Y :ZP-INDIRECT-Y
:ABSOLUTE-INDIRECT)))))
 
;; acc imm abs abs-x abs-y zp zp-x zp-x-ind zp-y zp-ind-y abs-ind
 
(def-opcode-test STA nil nil 141 157 153 133 149 129 nil 145 nil)
(def-opcode-test LDA nil 169 173 189 185 165 181 161 nil 177 nil)
(def-opcode-test ORA nil 9 13 29 25 5 21 1 nil 17 nil)
(def-opcode-test ADC nil 105 109 125 121 101 117 97 nil 113 nil)
(def-opcode-test SBC nil 233 237 253 249 229 245 225 nil 241 nil)
(def-opcode-test EOR nil 73 77 93 89 69 85 65 nil 81 nil)
(def-opcode-test CMP nil 201 205 221 217 197 213 193 nil 209 nil)
(def-opcode-test AND nil 41 45 61 57 37 53 33 nil 49 nil)
 
#||
(build-suite "accum-suite"
"STA-test" "LDA-test"
"ADC-test" "SBC-test"
"ORA-test" "EOR-test" "AND-test"
"CMP-test")
||#
 
;; acc imm abs abs-x abs-y zp zp-x zp-x-ind zp-y zp-ind-y abs-ind
(def-opcode-test ASL 10 nil 14 30 nil 6 22 nil nil nil nil)
(def-opcode-test LSR 74 nil 78 94 nil 70 86 nil nil nil nil)
(def-opcode-test ROR 106 nil 110 126 nil 102 118 nil nil nil nil)
(def-opcode-test ROL 42 nil 46 62 nil 38 54 nil nil nil nil)
 
#||
(build-suite "rotate-suite"
"ASL-test" "LSR-test"
"ROL-test" "ROR-test")
||#
 
;; acc imm abs abs-x abs-y zp zp-x zp-x-ind zp-y zp-ind-y abs-ind
(def-opcode-test INC nil nil 238 254 nil 230 246 nil nil nil nil)
(def-opcode-test DEC nil nil 206 222 nil 198 214 nil nil nil nil)
 
(def-opcode-test BIT nil nil 44 nil nil 36 nil nil nil nil nil)
 
#||
(build-suite "inc/dec/bit-suite"
"INC-test"
"DEC-test"
"BIT-test")
||#
 
;; acc imm abs abs-x abs-y zp zp-x zp-x-ind zp-y zp-ind-y abs-ind
(def-opcode-test JMP nil nil 76 nil nil nil nil nil nil nil 108)
(def-opcode-test JSR nil nil 32 nil nil nil nil nil nil nil nil)
 
#||
(build-suite "jump-suite"
"JSR-test"
"JMP-test")
||#
 
;; acc imm abs abs-x abs-y zp zp-x zp-x-ind zp-y zp-ind-y abs-ind
(def-opcode-test LDX nil 162 174 nil 190 166 nil nil 182 nil nil)
(def-opcode-test STX nil nil 142 nil nil 134 nil nil 150 nil nil)
(def-opcode-test LDY nil 160 172 188 nil 164 180 nil nil nil nil)
(def-opcode-test STY nil nil 140 nil nil 132 148 nil nil nil nil)
 
(def-opcode-test CPX nil 224 236 nil nil 228 nil nil nil nil nil)
(def-opcode-test CPY nil 192 204 nil nil 196 nil nil nil nil nil)
 
#||
(build-suite "index-suite"
"LDX-test" "LDY-test"
"STX-test" "STY-test"
"CPX-test" "CPY-test")
||#
 
#||
;; used by suites, unless the suite is built again.
 
;; suite-of-suites, requires modifications to elk-test.el
 
(build-suite "6502-opcode-suite"
"branch-suite" "implied-suite" "accum-suite" "rotate-suite"
"inc/dec/bit-suite" "jump-suite" "index-suite")
 
||#