Speeding Up Truchet Tiles on My ZX81 with Machine Code


Taking my ZX81 Truchet tiles program from BASIC to machine code for a big speed boost. Faster, smoother, and fun to watch in action.

Having finished my last Truchet tiles program in BASIC, I wondered how fast it would run in machine code. Soon afterward, I gave it a try, writing a version that runs significantly faster than the BASIC one. Let’s dive in and see how it works.

# Setting things up.

Turning Truchet into a machine language program was straightforward enough. After copying in my standard template, I stuck with the same looping concept I had originally used. The main loop of the program does just that—setting up the display locations and using the BC register as the X and Y loops.

mainloop:

ld de,(d_file) ; grab display file
inc de ; add one

ld b,12 ; height x 2
y_loop:

ld c,16 ; width x 2
x_loop:

With that done, I randomly print a tile—more on that in a bit. The rest of the X loop looks like this:

push bc                 ; save loop
call print_a_tile
pop bc ; restore loop

call delay

; done with x?
dec c
jp nz,x_loop

Before closing out the Y loop, I need to shift the display down a row. I could have optimized this a bit to remove the push and pop, but it keeps things more readable. Notice that I jump ahead 34. That’s because each tile is 2×2 and I have to move past the end-of-line return character on the first row, plus the row beneath it (33 with return).

push bc
ld bc,34 ; jump ahead
ex de,hl
add hl,bc ; to next row
ex de,hl
pop bc
; de at start of next row

; done with y?
djnz y_loop

jp mainloop ; start again!

Truchet ML, ZX81 Starting Screenshot, 2025 by Steven ReidTruchet ML, ZX81 Starting Screenshot, 2025 by Steven Reid

# Printing the tiles.

With the setup complete, now I need to print the tile. First, I have the tile patterns defined later in the program:

; Truchet tile patterns
tile_1: db $06,$00,$00,$06
tile_2: db $00,$86,$86,$00

The print_a_tile routine uses these locations to decide which tile to print. After setting HL to point to the first tile, the program calls a simple 8-bit random number generator. I then compare the result with 127 to decide if I’ll print a different tile.

print_a_tile:

; get tile
ld hl,tile_1 ; set to 1st tile data
call rnd ; get which tile
cp 127 ; compare to 50%
jp m, print_tile ; print first tile
ld hl,tile_2 ; set to 2nd tile data

At this point, DE points at the screen location of the tile, while HL points at the tile data. This is important since I’m going to use the ldi instruction to copy the contents at HL directly to the screen.

print_tile:
  ; de = display file location
  ; hl = tile pattern data
  ld bc,33 ; next row

  ; print 1st row
  ldi ; print 1st char
  ldi ; print 2nd char

At this point, half the Truchet tile is displayed. To print the bottom half, I move the display pointer down a line. Before I do that, I save DE since it’s already pointing to the correct location for the next tile, thanks to how ldi works. This is also why I set BC to 33 instead of 31. Here’s the code for the second row:

        push de         ; save display location
  ex de,hl
  add hl,bc ; move to print tile
  ex de,hl

  ; print 2nd row
  ldi ; print 1st char
  ldi ; print 2nd char

  pop de ; restore location
  ret

Truchet ML, ZX81 Screenshot, 2025 by Steven ReidTruchet ML, ZX81 Screenshot, 2025 by Steven Reid

# It’s so fast!

With the primary routines complete, running the program uncovered a bit of a problem. It was too fast! Odd to say on the ZX81, I know, but I needed to slow things down a bit. I added my default delay routine, along with a break check, to finish the program. The final version was still faster than the BASIC one and very pleasant to watch.

Now that it’s running smoothly, I’ve been thinking about ways to use it. With a less random routine—say, a memory pointer to ROM—I could make this into a scrolling background. That would fit nicely in a shooting or jumping game. Fun for another day.

---

Want to try it out? You can run the program, or view the code if you’d like to see how it works.



Comments on this article:

No comments so far.

Write a comment:

Type The Letters You See.
[captcha image][captcha image][captcha image][captcha image][captcha image][captcha image]
not case sensitive