A Documenting of mine Asphyxiation CHIP-8 Game This is documentation for the Asphyxiation game I've written, to later be improved in the Octo Jam 7 event. This is also a partial reimplementation of the Atari VCS game ``Entombed'', namely regarding its maze generation with a non-deterministic cellular automaton; follows is the program in mine MMC: 200-201 0512-0513 ▄▄▄▄▄▄▄▄ 00FF 00255 Enable extended mode 202-203 0514-0515 █▄█▄ ▄█▄ A2F7 41719 I ← from 204-205 0516-0517 ▀██▀▀█▀█ FF65 65381 Load V0→VF; I ← I + 16 206-207 0518-0519 ▀ █ ▄▄█ A22E 41518 I ← player 208-209 0520-0521 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR 20A-20B 0522-0523 ▀ ▀ ▄ ▀▀ A308 41736 maze I ← stage 20C-20D 0524-0525 ▀▀▀███▄▀ FD1E 64798 I ← I + VD 20E-20F 0526-0527 ▀██▀ ▄▀█ F365 62309 Load V0→V3; I ← I + 04 210-211 0528-0529 ▀▄ ▄ ▄ 8052 32850 V0 ← V0 AND V5 212-213 0530-0531 ▀▄ ▄ ▄▀ 8152 33106 V1 ← V1 AND V5 214-215 0532-0533 ▀▄ ▄ █ 8252 33362 V2 ← V2 AND V5 216-217 0534-0535 ▀▄ ▄ █▀ 8352 33618 V3 ← V3 AND V5 218-219 0536-0537 ▀ ▄██▀ 870E 34574 V7 ← V0 × 2; VF ← MSB 21A-21B 0538-0539 ▀ ▄ ▀▀█ 8711 34577 V7 ← V7 OR V1 21C-21D 0540-0541 █▄▄ █▄▄ 88EE 35054 V8 ← VE × 2; VF ← MSB 21E-21F 0542-0543 ▀ ▄ ▀ ▄ 8821 34849 V8 ← V8 OR V2 220-221 0544-0545 █ █▄▄ 888E 34958 V8 ← V8 × 2; VF ← MSB 222-223 0546-0547 ▀ ▄▄▀ ▄ 8831 34865 V8 ← V8 OR V3 224-225 0548-0549 ▀ ▄ ▀▀▀ 8E20 36384 VE ← V2 226-227 0550-0551 █▄█▄ ▄▀ A2F4 41716 I ← random 228-229 0552-0553 ▀▀▀█▄██▀ F71E 63262 I ← I + V7 22A-22B 0554-0555 ▀██▀ ▄ ▄ F065 61541 Load V0→V0; I ← I + 01 22C-22D 0556-0557 ▀ ▀ 8100 33024 V1 ← V0 22E-22F 0558-0559 █ 8080 32896 player V0 ← V8 230-231 0560-0561 ▄▄▀▄▄ █ 22DA 08922 Call shift 232-233 0562-0563 ▀▀ ▀ █ C901 51457 V9 ← ??? AND 001 234-235 0564-0565 ▀▀▀▀▀▀ 3F00 16128 Skip next if VF = 000 236-237 0566-0567 ▄ ▀ ▄█ 1246 04678 Jump to use 238-239 0568-0569 █▄█▄▄ ▀ A2F8 41720 I ← drunk 23A-23B 0570-0571 ▀▀▀█▄██▀ F71E 63262 I ← I + V7 23C-23D 0572-0573 ▀██▀ ▄ ▄ F065 61541 Load V0→V0; I ← I + 01 23E-23F 0574-0575 ▀ ▀ 8100 33024 V1 ← V0 240-241 0576-0577 █ 8080 32896 V0 ← V8 242-243 0578-0579 ▄▄▀▄▄ █ 22DA 08922 Call shift 244-245 0580-0581 █▄▄▄▀ ▀ 89F0 35312 V9 ← VF 246-247 0582-0583 ▀▀▀ ▀ 3900 14592 use Skip next if V9 = 000 248-249 0584-0585 ▄██▄█▄▄█ 69FF 27135 V9 ← 255 24A-24B 0586-0587 ▀ ▀ ▄ ▀▀ A308 41736 I ← stage 24C-24D 0588-0589 ▀▀▀███▄▀ FD1E 64798 I ← I + VD 24E-24F 0590-0591 ▀██▀ ▄ █ F165 61797 Load V0→V1; I ← I + 02 250-251 0592-0593 █ ▄ 8090 32912 V0 ← V9 252-253 0594-0595 ▀█▀█ ▄ ▄ F055 61525 Save V0→V0; I ← I + 01 254-255 0596-0597 ▀▀▀▀▀ █ 7D01 32001 VD ← VD + 001 256-257 0598-0599 ▀▀█▀ ▀ 3D08 15624 Skip next if VD = 008 258-259 0600-0601 ▀▄ █ 120A 04618 Jump to maze 25A-25B 0602-0603 ▀▀ ▀▀▄ 6601 26113 V6 ← 001 25C-25D 0604-0605 ▀▀ ▀▀ ▀ 6D00 27904 curtain opens VD ← 000 25E-25F 0606-0607 ██▄█▀ 6C78 27768 VC ← 120 260-261 0608-0609 ▀ ▀ ▄ █▀ A30A 41738 I ← set 262-263 0610-0611 ▄▄ ▄ 00C1 00193 Scroll ↓ by 01 264-265 0612-0613 ██▄█▀▀ █ DDF1 56817 show time Draw 08×01 at VD,VF; VF ← XOR 266-267 0614-0615 ██▄█▀▀ ▄ DCF1 56561 Draw 08×01 at VC,VF; VF ← XOR 268-269 0616-0617 ▀██▀ ▄ ▄ F065 61541 Load V0→V0; I ← I + 01 26A-26B 0618-0619 ▀▀▀█▀ ▀ 7D08 32008 VD ← VD + 008 26C-26D 0620-0621 ▄████▀ 7CF8 31992 VC ← VC + 248 26E-26F 0622-0623 ▄▀▀▀▀ ▀ 3D40 15680 Skip next if VD = 064 270-271 0624-0625 ▄▄▀ ▄▀ 1264 04708 Jump to show time 272-273 0626-0627 ▀▀▀▀ ▀█ 7B01 31489 VB ← VB + 001 274-275 0628-0629 ▀▀ ▄▄ 600C 24588 V0 ← 012 276-277 0630-0631 ▀▀▀█ ▄ ▄ F015 61461 delay ← V0 278-279 0632-0633 █ ▀ ▀▀ 4B40 19264 move Skip next if VB <> 064 27A-27B 0634-0635 ▄▄█▄ █ 127A 04730 self Jump to self 27C-27D 0636-0637 █ ▄ 80A0 32928 V0 ← VA 27E-27F 0638-0639 █ ▄▄ ▀ 81B0 33200 V1 ← VB 280-281 0640-0641 ▀ █ ▄▄█ A22E 41518 I ← player 282-283 0642-0643 ▀▀ ▀▀▄▀ 6D02 27906 VD ← 002 284-285 0644-0645 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 286-287 0646-0647 ▀▀▀▀ ▀█ 7B01 31489 VB ← VB + 001 288-289 0648-0649 █ ▀ ▀▀ 4B40 19264 Skip next if VB <> 064 28A-28B 0650-0651 ▀█▄█▄██ 6B3F 27455 VB ← 063 28C-28D 0652-0653 ▀▀ █▀ ▀ 6D08 27912 VD ← 008 28E-28F 0654-0655 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 290-291 0656-0657 ▄████▄██ 7BFF 31743 VB ← VB + 255 292-293 0658-0659 ▄█▄▄█▄██ 4BFF 19455 Skip next if VB <> 255 294-295 0660-0661 ▀▀ ▀ ▀▀ 6B00 27392 VB ← 000 296-297 0662-0663 ▀▀ ▀█ ▀ 6D04 27908 VD ← 004 298-299 0664-0665 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 29A-29B 0666-0667 ▄████▄█▄ 7AFF 31487 VA ← VA + 255 29C-29D 0668-0669 ▀▀ ▀█▄▀ 6D06 27910 VD ← 006 29E-29F 0670-0671 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 2A0-2A1 0672-0673 ▀▀▀▀ ▀▄ 7A01 31233 VA ← VA + 001 2A2-2A3 0674-0675 ██▄██▄█ 6D7F 28031 VD ← 127 2A4-2A5 0676-0677 █▄ ▄▀ █ 8AD2 35538 VA ← VA AND VD 2A6-2A7 0678-0679 ▀▀ ▀▀ ▀ 6D00 27904 VD ← 000 2A8-2A9 0680-0681 ▀▀ █ ▄ D011 53265 Draw 08×01 at V0,V1; VF ← XOR 2AA-2AB 0682-0683 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR 2AC-2AD 0684-0685 ▀ ▀▀▀▀ 4F00 20224 Skip next if VF <> 000 2AE-2AF 0686-0687 ▄ ▄█▄ ▀ 12B8 04792 Jump to bounded 2B0-2B1 0688-0689 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR 2B2-2B3 0690-0691 ▀ ▀ ▀ 8A00 35328 VA ← V0 2B4-2B5 0692-0693 ▀ ▄▀ ▀▀ 8B10 35600 VB ← V1 2B6-2B7 0694-0695 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR 2B8-2B9 0696-0697 █▀▀▄██▄▀ ED9E 60830 bounded Skip next if VD = key 2BA-2BB 0698-0699 ▄▄ ▀ ▄▀ 12C4 04804 Jump to cycle 2BC-2BD 0700-0701 █▄█▄ ▀ A2F0 41712 I ← break 2BE-2BF 0702-0703 ▄████▄▀▀ 7BFC 31740 VB ← VB + 252 2C0-2C1 0704-0705 █▀▄█▀▄▀ DAB4 55988 Draw 08×04 at VA,VB; VF ← XOR 2C2-2C3 0706-0707 ▀▀▀▀▄▀▀ 7B04 31492 VB ← VB + 004 2C4-2C5 0708-0709 ▀▀▀▀▀███ FF07 65287 cycle VF ← delay 2C6-2C7 0710-0711 ▀▀▀▀▀▀ 3F00 16128 Skip next if VF = 000 2C8-2C9 0712-0713 ▄▄█▄ ▀ 1278 04728 Jump to move 2CA-2CB 0714-0715 ▀▄▄ ▄██ 866E 34414 V6 ← V6 × 2; VF ← MSB 2CC-2CD 0716-0717 ▄▀█ █▀█▀ 6FAA 28586 VF ← 170 2CE-2CF 0718-0719 ▀ ▀▀ 4600 17920 Skip next if V6 <> 000 2D0-2D1 0720-0721 ▀▄ █ 120A 04618 Jump to maze 2D2-2D3 0722-0723 ▀▄▄ ▀▀█▀ 8F62 36706 VF ← VF AND V6 2D4-2D5 0724-0725 ▀▀▀▀▀▀ 3F00 16128 Skip next if VF = 000 2D6-2D7 0726-0727 ▄▄█▄ ▀ 1278 04728 Jump to move 2D8-2D9 0728-0729 ▄ █▄▄▀ 125C 04700 Jump to curtain opens 2DA-2DB 0730-0731 ▀ ▄▄▄ 800E 32782 shift V0 ← V0 × 2; VF ← MSB 2DC-2DD 0732-0733 █▄▀█▄▄█ B2DE 45790 Jump to V0 + next 2DE-2DF 0734-0735 ▀ ▄ ▄▄▀ 8116 33046 next V1 ← V1 ÷ 2; VF ← LSB 2E0-2E1 0736-0737 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E2-2E3 0738-0739 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E4-2E5 0740-0741 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E6-2E7 0742-0743 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E8-2E9 0744-0745 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2EA-2EB 0746-0747 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2EC-2ED 0748-0749 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2EE-2EF 0750-0751 ▄▄▄ ▄▄▄ 00EE 00238 Return 2F0-2F1 0752-0753 ████ F0F0 61680 break 2F2-2F3 0754-0755 ████ F0F0 61680 2F4-2F5 0756-0757 ▀▄ ▀▀ 1308 04872 random 2F6-2F7 0758-0759 ▄ █▄ 1098 04248! from 2F8-2F9 0760-0761 ███▄ E0F0 57584 drunk 2FA-2FB 0762-0763 ▀▀█ E020 57376 2FC 0764 █ 01 001 2FD 0765 00 000 2FE 0766 00 000 2FF 0767 00 000 300 0768 00 000 301 0769 ██████ 3F 063 302 0770 █████ 1F 031 303 0771 00 000 304-305 0772-0773 0000 00000 306-307 0774-0775 0000 00000 308-309 0776-0777 0000 00000 stage 30A-30B 0778-0779 0000 00000 set The register usage is as follows: V0 Hold a cell for the automaton; advance I, at times for saving; manipulate the delay register; hold the prior horizontal coordinate of the player; hold the argument to a subroutine. V1 Hold a cell for the automaton; advance I, at times for saving; hold the prior vertical coordinate of the player; hold the argument to a subroutine. V2 Hold a cell for the automaton. V3 Hold a cell for the automaton. V4 Unused. V5 Hold a mask. V6 Hold a magnitude as a linear counter. V7 Hold a generated index for the maze generation. V8 Hold a generated index for the maze generation. V9 Hold the current cell value being generated. VA Hold the horizontal coordinate of the player. VB Hold the vertical coordinate of the player. VC Hold the horizontal coordinate of part of the maze drawing. VD Hold an index for the maze generation; hold the horizontal coordinate of part of the maze drawing; hold miscellaneous constants. VE Hold a prior cell state for the automaton. VF Hold the result of a subroutine; hold the vertical coordinate of part of the maze drawing; collision; manipulate the delay register; hold a mask. These registers were chosen haphazardly, the lower due to circumstance with FX55 and FX65, and don't warrant more detailed explanations. This program was written purely to implement the algorithm from the paper detailing ``Entombed'', as an exercise, and a candidate for improvement in the Octo Jam 7. I believe this is that largest game I've written so far, yet still not so featured, and I'll be able to write a much better version; in particular, I've been able to avoid register pressure until this. This game begins by enabling a larger screen resolution and the scrolling instructions, initializing registers, and then draws the player at the starting coordinate, which is roughly the screen center: 200-201 0512-0513 ▄▄▄▄▄▄▄▄ 00FF 00255 Enable extended mode 202-203 0514-0515 █▄█▄ ▄█▄ A2F7 41719 I ← from 204-205 0516-0517 ▀██▀▀█▀█ FF65 65381 Load V0→VF; I ← I + 16 206-207 0518-0519 ▀ █ ▄▄█ A22E 41518 I ← player 208-209 0520-0521 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR The maze generation algorithm is detailed in the linked paper, being mere non-deterministic and one- dimensional cellular automaton. That algorithm uses five bits as a table index, the prior two cells generated, and the remaining three being left, center, and right from the current position, from the last iteration; sans the former left, the algorithm is merely in-place, and register fourteen stores this particular prior cell. The stage is offset by two from the true beginning, to accomodate those two prior values needed. Register five merely holds a one, to mask the empty or entirely full value of the registers; there's a better way to implementing this algorithm, which will be left for later. Registers seven and eight hold indices into bit tables, with seven holding an octet index from zero- to-three, and eight holding a bit index from zero-to-seven; register fourteen holds the old value of the middle cell, that former left, and this is easily set from the current state before overwriting: 20A-20B 0522-0523 ▀ ▀ ▄ ▀▀ A308 41736 maze I ← stage 20C-20D 0524-0525 ▀▀▀███▄▀ FD1E 64798 I ← I + VD 20E-20F 0526-0527 ▀██▀ ▄▀█ F365 62309 Load V0→V3; I ← I + 04 210-211 0528-0529 ▀▄ ▄ ▄ 8052 32850 V0 ← V0 AND V5 212-213 0530-0531 ▀▄ ▄ ▄▀ 8152 33106 V1 ← V1 AND V5 214-215 0532-0533 ▀▄ ▄ █ 8252 33362 V2 ← V2 AND V5 216-217 0534-0535 ▀▄ ▄ █▀ 8352 33618 V3 ← V3 AND V5 218-219 0536-0537 ▀ ▄██▀ 870E 34574 V7 ← V0 × 2; VF ← MSB 21A-21B 0538-0539 ▀ ▄ ▀▀█ 8711 34577 V7 ← V7 OR V1 21C-21D 0540-0541 █▄▄ █▄▄ 88EE 35054 V8 ← VE × 2; VF ← MSB 21E-21F 0542-0543 ▀ ▄ ▀ ▄ 8821 34849 V8 ← V8 OR V2 220-221 0544-0545 █ █▄▄ 888E 34958 V8 ← V8 × 2; VF ← MSB 222-223 0546-0547 ▀ ▄▄▀ ▄ 8831 34865 V8 ← V8 OR V3 224-225 0548-0549 ▀ ▄ ▀▀▀ 8E20 36384 VE ← V2 The table of the algorithm holds trits, indicating a live, dead, or random cell; this is implemented as two bit tables, with random being indexed first. Bit indexing is achieved by that shift routine. Register nine is given a random bit, and the cell value generation finishes if the table bit is one: 226-227 0550-0551 █▄█▄ ▄▀ A2F4 41716 I ← random 228-229 0552-0553 ▀▀▀█▄██▀ F71E 63262 I ← I + V7 22A-22B 0554-0555 ▀██▀ ▄ ▄ F065 61541 Load V0→V0; I ← I + 01 22C-22D 0556-0557 ▀ ▀ 8100 33024 V1 ← V0 22E-22F 0558-0559 █ 8080 32896 player V0 ← V8 230-231 0560-0561 ▄▄▀▄▄ █ 22DA 08922 Call shift 232-233 0562-0563 ▀▀ ▀ █ C901 51457 V9 ← ??? AND 001 234-235 0564-0565 ▀▀▀▀▀▀ 3F00 16128 Skip next if VF = 000 236-237 0566-0567 ▄ ▀ ▄█ 1246 04678 Jump to use If zero, the second table is referenced, which was apparently created whilst the original author was drunk. Afterwards, there's no futher work to do; this cell generation could also be more efficient: 238-239 0568-0569 █▄█▄▄ ▀ A2F8 41720 I ← drunk 23A-23B 0570-0571 ▀▀▀█▄██▀ F71E 63262 I ← I + V7 23C-23D 0572-0573 ▀██▀ ▄ ▄ F065 61541 Load V0→V0; I ← I + 01 23E-23F 0574-0575 ▀ ▀ 8100 33024 V1 ← V0 240-241 0576-0577 █ 8080 32896 V0 ← V8 242-243 0578-0579 ▄▄▀▄▄ █ 22DA 08922 Call shift 244-245 0580-0581 █▄▄▄▀ ▀ 89F0 35312 V9 ← VF The value in register nine is inefficiently transformed to either empty or entirely filled, and then is deposited into the stage, nicely using the implicit I movement as an indexing operation, as those first two registers can be trashed without issue; the maze generation routine runs eight iterations: 246-247 0582-0583 ▀▀▀ ▀ 3900 14592 use Skip next if V9 = 000 248-249 0584-0585 ▄██▄█▄▄█ 69FF 27135 V9 ← 255 24A-24B 0586-0587 ▀ ▀ ▄ ▀▀ A308 41736 I ← stage 24C-24D 0588-0589 ▀▀▀███▄▀ FD1E 64798 I ← I + VD 24E-24F 0590-0591 ▀██▀ ▄ █ F165 61797 Load V0→V1; I ← I + 02 250-251 0592-0593 █ ▄ 8090 32912 V0 ← V9 252-253 0594-0595 ▀█▀█ ▄ ▄ F055 61525 Save V0→V0; I ← I + 01 254-255 0596-0597 ▀▀▀▀▀ █ 7D01 32001 VD ← VD + 001 256-257 0598-0599 ▀▀█▀ ▀ 3D08 15624 Skip next if VD = 008 258-259 0600-0601 ▀▄ █ 120A 04618 Jump to maze The symmetrical new row is drawn by scrolling down and drawing the cell at both ends simultaneously. Originally, I'd planned to have two loops progressing through the cells forwards and backwards using only one register for horizontal coordinates, but I can only be stepped conveniently in the forwards direction, and so the two loops were nicely combined; amusingly, an earlier version of this loop was subtly incorrect, pointing to stage instead, and so having naught but blank on the outer maze edges: 25A-25B 0602-0603 ▀▀ ▀▀▄ 6601 26113 V6 ← 001 25C-25D 0604-0605 ▀▀ ▀▀ ▀ 6D00 27904 curtain opens VD ← 000 25E-25F 0606-0607 ██▄█▀ 6C78 27768 VC ← 120 260-261 0608-0609 ▀ ▀ ▄ █▀ A30A 41738 I ← set 262-263 0610-0611 ▄▄ ▄ 00C1 00193 Scroll ↓ by 01 264-265 0612-0613 ██▄█▀▀ █ DDF1 56817 show time Draw 08×01 at VD,VF; VF ← XOR 266-267 0614-0615 ██▄█▀▀ ▄ DCF1 56561 Draw 08×01 at VC,VF; VF ← XOR 268-269 0616-0617 ▀██▀ ▄ ▄ F065 61541 Load V0→V0; I ← I + 01 26A-26B 0618-0619 ▀▀▀█▀ ▀ 7D08 32008 VD ← VD + 008 26C-26D 0620-0621 ▄████▀ 7CF8 31992 VC ← VC + 248 26E-26F 0622-0623 ▄▀▀▀▀ ▀ 3D40 15680 Skip next if VD = 064 270-271 0624-0625 ▄▄▀ ▄▀ 1264 04708 Jump to show time This is the section for player movement; the player's vertical position is decremented to accomodate scrolling, the delay is started, and the player falling off the bottom edge of the screen is a loss. It's easiest to save the old player coordinates and restore them upon collision with a maze segment. As I faced register pressure, key codes are loaded into register thirteen immediately before they're needed. Now with a clearer idea of the program, having two register banks to use with FX65 would be better. The bounds of the screen are enforced by masking for wrapping as with the horizontal edges, or saturation arithmetic as for that upper bound of the screen. These could also be more efficient: 272-273 0626-0627 ▀▀▀▀ ▀█ 7B01 31489 VB ← VB + 001 274-275 0628-0629 ▀▀ ▄▄ 600C 24588 V0 ← 012 276-277 0630-0631 ▀▀▀█ ▄ ▄ F015 61461 delay ← V0 278-279 0632-0633 █ ▀ ▀▀ 4B40 19264 move Skip next if VB <> 064 27A-27B 0634-0635 ▄▄█▄ █ 127A 04730 self Jump to self 27C-27D 0636-0637 █ ▄ 80A0 32928 V0 ← VA 27E-27F 0638-0639 █ ▄▄ ▀ 81B0 33200 V1 ← VB 280-281 0640-0641 ▀ █ ▄▄█ A22E 41518 I ← player 282-283 0642-0643 ▀▀ ▀▀▄▀ 6D02 27906 VD ← 002 284-285 0644-0645 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 286-287 0646-0647 ▀▀▀▀ ▀█ 7B01 31489 VB ← VB + 001 288-289 0648-0649 █ ▀ ▀▀ 4B40 19264 Skip next if VB <> 064 28A-28B 0650-0651 ▀█▄█▄██ 6B3F 27455 VB ← 063 28C-28D 0652-0653 ▀▀ █▀ ▀ 6D08 27912 VD ← 008 28E-28F 0654-0655 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 290-291 0656-0657 ▄████▄██ 7BFF 31743 VB ← VB + 255 292-293 0658-0659 ▄█▄▄█▄██ 4BFF 19455 Skip next if VB <> 255 294-295 0660-0661 ▀▀ ▀ ▀▀ 6B00 27392 VB ← 000 296-297 0662-0663 ▀▀ ▀█ ▀ 6D04 27908 VD ← 004 298-299 0664-0665 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 29A-29B 0666-0667 ▄████▄█▄ 7AFF 31487 VA ← VA + 255 29C-29D 0668-0669 ▀▀ ▀█▄▀ 6D06 27910 VD ← 006 29E-29F 0670-0671 █▀█ ▀▀ █ EDA1 60833 Skip next if VD <> key 2A0-2A1 0672-0673 ▀▀▀▀ ▀▄ 7A01 31233 VA ← VA + 001 2A2-2A3 0674-0675 ██▄██▄█ 6D7F 28031 VD ← 127 2A4-2A5 0676-0677 █▄ ▄▀ █ 8AD2 35538 VA ← VA AND VD 2A6-2A7 0678-0679 ▀▀ ▀▀ ▀ 6D00 27904 VD ← 000 The player sprite is undrawn and drawn, to be drawn and its position reset if there's any collision: 2A8-2A9 0680-0681 ▀▀ █ ▄ D011 53265 Draw 08×01 at V0,V1; VF ← XOR 2AA-2AB 0682-0683 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR 2AC-2AD 0684-0685 ▀ ▀▀▀▀ 4F00 20224 Skip next if VF <> 000 2AE-2AF 0686-0687 ▄ ▄█▄ ▀ 12B8 04792 Jump to bounded 2B0-2B1 0688-0689 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR 2B2-2B3 0690-0691 ▀ ▀ ▀ 8A00 35328 VA ← V0 2B4-2B5 0692-0693 ▀ ▄▀ ▀▀ 8B10 35600 VB ← V1 2B6-2B7 0694-0695 █▀▄█▀ ▀▄ DAB1 55985 Draw 08×01 at VA,VB; VF ← XOR This implements the ``make break'' of that original game, which makes an unsolvable maze solvable by allowing it to be partially destroyed. There's currently no limit on them, and they can only be set in one direction. That original game used the background mirroring feature of the Atari VCS, and so breaking a segment of the maze had it mirrored; this game lacks the peculiarity. Anyone who resents the difficulty of breaking the maze accurately is advised to get better at the game; the coordinates are transformations of the player's; it's better to have the input routine set the offsets directly: 2B8-2B9 0696-0697 █▀▀▄██▄▀ ED9E 60830 bounded Skip next if VD = key 2BA-2BB 0698-0699 ▄▄ ▀ ▄▀ 12C4 04804 Jump to cycle 2BC-2BD 0700-0701 █▄█▄ ▀ A2F0 41712 I ← break 2BE-2BF 0702-0703 ▄████▄▀▀ 7BFC 31740 VB ← VB + 252 2C0-2C1 0704-0705 █▀▄█▀▄▀ DAB4 55988 Draw 08×04 at VA,VB; VF ← XOR 2C2-2C3 0706-0707 ▀▀▀▀▄▀▀ 7B04 31492 VB ← VB + 004 The delay is exhausted along with the key testing, which should ideally be capped to prevent varying player speeds with varying machine speeds, but isn't here. The game plays unevenly because the maze generation happens all-at-once every eight iterations; I was faced with an issue, since CHIP-8 lacks complex comparison instructions; I noticed I only needed a small counter, and that shifting provided a means to check greater-than or lesser-than with an AND mask; I later changed that mask to even the speed a tad, but the basic concept is nice. It changes a logarithmic notation to a linear notation: 2C4-2C5 0708-0709 ▀▀▀▀▀███ FF07 65287 cycle VF ← delay 2C6-2C7 0710-0711 ▀▀▀▀▀▀ 3F00 16128 Skip next if VF = 000 2C8-2C9 0712-0713 ▄▄█▄ ▀ 1278 04728 Jump to move 2CA-2CB 0714-0715 ▀▄▄ ▄██ 866E 34414 V6 ← V6 × 2; VF ← MSB 2CC-2CD 0716-0717 ▄▀█ █▀█▀ 6FAA 28586 VF ← 170 2CE-2CF 0718-0719 ▀ ▀▀ 4600 17920 Skip next if V6 <> 000 2D0-2D1 0720-0721 ▀▄ █ 120A 04618 Jump to maze 2D2-2D3 0722-0723 ▀▄▄ ▀▀█▀ 8F62 36706 VF ← VF AND V6 2D4-2D5 0724-0725 ▀▀▀▀▀▀ 3F00 16128 Skip next if VF = 000 2D6-2D7 0726-0727 ▄▄█▄ ▀ 1278 04728 Jump to move 2D8-2D9 0728-0729 ▄ █▄▄▀ 125C 04700 Jump to curtain opens This shift routine is a basic multiplier: zero holds the multiplier; one holds the multiplicand; and fifteen holds that bit result. This was made more complicated, due to the lack of an indirect call: 2DA-2DB 0730-0731 ▀ ▄▄▄ 800E 32782 shift V0 ← V0 × 2; VF ← MSB 2DC-2DD 0732-0733 █▄▀█▄▄█ B2DE 45790 Jump to V0 + next 2DE-2DF 0734-0735 ▀ ▄ ▄▄▀ 8116 33046 next V1 ← V1 ÷ 2; VF ← LSB 2E0-2E1 0736-0737 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E2-2E3 0738-0739 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E4-2E5 0740-0741 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E6-2E7 0742-0743 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2E8-2E9 0744-0745 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2EA-2EB 0746-0747 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2EC-2ED 0748-0749 ▀ ▄ ▄▄▀ 8116 33046 V1 ← V1 ÷ 2; VF ← LSB 2EE-2EF 0750-0751 ▄▄▄ ▄▄▄ 00EE 00238 Return The game ends with the ``make break'' sprite, those two bit tables, and the haphazard register bank: 2F0-2F1 0752-0753 ████ F0F0 61680 break 2F2-2F3 0754-0755 ████ F0F0 61680 2F4-2F5 0756-0757 ▀▄ ▀▀ 1308 04872 random 2F6-2F7 0758-0759 ▄ █▄ 1098 04248! from 2F8-2F9 0760-0761 ███▄ E0F0 57584 drunk 2FA-2FB 0762-0763 ▀▀█ E020 57376 2FC 0764 █ 01 001 2FD 0765 00 000 2FE 0766 00 000 2FF 0767 00 000 300 0768 00 000 301 0769 ██████ 3F 063 302 0770 █████ 1F 031 303 0771 00 000 304-305 0772-0773 0000 00000 306-307 0774-0775 0000 00000 308-309 0776-0777 0000 00000 stage 30A-30B 0778-0779 0000 00000 set I began work on this game well before October, so it won't be entered into the Octo Jam 7; I do plan to enter an improvement on the basic design along with code improvements and more features, however. .