back | Last regenerated: 2010-09-08 15:25:13 kio |
Information on the ZX Spectrum file formats can be found in the ZX Spectrum FAQ which can be found on WOS: www.worldofspectrum.org/faq/. General rulesThe Target filestarget file format must be set with the Assembler directives: #target, #end#target Source files: Assembler directivesassembler directive. Assembler directives: #target, #end#target [pathandfilename.]extension ... Assembler directives: #target, #end#end Assembler directives: #target, #end#target defines filename, extension and format of the Target filestarget file. typically there is only one Assembler directives: #target, #end#target ... #end section per assembler source, but there may be more. the latter probably requires to supply the full Target filestarget file names in the Assembler directives: #target, #end#target directives. (not yet implemented as of version 3.0.14) This does not define whether the generated Pseudo instructions: datadata should be written as a plain General rules: Binary filesbinary file or in General rules: Intel hex file formatintel hex file format. This must be selected be the '-b' or '-x' Command line optionscommand line option. The assembler always defaults to binary except if the output is written to a terminal. Up to version 0.3.13 the Assembler directives: #target, #end#target Source files: Assembler directivesassembler directive is required. Since version 0.3.14 the Assembler directives: #target, #end#target Source files: Assembler directivesassembler directive may be omitted. Then the default target format is Target files: #target romrom. Assembler directives: #head#head <size>
Target filesTarget files which store registers and similar information start with a Assembler directives: #head#head segment. The Pseudo instructions: datadata within the Assembler directives: #head#head segment are set using 'Pseudo instructions: defb, defm, db, dmdefb' and similar instructions. If portions of the Assembler directives: #head#head segment are not set or 'Pseudo instructions: defs, dsdefs' is used with no fill pattern then default values will be filled in which vary depending on the omitted Pseudo instructions: datadata's purpose. Assembler directives: #code#code <start>,<size>
This directive defines an object code segment and set's the initial logical code origin to <start> and defines a maximum segment size <size>. <start> does not neccessarily define the physical position of the code segment in the Target files: #target romrom. Binary output does not contain address information, just the pure Pseudo instructions: datadata. In contrast Intel hex files contain address information. Starting with version 3.0.13 addresses in hex files are biased to <start>. The 'Pseudo instructions: orgorg' assembler Source files: Pseudo instructionspseudo instruction does not affect the hex file addresses. Multiple code segments are possible and are simply concatenated. Code segments are either padded at the end to the declared maximum segment size or they are truncated, depending on the Assembler directives: #target, #end#target format. Up to version 0.3.13 the Assembler directives: #code#code Source files: Assembler directivesassembler directive is required. Since version 0.3.14 the Assembler directives: #code#code Source files: Assembler directivesassembler directive may be omitted. Then the used default values are start=0 and size=$10000. Intel hex file formatIf the file is saved in the General rules: Intel hex file formatintel hex file format, then the unused space at the end of all code segments is never saved (truncated). When reading these files you can decide what to do with the missing Pseudo instructions: datadata. e.g. an eprom burner will simply skip over the gaps, leaving the Pseudo instructions: datadata as is, probably $FF for erased cells. As stated above, Intel hex files contain address information at which to physically store the generated code. Starting with zasm version 3.0.13 this address is also set to <start>. Binary filesAll code segments are padded with $00 to the declared maximum size, except:
If you want to prevent that a code segment is truncated then you can simply add 'Pseudo instructions: defs, dsdefs' to fill it up to the last byte. General rules: Binary filesBinary files do not contain information about the address where they should be loaded. Where they are loaded purely depends on the application used to load the file into a simulator or eprom. #target romThis file is a plain Target files: #target romrom or eprom image. Segments are padded with $FF, except for the last code segment, which is not padded but truncated. Target files: #target rom#target rom Assembler directives: #code#code <start>,<len> ... Assembler directives: #target, #end#end #target binPretty the same as a Target files: #target romrom file, but rather expected to be loaded somewhere into ram. Segments are padded with $00, except for the last code segment, which is not padded but truncated. Target files: #target bin#target bin Assembler directives: #code#code <start>,<len> ... Assembler directives: #target, #end#end #target snaA ZX Spectrum snapshot file. This consists of a ram dump from location $4000 to $FFFF. Snapshot files also contain information about the machine state, most namely the Target files: #target z80Z80 registers. The Assembler directives: #head#head Source files: Assembler directivesassembler directive is required to set interrupt mode and all Target files: #target z80Z80 registers. Target files: #target sna#target sna Assembler directives: #head#head 27 ... Assembler directives: #code#code <start>,<len> ... Assembler directives: #target, #end#end The Target files: #target snaSNA snapshot file describes a ZX Spectrum 16k or 48k serving an nmi request. <start> should be $4000 and <len> should be $4000 or $C000. at least later it's loaded that way. when Assembler directives: #target, #end#end is reached, the file is padded with $00 to $4000 bytes (if possible) or $C000 bytes, which implicitely defines a ZX Spectrum 16k or ZX Spectrum 48k. The RAM contents are written to the file in the uncompressed Target files: #target snaSNA format. the Target files: #target snaSNA file format is an NMI snapshot. the instruction pointer PC is not stored in the header section but on the return stack in RAM. Default values for header data:Pseudo instructions: defb, defm, db, dmdefb $3f ; i Pseudo instructions: defw, dwdefw 0,0,0,0 ; hl',de',bc',af' Pseudo instructions: defw, dwdefw 0,0,0,0,0 ; hl,de,bc,iy,ix Pseudo instructions: defb, defm, db, dmdefb $04 ; bit 2 = iff2 (iff1 before nmi) 0=di, 1=ei Pseudo instructions: defb, defm, db, dmdefb 0,0,0 ; r,f,a Pseudo instructions: defw, dwdefw 0 ; sp Pseudo instructions: defb, defm, db, dmdefb 1 ; irpt mode Pseudo instructions: defb, defm, db, dmdefb 7 ; border color: 0=black ... 7=white #target z80zasm version 3.0.7: not yet implemented This ZX Spectrum snapshot format may contain a snapshot for the ZX Spectrum or the ZX 128. It contains all of the .Target files: #target snasna file's information and optionally some more. It is preferred over the .Target files: #target snasna format by some people, because it does not store the instruction pointer pc on the Target files: #target z80Z80 machine stack. The .Target files: #target z80z80 file may also contain one or two Target files: #target romroms and Pseudo instructions: datadata for the paged ram of the ZX 128. Target files: #target z80#target z80 Assembler directives: #head#head <size> ; vs.201 = 55; vs.300 = 86; xzx = 87 Assembler directives: #code#code <start>,<len> ... #page <index> ... Assembler directives: #target, #end#end The Target files: #target z80z80 format describes a ZX Spectrum 16k, 48k, 128k or, in versions written by the warajewo and xzx emulator, a Timex 2068, a ZX Spectrum +3, a Pentagon or a Scorpion. The object code from the code segments is written to the paged-in RAM according to the value stored for the paging control register at address $1FFD. start should be $4000, len should be $4000 or $C000. at least, this is how it get's loaded later. Note: $4000 = bank 5; $8000 = bank 2; $C000 = bank 0 after reset. The #page directive defines a RAM page in which the following object code is stored. it set's start to $C000 and len to $4000. this directive is only allowed for models which are capable of paging. The RAM contents are written to the file in the compressed Target files: #target z80Z80 format. Default values for header data:Pseudo instructions: defb, defm, db, dmdefb 0,0 ; a,f Pseudo instructions: defw, dwdefw 0,0 ; bc,hl Pseudo instructions: defw, dwdefw 0 ; flag idicating vs.201 header or later Pseudo instructions: defw, dwdefw 0,0 ; sp Pseudo instructions: defb, defm, db, dmdefb $3f ; i Pseudo instructions: defb, defm, db, dmdefb 0 ; r & 0x7f Pseudo instructions: defb, defm, db, dmdefb (7<<1) ; (r>>7) + (border_color<<1) Pseudo instructions: defw, dwdefw 0,0,0,0 ; de,bc',de',hl' Pseudo instructions: defb, defm, db, dmdefb 0,0 ; a',f' Pseudo instructions: defw, dwdefw 0,0 ; iy,ix Pseudo instructions: defb, defm, db, dmdefb 1 ; iff1: 0=di, 1=ei Pseudo instructions: defb, defm, db, dmdefb 1 ; iff2 Pseudo instructions: defb, defm, db, dmdefb 1+(1<<6) ; (irpt_mode) + (issue_2<<2) + (joystick_emu<<6) // vs.201 header: Pseudo instructions: defw, dwdefw headsize-32 ; size of header extension; should be 23 or 54 Pseudo instructions: defw, dwdefw 0 ; pc Pseudo instructions: defb, defm, db, dmdefb 0 ; ZX Spectrum model 1) Pseudo instructions: defb, defm, db, dmdefb 0 ; 128k: last out to $7ffd (bank switching) 2) Pseudo instructions: defb, defm, db, dmdefb 0 ; if1 paged in? 2) Pseudo instructions: defb, defm, db, dmdefb 7 ; proper r and ldir emulation, 48k ay emulation 3) Pseudo instructions: defb, defm, db, dmdefb 0 ; last out to $fffd (ay register select) Pseudo instructions: defs, dsdefs 16,$ff ; ay registers // vs.300 header: Pseudo instructions: defb, defm, db, dmdefb 0,0,0 ; T state counters Pseudo instructions: defb, defm, db, dmdefb 0 ; misc. Pseudo instructions: defb, defm, db, dmdefb 0,0,$ff,$ff ; MGT/Multiface/SamRam paging Pseudo instructions: defs, dsdefs 20,0 ; keyboard mapping for joystick emulation Pseudo instructions: defb, defm, db, dmdefb 0,0,0 ; Disciple flags // xzx header extension: Pseudo instructions: defb, defm, db, dmdefb 0 ; +3: last out to $1ffd (bank switching) 3) 1) 0 = 48k 3 = 128k in vs.201 4 = 128k in vs.300 128 = Timex 2068 (warajewo) 7 = +3 (xzx) 9 = pentagon (xzx) 10 = scorpion (xzx) 16 ram pages! 2) Timex 2068: last out to 244 last out to 255 3) Bit 2: enable ay emulation even in 48k mode (xzx) #target tapeA ZX Spectrum Target files: #target tapetape file. This file may and should contain several code segments. Any time a Assembler directives: #code#code segment is finished, it is appended to the Target files: #target tapetape file. Target files: #target tape#target tape Assembler directives: #code#code <start>,<len>,#target tape: <flag><flag> ... Assembler directives: #target, #end#end The Target files: #target tapetape file format represents programs and Pseudo instructions: datadata saved to a music compact cassette by the original ZX Spectrum Target files: #target tapetape saving routines. Each code segment defines a block on the Target files: #target tapetape. the flag argument defines the type of block, which is typically $00 for a header block and $FF for the subsequent Pseudo instructions: datadata block. The code segments are never padded but always truncated. the blocks are written to the file in the uncompressed Target files: #target tapeTAP format. Any kind of Pseudo instructions: datadata is typically saved in two blocks: a header block, containing information about the following Pseudo instructions: datadata, and a Pseudo instructions: datadata block, containing Pseudo instructions: datadata as described by the preceding header. A complete game is typically saved in two parts: a basic loader, which consists of a header and a Pseudo instructions: datadata block and the machine code part, which consists of a header and Pseudo instructions: datadata block too. All blocks in the .Target files: #target tapetap file start with two bytes specifying how many bytes will follow. Then raw Target files: #target tapetape Pseudo instructions: datadata follows, starting with the flag byte and ending with the checksum byte. A Target files: #target tapetape file is a simple sequence of any number of these blocks. Layout of a block in a tape file:Pseudo instructions: defw, dwdefw #target tape: <length><length> Pseudo instructions: defb, defm, db, dmdefb #target tape: <flag><flag> Pseudo instructions: defb, defm, db, dmdefm #target tape: <data><data> Pseudo instructions: defb, defm, db, dmdefb #target tape: <checksum><checksum> <length>This is the number of bytes that follow: including the #target tape: <flag><flag>, #target tape: <data><data> and #target tape: <checksum><checksum>; not counting the #target tape: <length><length> itself. Byte order is little endian, this means, the low byte is first. The ZX Spectrum save routine cannot save 0 bytes or more than $ff00 bytes, thus the minimum #target tape: <length><length> is 3, which means 1 byte flag + 1 byte Pseudo instructions: datadata + 1 byte checksum. <flag>This is the value of the A register when the ZX Spectrum save routine was called. A value of $00 normally indicates, that this is a header block, a value of $FF indicates, that this is a Pseudo instructions: datadata block, which contents are described by the preceding header block. <data>Contains a header (if #target tape: <flag><flag>==$00 and #target tape: <length><length>==19) or Pseudo instructions: datadata. These are the bytes which will be loaded into RAM. <checksum>this is the bitwise XOR of all bytes including the flag byte. To create a program which consists of a basic loader and a machine code part as described above, write an assembler program which consist of 4 code segments:
A header block is always 17 bytes long. The headers for a basic program and for binary Pseudo instructions: datadata are layed out as follows: Header for basic program:Pseudo instructions: defb, defm, db, dmdefb 0 ; this indicates a basic program Pseudo instructions: defb, defm, db, dmdefm name ; the 'file' name, 10 bytes long Pseudo instructions: defw, dwdefw length ; length of block, that is basic program plus variables Pseudo instructions: defw, dwdefw auto ; line number for auto-start, $8000 if none Pseudo instructions: defw, dwdefw proglen ; length of the basic program without variables Header for binary data:Pseudo instructions: defb, defm, db, dmdefb 3 ; this indicates binary Pseudo instructions: datadata Pseudo instructions: defb, defm, db, dmdefm name ; the 'file' name, 10 bytes long Pseudo instructions: defw, dwdefw length ; length of Pseudo instructions: datadata block which follows Pseudo instructions: defw, dwdefw origin ; original location from where the binary Pseudo instructions: datadata was saved Pseudo instructions: defw, dwdefw 0 ; unused A sample framework for a tape file assembler source:;****** Target files: #target tapeTAPE FILE ASSEMBLER SOURCE SAMPLE ************************************ headerflag: Pseudo instructions: defl, equequ 0 dataflag: Pseudo instructions: defl, equequ $ff tCLEAR Pseudo instructions: defl, equequ $FD ; token CLEAR tLOAD Pseudo instructions: defl, equequ $EF ; token LOAD tCODE Pseudo instructions: defl, equequ $AF ; token CODE tPRINT Pseudo instructions: defl, equequ $F5 ; token PRINT tUSR Pseudo instructions: defl, equequ $C0 ; token USR Target files: #target tape#target tap ;------ PROGRAM HEADER ------------------------------------------------------- Assembler directives: #code#code 0,17,headerflag Pseudo instructions: defb, defm, db, dmdefb 0 ; program Pseudo instructions: defb, defm, db, dmdefm "testloader" ; make sure these are 10 bytes! Pseudo instructions: defw, dwdefw programsize ; length of basic program and variables Pseudo instructions: defw, dwdefw 10 ; line number for auto start Pseudo instructions: defw, dwdefw programsize ; length of basic program without variables ;------ PROGRAM Pseudo instructions: dataDATA --------------------------------------------------------- Assembler directives: #code#code 0,$100,dataflag ; size is truncated as required ; 10 CLEAR 24000 Pseudo instructions: defb, defm, db, dmdefb 0,10 ; line number Pseudo instructions: defb, defm, db, dmdefb end10-($+1) ; line length Pseudo instructions: defb, defm, db, dmdefb 0 ; statement number Pseudo instructions: defb, defm, db, dmdefb tCLEAR ; token CLEAR Pseudo instructions: defb, defm, db, dmdefm '24000',$0e0000c05d00 ; number 24000, ascii & internal format end10: Pseudo instructions: defb, defm, db, dmdefb $0d ; line end marker ; 20 LOAD "" CODE 24000 Pseudo instructions: defb, defm, db, dmdefb 0,20 ; line number Pseudo instructions: defb, defm, db, dmdefb end20-($+1) ; line length Pseudo instructions: defb, defm, db, dmdefb 0 ; statement number Pseudo instructions: defb, defm, db, dmdefb tLOAD,'"','"',tCODE ; token LOAD, 2 quotes, token CODE Pseudo instructions: defb, defm, db, dmdefm '24000',$0e0000c05d00 ; number 24000, ascii & internal format end20: Pseudo instructions: defb, defm, db, dmdefb $0d ; line end marker ; 30 PRINT USR 24000 Pseudo instructions: defb, defm, db, dmdefb 0,30 ; line number Pseudo instructions: defb, defm, db, dmdefb end30-($+1) ; line length Pseudo instructions: defb, defm, db, dmdefb 0 ; statement number Pseudo instructions: defb, defm, db, dmdefb tPRINT,tUSR ; token PRINT, token USR Pseudo instructions: defb, defm, db, dmdefm '24000',$0e0000c05d00 ; number 24000, ascii & internal format end30: Pseudo instructions: defb, defm, db, dmdefb $0d ; line end marker programsize Pseudo instructions: defl, equequ $ ;------ CODE HEADER ---------------------------------------------------------- Assembler directives: #code#code 0,17,headerflag Pseudo instructions: defb, defm, db, dmdefb 3 ; code Pseudo instructions: defb, defm, db, dmdefm "samplecode" ; make sure these are 10 bytes! Pseudo instructions: defw, dwdefw codeend-24000 ; length of Pseudo instructions: datadata block Pseudo instructions: defw, dwdefw 24000 ; original position Pseudo instructions: defw, dwdefw 0 ; unused ;------ CODE Pseudo instructions: dataDATA ------------------------------------------------------------ Assembler directives: #code#code 24000,40000,dataflag ret ; insert your machine code here codeend: Assembler directives: #target, #end#end ;****** END OF CODE SAMPLE *************************************************** #target 80 / #target oThis creates a Target files: #target tapetape file for use with an ZX80 emulator. There is only one Assembler directives: #code#code segment allowed, which is not padded but truncated. The Target files: #target tapetape file will allways be loaded to ram start at address $4000. Assembler directives: #target, #end#target 80 Assembler directives: #code#code <start>,<len> ... Assembler directives: #target, #end#end "o" can be used instead of "80". This will create a Target filestarget file with extension "o" or "80" respectively, which are fully identical. The Target files: #target tapetape Pseudo instructions: datadata is always loaded to $4000, so this is the only choice for the <start> address in the Assembler directives: #code#code directive. The <size> may be any value up to a maximum of $C000, but note that most ZX80 had maximum 16 kB ram if extended with an external memory expansion, only 1 kB if none. The ram starts with system variables from $4000 to $4028, which must be set to proper values. The variable E_LINE at $400A, which contains the end of ram address, is set by the assembler. You need not to calculate it, just skip it with "Pseudo instructions: defs, dsdefs 2" or "Pseudo instructions: defw, dwdefw 0". #target 81 / #target pThis creates a Target files: #target tapetape file for use with an ZX81 emulator. There is only one Assembler directives: #code#code segment allowed, which is not padded but truncated. The Target files: #target tapetape file will allways be loaded to ram start + $09 at address $4009. Assembler directives: #target, #end#target 81 Assembler directives: #code#code <start>,<len> ... Assembler directives: #target, #end#end "p" can be used instead of "81". This will create a Target filestarget file with extension "p" or "81" respectively, which are fully identical. The Target files: #target tapetape Pseudo instructions: datadata is always loaded to $4009, so this is the only choice for the <start> address in the Assembler directives: #code#code directive. The <size> may be any value up to a maximum of $C000 minus $09, but note that most ZX81 had maximum 16 kB ram if extended with an external memory expansion, only 1 kB if none. The ram starts with system variables from $4009 to $403C, which must be set to proper values. The variable E_LINE at the address $4014, which contains the end of ram address, is set by the assembler. You need not to calculate it, just skip it with "Pseudo instructions: defs, dsdefs 2" or "Pseudo instructions: defw, dwdefw 0". This file also contains the screen file, which basically means, that the video memory must contain 25 HALT Z80 Instructions: Legal instructionsopcodes if the file was saved in SLOW mode. Here are few important variables:$4014 defines the end address (used to calculate the file length) $4029 points to the next executed (autostarted) BASIC line $403B bit 6 indicates if program runs in SLOW or FAST mode $403C++ may be misused for whatever purpose |