Here is the plain version with ECMA-48 color control functions, the game itself, and the game metadata.
This is documentation for the coin flipping game provided in the sixth edition of VIPER magazine. Firstly, follows is a view of the program when it is first loaded into the tool:
200-201 0512-0513 ▀▀ ▀▀▀ 6E00 28160 VE ← 000
202-203 0514-0515 ▀▀ ▀▀ ▀ 6D00 27904 VD ← 000
204-205 0516-0517 ▀█▄▀▀▄ 6C32 27698 VC ← 050
206-207 0518-0519 ▀▄█ █ A262 41570 I ← 0610
208-209 0520-0521 ▀▀ █▀▄ 6605 26117 V6 ← 005
20A-20B 0522-0523 ▀▀ ▀▀▀ 6700 26368 V7 ← 000
20C-20D 0524-0525 ▀█▄█ █▀▄ D675 54901 Draw 08×05 at V6,V7; VF ← XOR
20E-20F 0526-0527 ▀▄█ ▄█▄ A267 41575 I ← 0615
210-211 0528-0529 ▀█▄ ██ 6636 26166 V6 ← 054
212-213 0530-0531 ▀█▄█ █▀▄ D675 54901 Draw 08×05 at V6,V7; VF ← XOR
214-215 0532-0533 █▄█▄ ▀ A2F0 41712 I ← 0752
216-217 0534-0535 ▀▀██▀▀█▄ FE33 65075 VE as BCD stored from I
218-219 0536-0537 ▀▀ ▀▀ 6300 25344 V3 ← 000
21A-21B 0538-0539 ▄▀ █ 2242 08770 Call 0578
21C-21D 0540-0541 █▄█▄ ▀ A2F0 41712 I ← 0752
21E-21F 0542-0543 ▀▀██▀▀▄█ FD33 64819 VD as BCD stored from I
220-221 0544-0545 ▀█▄ █▀ 6332 25394 V3 ← 050
222-223 0546-0547 ▄▀ █ 2242 08770 Call 0578
224-225 0548-0549 ▀▀ ▀ ▀█ CB01 51969 VB ← ??? AND 001
226-227 0550-0551 ▀ ▀ ▀▀ 4B00 19200 Skip next if VB <> 000
228-229 0552-0553 ▀▀▀▀▀▀▄ 7E01 32257 VE ← VE + 001
22A-22B 0554-0555 ▀ ▀ ▀█ 4B01 19201 Skip next if VB <> 001
22C-22D 0556-0557 ▀▀▀▀▀ █ 7D01 32001 VD ← VD + 001
22E-22F 0558-0559 ▀ ▀▀ 4C00 19456 Skip next if VC <> 000
230-231 0560-0561 ▄█ ▀ 1230 04656 Jump to 0560
232-233 0562-0563 ▀▀▄▀ ▀ 6A10 27152 VA ← 016
234-235 0564-0565 ▀▀▀█▀▄▀▄ FA15 64021 delay ← VA
236-237 0566-0567 ▀▀▀▀▀▄█▄ FA07 64007 VA ← delay
238-239 0568-0569 ▀▀▀ ▀ 3A00 14848 Skip next if VA = 000
23A-23B 0570-0571 ▄█ ▄█ 1236 04662 Jump to 0566
23C-23D 0572-0573 ▄█████▄▄ 7CFF 31999 VC ← VC + 255
23E-23F 0574-0575 ▄▄▄ 00E0 00224 Clear the screen
240-241 0576-0577 ▀ ▄█ 1206 04614 Jump to 0518
242-243 0578-0579 ▀▀ ▄▀ █ 6509 25865 V5 ← 009
244-245 0580-0581 ▀██▀ ▄▀▄ F265 62053 Load V0→V2; I ← I + 03
246-247 0582-0583 ▀▀█▀▄ ▄ F029 61481 I ← digit sprite of V0
248-249 0584-0585 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
24A-24B 0586-0587 ▀▀▀ ▄▀█ 7305 29445 V3 ← V3 + 005
24C-24D 0588-0589 ▀▀█▀▄ █ F129 61737 I ← digit sprite of V1
24E-24F 0590-0591 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
250-251 0592-0593 ▀▀▀ ▄▀█ 7305 29445 V3 ← V3 + 005
252-253 0594-0595 ▀▀█▀▄ ▀▄ F229 61993 I ← digit sprite of V2
254-255 0596-0597 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
256-257 0598-0599 ▀ ▀ ▀▀ 4B00 19200 Skip next if VB <> 000
258-259 0600-0601 ▀▀ ▀ ▄ 6801 26625 V8 ← 001
25A-25B 0602-0603 ▀ ▀ ▀█ 4B01 19201 Skip next if VB <> 001
25C-25D 0604-0605 ▀▀ ▀ ▄ 6802 26626 V8 ← 002
25E-25F 0606-0607 ▀▀▀██ F818 63512 sound ← V8
260-261 0608-0609 ▄▄▄ ▄▄▄ 00EE 00238 Return
262-263 0610-0611 █ █ 8888 34952
264-265 0612-0613 █▀▀▀█ F888 63624
266-267 0614-0615 █▄▄▄█ 88F8 35064
268-269 0616-0617 █ 2020 08224 Call 0032
26A-26B 0618-0619 █ 2020 08224 Call 0032
Follows now is the fully annotated view of the program when it is loaded into the tool:
200-201 0512-0513 ▀▀ ▀▀▀ 6E00 28160 VE ← 000
202-203 0514-0515 ▀▀ ▀▀ ▀ 6D00 27904 VD ← 000
204-205 0516-0517 ▀█▄▀▀▄ 6C32 27698 VC ← 050
206-207 0518-0519 ▀▄█ █ A262 41570 begin I ← heads
208-209 0520-0521 ▀▀ █▀▄ 6605 26117 V6 ← 005
20A-20B 0522-0523 ▀▀ ▀▀▀ 6700 26368 V7 ← 000
20C-20D 0524-0525 ▀█▄█ █▀▄ D675 54901 Draw 08×05 at V6,V7; VF ← XOR
20E-20F 0526-0527 ▀▄█ ▄█▄ A267 41575 I ← tails
210-211 0528-0529 ▀█▄ ██ 6636 26166 V6 ← 054
212-213 0530-0531 ▀█▄█ █▀▄ D675 54901 Draw 08×05 at V6,V7; VF ← XOR
214-215 0532-0533 █▄█▄ ▀ A2F0 41712 I ← 0752
216-217 0534-0535 ▀▀██▀▀█▄ FE33 65075 VE as BCD stored from I
218-219 0536-0537 ▀▀ ▀▀ 6300 25344 V3 ← 000
21A-21B 0538-0539 ▄▀ █ 2242 08770 Call score and sound
21C-21D 0540-0541 █▄█▄ ▀ A2F0 41712 I ← 0752
21E-21F 0542-0543 ▀▀██▀▀▄█ FD33 64819 VD as BCD stored from I
220-221 0544-0545 ▀█▄ █▀ 6332 25394 V3 ← 050
222-223 0546-0547 ▄▀ █ 2242 08770 Call score and sound
224-225 0548-0549 ▀▀ ▀ ▀█ CB01 51969 VB ← ??? AND 001
226-227 0550-0551 ▀ ▀ ▀▀ 4B00 19200 Skip next if VB <> 000
228-229 0552-0553 ▀▀▀▀▀▀▄ 7E01 32257 VE ← VE + 001
22A-22B 0554-0555 ▀ ▀ ▀█ 4B01 19201 Skip next if VB <> 001
22C-22D 0556-0557 ▀▀▀▀▀ █ 7D01 32001 VD ← VD + 001
22E-22F 0558-0559 ▀ ▀▀ 4C00 19456 Skip next if VC <> 000
230-231 0560-0561 ▄█ ▀ 1230 04656 end Jump to end
232-233 0562-0563 ▀▀▄▀ ▀ 6A10 27152 VA ← 016
234-235 0564-0565 ▀▀▀█▀▄▀▄ FA15 64021 delay ← VA
236-237 0566-0567 ▀▀▀▀▀▄█▄ FA07 64007 delay VA ← delay
238-239 0568-0569 ▀▀▀ ▀ 3A00 14848 Skip next if VA = 000
23A-23B 0570-0571 ▄█ ▄█ 1236 04662 Jump to delay
23C-23D 0572-0573 ▄█████▄▄ 7CFF 31999 VC ← VC + 255
23E-23F 0574-0575 ▄▄▄ 00E0 00224 Clear the screen
240-241 0576-0577 ▀ ▄█ 1206 04614 Jump to begin
242-243 0578-0579 ▀▀ ▄▀ █ 6509 25865 score and sound V5 ← 009
244-245 0580-0581 ▀██▀ ▄▀▄ F265 62053 Load V0→V2; I ← I + 03
246-247 0582-0583 ▀▀█▀▄ ▄ F029 61481 I ← digit sprite of V0
248-249 0584-0585 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
24A-24B 0586-0587 ▀▀▀ ▄▀█ 7305 29445 V3 ← V3 + 005
24C-24D 0588-0589 ▀▀█▀▄ █ F129 61737 I ← digit sprite of V1
24E-24F 0590-0591 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
250-251 0592-0593 ▀▀▀ ▄▀█ 7305 29445 V3 ← V3 + 005
252-253 0594-0595 ▀▀█▀▄ ▀▄ F229 61993 I ← digit sprite of V2
254-255 0596-0597 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
256-257 0598-0599 ▀ ▀ ▀▀ 4B00 19200 Skip next if VB <> 000
258-259 0600-0601 ▀▀ ▀ ▄ 6801 26625 V8 ← 001
25A-25B 0602-0603 ▀ ▀ ▀█ 4B01 19201 Skip next if VB <> 001
25C-25D 0604-0605 ▀▀ ▀ ▄ 6802 26626 V8 ← 002
25E-25F 0606-0607 ▀▀▀██ F818 63512 sound ← V8
260-261 0608-0609 ▄▄▄ ▄▄▄ 00EE 00238 Return
262 0610 █ █ 88 136 heads
263 0611 █ █ 88 136
264 0612 █████ F8 248
265 0613 █ █ 88 136
266 0614 █ █ 88 136
267 0615 █████ F8 248 tails
268 0616 █ 20 032
269 0617 █ 20 032
26A 0618 █ 20 032
26B 0619 █ 20 032
The register usage is as follows:
The program begins by initializing the E, D, and C registers to zero, zero, and fifty, respectively:
200-201 0512-0513 ▀▀ ▀▀▀ 6E00 28160 VE ← 000
202-203 0514-0515 ▀▀ ▀▀ ▀ 6D00 27904 VD ← 000
204-205 0516-0517 ▀█▄▀▀▄ 6C32 27698 VC ← 050
Afterwards begins the prime loop of the program, which I name ``begin'' by convention. This is responsible for drawing most of the screen, which consists of the heads sprite in the top left corner and the tails sprite in the top right corner. It then points I to scratch space, initializes register 3, and uses the score and sound routine for displaying each score under its respective sprite; it does this twice, once for each score:
206-207 0518-0519 ▀▄█ █ A262 41570 begin I ← heads
208-209 0520-0521 ▀▀ █▀▄ 6605 26117 V6 ← 005
20A-20B 0522-0523 ▀▀ ▀▀▀ 6700 26368 V7 ← 000
20C-20D 0524-0525 ▀█▄█ █▀▄ D675 54901 Draw 08×05 at V6,V7; VF ← XOR
20E-20F 0526-0527 ▀▄█ ▄█▄ A267 41575 I ← tails
210-211 0528-0529 ▀█▄ ██ 6636 26166 V6 ← 054
212-213 0530-0531 ▀█▄█ █▀▄ D675 54901 Draw 08×05 at V6,V7; VF ← XOR
214-215 0532-0533 █▄█▄ ▀ A2F0 41712 I ← 0752
216-217 0534-0535 ▀▀██▀▀█▄ FE33 65075 VE as BCD stored from I
218-219 0536-0537 ▀▀ ▀▀ 6300 25344 V3 ← 000
21A-21B 0538-0539 ▄▀ █ 2242 08770 Call score and sound
21C-21D 0540-0541 █▄█▄ ▀ A2F0 41712 I ← 0752
21E-21F 0542-0543 ▀▀██▀▀▄█ FD33 64819 VD as BCD stored from I
220-221 0544-0545 ▀█▄ █▀ 6332 25394 V3 ← 050
222-223 0546-0547 ▄▀ █ 2242 08770 Call score and sound
As each score begins at zero, it will show zero for both, initially. The loop then sets register B to zero or one with the random number generator and increases the corresponding score. Heads corresponds to zero and tails one. It then checks if the game has iterated the appropriate number of times. It is interesting to note that, as CHIP-8 lacks an instruction to exit the game, the game simply enters an infinite loop upon finishing:
224-225 0548-0549 ▀▀ ▀ ▀█ CB01 51969 VB ← ??? AND 001
226-227 0550-0551 ▀ ▀ ▀▀ 4B00 19200 Skip next if VB <> 000
228-229 0552-0553 ▀▀▀▀▀▀▄ 7E01 32257 VE ← VE + 001
22A-22B 0554-0555 ▀ ▀ ▀█ 4B01 19201 Skip next if VB <> 001
22C-22D 0556-0557 ▀▀▀▀▀ █ 7D01 32001 VD ← VD + 001
22E-22F 0558-0559 ▀ ▀▀ 4C00 19456 Skip next if VC <> 000
230-231 0560-0561 ▄█ ▀ 1230 04656 end Jump to end
The game then enters a delay of 16/60 of a second using a simple subloop:
232-233 0562-0563 ▀▀▄▀ ▀ 6A10 27152 VA ← 016
234-235 0564-0565 ▀▀▀█▀▄▀▄ FA15 64021 delay ← VA
236-237 0566-0567 ▀▀▀▀▀▄█▄ FA07 64007 delay VA ← delay
238-239 0568-0569 ▀▀▀ ▀ 3A00 14848 Skip next if VA = 000
23A-23B 0570-0571 ▄█ ▄█ 1236 04662 Jump to delay
The game then decrements the game counter by adding two's complement negative one to the iteration counter. It then clears the screen to ease screen management and finishes the loop:
23C-23D 0572-0573 ▄█████▄▄ 7CFF 31999 VC ← VC + 255
23E-23F 0574-0575 ▄▄▄ 00E0 00224 Clear the screen
240-241 0576-0577 ▀ ▄█ 1206 04614 Jump to begin
The score and sound routine is responsible for displaying a single score and is used twice in the prime loop; it also provides sound based on the previous coin flip result. The routine depends on I being set to the BCD representation of the score to display and register 3 to the horizontal positioning of the sprite. The routine begins by initializing register 5; loading the BCD representation into registers 0, 1, and 2; and then displaying each number directly side-by-side:
242-243 0578-0579 ▀▀ ▄▀ █ 6509 25865 score and sound V5 ← 009
244-245 0580-0581 ▀██▀ ▄▀▄ F265 62053 Load V0→V2; I ← I + 03
246-247 0582-0583 ▀▀█▀▄ ▄ F029 61481 I ← digit sprite of V0
248-249 0584-0585 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
24A-24B 0586-0587 ▀▀▀ ▄▀█ 7305 29445 V3 ← V3 + 005
24C-24D 0588-0589 ▀▀█▀▄ █ F129 61737 I ← digit sprite of V1
24E-24F 0590-0591 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
250-251 0592-0593 ▀▀▀ ▄▀█ 7305 29445 V3 ← V3 + 005
252-253 0594-0595 ▀▀█▀▄ ▀▄ F229 61993 I ← digit sprite of V2
254-255 0596-0597 ▀█ █ ▄▀█ D355 54101 Draw 08×05 at V3,V5; VF ← XOR
The routine ends by sounding for 1/60 or 2/60 of a second, for heads and tails respectively, based on the previous flip. As this routine is called before the first coin flip, it will use whatever previous contents of the B register are present; this means, in the case of an interpreter which initializes all registers to zero, it will always sound as if a heads has been obtained. The routine then returns:
256-257 0598-0599 ▀ ▀ ▀▀ 4B00 19200 Skip next if VB <> 000
258-259 0600-0601 ▀▀ ▀ ▄ 6801 26625 V8 ← 001
25A-25B 0602-0603 ▀ ▀ ▀█ 4B01 19201 Skip next if VB <> 001
25C-25D 0604-0605 ▀▀ ▀ ▄ 6802 26626 V8 ← 002
25E-25F 0606-0607 ▀▀▀██ F818 63512 sound ← V8
260-261 0608-0609 ▄▄▄ ▄▄▄ 00EE 00238 Return
Lastly are the heads and tails sprites, which are 05×05 to match CHIP-8 digit sprites:
262 0610 █ █ 88 136 heads
263 0611 █ █ 88 136
264 0612 █████ F8 248
265 0613 █ █ 88 136
266 0614 █ █ 88 136
267 0615 █████ F8 248 tails
268 0616 █ 20 032
269 0617 █ 20 032
26A 0618 █ 20 032
26B 0619 █ 20 032