Index  Comments

All of nonogram.chip8, nonogram.mmc, and the puzzles are available under the CC0 Public Domain Dedication.

I'll improve this article soon.

This is a basic nonogram game written for the Octojam VIII event. For a previous iteration, someone submitted a nonogram game, and I thought I could easily do much better, and now have. Originally, I wanted to write this very basic version months ago and leave a much better implementation for later; I failed to do this, but may simply write the better version soon anyway. This is my largest CHIP-8 game, because I was very lazy and simply wrote something that worked; rather than carefully planning global optimizations, I wrote disconnected routines to combine them inefficiently in the prime loop.

Follows is a view of the complete game, when loaded into the MMC:

200-201 0512-0513 ▄▄▄▄▄▄▄▄ 00FF 00255                 Enable extended mode
202-203 0514-0515  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
204-205 0516-0517 █▄█▄████ AFFF 45055           begin I ← 4095
206-207 0518-0519 █▄▄      80E0 32992                 V0 ← VE
208-209 0520-0521 ▀█▀█ ▄ ▄ F055 61525                 Save V0→V0; I ← I + 01
20A-20B 0522-0523 █ █▄▄▄██ A3BF 41919                 I ← puzzles
20C-20D 0524-0525 █▄▄ ▄▄▄  80EE 33006                 V0 ← VE × 2; VF ← MSB
20E-20F 0526-0527 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
210-211 0528-0529 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
212-213 0530-0531 ▀▀▀█▄▄▄  F01E 61470                 I ← I + V0
214-215 0532-0533 ▀▀▀█▄▄▄  F01E 61470                 I ← I + V0
216-217 0534-0535 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
218-219 0536-0537 █ █ ▄▄██ A3AF 41903                 I ← primary work
21A-21B 0538-0539 ▀█▀█▀█▀█ FF55 65365                 Save V0→VF; I ← I + 16
21C-21D 0540-0541 █▄█▄████ AFFF 45055                 I ← 4095
21E-21F 0542-0543 ▀██▀ ▄ ▄ F065 61541                 Load V0→V0; I ← I + 01
220-221 0544-0545 ▀   ▀▀▀  8E00 36352                 VE ← V0
222-223 0546-0547 █ █ ▄▄██ A3AF 41903                 I ← primary work
224-225 0548-0549 ▀██▀ █▀█ F765 63333                 Load V0→V7; I ← I + 08
226-227 0550-0551 ▄▄█ ▄ █  22EA 08938                 Call rows
228-229 0552-0553 █ █▄ ▄██ A3B7 41911                 I ← secondary work
22A-22B 0554-0555 ▀██▀ █▀█ F765 63333                 Load V0→V7; I ← I + 08
22C-22D 0556-0557   █   ▀▀ 2320 08992                 Call columns
22E-22F 0558-0559 █▄█▄▀█▀▀ AFF4 45044                 I ← 4084
230-231 0560-0561 ▀██▀ █▀█ F765 63333                 Load V0→V7; I ← I + 08
232-233 0562-0563 █ █▄ ▄██ A3B7 41911                 I ← secondary work
234-235 0564-0565 ▀█▀█ █▀█ F755 63317                 Save V0→V7; I ← I + 08
236-237 0566-0567 █▄█▄██▀▀ AFFC 45052                 I ← 4092
238-239 0568-0569 ▀▀██▀▀█▄ FE33 65075                 VE as BCD stored from I
23A-23B 0570-0571 ▀██▀ ▄▀▄ F265 62053                 Load V0→V2; I ← I + 03
23C-23D 0572-0573 ▀▀█▀▄  ▄ F029 61481                 I ← digit sprite of V0
23E-23F 0574-0575 ▀█ ▀ ▄▀█ D345 54085                 Draw 08×05 at V3,V4; VF ← XOR
240-241 0576-0577  ▀▀▀ ▄▀█ 7305 29445                 V3 ← V3 + 005
242-243 0578-0579 ▀▀█▀▄  █ F129 61737                 I ← digit sprite of V1
244-245 0580-0581 ▀█ ▀ ▄▀█ D345 54085                 Draw 08×05 at V3,V4; VF ← XOR
246-247 0582-0583  ▀▀▀ ▄▀█ 7305 29445                 V3 ← V3 + 005
248-249 0584-0585 ▀▀█▀▄ ▀▄ F229 61993                 I ← digit sprite of V2
24A-24B 0586-0587 ▀█ ▀ ▄▀█ D345 54085                 Draw 08×05 at V3,V4; VF ← XOR
24C-24D 0588-0589 ▀▀▀▀█ ▄▀ F90A 63754           prime V9 ← key
24E-24F 0590-0591 █  ▄     8090 32912                 V0 ← V9
250-251 0592-0593 ▄ █ ▄ █  22AA 08874                 Call key check
252-253 0594-0595   ▀▀     3000 12288                 Skip next if V0 = 000
254-255 0596-0597  ▄ ▀▄▄▀  124C 04684                 Jump to prime
256-257 0598-0599 ▀▀▀▀█ ▄  F80A 63498                 V8 ← key
258-259 0600-0601 █        8080 32896                 V0 ← V8
25A-25B 0602-0603 ▄ █ ▄ █  22AA 08874                 Call key check
25C-25D 0604-0605   ▀▀     3000 12288                 Skip next if V0 = 000
25E-25F 0606-0607  ▄ ▀▄▄▀  124C 04684                 Jump to prime
260-261 0608-0609 █ █▄ ▄██ A3B7 41911                 I ← secondary work
262-263 0610-0611 ▀▀▀██▄▄  F81E 63518                 I ← I + V8
264-265 0612-0613 ▀██▀ ▄ ▄ F065 61541                 Load V0→V0; I ← I + 01
266-267 0614-0615 ▀      ▀ 8100 33024                 V1 ← V0
268-269 0616-0617 █  ▄▄▄▄  809E 32926                 V0 ← V9 × 2; VF ← MSB
26A-26B 0618-0619  ▀▀   ▀▄ 6201 25089                 V2 ← 001
26C-26D 0620-0621 ▀▄█▄  ▀  A270 41584                 I ← barrel
26E-26F 0622-0623 ▀▄██  ▀  B270 45680                 Jump to V0 + barrel
270-271 0624-0625 ▀ ▄ ▄▄█  822E 33326          barrel V2 ← V2 × 2; VF ← MSB
272-273 0626-0627 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
274-275 0628-0629 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
276-277 0630-0631 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
278-279 0632-0633 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
27A-27B 0634-0635 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
27C-27D 0636-0637 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
27E-27F 0638-0639 █ █▄ ▄██ A3B7 41911                 I ← secondary work
280-281 0640-0641 ▀▀▀██▄▄  F81E 63518                 I ← I + V8
282-283 0642-0643 ▀ ▄      8020 32800                 V0 ← V2
284-285 0644-0645 ▀  ▄  ▄▄ 8013 32787                 V0 ← V0 XOR V1
286-287 0646-0647 ▀█▀█ ▄ ▄ F055 61525                 Save V0→V0; I ← I + 01
288-289 0648-0649 ▄▄▀▄ ▄▀  22D4 08916                 Call fill in
28A-28B 0650-0651 █ █ ▄▄██ A3AF 41903                 I ← primary work
28C-28D 0652-0653 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
28E-28F 0654-0655 ▄ ▀ ▄ █▀ 238A 09098                 Call compare
290-291 0656-0657   ▀▀     3000 12288                 Skip next if V0 = 000
292-293 0658-0659  ▄ ▀▄▄▀  124C 04684                 Jump to prime
294-295 0660-0661  ▀▀ ▄ ▄  600A 24586                 V0 ← 010
296-297 0662-0663 ▀▀▀█▄    F018 61464                 sound ← V0
298-299 0664-0665 █▄█▄████ AFFF 45055                 I ← 4095
29A-29B 0666-0667 ▀██▀ ▄ ▄ F065 61541                 Load V0→V0; I ← I + 01
29C-29D 0668-0669  ▀▀▀   ▄ 7001 28673                 V0 ← V0 + 001
29E-29F 0670-0671  ▀▀▄███▄ 6E1F 28191                 VE ← 031
2A0-2A1 0672-0673 █▄▄   ▄  80E2 32994                 V0 ← V0 AND VE
2A2-2A3 0674-0675 ▀   ▀▀▀  8E00 36352                 VE ← V0
2A4-2A5 0676-0677 ▀▀▀▀▄ ▄  F00A 61450                 V0 ← key
2A6-2A7 0678-0679 ▄▄▄      00E0 00224                 Clear the screen
2A8-2A9 0680-0681    ▀ ▄▀  1204 04612                 Jump to begin
2AA-2AB 0682-0683 ▀   ▄▄▄  800E 32782       key check V0 ← V0 × 2; VF ← MSB
2AC-2AD 0684-0685 █ █▄  ▀  A2B0 41648                 I ← table
2AE-2AF 0686-0687 █ ██  ▀  B2B0 45744                 Jump to V0 + table
2B0-2B1 0688-0689 ▄▄ █  ▀  12D0 04816           table Jump to key turns
2B2-2B3 0690-0691 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2B4-2B5 0692-0693 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2B6-2B7 0694-0695 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2B8-2B9 0696-0697 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2BA-2BB 0698-0699 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2BC-2BD 0700-0701 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2BE-2BF 0702-0703 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2C0-2C1 0704-0705 ▀        8000 32768                 V0 ← V0
2C2-2C3 0706-0707 ▀        8000 32768                 V0 ← V0
2C4-2C5 0708-0709 ▀        8000 32768                 V0 ← V0
2C6-2C7 0710-0711 ▀        8000 32768                 V0 ← V0
2C8-2C9 0712-0713 ▀        8000 32768                 V0 ← V0
2CA-2CB 0714-0715 ▀        8000 32768                 V0 ← V0
2CC-2CD 0716-0717 ▀        8000 32768                 V0 ← V0
2CE-2CF 0718-0719  ▀ ▀     5000 20480                 Skip next if V0 = V0
2D0-2D1 0720-0721  ▀▀      6000 24576       key turns V0 ← 000
2D2-2D3 0722-0723 ▄▄▄ ▄▄▄  00EE 00238                 Return
2D4-2D5 0724-0725 █   ▄▄▄  808E 32910         fill in V0 ← V8 × 2; VF ← MSB
2D6-2D7 0726-0727 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
2D8-2D9 0728-0729 ▀   ▀▄   8804 34820                 V8 ← V8 + V0; VF ← overflow
2DA-2DB 0730-0731 █  ▄▄▄▄  809E 32926                 V0 ← V9 × 2; VF ← MSB
2DC-2DD 0732-0733 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
2DE-2DF 0734-0735 ▀   ▀▄ ▀ 8904 35076                 V9 ← V9 + V0; VF ← overflow
2E0-2E1 0736-0737 █ █ ▄ █▀ A3AA 41898                 I ← square
2E2-2E3 0738-0739  ▀▀█▀▄▄  7816 30742                 V8 ← V8 + 022
2E4-2E5 0740-0741  ▀▀██  ▀ 7918 31000                 V9 ← V9 + 024
2E6-2E7 0742-0743 █▀ ▀▀▄ █ D985 55685                 Draw 08×05 at V9,V8; VF ← XOR
2E8-2E9 0744-0745 ▄▄▄ ▄▄▄  00EE 00238                 Return
2EA-2EB 0746-0747  ▀▀ ▀▄ ▄ 6805 26629            rows V8 ← 005
2EC-2ED 0748-0749  ▀▀ ▀  ▀ 6900 26880                 V9 ← 000
2EE-2EF 0750-0751  ▀▀ █▄█▄ 6A0F 27151                 VA ← 015
2F0-2F1 0752-0753  ▀▀▄▀▄█▀ 6B16 27414                 VB ← 022
2F2-2F3 0754-0755  ▄▀▄ ▄█▀ 2356 09046                 Call display
2F4-2F5 0756-0757 ▀  ▄     8010 32784                 V0 ← V1
2F6-2F7 0758-0759  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
2F8-2F9 0760-0761  ▄▀▄ ▄█▀ 2356 09046                 Call display
2FA-2FB 0762-0763 ▀ ▄      8020 32800                 V0 ← V2
2FC-2FD 0764-0765  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
2FE-2FF 0766-0767  ▄▀▄ ▄█▀ 2356 09046                 Call display
300-301 0768-0769 ▀ ▄▄     8030 32816                 V0 ← V3
302-303 0770-0771  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
304-305 0772-0773  ▄▀▄ ▄█▀ 2356 09046                 Call display
306-307 0774-0775 ▀▄       8040 32832                 V0 ← V4
308-309 0776-0777  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
30A-30B 0778-0779  ▄▀▄ ▄█▀ 2356 09046                 Call display
30C-30D 0780-0781 ▀▄ ▄     8050 32848                 V0 ← V5
30E-30F 0782-0783  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
310-311 0784-0785  ▄▀▄ ▄█▀ 2356 09046                 Call display
312-313 0786-0787 ▀▄▄      8060 32864                 V0 ← V6
314-315 0788-0789  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
316-317 0790-0791  ▄▀▄ ▄█▀ 2356 09046                 Call display
318-319 0792-0793 ▀▄▄▄     8070 32880                 V0 ← V7
31A-31B 0794-0795  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
31C-31D 0796-0797  ▄▀▄ ▄█▀ 2356 09046                 Call display
31E-31F 0798-0799 ▄▄▄ ▄▄▄  00EE 00238                 Return
320-321 0800-0801  ▀▀ ▀    6800 26624         columns V8 ← 000
322-323 0802-0803  ▀▀ ▀▄ █ 6905 26885                 V9 ← 005
324-325 0804-0805  ▀▀▄█ ▀▄ 6A19 27161                 VA ← 025
326-327 0806-0807  ▀▀ █▄▀▀ 6B0C 27404                 VB ← 012
328-329 0808-0809  ▄▀▄ ▄█▀ 2356 09046                 Call display
32A-32B 0810-0811 ▀  ▄     8010 32784                 V0 ← V1
32C-32D 0812-0813  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
32E-32F 0814-0815  ▄▀▄ ▄█▀ 2356 09046                 Call display
330-331 0816-0817 ▀ ▄      8020 32800                 V0 ← V2
332-333 0818-0819  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
334-335 0820-0821  ▄▀▄ ▄█▀ 2356 09046                 Call display
336-337 0822-0823 ▀ ▄▄     8030 32816                 V0 ← V3
338-339 0824-0825  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
33A-33B 0826-0827  ▄▀▄ ▄█▀ 2356 09046                 Call display
33C-33D 0828-0829 ▀▄       8040 32832                 V0 ← V4
33E-33F 0830-0831  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
340-341 0832-0833  ▄▀▄ ▄█▀ 2356 09046                 Call display
342-343 0834-0835 ▀▄ ▄     8050 32848                 V0 ← V5
344-345 0836-0837  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
346-347 0838-0839  ▄▀▄ ▄█▀ 2356 09046                 Call display
348-349 0840-0841 ▀▄▄      8060 32864                 V0 ← V6
34A-34B 0842-0843  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
34C-34D 0844-0845  ▄▀▄ ▄█▀ 2356 09046                 Call display
34E-34F 0846-0847 ▀▄▄▄     8070 32880                 V0 ← V7
350-351 0848-0849  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
352-353 0850-0851  ▄▀▄ ▄█▀ 2356 09046                 Call display
354-355 0852-0853 ▄▄▄ ▄▄▄  00EE 00238                 Return
356-357 0854-0855  ▄█ ▄ █▀ 236A 09066         display Call decode
358-359 0856-0857 ▀▀█▀█▀ ▄ FC29 64553                 I ← digit sprite of VC
35A-35B 0858-0859 █▀▄█▀▄▀▄ DAB5 55989                 Draw 08×05 at VA,VB; VF ← XOR
35C-35D 0860-0861 █   ▀▄▀  8A84 35460                 VA ← VA + V8; VF ← overflow
35E-35F 0862-0863 █  ▄▀▄▀▀ 8B94 35732                 VB ← VB + V9; VF ← overflow
360-361 0864-0865 ▀▀█▀█▀ █ FD29 64809                 I ← digit sprite of VD
362-363 0866-0867 █▀▄█▀▄▀▄ DAB5 55989                 Draw 08×05 at VA,VB; VF ← XOR
364-365 0868-0869 █   ▀▄▀▄ 8A85 35461                 VA ← VA − V8; VF ← borrow
366-367 0870-0871 █  ▄▀▄▀█ 8B95 35733                 VB ← VB − V9; VF ← borrow
368-369 0872-0873 ▄▄▄ ▄▄▄  00EE 00238                 Return
36A-36B 0874-0875  ▀▀ ▀▀   6C00 27648          decode VC ← 000
36C-36D 0876-0877  ▀▀ ▀▀ ▀ 6D00 27904                 VD ← 000
36E-36F 0878-0879  ▀       4000 16384           check Skip next if V0 <> 000
370-371 0880-0881 ▄▄▄ ▄▄▄  00EE 00238                 Return
372-373 0882-0883 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
374-375 0884-0885   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
376-377 0886-0887  ▀▀▀▀▀ █ 7D01 32001                 VD ← VD + 001
378-379 0888-0889   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
37A-37B 0890-0891  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
37C-37D 0892-0893  ▀  ▀▀ ▀ 4D00 19712                 Skip next if VD <> 000
37E-37F 0894-0895  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
380-381 0896-0897   ▀▀▀▀   3C00 15360                 Skip next if VC = 000
382-383 0898-0899  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
384-385 0900-0901 █▄ ▄▀▀   8CD0 36048                 VC ← VD
386-387 0902-0903  ▀▀ ▀▀ ▀ 6D00 27904                 VD ← 000
388-389 0904-0905  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
38A-38B 0906-0907 █     ▄▄ 8083 32899         compare V0 ← V0 XOR V8
38C-38D 0908-0909 █  ▄  ▄█ 8193 33171                 V1 ← V1 XOR V9
38E-38F 0910-0911 █ ▄   █▄ 82A3 33443                 V2 ← V2 XOR VA
390-391 0912-0913 █ ▄▄  ██ 83B3 33715                 V3 ← V3 XOR VB
392-393 0914-0915 █▄   ▀▄▄ 84C3 33987                 V4 ← V4 XOR VC
394-395 0916-0917 █▄ ▄ ▀▄█ 85D3 34259                 V5 ← V5 XOR VD
396-397 0918-0919 █▄▄  ▀█▄ 86E3 34531                 V6 ← V6 XOR VE
398-399 0920-0921 █▄▄▄ ▀██ 87F3 34803                 V7 ← V7 XOR VF
39A-39B 0922-0923 ▀  ▄   ▄ 8011 32785                 V0 ← V0 OR V1
39C-39D 0924-0925 ▀ ▄    ▄ 8021 32801                 V0 ← V0 OR V2
39E-39F 0926-0927 ▀ ▄▄   ▄ 8031 32817                 V0 ← V0 OR V3
3A0-3A1 0928-0929 ▀▄     ▄ 8041 32833                 V0 ← V0 OR V4
3A2-3A3 0930-0931 ▀▄ ▄   ▄ 8051 32849                 V0 ← V0 OR V5
3A4-3A5 0932-0933 ▀▄▄    ▄ 8061 32865                 V0 ← V0 OR V6
3A6-3A7 0934-0935 ▀▄▄▄   ▄ 8071 32881                 V0 ← V0 OR V7
3A8-3A9 0936-0937 ▄▄▄ ▄▄▄  00EE 00238                 Return
3AA     0938      █████      F8   248          square 
3AB     0939      █████      F8   248                 
3AC     0940      █████      F8   248                 
3AD     0941      █████      F8   248                 
3AE     0942      █████      F8   248                 
3AF     0943                 00   000    primary work 
3B0-3B1 0944-0945          0000 00000                 
3B2-3B3 0946-0947          0000 00000                 
3B4-3B5 0948-0949          0000 00000                 
3B6-3B7 0950-0951          0000 00000! secondary work 
3B8-3B9 0952-0953          0000 00000                 
3BA-3BB 0954-0955          0000 00000                 
3BC-3BD 0956-0957          0000 00000                 
3BE     0958                 00   000                 
3BF     0959                 00   000         puzzles 

As the register usage is haphazard, I don't currently document it.

The game begins by entering extended mode, setting the initial puzzle to zero, and then saving this:

200-201 0512-0513 ▄▄▄▄▄▄▄▄ 00FF 00255                 Enable extended mode
202-203 0514-0515  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
204-205 0516-0517 █▄█▄████ AFFF 45055           begin I ← 4095
206-207 0518-0519 █▄▄      80E0 32992                 V0 ← VE
208-209 0520-0521 ▀█▀█ ▄ ▄ F055 61525                 Save V0→V0; I ← I + 01

The puzzles are indexed in units of sixteen; once indexed, they're copied to be dumped into the work area; then the puzzle code is restored. This segment of code limits the game to thirty-two puzzles:

20A-20B 0522-0523 █ █▄▄▄██ A3BF 41919                 I ← puzzles
20C-20D 0524-0525 █▄▄ ▄▄▄  80EE 33006                 V0 ← VE × 2; VF ← MSB
20E-20F 0526-0527 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
210-211 0528-0529 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
212-213 0530-0531 ▀▀▀█▄▄▄  F01E 61470                 I ← I + V0
214-215 0532-0533 ▀▀▀█▄▄▄  F01E 61470                 I ← I + V0
216-217 0534-0535 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
218-219 0536-0537 █ █ ▄▄██ A3AF 41903                 I ← primary work
21A-21B 0538-0539 ▀█▀█▀█▀█ FF55 65365                 Save V0→VF; I ← I + 16
21C-21D 0540-0541 █▄█▄████ AFFF 45055                 I ← 4095
21E-21F 0542-0543 ▀██▀ ▄ ▄ F065 61541                 Load V0→V0; I ← I + 01
220-221 0544-0545 ▀   ▀▀▀  8E00 36352                 VE ← V0

The first half is that which is canonical, and is easily used to report the row counts. That latter half is used solely for reporting the column counts with the same code, the area then being cleared:

222-223 0546-0547 █ █ ▄▄██ A3AF 41903                 I ← primary work
224-225 0548-0549 ▀██▀ █▀█ F765 63333                 Load V0→V7; I ← I + 08
226-227 0550-0551 ▄▄█ ▄ █  22EA 08938                 Call rows
228-229 0552-0553 █ █▄ ▄██ A3B7 41911                 I ← secondary work
22A-22B 0554-0555 ▀██▀ █▀█ F765 63333                 Load V0→V7; I ← I + 08
22C-22D 0556-0557   █   ▀▀ 2320 08992                 Call columns
22E-22F 0558-0559 █▄█▄▀█▀▀ AFF4 45044                 I ← 4084
230-231 0560-0561 ▀██▀ █▀█ F765 63333                 Load V0→V7; I ← I + 08
232-233 0562-0563 █ █▄ ▄██ A3B7 41911                 I ← secondary work
234-235 0564-0565 ▀█▀█ █▀█ F755 63317                 Save V0→V7; I ← I + 08

Lastly before the prime loop, the puzzle code is written in the top left corner of the screen:

236-237 0566-0567 █▄█▄██▀▀ AFFC 45052                 I ← 4092
238-239 0568-0569 ▀▀██▀▀█▄ FE33 65075                 VE as BCD stored from I
23A-23B 0570-0571 ▀██▀ ▄▀▄ F265 62053                 Load V0→V2; I ← I + 03
23C-23D 0572-0573 ▀▀█▀▄  ▄ F029 61481                 I ← digit sprite of V0
23E-23F 0574-0575 ▀█ ▀ ▄▀█ D345 54085                 Draw 08×05 at V3,V4; VF ← XOR
240-241 0576-0577  ▀▀▀ ▄▀█ 7305 29445                 V3 ← V3 + 005
242-243 0578-0579 ▀▀█▀▄  █ F129 61737                 I ← digit sprite of V1
244-245 0580-0581 ▀█ ▀ ▄▀█ D345 54085                 Draw 08×05 at V3,V4; VF ← XOR
246-247 0582-0583  ▀▀▀ ▄▀█ 7305 29445                 V3 ← V3 + 005
248-249 0584-0585 ▀▀█▀▄ ▀▄ F229 61993                 I ← digit sprite of V2
24A-24B 0586-0587 ▀█ ▀ ▄▀█ D345 54085                 Draw 08×05 at V3,V4; VF ← XOR

That prime loop begins by collecting the horizontal and then the vertical coordinates, zero-indexed; the key check routine limits the possible values, and restarts collection when a bad value is given:

24C-24D 0588-0589 ▀▀▀▀█ ▄▀ F90A 63754           prime V9 ← key
24E-24F 0590-0591 █  ▄     8090 32912                 V0 ← V9
250-251 0592-0593 ▄ █ ▄ █  22AA 08874                 Call key check
252-253 0594-0595   ▀▀     3000 12288                 Skip next if V0 = 000
254-255 0596-0597  ▄ ▀▄▄▀  124C 04684                 Jump to prime
256-257 0598-0599 ▀▀▀▀█ ▄  F80A 63498                 V8 ← key
258-259 0600-0601 █        8080 32896                 V0 ← V8
25A-25B 0602-0603 ▄ █ ▄ █  22AA 08874                 Call key check
25C-25D 0604-0605   ▀▀     3000 12288                 Skip next if V0 = 000
25E-25F 0606-0607  ▄ ▀▄▄▀  124C 04684                 Jump to prime

With valid indices, the selected row of the player's field is collected, and an XOR mask is created, by shifting a one according to the horizontal coordinate. The barrel routine is a group of shifting instructions dynamically entered; as the puzzle is indexed from the left, a coordinate of seven will result in no change to the initial mask, as no shifting instructions will be executed, to provide an example. After this, the XOR mask is applied to the prior row contents, and the new value is saved:

260-261 0608-0609 █ █▄ ▄██ A3B7 41911                 I ← secondary work
262-263 0610-0611 ▀▀▀██▄▄  F81E 63518                 I ← I + V8
264-265 0612-0613 ▀██▀ ▄ ▄ F065 61541                 Load V0→V0; I ← I + 01
266-267 0614-0615 ▀      ▀ 8100 33024                 V1 ← V0
268-269 0616-0617 █  ▄▄▄▄  809E 32926                 V0 ← V9 × 2; VF ← MSB
26A-26B 0618-0619  ▀▀   ▀▄ 6201 25089                 V2 ← 001
26C-26D 0620-0621 ▀▄█▄  ▀  A270 41584                 I ← barrel
26E-26F 0622-0623 ▀▄██  ▀  B270 45680                 Jump to V0 + barrel
270-271 0624-0625 ▀ ▄ ▄▄█  822E 33326          barrel V2 ← V2 × 2; VF ← MSB
272-273 0626-0627 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
274-275 0628-0629 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
276-277 0630-0631 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
278-279 0632-0633 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
27A-27B 0634-0635 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
27C-27D 0636-0637 ▀ ▄ ▄▄█  822E 33326                 V2 ← V2 × 2; VF ← MSB
27E-27F 0638-0639 █ █▄ ▄██ A3B7 41911                 I ← secondary work
280-281 0640-0641 ▀▀▀██▄▄  F81E 63518                 I ← I + V8
282-283 0642-0643 ▀ ▄      8020 32800                 V0 ← V2
284-285 0644-0645 ▀  ▄  ▄▄ 8013 32787                 V0 ← V0 XOR V1
286-287 0646-0647 ▀█▀█ ▄ ▄ F055 61525                 Save V0→V0; I ← I + 01

It's then necessary to display that change and validate the player's field against the puzzle field. The prime loop repeats, unless the fields match, in which case a sound is played, the puzzle code is incremented and applied to an AND mask to restrict its range, a key is taken to pause, and it loops:

288-289 0648-0649 ▄▄▀▄ ▄▀  22D4 08916                 Call fill in
28A-28B 0650-0651 █ █ ▄▄██ A3AF 41903                 I ← primary work
28C-28D 0652-0653 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
28E-28F 0654-0655 ▄ ▀ ▄ █▀ 238A 09098                 Call compare
290-291 0656-0657   ▀▀     3000 12288                 Skip next if V0 = 000
292-293 0658-0659  ▄ ▀▄▄▀  124C 04684                 Jump to prime
294-295 0660-0661  ▀▀ ▄ ▄  600A 24586                 V0 ← 010
296-297 0662-0663 ▀▀▀█▄    F018 61464                 sound ← V0
298-299 0664-0665 █▄█▄████ AFFF 45055                 I ← 4095
29A-29B 0666-0667 ▀██▀ ▄ ▄ F065 61541                 Load V0→V0; I ← I + 01
29C-29D 0668-0669  ▀▀▀   ▄ 7001 28673                 V0 ← V0 + 001
29E-29F 0670-0671  ▀▀▄███▄ 6E1F 28191                 VE ← 031
2A0-2A1 0672-0673 █▄▄   ▄  80E2 32994                 V0 ← V0 AND VE
2A2-2A3 0674-0675 ▀   ▀▀▀  8E00 36352                 VE ← V0
2A4-2A5 0676-0677 ▀▀▀▀▄ ▄  F00A 61450                 V0 ← key
2A6-2A7 0678-0679 ▄▄▄      00E0 00224                 Clear the screen
2A8-2A9 0680-0681    ▀ ▄▀  1204 04612                 Jump to begin

The key check routine merely jumps into a table for all sixteen possible values, as this was easy to write. The value in register zero can't be zero in the latter half; the value simply isn't changed:

2AA-2AB 0682-0683 ▀   ▄▄▄  800E 32782       key check V0 ← V0 × 2; VF ← MSB
2AC-2AD 0684-0685 █ █▄  ▀  A2B0 41648                 I ← table
2AE-2AF 0686-0687 █ ██  ▀  B2B0 45744                 Jump to V0 + table
2B0-2B1 0688-0689 ▄▄ █  ▀  12D0 04816           table Jump to key turns
2B2-2B3 0690-0691 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2B4-2B5 0692-0693 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2B6-2B7 0694-0695 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2B8-2B9 0696-0697 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2BA-2BB 0698-0699 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2BC-2BD 0700-0701 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2BE-2BF 0702-0703 ▄▄ █  ▀  12D0 04816                 Jump to key turns
2C0-2C1 0704-0705 ▀        8000 32768                 V0 ← V0
2C2-2C3 0706-0707 ▀        8000 32768                 V0 ← V0
2C4-2C5 0708-0709 ▀        8000 32768                 V0 ← V0
2C6-2C7 0710-0711 ▀        8000 32768                 V0 ← V0
2C8-2C9 0712-0713 ▀        8000 32768                 V0 ← V0
2CA-2CB 0714-0715 ▀        8000 32768                 V0 ← V0
2CC-2CD 0716-0717 ▀        8000 32768                 V0 ← V0
2CE-2CF 0718-0719  ▀ ▀     5000 20480                 Skip next if V0 = V0
2D0-2D1 0720-0721  ▀▀      6000 24576       key turns V0 ← 000
2D2-2D3 0722-0723 ▄▄▄ ▄▄▄  00EE 00238                 Return

The fill in routine nicely multiplies each register by five, adds a constant to each, and then draws a square. This takes advantage of the CHIP-8 display model using XOR, similarly to that field code:

2D4-2D5 0724-0725 █   ▄▄▄  808E 32910         fill in V0 ← V8 × 2; VF ← MSB
2D6-2D7 0726-0727 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
2D8-2D9 0728-0729 ▀   ▀▄   8804 34820                 V8 ← V8 + V0; VF ← overflow
2DA-2DB 0730-0731 █  ▄▄▄▄  809E 32926                 V0 ← V9 × 2; VF ← MSB
2DC-2DD 0732-0733 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
2DE-2DF 0734-0735 ▀   ▀▄ ▀ 8904 35076                 V9 ← V9 + V0; VF ← overflow
2E0-2E1 0736-0737 █ █ ▄ █▀ A3AA 41898                 I ← square
2E2-2E3 0738-0739  ▀▀█▀▄▄  7816 30742                 V8 ← V8 + 022
2E4-2E5 0740-0741  ▀▀██  ▀ 7918 31000                 V9 ← V9 + 024
2E6-2E7 0742-0743 █▀ ▀▀▄ █ D985 55685                 Draw 08×05 at V9,V8; VF ← XOR
2E8-2E9 0744-0745 ▄▄▄ ▄▄▄  00EE 00238                 Return

The rows routine was clearly written without any concern for size efficiency:

2EA-2EB 0746-0747  ▀▀ ▀▄ ▄ 6805 26629            rows V8 ← 005
2EC-2ED 0748-0749  ▀▀ ▀  ▀ 6900 26880                 V9 ← 000
2EE-2EF 0750-0751  ▀▀ █▄█▄ 6A0F 27151                 VA ← 015
2F0-2F1 0752-0753  ▀▀▄▀▄█▀ 6B16 27414                 VB ← 022
2F2-2F3 0754-0755  ▄▀▄ ▄█▀ 2356 09046                 Call display
2F4-2F5 0756-0757 ▀  ▄     8010 32784                 V0 ← V1
2F6-2F7 0758-0759  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
2F8-2F9 0760-0761  ▄▀▄ ▄█▀ 2356 09046                 Call display
2FA-2FB 0762-0763 ▀ ▄      8020 32800                 V0 ← V2
2FC-2FD 0764-0765  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
2FE-2FF 0766-0767  ▄▀▄ ▄█▀ 2356 09046                 Call display
300-301 0768-0769 ▀ ▄▄     8030 32816                 V0 ← V3
302-303 0770-0771  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
304-305 0772-0773  ▄▀▄ ▄█▀ 2356 09046                 Call display
306-307 0774-0775 ▀▄       8040 32832                 V0 ← V4
308-309 0776-0777  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
30A-30B 0778-0779  ▄▀▄ ▄█▀ 2356 09046                 Call display
30C-30D 0780-0781 ▀▄ ▄     8050 32848                 V0 ← V5
30E-30F 0782-0783  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
310-311 0784-0785  ▄▀▄ ▄█▀ 2356 09046                 Call display
312-313 0786-0787 ▀▄▄      8060 32864                 V0 ← V6
314-315 0788-0789  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
316-317 0790-0791  ▄▀▄ ▄█▀ 2356 09046                 Call display
318-319 0792-0793 ▀▄▄▄     8070 32880                 V0 ← V7
31A-31B 0794-0795  ▀▀▀▀▄▀█ 7B05 31493                 VB ← VB + 005
31C-31D 0796-0797  ▄▀▄ ▄█▀ 2356 09046                 Call display
31E-31F 0798-0799 ▄▄▄ ▄▄▄  00EE 00238                 Return

The columns routine is very similar to the rows routine directly preceding it:

320-321 0800-0801  ▀▀ ▀    6800 26624         columns V8 ← 000
322-323 0802-0803  ▀▀ ▀▄ █ 6905 26885                 V9 ← 005
324-325 0804-0805  ▀▀▄█ ▀▄ 6A19 27161                 VA ← 025
326-327 0806-0807  ▀▀ █▄▀▀ 6B0C 27404                 VB ← 012
328-329 0808-0809  ▄▀▄ ▄█▀ 2356 09046                 Call display
32A-32B 0810-0811 ▀  ▄     8010 32784                 V0 ← V1
32C-32D 0812-0813  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
32E-32F 0814-0815  ▄▀▄ ▄█▀ 2356 09046                 Call display
330-331 0816-0817 ▀ ▄      8020 32800                 V0 ← V2
332-333 0818-0819  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
334-335 0820-0821  ▄▀▄ ▄█▀ 2356 09046                 Call display
336-337 0822-0823 ▀ ▄▄     8030 32816                 V0 ← V3
338-339 0824-0825  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
33A-33B 0826-0827  ▄▀▄ ▄█▀ 2356 09046                 Call display
33C-33D 0828-0829 ▀▄       8040 32832                 V0 ← V4
33E-33F 0830-0831  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
340-341 0832-0833  ▄▀▄ ▄█▀ 2356 09046                 Call display
342-343 0834-0835 ▀▄ ▄     8050 32848                 V0 ← V5
344-345 0836-0837  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
346-347 0838-0839  ▄▀▄ ▄█▀ 2356 09046                 Call display
348-349 0840-0841 ▀▄▄      8060 32864                 V0 ← V6
34A-34B 0842-0843  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
34C-34D 0844-0845  ▄▀▄ ▄█▀ 2356 09046                 Call display
34E-34F 0846-0847 ▀▄▄▄     8070 32880                 V0 ← V7
350-351 0848-0849  ▀▀▀▀▄▀▄ 7A05 31237                 VA ← VA + 005
352-353 0850-0851  ▄▀▄ ▄█▀ 2356 09046                 Call display
354-355 0852-0853 ▄▄▄ ▄▄▄  00EE 00238                 Return

The display routine calls decode and draws the two results as numbers. To make the code smaller, it accepts parameters which control how the two are drawn relative to each other. It then reverses the changes to make calling this code simpler. A better design would more tightly couple both of these:

356-357 0854-0855  ▄█ ▄ █▀ 236A 09066         display Call decode
358-359 0856-0857 ▀▀█▀█▀ ▄ FC29 64553                 I ← digit sprite of VC
35A-35B 0858-0859 █▀▄█▀▄▀▄ DAB5 55989                 Draw 08×05 at VA,VB; VF ← XOR
35C-35D 0860-0861 █   ▀▄▀  8A84 35460                 VA ← VA + V8; VF ← overflow
35E-35F 0862-0863 █  ▄▀▄▀▀ 8B94 35732                 VB ← VB + V9; VF ← overflow
360-361 0864-0865 ▀▀█▀█▀ █ FD29 64809                 I ← digit sprite of VD
362-363 0866-0867 █▀▄█▀▄▀▄ DAB5 55989                 Draw 08×05 at VA,VB; VF ← XOR
364-365 0868-0869 █   ▀▄▀▄ 8A85 35461                 VA ← VA − V8; VF ← borrow
366-367 0870-0871 █  ▄▀▄▀█ 8B95 35733                 VB ← VB − V9; VF ← borrow
368-369 0872-0873 ▄▄▄ ▄▄▄  00EE 00238                 Return

The decode routine only returns correct results when the puzzle segment has but two objects, meaning each row or column of a puzzle must contain only two bodies as a restriction of this implementation. When that segment be empty, decode returns; otherwise, it's shifted and a count incremented when its value be one; when zero, the count is either left untouched when zero itself or when the other count be not zero, or the current count is transferred to the other count and reset before decode resumes:

36A-36B 0874-0875  ▀▀ ▀▀   6C00 27648          decode VC ← 000
36C-36D 0876-0877  ▀▀ ▀▀ ▀ 6D00 27904                 VD ← 000
36E-36F 0878-0879  ▀       4000 16384           check Skip next if V0 <> 000
370-371 0880-0881 ▄▄▄ ▄▄▄  00EE 00238                 Return
372-373 0882-0883 ▀   ▄▄▄  800E 32782                 V0 ← V0 × 2; VF ← MSB
374-375 0884-0885   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
376-377 0886-0887  ▀▀▀▀▀ █ 7D01 32001                 VD ← VD + 001
378-379 0888-0889   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
37A-37B 0890-0891  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
37C-37D 0892-0893  ▀  ▀▀ ▀ 4D00 19712                 Skip next if VD <> 000
37E-37F 0894-0895  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
380-381 0896-0897   ▀▀▀▀   3C00 15360                 Skip next if VC = 000
382-383 0898-0899  ▄▄▀▄▄█▀ 136E 04974                 Jump to check
384-385 0900-0901 █▄ ▄▀▀   8CD0 36048                 VC ← VD
386-387 0902-0903  ▀▀ ▀▀ ▀ 6D00 27904                 VD ← 000
388-389 0904-0905  ▄▄▀▄▄█▀ 136E 04974                 Jump to check

I'm particularly pleased with the compare routine, which I'd planned long before writing any code to be constant time and so avoid the player being able to derive that secret puzzle value. Using every register to hold both fields, it XOR compares them, and then collapses these into a result using OR:

38A-38B 0906-0907 █     ▄▄ 8083 32899         compare V0 ← V0 XOR V8
38C-38D 0908-0909 █  ▄  ▄█ 8193 33171                 V1 ← V1 XOR V9
38E-38F 0910-0911 █ ▄   █▄ 82A3 33443                 V2 ← V2 XOR VA
390-391 0912-0913 █ ▄▄  ██ 83B3 33715                 V3 ← V3 XOR VB
392-393 0914-0915 █▄   ▀▄▄ 84C3 33987                 V4 ← V4 XOR VC
394-395 0916-0917 █▄ ▄ ▀▄█ 85D3 34259                 V5 ← V5 XOR VD
396-397 0918-0919 █▄▄  ▀█▄ 86E3 34531                 V6 ← V6 XOR VE
398-399 0920-0921 █▄▄▄ ▀██ 87F3 34803                 V7 ← V7 XOR VF
39A-39B 0922-0923 ▀  ▄   ▄ 8011 32785                 V0 ← V0 OR V1
39C-39D 0924-0925 ▀ ▄    ▄ 8021 32801                 V0 ← V0 OR V2
39E-39F 0926-0927 ▀ ▄▄   ▄ 8031 32817                 V0 ← V0 OR V3
3A0-3A1 0928-0929 ▀▄     ▄ 8041 32833                 V0 ← V0 OR V4
3A2-3A3 0930-0931 ▀▄ ▄   ▄ 8051 32849                 V0 ← V0 OR V5
3A4-3A5 0932-0933 ▀▄▄    ▄ 8061 32865                 V0 ← V0 OR V6
3A6-3A7 0934-0935 ▀▄▄▄   ▄ 8071 32881                 V0 ← V0 OR V7
3A8-3A9 0936-0937 ▄▄▄ ▄▄▄  00EE 00238                 Return

The game ends with the only explicit graphic, the square, and the labelled areas:

3AA     0938      █████      F8   248          square 
3AB     0939      █████      F8   248                 
3AC     0940      █████      F8   248                 
3AD     0941      █████      F8   248                 
3AE     0942      █████      F8   248                 
3AF     0943                 00   000    primary work 
3B0-3B1 0944-0945          0000 00000                 
3B2-3B3 0946-0947          0000 00000                 
3B4-3B5 0948-0949          0000 00000                 
3B6-3B7 0950-0951          0000 00000! secondary work 
3B8-3B9 0952-0953          0000 00000                 
3BA-3BB 0954-0955          0000 00000                 
3BC-3BD 0956-0957          0000 00000                 
3BE     0958                 00   000                 
3BF     0959                 00   000         puzzles 

This game was designed to have its puzzles processed and appended to its end separately.