Porting Meteor Mission II to Microbee

Part 5 - Improving the Debugger and More Keyboard Work

This article continues on from Part 4 - Keyboard and Flashing Text.

In getting this far with Meteor's port I've been using ubee512's debugger fairly heavily. Unfortunately, it was still a tedious process and since it looked like some of the upcoming problems were going to be pretty nasty I decided to contact ubee512's developer Stewart Kay about improving the debugger. I've now made a number of changes that will be sent back to Stewart who will consider them for inclusion in the next version. In the meantime, these are the new features I've added to my local build:

  1. Memory read/write breakpoints - this is an incredibly useful way to find issues (see below).
  2. Added the ability to step over function calls (--db-step=o);
  3. Added the ability to step out of a function call (--db-step=x);
  4. Improved the interaction between the console (where the debugger runs) and the main emulator window so that you don't need to switch back to the emulator for z80 code to execute.

The above combined with a few macros in the ubee512rc config files:

[s]
--db-step=1

[o]
--db-step=o

[c]
--db-step=0

[regs]
--db-dumpr

[x]
--db-step=x

[t]
--db-step=c

and suddenly the debugger becomes pretty powerful and much easier to use.

Fixing the Corrupted Landing Pad Scores

So armed with the upgraded debugger and following my theory of tackling the simplest issues first my next goal was to fix the corrupted score indicators on the landing pads. My idea here was to calculate the memory address of the first landing pad score, and set a memory write break-point to see if I could find the code writing to it.

meteor_port5.png

I grabbed a snap shot of the screen, loaded it into a graphics editor and calculated the character number of the score indicator - row 14, column 14 and converted it to an offset into the video frame buffer = 0xF000 + 64 * 14 + 14 = 0xF38E.

Next I ran up the game, let it start, and then jumped into the console and set a memory write break-point:

ubee512>--db-bp-mem=w,0xF38E
ubee512>c
0e5e: ldir                t16/21 FLG: --P---Z- AF:0044 BC:0031 DE:f38f HL:3c0f
Z80 'Write to memory address 0xf38e' Debugging break point at PC: 0x0e5e
0e5e: ldir                <---
ubee512>

So that area of the screen was getting copied from 0x3C0e. Looking back at my annotated asm listing showed that this area was in an area I'd previously figured out to be an off-screen buffer. It looks like the game has two such buffers - one containing the static background and one containing the rendered screen which is then transferred to the real video buffer. So I cleared that break point and set one on the off-screen buffer:

ubee512>--db-bpclr-mem=w,0,0xFFFF
ubee512>--db-bp-mem=w,0x3c0E
ubee512>c
0e5e: ldir                t16/21 FLG: --P---Z- AF:2f6c BC:0031 DE:3c0f HL:400f
Z80 'Write to memory address 0x3c0e' Debugging break point at PC: 0x0e5e
0e5e: ldir                <---
ubee512>c
22aa: ldir                t16/21 FLG: --P----- AF:3104 BC:0001 DE:3c0f HL:17aa
Z80 'Write to memory address 0x3c0e' Debugging break point at PC: 0x22aa
22aa: ldir                <---
ubee512>

The first stop looks like the background buffer getting cleared using the static buffer. The second stop looks suspicious. Going back to the ASM listing though and there it was - a memory address that I missed in the original conversion. Fixed.

Fixing the Weird Bouncing Flagship

Next I thought I'd tackle the flagship that was appearing the the top left corner:

meteor_port7.png

I tried a similar approach to above but it led to some pretty complex code - I think the core of the game and the graphics rendering code. After about half hour of that I decided to try something else. This time I set a memory read and a memory write breakpoint on the area of memory where the game used to reside - figuring that any other addresses that I missed would end up reading or writing from that area. The game used to reside at 0x4500 and the stack grows down from 0x8000 so:

ubee512>--db-bp-mem=w,0x4500,0x7f00
ubee512>--db-bp-mem=r,0x4500,0x7f00

Ran up the game and immediately hit a break-point - after which it took about 30 seconds to trace back to another missed address. Now it's looking a lot better, with even the little men at the bottom re-appearing.

meteor_port8.png

In retrospect, this is a pretty powerful way to find these issues and wish I had the debugger functionality (and the idea) from the very start.

More Keyboard Work.

In the previous article where I first addressed the keyboard port I mentioned that some of the keyboard handling I temporarily disabled. Since I now had the game basically running it was time to fix that up. In the end this was more an exercise in reverse engineering the code and re-implementing it.

Starting with the 'R' key used to release the ship and to fire the retro rockets. The code was easy to find and this:

       LD      A,(3804h) 
       AND     04h                        ; 'R' Key
       LD      B,A
       LD      A,(3840h)
       AND     80h                        ; Enter Key
       OR      B
       LD      B,A
       IN      A,(13h)
       CALL    L4C71_sndout
       CPL
       AND     13h
       INC     A
       AND     14h
       OR      B
       RET

became this:

       LD       A,KEY_R
       call     isKeyDown
       JR       Z,r_pressed
       LD       A,KEY_SPACE
       call     isKeyDown
       JR       Z,r_pressed
       XOR      A
       RET
r_pressed:
       LD       A,1
       OR       A
       RET

The arrows keys for left right was similar though a little more complex:

check_left_key:
       LD      A,KEY_LEFT
       CALL    isKeyDown
       JR      Z,left_arrow_pressed
       LD      A,KEY_COMMA
       CALL    isKeyDown
       JR      Z,left_arrow_pressed
       LD      B,0
       JR      check_right_key
left_arrow_pressed:
       LD     B,20h

check_right_key:
       LD     A,KEY_RIGHT
       CALL   isKeyDown
       JR     Z,right_arrow_pressed
       LD     A,KEY_PERIOD
       CALL   isKeyDown
       JR     Z,right_arrow_pressed
       LD     C,0
       JR     keys_checked
right_arrow_pressed:
       LD     C,40h

keys_checked:
       LD     A,B
       OR     C

I now had a playable game!

Although, on getting the highest score though was presented with this:

meteor_port9.png

Hrm... I reckon that'll be those calls to the TRS80 Basic routines that I mentioned in the first article.

Getting close now (I think).

Porting Meteor Mission II to Microbee continues with Part 6 - Replacing the TRS80 ROM Basic Calls.