163 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
.TH Z8000_AS 1
 | 
						|
.ad
 | 
						|
.SH NAME
 | 
						|
z8000_as \- assembler for Zilog z8000 (segmented version)
 | 
						|
.SH SYNOPSIS
 | 
						|
/usr/em/lib/z8000_as [options] argument ...
 | 
						|
.SH DESCRIPTION
 | 
						|
This assembler is made with the general framework
 | 
						|
described in \fIuni_ass\fP(6).
 | 
						|
.SH SYNTAX
 | 
						|
.IP instructions
 | 
						|
Instruction mnemonics are implemented exactly as described in
 | 
						|
\fIZ8000 PLZ/ASM Assembly Language Programming Manual\fP and
 | 
						|
\fIAmZ8001/2 Processor Instruction Set\fP.
 | 
						|
.IP registers
 | 
						|
The z8000 has sixteen 16-bit general purpose registers specified
 | 
						|
as R0 through R15.  All sixteen registers can be used as accumulators.
 | 
						|
In addition to this, fifteen of the sixteen registers may be used
 | 
						|
in addressing mode calculations as either indirect, index or
 | 
						|
base-address registers. Because the instruction format encoding
 | 
						|
uses the value zero to differentiate between various addressing
 | 
						|
modes, register R0 (or the register pair RR0) cannot be used as an
 | 
						|
indirect, index or base-address register.
 | 
						|
It is also possible to address registers as groups of 8, 32 or 64 bits.
 | 
						|
These registers are specified as follows.
 | 
						|
.nf
 | 
						|
.ta 8n 16n 24n 32n 40n 48n
 | 
						|
- RH0, RL0, RH1, RL1, ..., RH7, RL7  for  8-bit  regis-
 | 
						|
  ters. (\fIH\fP stands for high-order byte, and \fIL\fP stands
 | 
						|
  for low-order byte within a  word  register).   These
 | 
						|
  registers overlap 16-bit registers R0 through R7.
 | 
						|
- RR0, RR2, ..., RR14 for 32-bit register pairs.
 | 
						|
- RQ0, RQ4, RQ8 and RQ12 for 64-bit register quadruples.
 | 
						|
.fi
 | 
						|
Besides register pair RR14 is used as stackpointer.
 | 
						|
.IP "addressing modes"
 | 
						|
.nf
 | 
						|
.ta 8n 16n 24n 32n 40n 48n
 | 
						|
syntax		meaning (name-mnemonic)
 | 
						|
 | 
						|
$expr		the value of expr is the operand.
 | 
						|
		(immediate-IM)
 | 
						|
 | 
						|
reg		contents of register reg is operand. Any
 | 
						|
		register as described above is allowed.
 | 
						|
		(register-R)
 | 
						|
 | 
						|
*reg32		contents of register pair reg32 is add-
 | 
						|
		ress of operand.  Any register pair can
 | 
						|
		be used except RR0.
 | 
						|
		(indirect register-IR)
 | 
						|
 | 
						|
expr		expr is address of operand.
 | 
						|
		(direct address-DA)
 | 
						|
 | 
						|
expr(reg16)	value of expr + contents of word regis-
 | 
						|
		ter  reg16  yields  address of operand.
 | 
						|
		Any word register can be used except R0.
 | 
						|
		(indexed address-X)
 | 
						|
 | 
						|
expr		expr is address of  operand.  This mode
 | 
						|
		is  implied  by its instruction.  It is
 | 
						|
		only used by CALR, DJNZ, JR,  LDAR  and
 | 
						|
		LDR  and  is the only mode available to
 | 
						|
		these instructions.   In fact this mode
 | 
						|
		differs not from the mode DA.
 | 
						|
		(relative address-RA)
 | 
						|
 | 
						|
reg32($expr)	contents of register pair reg32 + value
 | 
						|
		of expr yields address of operand.  Any
 | 
						|
		register pair can be used except RR0.
 | 
						|
		(based address-BA)
 | 
						|
 | 
						|
reg32(reg16)	contents  of register pair reg32 + con-
 | 
						|
		tents of  word  register  reg16  yields
 | 
						|
		address of operand.  Any register pair/
 | 
						|
		word register can be used except RR0/R0.
 | 
						|
		(based indexed address-BX)
 | 
						|
 | 
						|
.fi
 | 
						|
.IP "segmented addresses"
 | 
						|
Segmented addresses require 23 bits, 7 bits for the segment number
 | 
						|
and 16 bits for the offset within a segment.
 | 
						|
So segment 0 contains addresses 0-FFFF, segment 1 contains addresses
 | 
						|
10000-1FFFF, and so on.
 | 
						|
.br
 | 
						|
Assembler syntax of addresses and immediate data is as described above
 | 
						|
(modes IM, DA and X).
 | 
						|
Thus the assembler treats e.g. address 2BC0F as an address in segment 2
 | 
						|
with offset BC0F within the segment.
 | 
						|
There is also an explicit way to express this using the, more unusual,
 | 
						|
syntax <<segment>>offset.
 | 
						|
.br
 | 
						|
There are two internal representations of segmented addresses
 | 
						|
depending on the size of the offset. If the offset fits into 8 bits
 | 
						|
the address is stored in one word (the low-order byte containing
 | 
						|
the offset, bits 8 to 14 containing the segment number and
 | 
						|
bit 15 containing a zero) otherwise the address is stored in two
 | 
						|
words (the lower word containing the offset, the upper word as
 | 
						|
before but bit 15 containing 1 indicating that the offset is in
 | 
						|
the next word).
 | 
						|
This is important for instructions which has an operand of mode DA
 | 
						|
or X.
 | 
						|
.IP "extended branches"
 | 
						|
When the target address in a relative jump/call (JR/CALR)
 | 
						|
does not fit into the instruction format, the assembler generates
 | 
						|
a corresponding `normal' jump/call (JP/CALL).
 | 
						|
.SH EXAMPLE
 | 
						|
An example of z8000 assembly code.
 | 
						|
.nf
 | 
						|
.ta 8n 16n 24n 32n 40n 48n
 | 
						|
 | 
						|
!   This z8000 assembly routine converts a positive number
 | 
						|
!(in R1) to a string representing the number and puts this
 | 
						|
!string into a buffer (R3 contains the starting address of
 | 
						|
!this buffer.  The base is in R4 determining %x, %d or %o.
 | 
						|
 | 
						|
convert:
 | 
						|
	exts	RR0		!sign-extend R1
 | 
						|
	div	RR0, R4		!divide by the base
 | 
						|
	test	R1		!R1 contains the quotient
 | 
						|
	jr	EQ, 5f
 | 
						|
			!if quotient is 0 convert is ready
 | 
						|
			!else push remainder onto the stack
 | 
						|
	push	*RR14, R0
 | 
						|
	calr	convert		!and again...
 | 
						|
	pop	R0, *RR14
 | 
						|
5:	add	R0, $060	!add `0'
 | 
						|
	cp	R0, $071	!compare to `9'
 | 
						|
	jr	LE, 8f
 | 
						|
	add	R0, $7		!in case of %x `A'-`F'
 | 
						|
8:	ldb	0(R3), RL0	!put character into buffer
 | 
						|
	inc	R3
 | 
						|
	ret
 | 
						|
 | 
						|
.fi
 | 
						|
.SH "SEE ALSO"
 | 
						|
uni_ass(6).
 | 
						|
.br
 | 
						|
ack(1).
 | 
						|
.br
 | 
						|
Z8000 PLZ/ASM Assembly Language Programming Manual, april 1979.
 | 
						|
.br
 | 
						|
AmZ8001/2 Processor Instruction Set, 1979.
 | 
						|
.SH BUGS
 | 
						|
You cannot use (reg16) instead of 0(reg16).
 | 
						|
.br
 | 
						|
Condition codes \fIZ\fP (meaning zero), \fIC\fP (meaning carry) and <nothing>
 | 
						|
(meaning always false) are not implemented.
 | 
						|
The first two because they also represent flags and the third one
 | 
						|
because it's useless.
 | 
						|
So for \fIZ\fP/\fIC\fP use \fIEQ\fP/\fIULT\fP.
 | 
						|
.br
 | 
						|
The z8000 assembly instruction set as described in the book
 | 
						|
\fIAmZ8001/2 Processor Instruction Set\fP differs from the one
 | 
						|
described in the manual \fIZ8000 PLZ/ASM Assembly Language Programming
 | 
						|
Manual\fP in that the book includes CLRL, LDL (format F5.1) and
 | 
						|
PUSHL (format F5.1) which all in fact do not (!) work.
 | 
						|
.br
 | 
						|
On the other side the book excludes SIN, SIND, SINDR, SINI, SINIR,
 | 
						|
SOUT, SOUTD, SOTDR, SOUTI and SOTIR.
 | 
						|
Whether these instructions do work as described in the manual has not
 | 
						|
been tested yet.
 |