Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
X80 Math 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.
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)
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).