Skip to main content

Diagnosing and fixing a couple of sprite issues with my TMS9918A emulator

Recently I've been working on a small hardware enhancement for my TMSEMU board for RC2014 to allow it to be used with my MSX2014 and perhaps more importantly, with MSX ROMs running on the CP/M RC2014

Anyway, I've reduced the additional circuit to a single logic IC and couple of passives, so I'll be adding that to the TMSEMU board very soon. You can see the additional circuitry on a bit of proto board in this picture, and you can see the fantastic picture that the TMSEMU gives to my MSX2014 (and to any RC2014).

However, this showed up a couple of problems that I hadn't been aware of with my TMS emulation, specifically with sprites.

The first happens with the game 'The Goblin' (sorry for the reflection). The screen should be blank other than the decorative border at that point but many sprites are still showing.

The second shot shows one of my favourite games, Keystone Kapers, you can see bits of sprites appearing in the top border. These problems may or may not be unrelated. 

Obviously in both cases, sprites should be hidden but are showing.

Ways to hide sprites when you don't need them on the screen

  1. There's a special bit in the sprite's attributes which moves the sprite 32 pixels to the left. It's used for moving a sprite into the screen from the left. The documentation does say 32 pixels, so even for a magnified sprite which is 32 pixels wide, it should be totally off screen if its x coord is zero. A 16x16 sprite could definitely be shifted offscreen using this method.
  2. It may be moved entirely off the top/bottom of the screen. There are only 192 scanlines in the picture area, which means that Y values in the C0-E0 range will put a 16x16 or 32x32 sprite entirely in the border area and therefore not visible.
  3. If a sprite contains a special value D0 in its Y position, then that means 'stop processing' and all sprites after that in the table will be invisible. This is very useful because you can blank out many or all sprites by changing a single byte.
  4. A sprite's colour byte can be set to 0 (transparent) to render the sprite invisible 
  5. A sprites 'name' byte (pointer to the sprite data table) can be changed to point to sprite data that contains all zeros - then the sprite will have no visible pixels
  6. Sprites are not active in text mode

There may be more. Let me know if I've missed something off this list.

Some of these can be ruled out for the Goblin issue. The most likely suspect would be number 3, the D0 trick. 

I was confident that I had implemented and tested this feature in TMSEMU (as well as all of the other things in this list). 

Analysing these problem was tricky because they happened with a couple of specific games on my MSX computer. I couldn't easily examine the code to see what they were doing to hide the sprites at that point.

I thought about disassembly. I guess I could have spoken to the authors of the games.

It would be very helpful to examine the data in the sprite attribute table, and the VDP registers, at the point that the problem happens. Looking back now, maybe one of the emulators has a monitor that I could have used for this purpose.

I'm a printf person when it comes to debugging. My emulator is based on an RP2040 which can do serial, in fact it already monitors the serial line on the bus to act as a terminal when in text mode.

Here is my answer. It looks unsightly but it worked beautifully. Behind the regular TMSEMU with its currently-bodged-on circuitry is another TMSEMU which has been butchered. Parts of the hardware are removed because it doesn't need to put anything on the bus, just listen. And the software is severely cut-down to take out the DVI functionality and other things, and to send debugging information. (It would have been nice to use the micro-USB for serial out, but for reasons I don't understand, the way that I'm using interrupts in TMSEMU breaks the built-in serial, leaving me with PIO UART). 

It took a lot of work to develop that, but  it works beautifully!

It shows me a dump of the sprite attribute table as well as a couple of registers I wanted to see. At the point when the problem happens in the Goblin game, we can see clearly that the D0 trick is being used to turn off all the sprites as suspected (highlighted in the above shot.)

I don't know whether to admit this or not, but I've made an ass out of u and me by believing my own memory of implementing that feature. When I looked at the appropriate code I found this:

What that means is that I did implement the feature, it was working. But then I fixed another minor issue with the sprite display order which broke the D0 feature. I was well aware of that and left a note for myself to fix it. Which I did not do.

That fixed the problem with the Goblin game. The screen now looks as it should in between levels or after losing a life. 

But it didn't fix the Keystone Kapers problem, so they were unrelated. 

The spurious sprites were appearing in the border area, which shouldn't happen under any conditions. 

I wrote a program (or adapted an existing demo) to display these sprites and decrement the Y positions slowly pixel by pixel, for all 256 values of the Y position byte. I watched it without daring to blink until my eyes dried out, but it correctly disappeared as it went up into the border and reappeared at the bottom within the screen area.

once again the debug data came into its own! No D0 trick here (though they are being moved up into the border area - see the E0's). The sprites are once again 16x16 and unmagnified, as per my little test program. But those two status registers show that the screen mode is in 'graphics mode 1' or tile mode, not graphics II / bitmap. And this made the difference - bingo!

Again, the hard part was diagnosing and reprocuding the problem. The fix was simple.

Now I can play Keystone Kapers with sharp video and no disembodied bits of enemy in the screen border!

I'll apply the sprite fix to TMSEMU modules that leave here from now on. The addition to the hardware to help with MSX ROMs will probably take a couple of weeks.


Comments

Popular posts from this blog

RC2024/10 - my entry

A while ago I made this MIDI module for RC2014: It works but a better design would have its own serial chip and port decoding.  As it is, it provides the MIDI interface and a clock signal for the second SIO2 serial port. This means that it requires a little setting up and will only work for RC2014s with an SIO2 (and port B not already used). I think people might reasonably expect it to be plug-and-play and self-contained, ie do all the serial itself. My challenge to myself is to:  learn how to connect a serial chip (probably 68B50 ACIA) to receive the incoming MIDI and to serialise outgoing MIDI design the module, including the port decoding write a library so that it can easily be used on any RC2014. Potential applications include a MIDI sequencer and using incoming MIDI to trigger notes on the AY or SID sound chips. Entering the Retro Challenge 2024 (aka RC2024/10)  has given me an incentive to get on with this! I'm happy to see several more entries in the RC2014 catego...

IM53 8080 birthday cake

 Each year I've been trying to get more creative with ideas for Spencer's birthday cake. The plan this year was to incorporate LEDs in place of candles. I eventually settled on an Altair / IMSAI / PDP -style computer since those are the type of computers that inspired his RC2014. The IMSAI 8080 has the most colourful switches as well as a name that I could twist. The thought that it could show randomly flashing lights (as if the computer were running) and that it could also play a game of 'kill the bit' was very appealing. A plan formed to use a capacitive touch pad on the cake itself. The first job is to bake the fruitcake. I often use a 7" square tin and one of those cut in half and rearranged makes a cake of suitable proportions.  Even after taking a slice off the faces to make them nice and square, there are still some rounded corners, so after putting on the marzipan, I used more marzipan as a filler to flatten the whole thing. Even though I wanted to end up w...

How to convert images for TMS9918A graphics on the RC2014

For me, graphics capability is essential for an 8-bit computer. My graphics chip of choice for the RC2014 is the very capable TMS9918A. It has 15 colours, sprites, several modes and a max resolution of 256x192. It makes arcade-style games possible, such as Tut-Tut above.  I enjoy simply displaying images and have a bunch on my CF card (my 'hard drive') and have written image viewer and slideshow apps to display them. Some useful links: Convert9918 Tutorial of Convert9918's settings Multipaint J B Langston's TMS9918A video module my own TMSEMU video module my respository of TMS9918A software, games and .s2/.sc3 images Image conversion I did dabble in writing my own utility to convert .png images but then settled on the Multipaint app which can open a png in a MSX 'screen 2', allow you to tidy it up with paint tools and save as a .sc2 file. (An sc2 file is little more than a video-memory dump and so it's easy to blast that back into vram to display the image....