Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
13659 lines (11181 sloc)
551 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Ms. Pac-Man documented disassembly | |
;; | |
;; The copyright holders for the core program | |
;; included within this file are: | |
;; (c) 1980 NAMCO | |
;; (c) 1980 Bally/Midway | |
;; (c) 1981 General Computer Corporation (GCC) | |
;; | |
;; Research and compilation of the documentation by | |
;; Scott Lawrence | |
;; pacman@umlautllama.com @yorgle | |
;; | |
;; Documentation and Hack Contributors: | |
;; Don Hodges http://www.donhodges.com | |
;; David Caldwell http://www.porkrind.org | |
;; Frederic Vecoven http://www.vecoven.com (Music, Sound) | |
;; Fred K "Juice" | |
;; Marcel "The Sil" Silvius http://home.kabelfoon.nl/~msilvius/ | |
;; Mark Spaeth http://rgvac.978.org/asm | |
;; Dave Widel http://www.widel.com/ | |
;; M.A.B. from Vigasoco | |
;; | |
;; DISCLAIMER: | |
;; This project is a learning experience. The goal is to try | |
;; to figure out how the original programmers and subsequent | |
;; GCC programmers wrote Pac-Man, Crazy Otto, and Ms. Pac-Man. | |
;; This disassembly and comments are not sanctioned in any | |
;; way by any of the copyright holders of these programs. | |
;; | |
;; Over time, this document may transform from a documented disassembly | |
;; of the bootleg ms-pacman roms into a re-assemblable source file. | |
;; | |
;; This is also made to determine which spaces in the roms are available | |
;; for patches and extra functionality for your own hacks. | |
;; | |
;; NOTE: This disassembly is based on the base "bootleg" | |
;; version of Ms. Pac-Man. ("boot1" through "boot6") | |
;; rom images used: | |
;; 0x0000 - 0x0fff boot1 | |
;; 0x1000 - 0x1fff boot2 | |
;; 0x2000 - 0x2fff boot3 | |
;; 0x3000 - 0x3fff boot4 | |
;; 0x8000 - 0x8fff boot5 | |
;; 0x9000 - 0x9fff boot6 | |
;; | |
;; More information about the actual Ms. Pac-Man aux board is below. | |
;; | |
;; | |
;; IF YOU ARE AWARE OF ANY BITS OF CODE THAT ARE NOT DOCUMENTED | |
;; HERE, OR KNOW OF MORE RAM ADDRESSES OR SUCH, PLEASE EMAIL | |
;; ME SO THAT I MAY INTEGRATE YOUR INFORMATION INTO HERE. | |
;; | |
;; THANKS! | |
;; 2014-01-18 | |
;; tried to document HACK2 (standard speedup hack) but it makes no sense | |
;; added more info about #f2 LOOP and ANIMATIONS in general | |
;; | |
;; 2014-01-16 | |
;; Completely documented DrawText (2c5e) | |
;; | |
;; 2014-01-12 | |
;; Text string decodings (0x3713, 0x3d00) for readibility | |
;; Animation code engine at 0x34a9 | |
;; Animation code lists at 0x8251, Rosetta stone at 0x8395 | |
;; | |
;; 2014-01-06 | |
;; Don Hodges' documentation work added | |
;; bugfix section added. | |
;; HACK8 -> BUGFIX01 | |
;; HACK9 -> BUGFIX02 | |
;; HACK10 -> HACK8 | |
;; HACK11 -> HACK9 | |
;; | |
;; 2014-01-02 | |
;; Added "OTTOPATCH" information from Crazy Otto source | |
;; | |
;; 2009-12-16 | |
;; Added some Crazy Otto notes | |
;; | |
;; 2009-01-18 | |
;; Added content from Don Hodges for much of the undocumented code | |
;; | |
;; 2008-06-20 | |
;; Added content from Frederic Vecoven for all of the sound code | |
;; | |
;; 2007-09-03 | |
;; added more notes about mspac blocks in 8000/9000 | |
;; RAM layout, data tables from M.A.B. in the VIGASOCO project (pac) | |
;; | |
;; 2004-12-28 | |
;; added Interrupt Mode 1/2 documentation | |
;; | |
;; 2004-12-22 | |
;; added HACK12 - the C000 text mirror bug fix | |
;; | |
;; 2004-03-21 | |
;; added information for most of the reference tables for map-related-data | |
;; | |
;; 2004-03-15 | |
;; working on figuring out RST 28 | |
;; | |
;; 2004-03-09 | |
;; added comments about how the text rendering works (at 0x2c5e) | |
;; added more details about the text string look up table | |
;; added information about midway logo rendering at 0x964a | |
;; changed all of the RST 28 calls to have data after them | |
;; | |
;; 2004-03-03 | |
;; mapped out most of the patches in 8000-81ef range | |
;; (some are unused ff's, some I couldn't find...) | |
;; | |
;; 2004-03-02 | |
;; HACK10: Dave Widel's fast intermission fix (based on Dock Cutlip's code) | |
;; (now HACK8) | |
;; HACK11: Dave Widel's coin light blink with power pellets | |
;; (now HACK9) | |
;; | |
;; 2004-02-18 | |
;; HACK8: Mark Spaeth's "20 byte" level 255 Pac-Man rom fix (BUGFIX01) | |
;; HACK9: Mark Spaeth's Ms. Pac-Man level fix (BUGFIX02) | |
;; | |
;; 2004-01-10 | |
;; figured out some of the sound generation triggering | |
;; | |
;; 2004-01-09 | |
;; added notes about HACK7 : eliminating all of the startup tests | |
;; figured out the easter egg routine as well as storage method for data | |
;; | |
;; 2004-01-05 | |
;; added notes about HACK6 : the standard "HARD" romset | |
;; changed all of the HACK numbers | |
;; | |
;; 2004-01-04 | |
;; added notes from Fred K's roms about skipping the self test HACK4 | |
;; added notes about the pause routine HACK5 | |
;; added notes from Fred K about 018c game loop | |
;; | |
;; 2004-01-03 | |
;; added note about 0068-008c being junk - INCORRECT! (ed.) | |
;; | |
;; 2004-01-02 | |
;; added in more information about controllers | |
;; added info about the always-on fast upgrade HACK2 | |
;; added info about the P1P2 cheat HACK3 | |
;; | |
;; 2004-01-01 | |
;; integrated in Mark Spaeth's random fruit doc. | |
;; | |
;; 2003-07-16 | |
;; added in red ghost AI code documentation (2730, 9561) | |
;; | |
;; 2003-03-26 | |
;; changed some 'kick the dog' text | |
;; added a note about the checksum hack ; HACK1 | |
;; | |
;; 2003-03 | |
;; cleaned up some notes, added the "Made By Namco" egg notes | |
;; | |
;; + 2001-07-13 | |
;; more notes from David Widel. Ram variables, $2a23m $8768 | |
;; | |
;; + 2001-06-25,26 | |
;; integrated in some notes from David Widel (THANKS!) | |
;; | |
;; 2001-03-06 | |
;; integrated in Fred K's pacman notes. | |
;; | |
;; 2001-03-04 | |
;; corrected text strings in the lookup table at 36a5 | |
;; commented some of the text string routines | |
;; | |
;; 2001-02-28 | |
;; added text string lookup tables | |
;; added indirect lookup at 36a5 | |
;; added more commenting over from the pacman.asm file | |
;; | |
;; 2001-02-27 | |
;; table data pulled out, and bogus opcodes removed. | |
;; more score information found as well | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; Documented Hacks | |
;; | |
;; these are common hacks done to this codebase | |
HACK1 | |
Skips the traditional bad-rom checksum routine. | |
HACK2 | |
Traditional "Fast Chip" hack | |
HACK3 | |
Dock Cutlip's Fast/Invincibility hack. | |
Press P1 start for super speed | |
Press P2 start for invincibility | |
HACK4 | |
Self-Test skip | |
Reclaims rom space 3006 - 30c0 for custom code use | |
HACK5 | |
Game pause routine | |
Press P1 start to pause | |
Press P2 start to unpause | |
HACK6 | |
The standard "HARD" romset. | |
Unknown exactly what the changes are. (data table) | |
HACK7 | |
Skips the Test startup display | |
(Alternate) just skips the grid. | |
HACK8 (formerly HACK10) | |
Dave Widel's faster intermission fix | |
Based on Dock Cutlip's code | |
Pac moves at normal speeds in intermissions | |
(this is a hack, not a fix, since it's based on a hack/mod | |
HACK9 (formerly HACK11) | |
Dave Widel's coin light blink with power pellets | |
Coin lights blink when power pellets blink now | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; Documented bugfixes | |
;; | |
;; these are bugfixes to the code base | |
BUGFIX01 - Level 255 Pac-Man kill screen killer | |
from: Mark Spaeth | |
notes: Mark Spaeth's level 255 Pac-Man fix | |
Mspac never gets to 255, so this fix is pac-only | |
BUGFIX02 - Level 141 Ms. Pac-Man kill screen killer | |
ref: http://www.funspotnh.com/discus/messages/10/508.html?1077146991 | |
from: Mark Spaeth | |
notes: This fix is Ms. Pac only, but will work for pac as well. | |
BUGFIX03 - Blue Maze | |
from: Don Hodges | |
ref: http://donhodges.com/ms_pacman_bugs.htm | |
symptoms: Sometimes when starting Ms Pac, the first | |
board is blue. | |
BUGFIX04 - Marquee left side animation fix | |
from: Don Hodges | |
ref: http://donhodges.com/ms_pacman_bugs.htm | |
symptoms: incorrect character in the intro screen | |
causes the intro marquee to not work on the left side | |
BUGFIX05 - Map discoloration fix | |
from: Don Hodges | |
ref: http://donhodges.com/ms_pacman_bugs.htm | |
symptoms: The marquee doesn't light correctly, | |
Other characters glitch on gameplay maps | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; | |
;; Known Ms. Pac variants: | |
; | |
; Pac variants: | |
; Puckman Namco "original" | |
; Hanglyman Maze disappears sometimes, vertical tunnel? | |
; Pac-Man Namco/Midway | |
; Pac-Man Hard (table changes) | |
; Pac-Man Plus Midway upgrade - New ghosts, | |
; harder gameplay, disappearing map | |
; | |
; (pre-release GCC versions:) | |
; Crazy Otto 10/12/1981 (P1) Pac-man intro, legs, monsters, | |
; GENCOMP logo, | |
; no eyes when ghosts return to jail | |
; Crazy Otto 10/20/1981 (P2) Marquee (Mspac) intro, legs, | |
; ghosts, Midway logo | |
; Super Pac-Man 10/29/1981 (P3) Same as P2, with no legs, monsters | |
; Super Pac-Man 10/29/1981 (P4) Same as P3, ghosts | |
; Miss Pac-Man 11/12/1981 (P5) Marquee, "Pac-Woman" graphics, monsters | |
; Ms. Pac-Man 11/25/1981 (P6) Same as P5, MsPac graphics, Bonnie | |
; | |
' (Released versions) | |
; Ms. Pac-Man 12/18/1981 Original GCC/Midway w/ aux board | |
; (hardware protected) | |
; Ms. Pac-Man Bootleg (various) decoded aux board | |
; (no hardware protection) | |
; Ms. Pac-Man Attack four new maps, broken fruit movement | |
; Miss Pac Plus four new maps (same as Attack, reversed) | |
; and of course, the "fast" and "cheat" versions of those above. | |
; | |
; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; | |
;; JUNK REGIONS OF ROMSPACE | |
;; | |
There are a few regions of rom space that are unused by | |
the ms-pac program. These can be used for your own patches, | |
or for data, or whatever. | |
This list is most definitely incomplete. | |
Not all of these regions have been tested. | |
The list is inclusive of the start and end byte listed below. | |
Some routines (like the self-test) can be dropped to give | |
you more romspace to work with. You should be careful | |
however in that some chunks of romspace might not be free | |
with some rom hacks. | |
(0f3c - 0f4b for example) | |
003b - 0041 7 bytes Tested | |
0f3c - 0fff 195 bytes Untested, nops | |
1fa9 - 1fff 87 bytes Untested, nops, 48 used for HACK3 cheat | |
2fba - 2fff 70 bytes Untested, nops | |
3ce0 - 3cff 32 bytes Untested, nops | |
8000 - 81ef 1f0 bytes Untested, bootleg hardware ONLY! | |
97c4 - 97cf c bytes Untested, FF's | |
97d0 - 97f0 30 bytes Untested, message | |
9800 - 9fff 400 bytes not available on "pure" mspac. | |
Similarly, there are chunks of code in the 0x0000-0x3fff area that are previously | |
used for Pac functionality that has been replaced by the aux roms, which can be | |
re-purposed. | |
If you're working with a bootleg romset, then the roms specific | |
to the Aux Board, namely "BOOT5" 0x8000-0x8fff, has a lot of space | |
previously used by the patching mechanism, in 0x8000-0x87ff, which | |
can be re-used for other code/tables. | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; | |
; Ms Pacman Aux board information (GCC/Midway Pac-Man "Upgrade") | |
ED note: The U5, U6 and U7 notes below have yet to be confirmed. | |
It turns out the bootleg is the decrypted version with the | |
checksum check removed and interrupt mode changed to 1. | |
u7= boot 4($3000-$3fff) other than 4 bytes(checksum check | |
and interupt mode) | |
u6= boot 6($9000-$9fff). The second half of u6 gets mirrored | |
Renders to the second half of boot5($8800-$8fff) where it | |
is used. | |
u5= first half of boot5($8000-$87ff) | |
$8000-$81ef contain 8 byte patches that are overlayed on | |
locations in $0000-$2fff | |
The Ms Pacman aux board is not activated with the | |
mainboard. As near as I can tell it requires a sequence | |
of bytes starting at around 3176 and ending with 3196. The | |
location of the bytes doesn't seem to matter, just that | |
those bytes are executed. That sequence of bytes includes | |
a write to 5006 so I'm using that to bankswitch, but that | |
is not accurate. The actual change is I believe at $317D. | |
The aux board can also be deactivated. A read to any | |
of the several 8 byte chunks listed will cause the Ms Pac | |
roms to disappear and Pacman to show up. As a result I | |
couldn't verify what they contained. They should be the | |
same as the pacman roms, but I don't see how it could | |
matter. These areas can be accessed by the random number | |
generator at $2a23 and the board is deactivated but is | |
immediately reactivated. So the net result is no change. | |
The exact trigger for this is not yet known. | |
deactivation, 8 bytes starting at: | |
$38,$3b0,$1600,$2120,$3ff0,$8000 | |
David Widel | |
d_widel@hotmail.com | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
Ghost names: | |
Pac-Man Otto Ms pre Ms Release | |
Red Shadow/Blinky Mad Dog/Plato Blinky Blinky | |
Pink Speedy/Pinky Killer/Darwin Pinky Pinky | |
Cyan Bashful/Inky Brute/Freud Inky Inky | |
Orange Pokey/Clyde Sam/Newton Bonnie Sue | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; | |
;; ram: | |
; 4c00 unknown | |
; 4c01 unknown | |
; | |
; Sprite variables | |
; | |
; 4c02 red ghost sprite number | |
; 4c03 red ghost color entry | |
; 4c04 pink ghost sprite number | |
; 4c05 pink ghost color entry | |
; 4c06 blue ghost sprite number | |
; 4c07 blue ghost color entry | |
; 4c08 orange ghost sprite number | |
; 4c09 orange ghost color entry | |
; 4c0a pacman sprite number | |
; 4c0b pacman color entry | |
; 4c0c fruit sprite number | |
; 4c0d fruit sprite entry | |
; | |
; 4c20 sprite data that goes to the hardware sprite system | |
; | |
; 4c22-4c2f sprite positions for spriteram2 | |
; 4c32-4c3f sprite number and color for spriteram | |
; | |
; 4C40-4C41 used for moving fruit positions | |
; 4C42-4C43 used to hold address of the fruit path | |
; 4c44-4c7f unused/unknown | |
; | |
; Tasks and Timers | |
; | |
; 4c80 \ pointer to the end of the tasks list | |
; 4c81 / | |
; 4c82 \ pointer to the beginning of the tasks list | |
; 4c83 / | |
; 4c84 8 bit counter (0x00 to 0xff) used by sound routines | |
; 4c85 8 bit counter (0xff to 0x00) (unused) | |
; 4c86 counter 0: 0..5 10..15 20..25 .. 90..95 - hundreths | |
; 4c87 counter 1: 0..9 10..19 20..29 .. 50..59 - seconds | |
; 4c88 counter 2: 0..9 10..19 20..29 .. 50..59 - minutes | |
; 4c89 counter 3: 0..9 10..19 20..29 .. 90..99 - hours | |
; | |
; 4c8a number of counter limits changes in this frame (to init time) | |
; 0x01 1 hundredth | |
; 0x02 10 hundredths | |
; 0x03 1 second | |
; 0x04 10 seconds | |
; 0x05 1 minute | |
; 0x06 10 minutes | |
; 0x07 1 hour | |
; 0x08 10 hours | |
; 0x09 100 hours | |
; 4c8b random number generation (unused) | |
; 4c8c random number generation (unused) | |
; | |
; 4c90-4cbf scheduled tasks list (run inside IRQ) | |
; 16 entries, 3 bytes per entry | |
; Format: | |
; byte 0: scheduled time | |
; 7 6 5 4 3 2 1 0 | |
; | | | | | | | | | |
; | | ------------ number of time units to wait | |
; | | | |
; ---------------- time units | |
; 0x40 -> 10 hundredths | |
; 0x80 -> 1 second | |
; 0xc0 -> 10 seconds | |
; byte 1: index for the jump table | |
; byte 2: parameter for b | |
; these tasks are assigned using RST #30, with the three data bytes immediatly after the call used for the timer, index and parameter | |
; these tasks are decoded at routine starting at #0221 | |
; | |
; 4cc0-4ccf tasks to execute outside of IRQ | |
; 0xFF fill for empty task | |
; 16 entries, 2 bytes per entry | |
; Format: | |
; byte 0: routine number | |
; byte 1: parameter | |
; these tasks are assigned using RST #28, with the two data bytes immedately after the call used for the routine number and parameter | |
alternately, tasks can be assigned by manually loading B and C with routine and parameter, and then executing call #0042 | |
; tasks are decoded at routine starting at #238D | |
; | |
; Game variables | |
; ** note - need to be sorted | |
; | |
; 4DD2 FRUITP fruit position | |
; 4DD4 FVALUE value of the current fruit (0=no fruit) | |
; 4C40 COUNT current place in fruit path | |
; 4E0C FIRSTF flag to indicate that first fruit has been released | |
; 4E0D SECONDF flag to indicate that second fruit has been eaten | |
; 4C41 BCNT current place within bounce | |
; 4C42 PATH pointer to the path the fruit is currently following | |
; 4E0E DOTSEAT how many dots the current player has eaten | |
; 4EBC BNOISE set bit 5 of BNOISE to make the bounce sound | |
; 4d00 red ghost Y position (bottom to top = decreases) | |
; 4d01 red ghost X position (left to right = decreases) | |
; 4d02 pink ghost Y position (bottom to top = decreases) | |
; 4d03 pink ghost X position (left to right = decreases) | |
; 4d04 blue ghost Y position (bottom to top = decreases) | |
; 4d05 blue ghost X position (left to right = decreases) | |
; 4d06 orange ghost Y position (bottom to top = decreases) | |
; 4d07 orange ghost X position (left to right = decreases) | |
; | |
; 4d08 pacman Y position | |
; 4d09 pacman X position | |
; | |
; 4d0a red ghost Y tile pos (mid of tile) (bottom to top = decrease) | |
; 4d0b red ghost X tile pos (mid of tile) (left to right = decrease) | |
; 4d0c pink ghost Y tile pos (mid of tile) (bottom to top = decrease) | |
; 4d0d pink ghost X tile pos (mid of tile) (left to right = decrease) | |
; 4d0e blue ghost Y tile pos (mid of tile) (bottom to top = decrease) | |
; 4d0f blue ghost X tile pos (mid of tile) (left to right = decrease) | |
; 4d10 orange ghost Y tile pos (mid of tile) (bottom to top = decrease) | |
; 4d11 orange ghost X tile pos (mid of tile) (left to right = decrease) | |
; 4d12 pacman tile pos in demo and cut scenes | |
; 4d13 pacman tile pos in demo and cut scenes | |
; | |
; for the following, last move was | |
; (A) 0x00 = left/right, 0x01 = down, 0xff = up | |
; (B) 0x00 = up/down, 0x01 = left, 0xff = right | |
; 4d14 red ghost Y tile changes (A) | |
; 4d15 red ghost X tile changes (B) | |
; 4d16 pink ghost Y tile changes (A) | |
; 4d17 pink ghost X tile changes (B) | |
; 4d18 blue ghost Y tile changes (A) | |
; 4d19 blue ghost X tile changes (B) | |
; 4d1a orange ghost Y tile changes (A) | |
; 4d1b orange ghost X tile changes (B) | |
; 4d1c pacman Y tile changes (A) | |
; 4d1d pacman X tile changes (B) | |
; | |
; 4d1e red ghost y tile changes | |
; 4d1f red ghost x tile changes | |
; 4d20 pink ghost y tile changes | |
; 4d21 pink ghost x tile changes | |
; 4d22 blue ghost y tile changes | |
; 4d23 blue ghost x tile changes | |
; 4d24 orange ghost y tile changes | |
; 4d25 orange ghost x tile changes | |
; 4d26 wanted pacman tile changes | |
; 4d27 wanted pacman tile changes | |
; | |
; character orientations: | |
; 0 = right, 1 = down, 2 = left, 3 = up | |
; 4d28 previous red ghost orientation (stored middle of movement) | |
; 4d29 previous pink ghost orientation (stored middle of movement) | |
; 4d2a previous blue ghost orientation (stored middle of movement) | |
; 4d2b previous orange ghost orientation (stored middle of movement) | |
; 4d2c red ghost orientation (stored middle of movement) | |
; 4d2d pink ghost orientation (stored middle of movement) | |
; 4d2e blue ghost orientation (stored middle of movement) | |
; 4d2f orange ghost orientation (stored middle of movement) | |
; | |
; 4d30 pacman orientation | |
; | |
; these are updated after a move | |
; 4d31 red ghost Y tile position 2 (See 4d0a) | |
; 4d32 red ghost X tile position 2 (See 4d0b) | |
; 4d33 pink ghost Y tile position 2 | |
; 4d34 pink ghost X tile position 2 | |
; 4d35 blue ghost Y tile position 2 | |
; 4d36 blue ghost X tile position 2 | |
; 4d37 orange ghost Y tile position 2 | |
; 4d38 orange ghost X tile position 2 | |
; | |
; 4d39 pacman Y tile position (0x22..0x3e) (bottom-top = decrease) | |
; 4d3a pacman X tile position (0x1e..0x3d) (left-right = decrease) | |
; | |
; 4d3c wanted pacman orientation | |
; | |
; path finding algorithm: | |
; 4d3b best orientation found | |
; 4d3d saves the opposite orientation | |
; 4d3e-4d3f saves the current tile position | |
; 4d40-4d41 saves the destination tile position | |
; 4d42-4d43 temp resulting position | |
; 4d44-4d45 minimum distance^2 found | |
; | |
; 4dc7 current orientation we're trying | |
; 4d46-4d85 speed bit patterns (difficulty dependant) | |
; 4D46-4D49 speed bit patterns for pacman in normal state | |
; 4D4A-4D4D speed bit patterns for pacman in big pill state | |
; 4D4E-4D51 speed bit patterns for second difficulty flag | |
; 4D52-4D55 speed bit patterns for first difficulty flag | |
; 4D56-4D59 speed bit patterns for red ghost normal state | |
; 4D5A-4D5D speed bit patterns for red ghost blue state | |
; 4D5E-4D61 speed bit patterns for red ghost tunnel areas | |
; 4D62-4D65 speed bit patterns for pink ghost normal state | |
; 4D66-4D69 speed bit patterns for pink ghost blue state | |
; 4D6A-4D6D speed bit patterns for pink ghost tunnel areas | |
; 4D6E-4D71 speed bit patterns for blue ghost normal state | |
; 4D72-4D75 speed bit patterns for blue ghost blue state | |
; 4D76-4D79 speed bit patterns for blue ghost tunnel areas | |
; 4D7A-4D7D speed bit patterns for orange ghost normal state | |
; 4D7E-4D81 speed bit patterns for orange ghost blue state | |
; 4D82-4D83 speed bit patterns for orange ghost tunnel areas | |
; | |
; 4d86-4d93 | |
; Difficulty related table. Each entry is 2 bytes, and | |
; contains a counter value. when the counter at 4DC2 | |
; reaches each entry value, the ghosts changes their | |
; orientation and 4DC1 increments it's value to point to | |
; the next entry | |
; | |
; 4d94 counter related to ghost movement inside home | |
; 4d95-4d96 number of units before ghost leaves home (no change w/ pills) | |
; 4d97-4d98 inactivity counter for units of the above | |
; | |
; 4d99 - 4d9c | |
; These values are normally 0, but are changed to 1 when a ghost has | |
; entered a tunnel slowdown area | |
; 4d99 aux var used by red ghost to check positions | |
; 4d9a aux var used by pink ghost to check positions | |
; 4d9b aux var used by blue ghost to check positions | |
; 4d9c aux var used by orange ghost to check positions | |
; | |
; 4d9d delay to update pacman movement | |
; not 0xff - the game doesn't move pacman, but decrements instead | |
; 0x01 when eating pill | |
; 0x06 when eating big pill | |
; 0xff when not eating a pill | |
; 4d9e related to number of pills eaten before last pacman move | |
; 4d9f eaten pills counter after pacman has died in a level | |
; used to make ghosts go out of home after # pills eaten | |
; | |
; ghost substates: | |
; 0 = at home | |
; 1 = going for pac-man | |
; 2 = crossing the door | |
; 3 = going to the door | |
; | |
; 4da0 red ghost substate (if alive) | |
; 4da1 pink ghost substate (if alive) | |
; 4da2 blue ghost substate (if alive) | |
; 4da3 orange ghost substate (if alive) | |
; 4da4 # of ghost killed but no collision for yet [0..4] | |
; 4da5 pacman dead animation state (0 if not dead) | |
; 4da6 power pill effect (1=active, 0=no effect) | |
; | |
; 4da7 red ghost blue flag (0=not blue) | |
; 4da8 pink ghost blue flag (0=not blue) | |
; 4da9 blue ghost blue flag (0=not blue) | |
; 4daa orange ghost blue flag (0=not blue) | |
; | |
; 4dab killing ghost state | |
; 0 = nothing | |
; 1 = kill red ghost | |
; 2 = kill pink ghost | |
; 3 = kill blue ghost | |
; 4 = kill orange ghost | |
; | |
; ghost states: | |
; 0 = alive | |
; 1 = dead | |
; 2 = entering home after being killed | |
; 3 = go left after entering home after dead (blue) | |
; 3 = go right after entering home after dead (orange) | |
; 4dac red ghost state | |
; 4dad pink ghost state | |
; 4dae blue ghost state | |
; 4daf orange ghost state | |
; | |
; 4db0 related to difficulty, appears to be unused | |
; | |
; with these, if they're set, ghosts change orientation | |
; 4db1 red ghost change orientation flag | |
; 4db2 pink ghost change orientation flag | |
; 4db3 blue ghost change orientation flag | |
; 4db4 orange ghost change orientation flag | |
; 4bd5 pacman change orientation flag | |
; | |
; Difficulty settings | |
; | |
; 4db6 1st difficulty flag (rel 4dbb) (cruise elroy 1) | |
; 0: red ghost goes to upper right corner on scatter | |
; 1: red ghost goes for pacman on scatter | |
; 1: red ghost goes faster | |
; 4db7 2nd difficulty flag (rel 4dbc) (cruise elroy 2) | |
; when set, red uses a faster bit speed pattern | |
; 0: not set | |
1: faster movement | |
; 4db8 pink ghost counter to go out of home limit (rel 4e0f) | |
; 4db9 blue ghost counter to go out of home limit (rel 4e10) | |
; 4dba orange ghost counter to go out of home limit (rel 4e11) | |
; 4dbb remainder of pills when first diff. flag is set (cruise elroy 1) | |
; 4dbc remainder of pills when second diff. flag is set (cruise elroy 2) | |
; 4dbd-4dbe Time the ghosts stay blue when pacman eats a big pill | |
; | |
; 4dbf 1=pacman about to enter a tunnel, otherwise 0 | |
; | |
; Counters | |
; | |
; 4dc0 changes every 8 frames; used for ghost animations | |
; 4dc1 orientation changes index [0..7]. used to get value 4d86-4d93 | |
; 0: random ghost movement, 1: normal movement (?) | |
; 4dc2-4dc3 counter related to ghost orientation changes | |
; 4dc4 counter 0..8 to handle things once every 8 times | |
; 4dc5-4dc6 counter started after pacman killed | |
; 4dc7 counter for current orientation we're trying | |
; 4dc8 counter used to change ghost colors under big pill effects | |
; | |
; 4dc9-4dca pointer to pick a random value from the ROM (routine 2a23) | |
; | |
; 4dcb-4dcc counter while ghosts are blue. effect ceases at 0 | |
; 4dce counter started after insert coin (LED and 1UP/2UP blink) | |
; 4dcf counter to handle power pill flashes | |
; 4dd0 current number of killed ghosts (0..4) (rel 4da5) | |
; | |
; 4dd1 killed ghost animation state | |
; if 4da4 != 0: | |
; 4dd1 = 0: killed, showing points per kill | |
; 4dd1 = 1: wating | |
; 4dd1 = 2: clearing killed ghost, changing state to 0 | |
; 4dd2-4dd3 fruit position (sometimes for other sprite) | |
; | |
; 4dd4 entry to fruit points or 0 if no fruit | |
; 4dd6 used for LED state( 1: game waits for 1P/2P start button press) | |
; | |
; Main States | |
; | |
; 4e00 main routine number | |
; 0: init | |
; 1: demo | |
; 2: coin inserted | |
; 3: playing | |
; 4e01 main routine 0, subroutine # | |
; 4e02 main routine 1, subroutine # (related to blue maze bug) | |
; 4e03 main routine 2, subroutine # | |
; 4e04 level state subroutine # | |
; 3=ghost move, 2=ghost wait for start | |
; (set to 2 to pause game) | |
; | |
; 4e06 state in first cutscene (pac-man only) | |
; 4e07 state in second cutscene (pac-man only) | |
; 4e08 state in third cutscene (pac-man only) | |
; | |
; 4e09 current player number: 0=P1, 1=P2 | |
; | |
; 4e0a-4e0b pointer to current difficulty settings | |
; | |
; 4C40 COUNT current place in fruit path | |
; 4E0C FIRSTF flag to indicate that first fruit has been released | |
; 4E0D SECONDF flag to indicate that second fruit has been eaten | |
; 4C41 BCNT current place within bounce | |
; 4C42 PATH pointer to the path the fruit is currently following | |
; 4E0E DOTSEAT how many dots the current player has eaten | |
; 4EBC BNOISE set bit 5 of BNOISE to make the bounce sound | |
; | |
; 4e0c first fruit flag (1 if fruit has appeared) | |
; 4e0d second fruit flag (1 if fruit has appeared) | |
; 4e0e number of pills eaten in this level | |
; 4e0f counter incremented if orange, blue and pink ghosts are home | |
; and pacman is eating pills. | |
; used to make pink ghost leave home (rel 4db8) | |
; 4e10 counter incremented if orange, blue and pink ghosts are home | |
; and pacman is eating pills. | |
; used to make blue ghost leave home (rel 4db9) | |
; 4e11 counter incremented if orange, blue and pink ghosts are home | |
; and pacman is eating pills. | |
; used to make orange ghost leave home (rel 4db9) | |
; 4e12 1 after dying in a level, reset to 0 if ghosts have left home | |
; because of 4d9f | |
; | |
; 4e13 current level | |
; 4e14 real number of lives | |
; 4e15 number of lives displayed | |
; | |
; 4e16-4e33 0x13 pill data entries. each bit means if a pill is there | |
; or not (1=yes 0=no) | |
; the pills start at upper right corner, go down, then left. | |
; first pill is bit 7 of 4e16 | |
; 4e34-4e37 power pills data entries | |
; 4e38-4e65 copy of level data (430a-4e37) | |
; | |
; coins, credits | |
; | |
; 4e66 last 4 SERVICE1 to detect transitions | |
; 4e67 last 4 COIN2 to detect transitions | |
; 4e68 last 4 COIN1 to detect transitions | |
; | |
; 4e69 coin counter (coin->credts, this gets decremented) | |
; 4e6a coin counter timeout, used to write coin counters | |
; | |
; these are copied from the dipswitches | |
; 4e6b number of coins per credit | |
; 4e6c number of coins inserted | |
; 4e6d number of credits per coin | |
; 4e6e number of credits, 0xff for free play | |
; 4e6f number of lives | |
; 4e70 number of players (0=1 player, 1=2 players) | |
; 4e71 bonus/life | |
; 0x10 = 10000 0x15 = 15000 | |
; 0x20 = 20000 0xff = none | |
; 4e72 cocktail mode (0=no, 1=yes) | |
; 4e73-4e74 pointer to difficulty settings | |
; 4e73: 68=normal 7d=hard checked at start of game | |
; 4e75 ghost names mode (0 or 1) | |
; | |
; SCORE AABBCC | |
; 4e80-4e82 score P1 80=CC 81=BB 82=CC | |
; 4e83 P1 got bonus life? 1=yes | |
; 4e84-4e86 score P2 84=CC 85=BB 86=CC | |
; 4e87 P2 got bonus life? 1=yes | |
; 4e88-4e8a high score 88=CC 89=BB 8A=CC | |
; | |
; Sound Registers | |
;; these 16 values are copied to the hardware every vblank interrupt. | |
CH1_FREQ0 EQU 4e8c ; 20 bits | |
CH1_FREQ1 EQU 4e8d | |
CH1_FREQ2 EQU 4e8e | |
CH1_FREQ3 EQU 4e8f | |
CH1_FREQ4 EQU 4e90 | |
CH1_VOL EQU 4e91 | |
CH2_FREQ1 EQU 4e92 ; 16 bits | |
CH2_FREQ2 EQU 4e93 | |
CH2_FREQ3 EQU 4e94 | |
CH2_FREQ4 EQU 4e95 | |
CH2_VOL EQU 4e96 | |
CH3_FREQ1 EQU 4e97 ; 16 bits | |
CH3_FREQ2 EQU 4e98 | |
CH3_FREQ3 EQU 4e99 | |
CH3_FREQ4 EQU 4e9a | |
CH3_VOL EQU 4e9b | |
SOUND_COUNTER EQU 4c84 ; counter, incremented each VBLANK | |
; (used to adjust sound volume) | |
EFFECT_TABLE_1 EQU 3b30 ; channel 1 effects. 8 bytes per effect | |
EFFECT_TABLE_2 EQU 3b40 ; channel 2 effects. 8 bytes per effect | |
EFFECT_TABLE_3 EQU 3b80 ; channel 3 effects. 8 bytes per effect | |
#if MSPACMAN | |
SONG_TABLE_1 EQU 9685 ; channel 1 song table | |
SONG_TABLE_2 EQU 967d ; channel 2 song table | |
SONG_TABLE_3 EQU 968d ; channel 3 song table | |
#else | |
SONG_TABLE_1 EQU 3bc8 | |
SONG_TABLE_2 EQU 3bcc | |
SONG_TABLE_3 EQU 3bd0 | |
#endif | |
CH1_E_NUM EQU 4e9c ; effects to play sequentially (bitmask) | |
CH1_E_1 EQU 4e9d ; unused | |
CH1_E_CUR_BIT EQU 4e9e ; current effect | |
CH1_E_TABLE0 EQU 4e9f ; table of parameters, initially copied from ROM | |
CH1_E_TABLE1 EQU 4ea0 | |
CH1_E_TABLE2 EQU 4ea1 | |
CH1_E_TABLE3 EQU 4ea2 | |
CH1_E_TABLE4 EQU 4ea3 | |
CH1_E_TABLE5 EQU 4ea4 | |
CH1_E_TABLE6 EQU 4ea5 | |
CH1_E_TABLE7 EQU 4ea6 | |
CH1_E_TYPE EQU 4ea7 | |
CH1_E_DURATION EQU 4ea8 | |
CH1_E_DIR EQU 4ea9 | |
CH1_E_BASE_FREQ EQU 4eaa | |
CH1_E_VOL EQU 4eab | |
; 4EAC repeats the above for channel 2 | |
; 4EBC repeats the above for channel 3 | |
CH1_W_NUM EQU 4ecc ; wave to play (bitmask) | |
CH1_W_1 EQU 4ecd ; unused | |
CH1_W_CUR_BIT EQU 4ece ; current wave | |
CH1_W_SEL EQU 4ecf | |
CH1_W_4 EQU 4ed0 | |
CH1_W_5 EQU 4ed1 | |
CH1_W_OFFSET1 EQU 4ed2 ; address in ROM to find the next byte | |
CH1_W_OFFSET2 EQU 4ed3 ; (16 bits) | |
CH1_W_8 EQU 4ed4 | |
CH1_W_9 EQU 4ed5 | |
CH1_W_A EQU 4ed6 | |
CH1_W_TYPE EQU 4ed7 | |
CH1_W_DURATION EQU 4ed8 | |
CH1_W_DIR EQU 4ed9 | |
CH1_W_BASE_FREQ EQU 4eda | |
CH1_W_VOL EQU 4edb | |
; | |
; 4EDC repeats the above for channel 2 | |
; 4EEC repeats the above for channel 3 | |
; | |
; | |
; Runtime | |
; | |
; 4F00 Is set to 1 during intermissions and parts of the attract mode, otherwise 0 | |
; 4F01-4FBF Stack | |
; 4FC0-4FEF Unused | |
; 4FF0-4FFF Sprite RAM | |
; | |
; | |
; | |
; | |
; Memory mapped ports: | |
; Read ports: | |
; port# Name ; condition & change Example value | |
; ---------------------------------------------------------------------- | |
; 5000 IN0 ; When Nothing pressed #FF | |
; ; Joystick 1 UP clears bit 0 #FE | |
; ; Joystick 1 LEFT clears bit 1 #FD | |
; ; Joystick 1 RIGHT clears bit 2 #FB | |
; ; Joystick 1 DOWN clears bit 3 #F7 | |
; ; Rack test clears bit 4 #EF | |
; ; Coin 1 inserted clears bit 5 #DF | |
; ; Coin 2 inserted clears bit 6 #BF | |
; ; Service 1 pressed clears bit 7 #7F | |
; | |
; 5040 IN1 ; When Nothing pressed #FF | |
; ; Joystick 2 UP clears bit 0 #FE | |
; ; Joystick 2 LEFT clears bit 1 #FD | |
; ; Joystick 2 RIGHT clears bit 2 #FB | |
; ; Joystick 2 DOWN clears bit 3 #F7 | |
; ; service mode switch clears bit 4 #EF | |
; ; Player 1 start button clears bit 5 #DF | |
; ; Player 2 start button clears bit 6 #BF | |
; ; Cocktail cabinet DIP clears bit 7 #7F | |
; | |
; 5080 DSW 1 ; controls free play/coins per credit, # of lives per game, | |
; ; points needed for bonus, rack test, game freeze | |
; | |
; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; | |
; PAC-MAN SPRITE CODES | |
; | |
; 00-07 fruits | |
; 08-0D naked ghosts for cutscenes | |
; 0E-0F empty | |
; 10-1B big pacman | |
; 1C-1D ghost in panic mode | |
; 1E-1F empty | |
; 20-27 ghosts | |
; 28-2B points | |
; 2C-2F pacmans | |
; 30 big pacman | |
; 31 explosion | |
; 32-33 broken ghost | |
; 34-3F pacman dead | |
; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; | |
; MS. PAC-MAN SPRITE CODES | |
; | |
; 00 cherry | |
; 01 strawberry | |
; 02 peach | |
; 03 pretzel | |
; 04 apple | |
; 05 pear | |
; 06 banana | |
; 07 sack that is dropped from stork in act 3 | |
; 08 100 | |
; 09 200 | |
; 0A 500 | |
; 0B 700 | |
; 0C 1000 | |
; 0D 2000 | |
; 0E 5000 | |
; 0F junior pac-man seen in act 3 | |
; 10-17 parts of ACT director's sign | |
; 18 stork | |
; 19-1B pac-man | |
; 1C-1D ghost in panic mode | |
; 1E heart | |
; 1F empty | |
; 20-27 ghosts | |
; 28 200 | |
; 29 400 | |
; 2A 800 | |
; 2B 1600 | |
; 2C stork | |
; 2D ms pacman | |
; 2E pac-man | |
; 2F ms pacman | |
; 30 stork head + beak | |
; 31 ms pacman | |
; 32 pac-man | |
; 33-3F ms pacman (used during dying animation) | |
; 40-7F same as 00-3F, but upside down | |
; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; | |
; PACMAN TILE CODES | |
; | |
; 00-0F hex digits | |
; 10-15 pills | |
; 16-1F empty | |
; ... | |
; 40-5B space + ASCII chars | |
; 5C copyright | |
; 5D-5F PTS | |
; ... | |
; C0-FF map obstacles | |
; | |
; SPECIAL COLOR ENTRIES | |
; | |
; 18 for ghost's door | |
; 1A for pacman's and ghost's initial map positions | |
; 1B for tunnel area | |
; | |
; PACMAN TILE CONFIGURATION | |
; | |
; tile position x can go from 0x1e to 0x3d. | |
; 0x1d == wraparound -> 0x3d | |
; 0x3e == wraparound -> 0x1e | |
; tile position y can go from 0x22 to 0x3e. | |
; Why? | |
; Because of the graphics hardware. | |
; With that configuration, you can convert directly between | |
; tile position to hardware sprite positions | |
; | |
; | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
; rst 0 - initialization | |
; init | |
0000 f3 di ; Disable interrupts | |
0001 3e00 ld a,#00 ; A := #00 | |
0003 ed47 ld i,a ; Clear interrupt status register | |
0005 c30b23 jp #230b ; jump to startup test | |
;; PAC | |
;0001 3e3f ld a,#3f | |
;; | |
; rst 8 - memset() | |
; Fill HL to HL+B with A | |
0008 77 ld (hl),a ; store A | |
0009 23 inc hl ; next memory | |
000a 10fc djnz #0008 ; loop until B == #00 | |
000c c9 ret ; return | |
; arrive here from #23A7 | |
000d c30e07 jp #070e ; sets up difficulty | |
; rst 10 (for dereferencing pointers to bytes) | |
; HL = HL + A, , A := (HL) | |
; HL = base address of table | |
; A = index | |
; after the call, A gets the data in HL+A | |
0010 85 add a,l ; Add L into A | |
0011 6f ld l,a ; copy result into L | |
0012 3e00 ld a,#00 ; A := #00 | |
0014 8c adc a,h ; Add with carry into H | |
0015 67 ld h,a ; copy result into H | |
0016 7e ld a,(hl) ; load A with value in HL | |
0017 c9 ret ; return | |
; rst 18 (for dereferencing pointers to words) | |
; hl = hl + 2*b, (hl) -> e, (++hl) -> d, de -> hl | |
; HL = base address of table | |
; B = index | |
; after the call, HL gets the data in HL+(2*B). DE becomes HL+2B | |
; modified: DE, A | |
0018 78 ld a,b ; load A with B | |
0019 87 add a,a ; double it | |
001a d7 rst #10 ; A:= data in (HL + 2B), HL := HL + 2B | |
001b 5f ld e,a ; copy result into E | |
001c 23 inc hl ; next HL | |
001d 56 ld d,(hl) ; D := (HL+2B+1) | |
001e eb ex de,hl ; Exchange DE with HL. | |
001f c9 ret ; return | |
; rst 20 (jump table) | |
; Uses A as a vector to jump to the location indicated by 2*A after the call | |
; For example, if A has #00 and the two bytes following the call are #AB and #CD, the program will jump to #CDAB | |
0020: E1 pop hl ; load HL with return address. This is the next byte after the call. | |
0021: 87 add a,a ; A := 2*A | |
0022: D7 rst #10 ; HL += A, A = (HL) | |
0023: 5F ld e,a ; Copy first (low) byte to E | |
0024: 23 inc hl ; next Address | |
0025: 56 ld d,(hl) ; D = (HL+1) [high byte], so DE = 16-bit address at 2*A after the call | |
0026: EB ex de,hl ; DE <-> HL | |
0027: E9 jp (hl) ; jump to HL | |
; rst 28 | |
; takes the 2 bytes after the call as data and inserts them into the task list | |
0028 e1 pop hl ; HL = next byte after call, first data element | |
0029 46 ld b,(hl) ; load B with first data byte | |
002a 23 inc hl ; next data byte | |
002b 4e ld c,(hl) ; load C with second data byte | |
002c 23 inc hl ; HL now has the proper return address | |
002d e5 push hl ; push to stack so RET will return properly | |
002e 1812 jr #0042 ; continue this sub below | |
; rst #30 | |
; when rst #30 is called, the 3 data bytes following the call are inserted | |
; into the timed task list at the next available location. Up to #10 (16 decimal) | |
; locations are searched before giving up. | |
0030: 11 90 4C ld de,#4C90 ; load DE with starting address of task table | |
0033: 06 10 ld b,#10 ; For B = 1 to #10 | |
0035: C3 51 00 jp #0051 ; continue this sub below | |
; rst 38 (vblank) | |
; INTERRUPT MODE 1 handler | |
0038 c39b1f jp #1f9b ; patched jump from pacman. | |
003b ----50 ; junk from pac-man | |
003c 320750 ld (#5007),a ; junk from pac-man | |
003f c33800 jp #0038 ; junk from pac-man | |
;; INTERRUPT MODE 2 (original hardware, non-bootlegs, puckman, pac plus) | |
;0038 af xor a | |
;0039 320050 ld (#5000),a | |
;003c 320750 ld (#5007),a | |
;003f c33800 jp #0038 | |
;; | |
; continuation of rst 28 from #002E | |
; this sub can be called with call #0042, if B and C are loaded manually | |
; B and C have the data bytes | |
0042 2a804c ld hl,(#4c80) ; load HL with address pointing to the beginning of the task list | |
0045 70 ld (hl),b ; store task | |
0046 2c inc l ; next address | |
0047 71 ld (hl),c ; store parameter | |
0048 2c inc l ; next address | |
0049 2002 jr nz,#004d ; If non zero, skip next step | |
004b 2ec0 ld l,#c0 ; else load L with C0 to cycle HL back to #4CC0 (spins #C0-#FF) | |
004d 22804c ld (#4c80),hl ; store new task pointer back (4c80, 4c81) = hl | |
0050 c9 ret ; return to program | |
; continuation of rst 30 from #0035 (Task manager) | |
0051: 1A ld a,(de) ; load A with task | |
0052: A7 and a ; == #00 ? | |
0053: 28 06 jr z,#005B ; yes, skip ahead, we will insert the new task here | |
0055: 1C inc e ; else inc E by 3 | |
0056: 1C inc e | |
0057: 1C inc e ; DE now at next task | |
0058: 10 F7 djnz #0051 ; Next B, loops up to #10 times | |
005A: C9 ret ; return | |
005B: E1 pop hl ; HL = data address of the 3 data bytes to be inserted | |
005C: 06 03 ld b,#03 ; For B = 1 to 3 | |
005E: 7E ld a,(hl) ; load A with table value | |
005F: 12 ld (de),a ; store into task list | |
0060: 23 inc hl ; next HL | |
0061: 1C inc e ; next DE | |
0062: 10 FA djnz #005E ; next B | |
0064: E9 jp (hl) ; return to program (HL now has return address following the 3 data bytes) | |
; this is a common call | |
; converts pac-mans sprite position into a grid position | |
0065 c32d20 jp #202d | |
; difficulty settings table data - normal #0068 | |
; these are assigned at a routine starting at #070E | |
0068 00 01 02 03 04 05 06 07 | |
0070 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 | |
; difficulty settings table data - hard #007D | |
; these are assigned at a routine starting at #070E | |
007D 01 03 04 | |
0080 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 14 | |
;; part of the interrupt routine (non-test) | |
;; continuation of RST 38 partially... (vblank) | |
;; (gets called from the #1f9b patch, from #0038) | |
008d f5 push af ; save AF [restored at #01DA] | |
008e 32c050 ld (#50c0),a ; kick the dog | |
0091 af xor a ; 0 -> a | |
0092 320050 ld (#5000),a ; disable hardware interrupts | |
0095 f3 di ; disable cpu interrupts | |
; save registers. they are restored starting at #01BF | |
0096 c5 push bc ; save BC | |
0097 d5 push de ; save DE | |
0098 e5 push hl ; save HL | |
0099 dde5 push ix ; save IX | |
009b fde5 push iy ; save IY | |
;; | |
;; VBLANK - 1 (SOUND) | |
;; | |
;; load the sound into the hardware | |
;; | |
009d ld hl,#CH1_FREQ0 ; pointer to frequencies and volumes of the 3 voices | |
00a0 ld de,#5050 ; hardware address | |
00a3 ld bc,#0010 ; #10 (16 decimal) byte to copy | |
00a6 ldir ; copy | |
;; voice 1 wave select | |
00a8 ld a,(#CH1_W_NUM) ; if we play a wave | |
00ab and a | |
00ac ld a,(#CH1_W_SEL) ; then WaveSelect = CH1_W_SEL | |
00af jr nz,#00b4 | |
00b1 ld a,(#CH1_E_TABLE0) ; else WaveSelect = CH1_E_TABLE0 | |
00b4 ld (#5045),a ; write WaveSelect to hardware | |
;; voice 2 wave select | |
00b7 ld a,(#CH2_W_NUM) | |
00ba and a | |
00bb ld a,(#CH2_W_SEL) | |
00be jr nz,#00c3 | |
00c0 ld a,(#CH2_E_TABLE0) | |
00c3 ld (#504a),a | |
;; voice 3 wave select | |
00c6 ld a,(#CH3_W_NUM) | |
00c9 and a | |
00ca ld a,(#CH3_W_SEL) | |
00cd jr nz,#00d2 | |
00cf ld a,(#CH3_E_TABLE0) | |
00d2 ld (#504f),a | |
; copy last frame calculated sprite data into sprite buffer | |
00d5 21024c ld hl,#4c02 ; load HL with source address (calculated sprite data) | |
00d8 11224c ld de,#4c22 ; load DE with destination (sprite buffer) | |
00db 011c00 ld bc,#001c ; load counter with #1C bytes to copy | |
00de edb0 ldir ; copy | |
; update sprite data, adjusting to hardware | |
00e0 dd21204c ld ix,#4c20 ; load IX with start of sprite buffer | |
00e4 dd7e02 ld a,(ix+#02) ; load A with red ghost sprite | |
00e7 07 rlca | |
00e8 07 rlca ; rotate 2 bits up | |
00e9 dd7702 ld (ix+#02),a ; store | |
00ec dd7e04 ld a,(ix+#04) ; load A with pink ghost sprite | |
00ef 07 rlca | |
00f0 07 rlca ; rotate 2 bits up | |
00f1 dd7704 ld (ix+#04),a ; store | |
00f4 dd7e06 ld a,(ix+#06) ; load A with blue (inky) ghost sprite | |
00f7 07 rlca | |
00f8 07 rlca ; rotate 2 bits up | |
00f9 dd7706 ld (ix+#06),a ; store | |
00fc dd7e08 ld a,(ix+#08) ; load A with orange ghost sprite | |
00ff 07 rlca | |
0100 07 rlca ; rotate 2 bits up | |
0101 dd7708 ld (ix+#08),a ; store | |
0104 dd7e0a ld a,(ix+#0a) ; load A with ms pac sprite | |
0107 07 rlca | |
0108 07 rlca ; rotate 2 bits up | |
0109 dd770a ld (ix+#0a),a ; store | |
010c dd7e0c ld a,(ix+#0c) ; load A with fruit sprite | |
010f 07 rlca | |
0110 07 rlca ; rotate 2 bits up | |
0111 dd770c ld (ix+#0c),a ; store | |
0114 3ad14d ld a,(#4dd1) ; load A with killed ghost animation state | |
0117 fe01 cp #01 ; is there a ghost being eaten ? | |
0119 2038 jr nz,#0153 ; no , skip ahead | |
011b dd21204c ld ix,#4c20 ; else load IX with sprite data buffer start | |
011f 3aa44d ld a,(#4da4) ; load A with the unhandled killed ghost # | |
0122 87 add a,a ; A := A * 2 | |
0123 5f ld e,a ; copy to E | |
0124 1600 ld d,#00 ; D := #00 | |
0126 dd19 add ix,de ; add to index. now has the eaten ghost sprite | |
0128 2a244c ld hl,(#4c24) ; load HL with start of ghost sprite address | |
012b ed5b344c ld de,(#4c34) ; load DE with sprite number and color for spriteram | |
012f dd7e00 ld a,(ix+#00) ; load A with eaten ghost sprite | |
0132 32244c ld (#4c24),a ; store | |
0135 dd7e01 ld a,(ix+#01) ; load A with next ghost sprite | |
0138 32254c ld (#4c25),a ; store | |
013b dd7e10 ld a,(ix+#10) ; load A with eaten ghost spriteram | |
013e 32344c ld (#4c34),a ; store | |
0141 dd7e11 ld a,(ix+#11) ; load A with next ghost spriteram | |
0144 32354c ld (#4c35),a ; store | |
0147 dd7500 ld (ix+#00),l ; | |
014a dd7401 ld (ix+#01),h | |
014d dd7310 ld (ix+#10),e | |
0150 dd7211 ld (ix+#11),d ; store L, H, E, and D | |
0153 3aa64d ld a,(#4da6) ; load A with power pill effect (1=active, 0=no effect) | |
0156 a7 and a ; is a power pill active ? | |
0157 ca7601 jp z,#0176 ; no, skip ahead | |
; power pill active | |
015a ed4b224c ld bc,(#4c22) ; else swap pac for first ghost. load BC with red ghost sprite | |
015e ed5b324c ld de,(#4c32) ; load DE with highest sprite for spriteram | |
0162 2a2a4c ld hl,(#4c2a) ; load HL with fruit sprite | |
0165 22224c ld (#4c22),hl ; store into highest priority sprite | |
0168 2a3a4c ld hl,(#4c3a) ; load HL with ms pac spriteram | |
016b 22324c ld (#4c32),hl ; store into highest priority spriteram | |
016e ed432a4c ld (#4c2a),bc ; store first ghost sprite | |
0172 ed533a4c ld (#4c3a),de ; store first ghost spriteram | |
; | |
0176 21224c ld hl,#4c22 ; load source address with start of sprites | |
0179 11f24f ld de,#4ff2 ; load destiantion address with spriteram2 | |
017c 010c00 ld bc,#000c ; set counter at #0C bytes | |
; green eyed ghost bug encountered here | |
; 4FF2,3 - | |
; 4FF2,3 - red ghost (8x,11) | |
; 4FF4,5 - pink ghost (8x,11) | |
; 4FF6,7 - blue ghost (8x,11) | |
; 4FF8,9 - orange ghost (8x,11) | |
017f edb0 ldir ; copy | |
0181 21324c ld hl,#4c32 ; load source address with start of spriteram | |
0184 116250 ld de,#5062 ; load destination address with hardware sprite | |
0187 010c00 ld bc,#000c ; set counter at #0C bytes | |
018a edb0 ldir ; copy [write updated sprites to spriteram] | |
; | |
; Core game loop | |
; | |
018c cddc01 call #01dc ; update all timers | |
018f cd2102 call #0221 ; check timed tasks and execute them if it is time to do so | |
0192 cdc803 call #03c8 ; runs subprograms based on game mode, power-on stuff, attract mode, push start screen, and core loops for game playing | |
0195 3a004e ld a,(#4e00) ; load A with game mode | |
0198 a7 and a ; is the game still in power-on mode ? | |
0199 2812 jr z,#01ad ; yes, skip over next calls | |
019B cd9d03 call #039d ; check for double size pacman in intermission (pac-man only) | |
019E cd9014 call #1490 ; when player 1 or 2 is played without cockatil mode, update all sprites | |
01a1 cd1f14 call #141f ; when player 2 is played on cockatil mode, update all sprites | |
01a4 cd6702 call #0267 ; debounce rack input / add credits | |
01a7 cdad02 call #02ad ; debounce coin input / add credits | |
01aa cdfd02 call #02fd ; blink coin lights | |
; print player 1 and player two | |
; check for game mode 3 | |
; draw cprt stuff | |
01ad 3a004e ld a,(#4e00) ; load A with game mode | |
01b0 3d dec a ; are we in the demo mode ? | |
01b1 2006 jr nz,#01b9 ; no, skip next 2 steps ; set to jr #01b9 to enable sound in demo | |
01B3: 32 AC 4E ld (#4EAC),a ; yes, clear sound channel 2 | |
01B6: 32 BC 4E ld (#4EBC),a ; clear sound channel 3 | |
;; VBLANK - 2 (SOUND) | |
;; | |
;; Process sound | |
01b9 call #2d0c ; process effects | |
01bc call #2cc1 ; process waves | |
; restore registers. they were saved at #0096 | |
01bf fde1 pop iy ; restore IY | |
01c1 dde1 pop ix ; restore IX | |
01c3 e1 pop hl ; restore HL | |
01c4 d1 pop de ; restore DE | |
01c5 c1 pop bc ; restore BC | |
; | |
01c6 3a004e ld a,(#4e00) ; load A with game mode | |
01c9 a7 and a ; is this the initialization? | |
01ca 2808 jr z,#01d4 ; yes, skip ahead | |
01cc 3a4050 ld a,(#5040) ; else load A with IN1 | |
01cf e610 and #10 ; is the service mode switch set ? | |
; elimiate test mode ; HACK7 | |
;01d1 00 nop | |
;01d2 00 nop | |
;01d3 00 nop | |
; | |
01d1 ca0000 jp z,#0000 ; yes, reset | |
01d4 3e01 ld a,#01 ; else A := #01 | |
01d6 320050 ld (#5000),a ; reenable hardware interrupts | |
01d9 fb ei ; enable cpu interrupts | |
01da f1 pop af ; restore AF [was saved at #008D] | |
01db c9 ret ; return | |
; called from #018C | |
; this sub increments the timers and random numbers from #4C84 to #4C8C | |
01dc 21844c ld hl,#4c84 ; load HL with sound counter address | |
01df 34 inc (hl) ; increment | |
01e0 23 inc hl ; load HL with 2nd sound counter address | |
01e1 35 dec (hl) ; decrement | |
01e2 23 inc hl ; next address. HL now has #4C86 | |
01e3 111902 ld de,#0219 ; load DE with start of table data | |
01e6 010104 ld bc,#0401 ; C := #01, For B = 1 to 4, | |
01e9 34 inc (hl) ; increase memory | |
01ea 7e ld a,(hl) ; load A with this value | |
01eb e60f and #0f ; mask bits, now between #00 and #0F | |
01ed eb ex de,hl ; DE <-> HL | |
01ee be cp (hl) ; compare with value in table | |
01ef 2013 jr nz,#0204 ; if not equal, break out of loop | |
01f1 0c inc c ; else C := C + 1 | |
01f2 1a ld a,(de) ; load A with the value | |
01f3 c610 add a,#10 ; add #10 | |
01f5 e6f0 and #f0 ; mask bits | |
01f7 12 ld (de),a ; store result | |
01f8 23 inc hl ; next table value | |
01f9 be cp (hl) ; compare with value in table | |
01fa 2008 jr nz,#0204 ; if not equal, break out of loop | |
01fc 0c inc c ; else C := C + 1 | |
01fd eb ex de,hl ; DE <-> HL | |
01fe 3600 ld (hl),#00 ; clear the value in HL | |
0200 23 inc hl ; next HL | |
0201 13 inc de ; next table value | |
0202 10e5 djnz #01e9 ; loop | |
; set up psuedo random number generator values, #4C8A, #4C8B, #4C8C | |
0204 218a4c ld hl,#4c8a ; load HL with timer address | |
0207 71 ld (hl),c ; store C which was computed above | |
0208 2c inc l ; next address. HL now has #4C8B | |
0209 7e ld a,(hl) ; load A with the value from this timer | |
020a 87 add a,a ; A := A * 2 | |
020b 87 add a,a ; A := A * 2 | |
020c 86 add a,(hl) ; A := A + (HL) (A is now 5 times what it was) | |
020d 3c inc a ; increment. (A is now 5 times plus 1 what it was) | |
020e 77 ld (hl),a ; store new value | |
020f 2c inc l ; next address. HL now has #4C8C | |
0210 7e ld a,(hl) ; load A with the value from this timer | |
0211 87 add a,a ; A := A * 2 | |
0212 86 add a,(hl) ; A := A + (HL) (A is now 3 times what it was) | |
0213 87 add a,a ; A := A * 2 | |
0214 87 add a,a ; A := A * 2 | |
0215 86 add a,(hl) ; A := A + (HL) (A is now 13 times what it was) | |
0216 3c inc a ; increment. (A is now 13 times plus 1 what it was) | |
0217 77 ld (hl),a ; store result | |
0218 c9 ret ; return | |
; data used in subrotine above, loaded at #01E3 | |
0219 06 A0 0A 60 0A 60 0A A0 | |
; checks timed tasks | |
; counts down timer and executes the task if the timer has expired | |
; called from #018F | |
0221: 21 90 4C ld hl,#4C90 ; load HL with task list address | |
0224: 3A 8A 4C ld a,(#4C8A) ; load A with number of counter limits changes in this frame | |
0227: 4F ld c,a ; save to C for testing in line #0232 | |
0228: 06 10 ld b,#10 ; for B = 1 to #10 | |
022A: 7E ld a,(hl) ; load A with task list first value (timer) | |
022B: A7 and a ; == #00 ? (is this task empty?) | |
022C: 28 2F jr z,#025D ; Yes, jump ahead and loop for next task | |
022E: E6 C0 and #C0 ; else mask bits with binary 1100 0000 - the left 2 bits (6 and 7) are the time units | |
0230: 07 rlca | |
0231: 07 rlca ; rotate twice left. The time unit bits are now rightmost, in bits 0 and 1. EG #02 for seconds | |
0232: B9 cp c ; compare to counter. is it time to count down the timer? | |
0233: 30 28 jr nc,#025D ; if no, jump ahead and loop for next task | |
0235: 35 dec (hl) ; else decrease the task timer | |
0236: 7E ld a,(hl) ; load A with new task timer | |
0237: E6 3F and #3F ; mask bits with binary 0011 1111. This will erase the units in the left 2 bits. is the timer counted all the way down? | |
0239: 20 22 jr nz,#025D ; no, jump ahead and loop for next task | |
023B: 77 ld (hl),a ; yes, store A into task timer. this should be zero and effectively clears the task | |
023C: C5 push bc ; save BC | |
023D: E5 push hl ; save HL | |
023E: 2C inc l ; HL now has the coded task number address | |
023F: 7E ld a,(hl) ; load A with task number, used for jump table below | |
0240: 2C inc l ; HL now has the coded task parameter address | |
0241: 46 ld b,(hl) ; load B with task parameter | |
0242: 21 5B 02 ld hl,#025B ; load HL with return address | |
0245: E5 push hl ; push to stack so a RET call will return to #025B | |
0246: E7 rst #20 ; jump based on A | |
0247: 94 08 ; A==0, #0894 ; increases main subroutine number (#4E04) and returns | |
0249: A3 06 ; A==1, #06A3 ; increments main routine 2, subroutine # (#4E03) | |
024B: 8E 05 ; A==2, #058E ; increases the main routine # (#4E02) | |
024D: 72 12 ; A==3, #1272 ; increases killed ghost animation state when a ghost is eaten | |
024F: 00 10 ; A==4, #1000 ; clears the fruit sprite | |
0251: 0B 10 ; A==5, #100B ; clears the fruit score sprite | |
0253: 63 02 ; A==6, #0263 ; clears the "READY!" message | |
0255: 2B 21 ; A==7, #212B ; to increase state in 1st cutscene (#4E06) (pac-man only) | |
0257: F0 21 ; A==8, #21F0 ; to increase state in 2nd cutscene (#4E07) (pac-man only) | |
0259: B9 22 ; A==9, #22B9 ; to increase state in 3rd cutscene (#4E08) (pac-man only) | |
025B: E1 pop hl ; restore HL | |
025C: C1 pop bc ; restore BC | |
025D: 2C inc l | |
025E: 2C inc l | |
025F: 2C inc l ; next task | |
0260: 10 C8 djnz #022A ; next B | |
0262: C9 ret ; return | |
; timed task #06 - clears ready message | |
0263 EF rst #28 ; insert task #1C, parameter 86 to clear the "READY!" message | |
0264 1C 86 ; task data | |
0266 C9 ret ; return | |
;; debounce rack input / add credits (if 99 or over, return) | |
; called from #01A4 | |
0267 3a6e4e ld a,(#4e6e) ; load A with number of current credits in BCD | |
026a fe99 cp #99 ; == #99 ? (99 is max number of credits avail) | |
026c 17 rla ; rotate left A | |
026d 320650 ld (#5006),a ; store into #5006 (coin lockout, not used ?) | |
0270 1f rra ; rotate right A | |
0271 d0 ret nc ; return if 99 credits | |
0272 3a0050 ld a,(#5000) ; load A with IN0 input (joystick, credits, service mode button) | |
0275 47 ld b,a ; copy to B | |
0276 cb00 rlc b ; rotate left | |
0278 3a664e ld a,(#4e66) ; load A with service mode indicator | |
027b 17 rla ; rotate left with carry | |
027c e60f and #0f ; and it with #0F | |
027e 32664e ld (#4e66),a ; put it back | |
0281 d60c sub #0c ; subtract #0C. is the service mode being used to add a credit? | |
0283 ccdf02 call z,#02df ; If yes, call #02df ; add credit | |
0286 cb00 rlc b ; rotate left B | |
0288 3a674e ld a,(#4e67) ; load A with coin input #1 | |
028b 17 rla ; rotate left | |
028c e60f and #0f ; mask bits | |
028e 32674e ld (#4e67),a ; put back | |
0291 d60c sub #0c ; subtract C. is a coin being inserted? | |
0293 c29a02 jp nz,#029a ; no, skip ahead | |
0296 21694e ld hl,#4e69 ; yes, load HL with coin counter | |
0299 34 inc (hl) ; increase counter | |
029a cb00 rlc b ; rotaate left B | |
029c 3a684e ld a,(#4e68) ; load A with coint input #2 | |
029f 17 rla ; rotate left | |
02a0 e60f and #0f ; maks bits | |
02a2 32684e ld (#4e68),a ; put back | |
02a5 d60c sub #0c ; subtract #0C. is a coin being inserted? | |
02a7 c0 ret nz ; no, return | |
02a8 21694e ld hl,#4e69 ; else load HL with coin counter | |
02ab 34 inc (hl) ; increase | |
02ac c9 ret ; return | |
;; debounce coin input / add credits | |
; called from #01A7 | |
02ad 3a694e ld a,(#4e69) ; load A with coin counter | |
02b0 a7 and a ; == #00 ? | |
02b1 c8 ret z ; yes, return | |
02b2 47 ld b,a ; else copy coin counter to B | |
02b3 3a6a4e ld a,(#4e6a) ; load A with coin counter timeout | |
02b6 5f ld e,a ; copy timeout to E | |
02b7 fe00 cp #00 ; is the timeout == #00? | |
02b9 c2c402 jp nz,#02c4 ; no, skip ahead | |
02bc 3e01 ld a,#01 ; else A := #01 | |
02be 320750 ld (#5007),a ; store into coin counter | |
02c1 cddf02 call #02df ; call coins -> credits routine | |
02c4 7b ld a,e ; load A with timeout | |
02c5 fe08 cp #08 ; is the timeout == #08 ? | |
02c7 c2ce02 jp nz,#02ce ; no, skip next 2 steps | |
02ca af xor a ; A := #00 | |
02cb 320750 ld (#5007),a ; clear coin counter | |
02ce 1c inc e ; increment timeout | |
02cf 7b ld a,e ; copy to A | |
02d0 326a4e ld (#4e6a),a ; store into coin counter timeout | |
02d3 d610 sub #10 ; subtract #10. did the timeout end? | |
02d5 c0 ret nz ; no, return | |
02d6 326a4e ld (#4e6a),a ; else clear the counter timeout [A now has #00] | |
02d9 05 dec b ; decrement B, this was a copy of the coin counter | |
02da 78 ld a,b ; copy to A | |
02db 32694e ld (#4e69),a ; store into coin counter | |
02de c9 ret ; return | |
;; coins -> credits routine | |
02df 3a6b4e ld a,(#4e6b) ; load A with #coins per #credits | |
02e2 216c4e ld hl,#4e6c ; load HL with # of leftover coins | |
02e5 34 inc (hl) ; add 1 | |
02e6 96 sub (hl) ; subract this value from A | |
02e7 c0 ret nz ; if not zero, then not enough coins for credits. return | |
02e8 77 ld (hl),a ; else store A into leftover coins | |
02e9 3a6d4e ld a,(#4e6d) ; load A with #credits per #coins | |
02ec 216e4e ld hl,#4e6e ; load HL with #credits | |
02ef 86 add a,(hl) ; add # credits | |
02f0 27 daa ; decimal adjust | |
02f1 d2f602 jp nc,#02f6 ; if no carry, skip ahead | |
02f4 3e99 ld a,#99 ; else load a with #99 | |
02f6 77 ld (hl),a ; store #credits, max #99 | |
02f7 219c4e ld hl,#4e9c ; load HL with sound register | |
02fa cbce set 1,(hl) ; play credit sound | |
02fc c9 ret ; return | |
;; blink coin lights, print player 1 and player 2, check for mode 3 | |
; called from #01AA | |
02fd 21ce4d ld hl,#4dce ; load HL with counter started after insert coin (LED and 1UP/2UP blink) | |
0300 34 inc (hl) ; increment counter | |
0301 7e ld a,(hl) ; load A with counter | |
0302 e60f and #0f ; mask 4 left bits to zero | |
0304 201f jr nz,#0325 ; skip ahead if result is not zero | |
0306 7e ld a,(hl) ; load A with counter | |
0307 0f rrca | |
0308 0f rrca | |
0309 0f rrca | |
030a 0f rrca ; shift right 4 times | |
030b 47 ld b,a ; copy A to B | |
;; blink coin lights to pellets ; HACK9 | |
;; | |
;; 030c 3aa74d ld a,(#4da7) | |
;; 030f 4f ld c,a | |
;; 0310 180b jr #0317 | |
;; | |
030c 3ad64d ld a,(#4dd6) ; load A with LED state (1: game waits for 1P/2P start button press) | |
030f 2f cpl ; 1's complement of A | |
0310 b0 or b ; or with B | |
0311 4f ld c,a ; load C with result | |
0312 3a6e4e ld a,(#4e6e) ; load A with number of credits | |
0315 d601 sub #01 ; subtract one from it. | |
0317 3002 jr nc,#031b ; if no carry then skip next 2 steps | |
0319 af xor a ; A := #00 | |
031a 4f ld c,a ; c := #00 | |
031b 2801 jr z,#031e ; If zero then skip next step | |
031d 79 ld a,c ; else load A with C | |
031e 320550 ld (#5005),a ; Store A into player 2 start lamp | |
0321 79 ld a,c ; load A with C | |
0322 320450 ld (#5004),a ; store A into player 1 start lamp | |
0325 dd21d843 ld ix,#43d8 ; load IX with start address where the screen shows "1UP" | |
0329 fd21c543 ld iy,#43c5 ; load IY with start address where the screen shows "1UP" | |
032d 3a004e ld a,(#4e00) ; load A with game mode | |
0330 fe03 cp #03 ; is a game being played ? | |
0332 ca4403 jp z,#0344 ; Yes, Jump ahead | |
0335 3a034e ld a,(#4e03) ; else load A with main routine 2, subroutine # | |
0338 fe02 cp #02 ; <= 2 ? | |
033a d24403 jp nc,#0344 ; yes, skip ahead | |
033d cd6903 call #0369 ; else draw "1UP" | |
0340 cd7603 call #0376 ; draw "2UP" | |
0343 c9 ret ; return | |
;; display and blink 1UP/2UP depending on player up | |
0344 3a094e ld a,(#4e09) ; load A with current player number: 0=P1, 1=P2 | |
0347 a7 and a ; is this player 1 ? | |
0348 3ace4d ld a,(#4dce) ; load A with counter started after insert coin (LED and 1UP/2UP blink) | |
034b c25903 jp nz,#0359 ; | |
034e cb67 bit 4,a ; test bit 4 of the counter. is it on? | |
0350 cc6903 call z,#0369 ; no, draw "1UP" | |
0353 c48303 call nz,#0383 ; yes, clear "1UP" | |
0356 c36103 jp #0361 ; skip ahead | |
0359 cb67 bit 4,a ; test bit 4 of the counter. is it on? | |
035b cc7603 call z,#0376 ; no, draw "2UP" | |
035e c49003 call nz,#0390 ; yes, clear "2UP" | |
0361 3a704e ld a,(#4e70) ; load A with player# (0=player1, 1=player2) | |
0364 a7 and a ; is this player 1 ? | |
0365 cc9003 call z,#0390 ; yes, clear "2UP" | |
0368 c9 ret ; return | |
; draw "1UP" | |
0369 dd360050 ld (ix+#00),#50 ; 'P' | |
036d dd360155 ld (ix+#01),#55 ; 'U' | |
0371 dd360231 ld (ix+#02),#31 ; '1' | |
0375 c9 ret | |
; draw "2UP" | |
0376 fd360050 ld (iy+#00),#50 ; 'P' | |
037a fd360155 ld (iy+#01),#55 ; 'U' | |
037e fd360232 ld (iy+#02),#32 ; '2' | |
0382 c9 ret | |
; clear "1UP" | |
0383 dd360040 ld (ix+#00),#40 ; ' ' | |
0387 dd360140 ld (ix+#01),#40 ; ' ' | |
038b dd360240 ld (ix+#02),#40 ; ' ' | |
038f c9 ret | |
; clear "2UP" | |
0390 fd360040 ld (iy+#00),#40 ; ' ' | |
0394 fd360140 ld (iy+#01),#40 ; ' ' | |
0398 fd360240 ld (iy+#02),#40 ; ' ' | |
039c c9 ret | |
; draws big pacman in intermission. used for pac-man only, not ms.pac | |
; called from #019b | |
039d 3a064e ld a,(#4e06) ; load A with 1st intermission counter | |
03a0 d605 sub #05 ; is big-pac onscreen ? | |
03a2 d8 ret c ; no, return. (always returns in ms. pacman) | |
; draw big pac (pac-man only, during 1st cutscene) | |
03a3 2a084d ld hl,(#4d08) | |
03a6 0608 ld b,#08 | |
03a8 0e10 ld c,#10 | |
03aa 7d ld a,l | |
03ab 32064d ld (#4d06),a | |
03ae 32d24d ld (#4dd2),a | |
03b1 91 sub c | |
03b2 32024d ld (#4d02),a | |
03b5 32044d ld (#4d04),a | |
03b8 7c ld a,h | |
03b9 80 add a,b | |
03ba 32034d ld (#4d03),a | |
03bd 32074d ld (#4d07),a | |
03c0 91 sub c | |
03c1 32054d ld (#4d05),a | |
03c4 32d34d ld (#4dd3),a | |
03c7 c9 ret | |
;; enable sound out and other stuff | |
; called from #0192 | |
03c8 3a004e ld a,(#4e00) ; load A with game mode | |
03cb e7 rst #20 ; jump based on A | |
03cc d4 03 ;#03D4 ;#4E00 = 0 ;GAME POWER ON | |
03ce fe 03 ;#03FE ;#4E00 = 1 ;ALL ATTRACT MODES. this runs until a credit is inserted | |
03d0 e5 05 ;#05E5 ;#4E00 = 2 ;PLAYER 1 OR 2 SCREEN. draw screen and wait for start to be pressed | |
03d2 be 06 ;#06BE ;#4E00 = 3 ;PLAYER 1 OR 2 PLAYING. runs core game loop | |
; arrive here after power on | |
03d4 3a014e ld a,(#4e01) ; load A with main routine 0, subroutine # | |
03d5 e7 rst #20 ; jump based on A | |
03D8: DC 03 ; #03DC | |
03DA: 0C 00 ; #000C. returns immediately (to #0195) | |
; arrive here after powering on | |
; this sets up the following tasks | |
03DC: EF rst #28 ; insert task to clear the whole screen | |
03DD: 00 00 ; data for above, task #00 | |
03DF: EF rst #28 ; insert task to clear the color RAM | |
03E0: 06 00 ; data for above, task #06 | |
03e2 ef rst #28 ; insert task color the maze | |
03e3 01 00 ; data for above, task #01 | |
03e5 ef rst #28 ; insert task to check all dip switches and assign memories to the settings indicated | |
03e6 14 00 ; data for above, task #14 | |
03e8 ef rst #28 ; insert task - draws "high score" and scores. clears player 1 and 2 scores to zero. | |
03e9 18 00 ; data for above, task #18 | |
03eb ef rst #28 ; insert task - resets a bunch of memories | |
03ec 04 00 ; data for above, task #04 | |
03ee ef rst #28 ; insert task - clear fruit, pacman, and all ghosts | |
03ef 1e 00 ; data for above, task #1E | |
03f1 ef rst #28 ; insert task - set game to demo mode | |
03f2 07 00 ; data for above, task #07 | |
03F4: 21 01 4E ld hl,#4E01 ; load HL with main routine 0, subroutine # | |
03F7: 34 inc (hl) ; increase so this sub doesn't run again. | |
03f8 210150 ld hl,#5001 ; load HL with sound address | |
03fb 3601 ld (hl),#01 ; enable sound | |
03fd c9 ret ; return | |
; attract mode main routine | |
03fe cda12b call #2ba1 ; write # of credits on screen | |
0401 3a6e4e ld a,(#4e6e) ; load A with # of credits | |
0404 a7 and a ; == #00 ? | |
0405 280c jr z,#0413 ; yes, skip ahead | |
0407 af xor a ; else A := #00 | |
0408 32044e ld (#4e04),a ; clear level state subroutine # | |
040b 32024e ld (#4e02),a ; clear main routine 1, subroutine # | |
040e 21004e ld hl,#4e00 ; load HL with game mode | |
0411 34 inc (hl) ; increase game mode to press start screen | |
0412 c9 ret ; return (to #0195) | |
; table lookup | |
; OTTOPATCH | |
;PATCH FOR NEW ATTRACT MODE | |
ORG 0413H | |
JP ATTRACT | |
0413 c35c3e jp #3e5c ; jump to mspac patch when there are no credits - controls the demo mode | |
; code resumes at #045F | |
; Pac-man code: | |
; 0413 3a024e ld a,(#4e02) ; load A with main routine 1, subroutine # | |
; end Pac-man code | |
0416 e7 rst #20 ; jump based on A (pac-man only) | |
; jump table based from value in #4E02 | |
; task routine to draw out the attract screen, only used in pac-man, not ms. pac | |
0417 5f 04 ; #045F ;(#4e02)=#00 ; clear screen, reset memories, clear sprites | |
0419 0c 00 ; #000C ;(#4e02)=#01 ; returns immediately | |
041b 71 04 ; #0471 ;(#4e02)=#02 ; draw red ghost | |
041d 0c 00 ; #000C ;(#4e02)=#03 ; returns immediately | |
041f 7f 04 ; #047F ;(#4e02)=#04 ; draw "-SHADOW" | |
0421 0C 00 ; #000C ;(#4e02)=#05 ; returns immediately | |
0423 85 04 ; #0485 ;(#4e02)=#06 ; draw ""BLINKY"" | |
0425 0c 00 ; #000C ;(#4e02)=#07 ; returns immediately | |
0427 8b 04 ; #048B ;(#4e02)=#08 ; draw pink ghost | |
0429 0c 00 ; #000C ;(#4e02)=#09 ; returns immediately | |
042b 99 04 ; #0499 ;(#4e02)=#0A ; draw "-SPEEDY" | |
042d 0c 00 ; #000C ;(#4e02)=#0B ; returns immediately | |
042f 9f 04 ; #049F ;(#4e02)=#0C ; draw ""PINKY"" | |
0431 0c 00 ; #000C ;(#4e02)=#0D ; returns immediately | |
0433 a5 04 ; #04A5 ;(#4e02)=#0E ; draw blue ghost (inky) | |
0435 0c 00 ; #000C ;(#4e02)=#0F ; returns immediately | |
0437 b3 04 ; #04B3 ;(#4E02)=#10 ; draw "-BASHFUL" | |
0439: 0C 00 ; #000C ;(#4E02)=#11 ; returns immediately | |
043B: B9 04 ; #04B9 ;(#4E02)=#12 ; draw ""INKY"" | |
043D: 0C 00 ; #000C ;(#4E02)=#13 ; returns immediately | |
043F: BF 04 ; #04BF ;(#4E02)=#14 ; draw orange ghost | |
0441: 0C 00 ; #000C ;(#4E02)=#15 ; returns immediately | |
0443: CD 04 ; #04CD ;(#4E02)=#16 ; draw "-POKEY" | |
4445: 0C 00 ; #000C ;(#4E02)=#17 ; returns immediately | |
0447: D3 04 ; #04D3 ;(#4E02)=#18 ; draw ""CLYDE"" | |
0449: 0C 00 ; #000C ;(#4E02)=#19 ; returns immediately | |
044B: D8 04 ; #04D8 ;(#4E02)=#1A ; draw ". 10 Pts" and "o 50pts" | |
044D: 0C 00 ; #000C ;(#4E02)=#1B ; returns immediately | |
044F: E0 04 ; #04E0 ;(#4E02)=#1C ; get demo ready and draw invisible maze | |
0451: 0C 00 ; #000C ;(#4E02)=#1D ; returns immediately | |
0453: 1C 05 ; #051C ;(#4E02)=#1E ; start and run demo | |
0455: 4B 05 ; #054B ;(#4E02)=#1F ; check to release pink ghost | |
0457: 56 05 ; #0556 ;(#4E02)=#20 ; check to release inky | |
0459: 61 05 ; #0561 ;(#4E02)=#21 ; check to release orange ghost | |
045B: 6C 05 ; #056C ;(#4E02)=#22 ; check for completion of demo | |
045D: 7C 05 ; #057C ;(#4E02)=#23 ; end demo and return to program | |
; ms. pac code resumes here | |
; arrive here from #3E67 when subroutine # = 00 | |
; sets up the attract mode | |
045f ef rst #28 ; insert task #00 - clears the maze | |
0460 00 01 | |
0462 ef rst #28 ; insert task #01 - colors the screen | |
0464 01 00 | |
0465 ef rst #28 ; insert task #04 - resets a bunch of memories | |
0466 04 00 | |
0468 ef rst #28 ; insert task #1E - clear fruit, pacman and all ghosts | |
0469 1e 00 | |
046b 0e0c ld c,#0c ; load C with text code for "Ms Pac Man" | |
046d cd8505 call #0585 ; draw text to screen, increase subroutine # | |
0470 c9 ret ; return (to #0195) | |
; pac-man only attract mode code from #0471 to #0579 | |
0471 210443 ld hl,#4304 ; load HL with starting screen address of stationary red ghost | |
0474 3e01 ld a,#01 ; load A with the color code for red | |
0476 cdbf05 call #05bf ; draw stationary red ghost on screen | |
0479 0e0c ld c,#0c ; load C with text code for "CHARACTER / NICKNAME" | |
047b cd8505 call #0585 ; insert task to write text to screen | |
047e c9 ret ; return | |
047f 0e14 ld c,#14 ; load C with text code for "-SHADOW" | |
0481 cd9305 call #0593 ; draw text to screen | |
0484 c9 ret ; return | |
0485 0e0d ld c,#0d ; load C with text code for ""BLINKY"" | |
0487 cd9305 call #0593 ; draw text to screen | |
048a c9 ret ; return | |
048b 210743 ld hl,#4307 ; load HL with starting screen address of stationary pink ghost | |
048e 3e03 ld a,#03 ; load A with color code for pink | |
0490 cdbf05 call #05bf ; draw stationary pink ghost on screen | |
0493 0e0c ld c,#0c ; load C with text code for "CHARACTER / NICKNAME" | |
0495 cd8505 call #0585 ; insert task to write text to screen | |
0498 c9 ret ; return | |
0499 0e16 ld c,#16 ; load C with text code for "-SPEEDY" | |
049b cd9305 call #0593 ; draw text to screen | |
049e c9 ret ; return | |
049f 0e0f ld c,#0f ; load C with text code for ""PINKY"" | |
04a1 cd9305 call #0593 ; draw text to screen | |
04a4 c9 ret ; return | |
04a5 210a43 ld hl,#430a ; load HL with starting screen address of stationary blue ghost (inky) | |
04a8 3e05 ld a,#05 ; load A with color code for light blue | |
04aa cdbf05 call #05bf ; draw stationary inky on screen | |
04ad 0e0c ld c,#0c ; load C with text code for "CHARACTER / NICKNAME" | |
04af cd8505 call #0585 ; insert task to write text to screen | |
04b2 c9 ret ; return | |
04b3 0e33 ld c,#33 ; load C with text code for "-BASHFUL" | |
04b5 cd9305 call #0593 ; draw text to screen | |
04b8 c9 ret ; return | |
04b9 0e2f ld c,#2f ; load C with text code for ""INKY"" | |
04bb cd9305 call #0593 ; draw text to screen | |
04be c9 ret ; return | |
04bf 210d43 ld hl,#430d ; load HL with starting screen address of staionary orange ghost | |
04c2 3e07 ld a,#07 ; load A with color code for orange | |
04c4 cdbf05 call #05bf ; draw stationary orange ghost on screen | |
04c7 0e0c ld c,#0c ; load C with text code for "CHARACTER / NICKNAME" | |
04c9 cd8505 call #0585 ; insert task to write text to screen | |
04cc c9 ret ; return | |
04cd 0e35 ld c,#35 ; load C with text code for "-POKEY" | |
04cf cd9305 call #0593 ; draw text on screen | |
04d2 c9 ret ; return | |
04d3 0e31 ld c,#31 ; load C with text code for ""CLYDE"" | |
04d5 c38005 jp #0580 ; draw text and increase game mode | |
04d8 ef rst #28 ; insert task to write text ". 10 Pts" | |
04d9 1c 11 | |
04da 0e12 ld c,#12 | |
04dd c38505 jp #0585 ; insert task to write text "o 50 Pts" | |
04e0 0e13 ld c,#13 ; load C with text code for "(C) MIDWAY MFG CO" | |
04e2 cd8505 call #0585 ; insert task to write text to screen | |
04e5 cd7908 call #0879 ; setup game start variables | |
04e8 35 dec (hl) | |
04e9 ef rst #28 ; set task #11 to clear memories #4d00 through #4dff | |
04ea 11 00 | |
04ec ef rst #28 ; set task #05 to reset ghost home counter | |
04ed 05 01 | |
04EF ef rst #28 ; set task #10 to set up difficulty | |
04F0 10 14 | |
04f2 ef rst #28 ; set task #04 to reset a bunch of memories and set up sprite locations for demo mode | |
04f3 04 01 | |
04f4 3e01 ld a,#01 ; A := #01 | |
04f7 32144e ld (#4e14),a ; store into number of lives left | |
04fa af xor a ; A := #00 | |
04fb 32704e ld (#4e70),a ; store into number of players ( 0=1 1=2 ) | |
04fe 32154e ld (#4e15),a ; store into number of lives displayed | |
0501 213243 ld hl,#4332 ; load HL with screen address where energizer is in attract mode | |
0504 3614 ld (hl),#14 ; draw energizer | |
0506 3efc ld a,#fc ; load A with code for invisible maze block | |
0508 112000 ld de,#0020 ; load DE with offset for columns | |
050b 061c ld b,#1c ; For B = 1 to #1C | |
050d dd214040 ld ix,#4040 ; load IX with start address of video memory for playfield | |
0511 dd7711 ld (ix+#11),a ; draw invisible maze block | |
0514 dd7713 ld (ix+#13),a ; draw invisible maze block | |
0517 dd19 add ix,de ; add offset for next column | |
0519 10f6 djnz #0511 ; Next B | |
051b c9 ret ; return | |
; called during attract mode, pac-man only, not ms. pac | |
051c 21a04d ld hl,#4da0 ; load HL with red ghost substate address | |
051f 0621 ld b,#21 ; B := #21 | |
0521 3a3a4d ld a,(#4d3a) ; load A with pacman X tile position | |
0524 90 sub b ; has pacman/ghost reached the far right side of the screen? | |
0525 2005 jr nz,#052c ; no, skip ahead and do a core loop | |
0527 3601 ld (hl),#01 ; yes, change ghost substate to going for pac-man | |
0529 c38e05 jp #058e ; jump ahead, increase game state and return | |
; a core game loop used in pac-man demo mode only, not used in ms. pac | |
052c cd1710 call #1017 ; another core game loop which does many things | |
052f cd1710 call #1017 ; another core game loop which does many things | |
0532 cd230e call #0e23 ; change animation of ghosts every 8th frame | |
0535 cd0d0c call #0c0d ; handle power pill flashes | |
0538 cdd60b call #0bd6 ; set ghost colors | |
053b cda505 call #05a5 ; check for direction reversal after eating power pill | |
053e cdfe1e call #1efe ; check for red ghost direction reversal | |
0541 cd251f call #1f25 ; check for pink ghost direction reversal | |
0544 cd4c1f call #1f4c ; check for blue ghost (inky) direction reversal | |
0547 cd731f call #1f73 ; check for orange ghost direction reversal | |
054a c9 ret | |
054b 21a14d ld hl,#4da1 ; load HL with pink ghost substate | |
054e 0620 ld b,#20 ; B := #20 | |
0550 3a324d ld a,(#4d32) ; load A with red ghost X tile position 2 | |
0553 c32405 jp #0524 ; check for reaching position to release next ghost | |
0556 21a24d ld hl,#4da2 ; load HL with blue ghost (inky) substate | |
0559 0622 ld b,#22 ; B := #22 | |
055b 3a324d ld a,(#4d32) ; load A with red ghost X tile position 2 | |
055e c32405 jp #0524 ; check for reaching position to release next ghost | |
0561 21a34d ld hl,#4da3 ; load HL with orange ghost substate | |
0564 0624 ld b,#24 ; B := #24 | |
0566 3a324d ld a,(#4d32) ; load A with red ghost X tile position 2 | |
0569 c32405 jp #0524 ; check for reaching position to release next ghost | |
056c 3ad04d ld a,(#4dd0) ; load A with current number of killed ghosts | |
056f 47 ld b,a ; copy to B | |
0570 3ad14d ld a,(#4dd1) ; load A with killed ghost animation state | |
0573 80 add a,b ; add to number of killed ghosts | |
0574 fe06 cp #06 ; == #06? (are we done ?) | |
0576 ca8e05 jp z,#058e ; yes, skip ahead and increase subroutine number | |
0579 c32c05 jp #052c ; no, loop back again to core loop | |
; arrive here in demo mode from #3ECD | |
057c cdbe06 call #06be ; jump to new subroutine based on game state | |
057f c9 ret ; returns to #0195 | |
; pac-man only ??? | |
; arrive here from #04D5 | |
0580 3a754e ld a,(#4e75) ; load A with ghost name mode (0 or 1) | |
0583 81 add a,c | |
0584 4f ld c,a | |
; called from #046D and other places. C is preloaded with the text code to display | |
0585 061c ld b,#1c ; load B with task code for text display | |
0587 cd4200 call #0042 ; insert task to display text, parameter = variable text | |
058a f7 rst #30 ; insert timed task to increase the main routine # (#4E02) | |
058b 4a 02 00 ; timer = #4A, task = 2, parameter = 0 | |
; BUGFIX03 - Blue maze - Don Hodges | |
058b 41 02 00 ; 41 is 1/10 second rather than 1 second | |
; called from # 0246 from jump table based on game state | |
; or, timed task number #02 has been encountered, arrive from #0246 | |
; also arrive from #3E93 during marquee mode in demo | |
058e 21024e ld hl,#4E02 ; load HL with main routine 1, subroutine # | |
0591 34 inc (hl) ; increase | |
0592 c9 ret ; return | |
; pac-man only - used in demo mode for introducing ghost names | |
; called from several places after C has been preloaded with ghost name code | |
0593 3a754e ld a,(#4e75) ; Load A with ghost name mode (0 or 1) | |
0596 81 add a,c ; add to C | |
0597 4f ld c,a ; load result into C | |
0598 061c ld b,#1c ; load B with task code for text display | |
059a cd4200 call #0042 ; set task to display ghost name | |
059d f7 rst #30 ; set timed task to increase the main routine # (#4E02) | |
059e 45 02 00 ; data for rst #30 above. timer=45, task=2, param=0 | |
05a1 cd8e05 call #058e ; increase main routine 1, subroutine # (#4E02) | |
05a4 c9 ret ; return | |
; pac-man only, used during attract mode when pac-man moves toward energizer followed by the 4 ghosts | |
05a5 3ab54d ld a,(#4db5) ; load A with pacman change orientation flag | |
05a8 a7 and a ; == #00 ? | |
05a9 c8 ret z ; yes, return | |
; pac-man only, used during attract mode when pac-man reaches the energizer | |
05aa af xor a ; no, A := #00 | |
05ab 32b54d ld (#4db5),a ; store into pacman change orientation flag | |
05ae 3a304d ld a,(#4d30) ; load A with pacman orientation | |
05b1 ee02 xor #02 ; flip bit = change direction | |
05b3 323c4d ld (#4d3c),a ; store into wanted pacman orientation | |
05b6 47 ld b,a ; store into B | |
05b7 21ff32 ld hl,#32ff ; load HL with tile direction table | |
05ba df rst #18 ; load HL with tile direction based on direction | |
05bb 22264d ld (#4d26),hl ; store into wanted pacman tile changes | |
05be c9 ret ; return | |
; pac-man only, used during attract mode to draw the stationary ghosts during introductions | |
; HL is preloaded with starting screen address, | |
; A is preloaded with the ghost color code | |
05bf 36b1 ld (hl),#b1 ; draw first part of ghost | |
05c1 2c inc l | |
05c2 36b3 ld (hl),#b3 ; draw 2nd part of ghost | |
05c4 2c inc l | |
05c5 36b5 ld (hl),#b5 ; draw 3rd part of ghost | |
05c7 011e00 ld bc,#001e ; load BC with offset for next column | |
05ca 09 add hl,bc ; add offset | |
05cb 36b0 ld (hl),#b0 ; draw 4th part of ghost | |
05cd 2c inc l | |
05ce 36b2 ld (hl),#b2 ; draw 5th part of ghost | |
05d0 2c inc l | |
05d1 36b4 ld (hl),#b4 ; draw last part of ghost | |
05d3 110004 ld de,#0400 | |
05d6 19 add hl,de ; add offset for color | |
05d7 77 ld (hl),a ; color last part of ghost | |
05d8 2d dec l | |
05d9 77 ld (hl),a ; color 5th part of ghost | |
05da 2d dec l | |
05db 77 ld (hl),a ; color 4th part of ghost | |
05dc a7 and a ; clear carry flag | |
05dd ed42 sbc hl,bc ; subtract offset for previous column | |
05df 77 ld (hl),a ; color 3rd part of ghost | |
05e0 2d dec l | |
05e1 77 ld (hl),a ; color 2nd part of ghost | |
05e2 2d dec l | |
05e3 77 ld (hl),a ; color first part of ghost | |
05e4 c9 ret ; return | |
; arrive from #03CB | |
; arrive here when credit has been inserted and game is waiting for start button to be pressed | |
05E5: 3A 03 4E ld a,(#4E03) ; load A with main routine 2, subroutine # | |
05E8: E7 rst #20 ; jump based on A | |
05E9: F3 05 ; #05F3 ; inserts tasks to draw info on screen | |
05EB: 1B 06 ; #061B ; display 1/2 player and check start buttons | |
05ED: 74 06 ; #0674 ; run when start button pressed, gets game ready to be played | |
05EF: 0C 00 ; #000C ; returns immediately | |
05F1: A8 06 ; #06A8 ; draw remaining lives at bottom of screen and start game | |
05F3: CD A1 2B call #2BA1 ; write # of credits on screen | |
05F6: EF rst #28 ; insert task to clear the maze | |
05F7: 00 01 ; task #00, parameter #01 | |
05F9: EF rst #28 ; insert task to color the maze | |
05FB: 01 00 ; task #01 | |
05FC: EF rst #28 ; insert task to display "PUSH START BUTTON" | |
05FD: 1C 07 ; task #1c, parameter #07. | |
05FF: EF rst #28 ; insert task to display "ADDITIONAL AT 000" | |
0600: 1C 0B ; task #1C, parameter #0B. | |
0602: EF rst #28 ; insert task to clear fruit, pacman, and all ghosts | |
0603: 1E 00 ; task #1E | |
0605: 21 03 4E ld hl,#4E03 ; load HL with main routine 2, subroutine # | |
0608: 34 inc (hl) ; increase | |
0609: 3E 01 ld a,#01 ; A := #01 | |
060B: 32 D6 4D ld (#4DD6),a ; store in LED state ( 1: game waits for 1P/2P start button press) | |
060E: 3A 71 4E ld a,(#4E71) ; load A with setting for bonus life | |
0611: FE FF cp #FF ; does this game award any bonus lives? | |
0613: C8 ret z ; no, return | |
0614: EF rst #28 ; else insert task to draw the MS PAC MAN graphic which appears between "ADDITIONAL" and "AT 10,000 pts" | |
0615: 1C 0A ; task data | |
0617: EF rst #28 ; insert task to write points needed for extra life digits to screen | |
0618: 1F 00 ; task data | |
061A: C9 ret ; return | |
;; jump here from #05E8 | |
;; display 1/2 player and check start buttons | |
061b cda12b call #2ba1 ; write # of credits on screen | |
061e 3a6e4e ld a,(#4e6e) ; load A with # of credits | |
0621 fe01 cp #01 ; is it 1? | |
0623 0609 ld b,#09 ; load B with message #9: "1 OR 2 PLAYERS" | |
0625 2002 jr nz,#0629 ; if >= 2 credits, skip next step | |
0627 0608 ld b,#08 ; load B with message #8: "1 PLAYER ONLY" | |
0629 cd5e2c call #2c5e ; print message | |
062c 3a6e4e ld a,(#4e6e) ; load A with # of credits | |
062f fe01 cp #01 ; 1 credit? | |
0631 3a4050 ld a,(#5040) ; load A with IN1 (player start buttons) | |
0634 280c jr z,#0642 ; don't check p2 with 1 credit | |
0636 cb77 bit 6,a ; check for player 2 start button | |
0638 2008 jr nz,#0642 ; if not, pressed, skip ahead to check for player 1 start | |
063a 3e01 ld a,#01 ; else set 2 players | |
063c 32704e ld (#4e70),a ; store into # of players (0=1 player, 1=2 players) | |
063f c34906 jp #0649 ; jump ahead | |
0642 cb6f bit 5,a ; player 1 start being pressed ? | |
0644 c0 ret nz ; no, return | |
0645 af xor a ; A := #00 | |
0646 32704e ld (#4e70),a ; store into # of players (0=1 player, 1=2 players) | |
0649 3a6b4e ld a,(#4e6b) ; load A with number of coins per credit | |
064c a7 and a ; Is free play activated? | |
064d 2815 jr z,#0664 ; Yes, skip ahead | |
064f 3a704e ld a,(#4e70) ; else load A with # of players | |
0652 a7 and a ; Is this a 1 player game? | |
0653 3a6e4e ld a,(#4e6e) ; load A with number of credits | |
0656 2803 jr z,#065b ; If 1 player game, skip ahead and only subtract 1 credit | |
0658 c699 add a,#99 ; else subtract 2 credits. one here... | |
065a 27 daa ; decimal adjust | |
065b c699 add a,#99 ; subtract a credit | |
065d 27 daa ; decimal adjust | |
065e 326e4e ld (#4e6e),a ; save result in credits counter | |
0661 cda12b call #2ba1 ; write # of credits on screen | |
0664 21034e ld hl,#4e03 ; load HL with main routine 2, subroutine # | |
0667 34 inc (hl) ; increase | |
0668 af xor a ; A := #00 | |
0669 32d64d ld (#4dd6),a ; store in LED state ( 1: game waits for 1P/2P start button press) | |
066c 3c inc a ; A := #01 | |
066d 32cc4e ld (#4ecc),a ; store in wave to play (begins intro music tune) | |
0670 32dc4e ld (#4edc),a ; store in wave to play (beigns intro music tune) | |
0673 c9 ret ; return (to #0195) | |
; arrive from #05E8 when start button has been pressed | |
0674 ef rst #28 ; set task #00, parameter #01 - clears the maze | |
0675 00 01 | |
0677 ef rst #28 ; set task #01, parameter #01 - colors the maze | |
0678 01 01 | |
067a ef rst #28 ; set task #02, parameter #00 - draws the maze | |
067b 02 00 | |
067d ef rst #28 ; set task #12, parameter #00 - sets up coded pill and power pill memories | |
067e 12 00 | |
0680 ef rst #28 ; set task #03, parameter #00 - draws the pellets | |
0681 03 00 | |
0683 ef rst #28 ; set task #1C, parameter #03 - draws text on screen "PLAYER 1" | |
0684 1c 03 | |
0686 ef rst #28 ; set task #1C, parameter #06 - draws text on screen "READY!" and clears the intermission indicator | |
0687 1c 06 | |
0689 ef rst #28 ; set task #18, parameter #00 - draws "high score" and scores. clears player 1 and 2 scores to zero. | |
068a 18 00 | |
068c ef rst #28 ; set task #1B, parameter #00 - draws fruit at bottom right of screen | |
068d 1b 00 | |
068f af xor a ; A := #00 | |
0690 32134e ld (#4e13),a ; current board level = 0 | |
0693 3a6f4e ld a,(#4e6f) ; load number of lives to start | |
0696 32144e ld (#4e14),a ; set number of lives | |
0699 32154e ld (#4e15),a ; set number of lives displayed | |
069c ef rst #28 ; set task #1A, parameter #00 - draws remaining lives at bottom of screen | |
069d 1a 00 | |
069f f7 rst #30 ; set timed task to increment main routine 2, subroutine # (#4E03) | |
06a0 57 01 00 ; task data: timer=#57, task=01, parameter=0. | |
; also arrive here from #0246. This is timed task #01 | |
06a3 21 03 4E ld hl,#4E03 ; load HL with main routine 2, subroutine # | |
06a6 34 inc (hl) ; increase | |
06a7 c9 ret ; return | |
;; draw lives displayed onto the screen | |
06a8 21154e ld hl,#4e15 ; load HL with lives displayed on screen loc | |
06ab 35 dec (hl) ; decrement | |
06ac cd6a2b call #2b6a ; draw remaining lives at bottom of screen | |
06af af xor a ; A := #00 | |
06b0 32034e ld (#4e03),a ; clear main routine 2, subroutine # | |
06b3 32024e ld (#4e02),a ; clear main routine 1, subroutine # | |
06b6 32044e ld (#4e04),a ; clear level state subroutine # | |
06b9 21004e ld hl,#4e00 ; load HL with game mode address | |
06bc 34 inc (hl) ; inc game mode. game mode is now 3 = game is just now starting | |
06bd c9 ret ; return | |
; arrive here from #03CB or from #057C, when someone or demo is playing | |
06BE: 3A 04 4E ld a,(#4E04) ; load A with level state | |
06C1: E7 rst #20 ; jump based on A | |
06C2: 79 08 ; #0879 ; set up game initialization | |
06C4: 99 08 ; #0899 ; set up tasks for beginning of game | |
06C6: 0C 00 ; #000C ; returns immediately | |
06C8: CD 08 ; #08CD ; demo mode or player is playing | |
06CA: 0D 09 ; #090D ; when player has collided with hostile ghost (died) | |
06CC: 0C 00 ; #000C ; returns immediately | |
06CE: 40 09 ; #0940 ; check for game over, do things if true | |
06D0: 0C 00 ; #000C ; returns immediately | |
06D2: 72 09 ; #0972 ; end of demo mode when ms pac dies in demo. clears a bunch of memories. | |
06D4: 88 09 ; #0988 ; sets a bunch of tasks and displays "ready" or "game over" | |
06D6: 0C 00 ; #000C ; returns immediately | |
06D8: D2 09 ; #09D2 ; begin start of maze demo after marquee | |
06DA: D8 09 ; #09D8 ; clears sounds and sets a small delay. run at end of each level | |
06DC: 0C 00 ; #000C ; returns immediately | |
06DE: E8 09 ; #09E8 ; flash screen | |
06E0: 0C 00 ; #000C ; returns immediately | |
06E2: FE 09 ; #09FE ; flash screen | |
06E4: 0C 00 ; #000C ; returns immediately | |
06E6: 02 0A ; #0A02 ; flash screen | |
06E8: 0C 00 ; #000C ; returns immediately | |
06EA: 04 0A ; #0A04 ; flash screen | |
06EC: 0C 00 ; #000C ; returns immediately | |
06EE: 06 0A ; #0A06 ; flash screen | |
06F0: 0C 00 ; #000C ; returns immediately | |
06F2: 08 0A ; #0A08 ; flash screen | |
06F4: 0C 00 ; #000C ; returns immediately | |
06F6: 0A 0A ; #0A0A ; flash screen | |
06F8: 0C 00 ; #000C ; returns immediately | |
06FA: 0C 0A ; #0A0C ; flash screen | |
06FC: 0C 00 ; #000C ; returns immediately | |
06FE: 0E 0A ; #0A0E ; set a bunch of tasks | |
0700: 0C 00 ; #000C ; returns immediately | |
0702: 2C 0A ; #0A2C ; clears all sounds and runs intermissions when needed | |
0704: 0C 00 ; #000C ; returns immediately | |
0706: 7C 0A ; #0A7C ; clears sounds, increases level, increases difficulty if needed, resets pill maps | |
0708: A0 0A ; #0AA0 ; get game ready to play and set this sub back to #03 | |
070A: 0C 00 ; #000C ; returns immediately | |
070C: A3 0A ; #0AA3 ; sets sub # back to #03 | |
; arrive here from #000D | |
; sets up game difficulty | |
070e 78 ld a,b ; load A with parameter from task | |
070f a7 and a ; == #00 ? | |
0710 2004 jr nz,#0716 ; no, skip ahead | |
0712 2a0a4e ld hl,(#4e0a) ; else load HL with difficulty setting pointer. EG #0068 | |
0715 7e ld a,(hl) ; load A with difficulty, EG #00 | |
0716 dd219607 ld ix,#0796 ; load IX with difficulty table start | |
071a 47 ld b,a | |
071b 87 add a,a | |
071c 87 add a,a | |
071d 80 add a,b | |
071e 80 add a,b ; A is now 6 times what it was | |
071f 5f ld e,a | |
0720 1600 ld d,#00 | |
0722 dd19 add ix,de ; adjust IX based on current difficulty | |
0724 dd7e00 ld a,(ix+#00) ; load A with first value from table | |
0727 87 add a,a | |
0728 47 ld b,a | |
0729 87 add a,a | |
072a 87 add a,a | |
072b 4f ld c,a | |
072c 87 add a,a | |
072d 87 add a,a | |
072e 81 add a,c | |
072f 80 add a,b | |
0730 5f ld e,a | |
0731 1600 ld d,#00 | |
0733 210f33 ld hl,#330f ; load HL with start of data table - speeds of ghosts and pacman | |
0736 19 add hl,de ; add offset computed above | |
0737 cd1408 call #0814 ; copy data into #4d46 through #4d94 | |
073a dd7e01 ld a,(ix+#01) ; load A with second value from table | |
073d 32b04d ld (#4db0),a ; store. appears to be unused | |
0740 dd7e02 ld a,(ix+#02) ; load A with third value from table | |
0743 47 ld b,a ; copy to B | |
0744 87 add a,a ; A := A*2 | |
0745 80 add a,b ; A is now 3 times value in table | |
0746 5f ld e,a ; store in E | |
0747 1600 ld d,#00 ; D := #00 | |
0749 214308 ld hl,#0843 ; load HL with hard/easy data table check | |
074c 19 add hl,de ; add offset computed above | |
074d cd3a08 call #083a ; copy difficulty info to #4DB8 to #4DBA | |
0750 dd7e03 ld a,(ix+#03) ; load A with fourth value from table | |
0753 87 add a,a ; A := A * 2 | |
0754 5f ld e,a ; copy to E | |
0755 1600 ld d,#00 ; D := #00 | |
0757 fd214f08 ld iy,#084f ; load IY with data table start | |
075b fd19 add iy,de ; add offset | |
075d fd6e00 ld l,(iy+#00) ; | |
0760 fd6601 ld h,(iy+#01) ; load HL with table data | |
0763 22bb4d ld (#4dbb),hl ; store into remainder of pills when first diff. flag is set | |
0766 dd7e04 ld a,(ix+#04) ; load A with fifth value from table | |
0769 87 add a,a ; A := A * 2 | |
076a 5f ld e,a ; store into E | |
076b 1600 ld d,#00 ; clear D | |
076d fd216108 ld iy,#0861 ; load IY with start of table that controls time that ghosts stay blue | |
0771 fd19 add iy,de ; add offset | |
0773 fd6e00 ld l,(iy+#00) ; | |
0776 fd6601 ld h,(iy+#01) ; load HL with data from table | |
0779 22bd4d ld (#4dbd),hl ; store into time the ghosts stay blue when pacman eats a power pill | |
077c dd7e05 ld a,(ix+#05) ; load A with sixth value from table | |
077f 87 add a,a ; A := A * 2 | |
0780 5f ld e,a ; copy to E | |
0781 1600 ld d,#00 ; clear D | |
0783 fd217308 ld iy,#0873 ; load IY with start of difficulty table - number of units before ghosts leaves home | |
0787 fd19 add iy,de ; add offset | |
0789 fd6e00 ld l,(iy+#00) | |
078c fd6601 ld h,(iy+#01) ; load HL with data from table | |
078f 22954d ld (#4d95),hl ; store | |
0792 cdea2b call #2bea ; draw fruit at bottom of screen | |
0795 c9 ret ; return (to # 238D ?) | |
; -- difficulty related table | |
; each entry is 6 bytes | |
; byte 0: (0..6) speed bit patterns and orientation changes (table at #330F) | |
; byte 1: (00, 01, 02) stored at #4DB0 - seems to be unused | |
; byte 2: (0..3) ghost counter table to exit home (table at #0843) | |
; byte 3: (0..7) remaining number of pills to set difficulty flags (table at #084F) | |
; byte 4: (0..8) ghost time to stay blue when pacman eats the big pill (table at #0861) | |
; byte 5: (0..2) number of units before a ghost goes out of home (table at #0873) | |
0796 03 01 01 00 02 00 | |
079c 04 01 02 01 03 00 | |
07a2 04 01 03 02 04 01 | |
07a8 04 02 03 02 05 01 | |
07ae 05 00 03 02 06 02 | |
07b4 05 01 03 03 03 02 | |
07ba 05 02 03 03 06 02 | |
07c0 05 02 03 03 06 02 | |
07c6 05 00 03 04 07 02 | |
07cc 05 01 03 04 03 02 | |
07d2 05 02 03 04 06 02 | |
07d8 05 02 03 05 07 02 | |
07de 05 00 03 05 07 02 | |
07e4 05 02 03 05 05 02 | |
07ea 05 01 03 06 07 02 | |
07f0 05 02 03 06 07 02 | |
07f6 05 02 03 06 08 02 | |
07fc 05 02 03 06 07 02 | |
0802 05 02 03 07 08 02 | |
0808 05 02 03 07 08 02 | |
080e 06 02 03 07 08 02 | |
; called from #0737 | |
; copies difficulty-related data into #4d46 through #4d94 | |
; includes 4d58 which is blinky's normal speed | |
; include 4d86 which controls timing of reversals | |
0814 11464d ld de,#4d46 ; set destination | |
0817 011c00 ld bc,#001c ; set counter | |
081a edb0 ldir ; copy | |
081c 010c00 ld bc,#000c ; set counter | |
081f a7 and a ; clear carry flag | |
0820 ed42 sbc hl,bc ; subtract from source | |
0822 edb0 ldir ; copy | |
0824 010c00 ld bc,#000c ; set counter | |
0827 a7 and a ; clear carry flag | |
0828 ed42 sbc hl,bc ; subtract from source | |
082a edb0 ldir ; copy | |
082c 010c00 ld bc,#000c ; set counter | |
082f a7 and a ; clear carry flag | |
0830 ed42 sbc hl,bc ; subtract source | |
0832 edb0 ldir ; copy | |
0834 010e00 ld bc,#000e ; set counter | |
0837 edb0 ldir ; copy | |
0839 c9 ret ; return | |
; called from #0749 | |
083a 11b84d ld de,#4db8 ; load destination with #4DB8 | |
083d 010300 ld bc,#0003 ; set bytes to copy at 3 | |
0840 edb0 ldir ; copy | |
0842 c9 ret ; return | |
;-- table related to difficulty - each entry is 3 bytes | |
; b0: when counter at 4E0F reaches this value, pink ghost goes out of home | |
; b1: when counter at 4E10 reaches this value, blue ghost goes out of home | |
; b2: when counter at 4E11 reaches this value, orange ghost goes out of home | |
; these don't seem to be used in ms-pac at all. | |
0843 14 1e 46 00 1e 3c 00 00 32 00 00 00 | |
; hard hack: HACK6 | |
; 0843 0f 14 37 04 18 34 02 06 28 00 04 08 | |
; | |
; -- difficulty table -- | |
; each entry is 2 bytes | |
; b1: remaining number of pills when first difficulty flag is set (cruise elroy 1) | |
; b2: remaining number of pills when second difficulty flag is set (cruise elroy 2) | |
084f 14 0a | |
0851 1e 0f | |
0853 28 14 | |
0855 32 19 | |
0857 3c 1e | |
0859 50 28 | |
085B 64 32 | |
085D 78 3c | |
085F 8c 46 | |
; difficulty table - Time the ghosts stay blue when pacman eats a big pill | |
; -- do not use with l set up at #076D | |
0861 c0 03 ; 03c0 (960) 8 seconds (not used) | |
0863 48 03 ; 0348 (840) 7 seconds (not used) | |
0865 d0 02 ; 02d0 (720) 6 seconds | |
0867 58 02 ; 0258 (600) 5 seconds | |
0869 e0 01 ; 01e0 (480) 4 seconds | |
086b 68 01 ; 0168 (360) 3 seconds | |
086d f0 00 ; 00f0 (240) 2 seconds | |
086f 78 00 ; 0078 (120) 1 second | |
0871 01 00 ; 0001 (1) 0 seconds | |
; difficulty table - number of units before ghosts leaves home | |
; set up at #0783 | |
0873 f0 00 ; 00f0 (240) 2 seconds | |
0875 f0 00 ; 00f0 (240) 2 seconds | |
0877 b4 00 ; 00b4 (180) 1.5 seconds | |
; main routine #3. arrive here at the start of the game when a new game is started | |
; arrive from #04E5 or #06C1 | |
0879 21094e ld hl,#4e09 ; load HL with player # address | |
087c af xor a ; A := #00 | |
087d 060b ld b,#0b ; set counter to #0B | |
087f cf rst #8 ; clear memories from #4E09 through #4E09 + #0B | |
0880 cdc924 call #24c9 ; set up pills and power pills in RAM | |
0883 2a734e ld hl,(#4e73) ; load HL with difficulty | |
0886 220a4e ld (#4e0a),hl ; store difficulty | |
0889 210a4e ld hl,#4e0a ; load source with difficulty | |
088c 11384e ld de,#4e38 ; load destination with difficulty | |
088f 012e00 ld bc,#002e ; set byte counter at #2E | |
0892 edb0 ldir ; copy | |
; arrive here from #09CF | |
; this is also timed task #00, arrive from #0246 | |
0894 21044e ld hl,#4e04 ; load HL with main subroutine number | |
0897 34 inc (hl) ; increment | |
0898 c9 ret ; return | |
; arrive from #06C1 | |
0899 3a004e ld a,(#4e00) ; load A with game mode | |
089c 3d dec a ; are we in the demo mode ? | |
089d 2006 jr nz,#08a5 ; no, skip ahead | |
089f 3e09 ld a,#09 ; yes, load A with #09 | |
08a1 32044e ld (#4e04),a ; store in main subroutine | |
08a4 c9 ret ; return | |
08a5 ef rst #28 ; insert task #11 - clears memories from #4D00 through #4DFF | |
08a6 11 00 | |
08a8 ef rst #28 ; insert task #1C, parameter #83 - displays or clears text | |
08a9 1c 83 | |
08ab ef rst #28 ; insert task #04 - resets a bunch of memories and | |
08ac 04 00 | |
08ae ef rst #28 ; insert task #05 - resets ghost home counter | |
08af 05 00 | |
08b1 ef rst #28 ; insert task #10 - sets up difficulty | |
08b2 10 00 | |
08b4 ef rst #28 ; insert task #1A - draws remaining lives at bottom of screen | |
08b5 1a 00 | |
08b7 f7 rst #30 ; set timed task to increase the main subroutine number (#4E04) | |
08b8 54 00 00 ; task timer=#54, task=0, param=0 | |
08bb f7 rst #30 ; set timed task to clear the "READY!" message | |
08bc 54 06 00 ; task timer=#54, task=6, param=0 | |
08bf 3a724e ld a,(#4e72) ; load A with cocktail or upright | |
08c2 47 ld b,a ; copy to B | |
08c3 3a094e ld a,(#4e09) ; load A with current player # | |
08c6 a0 and b ; is this game cockatil mode and player # 2 ? If so , this value becomes 1 | |
08c7 320350 ld (#5003),a ; store into flip screen register | |
08ca c39408 jp #0894 ; loop back to increment level complete register and return | |
; demo or game is playing | |
08cd 3a0050 ld a,(#5000) ; load A with IN0 | |
08d0 cb67 bit 4,a ; is rack test on? | |
08d2 c2de08 jp nz,#08de ; no, skip ahead | |
08d5 21044e ld hl,#4e04 ; else rack switch on, so advance. load HL with game state | |
08d8 360e ld (hl),#0e ; store value of #0E. this signals end of level | |
08da ef rst #28 ; insert task #13 with parameter #00 - clears the sprites | |
08db 13 00 | |
08dd c9 ret ; return | |
;; routine to determine the number of pellets which must be eaten | |
08de 3a0e4e ld a,(#4e0e) ; load A with number of pellets eaten | |
; OTTOPATCH | |
;PATCH TO ADJUST THE TOTAL DOT NUMBER | |
ORG 08E1H | |
JP MOREDOTS | |
NOP | |
08e1 c3a194 jp #94a1 ; jump to ms pac man new check for end of level routine | |
08e4 00 nop ; junk | |
; returns here if the level is complete | |
08e5 21044e ld hl,#4e04 ; load HL with game state | |
08e8 360c ld (hl),#0c ; store value of #0C, signals end of level | |
08ea c9 ret ; return | |
;; pacman original: | |
; 08de 3a0e4e ld a,(#4e0e) ; load A with number of pellets eaten | |
; 08e1 fef4 cp #f4 ; == 244 ? | |
; 08e3 2006 jr nz,#08eb ; No, jump ahead | |
; 08e5 21044e ld hl,#4e04 ; Yes, then end of level. Load HL with main subroutine # | |
; 08e8 360c ld (hl),#0c ; store #0C into main sub #to signal end of level | |
; 08ea c9 ret ; return | |
;; | |
; returns here if level is not complete | |
; core game loop | |
08eb cd1710 call #1017 ; another core game loop that does many things | |
08ee cd1710 call #1017 ; another core game loop that does many things | |
08f1 cddd13 call #13dd ; check for release of ghosts from ghost house | |
08f4 cd420c call #0c42 ; adjust movement of ghosts if moving out of ghost house | |
08f7 cd230e call #0e23 ; change animation of ghosts every 8th frame | |
08fa cd360e call #0e36 ; periodically reverse ghost direction based on difficulty (only when energizer not active) | |
08fd cdc30a call #0ac3 ; handle ghost flashing and colors when power pills are eaten | |
0900 cdd60b call #0bd6 ; color dead ghosts the correct colors | |
0903 cd0d0c call #0c0d ; handle power pill (dot) flashes | |
0906 cd6c0e call #0e6c ; change the background sound based on # of pills eaten | |
0909: CD AD 0E call #0EAD ; check for fruit to come out. (new ms. pac sub actually at #86EE.) | |
090C: C9 ret ; return ( to #0195 ) | |
; arrive here from #06C1 when player has died | |
090d 3e01 ld a,#01 ; A := #01 | |
090f 32124e ld (#4e12),a ; store into player dead flag | |
; 4e12 1 after dying in a level, reset to 0 if ghosts have left home | |
; because of 4d9f | |
0912 cd8724 call #2487 ; save pellet info to memory | |
0915 21044e ld hl,#4e04 ; load HL with main subroutine number | |
0918 34 inc (hl) ; increase it | |
0919 3a144e ld a,(#4e14) ; load A with number of lives left | |
091c a7 and a ; == #00 ? | |
091d 201f jr nz,#093e ; no, skip ahead | |
091f 3a704e ld a,(#4e70) ; else game over. load A with number of players (0=1 player, 1=2 players) | |
0922 a7 and a ; is this a one player game? | |
0923 2819 jr z,#093e ; yes, skip ahead | |
0925 3a424e ld a,(#4e42) ; else load A with game state | |
0928 a7 and a ; is this the demo mode ? | |
0929 2813 jr z,#093e ; yes, skip ahead | |
092b 3a094e ld a,(#4e09) ; else load A with current player number: 0=P1, 1=P2 | |
092e c603 add a,#03 ; add #03, result is either #03 or #04 | |
0930 4f ld c,a ; store into C for call below | |
0931 061c ld b,#1c ; load B with #1C for task call below | |
0933 cd4200 call #0042 ; insert task to draw to screen either "PLAYER ONE" or "PLAYER TWO" | |
0936 ef rst #28 ; insert task to draw "GAME OVER" | |
0937 1c 05 | |
0939 f7 rst #30 ; set timed task to increase the main subroutine number (#4E04) | |
093a 54 00 00 ; task timer=#54, task=0, param=0 | |
093d c9 ret ; return | |
093e 34 inc (hl) ; increase game state | |
093f c9 ret ; return | |
; arrive from #06C1 | |
0940 3a704e ld a,(#4e70) ; load A with number of players | |
0943 a7 and a ; == #00 ? | |
0944 2806 jr z,#094c ; yes, skip ahead if 1 player | |
0946 3a424e ld a,(#4e42) ; else load A with game state | |
0949 a7 and a ; is a game being played ? | |
094a 2015 jr nz,#0961 ; yes, skip ahead and switch from player 1 to player 2 or vice versa | |
094c 3a144e ld a,(#4e14) ; else load A with number of lives left | |
094f a7 and a ; are there any lives left ? | |
0950 201a jr nz,#096c ; yes, jump ahead | |
; change 0950 to | |
; 0950 18 1a jr #096C ; always jump ahead | |
; for never-ending pac goodness | |
0952 cda12b call #2ba1 ; else draw # credits or free play on bottom of screen | |
0955 ef rst #28 ; insert task #1C , parameter #05 . Draws text on screen "GAME OVER" | |
0956 1c 05 ; task data | |
0958 f7 rst #30 ; set timed task to increase main subroutine number (#4E04) | |
0959 54 00 00 ; task timer=#54, task=0, param=0 | |
095c 21044e ld hl,#4e04 ; Load HL with level state subroutine # | |
095f 34 inc (hl) ; increment | |
0960 c9 ret ; return | |
; arrive here from #094a when there 2 players, when a player dies | |
0961 cda60a call #0aa6 ; transposes data from #4e0a through #4e37 into #4e38 through #4e66 | |
0964 3a094e ld a,(#4e09) ; load A with current player number: 0=P1, 1=P2 | |
0967 ee01 xor #01 ; flip bit 0 | |
0969 32094e ld (#4e09),a ; store result. toggles between player 1 and 2 | |
096c 3e09 ld a,#09 ; A := #09 | |
096e 32044e ld (#4e04),a ; store into level state subroutine # | |
0971 c9 ret ; return | |
; arrive from #06C1 when subroutine# (#4E04)= #08 | |
; zeros some important variables | |
; arrive here after demo mode finishes (ms pac man dies in demo) | |
0972 af xor a ; A := #00 | |
0973 32024e ld (#4e02),a ; clear main routine 1, subroutine # | |
0976 32044e ld (#4e04),a ; clear level state subroutine # | |
0979 32704e ld (#4e70),a ; clear number of players | |
097c 32094e ld (#4e09),a ; clear current player number | |
097f 320350 ld (#5003),a ; clear flip screen register | |
0982 3e01 ld a,#01 ; A := #01 | |
0984 32004e ld (#4e00),a ; set game mode to demo | |
0987 c9 ret ; return (to #057F) | |
; arrive from #06C1 when (#4E04==#09) when marquee mode ends or after player has been killed | |
; or from #06C1 when (#4E04 == #20) when a level has ended and a new one is about to begin | |
0988 ef rst #28 ; set task #00, parameter = #01. - clears the maze | |
0989 00 01 | |
098b ef rst #28 ; set task #01, parameter = #01. - colors the maze | |
098c 01 01 | |
098e ef rst #28 ; set task #02, parameter = #00. - draws the maze | |
098f 02 00 | |
0991 ef rst #28 ; set task #11, parameter = #00. - clears memories from #4D00 through #4DFF | |
0992 11 00 | |
0994 ef rst #28 ; set task #13, parameter = #00. - clears the sprites | |
0995 13 00 | |
0997 ef rst #28 ; set task #03, parameter = #00. - draws the pellets | |
0998 03 00 | |
099a ef rst #28 ; set task #04, parameter = #00. - resets a bunch of memories | |
099b 04 00 | |
099d ef rst #28 ; set task #05, parameter = #00. - resets ghost home counter | |
099e 05 00 | |
09a0 ef rst #28 ; set task #10, parameter = #00. - sets up difficulty | |
09a1 10 00 | |
09a3 ef rst #28 ; set task #1A, parameter = #00. - draws remaining lives at bottom of screen | |
09a4 1a 00 | |
09a6 ef rst #28 ; set task #1C, parameter = #06. Draws text on screen "READY!" and clears the intermission indicator | |
09a7 1c 06 | |
09a8 3a004e ld a,(#4e00) ; load A with game state | |
09ac fe03 cp #03 ; is someone playing ? | |
09ae 2806 jr z,#09b6 ; Yes, skip ahead | |
09b0 ef rst #28 ; set task #1C, parameter = #05. Draws text on screeen "GAME OVER" | |
09b1 1c 05 | |
09b3 ef rst #28 ; set task #1D - write # of credits on screen | |
09b4 1d 00 | |
09b6 f7 rst #30 ; set timed task to increase main subroutine number (#4E04) | |
09b7 54 00 00 ; taks timer = #54, task = 00, parameter = 00 | |
09ba 3a004e ld a,(#4e00) ; load A with game sate | |
09bd 3d dec a ; is this the demo mode ? | |
09be 2804 jr z,#09c4 ; yes, skip next step | |