Sunday 26 February 2017

Everyone's a Wally (Mikro-Gen) Part 1

I bought Everyone's a Wally as a budget title back in the 80s on cassette for the Commodore 64.  I owned and played several of the Wally games but kept going back to this one, although I never got close to finishing it.

Everyone's a Wally (C64) - Town square

Looking at the game now, it was certainly very well-featured for the budget price.  There are 5 playable characters you can switch between and they continue to roam the map and pick up/drop objects as they go around.  There's several interesting puzzles to complete and the aim of the game is to collect several letters (B-R-E-A-K) and take them to the Bank to finish.  If all this wasn't enough, the graphics are bright and colourful, there's a back story for all the characters and there's a music single on the B side of the tape.

The first puzzle game I really got into in a big way was Adventure for the Atari 2600 and this game is similar in some respects, e.g. objects being moved around randomly by other characters (The Bat), nasties roaming the map (Dragons), puzzles (Keys/Castles/Bridge/Magnet), collecting items and taking them to a special location to finish the game (Chalice and Yellow Castle).

This YouTube video has the Mike Berry song from the tape B side and shows the C64 gameplay.  Note the character inventory in the top left and the energy/lives at top right.

 

Back in the day I found the game difficult to complete because I ran out of lives quickly and it's often time consuming to track down specific items as they could either be carried by another character or in one of the many locations.  The longer you roam the map looking for items, the greater the likelihood of running into a nasty.  I didn't have any pokes for the game and my early Datel Action Replay Mk IV couldn't locate the lives counter.

Looking at the game today, the newer Action Replay Mk VI correctly finds the code for decrementing the lives counter (for all characters) as follows:

Infinite lives poke:
POKE 36317,189        (Switches STA to LDA instruction)

However, that's way too easy.  Let's hack this the hard way for fun and get a better understanding of the Commodore 64 memory map and play with some 6502.

I used the following cracked .d64 for this (I do own the physical tape so don't judge me!).

006980209167de90736f18fd032e059b  Everyone's a wally.DC.d64

Infinite Lives

The game sets up the 64's VIC-II graphics as follows:

CIA2 Port A
$DD00 = $C4 (1100 0100)

VIC-II Bank = 3 (00), memory mapped $c000-$ffff

VIC-II Mode
$d011 = $bb (1011 1011) Bitmap Mode, Extended bg mode off
$d016 = $c8 (1100 1000) Multicolour mode off
$d018 = $39 (0011 1001) Char memory 1xx = $2000-$3fff
                        Screen memory 0011 = $0c00-$0fff

So we're running in VIC-II bitmap mode at 320x200.

    Screen memory (colour)  = $cc00-cfff
    Bitmap/Character memory = $e000-$efff

Let's find the character memory location where the lives (heart symbols) are drawn on screen.  We can do this with maths or by trial and error writing to $e000 onwards.

$e3a0-$e3a7

We can overwrite the character with FF to prove this is the correct location:
> f e3a0 e3a7 ff

Let's watch this memory location for updates.

watch e3a0

Now touch a nasty and/or lose a life.  Note how both the energy bar and the lives remaining are always redrawn every time energy is decremented even if a life isn't actually lost.

#4 (Stop on  load e3a0)  098 037
.C:3c2d  91 0A       STA ($0A),Y    - A:6C X:24 Y:00 SP:78 ..-..I..  171937243
.C:3c2f  C8          INY            - A:6C X:24 Y:00 SP:78 ..-..I..  171937243


Add breakpoint on 3c2d where bitmap memory update occurs.

break $3c2d

#6 (Stop on  exec 3c2d)  106 049
.C:3c2d  91 0A       STA ($0A),Y    - A:6C X:24 Y:00 SP:78 ..-..I..  125117167
(C:$3c2d) bt
(0) 8e0f
(2) 9acc
(4) 4f07
(6) 4edb
(118) 0b77
(131) a677


$3bd5 subroutine updates the lives bitmap (decrement happens before this)

.C:8de2  4C 51 43    JMP $4351
.C:8de5  84 42       STY $42
.C:8de7  A9 70       LDA #$70
.C:8de9  85 0C       STA $0C
.C:8deb  A9 92       LDA #$92
.C:8ded  8D EE 3B    STA $3BEE
.C:8df0  A9 83       LDA #$83
.C:8df2  8D F5 3B    STA $3BF5
.C:8df5  A6 0F       LDX $0F
.C:8df7  BD 18 5C    LDA $5C18,X    ; Probably lives?
.C:8dfa  85 23       STA $23

.C:8dfc  C6 23       DEC $23
.C:8dfe  A2 24       LDX #$24
.C:8e00  A0 02       LDY #$02
.C:8e02  84 24       STY $24
.C:8e04  A5 23       LDA $23
.C:8e06  D0 05       BNE $8E0D
.C:8e08  A9 20       LDA #$20
.C:8e0a  4C 0F 8E    JMP $8E0F
.C:8e0d  A9 1F       LDA #$1F
.C:8e0f  20 D5 3B    JSR $3BD5


Looks like lives are probably stored in memory at $5c18 onwards:
The offset is for the character being played (5 different characters).

>C:5c18  03 03 03 03  03 00 08 10  18 20 00 00   ......... ..

Lose a life (Wally)...
>C:5c18  02 03 03 03  03 04 0c 14  1c 20 00 00   ......... ..

Yep, this is it.  Let's prove it by restoring the starting number of lives (Wally):
> 5c18 3

Watch this memory location for writes...

watch store 5c18
WATCH: 10  C:$5c18  (Stop on store)

#10 (Stop on store 5c18)  033 050
.C:8ddd  DE 18 5C    DEC $5C18,X    - A:80 X:00 Y:01 SP:7a ..-..I.C  215883977
.C:8de0  D0 03       BNE $8DE5      - A:80 X:00 Y:01 SP:7a ..-..I.C  215883977



Found it! Remaining lives counters are decremented by the DEC instruction at $8ddd


Remove the 3 byte DEC instruction and test it:
a 8ddd
nop
nop
nop
x

Yes, we now have unlimited lives.  Let's make this an Action Replay style poke by switching the STA to an LDA instruction with the same addressing mode which takes the same number of bytes in memory.

Infinite lives poke:
POKE 36317,189        (Switch STA to LDA instruction)


Note that this poke matches the poke determined by Datel's Action Replay Mk VI cartridge (see above), which demonstrates just how clever that cartridge was.

Remaining lives memory locations:

    5c18    Lives Wally
    5c19    Lives Wilma
    5c1a    Lives Tom
    5c1b    Lives Dick
    5c1c    Lives Harry

More tracing and disassembly to come in the next post...

No comments:

Post a Comment