git @ Cat's Eye Technologies SixtyPical / 5a49382
Improve test coverage. One failing test. Cat's Eye Technologies 7 years ago
1 changed file(s) with 60 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
1818 = NamedLocation Nothing "score": UpdatedWith A
1919
2020 A routine cannot expect registers which a called routine does not
21 preserve, to be preserved.
21 preserve, to be preserved. We say the called routine "poisons" those
22 registers.
2223
2324 | assign byte border_colour 4000
2425 | reserve byte score
3435 | }
3536 ? routine 'main' does not preserve 'A'
3637
37 But if it does it can.
38 But if a called routine does preserve those registers, the caller can
39 continue to use them after calling the routine.
3840
3941 | assign byte border_colour 4000
4042 | reserve byte score
5961 = X: UpdatedWith (Immediate 1)
6062 = NamedLocation Nothing "score": UpdatedWith X
6163
62 We can't expect to stay named variables to stay unmodified either.
64 Not only registers, but also named variables, can be poisoned by a called
65 routine.
6366
6467 | reserve byte score
6568 | routine update_score
7376 | }
7477 ? routine 'main' does not preserve 'NamedLocation Nothing "score"'
7578
76 What the solution to the above is to notate `update_score` as intentionally
77 modifying score, as an "output" of the routine.
79 Of course, the difference between poisoning and intentionally modifying a
80 storage location is a matter of intent. The solution to the above is to
81 explicitly notate `update_score` as an "output" of the routine.
7882
7983 | assign byte border_colour 4000
8084 | reserve byte score
235239 | }
236240 ? routine 'main' does not preserve 'NamedLocation Nothing "score"'
237241
238 | assign vector cinv 788
239 | reserve vector save_cinv
240 |
242 Some more tests...
243
241244 | assign word position $fb
242 |
243245 | reserve byte value
244246 |
245247 | routine reset_position {
249251 | sta >position
250252 | }
251253 |
252 | routine our_cinv {
254 | routine main {
253255 | inc value
254256 | lda value
255257 | ldy #0
258260 | jsr reset_position
259261 | } else {
260262 | }
261 | jmp (save_cinv)
262 | }
263 |
264 | routine main {
265 | jsr reset_position
266 | sei {
267 | copy cinv save_cinv
268 | copy routine our_cinv to cinv
269 | }
270 | clc
271 | repeat bcc { }
272 | }
273 = main ([])
274 = A: PoisonedWith (Immediate 4)
275 = FlagC: UpdatedWith (Immediate 0)
276 = NamedLocation Nothing "cinv": UpdatedWith (Immediate 7)
277 = NamedLocation Nothing "position": PoisonedWith A
278 = NamedLocation Nothing "save_cinv": UpdatedWith (NamedLocation Nothing "cinv")
279 =
280 = our_cinv ([])
263 | }
264 = main ([])
281265 = A: PoisonedWith (Immediate 4)
282266 = Y: UpdatedWith (Immediate 0)
283267 = IndirectIndexed (NamedLocation (Just Word) "position") Y: UpdatedWith A
287271 = reset_position ([])
288272 = A: UpdatedWith (Immediate 4)
289273 = NamedLocation Nothing "position": UpdatedWith A
274
275 | assign word position $fb
276 | reserve byte value
277 |
278 | routine reset_position {
279 | lda #$00
280 | sta <position
281 | lda #$04
282 | sta >position
283 | }
284 |
285 | routine main {
286 | inc value
287 | lda value
288 | ldy #0
289 | sta (position), y
290 | if beq {
291 | jsr reset_position
292 | } else {
293 | }
294 | sta value
295 | }
296 ? routine 'main' does not preserve 'A'
297
298 | assign word position $fb
299 | reserve byte value
300 |
301 | routine reset_position {
302 | lda #$00
303 | sta <position
304 | lda #$04
305 | sta >position
306 | }
307 |
308 | routine main {
309 | inc value
310 | lda value
311 | ldy #0
312 | sta (position), y
313 | jsr reset_position
314 | if beq {
315 | } else {
316 | sta value
317 | }
318 | }
319 ? routine 'main' does not preserve 'A'