A Documenting of the Coin Flipping CHIP-8 Game 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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: V0 Load from I and then BCD display. V1 Load from I and then BCD display. V2 Load from I and then BCD display. V3 Horizontal positioning of BCD sprites. V4 Unused. V5 Vertical positioning of BCD sprites. V6 Horizontal positioning of heads and tails sprites. V7 Vertical positioning of heads and tails sprites. V8 Manipulating the sound register. V9 Unused. VA Manipulating the delay register. VB Contain a randomly generated number of zero or one. VC Contain the number of iterations of the game. VD Contain the tails count. VE Contain the heads count. VF Unused. 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 08x05 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 08x05 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 08x05 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 08x05 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 08x05 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 05x05 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 .