Lesson 8: Intro to graphics and bit operations
To start off, we are going to learn three commands that deal directly with bits. They have pretty straightforward names, so it gets pretty hard to mix them up.
OR
OR takes the bits of register A and or's them with a given value.
It compares each bit in each and if one of the two are on (1),
then the result is on. If neither bit is on, then the answer is
Off (0).
Example:
ld a,50
ld b,15
or b
After executing these lines of code, A will equal 63. Let me show you why:
50 (A): | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
15 (B) | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
Ans | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
111111b is 63. You see that if either was 1, the Ans is 1.
AND
Very similar to OR, except that when each bit is compared, they
both have to be 1 for the bit in the answer to be 1.
I will use the same example above:
ld a,50
ld b,15
and b
After executing these lines of code, A will equal 2 Here is why.:
50 (A): | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
15 (B) | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
Ans | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
10b is 2. It requires both bits to be 1. If only one is 1, then the answer is 0.
XOR
This one is just a twisted OR. It behaves like or with a
backwards and buiilt in. If one of two correspoinding bits are 1,
then that bit in the asnwer is 1. If both bits are the same, then
the answer will be 0.
I will use the same example, just because it is easier on me :)
ld a,50
ld b,15
xor b
After executing these lines of code, A will equal 61.
50 (A): | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 |
15 (B) | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
Ans | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 1 |
111101b is 61. You see where both bits are set, the ans comes out to 0.
A few notes on these operations:
You do not have to use a register for the second operand: or 15
is perfectly legal.
The value returned is obviously stored in A.
OR A is a shortcut for CP 0, since all three of these operations
affect the flags.
XOR 255 will reverse the bits in A, 11001100b becomes 00110011b.
Graphics
Graphics are a lot easier than you may think. The fact is, it really isn't that hard since most of the hard work has been done for you!
To start it all off, there is one rom call that
handles a lot of graphic stuff. It is FIND_PIXEL. Unfortunatley,
you just can't call it haphazardly like you can do with just
about every other rom call.. FIND PIXEL lies on rom page 4. Which
is not automatically available. To change rom page you have to
use port 5 (Ports are another lesson). To change to page 4, at
the top of your program, insert these lines:
ld a,4
out (5),a
Here are three routines that deal with pixels.
putpixel:
ROM_CALL(FIND_PIXEL)
ld de,$FC00
add hl,de
or (HL)
ld (HL),A
ret
delpixel:
ROM_CALL(FIND_PIXEL)
ld de,$FC00
add hl,de
xor 255
and (HL)
ld (HL),A
ret
chgpixel:
ROM_CALL(FIND_PIXEL)
ld de,$FC00
add hl,de
xor (HL)
ld (HL),A
ret
You see they are all basically the same, just using different
bit operations. To call these functions you must first load up BC
with the location of the pixel. The screen is layed out with
(0,0) as the upeer left corner and (127,63) as the lower right.
so,
ld b,64
ld c,32
call &putpixel
will put a pixel around the direct center of the screen.
Knowing how the graphics buffer works is a huge part of graphics. The graphics buffer is a region of bitmapped memory from $FC00 to $FFFF. That is a range of 1024 bytes or 8192 bits. You will also notice that 128*64 is also 8192. Therefore each bit in the video buffer stands for a pixel. The byte at $FC00 is actually the first 8 pixels on the screen.
The screen is 16 bytes wide, so a common way of drawing allgned sprites is writing whole bytes to a part of the vid-buffer and, for eaxample, if the sprite was 2 bytes wide, After incrememnting once to get to the second byte of the sprite, adding 15 will get you one row down under the first byte read.
FIND_PIXEL is a wierd rom call. It takes BC in as a location, and returns HL as a relative address. Also it returns A as a value to be placed in the video buffer. The relative address HL is holding, is added to $FC00, it becomes an absolute address in the video buffer. If you get the byte that hl points to, or it with a and copy it back, you got yourself a new pixel. Why? A knows which bit in that byte is the pixel you are looking for. If you get the rest of the pixels in that byte and put it together with A, then it is safe to copy back to the video buffer. If you just take A without oring it and put it in the buffer, then you run the risk of erasing up to 7 other pixels!
Okay, this has kinda gotten technical. Next lesson we will get into sprites and fullscreen pictures using ZCP.