Filling up with pixels

“At last!”, the followers cheer, “He’s doing the screen!!” 🙂

Yes!  But only in a very simple way to begin with…  I once mentioned that the screen starts at address 16384, and is 6144 bytes long.  This means that you could use roughly the same code as the colour-fill example to fill it with content (maybe you already have?)

That routine can be used for filling with a single value, but it’s actually somewhat overblown for that task, so lets use a quicker, and much simpler method.

LDIR – LoaD Increase and Repeat – is used for copying a block of memory from one location to another.  You set HL to the memory address what you want to copy from, DE to the address you want to copy to, and BC for the number of bytes to copy.  Simples!  So, for example, to copy the first 6144 bytes of ROM into the screen, you’d use:

ld hl, 0
ld de, 16384
ld bc, 6144
ldir

Very neat, and pretty fast.  (There are faster methods, but that’s good for starters, and actually for most of the cases you’re likely to need).  You can also be a little crafty with it, if you know how it works…

In the above case, it starts by copying the data at 0 (from HL) into 16384 (to DE). HL and DE are then increased (to 1 & 16385 respectively), and BC is decreased (to 6143), and it keeps doing that until BC is zero.  Knowing that, it’s straightforward to use it to fill a block of memory with a single value (or even a set number of repeating values), if you copy to an area inside the area of memory you are copying from.

Try this:

ld hl, 16384
ld de, 16385
ld bc, 6143
ld (hl), 15
ldir

We initially puts 15 into 16384, and then LDIR copies that value into 16385, then copies from 16385 to 16386, and so on. Notice that the loop is one shorter than before, as we’ve already set the first value.

With this, you should be able to modify the colours program to fill the screen with a value (zero to blank it) before we colour it, and then wait for a keypress afterwards before returning to BASIC.  And if you’re feeling adventurous, see what happens if you try to fill half the screen (the first 3072 bytes) with one value, and the other half (the last 3072) with another – it might not show quite what you are expecting… the explanation is next…

Advertisements

11 thoughts on “Filling up with pixels

    1. Yes, these are additional pieces of code to add as needed.
      I won’t be doing any online source repository though – it takes most of my time just doing these posts – the idea is that you learn from these posts and use them in your own code 🙂

      Liked by 1 person

  1. Not sure if I approached this in the right way, but I assumed that HL and DE would retain their values (mid-way through the screen fill) so I only needed to adjust BC and whatever’s being placed in (HL). Here’s my code:

    ——————–
    org 32768

    ld hl,16384
    ld de,16385
    ld bc,3072
    ld (hl),85
    ldir

    ld (hl),15
    ld bc,3072
    ldir

    ret
    end 32768
    ———————-

    I picked 85 and 15 as contents for HL as I knew they would both produce distinctive and recognisable patterns. Is the unexpected pattern a mish-mash of the two values in the middle third of the screen?

    If so, do I get a lolly?

    Tobo

    Liked by 1 person

  2. Yet another perfectly byte sized portion of learning 🙂 I did in the less effective way by repeating the whole piece of code with different memory adresses for each part. However I am stumped as to why they would spilt the screen memory up like that into parts and intertwine the middle! And it doesn’t follow the colouring which is incremental all over the screen.

    Liked by 1 person

  3. Hi Bob, Really sorry that this post is late but other commitments have to be done so I am behind on following your tutorial. I am back to this one and there is a few questions I would like to ask if I may.

    1. ld hl, 0 This loads the value 0 into HL (register pair)
    2. ld de, 16384 This loads the value 16384 into DE (register pair)
    3. ld bc, 6144 This loads the value 6144 into BC (again register pair)
    4. ldir means LoaD with Increment and Repeat.

    I get what this does BUT I don’t get how it does it. I’ll break it down so you can see why I am puzzled.

    1. How does the register pair HL know that the value 0 is an address and not a number for calculation ?
    2. How does the register pair DE know that the value 16384 is an address and not a number for calculation ?
    3. How does the register pair BC know that this is a value to decrement and not an address ?
    and finally if I swap any register pair with another it doesn’t work ?

    This is the bit I find hard to grasp but I am surely missing something really simple and maybe feel an idiot after your reply but I feel I need to ask. Thanks in advance … Andy

    Like

  4. Oh no …. I feel an idiot already .. I’ve missed an important explanation … LDIR – LoaD Increase and Repeat – is used for copying a BLOCK OF MEMORY from one location to another. Ok that explains the first two (or three) instructions but why can’t the register pairs be swapped to get the same result ? .. in other words if I compile :
    ld bc ,0
    ld hl, 16384
    ld de, 6144
    ldir
    It doesn’t work ?

    Like

    1. The above does ‘work’, in that it does something, but you’ve told it to copy the first 0 bytes (BC) of the screen (HL) to address 6144 (DE). As BC is zero, and LDIR will decrease that before testing it for zero, it’ll actually copy 65536 bytes, and so the whole of the Speccy’s memory, overwriting everything.

      Like

      1. OK I think I have finally got it. I have always assumed any register (apart from A) or register pair was like variables which are as flexible as each other and that any available can be used (as in DE being used instead of BC to decrease) . Now thinking about it as you have explained above, instructions wouldn’t know which registers was doing what. Now it makes sense that BC is only used to decrease and no other pair.

        Like

      2. In your own code you can use the registers how you wish, within the confines of the instructions themselves, but certain instructions use registers in a set way, and that can’t be changed. For example, the instruction SUB 10 will only ever take 10 from the A register, and LDIR will only ever copy from HL to DE.

        Like

  5. “LDIR will only ever copy from HL to DE.” That explains the whole lot. Thank you so much. I have realised that the screen graphics is split into three and that’s how the screen is loaded from tape. I have done this and although it may be sloppy it seems to work 🙂

    ld hl,16384
    ld de,16385
    ld bc,2048
    ld (hl),170
    ldir
    ld bc,2048
    ldir
    ld bc,2047
    ldir
    ret

    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