Index  Comments

Both of enchantment.chip8 and enchantment.mmc are available under the CC0 Public Domain Dedication.

This serves as documentation for my Enchantment CHIP-8 game, made to serve as a small demonstration. Follows is the game when first loaded into my Meta-Machine Code targeted at CHIP-8, fully annotated:

200-201 0512-0513 ▀▄█   █  A262 41570                 I ← from
202-203 0514-0515 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
204-205 0516-0517 ▀ █▄  ▀▄ A231 41521                 I ← ball
206-207 0518-0519 ▀▀ █   ▄ D011 53265                 Draw 08×01 at V0,V1; VF ← XOR
208-209 0520-0521 ▀▀▀█ █ █ F515 62741            move delay ← V5
20A-20B 0522-0523 ▀▀ █   ▄ D011 53265                 Draw 08×01 at V0,V1; VF ← XOR
20C-20D 0524-0525 █▀█   ▀▄ E2A1 58017                 Skip next if V2 <> key
20E-20F 0526-0527  ▀▀▀   ▄ 7001 28673                 V0 ← V0 + 001
210-211 0528-0529 █▀█   ▀█ E3A1 58273                 Skip next if V3 <> key
212-213 0530-0531 ▄███▄▄▄▄ 70FF 28927                 V0 ← V0 + 255
214-215 0532-0533 █▀█  ▀ ▄ E4A1 58529                 Skip next if V4 <> key
216-217 0534-0535 ▄███▄▄▄█ 71FF 29183                 V1 ← V1 + 255
218-219 0536-0537 █▀█  ▀ █ E5A1 58785                 Skip next if V5 <> key
21A-21B 0538-0539  ▀▀▀   █ 7101 28929                 V1 ← V1 + 001
21C-21D 0540-0541 ▀▄▄   ▄  8062 32866                 V0 ← V0 AND V6
21E-21F 0542-0543 ▀▄▄▄  ▄▀ 8172 33138                 V1 ← V1 AND V7
220-221 0544-0545 ▀▀ █   ▄ D011 53265                 Draw 08×01 at V0,V1; VF ← XOR
222-223 0546-0547  ▀  ▀▀▀▀ 4F00 20224                 Skip next if VF <> 000
224-225 0548-0549   ▄▀▄ █  122A 04650                 Jump to live
226-227 0550-0551 ▄▄▄      00E0 00224                 Clear the screen
228-229 0552-0553    ▀  ▀  1200 04608                 Jump to 0512
22A-22B 0554-0555   ▀▀▀▀▀  3E00 15872            live Skip next if VE = 000
22C-22D 0556-0557  ▄ ▀ ▄▀  1244 04676                 Jump to draw
22E-22F 0558-0559 ▀▀▄▄█▄▄▄ C83F 51263                 V8 ← ??? AND 063
230-231 0560-0561 █▀  ▀  ▀ C980 51584!           ball V9 ← ??? AND 128
232-233 0562-0563  ▀▀ ▀ ▀▄ 6A01 27137                 VA ← 001
234-235 0564-0565  ▀▀ ▀▀▀▄ 6E01 28161                 VE ← 001
236-237 0566-0567 ▄▀  ▀  ▀ 4980 18816                 Skip next if V9 <> 128
238-239 0568-0569   ▄█▄▄█  123E 04670                 Jump to next
23A-23B 0570-0571  ▀▀▄█▄▄█ 691F 26911                 V9 ← 031
23C-23D 0572-0573 ▄██▄█▄█▄ 6AFF 27391                 VA ← 255
23E-23F 0574-0575 ▀▀  ▀ ▀█ CB01 51969            next VB ← ??? AND 001
240-241 0576-0577   ▀▀▀ ▀█ 3B01 15105                 Skip next if VB = 001
242-243 0578-0579 ▄██▄█▄██ 6BFF 27647                 VB ← 255
244-245 0580-0581 █▀ █▀  ▄ D891 55441            draw Draw 08×01 at V8,V9; VF ← XOR
246-247 0582-0583 █ ▄▄▀▄   88B4 34996                 V8 ← V8 + VB; VF ← overflow
248-249 0584-0585 █ ▄ ▀▄ ▀ 89A4 35236                 V9 ← V9 + VA; VF ← overflow
24A-24B 0586-0587  ▀  ▀    4800 18432                 Skip next if V8 <> 000
24C-24D 0588-0589  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
24E-24F 0590-0591  ▀▄▄█▄▄▄ 483F 18495                 Skip next if V8 <> 063
250-251 0592-0593  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
252-253 0594-0595  ▀  ▀  ▀ 4900 18688                 Skip next if V9 <> 000
254-255 0596-0597  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
256-257 0598-0599  ▀ ▄█▄▄█ 491F 18719                 Skip next if V9 <> 031
258-259 0600-0601  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
25A-25B 0602-0603 ▀▀▀▀▀███ FF07 65287            time VF ← delay
25C-25D 0604-0605   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
25E-25F 0606-0607  ▄ █▄ █  125A 04698                 Jump to time
260-261 0608-0609    ▀▄ ▀  1208 04616                 Jump to move
262     0610         █████   1F   031            from
263     0611         █       10   016
264     0612           ██    06   006
265     0613           █     04   004
266     0614            █    02   002
267     0615          █      08   008
268     0616        ██████   3F   063
269     0617         █████   1F   031

The register usage is as follows:

  1. V0 Horizontal coordinate of player.
  2. V1 Vertical coordinate of player.
  3. V2 Right movement button.
  4. V3 Left movement button.
  5. V4 Down movement button.
  6. V5 Up movement button and delay.
  7. V6 Horizontal mask.
  8. V7 Vertical mask.
  9. V8 Horizontal coordinate of line.
  10. V9 Vertical coordinate of line.
  11. VA Vertical delta.
  12. VB Horizontal delta.
  13. VC Unused.
  14. VD Unused.
  15. VE Flag.
  16. VF Collision detection and delay.

As this is a game I've written, it's appropriate to explain its history. The intent in writing this was to create a small core of gameplay which could be expressed concisely, and expanded on later for the next Octo Jam. The player is a lone pixel avoiding diagonal lines being drawn, without any end.

The registers were chosen for the following reasons:

  1. V0 Ease of access.
  2. V1 Ease of access.
  3. V2 Ease of access.
  4. V3 Ease of access.
  5. V4 Ease of access.
  6. V5 Ease of access.
  7. V6 Ease of access.
  8. V7 Ease of access.
  9. V8 No particular reason.
  10. V9 Follows V8.
  11. VA Follows V9.
  12. VB Follows VA.
  13. VC Unused.
  14. VD Unused.
  15. VE Distance from other registers.
  16. VF Unimportance and necessity.

The game begins by initializing all registers, setting I to its final value, and drawing the player:

200-201 0512-0513 ▀▄█   █  A262 41570                 I ← from
202-203 0514-0515 ▀██▀▀█▀█ FF65 65381                 Load V0→VF; I ← I + 16
204-205 0516-0517 ▀ █▄  ▀▄ A231 41521                 I ← ball
206-207 0518-0519 ▀▀ █   ▄ D011 53265                 Draw 08×01 at V0,V1; VF ← XOR

The prime loop of the game begins by making the delay, erasing the player, and calculating movement:

208-209 0520-0521 ▀▀▀█ █ █ F515 62741            move delay ← V5
20A-20B 0522-0523 ▀▀ █   ▄ D011 53265                 Draw 08×01 at V0,V1; VF ← XOR
20C-20D 0524-0525 █▀█   ▀▄ E2A1 58017                 Skip next if V2 <> key
20E-20F 0526-0527  ▀▀▀   ▄ 7001 28673                 V0 ← V0 + 001
210-211 0528-0529 █▀█   ▀█ E3A1 58273                 Skip next if V3 <> key
212-213 0530-0531 ▄███▄▄▄▄ 70FF 28927                 V0 ← V0 + 255
214-215 0532-0533 █▀█  ▀ ▄ E4A1 58529                 Skip next if V4 <> key
216-217 0534-0535 ▄███▄▄▄█ 71FF 29183                 V1 ← V1 + 255
218-219 0536-0537 █▀█  ▀ █ E5A1 58785                 Skip next if V5 <> key
21A-21B 0538-0539  ▀▀▀   █ 7101 28929                 V1 ← V1 + 001

Wraparound behaviour is achieved by masking. The game draws the player and resets upon a collision:

21C-21D 0540-0541 ▀▄▄   ▄  8062 32866                 V0 ← V0 AND V6
21E-21F 0542-0543 ▀▄▄▄  ▄▀ 8172 33138                 V1 ← V1 AND V7
220-221 0544-0545 ▀▀ █   ▄ D011 53265                 Draw 08×01 at V0,V1; VF ← XOR
222-223 0546-0547  ▀  ▀▀▀▀ 4F00 20224                 Skip next if VF <> 000
224-225 0548-0549   ▄▀▄ █  122A 04650                 Jump to live
226-227 0550-0551 ▄▄▄      00E0 00224                 Clear the screen
228-229 0552-0553    ▀  ▀  1200 04608                 Jump to 0512

Otherwise, the game continues drawing the lines which seek to harm the player. Register fourteen is the flag which determines if a new line is started. With this version, the lines vary by horizontal position and only whether they begin from the top or bottom of the screen. The movement deltas come from the vertical start or at random. Notice the trick of using one hundred and twenty-eight as the random value; this serves as the only sprite in the game and, as thirty-one won't come about cleanly from a mask, a conditional for this is necessary, in any case, but notice also not for setting zero:

22A-22B 0554-0555   ▀▀▀▀▀  3E00 15872            live Skip next if VE = 000
22C-22D 0556-0557  ▄ ▀ ▄▀  1244 04676                 Jump to draw
22E-22F 0558-0559 ▀▀▄▄█▄▄▄ C83F 51263                 V8 ← ??? AND 063
230-231 0560-0561 █▀  ▀  ▀ C980 51584!           ball V9 ← ??? AND 128
232-233 0562-0563  ▀▀ ▀ ▀▄ 6A01 27137                 VA ← 001
234-235 0564-0565  ▀▀ ▀▀▀▄ 6E01 28161                 VE ← 001
236-237 0566-0567 ▄▀  ▀  ▀ 4980 18816                 Skip next if V9 <> 128
238-239 0568-0569   ▄█▄▄█  123E 04670                 Jump to next
23A-23B 0570-0571  ▀▀▄█▄▄█ 691F 26911                 V9 ← 031
23C-23D 0572-0573 ▄██▄█▄█▄ 6AFF 27391                 VA ← 255
23E-23F 0574-0575 ▀▀  ▀ ▀█ CB01 51969            next VB ← ??? AND 001
240-241 0576-0577   ▀▀▀ ▀█ 3B01 15105                 Skip next if VB = 001
242-243 0578-0579 ▄██▄█▄██ 6BFF 27647                 VB ← 255

The game continues drawing the line, without regard for collision, and adjusts it, ending at bounds; in the next version of this game, placing the final eight instructions into a routine would be good:

244-245 0580-0581 █▀ █▀  ▄ D891 55441            draw Draw 08×01 at V8,V9; VF ← XOR
246-247 0582-0583 █ ▄▄▀▄   88B4 34996                 V8 ← V8 + VB; VF ← overflow
248-249 0584-0585 █ ▄ ▀▄ ▀ 89A4 35236                 V9 ← V9 + VA; VF ← overflow
24A-24B 0586-0587  ▀  ▀    4800 18432                 Skip next if V8 <> 000
24C-24D 0588-0589  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
24E-24F 0590-0591  ▀▄▄█▄▄▄ 483F 18495                 Skip next if V8 <> 063
250-251 0592-0593  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
252-253 0594-0595  ▀  ▀  ▀ 4900 18688                 Skip next if V9 <> 000
254-255 0596-0597  ▀▀ ▀▀▀  6E00 28160                 VE ← 000
256-257 0598-0599  ▀ ▄█▄▄█ 491F 18719                 Skip next if V9 <> 031
258-259 0600-0601  ▀▀ ▀▀▀  6E00 28160                 VE ← 000

The game ends in a loop to exhaust any remaining delay, a jump to the prime loop, and the constants:

25A-25B 0602-0603 ▀▀▀▀▀███ FF07 65287            time VF ← delay
25C-25D 0604-0605   ▀▀▀▀▀▀ 3F00 16128                 Skip next if VF = 000
25E-25F 0606-0607  ▄ █▄ █  125A 04698                 Jump to time
260-261 0608-0609    ▀▄ ▀  1208 04616                 Jump to move
262     0610         █████   1F   031            from
263     0611         █       10   016
264     0612           ██    06   006
265     0613           █     04   004
266     0614            █    02   002
267     0615          █      08   008
268     0616        ██████   3F   063
269     0617         █████   1F   031

I'm glad I was able to so easily write this game, requiring little effort, yet I'm disappointed with its lack of fun. The future version of this game should have concurrent lines, horizontal starting, and more line variety. To prevent sitting still, there should be a rare line which targets players.

I was almost able to write this in my reimplementation of my MMC, but needed insertion and deletion.