Example code to load a machine code program in TAP format

A .TAP file is a simple image format used to represent data saved to tape. It's a simple image format which can be generated by some assemblers like zasm.

Now we have a simple BASIC loader which generates a .TAP file. This is effectively a simple BASIC program which when run loads the next file on the tape into memory at address 24000 0x5DC0 and then executes the machine code at that same address.

Hello World Example

For this example we will write a simple machine code program which writes Hello World to the screen.

1wget https://area51.dev/sinclair/asm/loaders/tap/loader.tap
2wget https://area51.dev/sinclair/asm/loaders/tap/helloworld.z80
3zasm helloworld.z80
4cat loader.tap helloworld.tap > tape.tap

The commands do the following:

  1. Download loader.tap which is the precompiled loader. The source is viewable here along with how to compile it yourself.
  2. Download helloworld.z80 which is the source shown below.
  3. Compiles the source generating helloworld.tap.
  4. Concatenates both tap files to generate our final tape.tap file.

Links to the required files are available in the Resources panel at the top right of this page including a precompiled helloworld.tap file.

Running the example

If no errors occurred you can run it with the fuse emulator:

1fuse tape.tap

You should then see something like this screenshot.

The first line visible is from the boot loader as it loaded the file in helloworld.tap.

The second line is the output of the source below.

Hello World in Fuse Emulator

helloworld.z80 source

; *************************************************************************** ; Hello world example showing how to use the TAP format and our simple ; BASIC boot loader that has been recompiled into TAP format. ; ; Author: Peter Mount, Area51.dev & Contributors ; URL: https://area51.dev/sinclair/asm/loaders/tap/ ; *************************************************************************** ; for zasm we need to tell it to generate a tap file #target tap ; code_start will be where our code will be compiled to code_start equ 24000 ; *************************************************************************** ; Header block containing the block name and the size of the machine code ; *************************************************************************** #code CODE_HEADER,0,17,0 defb 3 ; Indicates binary data defb "helloworld" ; the block name, 10 bytes long defw code_end-code_start ; length of data block which follows defw code_start ; default location for the data defw 0 ; unused ; *************************************************************************** ; Data block containing a actual machine code program: ; ; Here we simply print the "Hello World!" message to the screen. ; *************************************************************************** #code CODE_DATA, code_start,*,0xff ; This is the code_start address 24000 0x5DC0 ld a,2 ; set print channel to Screen: call 0x1601 ld hl,msg ; message start address loop: ld a,(hl) ; get next byte and a ; check for null ret z ; stop when we get a null inc hl ; move to next character rst 2 ; print the character jr loop ; jump back to the loop msg: dm 13, "Hello World!", 13, 0 ; End of code marker needed for the CODE_HEADER code_end: ; Anything after this point will not be included in the .tap file
Last modified November 4, 2021: It's Fuse for the emulator not fuze (88c2bf1)