├── LICENSE ├── README.md ├── cavern ├── README.md ├── cavern.ch8 ├── cavern.txt └── img │ ├── level0.png │ ├── level1.png │ ├── level10.png │ ├── level11.png │ ├── level2.png │ ├── level3.png │ ├── level4.png │ ├── level5.png │ ├── level6.png │ ├── level7.png │ ├── level8.png │ └── level9.png ├── chipquarium ├── README.md ├── chipquarium.8o └── chipquarium.ch8 ├── delaytimer ├── delay_timer_test.8o └── delay_timer_test.ch8 ├── heartmonitor ├── README.md ├── heart_monitor.8o └── heart_monitor.ch8 ├── morsecode ├── README.md ├── morse_demo.8o └── morse_demo.ch8 └── randomnumber ├── README.md ├── random_number_test.8o └── random_number_test.ch8 /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2014-2017 Matthew Mikolay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CHIP-8 2 | A collection of CHIP-8 programs and documentation. 3 | 4 | ## Documentation 5 | 6 | - [CHIP-8 Technical Reference][technical] 7 | - [CHIP-8 Extensions Reference][extensions] 8 | - [CHIP-8 Instruction Set][instructions] 9 | - [Mastering CHIP-8][mastering] 10 | 11 | ## Programs 12 | 13 | ### Games 14 | 15 | - [Cavern](cavern) 16 | - [Chipquarium](chipquarium) 17 | 18 | ### Demos 19 | 20 | - [Heart Monitor](heartmonitor) 21 | - [Morse Code](morsecode) 22 | 23 | ### Utilities 24 | 25 | - [Delay Timer Test](delaytimer) 26 | - [Random Number Test](randomnumber) 27 | 28 | ## License 29 | Source code in this repository is licensed under the MIT License. For more 30 | information, see the included [LICENSE][mit-license] file. 31 | 32 | Documentation in the wiki is licensed under a [Creative Commons] license. Please 33 | see individual wiki pages for details. 34 | 35 | [mit-license]: LICENSE "MIT License" 36 | [Creative Commons]: https://creativecommons.org/ 37 | [technical]: https://github.com/mattmikolay/chip-8/wiki/CHIP%E2%80%908-Technical-Reference 38 | [extensions]: https://github.com/mattmikolay/chip-8/wiki/CHIP%E2%80%908-Extensions-Reference 39 | [instructions]: https://github.com/mattmikolay/chip-8/wiki/CHIP%E2%80%908-Instruction-Set 40 | [mastering]: https://github.com/mattmikolay/chip-8/wiki/Mastering-CHIP%E2%80%908 41 | -------------------------------------------------------------------------------- /cavern/README.md: -------------------------------------------------------------------------------- 1 | # Cavern 2 | Escape the cave without crashing into the walls! 3 | Navigate using the '2', '4', '6', and '8' keys. 4 | -------------------------------------------------------------------------------- /cavern/cavern.ch8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/cavern.ch8 -------------------------------------------------------------------------------- /cavern/cavern.txt: -------------------------------------------------------------------------------- 1 | Cavern 2 | Copyright 2014-2016 Matthew Mikolay 3 | See github.com/mattmikolay/chip-8 or mattmik.com for more info. 4 | 5 | ADDR LABEL INSTR COMMENT 6 | 7 | Begin program at address 200 8 | 9 | Display start screen 10 | V1 register is game difficulty 11 | V5 register is current level number 12 | 200 6100 Set V1 (difficulty) = 0 for no difficulty selected 13 | 202 6500 Set V5 (level) = 0 for intro screen 14 | 204 226E Jump to DRAWLEVEL subroutine to draw current level 15 | 206 KEYINTRO F60A Wait for a keypress, store in V6 16 | 208 4601 Skip next instruction if V6 != 1 17 | 20A 610A Set V1 (difficulty) = 10 18 | 20C 4602 Skip next instruction if V6 != 2 19 | 20E 6105 Set V1 (difficulty) = 5 20 | 210 4603 Skip next instruction if V6 != 3 21 | 212 6101 Set V1 (difficulty) = 1 22 | 214 4100 Skip next instruction if V1 != 0 23 | 216 1206 Jump to KEYINTRO 24 | 25 | Set player's x and y coordinates 26 | V2 register is player's current direction: 27 | 0 = stationary, 1 = right, 2 = up, 28 | 3 = left, 4 = down 29 | V3 register is X coordinate of player 30 | V4 register is Y coordinate of player 31 | 218 6200 Set V2 (direction) = 0, defaulting to stationary 32 | 21A 6334 V3 (X) = 52 33 | 21C 6414 V4 (Y) = 20 34 | 35 | Move forward to the first playable level 36 | 21E 6501 Set V5 (level) = 1 37 | 38 | 220 NEXTLEVEL 226E Jump to DRAWLEVEL subroutine to draw current level 39 | 40 | Check for game end 41 | 222 450B Skip next if V5 (level) != 11, the final level 42 | 224 126C Jump to ENDGAME 43 | 44 | Let the player be controlled by the keypad 45 | Update direction register based upon keypress 46 | V6 register is scratch register to check pressed key 47 | 226 KEYCHECK 6602 Set V6 = 2 48 | 228 E6A1 Skip next if V6 not pressed 49 | 22A 6202 Set V2 (direction) = up 50 | 22C 6606 Set V6 = 6 51 | 22E E6A1 Skip next if V6 not pressed 52 | 230 6201 Set V2 (direction) = right 53 | 232 6604 Set V6 = 4 54 | 234 E6A1 Skip next if V6 not pressed 55 | 236 6203 Set V2 (direction) = left 56 | 238 6608 Set V6 = 8 57 | 23A E6A1 Skip next if V6 not pressed 58 | 23C 6204 Set V2 (direction) = down 59 | 60 | Update player's x and y position based on direction 61 | 23E 4201 Skip next if V2 (direction) != 1 62 | 240 7301 Increment V3, X = X + 1 63 | 242 4202 Skip next if V2 (direction) != 2 64 | 244 74FF Decrement V4, Y = Y - 1 65 | 246 4203 Skip next if V2 (direction) != 3 66 | 248 73FF Decrement V3, X = X - 1 67 | 24A 4204 Skip next if V2 (direction) != 4 68 | 24C 7401 Increment V4, Y = Y + 1 69 | 70 | Check if player has beaten the current level 71 | (If player has reached the left side of the screen) 72 | 24E 33FF Skip next if V3 (X) = 255, meaning the player 73 | wrapped around to right side of screen) 74 | 250 1258 Jump to DRAWPLAYER 75 | 76 | Progress to the next level 77 | 252 633F Set V3 (X) = 63, the far right side of the screen 78 | 254 7501 Increment V5 (level) 79 | 256 1220 Jump to NEXTLEVEL 80 | 81 | Draw the player 82 | 258 DRAWPLAYER A273 Set I to address of player sprite 83 | 25A D341 Draw the player sprite on the screen 84 | 85 | Check for a collision with the graphics data 86 | 25C 3F00 Skip next if VF == 0 87 | 25E 126C Jump to ENDGAME 88 | 89 | Set delay timer depending upon the game's difficulty 90 | 260 F115 DT = V1 (difficulty) 91 | 262 TIMECHECK F607 Set V6 = DT 92 | 264 3600 Skip next if V6 = 0 93 | 266 1262 Jump to TIMECHECK 94 | 95 | 268 D341 Erase player sprite on the screen 96 | 26A 1226 Jump to KEYCHECK to keep the player moving 97 | 98 | 26C ENDGAME 126C Jump to ENDGAME 99 | 100 | Subroutine: Draw current level 101 | V6 is scratch register for address calculation 102 | V7 is scratch register for length of graphics data 103 | 26E DRAWLEVEL 00E0 Clear the screen 104 | 270 8650 V6 = V5 (scratch = level) 105 | 272 6780 V7 = 128 (number of bytes per half level data) 106 | 274 A29A Set I = address of first level data 107 | 108 | 276 FINDLEVEL 4600 Skip next instruction if V6 != 0 109 | 278 1282 Jump to LEVELSPRITE 110 | 27A F71E I = I + 128 111 | 27C F71E I = I + 128 112 | 27E 76FF V6 = V6 - 1 (V6 = V6 + 255) 113 | 280 1276 Jump to FINDLEVEL 114 | 115 | Draw the level's sprite data to the screen 116 | V6 is scratch register for x coordinate on screen 117 | V7 is scratch register for y coordinate on screen 118 | V8 is scratch register, stores the constant 8 119 | (length of a single block) 120 | 282 LEVELSPRITE 6808 V8 = 8 121 | 122 | Loop over y coordinates of screen 123 | 284 6700 V7 = 0 124 | 125 | Loop over x coordinates of screen 126 | 286 YDRAW 6600 V6 = 0 127 | 288 XDRAW D678 Draw 8 x 8 sprite 128 | 28A 7608 Increment V6 by 8 129 | 28C F81E I = I + 8 130 | 131 | 28E 3640 Skip next instruction if V6 = 64 132 | 290 1288 Jump to XDRAW 133 | 134 | 292 7708 Increment V7 by 8 135 | 294 3720 Skip next instruction if V7 = 32 136 | 296 1286 Jump to YDRAW 137 | 138 | 298 00EE End DRAWLEVEL subroutine 139 | 140 | Level graphics from here forward... 141 | 142 | Title screen (Level 0): 143 | 29A FFFF 144 | FF00 145 | FFFF 146 | 00FF 147 | FFFF 148 | FF00 149 | CFDF 150 | 19D8 151 | FFFF 152 | FF00 153 | 1EBF 154 | B333 155 | FFFF 156 | FF00 157 | 6363 158 | 6363 159 | FFFF 160 | FF00 161 | 7D7D 162 | 6179 163 | FFFF 164 | FF00 165 | F3FB 166 | 9BF3 167 | FFFF 168 | FF00 169 | 9B9B 170 | 985B 171 | FFFF 172 | FF00 173 | FFFF 174 | 00FF 175 | FF00 176 | FFFF 177 | 00FF 178 | 80BB 179 | D819 180 | DFCF 181 | 00FF 182 | 00AA 183 | 3FBF 184 | B333 185 | 00FF 186 | 003E 187 | 3636 188 | 1C1C 189 | 00FF 190 | 00EE 191 | 7961 192 | 7D7D 193 | 00FF 194 | 00EF 195 | F39B 196 | 9B9B 197 | 00FF 198 | 00AA 199 | 5B38 200 | 3B3B 201 | 00FF 202 | 00E9 203 | FF00 204 | FFFF 205 | 00FF 206 | 01D5 207 | 8ABA 208 | A2BB 209 | 80FF 210 | C0DD 211 | AAAE 212 | A2A2 213 | 00FF 214 | 00D1 215 | AA2A 216 | AA22 217 | 00FF 218 | 00DD 219 | A4E4 220 | A4A4 221 | 00FF 222 | 10D7 223 | 4A4A 224 | 4A48 225 | 00FF 226 | 0077 227 | AAAC 228 | AAAA 229 | 00FF 230 | 0076 231 | A9A9 232 | A9ED 233 | 00FF 234 | 4058 235 | 55DD 236 | 4949 237 | 01FF 238 | 033B 239 | D1DD 240 | C5DD 241 | C0FF 242 | FFFF 243 | 1191 244 | 11DD 245 | 00FF 246 | FFFF 247 | 1490 248 | 14DC 249 | 00FF 250 | FFFF 251 | 9497 252 | 9197 253 | 10FF 254 | FFFF 255 | 5476 256 | 4447 257 | 00FF 258 | FFFF 259 | 4565 260 | 4576 261 | 00FF 262 | FFFF 263 | 4849 264 | 485C 265 | 40FF 266 | FFFF 267 | 0BBB 268 | 0B3B 269 | 03FF 270 | FFFF 271 | 272 | Level 1: 273 | FFFF 274 | FFFF 275 | FFFF 276 | FFFF 277 | FFFF 278 | FFFF 279 | FFFF 280 | FFFF 281 | FFFF 282 | C080 283 | 0000 284 | 070F 285 | FFFF 286 | 0000 287 | 0000 288 | FFFF 289 | FFFF 290 | 0000 291 | 0000 292 | FFFF 293 | FFFF 294 | 0000 295 | 0000 296 | FFFF 297 | FFFF 298 | 0703 299 | 0101 300 | C1E1 301 | FFFF 302 | FFFF 303 | FFFF 304 | FFFF 305 | FFFF 306 | FFFF 307 | FFFF 308 | FFFF 309 | FFFF 310 | FFFF 311 | FFFF 312 | FFFF 313 | 0F0F 314 | 0F0F 315 | 0F0F 316 | 0F0F 317 | FFFF 318 | FFFF 319 | FFFF 320 | FFFF 321 | FFFF 322 | FFFF 323 | FFFF 324 | FFFF 325 | FFFF 326 | FFFF 327 | FFFF 328 | FEFC 329 | E1E1 330 | E1E1 331 | C000 332 | 0000 333 | FFFF 334 | FFFF 335 | FF3F 336 | 1F0F 337 | FFFF 338 | FFFF 339 | FFFF 340 | FFFF 341 | FFFF 342 | FFFF 343 | FFFF 344 | FFFF 345 | 0F0F 346 | 0F0F 347 | 0F0F 348 | 0F0F 349 | FFFF 350 | FFFF 351 | FFFF 352 | FFFF 353 | FFFF 354 | FFFF 355 | FFFF 356 | FFFF 357 | F8F8 358 | F0F0 359 | F0F0 360 | F0F0 361 | 0000 362 | 0000 363 | 0000 364 | 0000 365 | 0707 366 | 0303 367 | 0303 368 | 0303 369 | FFFF 370 | 0000 371 | 0000 372 | FFFF 373 | FFFE 374 | 0000 375 | 0000 376 | FFFF 377 | 0F0F 378 | 0F0F 379 | 1F3F 380 | FFFF 381 | FFFF 382 | FFFF 383 | FFFF 384 | FFFF 385 | FFFF 386 | FFFF 387 | FFFF 388 | FFFF 389 | F8F8 390 | FCFE 391 | FFFF 392 | FFFF 393 | 0000 394 | 0000 395 | 00C0 396 | FFFF 397 | 0707 398 | 0F1F 399 | 3FFF 400 | FFFF 401 | 402 | Level 2: 403 | 404 | FFFF 405 | FFFF 406 | FFFF 407 | FF07 408 | FFFF 409 | FFFF 410 | FFFF 411 | FFFF 412 | FFFF 413 | FFFF 414 | FFFF 415 | FFFF 416 | FFFF 417 | FEFC 418 | F8F8 419 | F8F8 420 | FFFF 421 | 0000 422 | 0000 423 | 3F7F 424 | FFFF 425 | 0000 426 | 0000 427 | FEFF 428 | FFFF 429 | 3F1F 430 | 0F0F 431 | 0F0F 432 | FFFF 433 | FFFF 434 | FFFF 435 | FFFF 436 | 0301 437 | 0181 438 | C1C1 439 | C1C1 440 | FFFF 441 | FFFF 442 | FFFF 443 | FFFF 444 | FFFF 445 | FFFF 446 | FFFF 447 | FFFF 448 | F8F8 449 | F8F8 450 | F8F8 451 | FCFE 452 | 7F7F 453 | 7F3F 454 | 0000 455 | 0000 456 | FFFF 457 | FFFF 458 | 7F3F 459 | 1F1F 460 | 0F0F 461 | 0F0F 462 | 0F0F 463 | 0F0F 464 | FFFF 465 | FFFF 466 | FFFF 467 | FFFF 468 | C1C0 469 | C0C0 470 | E0F0 471 | FFFF 472 | FFFF 473 | 0301 474 | 0000 475 | E0F0 476 | FFFF 477 | FFFF 478 | 0703 479 | 0000 480 | FFFF 481 | FFFF 482 | FFFF 483 | 0000 484 | FCFE 485 | FEFE 486 | FEFC 487 | 0000 488 | 1F1F 489 | 1F1F 490 | 1F1F 491 | 1F1F 492 | 0F0F 493 | 0F0F 494 | 0F0F 495 | 0F0F 496 | FFFF 497 | FFFF 498 | FFFF 499 | FFFF 500 | FFFF 501 | FFFF 502 | FFFF 503 | FFFF 504 | FFFF 505 | FFFF 506 | FFFF 507 | FFFF 508 | C0E0 509 | FFFF 510 | FFFF 511 | FFFF 512 | 0000 513 | FFFF 514 | FFFF 515 | FFFF 516 | 0000 517 | FFFF 518 | FFFF 519 | FFFF 520 | 3F7F 521 | FFFF 522 | FFFF 523 | FFFF 524 | 0F07 525 | 0000 526 | 80C0 527 | FFFF 528 | FFFF 529 | 0000 530 | 0000 531 | FFFF 532 | 533 | Level 3: 534 | FFFF 535 | FFFF 536 | FFFF 537 | FFFF 538 | FFFF 539 | FFFF 540 | FFFF 541 | FFFF 542 | FFFF 543 | FFFF 544 | FFFF 545 | FFFF 546 | FFFF 547 | FFFF 548 | FFFF 549 | FFFF 550 | FFFF 551 | FFFF 552 | FFFF 553 | FF00 554 | FFFC 555 | F0E0 556 | E1E3 557 | C303 558 | FF3F 559 | 0F07 560 | 87C7 561 | C3C0 562 | FFFF 563 | FFFF 564 | FFFF 565 | FF00 566 | FFFF 567 | FFFF 568 | FFFF 569 | FFFF 570 | FFFF 571 | FFFF 572 | FFFF 573 | FFFF 574 | FFFF 575 | FFFF 576 | FFFF 577 | FFFF 578 | FEFE 579 | FEFE 580 | FEFE 581 | FEFE 582 | 0000 583 | 001F 584 | 1F1F 585 | 1F1F 586 | 0307 587 | 1FFF 588 | FFFF 589 | FFFF 590 | C0E0 591 | F8FF 592 | FFFF 593 | FFFF 594 | 0000 595 | 00FF 596 | FFFF 597 | FFFF 598 | 00FF 599 | FF00 600 | FFFF 601 | FFFF 602 | 00FF 603 | FF00 604 | FFFF 605 | FFFF 606 | 00FF 607 | FF00 608 | FFFF 609 | FFFF 610 | 00F0 611 | F800 612 | FFFF 613 | FFFF 614 | 1F1F 615 | 1F1F 616 | FFFF 617 | FFFF 618 | FFFF 619 | FFFF 620 | FFFF 621 | FFFF 622 | FFFF 623 | FFFF 624 | FFFF 625 | FFFF 626 | FFFF 627 | FFFF 628 | FFFF 629 | FFFF 630 | FFFF 631 | FFFF 632 | FFFF 633 | FFFF 634 | FFFF 635 | FFFF 636 | FFFF 637 | FFFF 638 | FFFF 639 | FFFF 640 | FFFF 641 | FFFF 642 | FFFF 643 | FFFF 644 | FFFF 645 | FFFF 646 | FFFF 647 | FFFF 648 | FFFF 649 | FFFF 650 | FFFF 651 | FFFF 652 | FFFF 653 | FFFF 654 | FFFF 655 | FFFF 656 | FFFF 657 | FFFF 658 | FFFF 659 | FFFF 660 | FFFF 661 | FFFF 662 | 663 | Level 4: 664 | 665 | FFFF 666 | FFFF 667 | FFFF 668 | FFFF 669 | FFFF 670 | FFFF 671 | FFFF 672 | FFFF 673 | FFFF 674 | FFFF 675 | FFFF 676 | FFFF 677 | FFFF 678 | FFFF 679 | FFFF 680 | FFFF 681 | FFFF 682 | FFFF 683 | FFFF 684 | FFFF 685 | FFFF 686 | FFFF 687 | FFFF 688 | FFFF 689 | FFFF 690 | FFFF 691 | FFFF 692 | FFFF 693 | FFFF 694 | FFFF 695 | FFFF 696 | FFFF 697 | FF00 698 | FEFE 699 | FEFE 700 | FEFE 701 | FFF0 702 | F7F7 703 | F7F7 704 | F7F7 705 | FF3C 706 | BDBD 707 | BDBD 708 | BDBD 709 | FF0F 710 | EFEF 711 | EFEF 712 | EFEF 713 | FF03 714 | 7B7B 715 | 7B7B 716 | 7B7B 717 | FFC0 718 | DEDE 719 | DEDE 720 | DEDE 721 | FFFF 722 | FFFF 723 | FFFF 724 | FFFF 725 | FFFF 726 | FFFF 727 | FFFF 728 | FFFF 729 | FEFF 730 | FFFF 731 | FFFF 732 | FFFF 733 | 07FF 734 | FFFF 735 | FFFF 736 | FF80 737 | 81FF 738 | FFFF 739 | FFFF 740 | FF1F 741 | E0FF 742 | FFFF 743 | FFFF 744 | FFFF 745 | 78FF 746 | FFC0 747 | DFDF 748 | DFDF 749 | 1EFF 750 | FF00 751 | FFFF 752 | FFFF 753 | 00FF 754 | FF00 755 | FFFF 756 | FFFF 757 | 00FF 758 | FF00 759 | FFFF 760 | FFFF 761 | FFFF 762 | FFFF 763 | FF00 764 | FFFF 765 | BFBF 766 | BFBF 767 | BF3F 768 | FFFF 769 | DFDF 770 | DFC0 771 | FFFF 772 | FFFF 773 | FFFF 774 | FF00 775 | FFFF 776 | FFFF 777 | DFDF 778 | DF1F 779 | FFFF 780 | FFFF 781 | FFFF 782 | FFFF 783 | FFFF 784 | FFFF 785 | FFFF 786 | FFFF 787 | FFFF 788 | FFFF 789 | FFFF 790 | FFFF 791 | FFFF 792 | FFFF 793 | 794 | Level 5: 795 | 796 | FFFF 797 | 0000 798 | FFFF 799 | FFFF 800 | FFF0 801 | 0000 802 | FFFF 803 | FFFF 804 | 0000 805 | 0000 806 | FFFF 807 | FFFF 808 | 0000 809 | 0000 810 | FFFF 811 | 0000 812 | 0000 813 | 0000 814 | FFFF 815 | 0000 816 | 0000 817 | 0000 818 | FFFF 819 | FFFF 820 | 0001 821 | 077F 822 | FFFF 823 | FFFF 824 | FFFF 825 | FFFF 826 | FFFF 827 | FFFF 828 | FFFF 829 | FFFF 830 | FFFF 831 | FFFF 832 | FFFF 833 | FFFF 834 | FFFF 835 | FFFF 836 | FFFF 837 | FFFF 838 | FFFF 839 | FFFF 840 | 001F 841 | 1F1F 842 | 1C1C 843 | 1C1C 844 | 00F8 845 | F8F8 846 | 0000 847 | 007F 848 | FFFF 849 | FFFF 850 | FFFF 851 | FFFF 852 | FFFF 853 | FCF8 854 | F8F0 855 | F0F0 856 | FF00 857 | 0307 858 | 070F 859 | 0F0F 860 | FFFF 861 | FFFF 862 | FFFF 863 | FFFF 864 | FFFF 865 | FFFF 866 | FFFF 867 | FFFF 868 | FFFF 869 | FFFF 870 | FFFF 871 | FFFF 872 | 1C1C 873 | 1C1C 874 | 1C1F 875 | 1F1F 876 | 7F7F 877 | 0000 878 | 00FF 879 | FFFF 880 | FFFF 881 | 0000 882 | 00FF 883 | FFFF 884 | F0E0 885 | 0000 886 | 00E0 887 | F0F0 888 | 0F0F 889 | 0F0F 890 | 0F0F 891 | 0F0F 892 | FFFF 893 | FFFF 894 | FFFF 895 | FFFF 896 | FFFF 897 | FFFF 898 | FFFF 899 | FFFF 900 | FFFF 901 | FFFF 902 | FFFF 903 | E000 904 | 0000 905 | 00FF 906 | FF00 907 | 0000 908 | 0000 909 | 00FF 910 | FF00 911 | 0000 912 | 0000 913 | 00F8 914 | F000 915 | 0000 916 | 7070 917 | 3838 918 | 1C07 919 | 0300 920 | 0F07 921 | 0703 922 | 0000 923 | FFFF 924 | 925 | Level 6: 926 | 927 | FFFF 928 | FFFF 929 | FFFF 930 | FFFF 931 | FFFF 932 | FFFF 933 | FFFF 934 | FFFF 935 | FFFF 936 | F8F8 937 | F8F8 938 | F8F8 939 | FFFF 940 | 0000 941 | 0000 942 | 0000 943 | FFFF 944 | 0000 945 | 0000 946 | 0000 947 | FFFF 948 | 0000 949 | FFFF 950 | FFFF 951 | FFFF 952 | 0000 953 | FFFF 954 | FFFF 955 | FFFF 956 | 0000 957 | FFFF 958 | FFFF 959 | FFFF 960 | FFFF 961 | FFFF 962 | FFFF 963 | FFFF 964 | FFFF 965 | FFFF 966 | FFFF 967 | F8F8 968 | F8F8 969 | F8F8 970 | F8F8 971 | 0000 972 | 181E 973 | 1F1F 974 | 1F1F 975 | 0000 976 | 0000 977 | 20B0 978 | 10B8 979 | FF95 980 | B591 981 | D595 982 | FFFF 983 | FF11 984 | 5513 985 | 5555 986 | FFFF 987 | F15D 988 | 5137 989 | 5F57 990 | FFFF 991 | FFFF 992 | FFFF 993 | FFFF 994 | FFFF 995 | FFFF 996 | FFFF 997 | FFFF 998 | FFFF 999 | F8F8 1000 | F8F8 1001 | F8F8 1002 | F8F8 1003 | 1317 1004 | 1F1F 1005 | 1F1F 1006 | 1619 1007 | 18BC 1008 | 1CBC 1009 | FEFE 1010 | FEFE 1011 | FFFF 1012 | FFFF 1013 | FFFF 1014 | FFFF 1015 | FFFF 1016 | FFFF 1017 | FFFF 1018 | FFFF 1019 | FFFF 1020 | FFFF 1021 | FFFF 1022 | FFFF 1023 | FFFF 1024 | FFFF 1025 | FF00 1026 | 00FF 1027 | FFFF 1028 | FFFF 1029 | FF00 1030 | 00FF 1031 | F8F8 1032 | F8F9 1033 | FB03 1034 | 00FF 1035 | 1679 1036 | FFFF 1037 | FF3F 1038 | 1FFF 1039 | EEF6 1040 | F6B6 1041 | D6D6 1042 | EEFF 1043 | FFFF 1044 | FFFF 1045 | FFFF 1046 | FFFF 1047 | FFFF 1048 | FFFF 1049 | FFFF 1050 | FFFF 1051 | FFFF 1052 | FFFF 1053 | FFFF 1054 | FFFF 1055 | 1056 | Level 7: 1057 | 1058 | FFFF 1059 | 00FF 1060 | FFFF 1061 | FFFF 1062 | FFFF 1063 | 00FF 1064 | FFFF 1065 | FFFF 1066 | FFFF 1067 | 1FC0 1068 | FFFF 1069 | FFFF 1070 | FFFF 1071 | FF3F 1072 | BFBF 1073 | BFBF 1074 | FFFF 1075 | FFFF 1076 | FFFF 1077 | FFFF 1078 | FFFF 1079 | FFFF 1080 | FFFF 1081 | FFFF 1082 | FFFF 1083 | FFFF 1084 | FFFF 1085 | FFFF 1086 | FFFF 1087 | FFFF 1088 | FFFF 1089 | FFFF 1090 | FFFF 1091 | FFFF 1092 | FFFF 1093 | FFFF 1094 | FFFF 1095 | FFFF 1096 | FFFF 1097 | FFFF 1098 | FFFF 1099 | FFFF 1100 | FFFF 1101 | FFFF 1102 | BFBF 1103 | BFBF 1104 | BFBF 1105 | BFBF 1106 | FFFF 1107 | FFFF 1108 | FFFF 1109 | FFFF 1110 | FFFF 1111 | FFFF 1112 | FFFF 1113 | FFFF 1114 | FFFF 1115 | FFFF 1116 | FFFF 1117 | FFFF 1118 | FFFF 1119 | FFFF 1120 | FFFF 1121 | FFFF 1122 | F0F8 1123 | FDFD 1124 | F8F6 1125 | FFFF 1126 | 00C6 1127 | EFEF 1128 | C631 1129 | 7B7B 1130 | 0031 1131 | 7B7B 1132 | 318C 1133 | DEDE 1134 | 008C 1135 | DEDE 1136 | 8C63 1137 | F7F7 1138 | 0163 1139 | F7F7 1140 | 6319 1141 | BDBD 1142 | FFFF 1143 | FFFF 1144 | FFFF 1145 | FFFF 1146 | FFFF 1147 | FFFF 1148 | FFFF 1149 | FFFF 1150 | FFFF 1151 | FFFF 1152 | FFFF 1153 | FFFF 1154 | F6F1 1155 | FBFB 1156 | F1F0 1157 | FFFF 1158 | 318C 1159 | DEDE 1160 | 8C00 1161 | FFFF 1162 | 8C63 1163 | F7F7 1164 | 6300 1165 | FFFF 1166 | 6318 1167 | BDBD 1168 | 1800 1169 | FFFF 1170 | 19C7 1171 | EFEF 1172 | C700 1173 | FFFF 1174 | FFFF 1175 | FFFF 1176 | FF00 1177 | FFFF 1178 | FFFF 1179 | FFFF 1180 | FF00 1181 | F0FF 1182 | FFFF 1183 | FFFF 1184 | FF00 1185 | 00FF 1186 | 1187 | Level 8: 1188 | 1189 | FBFB 1190 | FBFB 1191 | FBFB 1192 | FBFB 1193 | FFFF 1194 | FFFF 1195 | FFFE 1196 | FCF8 1197 | FFFF 1198 | FFFF 1199 | FF1F 1200 | 0FC7 1201 | BFBF 1202 | BEBE 1203 | BEBE 1204 | BEBE 1205 | DFDF 1206 | 03DB 1207 | DBDB 1208 | DBDB 1209 | FEFE 1210 | FEFE 1211 | FEFE 1212 | FEFE 1213 | 7F7F 1214 | 7C7D 1215 | 7D7D 1216 | 7D7D 1217 | FFFF 1218 | 00FF 1219 | FFFF 1220 | FFFF 1221 | FB00 1222 | 00FB 1223 | FBFB 1224 | FBFB 1225 | F103 1226 | 03F1 1227 | F8FC 1228 | FEFF 1229 | E3F3 1230 | F3E3 1231 | C70F 1232 | 1F3F 1233 | BEBE 1234 | BEBE 1235 | BEBE 1236 | BEBE 1237 | DBDB 1238 | DBDB 1239 | D8D8 1240 | DFDF 1241 | FCF8 1242 | F1E3 1243 | 0707 1244 | E3F1 1245 | 3D1D 1246 | 8DC5 1247 | E1E1 1248 | C78F 1249 | FFFF 1250 | FFFF 1251 | FFFF 1252 | FFFF 1253 | FBFB 1254 | FBFB 1255 | FBFB 1256 | FBFB 1257 | FFFF 1258 | FFFF 1259 | FFFF 1260 | FFFF 1261 | 3F3F 1262 | 0000 1263 | FFFF 1264 | FFFF 1265 | BEBE 1266 | 3E3E 1267 | FEFE 1268 | FEFE 1269 | DFDF 1270 | DFDF 1271 | DFDF 1272 | DFDF 1273 | F8FC 1274 | FEFE 1275 | FEFE 1276 | FEFE 1277 | 1F3F 1278 | 7F7F 1279 | 7F7F 1280 | 7F7F 1281 | FFFF 1282 | FFFF 1283 | FFFF 1284 | FFFF 1285 | FBFB 1286 | FBFB 1287 | FBFB 1288 | FBFB 1289 | FFFF 1290 | FFFF 1291 | FFFF 1292 | FFFF 1293 | FFFF 1294 | FFFF 1295 | FFFF 1296 | FFFF 1297 | 80BF 1298 | BFBF 1299 | BFBF 1300 | BFBF 1301 | DFDF 1302 | DFDF 1303 | DFDF 1304 | DFDF 1305 | FEFE 1306 | FEFE 1307 | FEFE 1308 | FEFE 1309 | 7F7F 1310 | 7F7F 1311 | 7F7F 1312 | 7F7F 1313 | FFFF 1314 | FFFF 1315 | FFFF 1316 | FFFF 1317 | 1318 | Level 9: 1319 | 1320 | FFFF 1321 | FFFF 1322 | 0303 1323 | 03E3 1324 | FFFF 1325 | FFFF 1326 | FFFF 1327 | FFFF 1328 | FFFF 1329 | FFFF 1330 | FFFF 1331 | FFFF 1332 | FFFF 1333 | 80BF 1334 | A0AF 1335 | A8AB 1336 | FBFB 1337 | 03FF 1338 | 03FB 1339 | 0BEB 1340 | FFFF 1341 | FFFF 1342 | FFFF 1343 | FFFF 1344 | FFFF 1345 | FFFF 1346 | FFFF 1347 | FFFF 1348 | FFFF 1349 | FFFF 1350 | FFFF 1351 | FFFF 1352 | E3E3 1353 | E3E3 1354 | E3E3 1355 | E3E3 1356 | FFFF 1357 | FFFF 1358 | FFFF 1359 | FFFF 1360 | FFFF 1361 | FFFF 1362 | FFFF 1363 | FFFF 1364 | AAAA 1365 | AAAA 1366 | AAAB 1367 | A8AF 1368 | 23BF 1369 | 80FF 1370 | 11D5 1371 | 15F5 1372 | FF80 1373 | 00FF 1374 | FFFF 1375 | FFFF 1376 | FF00 1377 | 00FF 1378 | FFFF 1379 | FFFF 1380 | FF00 1381 | 00FF 1382 | FFFF 1383 | FFFF 1384 | E3E3 1385 | E3E3 1386 | E3E3 1387 | E3E3 1388 | FFFF 1389 | FFFF 1390 | FEFE 1391 | FEFE 1392 | FFFF 1393 | FFFF 1394 | 22AA 1395 | AAAA 1396 | A0BF 1397 | 80FF 1398 | 22AA 1399 | AAAA 1400 | 05FD 1401 | 01FF 1402 | 23AB 1403 | ABAB 1404 | FFFF 1405 | FFFF 1406 | FFFF 1407 | FFFF 1408 | FFFF 1409 | FFFF 1410 | FFFF 1411 | FFFF 1412 | FFFF 1413 | FFFF 1414 | FFFF 1415 | FFFF 1416 | E0FF 1417 | FFFF 1418 | FFFF 1419 | FFFF 1420 | 00FF 1421 | FFFF 1422 | FFFF 1423 | FFFF 1424 | 88FF 1425 | FFFF 1426 | FFFF 1427 | FFFF 1428 | 8AFA 1429 | FAFA 1430 | FAFA 1431 | F8FF 1432 | ABAB 1433 | ABAB 1434 | ABAB 1435 | 8BFB 1436 | FFFF 1437 | FFFF 1438 | FFFF 1439 | FFFF 1440 | FFFF 1441 | FFFF 1442 | FFFF 1443 | FFFF 1444 | FFFF 1445 | FFFF 1446 | FFFF 1447 | FFFF 1448 | 1449 | Level 10: 1450 | 1451 | FFFF 1452 | FFFF 1453 | FFFF 1454 | FFFF 1455 | FFFF 1456 | FFFF 1457 | FFFF 1458 | FFFF 1459 | FFFF 1460 | FFFF 1461 | FFFF 1462 | FFFF 1463 | FFFF 1464 | FFFF 1465 | FFFF 1466 | FFFF 1467 | FFFF 1468 | FFFF 1469 | FFFF 1470 | FFFF 1471 | FFFF 1472 | FFFF 1473 | FFFF 1474 | FFFF 1475 | FFFF 1476 | FFFF 1477 | FFFF 1478 | FEFC 1479 | FFFF 1480 | FFFF 1481 | 8000 1482 | 007F 1483 | FFFF 1484 | FFFF 1485 | FFFF 1486 | FFFF 1487 | FFFF 1488 | FFFF 1489 | FFFF 1490 | FFFF 1491 | FFFF 1492 | FFFF 1493 | FFFF 1494 | FFFF 1495 | FFFF 1496 | FFFF 1497 | FFFF 1498 | FFFF 1499 | FFFF 1500 | FFFF 1501 | FFFF 1502 | FFFF 1503 | FFFF 1504 | FFFF 1505 | FFFF 1506 | FEFC 1507 | F8F1 1508 | E3C7 1509 | 8F1F 1510 | 3F7F 1511 | FFFF 1512 | FFFF 1513 | FFFF 1514 | FFFF 1515 | FDF9 1516 | F1E1 1517 | F1F9 1518 | FDFF 1519 | 0075 1520 | 4562 1521 | 4575 1522 | 00FF 1523 | 0077 1524 | 2222 1525 | 2272 1526 | 00FF 1527 | 7F7F 1528 | 7F7F 1529 | 7F7F 1530 | 7FFF 1531 | FFFF 1532 | FFFF 1533 | FFFF 1534 | FEFC 1535 | F8F1 1536 | E3C7 1537 | 8F1F 1538 | 3F7F 1539 | FFFF 1540 | FFFF 1541 | FFFF 1542 | FFFF 1543 | FFFF 1544 | FFFF 1545 | FFFF 1546 | FFFF 1547 | 0000 1548 | 00FF 1549 | FFFF 1550 | FFFF 1551 | 0000 1552 | 00FF 1553 | FFFF 1554 | FFFF 1555 | 0000 1556 | 00FF 1557 | FFFF 1558 | FFFF 1559 | 0000 1560 | 00FF 1561 | FFFF 1562 | FFFF 1563 | 0001 1564 | 03FF 1565 | FFFF 1566 | FFFF 1567 | FFFF 1568 | FFFF 1569 | FFFF 1570 | FFFF 1571 | FFFF 1572 | FFFF 1573 | FFFF 1574 | FFFF 1575 | FFFF 1576 | FFFF 1577 | FFFF 1578 | FFFF 1579 | 1580 | Level 11: 1581 | 1582 | 0000 1583 | 0000 1584 | 0000 1585 | 0000 1586 | 0000 1587 | 0000 1588 | 0000 1589 | 0000 1590 | 0000 1591 | 0000 1592 | 0057 1593 | 5575 1594 | 0000 1595 | 0000 1596 | 0050 1597 | 5050 1598 | 0000 1599 | 0000 1600 | 008B 1601 | 89A9 1602 | 0000 1603 | 0000 1604 | 00B2 1605 | 2A2A 1606 | 0000 1607 | 0000 1608 | 0000 1609 | 0000 1610 | 0000 1611 | 0000 1612 | 0000 1613 | 0000 1614 | 0000 1615 | 0000 1616 | 0000 1617 | 0000 1618 | 0000 1619 | 0000 1620 | 0000 1621 | 0000 1622 | 2527 1623 | 0000 1624 | 0000 1625 | 0000 1626 | 5070 1627 | 0000 1628 | 0000 1629 | 0000 1630 | A9FB 1631 | 0000 1632 | 0000 1633 | 0000 1634 | 28AA 1635 | 0000 1636 | 0000 1637 | 0000 1638 | 0000 1639 | 0000 1640 | 0000 1641 | 0000 1642 | 0000 1643 | 0000 1644 | 0000 1645 | 0000 1646 | 0000 1647 | 0000 1648 | 0000 1649 | 0000 1650 | 0702 1651 | 0202 1652 | 0200 1653 | 0000 1654 | 5755 1655 | 7755 1656 | 5500 1657 | 3A2A 1658 | 6555 1659 | 5655 1660 | 5500 1661 | 3A2A 1662 | 7040 1663 | 7010 1664 | 7000 1665 | BB92 1666 | EE8A 1667 | EA8A 1668 | 8E00 1669 | 3AA2 1670 | E0A0 1671 | C0A0 1672 | A000 1673 | 0000 1674 | 0000 1675 | 0000 1676 | 0000 1677 | 0000 1678 | 0000 1679 | 0000 1680 | 0000 1681 | 0000 1682 | 0000 1683 | 0000 1684 | 0000 1685 | 0000 1686 | 3A22 1687 | 2300 1688 | 0000 1689 | 0000 1690 | 3B29 1691 | A900 1692 | 0000 1693 | 0000 1694 | 9212 1695 | 3A00 1696 | 0000 1697 | 0000 1698 | AAA8 1699 | BA00 1700 | 0000 1701 | 0000 1702 | 0000 1703 | 0000 1704 | 0000 1705 | 0000 1706 | 0000 1707 | 0000 1708 | 0000 1709 | 0000 -------------------------------------------------------------------------------- /cavern/img/level0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level0.png -------------------------------------------------------------------------------- /cavern/img/level1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level1.png -------------------------------------------------------------------------------- /cavern/img/level10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level10.png -------------------------------------------------------------------------------- /cavern/img/level11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level11.png -------------------------------------------------------------------------------- /cavern/img/level2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level2.png -------------------------------------------------------------------------------- /cavern/img/level3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level3.png -------------------------------------------------------------------------------- /cavern/img/level4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level4.png -------------------------------------------------------------------------------- /cavern/img/level5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level5.png -------------------------------------------------------------------------------- /cavern/img/level6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level6.png -------------------------------------------------------------------------------- /cavern/img/level7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level7.png -------------------------------------------------------------------------------- /cavern/img/level8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level8.png -------------------------------------------------------------------------------- /cavern/img/level9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/cavern/img/level9.png -------------------------------------------------------------------------------- /chipquarium/README.md: -------------------------------------------------------------------------------- 1 | # Chipquarium 2 | A CHIP-8 fish tank simulator. 3 | 4 | Your mission is to keep your pet fish alive as long as possible. To do so, you 5 | will need to: 6 | * Make sure the tank is kept clean. 7 | * Make sure your fish never too hungry. 8 | * Make sure your fish is happy. 9 | 10 | If your fish is healthy and happy enough, he will eventually grow larger. But be 11 | sure your fish gets enough sleep! He will refuse to eat and play if he is too 12 | tired. 13 | 14 | Chipquarium was programmed using [Octo][1] assembly language as part of 15 | [Octo-ber Jam III][2]. 16 | 17 | ## Controls 18 | 19 | ### Browser 20 | Press the `V` key to feed your fish. 21 | 22 | Press the `4` key to clean the tank. 23 | 24 | Press the `R` key to have your fish sleep. 25 | 26 | Press the `C` key to play rock-paper-scissors with your fish. 27 | 28 | Press the `F` key to view your fish's stats. 29 | 30 | During the rock-paper-scissors minigame: 31 | 32 | Press the `2` key to cycle up through the options. 33 | 34 | Press the `S` key to cycle down through the options. 35 | 36 | ### COSMAC VIP 37 | Press the `F` key to feed your fish. 38 | 39 | Press the `C` key to clean the tank. 40 | 41 | Press the `D` key to have your fish sleep. 42 | 43 | Press the `B` key to play rock-paper-scissors with your fish. 44 | 45 | Press the `E` key to view your fish's stats. 46 | 47 | During the rock-paper-scissors minigame: 48 | 49 | Press the `2` key to cycle up through the options. 50 | 51 | Press the `8` key to cycle down through the options. 52 | 53 | ## Notes 54 | Chipquarium was written using the original CHIP-8 instruction set. As a result, 55 | it should run on the [COSMAC VIP][3] without any issues. 56 | 57 | ## License 58 | This project is licensed under the MIT License. For more information, see the 59 | included [LICENSE][4] file. 60 | 61 | [1]: http://github.com/JohnEarnest/Octo "JohnEarnest / Octo" 62 | [2]: http://www.awfuljams.com/octojam-iii/ "Octo-ber Jam III" 63 | [3]: http://en.wikipedia.org/wiki/COSMAC_VIP "COSMAC VIP" 64 | [4]: ../LICENSE "MIT License" 65 | -------------------------------------------------------------------------------- /chipquarium/chipquarium.8o: -------------------------------------------------------------------------------- 1 | # Chipquarium 2 | # Copyright 2016 Matthew Mikolay 3 | # For licensing info, please see accompanying LICENSE file. 4 | # See github.com/mattmikolay/chip-8 or mattmik.com for more info. 5 | 6 | :alias stat_poop vB # Tank dirtiness 7 | :alias state_val1 v0 # State-dependent value (use varies with game_state) 8 | :alias state_val2 v5 # State-dependent value (use varies with game_state) 9 | :alias game_state v4 # Game state 10 | :alias fish_level v6 # Fish level 11 | :alias fish_dir v7 # Direction of the fishy 12 | :alias fish_x v8 # x coordinate of the fishy 13 | :alias fish_y v9 # y coordinate of the fishy 14 | :alias scratch_1 v1 # Scratch register 1 15 | :alias scratch_2 v2 # Scratch register 2 16 | :alias event_timer v3 17 | :alias hunger_stat va 18 | :alias happy_stat vd 19 | :alias stamina_stat vc 20 | :alias health_stat ve 21 | 22 | :const LEVEL_SMALL 0x00 23 | :const LEVEL_MEDIUM 0x01 24 | :const LEVEL_LARGE 0x02 25 | :const LEVEL_VICTORY 0x03 26 | 27 | :const DIRECTION_LEFT 0x00 28 | :const DIRECTION_RIGHT 0x01 29 | 30 | :const STATE_SWIMMING 0x00 31 | :const STATE_FEEDING 0x01 32 | :const STATE_SLEEPING 0x02 33 | :const STATE_PLAYING 0x03 34 | :const STATE_RPSEND 0x06 35 | :const STATE_STATS 0x04 36 | :const STATE_DEAD 0x05 37 | 38 | :const MAX_HEALTH 255 39 | :const MAX_HUNGER 100 40 | :const MAX_STAMINA 0x64 41 | :const MAX_HAPPINESS 100 42 | 43 | :const GAME_ROCK 0x01 44 | :const GAME_PAPER 0x02 45 | :const GAME_SCISSORS 0x03 46 | 47 | : main 48 | 49 | # Display the title screen to the user 50 | draw_title_screen 51 | draw_ground 52 | scratch_1 := key 53 | draw_title_screen 54 | 55 | # Default to the swimming state 56 | game_state := STATE_SWIMMING 57 | 58 | # Event timer will begin at zero and count up 59 | event_timer := 0x00 60 | 61 | # Set stat defaults 62 | stat_poop := 0x00 63 | health_stat := MAX_HEALTH 64 | hunger_stat := 20 65 | happy_stat := 0x40 66 | stamina_stat := MAX_STAMINA 67 | 68 | # At the start, the fish should point toward the right 69 | fish_dir := DIRECTION_RIGHT 70 | 71 | # Begin with a small fish! 72 | fish_level := LEVEL_SMALL 73 | 74 | : event_loop 75 | 76 | # If fish health hits zero, the game is over 77 | if health_stat == 0x00 then 78 | end_game 79 | 80 | # If fish is level 3, the user has won 81 | if fish_level == LEVEL_VICTORY then 82 | jump win_game 83 | 84 | if game_state == STATE_SWIMMING begin 85 | 86 | # Choose a random x offset in [1,4] for the fish 87 | scratch_1 := random 0b00000011 88 | 89 | # If fish is facing right, increase x coordinate 90 | if fish_dir == DIRECTION_RIGHT begin 91 | fish_x += scratch_1 92 | fish_x += 1 93 | 94 | # If fish is facing left, decrease x coordinate 95 | else 96 | fish_x -= scratch_1 97 | fish_x += -1 98 | end 99 | 100 | # Choose a random y coordinate in [6,21] for the fish 101 | fish_y := random 0x0F 102 | fish_y += 6 103 | 104 | # Draw the fish sprite at the newly calculated position 105 | draw_fish 106 | 107 | end 108 | 109 | if game_state == STATE_SLEEPING begin 110 | 111 | i := sprite_sleep_bubbles_2 112 | sprite state_val1 state_val2 6 113 | 114 | scratch_2 += -1 115 | 116 | # If done sleeping... 117 | if scratch_2 == 0x00 begin 118 | 119 | # Erase sleeping bubbles 120 | i := sprite_sleep_bubbles_1 121 | sprite state_val1 state_val2 6 122 | 123 | # Return to swimming state 124 | game_state := STATE_SWIMMING 125 | 126 | end 127 | 128 | end 129 | 130 | if game_state == STATE_RPSEND begin 131 | 132 | # End the minigame 133 | if state_val2 == 0x00 begin 134 | 135 | # Clear screen and redraw ground, poop, and fish 136 | clear 137 | draw_ground 138 | draw_poop 139 | draw_fish 140 | 141 | # Transition to swimming state 142 | game_state := STATE_SWIMMING 143 | 144 | end 145 | 146 | # Decrease minigame timer 147 | state_val2 += -1 148 | 149 | end 150 | 151 | if game_state == STATE_PLAYING begin 152 | 153 | if state_val2 == 10 begin 154 | i := sprite_thinking_dots_1 155 | scratch_1 := 37 156 | scratch_2 := 11 157 | sprite scratch_1 scratch_2 1 158 | end 159 | 160 | if state_val2 == 8 begin 161 | i := sprite_thinking_dots_2 162 | scratch_1 := 37 163 | scratch_2 := 11 164 | sprite scratch_1 scratch_2 1 165 | end 166 | 167 | if state_val2 == 6 begin 168 | i := sprite_thinking_dots_3 169 | scratch_1 := 37 170 | scratch_2 := 11 171 | sprite scratch_1 scratch_2 1 172 | end 173 | 174 | # Decide the fish's move 175 | if state_val2 == 4 begin 176 | 177 | # Erase thinking dots 178 | i := sprite_thinking_dots_all 179 | scratch_1 := 37 180 | scratch_2 := 11 181 | sprite scratch_1 scratch_2 1 182 | 183 | # scratch_1 will store fish's selection, a random number in [1,3] 184 | scratch_1 := random 0x01 185 | scratch_2 := random 0x01 186 | scratch_1 += scratch_2 187 | scratch_1 += 0x01 188 | 189 | # Update fish stats based upon game outcome 190 | if state_val1 == GAME_SCISSORS begin 191 | 192 | if scratch_1 == GAME_PAPER then 193 | happy_stat += 2 194 | if scratch_1 == GAME_ROCK then 195 | happy_stat += -1 196 | 197 | end 198 | 199 | if state_val1 == GAME_ROCK begin 200 | 201 | if scratch_1 == GAME_PAPER then 202 | happy_stat += -1 203 | if scratch_1 == GAME_SCISSORS then 204 | happy_stat += 2 205 | 206 | end 207 | 208 | if state_val1 == GAME_PAPER begin 209 | 210 | if scratch_1 == GAME_SCISSORS then 211 | happy_stat += -1 212 | if scratch_1 == GAME_ROCK then 213 | happy_stat += 2 214 | 215 | end 216 | 217 | # Confirm happiness is within bounds 218 | if happy_stat == 255 then 219 | happy_stat := 0x00 220 | state_val1 := MAX_HAPPINESS 221 | state_val1 -= happy_stat 222 | if vf == 0x00 then 223 | happy_stat := MAX_HAPPINESS 224 | 225 | load_rps_sprite 226 | 227 | # Temporarily use state_val1 to save fish's selection 228 | state_val1 := scratch_1 229 | 230 | # Draw fish's selection 231 | scratch_1 := 36 232 | scratch_2 := 8 233 | sprite scratch_1 scratch_2 7 234 | 235 | # If fish chose scissors, the scissors image consists of two sprites 236 | if state_val1 == GAME_SCISSORS begin 237 | scratch_1 := 44 238 | i := sprite_scissors_2 239 | sprite scratch_1 scratch_2 6 240 | end 241 | 242 | game_state := STATE_RPSEND 243 | 244 | end 245 | 246 | # Decrease minigame timer 247 | state_val2 += -1 248 | 249 | end 250 | 251 | if game_state == STATE_FEEDING begin 252 | 253 | # scratch_1 will store x offset of fish, moving in direction of food 254 | # scratch_2 will store y offset of fish, moving in direction of food 255 | scratch_1 := 0x00 256 | scratch_2 := 0x00 257 | 258 | # If fish is not at top of screen, move fish closer to food vertically 259 | if fish_y != 0x06 then 260 | scratch_2 := -1 261 | 262 | # If fish's x coordinate does not equal the x coordinate of the food... 263 | if fish_x != state_val1 begin 264 | 265 | # Move fish closer to food horizontally 266 | scratch_1 := fish_x 267 | scratch_1 =- state_val1 268 | scratch_1 := vf 269 | if scratch_1 == 0 then 270 | scratch_1 := -1 271 | 272 | end 273 | 274 | # Erase the fish sprite at its current location 275 | draw_fish 276 | 277 | fish_x += scratch_1 278 | fish_y += scratch_2 279 | 280 | # Update fish's direction based upon where it's moving 281 | fish_dir := DIRECTION_LEFT 282 | if scratch_1 == 0x01 then 283 | fish_dir := DIRECTION_RIGHT 284 | 285 | draw_fish 286 | 287 | # If both x and y offset of the fish equal zero 288 | scratch_1 |= scratch_2 289 | if scratch_1 == 0x00 begin 290 | 291 | # Erase food sprite and return to swimming state 292 | i := sprite_food 293 | sprite state_val1 state_val2 6 294 | game_state := STATE_SWIMMING 295 | 296 | end 297 | 298 | end 299 | 300 | scratch_1 := 30 301 | delay := scratch_1 302 | 303 | loop 304 | 305 | check_key 306 | 307 | scratch_1 := delay 308 | while scratch_1 != 0x00 309 | again 310 | 311 | if game_state == STATE_SWIMMING begin 312 | 313 | # Erase the fish sprite at its current location 314 | draw_fish 315 | 316 | update_direction 317 | 318 | # Increment the event timer 319 | event_timer += 0x01 320 | check_event_timer 321 | 322 | end 323 | 324 | jump event_loop 325 | 326 | : win_game 327 | clear 328 | draw_win_screen 329 | : idle 330 | jump idle 331 | 332 | ########################################################################## 333 | # Checks the event timer and updates accordingly. The fish's stats and the 334 | # tank's dirtiness are updated as time passes. 335 | ########################################################################## 336 | : check_event_timer 337 | 338 | # Level up if happiness stat is high enough and enough game time has passed 339 | if event_timer == 0x00 begin 340 | 341 | # If happy_stat > 72 342 | scratch_1 := 72 343 | scratch_1 -= happy_stat 344 | if vf == 0x00 then 345 | if fish_level != LEVEL_VICTORY then 346 | fish_level += 0x01 347 | 348 | end 349 | 350 | # Decrease stamina 351 | scratch_1 := 0x02 352 | stamina_stat -= scratch_1 353 | if vf == 0 then 354 | stamina_stat := 0x00 355 | 356 | # Increase hunger 357 | if hunger_stat != MAX_HUNGER then 358 | hunger_stat += 0x01 359 | 360 | # Decrease health and happiness if fish is too hungry (hunger > 80) 361 | scratch_1 := 80 362 | scratch_1 =- hunger_stat 363 | if vf == 0x01 begin 364 | 365 | if health_stat != 0x00 then 366 | health_stat += -1 367 | 368 | if happy_stat != 0x00 then 369 | happy_stat += -1 370 | 371 | end 372 | 373 | # Decrease health and happiness if tank is too dirty (more than five poops) 374 | scratch_1 := 0b11111000 375 | scratch_1 &= stat_poop 376 | if scratch_1 == 0b11111000 begin 377 | 378 | if health_stat != 0x00 then 379 | health_stat += -1 380 | 381 | if happy_stat != 0x00 then 382 | happy_stat += -1 383 | 384 | end 385 | 386 | # Event: Add a poop to the bottom of the tank 387 | if stat_poop != 0b11111111 begin 388 | scratch_1 := 0b00001111 389 | scratch_1 &= event_timer 390 | if scratch_1 == 0b0001111 begin 391 | 392 | draw_poop 393 | 394 | stat_poop >>= stat_poop 395 | stat_poop += 0b10000000 396 | 397 | draw_poop 398 | 399 | end 400 | end 401 | 402 | return 403 | 404 | ############################################################## 405 | # Checks if a key has been pressed and handles it accordingly. 406 | ############################################################## 407 | : check_key 408 | 409 | if game_state == STATE_SWIMMING begin 410 | 411 | # Play minigame if 'B' key is pressed 412 | scratch_2 := 0x0B 413 | if scratch_2 key begin 414 | 415 | # The fish cannot play if stamina is zero 416 | if stamina_stat == 0x00 then 417 | return 418 | 419 | draw_fish 420 | 421 | # Move the fish to the right edge of the screen, facing left 422 | fish_x := 48 423 | fish_y := 16 424 | fish_dir := DIRECTION_LEFT 425 | 426 | draw_fish 427 | 428 | draw_minigame_field 429 | 430 | # state_val1 will store user's rock/paper/scissors selection 431 | state_val1 := GAME_ROCK 432 | draw_rps_selection 433 | 434 | # state_val2 will store time until the fish decides 435 | state_val2 := 14 436 | 437 | # Transition to play state 438 | game_state := STATE_PLAYING 439 | 440 | end 441 | 442 | # Clean tank if 'C' key is pressed 443 | scratch_2 := 0x0C 444 | if scratch_2 key begin 445 | 446 | # Clean a single poop 447 | draw_poop 448 | stat_poop <<= stat_poop 449 | draw_poop 450 | 451 | return 452 | 453 | end 454 | 455 | # Sleep if 'D' key is pressed 456 | scratch_2 := 0x0D 457 | if scratch_2 key begin 458 | 459 | # state_val1 will temporarily store bubbles x 460 | state_val1 := fish_x 461 | state_val1 += -1 462 | 463 | # Shift bubbles to the right if the fish is facing right 464 | if fish_dir == DIRECTION_RIGHT begin 465 | 466 | state_val1 += 6 467 | 468 | # Adjust bubble x based upon fish width 469 | if fish_level == LEVEL_MEDIUM then 470 | state_val1 += 4 471 | if fish_level == LEVEL_LARGE then 472 | state_val1 += 10 473 | 474 | end 475 | 476 | # state_val2 will temporarily store bubbles y 477 | state_val2 := fish_y 478 | state_val2 += -6 479 | 480 | # Draw sleep bubbles above the fish 481 | i := sprite_sleep_bubbles_1 482 | sprite state_val1 state_val2 6 483 | 484 | # Transition to sleeping state and reset stamina 485 | game_state := STATE_SLEEPING 486 | stamina_stat := MAX_STAMINA 487 | 488 | # Use scratch_2 to keep track of how long to stay sleeping 489 | scratch_2 := 0x0A 490 | 491 | return 492 | 493 | end 494 | 495 | # Show stats if 'E' key is pressed 496 | scratch_2 := 0x0E 497 | if scratch_2 key begin 498 | 499 | # Transition to stats display state 500 | game_state := STATE_STATS 501 | 502 | clear 503 | draw_stats_text 504 | 505 | return 506 | 507 | end 508 | 509 | # Feed fish if 'F' key is pressed 510 | scratch_2 := 0x0F 511 | if scratch_2 key begin 512 | 513 | # The fish cannot be fed if stamina is zero 514 | if stamina_stat == 0x00 then 515 | return 516 | 517 | # Choose random x location in [16, 47] for fish food 518 | # state_val1 and state_val2 will temporarily store food x and y 519 | state_val1 := random 0b11111 520 | state_val1 += 16 521 | state_val2 := 0x00 522 | 523 | i := sprite_food 524 | sprite state_val1 state_val2 6 525 | 526 | # Transition to feeding state and reset hunger 527 | game_state := STATE_FEEDING 528 | hunger_stat := 0x00 529 | 530 | return 531 | 532 | end 533 | 534 | end 535 | 536 | if game_state == STATE_STATS begin 537 | 538 | # Wait for any key press to leave the stats screen 539 | scratch_1 := key 540 | 541 | # Clear screen and redraw ground, poop, and fish 542 | clear 543 | draw_ground 544 | draw_poop 545 | draw_fish 546 | 547 | # Transition to swimming state 548 | game_state := STATE_SWIMMING 549 | 550 | end 551 | 552 | if game_state == STATE_PLAYING begin 553 | 554 | # Navigate up among possible rock/paper/scissors options 555 | scratch_2 := 0x02 556 | if scratch_2 key begin 557 | 558 | draw_rps_selection 559 | 560 | state_val1 += 1 561 | if state_val1 == 0x04 then 562 | state_val1 := GAME_ROCK 563 | 564 | draw_rps_selection 565 | 566 | end 567 | 568 | # Navigate down among possible rock/paper/scissors options 569 | scratch_2 := 0x08 570 | if scratch_2 key begin 571 | 572 | draw_rps_selection 573 | 574 | state_val1 += -1 575 | if state_val1 == 0x00 then 576 | state_val1 := GAME_SCISSORS 577 | 578 | draw_rps_selection 579 | 580 | end 581 | 582 | end 583 | 584 | return 585 | 586 | ########################################################################## 587 | # Updates the fish's direction, if the fish has hit one of the boundaries. 588 | ########################################################################## 589 | : update_direction 590 | 591 | # Check for fish at right edge of screen 592 | scratch_1 := fish_x 593 | scratch_1 += 16 594 | scratch_2 := 0b11000000 595 | scratch_1 &= scratch_2 596 | if scratch_1 != 0x00 then 597 | fish_dir := DIRECTION_LEFT 598 | 599 | # Check for fish at left edge of screen 600 | scratch_1 := fish_x 601 | scratch_2 := 0b11111000 602 | scratch_1 &= scratch_2 603 | if scratch_1 == 0x00 then 604 | fish_dir := DIRECTION_RIGHT 605 | 606 | return 607 | 608 | ########################################################################### 609 | # Ends the game, preventing further user interaction. Rest in peace, fishy. 610 | ########################################################################### 611 | : end_game 612 | 613 | # If the fish has already gone to fishy heaven, there's nothing to do 614 | if game_state == STATE_DEAD then 615 | return 616 | 617 | game_state := STATE_DEAD 618 | 619 | # Draw an upside-down fish at the top of the tank 620 | fish_y := 0x00 621 | fish_dir := DIRECTION_RIGHT 622 | draw_flipped_fish 623 | 624 | # Draw a RIP message 625 | i := sprite_rip_1 626 | scratch_1 := 52 627 | scratch_2 := 23 628 | sprite scratch_1 scratch_2 5 629 | i := sprite_rip_2 630 | scratch_1 := 60 631 | sprite scratch_1 scratch_2 5 632 | 633 | return 634 | 635 | ############################################################################# 636 | # Draws the rock/paper/scissors minigame field. The field consists of a box 637 | # indicating the user's selection; up and down arrows; and the fish's thought 638 | # bubble. 639 | ############################################################################# 640 | : draw_minigame_field 641 | 642 | scratch_1 := 8 643 | scratch_2 := 10 644 | 645 | # Draw left half of box indicating user's selection 646 | i := sprite_box_left 647 | sprite scratch_1 scratch_2 11 648 | 649 | # Draw right half of box indicating user's selection 650 | scratch_1 := 16 651 | i := sprite_box_right 652 | sprite scratch_1 scratch_2 11 653 | 654 | # Draw up arrow 655 | scratch_1 := 12 656 | scratch_2 := 6 657 | i := sprite_up_arrow 658 | sprite scratch_1 scratch_2 3 659 | 660 | # Draw down arrow 661 | scratch_2 := 22 662 | i := sprite_down_arrow 663 | sprite scratch_1 scratch_2 3 664 | 665 | # Draw left half of the fish's thought bubble 666 | scratch_1 := 34 667 | scratch_2 := 6 668 | i := sprite_bubble_left 669 | sprite scratch_1 scratch_2 11 670 | 671 | # Draw right half of the fish's thought bubble 672 | scratch_1 := 42 673 | i := sprite_bubble_right 674 | sprite scratch_1 scratch_2 12 675 | 676 | return 677 | 678 | ############################################################################## 679 | # Draws the sprite corresponding to the user's selection at this moment in the 680 | # rock/paper/scissors minigame. 681 | ############################################################################## 682 | : draw_rps_selection 683 | 684 | scratch_1 := state_val1 685 | load_rps_sprite 686 | 687 | scratch_1 := 10 688 | scratch_2 := 12 689 | sprite scratch_1 scratch_2 7 690 | 691 | # The scissors image consists of two sprites 692 | if state_val1 == GAME_SCISSORS begin 693 | scratch_1 := 18 694 | i := sprite_scissors_2 695 | sprite scratch_1 scratch_2 6 696 | end 697 | 698 | return 699 | 700 | ############################################################################### 701 | # Loads the i register with the sprite corresponding to the user's selection at 702 | # this moment in the rock/paper/scissors minigame. 703 | ############################################################################### 704 | : load_rps_sprite 705 | i := sprite_rock 706 | if scratch_1 == GAME_SCISSORS then 707 | i := sprite_scissors_1 708 | if scratch_1 == GAME_PAPER then 709 | i := sprite_paper 710 | return 711 | 712 | ######################### 713 | # Draws the title screen. 714 | ######################### 715 | : draw_title_screen 716 | 717 | scratch_1 := 0 718 | scratch_2 := 4 719 | state_val1 := 4 720 | 721 | i := title_screen_data 722 | 723 | loop 724 | 725 | sprite scratch_1 scratch_2 4 726 | scratch_1 += 8 727 | if scratch_1 == 64 begin 728 | scratch_1 := 0 729 | scratch_2 += 4 730 | end 731 | 732 | i += state_val1 733 | 734 | if scratch_2 != 28 then 735 | again 736 | 737 | return 738 | 739 | ########################### 740 | # Draws the victory screen. 741 | ########################### 742 | : draw_win_screen 743 | 744 | scratch_1 := 0 745 | scratch_2 := 0 746 | state_val1 := 8 747 | 748 | i := win_screen_data 749 | 750 | loop 751 | 752 | sprite scratch_1 scratch_2 8 753 | scratch_1 += 8 754 | if scratch_1 == 64 begin 755 | scratch_1 := 0 756 | scratch_2 += 8 757 | end 758 | 759 | i += state_val1 760 | 761 | if scratch_2 != 32 then 762 | again 763 | 764 | return 765 | 766 | #################################### 767 | # Draws the bottom of the fish tank. 768 | #################################### 769 | : draw_ground 770 | 771 | i := sprite_ground 772 | 773 | scratch_2 := 31 774 | scratch_1 := 0 775 | 776 | loop 777 | sprite scratch_1 scratch_2 1 778 | scratch_1 += 8 779 | if scratch_1 != 64 then 780 | again 781 | return 782 | 783 | ############################################################ 784 | # Draws a row of fish droppings at the bottom of the screen. 785 | ############################################################ 786 | : draw_poop 787 | 788 | i := sprite_poop 789 | 790 | # x coordinate of poop sprite 791 | state_val1 := 0 792 | 793 | # y coordinate of poop sprite 794 | state_val2 := 29 795 | 796 | scratch_1 := stat_poop 797 | 798 | loop 799 | 800 | scratch_1 <<= scratch_1 801 | if vF != 0x00 then 802 | sprite state_val1 state_val2 2 803 | 804 | state_val1 += 8 805 | 806 | if scratch_1 != 0x00 then 807 | again 808 | 809 | return 810 | 811 | ######################################################## 812 | # Draws the fish sprite on the screen at fish_x, fish_y. 813 | # The fish's size will depend upon its level. 814 | ######################################################## 815 | : draw_fish 816 | 817 | if fish_level == LEVEL_SMALL then 818 | draw_small_fish 819 | if fish_level == LEVEL_MEDIUM then 820 | draw_medium_fish 821 | if fish_level == LEVEL_LARGE then 822 | draw_large_fish 823 | 824 | return 825 | 826 | ################################################################### 827 | # Draws an upside-down fish sprite on the screen at fish_x, fish_y. 828 | # The fish's size will depend upon its level. 829 | ################################################################### 830 | : draw_flipped_fish 831 | 832 | if fish_level == LEVEL_SMALL then 833 | draw_small_fish 834 | if fish_level == LEVEL_MEDIUM then 835 | draw_medium_flipped_fish 836 | if fish_level == LEVEL_LARGE then 837 | draw_large_flipped_fish 838 | 839 | return 840 | 841 | ####################################################### 842 | # Draws text describing the fish's stats on the screen. 843 | ####################################################### 844 | : draw_stats_text 845 | 846 | scratch_2 := 4 847 | 848 | i := sprite_hunger_text_1 849 | sprite scratch_2 scratch_2 5 850 | 851 | scratch_1 := 12 852 | i := sprite_hunger_text_2 853 | sprite scratch_1 scratch_2 5 854 | 855 | scratch_1 := 20 856 | i := sprite_hunger_text_3 857 | sprite scratch_1 scratch_2 5 858 | 859 | scratch_2 := 13 860 | 861 | scratch_1 := 4 862 | i := sprite_happy_text_1 863 | sprite scratch_1 scratch_2 5 864 | 865 | scratch_1 := 12 866 | i := sprite_happy_text_2 867 | sprite scratch_1 scratch_2 5 868 | 869 | scratch_1 := 20 870 | i := sprite_happy_text_3 871 | sprite scratch_1 scratch_2 5 872 | 873 | scratch_2 := 22 874 | 875 | scratch_1 := 4 876 | i := sprite_stamina_text_1 877 | sprite scratch_1 scratch_2 5 878 | 879 | scratch_1 := 12 880 | i := sprite_stamina_text_2 881 | sprite scratch_1 scratch_2 5 882 | 883 | scratch_1 := 20 884 | i := sprite_stamina_text_3 885 | sprite scratch_1 scratch_2 5 886 | 887 | scratch_1 := 28 888 | i := sprite_stamina_text_4 889 | sprite scratch_1 scratch_2 5 890 | 891 | # Store BCD of hunger stat 892 | i := bcd_address_1 893 | scratch_1 := hunger_stat 894 | bcd scratch_1 895 | 896 | i := bcd_address_1 897 | load v0 898 | i := hex v0 899 | 900 | scratch_1 := 46 901 | scratch_2 := 4 902 | sprite scratch_1 scratch_2 5 903 | 904 | i := bcd_address_2 905 | load v0 906 | i := hex v0 907 | 908 | scratch_1 := 51 909 | sprite scratch_1 scratch_2 5 910 | 911 | i := bcd_address_3 912 | load v0 913 | i := hex v0 914 | 915 | scratch_1 := 56 916 | sprite scratch_1 scratch_2 5 917 | 918 | # Store BCD of happy stat 919 | i := bcd_address_1 920 | scratch_1 := happy_stat 921 | bcd scratch_1 922 | 923 | i := bcd_address_1 924 | load v0 925 | i := hex v0 926 | 927 | scratch_1 := 46 928 | scratch_2 := 13 929 | sprite scratch_1 scratch_2 5 930 | 931 | i := bcd_address_2 932 | load v0 933 | i := hex v0 934 | 935 | scratch_1 := 51 936 | sprite scratch_1 scratch_2 5 937 | 938 | i := bcd_address_3 939 | load v0 940 | i := hex v0 941 | 942 | scratch_1 := 56 943 | sprite scratch_1 scratch_2 5 944 | 945 | # Store BCD of stamina stat 946 | i := bcd_address_1 947 | scratch_1 := stamina_stat 948 | bcd scratch_1 949 | 950 | i := bcd_address_1 951 | load v0 952 | i := hex v0 953 | 954 | scratch_1 := 46 955 | scratch_2 := 22 956 | sprite scratch_1 scratch_2 5 957 | 958 | i := bcd_address_2 959 | load v0 960 | i := hex v0 961 | 962 | scratch_1 := 51 963 | sprite scratch_1 scratch_2 5 964 | 965 | i := bcd_address_3 966 | load v0 967 | i := hex v0 968 | 969 | scratch_1 := 56 970 | sprite scratch_1 scratch_2 5 971 | 972 | return 973 | 974 | ######################################################## 975 | # Draws a small fish sprite on screen at fish_x, fish_y. 976 | ######################################################## 977 | : draw_small_fish 978 | 979 | i := sprite_small_fish_left 980 | if fish_dir == DIRECTION_RIGHT then 981 | i := sprite_small_fish_right 982 | 983 | sprite fish_x fish_y 3 984 | return 985 | 986 | ######################################################### 987 | # Draws a medium fish sprite on screen at fish_x, fish_y. 988 | ######################################################### 989 | : draw_medium_fish 990 | 991 | i := sprite_medium_fish_left 992 | if fish_dir == DIRECTION_RIGHT then 993 | i := sprite_medium_fish_right 994 | 995 | sprite fish_x fish_y 4 996 | return 997 | 998 | ##################################################################### 999 | # Draws a medium upside-down fish sprite on screen at fish_x, fish_y. 1000 | ##################################################################### 1001 | : draw_medium_flipped_fish 1002 | i := sprite_medium_flipped_fish 1003 | sprite fish_x fish_y 4 1004 | return 1005 | 1006 | ######################################################## 1007 | # Draws a large fish sprite on screen at fish_x, fish_y. 1008 | ######################################################## 1009 | : draw_large_fish 1010 | 1011 | # Draw the left half of the large fish sprite 1012 | i := sprite_large_fish_1_left 1013 | if fish_dir == DIRECTION_RIGHT then 1014 | i := sprite_large_fish_1_right 1015 | sprite fish_x fish_y 8 1016 | 1017 | fish_x += 8 1018 | 1019 | # Draw the right half of the large fish sprite 1020 | i := sprite_large_fish_2_left 1021 | if fish_dir == DIRECTION_RIGHT then 1022 | i := sprite_large_fish_2_right 1023 | sprite fish_x fish_y 8 1024 | 1025 | fish_x += -8 1026 | 1027 | return 1028 | 1029 | #################################################################### 1030 | # Draws a large upside-down fish sprite on screen at fish_x, fish_y. 1031 | #################################################################### 1032 | : draw_large_flipped_fish 1033 | 1034 | # Draw the left half of the large fish sprite 1035 | i := sprite_large_flipped_fish_1 1036 | sprite fish_x fish_y 6 1037 | 1038 | fish_x += 8 1039 | 1040 | # Draw the right half of the large fish sprite 1041 | i := sprite_large_flipped_fish_2 1042 | sprite fish_x fish_y 6 1043 | 1044 | return 1045 | 1046 | : sprite_ground 1047 | 0b11111111 1048 | 1049 | : sprite_poop 1050 | 0b00011000 1051 | 0b00111100 1052 | 1053 | : sprite_food 1054 | 0b10000000 1055 | 0b00010000 1056 | 0b01000000 1057 | 0b00001000 1058 | 0b10000000 1059 | 0b00100000 1060 | 1061 | : sprite_sleep_bubbles_1 1062 | 0b10000000 1063 | 0b00000000 1064 | 0b10000000 1065 | 0b00000000 1066 | 0b10000000 1067 | 0b00000000 1068 | 1069 | : sprite_sleep_bubbles_2 1070 | 0b10000000 1071 | 0b10000000 1072 | 0b10000000 1073 | 0b10000000 1074 | 0b10000000 1075 | 0b10000000 1076 | 1077 | : sprite_small_fish_left 1078 | 0b01101000 1079 | 0b11110000 1080 | 0b01101000 1081 | 1082 | : sprite_small_fish_right 1083 | 0b10110000 1084 | 0b01111000 1085 | 0b10110000 1086 | 1087 | : sprite_medium_fish_left 1088 | 0b01111011 1089 | 0b10111110 1090 | 0b11111110 1091 | 0b01111011 1092 | 1093 | : sprite_medium_fish_right 1094 | 0b11011110 1095 | 0b01111101 1096 | 0b01111111 1097 | 0b11011110 1098 | 1099 | : sprite_medium_flipped_fish 1100 | 0b11011110 1101 | 0b01111111 1102 | 0b01111111 1103 | 0b11011110 1104 | 1105 | : sprite_large_fish_1_left 1106 | 0b01110000 1107 | 0b10001000 1108 | 0b10011111 1109 | 0b00111111 1110 | 0b00101111 1111 | 0b00111111 1112 | 0b00000011 1113 | 0b00011111 1114 | 1115 | : sprite_large_fish_2_left 1116 | 0b00000000 1117 | 0b00000000 1118 | 0b10000000 1119 | 0b11011000 1120 | 0b11110000 1121 | 0b11100000 1122 | 0b11010000 1123 | 0b10011000 1124 | 1125 | : sprite_large_fish_1_right 1126 | 0b00000000 1127 | 0b00000000 1128 | 0b00001111 1129 | 0b11011111 1130 | 0b01111111 1131 | 0b00111111 1132 | 0b01011110 1133 | 0b11001111 1134 | 1135 | : sprite_large_fish_2_right 1136 | 0b01110000 1137 | 0b10001000 1138 | 0b11001000 1139 | 0b11100000 1140 | 0b10100000 1141 | 0b11100000 1142 | 0b00000000 1143 | 0b11000000 1144 | 1145 | : sprite_large_flipped_fish_1 1146 | 0b11001111 1147 | 0b01011110 1148 | 0b00111111 1149 | 0b01111111 1150 | 0b11011111 1151 | 0b00001111 1152 | 1153 | : sprite_large_flipped_fish_2 1154 | 0b11000000 1155 | 0b00000000 1156 | 0b11100000 1157 | 0b11100000 1158 | 0b11100000 1159 | 0b11000000 1160 | 1161 | : sprite_rip_1 1162 | 0b11001110 1163 | 0b10100100 1164 | 0b11000100 1165 | 0b10100100 1166 | 0b10101110 1167 | 1168 | : sprite_rip_2 1169 | 0b11100000 1170 | 0b10100000 1171 | 0b11100000 1172 | 0b10000000 1173 | 0b10000000 1174 | 1175 | : sprite_hunger_text_1 1176 | 0b10101010 1177 | 0b10101010 1178 | 0b11101010 1179 | 0b10101010 1180 | 0b10101110 1181 | 1182 | : sprite_hunger_text_2 1183 | 0b11001110 1184 | 0b10101000 1185 | 0b10101010 1186 | 0b10101010 1187 | 0b10101110 1188 | 1189 | : sprite_hunger_text_3 1190 | 0b11101100 1191 | 0b10001010 1192 | 0b11001100 1193 | 0b10001010 1194 | 0b11101010 1195 | 1196 | : sprite_happy_text_1 1197 | 0b10101110 1198 | 0b10101010 1199 | 0b11101110 1200 | 0b10101010 1201 | 0b10101010 1202 | 1203 | : sprite_happy_text_2 1204 | 0b11101110 1205 | 0b10101010 1206 | 0b11101110 1207 | 0b10001000 1208 | 0b10001000 1209 | 1210 | : sprite_happy_text_3 1211 | 0b10100000 1212 | 0b10100000 1213 | 0b11100000 1214 | 0b01000000 1215 | 0b01000000 1216 | 1217 | : sprite_stamina_text_1 1218 | 0b11101110 1219 | 0b10000100 1220 | 0b11100100 1221 | 0b00100100 1222 | 0b11100100 1223 | 1224 | : sprite_stamina_text_2 1225 | 0b11101111 1226 | 0b10101010 1227 | 0b11101010 1228 | 0b10101010 1229 | 0b10101010 1230 | 1231 | : sprite_stamina_text_3 1232 | 0b10111011 1233 | 0b10010010 1234 | 0b10010010 1235 | 0b10010010 1236 | 0b10111010 1237 | 1238 | : sprite_stamina_text_4 1239 | 0b00111000 1240 | 0b10101000 1241 | 0b10111000 1242 | 0b10101000 1243 | 0b10101000 1244 | 1245 | : sprite_up_arrow 1246 | 0b00100000 1247 | 0b01110000 1248 | 0b11111000 1249 | 1250 | : sprite_down_arrow 1251 | 0b11111000 1252 | 0b01110000 1253 | 0b00100000 1254 | 1255 | : sprite_rock 1256 | 0b00000000 1257 | 0b00011100 1258 | 0b00111110 1259 | 0b01111111 1260 | 0b01111111 1261 | 0b00111110 1262 | 0b00000000 1263 | 1264 | : sprite_paper 1265 | 0b01111110 1266 | 0b01001011 1267 | 0b01001001 1268 | 0b01001111 1269 | 0b01000001 1270 | 0b01000001 1271 | 0b01111111 1272 | 1273 | : sprite_scissors_1 1274 | 0b01000011 1275 | 0b10100111 1276 | 0b01101100 1277 | 0b00010000 1278 | 0b01101100 1279 | 0b10100111 1280 | 0b01000011 1281 | 1282 | : sprite_scissors_2 1283 | 0b00000000 1284 | 0b10000000 1285 | 0b00000000 1286 | 0b00000000 1287 | 0b00000000 1288 | 0b10000000 1289 | 1290 | : sprite_bubble_left 1291 | 0b01111111 1292 | 0b10000000 1293 | 0b10000000 1294 | 0b10000000 1295 | 0b10000000 1296 | 0b10000000 1297 | 0b10000000 1298 | 0b10000000 1299 | 0b10000000 1300 | 0b10000000 1301 | 0b01111111 1302 | 1303 | : sprite_bubble_right 1304 | 0b11110000 1305 | 0b00001000 1306 | 0b00001000 1307 | 0b00001000 1308 | 0b00001000 1309 | 0b00001000 1310 | 0b00001000 1311 | 0b00001000 1312 | 0b00001000 1313 | 0b00001000 1314 | 0b11110000 1315 | 0b00111000 1316 | 1317 | : sprite_box_left 1318 | 0b11111111 1319 | 0b10000000 1320 | 0b10000000 1321 | 0b10000000 1322 | 0b10000000 1323 | 0b10000000 1324 | 0b10000000 1325 | 0b10000000 1326 | 0b10000000 1327 | 0b10000000 1328 | 0b11111111 1329 | 1330 | : sprite_box_right 1331 | 0b11111000 1332 | 0b00001000 1333 | 0b00001000 1334 | 0b00001000 1335 | 0b00001000 1336 | 0b00001000 1337 | 0b00001000 1338 | 0b00001000 1339 | 0b00001000 1340 | 0b00001000 1341 | 0b11111000 1342 | 1343 | : sprite_thinking_dots_1 1344 | 0b10000000 1345 | 1346 | : sprite_thinking_dots_2 1347 | 0b00010000 1348 | 1349 | : sprite_thinking_dots_3 1350 | 0b00000010 1351 | 1352 | : sprite_thinking_dots_all 1353 | 0b10010010 1354 | 1355 | : title_screen_data 1356 | 0x03 0x04 0x05 0x05 0xFF 0x2A 0xAB 0xE3 1357 | 0xFF 0x21 0x6D 0x6D 0xFF 0x0B 0x6B 0x6B 1358 | 0xFF 0x66 0x5A 0x5A 0xFF 0x31 0xDB 0xDB 1359 | 0xFF 0x68 0x6A 0x6A 0xC0 0x20 0xA0 0xA0 1360 | 0x05 0x05 0x04 0x03 0xEB 0xAB 0x2A 0xFF 1361 | 0x61 0x6F 0x2F 0xFF 0x6B 0x5B 0x28 0xFF 1362 | 0x42 0x5A 0x5A 0xFF 0x3B 0xDB 0xD1 0xFF 1363 | 0x6A 0x6A 0x0A 0xFF 0xA0 0xA0 0xA0 0xC0 1364 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1365 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1366 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1367 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1368 | 0x03 0x02 0x03 0x02 0xB3 0xAA 0xB3 0x2A 1369 | 0xBB 0x22 0x3B 0x08 0x81 0x02 0x83 0x82 1370 | 0x32 0xAA 0xAB 0xA9 0x82 0x82 0x83 0x02 1371 | 0xBA 0xA2 0x33 0xA1 0x80 0x80 0x80 0x00 1372 | 0x02 0x00 0x00 0x00 0x2B 0x00 0x00 0x00 1373 | 0xBB 0x00 0x00 0x3B 0x82 0x00 0x00 0x83 1374 | 0xA9 0x00 0x00 0xA1 0x02 0x00 0x00 0x28 1375 | 0xB9 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1376 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1377 | 0x12 0x12 0x12 0x13 0x82 0x83 0x82 0x82 1378 | 0xA2 0xA3 0x22 0x3A 0xA8 0xB8 0x90 0x90 1379 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1380 | 1381 | : win_screen_data 1382 | 0x00 0x00 0x00 0x57 0x55 0x75 0x25 0x27 1383 | 0x00 0x00 0x00 0x51 0x51 0x51 0x51 0x71 1384 | 0x00 0x00 0x00 0x17 0x52 0x52 0x52 0xF7 1385 | 0x00 0x00 0x00 0x64 0x54 0x54 0x50 0x54 1386 | 0x00 0x00 0x00 0x01 0x07 0x1C 0x30 0x60 1387 | 0x03 0x1E 0x70 0xC0 0x00 0x00 0x00 0x78 1388 | 0xF0 0x00 0x00 0x01 0x00 0x00 0x00 0x00 1389 | 0x00 0x00 0x00 0x00 0x80 0x40 0x40 0x20 1390 | 0x00 0x00 0x00 0x00 0x75 0x25 0x27 0x25 1391 | 0x00 0x00 0x00 0x00 0x26 0x55 0x75 0x55 1392 | 0x00 0x00 0x00 0x00 0x57 0x54 0x67 0x51 1393 | 0x00 0x01 0x03 0x02 0x04 0x04 0x04 0x03 1394 | 0xC0 0x80 0x00 0x80 0x00 0x00 0x00 0x00 1395 | 0xCC 0x84 0x84 0xCC 0x78 0x00 0x00 0x00 1396 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 1397 | 0x20 0x20 0x40 0x40 0x40 0x80 0x80 0x00 1398 | 0x25 0x00 0x07 0x04 0x07 0x04 0x04 0x00 1399 | 0x55 0x00 0x76 0x55 0x56 0x55 0x75 0x00 1400 | 0x57 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1401 | 0x00 0x06 0x05 0x04 0x04 0x06 0x02 0x03 1402 | 0x80 0x78 0x04 0xF8 0x00 0x00 0x00 0x00 1403 | 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 1404 | 0x02 0x04 0x00 0x00 0x07 0x18 0x20 0x0F 1405 | 0x00 0x00 0x00 0xFE 0x01 0x3F 0xC1 0x0F 1406 | 0x74 0x54 0x74 0x44 0x47 0x00 0x00 0x00 1407 | 0x25 0x55 0x77 0x52 0x52 0x00 0x00 0x00 1408 | 0x76 0x25 0x25 0x25 0x75 0x00 0x00 0x00 1409 | 0x51 0x50 0x10 0x00 0x10 0x00 0x00 0x00 1410 | 0x80 0xC0 0x60 0x30 0x1C 0x07 0x01 0x00 1411 | 0x00 0x00 0x00 0x00 0x00 0x00 0xC0 0x7C 1412 | 0x00 0x0F 0x00 0x07 0x00 0x00 0x07 0x00 1413 | 0x32 0xC2 0x1C 0xEC 0x10 0xE0 0x00 0x00 1414 | 1415 | : bcd_address_1 1416 | 0x00 1417 | : bcd_address_2 1418 | 0x00 1419 | : bcd_address_3 1420 | 0x00 1421 | -------------------------------------------------------------------------------- /chipquarium/chipquarium.ch8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/chipquarium/chipquarium.ch8 -------------------------------------------------------------------------------- /delaytimer/delay_timer_test.8o: -------------------------------------------------------------------------------- 1 | # CHIP-8 Delay Timer Test 2 | # Copyright 2015 Matthew Mikolay 3 | # See github.com/mattmikolay/chip-8 or mattmik.com for more info. 4 | 5 | # Note: Don't use v0, v1, or v2, as they are needed for printing digits 6 | :alias x v3 # x coordinate of current digit 7 | :alias y v4 # y coordinate of current digit 8 | :alias current_key v5 # Key pressed by user 9 | :alias duration v6 # Duration of time entered by user 10 | 11 | : main 12 | 13 | y := 0 14 | 15 | loop 16 | 17 | loop 18 | 19 | print_time 20 | 21 | current_key := key 22 | 23 | # If user pressed 2 key, increment duration 24 | if current_key == 0x02 then 25 | duration += 0x01 26 | 27 | # If user pressed 8 key, decrement duration 28 | if current_key == 0x08 then 29 | duration += 0xFF 30 | 31 | # Continue accepting user input until the 5 key is pressed 32 | if current_key != 0x05 then 33 | again 34 | 35 | # Begin a countdown from the time entered by the user 36 | delay := duration 37 | loop 38 | duration := delay 39 | print_time 40 | if duration != 0x00 then 41 | again 42 | 43 | again 44 | 45 | : print_time 46 | 47 | clear 48 | 49 | # Store BCD of current time in program memory 50 | i := program_end 51 | bcd duration 52 | load v2 53 | 54 | x := 0 55 | 56 | # Print hundreds digit 57 | i := hex v0 58 | sprite x y 0x05 59 | 60 | x += 5 61 | 62 | # Print tens digit 63 | i := hex v1 64 | sprite x y 0x05 65 | 66 | x += 5 67 | 68 | # Print ones digit 69 | i := hex v2 70 | sprite x y 0x05 71 | 72 | return 73 | 74 | : program_end 75 | -------------------------------------------------------------------------------- /delaytimer/delay_timer_test.ch8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/delaytimer/delay_timer_test.ch8 -------------------------------------------------------------------------------- /heartmonitor/README.md: -------------------------------------------------------------------------------- 1 | # Heart Monitor 2 | A CHIP-8 demo meant to simulate the waveform of a heart monitor. 3 | -------------------------------------------------------------------------------- /heartmonitor/heart_monitor.8o: -------------------------------------------------------------------------------- 1 | # CHIP-8 Heart Monitor Simulation 2 | # Copyright 2015 Matthew Mikolay 3 | # See github.com/mattmikolay/chip-8 or mattmik.com for more info. 4 | 5 | :alias y v0 # y coordinate of wave sprite 6 | :alias x1 v1 # x coordinate of wave's right edge 7 | :alias x2 v2 # x coordinate of wave's left edge 8 | :alias px v3 # Temporary x coordinate used by subroutine 9 | :alias mod_val v4 # Stores the value 32, used in calculations 10 | :alias sound_reg v5 # Register used to play beeping noise 11 | 12 | :const BEEP_LENGTH 15 # Duration of beeping noise 13 | :const LINE_LENGTH 10 # Length of flat line before pulse occurs 14 | :const WAVE_Y 9 # y coordinate of wave sprite 15 | 16 | : main 17 | 18 | clear 19 | 20 | # Set initial values 21 | x1 := 0 22 | x2 := 0 23 | y := WAVE_Y 24 | mod_val := 0b00011111 25 | sound_reg := BEEP_LENGTH 26 | 27 | # Draw starting line 28 | i := step1 29 | loop 30 | sprite x1 y 13 31 | x1 += 1 32 | if x1 != LINE_LENGTH then 33 | again 34 | 35 | loop 36 | 37 | # Draw (x1,y) 38 | px := x1 39 | read_i 40 | sprite x1 y 13 41 | 42 | # When the previous call to read_i terminates, px will store x1 % 32, 43 | # which we can use to determine if we should play a beep sound 44 | if px == 12 then 45 | buzzer := sound_reg 46 | 47 | # Draw (x2,y) 48 | px := x2 49 | read_i 50 | sprite x2 y 13 51 | 52 | # Increment x1 and x2 53 | x1 += 1 54 | x2 += 1 55 | 56 | # Wrap x1 and x2 to the 64 pixel wide screen 57 | if x1 == 64 then 58 | x1 := 0 59 | if x2 == 64 then 60 | x2 := 0 61 | 62 | again 63 | 64 | # Reads memory address of corresponding sprite into i register based upon the 65 | # current x coordinate stored in register px 66 | : read_i 67 | 68 | # Get relative step, mod 32 69 | px &= mod_val 70 | 71 | # Load sprite based upon this relative step 72 | i := step1 73 | if px == 10 then 74 | i := step2 75 | if px == 13 then 76 | i := step3 77 | if px == 14 then 78 | i := step4 79 | if px == 15 then 80 | i := step5 81 | if px == 16 then 82 | i := step6 83 | if px == 17 then 84 | i := step7 85 | if px == 20 then 86 | i := step2 87 | 88 | return 89 | 90 | : step1 91 | 0b00000000 92 | 93 | : step2 94 | 0b00000000 95 | 0b00000000 96 | 0b00000000 97 | 0b00000000 98 | 0b00000000 99 | 0b00000000 100 | 0b10000000 101 | 0b00000000 # 102 | 103 | : step3 104 | 0b00000000 105 | 0b00000000 106 | 0b00000000 107 | 0b00000000 108 | 0b00000000 109 | 0b10000000 110 | 0b10000000 111 | 0b00000000 # 112 | 0b00000000 113 | 0b00000000 114 | 115 | : step4 116 | 0b00000000 117 | 0b00000000 118 | 0b00000000 119 | 0b10000000 120 | 0b10000000 121 | 0b00000000 122 | 0b00000000 123 | 0b00000000 # 124 | 0b00000000 125 | 0b00000000 126 | 0b00000000 127 | 0b00000000 128 | 0b00000000 129 | 130 | : step5 131 | 0b10000000 132 | 0b10000000 133 | 0b10000000 134 | 0b00000000 135 | 0b00000000 136 | 0b00000000 137 | 0b00000000 138 | 0b00000000 # 139 | 0b00000000 140 | 0b00000000 141 | 142 | : step6 143 | 0b00000000 144 | 0b00000000 145 | 0b00000000 146 | 0b10000000 147 | 0b10000000 148 | 0b10000000 149 | 0b10000000 150 | 0b10000000 # 151 | 152 | : step7 153 | 0b00000000 154 | 0b00000000 155 | 0b00000000 156 | 0b00000000 157 | 0b00000000 158 | 0b00000000 159 | 0b00000000 160 | 0b00000000 # 161 | 0b10000000 162 | 0b10000000 163 | 0b10000000 164 | 0b10000000 165 | 0b10000000 166 | -------------------------------------------------------------------------------- /heartmonitor/heart_monitor.ch8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/heartmonitor/heart_monitor.ch8 -------------------------------------------------------------------------------- /morsecode/README.md: -------------------------------------------------------------------------------- 1 | # Morse Code Demo 2 | This demo prints "COSMAC VIP" to the screen while using the sound timer to play 3 | the corresponding Morse code signal. 4 | -------------------------------------------------------------------------------- /morsecode/morse_demo.8o: -------------------------------------------------------------------------------- 1 | # CHIP-8 Morse Code Demo 2 | # Copyright 2015 Matthew Mikolay 3 | # See github.com/mattmikolay/chip-8 or mattmik.com for more info. 4 | 5 | :alias x v0 # x coordinate of current character 6 | :alias y v1 # y coordinate of current character 7 | :alias delay_reg v2 # Register used for general timing 8 | :alias sound_reg v3 # Register used for beeps and boops 9 | 10 | :const MESSAGE_X 11 # x coordinate of message top left 11 | :const MESSAGE_Y 14 # y coordinate of message top left 12 | 13 | :const DASH_LENGTH 15 # Duration of Morse code dash 14 | :const DOT_LENGTH 5 # Duration of Morse code dot 15 | :const DASH_DOT_LENGTH 20 # Duration of Morse code dash followed by dot 16 | :const DOT_DOT_LENGTH 10 # Duration of Morse code dot followed by dot 17 | 18 | # Duration between the printing of individual letters. 19 | # This value should be 2 * DOT_LENGTH, as it always follows an 20 | # extra duration of DOT_LENGTH. 21 | :const LETTER_SEP_LENGTH 10 22 | 23 | # Duration between the printing of complete words. 24 | # This value should be 6 * DOT_LENGTH, as it always follows an 25 | # extra duration of DOT_LENGTH. 26 | :const WORD_SEP_LENGTH 30 # Duration of 27 | 28 | # Duration of delay before erasing entire "COSMAC VIP" message 29 | :const PAUSE_LENGTH 120 30 | 31 | : main 32 | 33 | clear 34 | 35 | i := sprite_border 36 | 37 | # Draw borders at top and bottom of screen 38 | x := 0 39 | loop 40 | 41 | y := 0 42 | sprite x y 13 43 | 44 | y := 20 45 | sprite x y 12 46 | 47 | x += 8 48 | 49 | if x != 64 then 50 | 51 | again 52 | 53 | y := MESSAGE_Y 54 | 55 | : type_letters 56 | 57 | x := MESSAGE_X 58 | 59 | draw_c 60 | play_dash 61 | play_dot 62 | play_dash 63 | play_dot 64 | draw_c 65 | end_letter 66 | x += 4 67 | 68 | draw_o 69 | play_dash 70 | play_dash 71 | play_dash 72 | draw_o 73 | end_letter 74 | x += 4 75 | 76 | draw_s 77 | play_dot 78 | play_dot 79 | play_dot 80 | draw_s 81 | end_letter 82 | x += 4 83 | 84 | draw_m 85 | play_dash 86 | play_dash 87 | draw_m 88 | end_letter 89 | x += 6 90 | 91 | draw_a 92 | play_dot 93 | play_dash 94 | draw_a 95 | end_letter 96 | x += 4 97 | 98 | draw_c 99 | play_dash 100 | play_dot 101 | play_dash 102 | play_dot 103 | draw_c 104 | end_word 105 | x += 9 106 | 107 | draw_v 108 | play_dot 109 | play_dot 110 | play_dot 111 | play_dash 112 | draw_v 113 | end_letter 114 | x += 4 115 | 116 | draw_i 117 | play_dot 118 | play_dot 119 | draw_i 120 | end_letter 121 | x += 4 122 | 123 | draw_p 124 | play_dot 125 | play_dash 126 | play_dash 127 | play_dot 128 | draw_p 129 | end_word 130 | 131 | # Draw the entire message 132 | draw_all 133 | 134 | # Wait a bit before erasing the text 135 | delay_reg := PAUSE_LENGTH 136 | delay := delay_reg 137 | loop 138 | delay_reg := delay 139 | while delay_reg != 0x00 140 | again 141 | 142 | # Erase the entire message 143 | draw_all 144 | 145 | jump type_letters 146 | 147 | : play_dash 148 | sound_reg := DASH_LENGTH 149 | delay_reg := DASH_DOT_LENGTH 150 | buzzer := sound_reg 151 | delay := delay_reg 152 | loop 153 | delay_reg := delay 154 | while delay_reg != 0x00 155 | again 156 | return 157 | 158 | : play_dot 159 | sound_reg := DOT_LENGTH 160 | delay_reg := DOT_DOT_LENGTH 161 | buzzer := sound_reg 162 | delay := delay_reg 163 | loop 164 | delay_reg := delay 165 | while delay_reg != 0x00 166 | again 167 | return 168 | 169 | : end_letter 170 | delay_reg := LETTER_SEP_LENGTH 171 | delay := delay_reg 172 | loop 173 | delay_reg := delay 174 | while delay_reg != 0x00 175 | again 176 | return 177 | 178 | : end_word 179 | delay_reg := WORD_SEP_LENGTH 180 | delay := delay_reg 181 | loop 182 | delay_reg := delay 183 | while delay_reg != 0x00 184 | again 185 | return 186 | 187 | : draw_c 188 | i := sprite_c 189 | sprite x y 5 190 | return 191 | 192 | : draw_o 193 | i := sprite_o 194 | sprite x y 5 195 | return 196 | 197 | : draw_s 198 | i := sprite_s 199 | sprite x y 5 200 | return 201 | 202 | : draw_m 203 | i := sprite_m 204 | sprite x y 5 205 | return 206 | 207 | : draw_a 208 | i := sprite_a 209 | sprite x y 5 210 | return 211 | 212 | : draw_v 213 | i := sprite_v 214 | sprite x y 5 215 | return 216 | 217 | : draw_i 218 | i := sprite_i 219 | sprite x y 5 220 | return 221 | 222 | : draw_p 223 | i := sprite_p 224 | sprite x y 5 225 | return 226 | 227 | : draw_all 228 | 229 | x := MESSAGE_X 230 | 231 | draw_c 232 | x += 4 233 | 234 | draw_o 235 | x += 4 236 | 237 | draw_s 238 | x += 4 239 | 240 | draw_m 241 | x += 6 242 | 243 | draw_a 244 | x += 4 245 | 246 | draw_c 247 | x += 9 248 | 249 | draw_v 250 | x += 4 251 | 252 | draw_i 253 | x += 4 254 | 255 | draw_p 256 | return 257 | 258 | : sprite_c 259 | 0xE0 260 | 0xA0 261 | 0x80 262 | 0xA0 263 | 0xE0 264 | 265 | : sprite_o 266 | 0xE0 267 | 0xA0 268 | 0xA0 269 | 0xA0 270 | 0xE0 271 | 272 | : sprite_s 273 | 0xE0 274 | 0x80 275 | 0xE0 276 | 0x20 277 | 0xE0 278 | 279 | : sprite_m 280 | 0xF8 281 | 0xA8 282 | 0xA8 283 | 0xA8 284 | 0xA8 285 | 286 | : sprite_a 287 | 0xE0 288 | 0xA0 289 | 0xE0 290 | 0xA0 291 | 0xA0 292 | 293 | : sprite_v 294 | 0xA0 295 | 0xA0 296 | 0xA0 297 | 0xA0 298 | 0x40 299 | 300 | : sprite_i 301 | 0xE0 302 | 0x40 303 | 0x40 304 | 0x40 305 | 0xE0 306 | 307 | : sprite_p 308 | 0xE0 309 | 0xA0 310 | 0xE0 311 | 0x80 312 | 0x80 313 | 314 | : sprite_border 315 | 0xFF 316 | 0x00 317 | 0xFF 318 | 0x00 319 | 0xFF 320 | 0x00 321 | 0xFF 322 | 0x00 323 | 0xFF 324 | 0x00 325 | 0xFF 326 | 0x00 327 | 0xFF 328 | -------------------------------------------------------------------------------- /morsecode/morse_demo.ch8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/morsecode/morse_demo.ch8 -------------------------------------------------------------------------------- /randomnumber/README.md: -------------------------------------------------------------------------------- 1 | # Random Number Test 2 | A simple CHIP-8 program used to demonstrate the functionality of the random 3 | number generator. When any key is pressed, a random number between 0 and 255 is 4 | generated and shown on screen. 5 | -------------------------------------------------------------------------------- /randomnumber/random_number_test.8o: -------------------------------------------------------------------------------- 1 | # Random Number Test 2 | # Copyright 2015 Matthew Mikolay 3 | # See github.com/mattmikolay/chip-8 or mattmik.com for more info. 4 | 5 | # Note: Don't use v0, v1, or v2, as they are needed for printing digits 6 | :alias value v3 # Register used to store random value 7 | :alias x v4 # x coordinate of current digit 8 | :alias y v5 # y coordinate of current digit 9 | 10 | : main 11 | 12 | y := 0 13 | 14 | loop 15 | 16 | clear 17 | 18 | # Generate a random value between 0 and 255 inclusive 19 | value := random 0b11111111 20 | 21 | # Store BCD of random value in program memory 22 | i := program_end 23 | bcd value 24 | load v2 25 | 26 | x := 0 27 | 28 | # Print hundreds digit 29 | i := hex v0 30 | sprite x y 0x05 31 | 32 | x += 5 33 | 34 | # Print tens digit 35 | i := hex v1 36 | sprite x y 0x05 37 | 38 | x += 5 39 | 40 | # Print ones digit 41 | i := hex v2 42 | sprite x y 0x05 43 | 44 | # Wait for a keypress 45 | value := key 46 | 47 | again 48 | 49 | : program_end 50 | -------------------------------------------------------------------------------- /randomnumber/random_number_test.ch8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattmikolay/chip-8/fb6f4463537e79d9e64068559176c818e561062e/randomnumber/random_number_test.ch8 --------------------------------------------------------------------------------