A Documenting of my Rule 30 Improved CHIP-8 Program This is a documenting of the Rule 30, Improved, program I've written. If you've not read my article documenting the Rule 30 program, 2019-08-18, then I suggest you do so. This program was written for the Octo Jam VI event and is a rewrite and heavy improvement of the previous program. As with those other programs of mine, only the fully annotated view will be shown here and so follows is a view of the program when it is first loaded into the tool: 200-201 0512-0513 ÜÜÜÜÜÜÜÜ 00FF 00255 Enable extended mode 202-203 0514-0515 ÜÜÜ 00E0 00224 Clear the screen 204-205 0516-0517 Û Û ÛÛÛÛ AFAF 44975 I  4015 206-207 0518-0519 ßÛÛßßÛßÛ FF65 65381 Load V0VF; I  I + 16 208-209 0520-0521 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 20A-20B 0522-0523 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 20C-20D 0524-0525 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 20E-20F 0526-0527 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 210-211 0528-0529 ßß 6000 24576 V0  000 212-213 0530-0531 ßÛßÛ Ü Ü F055 61525 Save V0V0; I  I + 01 214-215 0532-0533 Û ßÜ ÜßÜ A295 41621 I  from 216-217 0534-0535 ßÛÛßßÛßÛ FF65 65381 Load V0VF; I  I + 16 218-219 0536-0537 ß Û Ü ß A228 41512 entry I  bar 21A-21B 0538-0539 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 21C-21D 0540-0541 ßßßßÜ Ü F00A 61450 key V0  key 21E-21F 0542-0543 ß Û Ü ß A228 41512 I  bar 220-221 0544-0545 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 222-223 0546-0547 ß ÜÜÜÜ 400F 16399 Skip next if V0 <> 015 224-225 0548-0549 Ü Û Üß 1254 04692 Jump to phase 226-227 0550-0551 ß Ü 4008 16392 Skip next if V0 <> 008 228-229 0552-0553 ßßßßßßÜ 7E01 32257 bar VE  VE + 001 22A-22B 0554-0555 ß Ü 4002 16386 Skip next if V0 <> 002 22C-22D 0556-0557 ÜÛÛÛÛÛÛÜ 7EFF 32511 VE  VE + 255 22E-22F 0558-0559 ß ÜßßÛ 8E12 36370 VE  VE AND V1 230-231 0560-0561 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 232-233 0562-0563 ßß Ü Ü 3005 12293 Skip next if V0 = 005 234-235 0564-0565 ÛÜÜß 121C 04636 Jump to key 236-237 0566-0567 Üß ÜÜÛ 224E 08782 Call index 238-239 0568-0569 ßÛÛß Ü Ü F065 61541 Load V0V0; I  I + 01 23A-23B 0570-0571 Üß ÜÜÛ 224E 08782 Call index 23C-23D 0572-0573 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 23E-23F 0574-0575 ß Ü ÜÜ 8023 32803 V0  V0 XOR V2 240-241 0576-0577 Üß Ü ß 2248 08776 Call save 242-243 0578-0579 Üß ÜÜÛ 224E 08782 Call index 244-245 0580-0581 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 246-247 0582-0583 ÛÜÜß 121C 04636 Jump to key 248-249 0584-0585 Üß ÜÜÛ 224E 08782 save Call index 24A-24B 0586-0587 ßÛßÛ Ü Ü F055 61525 Save V0V0; I  I + 01 24C-24D 0588-0589 ÜÜÜ ÜÜÜ 00EE 00238 Return 24E-24F 0590-0591 Û ÛÜÛÛÛÛ AFBF 44991 index I  4031 250-251 0592-0593 ßßßÛÛÛÛ FE1E 65054 I  I + VE 252-253 0594-0595 ÜÜÜ ÜÜÜ 00EE 00238 Return 254-255 0596-0597 ÛÜÜ ßß ß 8DE0 36320 phase VD  VE 256-257 0598-0599 ÜÜÜÜÜ ÜÜ 00FB 00251 scroll Scroll  by 04 258-259 0600-0601 ßßßÛßÛ Û FD15 64789 automata delay  VD 25A-25B 0602-0603 ßß ßß 6C00 27648 VC  000 25C-25D 0604-0605 ßß ßßß 6E00 28160 VE  000 25E-25F 0606-0607 ÜÛÛÛÜÜÛÜ 72FF 29439 V2  V2 + 255 260-261 0608-0609 ß ÜÜ Û 8232 33330 V2  V2 AND V3 262-263 0610-0611 Üß ÜÜÛ 224E 08782 prime Call index 264-265 0612-0613 ßÛÛß Ü Û F165 61797 Load V0V1; I  I + 02 266-267 0614-0615 ß ßßßß 8F00 36608 begin rule 30 VF  V0 268-269 0616-0617 ß Ü Ü 8011 32785 V0  V0 OR V1 26A-26B 0618-0619 ÛÜ ÜÜ 80C3 32963 V0  V0 XOR VC 26C-26D 0620-0621 ÛÜÜÜßß 8CF0 36080 end rule 30 VC  VF 26E-26F 0622-0623 Üß Ü ß 2248 08776 Call save 270-271 0624-0625 ßßßßßßÜ 7E01 32257 VE  VE + 001 272-273 0626-0627 Üßßßßß 3E40 15936 Skip next if VE = 064 274-275 0628-0629 ÜÜß Û 1262 04706 Jump to prime 276-277 0630-0631 ßß ßßß 6E00 28160 VE  000 278-279 0632-0633 Üß ÜÜÛ 224E 08782 draw Call index 27A-27B 0634-0635 ÛÛÜßÜÜÛÜ D2EF 53999 Draw 08x15 at V2,VE; VF  XOR 27C-27D 0636-0637 ßßßÛÛÛÜ 7E0F 32271 VE  VE + 015 27E-27F 0638-0639 ÛÛÛÛß 3E3C 15932 Skip next if VE = 060 280-281 0640-0641 ÜÜÛÜ ß 1278 04728 Jump to draw 282-283 0642-0643 Üß ÜÜÛ 224E 08782 Call index 284-285 0644-0645 ÛÛÜß Üß D2E4 53988 Draw 08x04 at V2,VE; VF  XOR 286-287 0646-0647 ßßßßßÛÛÛ FF07 65287 delay VF  delay 288-289 0648-0649 ÛßÛ ß Ü E4A1 58529 Skip next if V4 <> key 28A-28B 0650-0651 ß ß 1200 04608 Jump to 0512 28C-28D 0652-0653 ßßßßßß 3F00 16128 Skip next if VF = 000 28E-28F 0654-0655 Ü ß ÜÛ 1286 04742 Jump to delay 290-291 0656-0657 ßß ß 3200 12800 Skip next if V2 = 000 292-293 0658-0659 Ü ÛÜ ß 1258 04696 Jump to automata 294-295 0660-0661 Ü Û ÜÛ 1256 04694! from Jump to scroll 296 0662 ÛÛÛÛÛÛ 3F 063 297 0663 Û 80 128 298 0664 ÛÛ 03 003 299 0665 ÛÛÛ 0E 014 The register usage is as follows; this omits usage of all registers at the beginning of the program: V0 Set the right pattern boundary; store a key; cell manipulation. V1 Cell manipulation; hold a boundary. V2 Hold a constant for cell manipulation; horizontal positioning of most drawing. V3 Hold a boundary V4 Hold a key code. V5 Unused. V6 Unused. V7 Unused. V8 Unused. V9 Unused. VA Unused. VB A zero source for horizontal positioning of some drawing. VC Store a previous cell. VD Manipulating the delay register VE Vertical positioning of all drawing. VF Store a temporary result; manipulating the delay register. As I'm the author of this program, I will discuss the history of it to a point, as opposed to a more bare examination. This and the previous are the only Rule 30 programs in CHIP-8 I'm aware of. This program was written with concerns other than a minimal size, although it's still rather small; to be efficient in drawing, as the opportunity for this is rare; and to make modification of those pattern boundaries simple. The registers were chosen for the following reasons: V0 Ease of access. V1 Ease of access. V2 Ease of access. V3 Ease of access. V4 Ease of access. V5 Unused. V6 Unused. V7 Unused. V8 Unused. V9 Unused. VA Unused. VB Unimportance and distance from lower registers. VC Unimportance and distance from lower registers. VD Unimportance and distance from lower registers. VE Unimportance and distance from lower registers; sprite happenstance. VF Unimportance and distance from lower registers. This program begins by entering Super CHIP-8 mode, clearing the screen, overwriting those sixty-five final bytes of memory with zeroes by loading all registers with memory obtained directly beforehand, and then initializing all registers from the end of the program. Note that the 6000 instruction may be modified to affect the right boundary of the pattern space; note that this adds four bytes to the program's size, as that memory can safely remain untouched, otherwise: 200-201 0512-0513 ÜÜÜÜÜÜÜÜ 00FF 00255 Enable extended mode 202-203 0514-0515 ÜÜÜ 00E0 00224 Clear the screen 204-205 0516-0517 Û Û ÛÛÛÛ AFAF 44975 I  4015 206-207 0518-0519 ßÛÛßßÛßÛ FF65 65381 Load V0VF; I  I + 16 208-209 0520-0521 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 20A-20B 0522-0523 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 20C-20D 0524-0525 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 20E-20F 0526-0527 ßÛßÛßÛßÛ FF55 65365 Save V0VF; I  I + 16 210-211 0528-0529 ßß 6000 24576 V0  000 212-213 0530-0531 ßÛßÛ Ü Ü F055 61525 Save V0V0; I  I + 01 214-215 0532-0533 Û ßÜ ÜßÜ A295 41621 I  from 216-217 0534-0535 ßÛÛßßÛßÛ FF65 65381 Load V0VF; I  I + 16 The program displays the bar sprite at location 0,0; waits for a key; and afterwards erases the bar: 218-219 0536-0537 ß Û Ü ß A228 41512 entry I  bar 21A-21B 0538-0539 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 21C-21D 0540-0541 ßßßßÜ Ü F00A 61450 key V0  key 21E-21F 0542-0543 ß Û Ü ß A228 41512 I  bar 220-221 0544-0545 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR The next phase of the program is entered, if key fifteen has been pressed; otherwise, the bar sprite is moved up or down for keys two and eight, respectively, and the screen boundary is respected by an AND which provides wrap-around behavior. The bar is then redrawn; note that it is drawn and redrawn even in cases where it's not been moved; note that the bar sprite is taken from an instruction here, which is part of the reason register fourteen was used for this: 222-223 0546-0547 ß ÜÜÜÜ 400F 16399 Skip next if V0 <> 015 224-225 0548-0549 Ü Û Üß 1254 04692 Jump to phase 226-227 0550-0551 ß Ü 4008 16392 Skip next if V0 <> 008 228-229 0552-0553 ßßßßßßÜ 7E01 32257 bar VE  VE + 001 22A-22B 0554-0555 ß Ü 4002 16386 Skip next if V0 <> 002 22C-22D 0556-0557 ÜÛÛÛÛÛÛÜ 7EFF 32511 VE  VE + 255 22E-22F 0558-0559 ß ÜßßÛ 8E12 36370 VE  VE AND V1 230-231 0560-0561 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR The pattern toggle code is entered when key five has been pressed; otherwise, control returns to key collection. The index routine is called; the contents of the pattern array are loaded into register zero; the index routine is called again, due to implicit I movement; the pattern contents, which are zero or 2**7, are displayed once to erase them if necessary. The pattern is then toggled by XOR and the save routine is entered; index is called once more; and then the current pattern value is shown. After this, key collection resumes. Note that the pattern is displayed twice, as this is the method to ensure a live sprite is erased by itself before nothing is drawn; the other case poses no issues: 232-233 0562-0563 ßß Ü Ü 3005 12293 Skip next if V0 = 005 234-235 0564-0565 ÛÜÜß 121C 04636 Jump to key 236-237 0566-0567 Üß ÜÜÛ 224E 08782 Call index 238-239 0568-0569 ßÛÛß Ü Ü F065 61541 Load V0V0; I  I + 01 23A-23B 0570-0571 Üß ÜÜÛ 224E 08782 Call index 23C-23D 0572-0573 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 23E-23F 0574-0575 ß Ü ÜÜ 8023 32803 V0  V0 XOR V2 240-241 0576-0577 Üß Ü ß 2248 08776 Call save 242-243 0578-0579 Üß ÜÜÛ 224E 08782 Call index 244-245 0580-0581 ÛÛÜßß ßÛ DBE1 56289 Draw 08x01 at VB,VE; VF  XOR 246-247 0582-0583 ÛÜÜß 121C 04636 Jump to key For size efficiency, the save and index routines exist. The save routine calls index and then saves register zero to the resulting location. The index routine merely positions I according to register fourteen; there is no name for address 4031, as this is the last valid location for it to begin, and so there will never be a need to move it: 248-249 0584-0585 Üß ÜÜÛ 224E 08782 save Call index 24A-24B 0586-0587 ßÛßÛ Ü Ü F055 61525 Save V0V0; I  I + 01 24C-24D 0588-0589 ÜÜÜ ÜÜÜ 00EE 00238 Return 24E-24F 0590-0591 Û ÛÜÛÛÛÛ AFBF 44991 index I  4031 250-251 0592-0593 ßßßÛÛÛÛ FE1E 65054 I  I + VE 252-253 0594-0595 ÜÜÜ ÜÜÜ 00EE 00238 Return The next phase of the program assigns the vertical coordinate of the bar sprite to register thirteen to act as the delay; the bar isn't displayed at this point in the program and the speed maps cleanly to height due to larger vertical coordinates being lower being longer delays. The screen is shifted to the right by four and the next main routine is entered by beginning the delay; register twelve is used to represent the left boundary of the pattern space and then later the leftmost cell. Register fourteen is initialized to zero; register two is set to the next horizontal coordinate; the usage of register two is interesting, as I wanted to take advantage of the binary cycling of zero to three and so sought to avoid a conditional setting of the horizontal coordinate register; mistakenly I used register two, at first thinking I would need initialize a register to four for the purpose; I noticed that 2**7-1 AND 3 would provide the desired cycle of three, two, one, and zero and so gladly I used this register for the purpose and avoided storing another byte: 254-255 0596-0597 ÛÜÜ ßß ß 8DE0 36320 phase VD  VE 256-257 0598-0599 ÜÜÜÜÜ ÜÜ 00FB 00251 scroll Scroll  by 04 258-259 0600-0601 ßßßÛßÛ Û FD15 64789 automata delay  VD 25A-25B 0602-0603 ßß ßß 6C00 27648 VC  000 25C-25D 0604-0605 ßß ßßß 6E00 28160 VE  000 25E-25F 0606-0607 ÜÛÛÛÜÜÛÜ 72FF 29439 V2  V2 + 255 260-261 0608-0609 ß ÜÜ Û 8232 33330 V2  V2 AND V3 Index is called, the rightmost two cells loaded, and the Rule 30 algorithm begins. Register fifteen stores the future leftmost cell, the new cell is calculated by V0 OR V1 XOR VC, and the new leftmost cell is stored for the next iteration. The new cell is then saved: 262-263 0610-0611 Üß ÜÜÛ 224E 08782 prime Call index 264-265 0612-0613 ßÛÛß Ü Û F165 61797 Load V0V1; I  I + 02 266-267 0614-0615 ß ßßßß 8F00 36608 begin rule 30 VF  V0 268-269 0616-0617 ß Ü Ü 8011 32785 V0  V0 OR V1 26A-26B 0618-0619 ÛÜ ÜÜ 80C3 32963 V0  V0 XOR VC 26C-26D 0620-0621 ÛÜÜÜßß 8CF0 36080 end rule 30 VC  VF 26E-26F 0622-0623 Üß Ü ß 2248 08776 Call save Register fourteen is incremented and the program loops until all new cells are calculated: 270-271 0624-0625 ßßßßßßÜ 7E01 32257 VE  VE + 001 272-273 0626-0627 Üßßßßß 3E40 15936 Skip next if VE = 064 274-275 0628-0629 ÜÜß Û 1262 04706 Jump to prime Drawing begins; register fourteen is reinitialized to zero, index is called, and an eight-by-fifteen sprite is drawn four times, in a loop which draws the firsty sixty cells of the pattern. Drawing is more efficient with eight eight-by-eight sprites, rather than this four eight-by-fifteen followed by one eight-by-four, but this is more efficient and such an opportunity is rarely applicable. This is another set of four bytes that is unnecessary but was chosen due to size not being the only concern: 276-277 0630-0631 ßß ßßß 6E00 28160 VE  000 278-279 0632-0633 Üß ÜÜÛ 224E 08782 draw Call index 27A-27B 0634-0635 ÛÛÜßÜÜÛÜ D2EF 53999 Draw 08x15 at V2,VE; VF  XOR 27C-27D 0636-0637 ßßßÛÛÛÜ 7E0F 32271 VE  VE + 015 27E-27F 0638-0639 ÛÛÛÛß 3E3C 15932 Skip next if VE = 060 280-281 0640-0641 ÜÜÛÜ ß 1278 04728 Jump to draw 282-283 0642-0643 Üß ÜÜÛ 224E 08782 Call index 284-285 0644-0645 ÛÛÜß Üß D2E4 53988 Draw 08x04 at V2,VE; VF  XOR Finally, the delay is exhuasted and interleaved with checking four key fourteen to end the automata; key fourteen is unnecessary as I was going to use register three's value of three, but was chosen to pad to an even size and originally to use key fifteen, to be similar to the pattern entry, but I had troubles with a CHIP-8 implementation and how it registered key presses, so using a different key is the best way to solve that issue and avoid unintended multiple presses. An advantage of my desiring to avoid depending on initial register values of zero is that the program is more easily re-entered. When the delay is exhausted, the automata routine is entered again or, after four iterations, scroll is entered: 286-287 0646-0647 ßßßßßÛÛÛ FF07 65287 delay VF  delay 288-289 0648-0649 ÛßÛ ß Ü E4A1 58529 Skip next if V4 <> key 28A-28B 0650-0651 ß ß 1200 04608 Jump to 0512 28C-28D 0652-0653 ßßßßßß 3F00 16128 Skip next if VF = 000 28E-28F 0654-0655 Ü ß ÜÛ 1286 04742 Jump to delay 290-291 0656-0657 ßß ß 3200 12800 Skip next if V2 = 000 292-293 0658-0659 Ü ÛÜ ß 1258 04696 Jump to automata 294-295 0660-0661 Ü Û ÜÛ 1256 04694! from Jump to scroll Those reading this in a terminal with color note that the code for orange is subtly incorrect. Many terminal emulators don't properly parse these extended colors and this failure of such a basic thing is disgusting to me, but one should expect this from incompetent and foolish programmers; they don't read even the standards they claim to implement, yet then insist on continued incorrect behavior for backwards compatibility. I read and follow relevant standards, and yet I may be less of a bother in some cases, as such programmers tend to have pet standards they will ironically defend to no ending. This program ends with the continuation of the from name, 661, for those initial values of registers one through four: 296 0662 ÛÛÛÛÛÛ 3F 063 297 0663 Û 80 128 298 0664 ÛÛ 03 003 299 0665 ÛÛÛ 0E 014 .