Skip to content

Carry a pixel into the next byte

  • Sinclair ZX Spectrum
  • Assembly

Our ship needs to move less than one character at a time. First, move two pixels one place to the right without losing either of them.

This is a fresh project for a 48K PAL ZX Spectrum. We will use registers, memory addresses, calls and branches from Meet Assembly. You do not need BASIC. Each editor contains a complete program; Assemble and run starts a fresh machine without a tape wait. Save your edits before using Revert.

A row that crosses a boundary

The byte %10000001, hexadecimal $81, lights its leftmost and rightmost pixels. Put an empty byte after it and we have sixteen possible pixel positions:

Code
Before: 10000001 00000000
After:  01000000 10000000

The rightmost 1 of the first byte must become the leftmost bit of the second. Throw it away and one of our pixels vanishes every time it crosses a byte boundary.

Run the program. Most of the screen will stay black: these two rows are tiny. The magnified view reads the actual screen bytes. Its first row is the original pair; its second is the shifted pair.

Source · view and edit
ZX Spectrum

Edit the source, then assemble.

Edits are saved in this browser. Keep a downloaded copy of work you want to keep.

Run the program to inspect it. Editing source does not change the running machine.

The two bitmap bytes on each row, read from RAM. White is a set bit; black is a cleared bit.
Run to read the bytes.

Follow the carry

The program sets A to $81 and B to zero. srl a shifts A right, puts zero into its leftmost bit, and puts the bit that fell off the right into the carry flag. Carry is one bit in the flags register; here it remembers the displaced pixel.

rr b rotates B right through carry. The previous carry enters B’s leftmost bit. B’s former rightmost bit becomes the new carry. After these two instructions A is $40 and B is $80.

meteor-storm.asm, excerpt
 ld a,%10000001
 ld ($480C),a
 ; Shift right once, carrying the lost bit into the next byte.
 ; RR starts with the carry from SRL: $81,0 becomes $40,$80.
 ld a,%10000001
 ld b,0
 srl a
 rr b
 ld ($490C),a
 ld a,b
 ld ($490D),a

The writes to $480C, $490C and $490D choose two neighbouring bytes on neighbouring pixel rows. We will derive those addresses shortly. ld (address),a copies the value; it does not move the value out of A.

Change one thing

Replace both occurrences of %10000001 with %11111111. Predict both rows, then assemble again.

After changing both patterns to %11111111, what should the original and shifted rows contain?

Show the explanation

The original pair is $FF,$00. The shifted pair is $7F,$80: seven set bits remain in the first byte and the eighth enters the second.

What would happen if we replaced rr b with srl b?

Show the explanation

B would stay zero. SRL inserts zero at the left instead of accepting the carry from A. The pixel that left A would not appear anywhere. Try that single instruction change, then Revert to recover both the original pattern and instruction.

clear prepares black bitmap memory and white ink. It uses LDIR: copy the byte at HL to DE, advance both pointers, decrement BC and repeat until BC is zero. The source and destination are one byte apart, so the first value propagates through the range. Bitmap and attribute memory are cleared separately. The hold loop keeps execution away from the following helper code.

Use Download source for meteor-storm.asm. For local work, Asm198x is the primary tool; upstream Pasmo accepts the same source:

Shell
asm198x --dialect pasmo --cpu z80 --tapbas meteor-storm.asm -o meteor-storm.tap
# Or:
pasmo --tapbas meteor-storm.asm meteor-storm.tap

To run the tape on the desktop, use Emu198x, the recommended emulator; getting started covers downloading it and the 48K ROM it needs. From its folder:

Shell
./emu198x-spectrum --rom "path/to/48.rom" --tape meteor-storm.tap --autoload-tape

Reassembling reloads the whole experiment. Use the magnified bitmap reading to inspect the two rows.

Sources

Sinclair Research, ZX Spectrum BASIC Programming, chapter 24, display-file and attribute layout. Zilog, Z80 CPU User Manual, UM008011-0816, instruction descriptions for shifts, logical operations and loads.

Run it here

This unit's program, built for you.

Program
meteor-storm.tap
Machine
ZX Spectrum 48K (PAL)

Download meteor-storm.tap