iain's development activities. May contain z80, Cocoa, or whatever.

20 January 2023

My time has been split between various different things, so I’ve not had as much time as I’d have liked to work on the scrolling, but what time I did have has been spent trying to fix niggling little bugs in the various different odd and even scrolling routines, sharing code and things like that. I got one pixel per update working, but it still felt slow and the code was very complex with the start of each routine having to set up the different values and subroutines necessary to share some code with lots of SMC code.

So, I had a think and put in some profiling code, and I think it was taking a frame and a half to draw the screen each time. If this code is to ever become something more than an experiment, if it would turn into a game, then that’s far too much, because we still need all the other sprites drawn, all the animation handled, all the game logic handled, keyboard processing, music and sfx processing… and there doesn’t seem like there’s time left for that.

The outcome is that I’ve simplified the code so now it only draws the even frames: 2 pixels per update. This makes things so much simpler, the odd offset code means it never needs to merge nibbles from screen with sprite nibbles and one path for drawing every time. It also reduces the memory usage as the map tiles don’t need to be shifted. It also makes the scrolling move at double speed, so I can make it only update the screen once every 2 frames to get the same speed as 1 pixel per update and suddenly I’ve regained an entire screen refresh for logic stuff.

11 January 2023

Slow few days. Have the even clip code done and am now adjusting it to work for the odd clips as well. Most of the last few days has been spent agonising about how to improve the speed and keep the code maintainable. For example, the code for drawing the even/odd maps are identical except for three subroutine calls, and I was trying to find the best way to not duplicate this code, but not add too much extra time to each frame. I tried jump tables and vector tables and finally the thing that worked was just using self modifying code to change the addresses that get called every frame. But that added about 60 t-states to each frame over just having the same code duplicated twice.

I had resigned myself to just maintaining two copies of slightly complex code, but then I realised that if I can move the memory page switching code to just switch pages once at the start of each frame then I’ll save 100 t-states per tile, which for the level I’m using to test works out as a saving of about 15,000 t-states, so I shouldn’t worry too much about adding 60 t-states per frame.

6 January 2023

Tile overdraw is now working and drawing is much faster now we don’t need to blank the whole play area each frame. It’s just too slow at the moment to run without double buffering especially once the clipped tiles get drawn. Going to go back to those soon, to get scrolling “finished”.

Currently the screen is drawn between lines 44 and 148, but the draw routine is synced to the vblank interrupt. Technically I could move it down to the bottom of the screen to give more drawing time, but I quite like having it centred in the screen. The Sam Coupé does have per line interrupts, so I could set a line interrupt at line 148 and sync the drawing to that. But ultimately, any extra time gained there would end up being lost when game logic and sprites were introduced to the so we’d end up back at square one and have to double buffer anyway.

5 January 2023

Still working on tile overdraw to erase any tile. Ended up spending time playing with the less used jp conditionals like m, po, and pe, which I will never remember what they actually mean. p means that the sign didn’t change, m checks that it did. So it lets us do to check when a was 0, like in a decrement loop.

dec a
jp m, noReset
ld a, 7
noReset:

if you want to loop from 7 -> 0 and then reset back to 7. The alternative would be to check for 0 before the dec which is larger and slower and is going to need multiple jumps.

4 January 2023

Tiles are 8x8. In the zeroOffset and evenOffset case we just draw the 8 pixels of width, but because tiles are shifted 1 nibble right in the oddOffset case we end up drawing 10 pixels, with the right hand pixel being set to the background colour. It occurred to me that if we drew the 10 pixels in zeroOffset and evenOffset as well, with the right most two pixels set to the background colour that would erase any previous content, removing the need for a clearPlayarea call. A quick test suggests it works greatly increases the scrolling speed although there’s still something wrong with it.