\documentstyle[a4,12pt]{article} \begin{document} \author{Rainer Thonnes} \title{APM Cross-Assembler for Z80} \maketitle \parskip .1 in \setcounter{secnumdepth}{10} \parindent 0in \section{Preamble} {\hspace*{1.2 in}} EUCSD Zilog Z-80 Assembler - User Notes \section{Introduction} {\hspace*{0.2 in}} This assembler is a very basic low-level program development tool. There are no macros, and only one data byte or data word or machine instruction is generated per statement. {\hspace{0.2 in}} Provided that no use is made of the Z-80's advanced instructions, this assembler may also be used to generate code for Intel 8080 and 8085 processors. {\hspace*{0.2 in}} The syntax is as nearly as possible identical to that specified in the Zilog Z80-CPU technical manual. {\hspace*{0.2 in}} Statements usually appear one to a line, but several may appear to a line (separated {\hspace{0.2 in}} by {\hspace{0.2 in}} semicolons), {\hspace{0.2 in}} provided {\hspace{0.2 in}} that {\hspace{0.2 in}} (due {\hspace{0.2 in}} to {\hspace{0.2 in}} crude implementation) no more than 4 bytes of code are generated on any one line. N.B. no Z-80 instruction exceeds 4 bytes in length. {\hspace*{0.2 in}} A comment, which starts with a '/', may appear either on a line by itself, or to the right of any other statement. {\hspace{0.2 in}} Comments occupy the entire rest of the line, i.e. a semicolon does not terminate a comment. {\hspace*{0.2 in}} Names obey the same rules as in HAL, i.e. a name is an arbitrary collection of letters and digits, starting with a letter, and containing no other characters, such as spaces. Although a name may be longer than 6 characters, only the first 6 are used to identify the name uniquely. {\hspace*{0.2 in}} Numbers are assumed to be in decimal. {\hspace{0.2 in}} Other bases may be used by prefixing the number by the base and '\_', as in IMP-77, e.g. 8\_23, 16\_3FF. Constructs such as 8\_16\_2A, though silly, are quite legal if you know how to use them (this example means 38). {\hspace{0.2 in}} Numbers may be signed with '-'(minus) or '$\backslash$'(not). {\hspace{0.2 in}} Quoted characters are enclosed in single quotes (as in IMP), e.g. 'A', and generate 8-bit constants. {\hspace{0.2 in}} The special form of a quoted quote is ''' (not ''''). {\hspace{0.2 in}} Double quotes are used to generate 16-bit constants, e.g. "AB", which is equivalent to 'A'$<$$<$8+'B'. \section{Operands} These fall into the following categories: \small\tt \begin{verbatim}8-bit constant 16-bit constant 8-bit register 16-bit register index register special register the top-of-stack <(SP)> memory operand <(constant),(16-bit register),(16-bit register + constant)> IO-reference <(C) or (constant)> \end{verbatim}\rm \normalsize {\hspace*{0.2 in}} Whether a memory operand or a constant operand refers to an 8-bit or a 16-bit quantity depends on the context in which it is used. {\hspace*{0.2 in}} Assembly-time expressions, which must evaluate to a constant or an operand, are worked out strictly left-to-right {\hspace{0.2 in}} with {\hspace{0.2 in}} no {\hspace{0.2 in}} operator precedence. {\hspace{0.2 in}} Parentheses may not be used to force any different order of evaluation. Operators available are +, -, \&, !(or), $\backslash$(xor), $<$$<$, and $>$$>$. {\hspace*{0.2 in}} Special operands are ".", "\$", and "*", all of which mean the same thing, namely the location counter at the beginning of the current instruction. {\hspace{0.3 in}} Use whichever one you prefer. {\hspace{0.3 in}} E.g. "DJNZ ." means "decrement B until it is zero", a useful delay instruction. {\hspace*{0.2 in}} Statement types. {\hspace{0.2 in}} A statement is either an instruction (with two, one, or no operands), a data statement, a name definition, or a directive (possibly with parameters). {\hspace*{0.2 in}} A data statement consists simply of a constant (number, name, or expression). {\hspace{0.2 in}} Normally this constant is dumped as one byte, but if it cannot thus be expressed, it is dumped as two, least significant byte first. {\hspace{0.2 in}} Most zero-operand instructions are in fact just constants used as data statements. {\hspace{0.2 in}} A small constant may be forced to occupy two bytes by prefixing it with the pseudo-instruction "W". {\hspace*{0.2 in}} A name definition is either a label or an explicit definition. {\hspace{0.2 in}} As expected, a label takes the form "name:", and may occur in front of any (possibly null) statement. {\hspace{0.3 in}} An explicit definition takes the form "name=expression" (which in HAL would be preceeded by "\$DEF"), e.g. BIT4=1$<$$<$4; POINTER=HL; ITEM=(POINTER) \section{Directives} These are illustrated here with sample parameters. \small\tt \begin{verbatim}LISTON turn listing on LISTOFF turn listing off END Must occur as the last statement in the file LOC 16_400 Set location counter W Force word data-statement (see above) BLOCK 13 Reserve a block of storage 13 bytes long. This directive has a padding side effect, and so usually takes the form BLOCK 16_66-. which means "pad to location 16_66". The value 255 (16_FF) is used as padding data, unless specified otherwise, as in BLOCK .+8&\7-.,nop which pads with NOPs up to the next 8-byte boundary. \end{verbatim}\rm \normalsize \section{Instructions} {\hspace*{0.2 in}} These take the form of Zilog-compatible mnemonics, possibly followed by one or two operands. They are listed here. \small\tt \begin{verbatim}LD dest,source 'Load' or 'move'. Used both for 8-bit and 16-bit quantities. Note especially: Using (SP) as an operand has a side-effect, so LD HL,(SP) is the same as POP HL. Certain operands cannot be moved in one instruction, so e.g. LD BC,HL must be written as LD B,H; LD C,L. ADD dest,source Addition (8 or 16 bit). Destinations are restricted to A, HL, IX, and IY. Similarly ADC and SBC, but with destinations A and HL only. INC dest Both 8-bit and 16-bit. Similarly DEC. SUB source Subtract (destination is A by implication). Similarly AND, XOR, OR, CP. EX op1,op2 The possibilities are: EX (SP), Note: (SP) must come first EX DE,HL Note: DE must come first EX AF,AF Not EX AF,AF' EXX Swop register sets PUSH POP RST label Restart (special kind of CALL) IN reg,dev Input instruction (dev is either (constant) or (C)). OUT dev,reg Output instruction (dev as above). RLC dest Rotate left circularly. Also RRC, RLA, RRA, SLA, SRA, SRL. Rotate, shift, left, right, circularly, logically, arithmetically. BIT bit,dest Bit test. Also SET, RES. CALL cond,label Conditional call JP cond,label Conditional absolute jump JR cond,label Conditional relative jump. Note that the second parameter is a label and not a displacement. Also note that the 8080/8085 does not have relative jumps. RET cond Conditional return CALL label Unconditional call JP label Unconditional absolute jump JR label Unconditional relative jump RET Unconditional return. DJNZ label Special Decrement B and jump if zero (Z80 only) \end{verbatim}\rm \normalsize \section{Miscellaneous instructions} \small\tt \begin{verbatim}LDI,LDD,LDIR,LDDR, block move CPI,CPD,CPIR,CPDR, block compare INI,IND,INIR,INDR, block input OUTI,OUTD,OTIR,OTDR, block output RETI,RETN,EI,DI, interrupt control IM0,IM1,IM2, ditto DAA, decimal adjust CPL,NEG, complement, negate A CCF,SCF, complement, set carry flag NOP,HALT,DJNZ, misc RLCA,RRCA,RLA,RRA 8080-compatible rotates RLD,RRD BCD digit digit rotates \end{verbatim}\rm \normalsize \section{Condition codes for calls, jumps, and returns} \small\tt \begin{verbatim}NZ non-zero Z zero NC no carry CY carry (not C, since C is a register) PO parity odd PE parity even P sign positive N sign negative \end{verbatim}\rm \normalsize \section{Error flags} \small\tt \begin{verbatim}F Statement syntactically unacceptable U Undefined name I Improper operand type V Overflow - more than 4 bytes generated on a line T Truncation - relative jump label out of range P Phase error - usually caused by forward reference in non-W data statement * Name-dictionary full \end{verbatim}\rm \normalsize \section{Deviations from Zilog's syntax spec} 1) The jump qualifier for the condition carry is CY, not C; this is because the name would otherwise conflict with that of the C-register. 2) The destination for relative jumps is specified as a label, not as an absolute displacement. So use JR CY,LABEL rather than JR CY,LABEL-\$. Implementations A) Legos \_z80 $<$source$>$/$<$object$>$,$<$listing$>$ Object and listing file names, if omitted, default to \$obj and \$list. {\hspace{0.2 in}} Your "LIB" should be any one of ASSEM, MICROS, or EPROM. B) Vax \$ z80 $<$file$>$ \\ {\hspace*{0.2 in}} The source is taken from $<$file$>$.Z80, the object goes into $<$file$>$.OBJ, and the listing will be put into $<$file$>$.LIS. {\hspace{0.2 in}} Both source and listing are in normal VMS format, while the object is in IMP binary format. {\hspace{0.2 in}} The symbol Z80 is defined by the public LOGIN file as "@SI1:[MICROS]Z80ASS". {\hspace*{0.2 in}} In both VAX and LEGOS implementations the object file will be 1024n characters long, suitable for feeding into the EPROM blowing program. \section{Coda} Document dated 11/09/79 revised 15/11/79 RWT. \vspace{.75in} assem:z80.doc printed on 14/03/89 at 17.12 \newpage \tableofcontents \end{document}