<--  back   Last regenerated: 2022-04-20 17:31:36 kio

zasm - Z80 Assembler – Version 4.4

Targets

#target TAP or TAPE

; ZX Spectrum tape file:
Assembler directives: #target
Including C Source Files: #target
#target tap Assembler directives: #code
Including C Source Files: #code
#code <name>, <start>,<len>,<flag> Assembler directives: #code
Including C Source Files: #code
#code <name>, <start>,<len>,flag=<flag> Assembler directives: #code
Including C Source Files: #code
#code <name>, <start>,<len>,FLAG=<flag> ...
; Jupiter Ace tape file:
Assembler directives: #target
Including C Source Files: #target
#target tap Assembler directives: #code
Including C Source Files: #code
#code <name>, <start>,<len>,flag=none Assembler directives: #code
Including C Source Files: #code
#code <name>, <start>,<len>,none

This target defines a ZX Spectrum or a Jupiter Ace tape file. This file may and should contain several code segments. Normally each code segment defines one block on the tape. The blocks are written to the file in the uncompressed TAP format.

The tape file format represents programs and data saved to a music compact cassette by the original ZX Spectrum tape saving routines.

ZX Spectrum vs. Jupiter Ace tap format

Unluckily the tape file formats for the ZX Spectrum and for the Jupiter Ace are only similar, not identical. zasm handles this difference for you, but it has to use a little heuristics to decide in which format to save.

Normally a ZX Spectrum file is written. Except Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if the following conditions are met, then a Jupiter Ace tape file is written:

Since version 4.2.0 zasm uses a different method to select Jupiter Ace .tap format:

Layout of a block in a ZX Spectrum tape file:

defw    <length>
defb    <flag>
defm    <data>
defb    <checksum>

Layout of a block in a Jupiter Ace tape file:

defw    <length>
defm    <data>
defb    <checksum>

The flag argument defines the type of block and is Pseudo instructions: defl, set and '='
Labels: SET
set from the Assembler directives: #code
Including C Source Files: #code
#code segment's #code: Flag Byte
#code: Flag Byte
flag byte.

Then the raw data follows which is taken from the Assembler directives: #code
Including C Source Files: #code
#code segment's data.

Finally a checksum follows which is calculated and appended by the assembler.

A tape file is a simple sequence of any number of these blocks.

Any kind of data is typically saved in two blocks: a header block, containing information about the following data, and a data block, containing data as described by the preceding header.

A complete game for the ZX Spectrum is typically saved in two parts: a basic loader, which consists of a header and a data block and the machine code part, which consists of a header and data block too. The basic part is typically saved with an auto start address which loads the following parts and starts the game.

A game for the Jupiter Ace may consist of only a single part (which consists of a header and data block). Machine code was not such a requirement because Forth is already pretty fast. The Jupiter Ace did not support auto starting and therefore the user had to type commands to load following blocks (Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if any) and to start and even restart a game.

The flag argument defines the type of block. On both the ZX Spectrum and the Jupiter Ace this is typically $00 for a header block and $FF for the following data block.

For an #insert: Examples:
#assert: Example:
incbin: Examples:
#assert: Example:
example see the .tap template file: template_tap.asm

It is possible to spread a tape block across multiple Assembler directives: #code
Including C Source Files: #code
#code segments. This is required Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if you want to include c source files. The first Assembler directives: #code
Including C Source Files: #code
#code segment must define an address and the block flag and the following Assembler directives: #code
Including C Source Files: #code
#code segments must have exactly matching addresses (you may put in '*' for the address) and no flag. All Assembler directives: #code
Including C Source Files: #code
#code segments which meet this requirement will be united with the first segment to one tape block.

New since version 4.0.24: Each code segment which has a #code: Flag Byte
#code: Flag Byte
flag byte starts a new tape block. All following segments which have no #code: Flag Byte
#code: Flag Byte
flag byte are appended to this tape block. A segment address defined for a following block does not create a 'gap' on the tape. The segment will be loaded where it is loaded and the program is assumed to move it to the defined location befor it is used. Actually this is true for the first block too: The tape loader defines where the block will be loaded, not the segment address stated in the Assembler directives: #code
Including C Source Files: #code
#code directive. This can be used Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if you want to move the entire program to a lower location in ram when it starts up.

Basic layout of a ZX Spectrum tape
Assembler directives: #target
Including C Source Files: #target
#target tap ; headerflag: Pseudo instructions: equ
Types of labels: Named values
Labels: EQU
equ 0 dataflag: Pseudo instructions: equ
Types of labels: Named values
Labels: EQU
equ 0xff ; ; use printer buffer for variables: ; Assembler directives: #data
Including C Source Files: #data
#data VARIABLES, 0x5B00, 0x100 ; ; Basic loader, header: ; Assembler directives: #code
Including C Source Files: #code
#code PROG_HEADER,0,17,headerflag defb 0 ; Indicates a Basic program defb "mloader " ; the block name, 10 bytes long defw variables_end-0 ; length of block = length of basic program plus variables defw 10 ; line number for auto-start, 0x8000 Assembler directives: #if, #elif, #else, #endif
Pseudo instructions: if, endif
if none defw program_end-0 ; length of the basic program without variables ; ; Tokenized Basic program: ; Assembler directives: #code
Including C Source Files: #code
#code PROG_DATA,0,*,dataflag ; ; 10 CLEAR 23999 defb 0,10 ; line number defb end10-($+1) ; line length defb 0 ; statement number defb tCLEAR ; token CLEAR defm "23999",$0e0000bf5d00 ; number 23999, ascii & internal format end10: defb $0d ; line Pseudo instructions: end, .end
8080 pseudo instructions: END
end marker ; ; 20 LOAD "" CODE 24000 defb 0,20 ; line number defb end20-($+1) ; line length defb 0 ; statement number defb tLOAD,'"','"',tCODE ; token LOAD, 2 quotes, token CODE defm "24000",$0e0000c05d00 ; number 24000, ascii & internal format end20: defb $0d ; line Pseudo instructions: end, .end
8080 pseudo instructions: END
end marker ; ; 30 RANDOMIZE USR 24000 defb 0,30 ; line number defb end30-($+1) ; line length defb 0 ; statement number defb tRANDOMIZE,tUSR ; token RANDOMIZE, token USR defm "24000",$0e0000c05d00 ; number 24000, ascii & internal format end30: defb $0d ; line Pseudo instructions: end, .end
8080 pseudo instructions: END
end marker ; program_end: ; ; <-- Basic variables --> ; variables_end: ; ; Machine code block, header: ; Assembler directives: #code
Including C Source Files: #code
#code CODE_HEADER,0,17,headerflag defb 3 ; Indicates binary data defb "mcode " ; 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 ; ; Machine code block, data: ; Assembler directives: #code
Including C Source Files: #code
#code CODE_DATA, code_start,*,dataflag ; ; <-- Command Line Options: --z80
Pseudo instructions: .z80, .z180 and .8080
Targets: #target Z80
Z80 assembler code and data --> ; code_end:

Valid HTML   Valid CSS