A Documenting of my Nonogram CHIP-8 Game 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. .