Okay, so we now know how to set colours, so lets fill the screen with them.
We could try expanding our original program to do this like so:
org 32768 ld a, 32 ld (22528), a ld a, 33 ld (22529), a ld a, 34 ld (22530), a ... ... ...and so on...
But that could take some time to type to fill all 768 blocks of colour on the screen, and take quite a lot of memory too, so we’ll find a better way by learning some more Z80.
Thinking it through, we’ve got 768 block to fill, starting from address 22528, so really we just want to fill each one in turn with the next number – so we start with colour value 0 in 22528, 1 in 22529, 2 in 22530, and so on, using all 256 colour values three times over to fill all 768 blocks on the screen.
Try the following code:
org 32768 ld hl, 22528 ld bc, 768 ld d, 0 LOOP: ld (hl), d inc d inc hl dec bc ld a, b or c jp nz, LOOP ret END 32768
That’s a lot of new stuff – I said things would start moving faster – but it’s pretty straightforward really, honest!
Lets split it up…
ld hl, 22528 ld bc, 768 ld d, 0
I mentioned before that we had a few 8-bit registers – named A, B, C, D, E, H & L – which we could use to store values between 0 and 255? Well, some of those registers – B & C, D & E, and H & L – can be combined to work as 16-bit registers – BC, DE, & HL – which can be used to store values in the range 0 to 65535. So what we have above is 22528 in HL, 768 in BC, and 0 in D. So HL holds the address of the top-left of the screen’s colours, BC the number of blocks of colour on the screen, and D will hold the colour value.
LOOP: ld (hl), d inc d inc hl dec bc
LOOP: is a label – it’s a named point on the program we can refer back to later on. The next line puts D into the address held in HL – so we put 0 into 22528 – just like the original program did with. 32. After that we increase the value of D, making it 1 (the next colour value), increase the value of HL, making it 22529 (the next address), and decreases the value of BC, to 767 (one less address to fill)
ld a, b or c jp nz, LOOP
Here we put whatever is in register B into A. This is because the A register, or ‘Accumulator’ as it’s called, is really good for doing calculations on, where the other registers aren’t. We then combine A with register C, using a logical OR, which also does something special as a by-product – it calculates if result is zero or not. We then use that final instruction, a Jump, to go back to our LOOP label if it isn’t zero (‘nz’ = not zero), which will keep setting the colours until all 768 are filled. The OR operation is very handy for checking if a 16-bit number is zero, as only if both A & C are zero will the result be zero,
And when you run it, you should get something like, with extra flashing stuff as well!
Phew! That’s a lot of new stuff, but I’m getting the feeling that you all might just understand it? Please let me know in the comments if you don’t. You probably need to have a companion guide to Z80 to go with this, so you can read up on new stuff and understand what’s going on. Hope I’ve not frightened off anybody!