Sunday, July 13, 2008

ZX Spectrum Assembly Programming Under Linux

There's been some Z80 activity on the BBS which sent me down - what I figured would be - a simple path... Write "Hello World" in Z80 assembler, assemble it and run it on an emulator.

The first place to start is the emulator. I installed spectemu (xspect) since it was available through debian's apt-get. It worked from the start; I didn't have to hunt down roms like other emulated platorms (68k, C64). If you're following along, at this point you should go download some existing Spectrum games and test everything out, make sure it works.

Next I installed z80asm and downloaded a simple assembly language program. Assembled it, loaded it into xspect and watched nothing happen. The output of z80asm is binary z80 machine code. The output of z80asm needs a piece of code added to the beginning of your binary file to get the Spectrum to load it. It also needs to be in a .tap file format. This code can be machine code, or basic. You don't have to understand, you just have to know it's required.

What to do? I was directed towards BIN2TAP and BIN2CODE on the SevenuP website. They have an .exe version for windows/dos, but also the c source code, which compiled fine with gcc. I have the files including compiled executables for linux x86 on my website here.

Many of the simple asm files I found for spectrum wouldn't assemble, or when if they did didn't work when run. I then thought to check the 99 bottles of beer website, and downloaded the Spectrum Z80 assembly version. It assembled without errors, and ran flawlessly. The 99 Bottles website is a great place to find a simple (but not too simple) program in almost any computer language you can think of, and it's often helpful when one needs a reminder after a few years away from a language.

Here's a link to the .tap and the .asm files of my Hello World app. Let it underwhelm you...

; Hello World in Z80 assembly language.
; Assembles for ZX Spectrum
; Assembled/Tested under linux with the following tools...
; z80asm $@.asm ; utils/bin2tap a.bin $@.tap ; xspect $@.tap
; Author: Nathanial Hendler ;
; Adapted from Damien Guard's 99 Bottles of Beer on the wall...
; Adapted from the Alan deLespinasse's Intel 8086 version

org 32768

ld a, 2 ; channel 2 = "S" for screen
call $1601 ; Select print channel using ROM

ld hl,line ; Print line
call printline

printline: ; Routine to print out a line
ld a,(hl) ; Get character to print
cp '$' ; See if it '$' terminator
jp z,printend ; We're done if it is
rst 16 ; Spectrum: Print the character in 'A'
inc hl ; Move onto the next character
jp printline ; Loop round


; Data
line: defb 'Hello, world.',13,'$'

Here's the bash script I use to assemble, convert to tape, and run the program; in case anyone cares (no error checking because I never make mistakes)...

#!/bin/sh -e
# Usage: ./makez80 hello

z80asm $@.asm ; utils/bin2tap a.bin $@.tap ; xspect $@.tap

Lastly, I found zxbasic on It's a set of python scripts, and it includes one that assembles and outputs .tap files. It seems like an interesting suite of tools, and the fact that they're written in python makes them appealing for their hackability.


Ratty said...

Cool stuff, however when I tried your hello world and the 99 bottles one I get an error on the "data" lines.

i.e. on yours I get
File 'hello.asm', at line 33, Syntax error in expression

Any ideas why?

zeppelinero said...

how do you created your file hello.tap?

paines said...

@Ratty: I had the same error. Check that you are using z80asm, instead of z88dk, which was my problem in the first place.

With z80asm (V1.8) It compiled fine.
With bin2tap it converted the Binary to a TapFile which played fine with fuse emulator and my real +2a.

Convert the bin to a Tap File with

@Equants: Thanks mate. I tried diffrent tutorials but none of them would work for me to generate a working spectrum programm. Your little tutorial did it. BR

boriel said...

Hi, I'm Boriel, the author of the ZX Basic compiler in python.

Yes, ZX Basic is entirely in python an it includes an ASM which can create .tap and .tzx files.

Just compile your program with: -t program.asm for .tap
or -T program.asm for .tzx

If you want your program to autoload with a basic loader then user -taB or -TaB respectively.

tobiasbp said...

If you use the Fuse emulator, the .tap will load and run automatically with the emulators default options. In my experience, the loading has to be done manually with spectem.

Fuse is is available in the ubuntu/debian package systems.