X80

From SinclairFAQ
Jump to: navigation, search

X80 Maths Co-processor

The X80 is a proposed floating-point unit for Z80 based computers. It is a hardware implementation of the calculator library of the ZX Spectrum ROM written by Steve Vickers. Programs written for the ZX Spectrum will automatically use the standard functions without the need for recompiling. New programs may be written to take advantage of the additional floating point instructions. A side effect of using the X80 is that a large section of the ROM becomes redundant and could be used for something else.

The X80 takes advantage of the fact that all calculator calls are handled via the RST 28H instruction. Ordinarily a call to RST 28H would invoke the software floating point routines, leaving the address of the first calculator instruction on the stack. The X80 intercepts this instruction and sniffs the address and data buses to determine the address of the first calculator instruction, and the address of the stack pointer. It then halts the Z80, and performs the floating point operations, reading the calculator instructions as native op-codes until it reads the a FCE instruction. At this point it replaces the contents of the stack pointer with the next address after the FCE instruction, forces a RET instruction onto the bus and returns control to the Z80.

Because the original names of the calculator op-codes are unknown, the X80 specification defines its own, based loosely on those used by the Intel 8087 and the Motorola 68881. All X80 instructions start with an F. You can add the instructions to assemblers that support macros, for example (in Pasmo):

fjptr	MACRO
	defb	0x00
	ENDM

Note: Macros are usually case sensitive so you must decide in advance if you prefer upper or lower case.

Instruction Set

Opcode	Instruction	Description

RST28H	FWAIT		cpu wait
00	FJPT		jump true
01	FXCH		exchange
02	FDEL		delete
03	FSUB		subtract
04	FMUL		multiply
05	FDIV		divide
06	FTOP		to power
07	FBOR		binary or
08	FBAND		binary and
09	FCP	.LE	compare (less or equal)
0A	FCP	.GE	compare (greater or equal)
0B	FCP	.NE	compare (not equal)
0C	FCP	.GT	compare (greater than)
0D	FCP	.LT	compare (less than)
0E	FCP	.EQ	compare (equal)
0F	FADD		add
10	FBANDS		string binary and
11	FCPS	.LE	string compare (less or equal)
12	FCPS	.GE	string compare (greater or equal)
13	FCPS	.NE	string compare (not equal)
14	FCPS	.GT	string compare (greater than)
15	FCPS	.LT	string compare (less than)
16	FCPS	.EQ	string compare (equal)
17	FCAT		string concatenate
18	FVALS		VAL$
19	FUSRS		USR$
1A	FREAD		read in
1B	FNEG		negate
1C	FASC		character ASCII value
1D	FVAL		VAL
1E	FLEN		length of string
1F	FSIN		sine
20	FCOS		cosine
21	FTAN		tangent
22	FASIN		arcsine
23	FACOS		arccosine
24	FATAN		arctangent
25	FLOGN		natuaral logarithm
26	FEXP		exponential
27	FINT		integer
28	FSQRT		square root
29	FSGN		signum
2A	FABS		absolute magnitude
2B	FPEEK		PEEK
2C	FIN		IN
2D	FUSR		USR
2E	FSTRS		STR$
2F	FCHRS		CHR$
30	FNOT		not
31	FMOVE		move
32	FMOD		modulus
33	FJP		jump
34	FSTK		stack data
35	FDJNZ		equivalent to DJNZ
36	FCP	.LZ	less than zero
37	FCP	.GZ	greater than zero
38	FCE		cpu enable
39	FGET		get argument
3A	FTRN		truncate
3B	FSGL		single operation 
3C	FETOF		e to floating-point
3D	FRSTK		restack


The following two opcodes can be used to add new instructions, not present in the
original implementation.

3E	double byte instruction in the form 0x3Exx
3F	double byte instruction in the form 0x3Fxx


A0	FSTK0		stack zero
A1	FSTK1		stack one
A2	FSTK.5		stack half
A3	FSTKPIX.5	stack pi/2
A4	FSTK10		stack ten

C0	FST	0	store in mem 0
C1	FST	1	store in mem 1
C2	FST	2	store in mem 2
C3	FST	3	store in mem 3
C4	FST	4	store in mem 4
C5	FST	5	store in mem 5

E0	FGT	0	get from mem 0
E1	FGT	1	get from mem 1
E2	FGT	2	get from mem 2
E3	FGT	3	get from mem 3
E4	FGT	4	get from mem 4
E5	FGT	5	get from mem 5

Other values are used by the series generator (See the Complete Spectrum ROM Disassembly for further details)

Notes

How to deal with getting the returned value to the right place remains to be figured out. It will probably involve use of the system variables BREG, STKBOT STKEND, and MEMBOT. It may also prove impossible to create the full set of instructions, in which case it should be possible to hand over and let the ROM take over for unimplemented instructions (the string functions probably fall into this set).