M/C SCREEN$?

Back in June Peter Jones (Hi Peter, hope you’re still reading?) asked after a machine-code version of the BASIC SCREEN$ command, to help him convert a BASIC program.  At the time I briefly replied that it wasn’t the best way to do things in m/c, and now I’ll explain why, and what a better alternative is.

Firstly,  lets look at what the SCREEN$ command does – it tells you the character which is on the screen at a certain position.  The Spectrum uses the modified version of the ASCII character set, and can print 96 different characters from it, starting with a space character (ASCII value 32), and ending with the copyright symbol (value 127).  The Spectrum also allows you to print inverted versions of all those characters – doubling the possibilities to 192.  And as we know, each character is stored in 8 bytes – one for each row.

What that means is that the SCREEN$ command has to find the location in screen memory which you want to check, and then work through every possible character which can be shown, trying to match it with what it finds on the screen.  As you might imagine, this can take some time.  It’s also not a consistent amount of time – for example, if the character on the screen is a space (i.e. empty) the command returns very quickly, as it’s the first character it tests, but if it’s the copyright symbol that’s at the end of the range it tests, and so it’s had to work through, and discount, all the other characters in the range before it matches that.  In the confines of a BASIC program, you probably wouldn’t notice the time it takes, because every instruction is slow compared to machine code, but in a game that kind of exhaustive searching isn’t at all optimal, and so is avoided when possible.

Now, we could be more efficient than the BASIC version if we know which characters we are going to print, and so reduce the range of characters which we have to check for, and we might also be able to remove testing for the inverted form of the character, again, as we know what we’re going to print, but it’s still not a very good way of doing things.

So what’s the alternative?  The answer is really quite simple – what if we had a version of the screen which stored which character we wrote to it, instead of the actual graphic represented by that character?  If we had that, we could just read the value directly, and it would be a fast and constant-time routine.  In BASIC this would be a 2D array of 32 x 24 values – one for each character position – something like DIM c(32,24) – in machine code we’d do the same, and reserve a block of memory 768 bytes in size, and use methods similar to that of writing colours to the screen to interact with it.

So that’s a solution to the problem of SCREEN$, but the concept can be used for many other things.  What we’ve done is logically split what you see on the screen from a more abstract version of what describes it, and that’s how you setup levels for a game, or a big scrolling map.  In a Boulder-Dash style game, you would make an array as large as the level, and use each entry to describe what it stores – a boulder, soil, gem, wall, and so on – and use that to populate the screen, and know how to react when the player, or anything else, moves on the map.

 

Advertisements

3 thoughts on “M/C SCREEN$?

    1. When I originally started to learn machine code I was using a book which used a lot of ROM routines, and so my first game also did, as that was the way I had been taught. The game I wrote wasn’t what I wanted to write though, as everything seemed slow, and I had to limit what the game was in order for it to run at a reasonable rate. It was only later that I discovered that it was those ROM routines that were the reason it was slow, and that much faster code could be written to replace them. Ever since then I’ve largely ignored the ROM.

      I think it helps to know exactly how each aspect of your code works, rather than using ‘Black Box’ ROM routines which do the thing you want, but slowly. It also helps if you ever try your hand at writing for a different machine, as you aren’t forced to try and find similar ROM routines on that new machine. This came in very handy when I moved from the Spectrum to the ZX81, where the ROM is very different.

      You can easily download a copy of the Spectrum ROM Disassembly and find routines you can use, and obviously if the routine is in the ROM then it isn’t using any of that precious 48K of memory. The one caveat I have to all this is the SAVE/LOAD routines, as they are very specialised in order to get all the timings correct. If you want to write your own versions of those it’s probably best to take a copy of those ROM routines, and then change them as required.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s