To move a picture, first remove it at its old position. Changing the position byte alone cannot take away pixels that were already written.
This complete checkpoint adds input and a repeated loop around the drawing work. The helper ship supplies the current ship_x, fixed Y=160, the ship table and sixteen rows to the drawing routine. Each call toggles that image with XOR.
Three operations, in order
The main loop calls ship, then steer, then ship again. The first call removes the old image. steer changes the stored X. The second call draws at the new position. If no movement is requested, the two XOR calls cancel: the ship ends up exactly as it was.
Source · view and edit
Companion file: assets.inc
The include line reads this editable data when you assemble. Keep it beside your source for a local build.
Edit the source, then assemble.
Edits are saved in this browser. Keep a downloaded copy of work you want to keep.
Focus the Spectrum screen to use the keyboard, or hold these buttons. Assemble again for a fresh machine.
Run the program to inspect it. Editing source does not change the running machine.
ship_x- —
updates- —
Hold O or P. Both keys held together cancel, as do both keys released. R resets the ship to x=116. ship_x is state; the bitmap is the picture made from that state. The inspector samples real RAM and may skip intermediate values.
Read the active-low keys
The O/P row is read using port $DFFE. and 3 keeps the two bits we need. Pressing a key clears its bit. The four possible masked values are:
| Value | Keys | Action |
|---|---|---|
| 3 | Neither | Stay |
| 1 | O | Left |
| 2 | P | Right |
| 0 | Both | Stay |
steer changes X by two and clamps it to 8..224. We leave space for the sprite’s four-byte writes at both sides. The comparisons apply to a proposed new position, before storing it.
steer:
ld e,2
steer_keys:
ld bc,$DFFE
in a,(c)
and 3
cp 1
jr z,steer_left
cp 2
ret nz
ld a,(ship_x)
add a,e
cp 225
jr c,steer_store
ld a,224
jr steer_store
steer_left:
ld a,(ship_x)
sub e
cp 8
jr nc,steer_store
ld a,8
steer_store:
ld (ship_x),a
retKeep the old image until it is removed
Find the three calls in main_loop. Delete only the first call ship, assemble and move. The trail is evidence that the old pixels remain. Revert, then repeat the move to confirm that erasing repairs the picture.
Would replacing the old image with four zero bytes always be a safe eraser?
Show the explanation
It would clear our empty background, but it could also erase pixels belonging to another object. XORing the same image again restores the bits beneath it, including other XOR images, provided nobody has overwritten that background in the meantime. A scrolling or repainted background needs a different agreement between drawing and erasing.
The small text helper draws the control line by copying eight ROM-font bytes per character. It takes B=character row, C=column and DE=zero-terminated text; it changes the primary registers. It writes outside the ship’s rows. We will examine that helper when building the game’s instruction screens.
This version uses a counted delay between updates. dec bc does not set the zero flag, so ld a,b followed by or c checks whether both bytes have reached zero. It slows the loop, but more drawing would also slow movement. Next we will give the program a clock that does not depend on how much work that loop contains.
Sources
Sinclair Research, ZX Spectrum BASIC Programming, chapter 23, the keyboard input ports. Zilog, Z80 CPU User Manual, UM008011-0816, IN, AND, CP and conditional branch entries.
Run it here
This unit's program, built for you.
- Program
- meteor-storm.tap
- Machine
- ZX Spectrum 48K (PAL)