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

# zasm - Z80 Assembler – Version 4.4

# Targets

[<prev] [next>]

| ### #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: The first segment is 25 bytes long (the Jupiter Ace header size) Block flags start with 0x00 for the first header block and then alternate between 0xFF and 0x00 for all following blocks. This is required for the Jupiter Ace tape file, because they do not store the #code: Flag Byte #code: Flag Byte flag byte. Since version 4.2.0 zasm uses a different method to select Jupiter Ace .tap format: Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If you Pseudo instructions: defl, set and '=' Labels: SET set the #code: Flag Byte #code: Flag Byte flag byte in the `Assembler directives: #code Including C Source Files: #code#code` directive to `none`, then a Jupiter Ace-style tape block is written. This block does not store the #code: Flag Byte #code: Flag Byte flag byte (therefore 'none') but instead emulators will implicitely assume `$00` and `$FF` for the #code: Flag Byte #code: Flag Byte flag byte in alternating order. 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: EQUequ 0
    dataflag:       Pseudo instructions: equ
    Types of labels: Named values
    Labels: EQUequ 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, endifif 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: ENDend 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: ENDend 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: ENDend 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 Z80Z80 assembler code and data -->
    ;
    code_end:

[<prev] [top] [next>]