UZ80 is a freeware Z80 assembler that aims to be both small and fast while still providing valuable services such as macro instructions and conditional assembly. Internally, it departs from full two-pass methods and relies instead on assembling as much code as possible during the first pass and writing down the lines making references to still unseen symbols; these lines will be assembled when all symbols are known.
How to use
UZ80 relies on the standard C library, it doesn't need other libraries to run. Its command line syntax is as follows:
Indenting is important: labels must begin on the first character of each line and instructions start later in the line even when there are no labels. Instructions are either those belonging to the Z80, or the following pseudo instructions:
org EXPRESSION : sets the assembly origin point at EXPRESSION;
align EXPRESSION : aligns the current assembly point to the next address that is a multiplo of EXPRESSION;
defb EXPRESSION... : defines a data block as a series of bytes separated with commas; strings within quotes can be used, too;
defw EXPRESSION... : like "defb", but with 16-bit words and without strings;
defd EXPRESSION... : like "defw", but with 32-bit double words;
defs EXPRESSION : fills with zeroes the amount of bytes set by EXPRESSION;
LABEL equ EXPRESSION / LABEL = EXPRESSION : creates a new symbol named LABEL whose value will be EXPRESSION;
if EXPRESSION : assembles the next lines if EXPRESSION is nonzero (conditional assembly); "else" can follow, "endif" must follow;
else : assembles the next lines if the current conditional assembly is zero; must follow "if", "endif" must follow;
endif : ends the current conditional assembly; can follow "else", must follow "if";
include "FILENAME" : includes the contents of another source file named FILENAME within the current assembly;
LABEL macro [PARAM1[,PARAM2 ...] : defines a macro instruction named LABEL featuring the optional parameters PARAM1, PARAM2...
endm : ends the definition of the current macro;
end : stops assembling the current source file.
Expressions are similar to those used in C and in other assemblers: integers (either decimal formatted as 1234 or 1234d, hexadecimal as #1234, $1234, 1234h or 0x1234, octal as 1234o or binary as %10110111 or 10110111b) and symbols (case-insensitive; "$" stands for the current address) can endure addition ('+'), substraction ('-'), multiplication ('*'), division ('/'), modulo ('%'), logical NOT ('!'), bitwise NOT ('~'), bitwise AND ('&'), bitwise OR ('|'), bitwise XOR ('^'), left shift ('<<'), right shift ('>>') and several types of comparison ('<', '<=', '='/'==', '<>'/'!=', '>=', '>'); operation precedence follows common rules such as additions and substractions taking place after multiplications and divisions, but before comparisons, unless parentheses are used to prioritise some operations over others. Notice that "equ" and "macro" must include labels and thus need to begin on the first character of the line. An example of a macro with parameters is as follows:
Using it with "memcpy buffer,string,10" generates the following code:
Originally undocumented instructions such as SLL (Shift Left Logical) and OUT (C),0 and parameters such as the high and low halves of IX and IY (XH, XL, YH and YL respectively) are supported, as well as synonyms:
DEFM : DEFB
DB : DEFB
DW : DEFW
DD : DEFD
DS : DEFS
IXH/HX : XH
IXL/LX : XL
IYH/HY : YH
IYL/LY : YL
SHL : SLA
SHR : SRL
JP/CALL V/NV/S/NS,ADDR : JP/CALL PO/PE/M/P,ADDR
PUSH REG1,REG2,REG3... : PUSH REG1 + PUSH REG2 + PUSH REG3 ...
POP REG1,REG2,REG3... : ... POP REG3 + POP REG2 + POP REG1
NOP NUMBER : NOP repeated NUMBER times
The pseudoinstructions "if" and "include" can be recursively nested; however, too much nesting will cause a fatal error. Exit codes are either 0 (success) or 1 (fatal error); errors will show a short message stating the type of error and its location in the source.
20180528-2020: minor patch fixing illegal command ADD IX/IY,HL being accepted instead of ADD IX,IX/ADD IY,IY.
20180510-1255: minor patch fixing a bug in source paths with folders.
20180506-1230: minor patch fixing a bug in hexadecimal suffixes (1234h) and adding octal and decimal suffixes (1234o and 1234d).
20180426-1030: sixth public release. Added synonyms LD BC/DE/HL,BC/DE/HL for LD C/E/L,C/E/L+LD B/D/H,B/D/H. Fixed illegal commands LD XL,L/H/(IX) and similar being accepted. INCLUDE swaps '/' and '\' if required.
20180417-1920: fifth public release. Ditched the last remainder of AS80 compatibility: the symbol "$" means the current target address rather than the current line's target; "defb nextline-$,nextline-$,nextline-$" followed by "nextline:" is now equivalent to "db 3,2,1" rather than "db 3,3,3". CHIPNSFX has been modified accordingly. Fixed error messages of missing symbols in label definition expressions.
20180414-1140: minor patch. Removed synonyms OTD and OTI. Code cleanup: source is 48k, binary is 32k.
20180408-1440: fourth public release. Buffers are now dynamically allocated and reallocated, "out of memory" should happen only when no more memory can be allocated. Several fixes in error handling: word overflow no longer names itself as "byte out of range"; error messages during final calculations are shown only once; opcodes relying on small constants (BIT, IM and RST) perform consistent range checks.
20180326-1155: third public release. Added synonyms SUB/AND/XOR/OR/CP A,PARAM for SUB/AND/XOR/OR/CP PARAM. Improper escape sequences raise fatal errors. The Win32 binary is no longer packed with UPX.
20180322-1930: second public release. Added instructions OUTD and OUTI (synonyms of OTD and OTI) and fixed inconsistencies when using a macro with fewer parameters than defined: BB4CPC and DUCKOUT compile.
20180321-2040: first public release. Succesfully compiles FROGALOT, HIREHARE, BASKETCS and the CHIPNSFX player demo.