Hi All,
I try design a Intel C8231 based floating point unit for my CPC6128.
The following schematic shown the basic idea which is very simple : see attachment 1.
All the signals required are on the CPC expansion port. The only difficult will be to made 12 V (required by the C8231) from 5 V supply.
The FPU is selected by the Y output of the LS138 (choose between Y0 to Y1) and selected by A1/A2/A3, if A7 high and A5/A6 both low.
The question : Is the proposed address decoding here adapted to the CPC6128 where I/O are addressed by 16 bits address and not by 8 bits address like generally on Z80 system.
I found these explanations : see attachment 2 but they are unclear (at least for me).
Is the "Address" column corresponding to b0-b7 ?
Fo example if I use Y0 on the LS138 the address will be $40 for r/w "data" and $41 for write "command" or read "status". In this case what will be the IN / OUT Z80 instructions I should use for send receive data from the fpu ?
Thanks for help and advice.
Philippe
You MUST use A10 line Z80. Only when A10=0, Y and CS can be 0.
ps.
LD B, #FB ;ADDRES b15-b8 as 1111 1011 ; only b10 work.
LD C, LoADR ; When use line A0-A7.
LD A, DATA
OUT (C), A ; (ADDRES)<--DATA , C is ignored in CPC system, if You use for Adres, line A0-A7, You must not use reg. C as DATA.
IN (C), D ; DATA <--(ADDRES) DATA in A,D,E,H.L or C* ;When don't use line A0-A7
ps2. In simple world you can A10 join to CS and pray that no one sends more than one 0 in reg B (address) in OUT, when B10 (A10). is 0
On the 74LS138 truth table :
G1 = A7
G2 = G2A + G2B = A6 + A5
A3 = C
A2 = B
A1 = A
A10 has nothing to do with Y output selection at least into the schematic of the board... May be inside the CPC ?
Can you explain please ?
Thanks.
Philippe
ps I should mention that I am not very familiar with Z80 assembly language and with IN / OUT instructions. I come from 6502 world...
Without using A10, all firmware and CPC firmware when using IN C,(C) will randomly use your 8231 and short circuit with CPC. Failure ready.
ps3. Use A8 instead of A0
ps4. and Y7=CS
G2=A10
A =A11
B =A13
C =A14
G1=A15
Thanks !
G2 is a OR between two inputs G2A and G2B. So A10 for G2A and for G2B ?
No need to use A9 and A12 ?
If I put A12 to G2B then this give 4 bytes that will activate CS : $E8 --> $EB. $E8 or $EA for data and $E9 or $EB for command...
What will be then IN / OUT instructions for read/write into the fpu ?
Philippe
We don't need this OR. We join them.
What will happen if we send the command IN A,(C) ;where B=0 ?
All devices in the CPC will turn on and respond by sending a byte!
If we use only A10, A8 without LS138 our i8231 resending byte too.
without LS138 , IN A,(C) ;where B=0 is dangerous.
instr Z80 IN reg, (C) really means IN reg, (BC)
instr Z80 OUT (C),reg really means OUT (BC), reg ;our A15-A8 we write to reg B LD B, adr
ps. A12 is only for Printer port. He is write only.
LS138 in simulator. https://tinyurl.com/2yj45eat
Okay, I start to understand... I think.
Let me try :
Using Y7 as cs means
A15 G1 1
A14 C 1
A13 B 1
A12 - x (assume 1)
A11 A 1
A10 G2 0
A9 - x (assume 1)
A8 C/D 0 for data - 1 for command
A7 --> A0 not involved (assume 1)
So if I have understand I should IN or OUT to address $FAFF and $FBFF. Right ?
For example IN A,(BC) with B=$FA and C=$FF ?
A7 not involved
BUT in assembler you writing IN A,(C) and OUT (C),A ; without B , in CPC , C is arbitrary.
Yes IN A,(C) I have understand that.
But is my address calculation right ?
YES! :D
now you can change ADR simple and fast INC B; DEC B
Great thanks !!!
I will keep the forum informed about the progress on this board.
Philippe
Quote from: Wawavoun on 19:03, 25 April 23A7 --> A0 not involved (assume 1)
Hi, I am currently building some PIO, CTC and DART boards and did not realise that A7 low is used to select the disk controller. A6 and A5 also appear to be reserved but not sure why.
Available adresss ranges for expansion cards according to one book I have read, The Ins Aand Outs of the Amstrad, are;F8E0 — F8FE F9E0 — F9FF FAE0 — FAFF FBE0 — FBFFSee also https://www.cpcwiki.eu/index.php/I/O_Port_Summary (https://www.cpcwiki.eu/index.php/I/O_Port_Summary)
You'll want to look at https://www.cpcwiki.eu/index.php/Default_I/O_Port_Summary - a serial adapter on A5 has native firmware support used by CP/M. A6 isn't used by internal hardware at all, only third party devices.
OMG !!! very bad news !!! #FA7E | %xxxxx0x0 0xxxxxxx | Floppy Motor Control (for 765 FDC) (https://www.cpcwiki.eu/index.php/765_FDC) | - | Write |
#FB7E | %xxxxx0x1 0xxxxxx0 | 765 FDC (internal) Status Register (https://www.cpcwiki.eu/index.php/765_FDC) | Read | - |
#FB7F | %xxxxx0x1 0xxxxxx1 | 765 FDC (internal) Data Register (https://www.cpcwiki.eu/index.php/765_FDC) | Read | Write |
on 6128, F8-F9, FA-FB have conflict with Internal Flopy !!!
I have to apologize to line A7. B input LS138 connect to A7 ( in 6128 is more important than A13)
Hi,
These addresses need A7 to 0.
If I keep A0 --> A7 to 1 these addresses will not be selected ?
We must NOT selected 8231 when Firmware of floppy use floppy device
we need test A7 and when it's 0 don't use 8231.
Yes. Now I understand why.
I will use G2A and G2B (may be with the help of a LS04 if needed) to do that.
B input LS138 connect to A7 ( in 6128 is more important than A13)
I can share with you later the schematics for my small boards, which have full strict address selection, while allowing the adress to be selectable via jumpers.
Initially I did not consider A7 and started to see &80 on an IN instruction which is a bit of a giveaway because this is the status from the disk controller.
I now use F8E0 or F8F0 with A0 and A1 selecting the device registers. The jumpers also allow F9XX, FAXX or FBXX ranges to be selected.
Currently waiting on fixed boards from the PCB manufacturer, so hopefully they work.
20230421_153605 (1).jpg
So just bear in mind, I am new to this and these are my first boards, so quite happy for someone to suggest a better approach.
This is what I have assumed, taken from "The Ins and Outs of the Amstrad" book.
A15 low is the Gate Array
A14 low is the CRT
A13 low is the Expansion ROM
A12 low is the printer
A11 low is the PPI
A10 low is the expansion bus*
A7 low is the disk controller
A6 low is a reserved function
A5 low is a communication channel
F8FF also has special meaning, calling all expansion devices to reset.
So the addresses available are;
F8E0 - F8FE
F9E0 - F9FF
FAE0 - FAFF
FBE0 - FBFF
I use a pair of 74138s and some logic gates to select the correct address. One 74138 for the high byte address and one for the low byte. There are probably better ways but I have a lot of 74138s. I also created a pair of excel sheets to model the outputs from the 74138s (you can have these if you want them).
I use the logic NAND gates to ensure that A15-A12 are high and connect this to G2A and G2B on one of 74138s. I then connect A11 to G1, so A15-A11 must be high. I then use the outputs from the 74138 where A10 is low (F8 to FB).
I repeat a similar process with the with the low byte but only select those outputs from the 74128 where A7-A5 are high (selecting E0 or F0). I then combined the outputs from the two 74138s.
Hope this makes sense and hope in works? I should find out in a couple of weeks when the PCBs arrive, although limited testing on a prototype seems ok.
LB_CS.JPGHB_CS.JPG
RABS664 Z80 PIO SCH.jpg
Wawavoun (https://www.cpcwiki.eu/forum/index.php?action=profile;u=5448), what use do you have in mind for a FPU ? Just curious.
Hi,
When I was young I do a lot of scientific calculations with 8 bits computers.
It was just the the beginning of the 16 bits "workstations" and their price was incredible...
The slowness of 8 bits computers in floating point operations traumatized me and now I put math coprocessors everywhere : my Junior Computer has one, my Apple II also, now Amstrad CPC !
Regards.
Philippe
At the end I will do that for address decoding.
Screenshot_20230428_183936.png
I can do everything with 7 components, no surprise !
When the dip switch programmed address (AB0 excluded) come the LS00 ouput go low.
AB0 is reserved for switching between data and and control register so not is use in this part of the schematic.
Regards.
Philippe
this mosquito has definitely been hit... :o
watch the current.
Think about the END signal.
;D Okay I must admit...
if every switches are on I need 17 mA... For sure 10 k pullup will also do the job and then current is less than 8.5 mA.
I do this kind of thing only one time. It is not for mass production.
If a problem appear I have to redo everything, pcb, soldering, etc...
For prototype it is more efficient to have flexibility even with a little bit higher price.
Regards.
Philippe
2x LS688 = 40-65mA x 2 for nothing :P
Quote from: Rabs on 21:03, 26 April 23So just bear in mind, I am new to this and these are my first boards, so quite happy for someone to suggest a better approach.
This is what I have assumed, taken from "The Ins and Outs of the Amstrad" book.
A15 low is the Gate Array
A14 low is the CRT
A13 low is the Expansion ROM
A12 low is the printer
A11 low is the PPI
A10 low is the expansion bus*
A7 low is the disk controller
A6 low is a reserved function
A5 low is a communication channel
F8FF also has special meaning, calling all expansion devices to reset.
So the addresses available are;
F8E0 - F8FE
F9E0 - F9FF
FAE0 - FAFF
FBE0 - FBFF
I use a pair of 74138s and some logic gates to select the correct address. One 74138 for the high byte address and one for the low byte. There are probably better ways but I have a lot of 74138s. I also created a pair of excel sheets to model the outputs from the 74138s (you can have these if you want them).
I use the logic NAND gates to ensure that A15-A12 are high and connect this to G2A and G2B on one of 74138s. I then connect A11 to G1, so A15-A11 must be high. I then use the outputs from the 74138 where A10 is low (F8 to FB).
I repeat a similar process with the with the low byte but only select those outputs from the 74138 where A7-A5 are high (selecting E0 or F0). I then combined the outputs from the two 74138s.
Hope this makes sense and hope in works? I should find out in a couple of weeks when the PCBs arrive, although limited testing on a prototype seems ok.
[url="https://www.cpcwiki.eu/forum/index.php?action=dlattach;attach=39245;type=preview;file"]LB_CS.JPG[/url][url="https://www.cpcwiki.eu/forum/index.php?action=dlattach;attach=39247;type=preview;file"]HB_CS.JPG[/url]
So my PCBs have arrived :) but the observant may have noticed the low address lines (A0-A7) connected to the 74138 did not match my excel model sheet and because I am not that observant I did not notice :picard:. So the addressing was not quite as I expected :-X Anyway I have corrected this and new PCBs are on order.
RABS664 Z80 PIO SCH 1.4.jpg
So now waiting for corrected set of PCBs, to see if this works.
But the ones I have are not going to waste as they work with my home brew Z80 Computer which does not have the same sort of addressing restrictions as the CPC :D
In the CPC Wiki there is an list of already used I/O addresses. It's also nice to see that there is actually more 'space' than expected.
For new developments please do use a fully decoded design (address IO) to stay compatible (as much as possible) to already existing hardware. :) :) :)
Hello,
On my CPC6128 I try this schematic connected on the expansion bus :
Screenshot_20230428_183936.png
I set the dip switches for decoding &FBFF or &FBFE, because A0 is not involved into the address decoding.
On the msb part of the address bus the LS688 correctly detect &FB so I can use his output (pin 19) down pulse as sync on the scope.
On the lsb part I see inconsistent bits at this moment (I assume A1 to A7 should be high when &FB on A8-A15)... Some are low during this pulse so of course the full address is not detected.
The problem is the same if I do a OUT &FBFF,&xx or a POKE(&FBFF,&xx).
The lsb address LS688 is working because with the scope in free run mode he is able to detect sometime &FF. I cross the LS688 but this is not the problem.
So I dont understand why I cant see at the same time &FB on the msb address and &FF on the lsb address.
I double check wiring etc... and didnt found the problem.
The CPC is working well and I already use the expansion port for other purpose (Usifac) without problem.
I am lost. Any help and advice's appreciated !
Regards.
Philippe
Your circuit on outputs no. 19 does not take into account IOR IOW signals, so on the oscilloscope you also see the addresses of the currently executing program. These are also BASIC ROM addresses &C000-&FFFF
Thanks for the explanation.
Thinking to something similar (the $FBxx detected correspond to something different that the instruction I give) I have increase the record length of the scope (to may be 200 µs) but dont see other pulse after.
I will do
- a measure using the expansion bus ioreq signal
- a measure at the output of the OR function so even if the requested address come later that the first $FBxx I should catch him.
Philippe
The address decoding works !
Measurement problem... :doh:
But now I have to go deeper into the timing and do a small modification of the /WAIT signal management.
Wait, why wait? :D
At this point two things remain to solve I think :
1_ The AM9511 / Intel C8231 need that /CS stay low longer (at least 25ns) that /WR otherwise the data are not read correctly by the chip.
I should find a way to do that easily but dont know how ? Add a monostable ? Try something with a resistor + diode and capacitor ?
2_ The fpu /PAUSE signal is connected directly to the /WAIT line of the CPC. This is a problem because this line is shared with others and should be managed by open collector or something like that. I will try a serial 1N4148 so if /PAUSE is high the line can do what other peripherals want but is forced to low if /PAUSE is low.
Philippe
Quote from: Wawavoun on 07:21, 01 June 231_ The AM9511 / Intel C8231 need that /CS stay low longer (at least 25ns) that /WR otherwise the data are not read correctly by the chip.
I should find a way to do that easily but dont know how ? Add a monostable ? Try something with a resistor + diode and capacitor ?
Following... I am curious how that can be achieved. I have a similar issue where (I think) a low signal is too short.
Quote from: Rabs on 18:06, 16 May 23Quote from: Rabs on 21:03, 26 April 23So just bear in mind, I am new to this and these are my first boards, so quite happy for someone to suggest a better approach.
This is what I have assumed, taken from "The Ins and Outs of the Amstrad" book.
A15 low is the Gate Array
A14 low is the CRT
A13 low is the Expansion ROM
A12 low is the printer
A11 low is the PPI
A10 low is the expansion bus*
A7 low is the disk controller
A6 low is a reserved function
A5 low is a communication channel
F8FF also has special meaning, calling all expansion devices to reset.
So the addresses available are;
F8E0 - F8FE
F9E0 - F9FF
FAE0 - FAFF
FBE0 - FBFF
I use a pair of 74138s and some logic gates to select the correct address. One 74138 for the high byte address and one for the low byte. There are probably better ways but I have a lot of 74138s. I also created a pair of excel sheets to model the outputs from the 74138s (you can have these if you want them).
I use the logic NAND gates to ensure that A15-A12 are high and connect this to G2A and G2B on one of 74138s. I then connect A11 to G1, so A15-A11 must be high. I then use the outputs from the 74138 where A10 is low (F8 to FB).
I repeat a similar process with the with the low byte but only select those outputs from the 74138 where A7-A5 are high (selecting E0 or F0). I then combined the outputs from the two 74138s.
Hope this makes sense and hope in works? I should find out in a couple of weeks when the PCBs arrive, although limited testing on a prototype seems ok.
LB_CS.JPG (https://www.cpcwiki.eu/forum/index.php?action=dlattach;attach=39245;type=preview;file)HB_CS.JPG (https://www.cpcwiki.eu/forum/index.php?action=dlattach;attach=39247;type=preview;file)
So my PCBs have arrived :) but the observant may have noticed the low address lines (A0-A7) connected to the 74138 did not match my excel model sheet and because I am not that observant I did not notice :picard:. So the addressing was not quite as I expected :-X Anyway I have corrected this and new PCBs are on order.
RABS664 Z80 PIO SCH 1.4.jpg (https://www.cpcwiki.eu/forum/index.php?action=dlattach;attach=39414;type=preview;file)
So now waiting for corrected set of PCBs, to see if this works.
But the ones I have are not going to waste as they work with my home brew Z80 Computer which does not have the same sort of addressing restrictions as the CPC :D
New Boards have arrived and all working.
Hello,
Today my schematic is like that :
Capture.JPG
The circuit did not work and I dont know why...
The basic test is to send &1A command (push pi on the stack) then read 4 times the stack and check if the 4 received bytes represent pi in floating format.
During the trials clock was 4 MHz, J3 and J4 in 1-2 position, J1 left open (I dont want generate interrupt at this moment). I use a 8231 instead of a 9511 but try both and see the same problem. Problem and signals are the same if I left J3 open.
What I can say is that :
- address decoding works (but /CS goes low during 1,7 µs which is long I think, Z80 manual say 4 clock cycles for io access then this is only 1 µs)
- A0 is ok : command/status to &FBFF and data in/out to &FBFE.
- LS139 works : /WR, /RD are consistent with /CS and /IOREQ (/WR is 125 ns shorter than /CS)
- clock is okay (the 8231 work asynchronously so his clock is not directly related with the bus timing)
- the data at Dx pins of the 8231 look correct during /WR or /RD low
- the 8231 react during read cycle (/PAUSE goes low)... I have test the chip on another computer and they work well.
I try to find a way to check if the problem come from command write or from data read operation.
May be the problem is somewhere in the timing but compare with the above schematics around the 8255 I dont see any functional difference...
Also reset the 8231 need at least 5 clock cycles. Remain the CPC clock active during reset ?
Thanks for any advice and help.
Regards.
Philippe
Am9511A is CLK=2MHz
Am9511A-1 is CLK=3MHz
The 8231 could run at up to 3 MHz
and the 8231A and 8232 up to 4 MHz (a slight improvement on the Am9512 which was limited to 3 MHz)
Do You have 8231A ? ??
Am9511A-4DC is CLK 4MHz
Yes.
And I test it at 4 Mhz on the other computer.
If you have 4MHz version then you set J2-(3-4).
at 2MHz all timiing is too slow for CPC.
I have not fully read this myself just skimmed it but may be of interest AM9511 Arithmetic Processor (https://github.com/mecparts/AM9511/blob/master/z80float.doc).
Also found this which may be of interest AM9000 product interface guide (https://archive.org/details/AdvancedMicroDevices-AMD-Am9500PeripheralProductsInterfaceGuide1980OCR).
Quote from: Rabs on 12:08, 02 June 23I have not fully read this myself just skimmed it but may be of interest AM9511 Arithmetic Processor (https://github.com/mecparts/AM9511/blob/master/z80float.doc).
@Wawavoun The article that
@Rabs provided a link for ( above) suggests connecting the FPU chip select pin to ground, and using the decoded address to gate /WR and /RD to the FPU. This way, the FPU is always selected, but only responds when it's ready or write pins are selected by the address decoder.
The author used this method to interface one to his CP/M machine.
Quote from: Animalgril987 on 13:08, 02 June 23Quote from: Rabs on 12:08, 02 June 23I have not fully read this myself just skimmed it but may be of interest AM9511 Arithmetic Processor (https://github.com/mecparts/AM9511/blob/master/z80float.doc).
@Wawavoun The article that @Rabs provided a link for ( above) suggests connecting the FPU chip select pin to ground, and using the decoded address to gate /WR and /RD to the FPU. This way, the FPU is always selected, but only responds when it's ready or write pins are selected by the address decoder.
The author used this method to interface one to his CP/M machine.
Also not sure how you can use WAIT given its assertion by the Gate Array and timing with CRTC.
@Rabs I believe the GA output to the Z80 /WAIT is open collector, so an open collector buffer between fpu /PAUSE and cpu /WAIT should suffice ? ( I assume ( yeah, I know: NEVER assume!) that CPC has a pull-up resistor on /WAIT)
Or it might need the timing circuit shown on page 16 of the interface guide you linked to ( the OR gate will probably have to be open collector output ).
Better yet: page 18 has a Z80 interface. But, as before, an open collector buffer will be needed in the CPC case.
And don't include the connection from fpu END to Z80 INT.
That signal on expansion port is not WAIT INPUT. This is READY OUTPUT. and have R=82 Ohm.
Oops! Yes. Good point.
So: modify the interface to use a 3rd address, and read /PAUSE from a latch, looping until /PAUSE goes high?
OUT (C),r has 4T to data writing. Any wait is impossible. Wait is only from GA for draw the screen correctly.
Hi there !
Thanks all for your help and advice.
I found a schematic form something similar to what I want do. See attachment.
Again it is functionally equivalent as what I have do... But may be you can see some interesting point.
On difference : /MREQ is used to avoid /CS if low (G2A and G2B should be both low to enable LS138 outputs).
The /READY signal coming from the gate array is an output clear. It is connected to the /WAIT pin of the Z80.
But the 82 ohms resistor is here so this line can be shared with other peripherals. Multiple peripherals can tie it down if they need wait state. On the first version of the gate array it was is real open collector output. I put the diode for that reason. The peripheral cant force /READY to high but can force it to low. Without the diode the CPC dont boot at all.
During a read cycle I see /PAUSE going low and one pulse is missing on the /READY line during this time. This seems not give perturbation to the CPC.
My option of a bad reset of the apu was false. Reset go high and the 4 MHz CPC clock continue to tick. There is far enough cycles to get a reset.
The /END is not connected to /INT when I do my trial. Connect stop the CPC at the first access to the APU (normal I assume, there is no routine to manage the interrupt).
Here I am... I have to think to that and will may be write a second message later !
Regards.
Philippe
Hi there !
The board works !!!
Since the beginning the problem was a rotten flat cable ! :picard2:
This morning I want to give a look to /MREQ with the scope. The signal on the expansion board was flat at 0 V... For a active low signal its strange !
I begin to search around that and finally found the link is broken between the edge connector and the 2*25 connector. Then I think to myself if one wire is cut may be others also...
I dismantle two expansion flat wires I have for made one but this time working.
And the board works directly with this cable...
For the interested the up to date gerber and a bom are just below.
A CPM Plus library using this board will come soon.
Great thanks to all for your help !
Regards.
Philippe
@Wawavoun congratulations! Excellent project.
Do you have an updated schematic?
The schematic is th joined zip file.
Philippe
And here the pictures... Can always be useful !
On the gerbers above (V2) there is a place for the two diodes. No need of the hack you see on the picture.
Please note that the 9512 / 8232 configuration has not be tested. I was not able to find one of these chips somewhere.
If you have one or information where I can buy one please take contact.
Regards.
philippe
In case of I have 2 remaining pcb.
what software will use it?
I have a library made for Microsoft Fortran and Microsoft Bascom.
Any program in these languages can then be linked with this library at compilation and then use the fpu instead of software arithmetic.
I have to finish to test this library but they work on my Z80 CPM Apple IIe so should work also on the CPC.
Its based on the work here : https://github.com/ratboy666/apu
How to use this board with Locomotive Basic ? I dont know a this moment and have to think to that.
Philippe
6128 ł 464 ł Size ł Comments on the memory locations
-------------------------------------------------------------------------------
&BD61 ł &BD3D ł 32*3 ł Maths Jumpblock (on the 464 this block is 48*3 bytes in size)
https://www.cpcwiki.eu/imgs/e/e1/The_Amstrad_CPC_Firmware_Guide.txt
You can change jumps to match procedures to other.
The Maths Firmware
000 &BDC1 MOVE REAL (&BD3D for the 464)
Action: Copies the five bytes that are pointed to by DE to the
location held in HL
Entry: DE points to the source real value, and HL points to
the destination
Exit: HL points to the real value in the destination, Carry
is true if the move went properly, F is corrupt, and
all other registers are preserved
Notes: For the 464 only, A holds the exponent byte of the real
value when the routine is exited
001 &BD64 INTEGER TO REAL (&BD40 for the 464)
Action: Converts an integer value into a real value
Entry: HL holds the integer value, DE points to the desti-
nation for the real value, bit 7 of A holds the sign of
the integer value - it is taken to be negative if bit 7
is set
Exit: HL points to the real value in the destination, AF and
DE are corrupt, and all others are preserved
002 &BD67 BINARY TO REAL (&BD43 for the 464)
Action: Converts a four byte binary value into a real value at
the same location
Entry: HL points to the binary value, bit 7 of A holds the
sign of the binary value - negative if it is set
Exit: HL points to the real value in lieu of the four byte
binary value, AF is corrupt, and all others are
preserved
Notes: A four byte binary value is an unsigned integer up to
&FFFFFFFF and is stored with the least significant byte
first, and with the most significant byte last
003 &BD6A REAL TO INTEGER (&BD46 for the 464)
Action: Converts a real value, rounding it into an unsigned
integer value held in HL
Entry: HL points to the real value
Exit: HL holds the integer value, Carry is true if the
conversion worked successfully, the Sign flag holds the
sign of the integer (negative if it is set). A, IX and
the other flags are corrupt, and all other registers
are preserved
Notes: This rounds the decimal part down if it is less than
0.5, but rounds up if it is greater than, or equal to
0.5
004 &BD6D REAL TO BINARY (&BD49 for the 464)
Action: Converts a real value, rounding it into a four byte
binary value at the same location
Entry: HL points to the real value
Exit: HL points to the binary value in lieu of the real
value, bit 7 of B holds the sign for the binary value
(it is negative if bit 7 is set), AF, B and IX are
corrupt, and all other registers are preserved
Notes: See REAL TO INTEGER for details of how the values are
rounded up or down
005 &BD70 REAL FIX (&BD4C for the 464)
Action: Performs an equivalent of BASIC's FIX function on a
real value, leaving the result as a four byte binary
value at the same location
Entry: HL points to the real value
Exit: HL points to the binary value in lieu of the real
value, bit 7 of B has the sign of the binary value (it
is negative if bit 7 is set), AF, B and IX are corrupt,
and all others are preserved
Notes: FIX removes any decimal part of the value, rounding
down whether positive or negative - see the BASIC
handbook for more details on the FIX command
006 &BD73 REAL INT (&BD4F for the 464)
Action: Performs an equivalent of BASIC's INT function on a
real value, leaving the result as a four byte binary
value at the same location
Entry: HL points to the real value
Exit: HL points to the binary value in lieu of the real
value, bit 7 of B has the sign of the binary value (it
is negative if bit 7 is set), AF, B and IX are corrupt,
and all others are preserved
Notes: INT removes any decimal part of the value, rounding
down if the nurnber is positive, but rounding up if it
is negative
007 &BD76 INTERNAL SUBROUTINE - not useful (&BD52 for the 464)
008 &BD79 REAL *10^A (&BD55 for the 464)
Action: Multiplies a real value by 10 to the power of the value
in the A register, leaving the result at the same
location
Entry: HL points to the real value, and A holds the power of
10
Exit: HL points to the result, AF, BC, DE, IX and IY are
corrupt
009 &BD7C REAL ADDITION (&BD58 for the 464)
Action: Adds two real values, and leaves the result in lieu of
the first real number
Entry: HL points to the first real value, and DE points to the
second real value
Exit: HL points to the result, AF, BC, DE, IX and IY are
corrupt
010 &BD82 REAL REVERSE SUBTRACTION (&BD5E for the 464)
Action: Subtracts the first real value from the second real
value, and leaves the result in lieu of the first
number
Entry: HL points to the first real value, and DE points to the
second real value
Exit: HL points to the result in place of the first real
value, AF, BC, DE, IX and IY are corrupt
011 &BD85 REAL MULTIPLICATION (&BD61 for the 464)
Action: Multiplies two real values together, and leaves the
result in lieu of the first number
Entry: HL points to the first real value, and DE points to the
second real value
Exit: HL points to the result in place of the first real
value, AF, BC, DE, IX and IY are corrupt
012 &BD88 REAL DIVISION (&BD64 for the 464)
Action: Divides the first real value by the second real value,
and leaves the result in lieu of the first number
Entry: HL points to the first real value, and DE points to the
second real value
Exit: HL points to the result in place of the first real
value, AF, BC, DE, IX and IY are corrupt
013 &BD8E REAL COMPARISON (&BD6A for the 464)
Action: Compares two real values
Entry: HL points to the first real value, and DE points to the
second real value
Exit: A holds the result of the comparison process, IX, IY,
and the other flags are corrupt, and all others are
preserved
Notes: After this routine has been called, the value in A
depends on the result of the comparison as follows:
if the first real number is greater than the second
real number, then A holds &01
if the first real number is the same as the second real
number, then A holds &00 if the second real number is
greater than the first real number, then A holds &FF
014 &BD91 REAL UNARY MINUS (&BD6D for the 464)
Action: Reverses the sign of a real value
Entry: HL points to the real value
Exit: HL points to the new value of the real number (which is
stored in place of the original number), bit 7 of A
holds the sign of the result (it is negative if bit 7
is set), AF and IX are corrupt, and all other registers
are preserved
015 &BD94 REAL SIGNUM/SGN (&BD70 for the 464)
Action: Tests a real value, and compares it with zero
Entry: HL points to the real value
Exit: A holds the result of this comparison process, IX and
the other ˇlags are corrupt, and all others are
preserved
Notes: After this routine has been called, the value in A
depends on the result of the comparison as follows:
if the real number is greater than 0, then A holds &01,
Carry is false, and Zero is false
if the real number is the same as 0, then A holds &00,
Carry is false, and Zero is true
if the real number is smaller than 0, then A holds &FF,
Carry is true, and Zero is false
016 &BD97 SET ANGLE MODE (&BD73 for the 464)
Action: Sets the angular calculation mode to either degrees
(DEG) or radians (RAD)
Entry: A holds the mode setting - 0 for RAD, and any other
value for DEG
Exit: All registers are preserved
017 &BD9A REAL PI (&BD76 for the 464)
Action: Places the real value of pi at a given memory location
Entry: HL holds the address at which the value of pi is to be
placed
Exit: AF and DE are corrupt, and all other registers are
preserved
018 &BD9D REAL SQR (&BD79 for the 464)
Action: Calculates the square root of a real value, leaving the
result in lieu of the real value
Entry: HL points to the real value
Exit: HL points to the result of the calculation, AF, BC, DE,
IX and IY are corrupt
019 &BDA0 REAL POWER (&BD7C for the 464)
Action: Raises the first real value to the power of the second
real value, leaving the result in lieu of the ˇirst
real value
Entry: HL points to the first real value, and DE points to the
second real value
Exit: HL points to the result of the calculation, AF, BC, DE,
IX and IY are corrupt
020 &BDA3 REAL LOG (&BD7F for the 464)
Action: Returns the naperian logarithm (to base e) of a real
value, leaving the result in lieu of the real value
Entry: HL points to the real value
Exit: HL points to the logarithrn that has been calculated,
AF, BC, DE, LY and IY are corrupt
021 &BDA6 REAL LOG 10 (&BD82 for the 464)
Action: Returns the logarithm (to base 10) of a real value,
leaving the result in lieu of the real value
Entry: HL points to the real value
Exit: HL points to the logarithrn that has been calculated,
AF, BC, DE, IX and IY are corrupt
022 &BDA9 REAL EXP (&BD85 for the 464)
Action: Returns the antilogarithm (base e) of a real value,
leaving the result in lieu of the real value
Entry: HL points to the real value
Exit: HL points to the antilogarithm that has been cal-
culated, AF, BC, DE, IX and IY are corrupt
Notes: See the BASIC handbook for details of EXP
023 &BDAC REAL SINE (&BD88 for the 464)
Action: Returns the sine of a real value, leaving the result in
lieu of the real value
Entry: HL points to the real value (ie all angle)
Exit: HL points to the sine value that has been calculated,
AF, BC, DE, IX and IY are corrupt
024 &BDAF REAL COSINE (&BD8B for the 464)
Action: Returns the cosine of a real value, leaving a the
result in lieu of the real value
Entry: HL points to the real value (ie an angle)
Exit: HL points to the cosine value that has been calculated,
AF, BC, DE, IX and IY are corrupt
025 &BDB2 REAL TANGENT (&BD8E for the 464)
Action: Returns the tangent of a real value, leaving the result
in lieu of the real value
Entry: HL points to the real value (ie an angle)
Exit: HL points to the tangent value that has been cal-
culated, AF, BC, DE, IX and IY are corrupt
026 &BDB5 REAL ARCTANGENT (&BD91 for the 464)
Action: Returns the arctangent of a real value, leaving the
result in lieu of the real value
Entry: HL points to the real value (ie an angle)
Exit: HL points to the arctangent value that has been
calculated, AF, BC, DE, IX and IY are corrupt
All of the above routines to calculate sine, cosine, tangent
and
arctangent are slightly inaccuarate
and how work floatingpoint data:
https://www.cpcwiki.eu/index.php?title=Technical_information_about_Locomotive_BASIC&mobileaction=toggle_view_desktop#Floating_Point_data_definition
I believe the FPU uses a different format ( for floating point numbers ) than the CPC, so some conversion will be necessary.
https://www.hartetechnologies.com/manuals/AMD/AMD%209511%20FPU.pdf
page 4
mantissa is shorter 3bytes plus one bit sigin in exponent byte.
exponent 7 bit
On a 6128 I'm pretty sure all the floating point stuff is in the firmware. If the data first within the 5-bytes of a standard BASIC real then it would (probably) be transparent to the rest to the system. Therefore you shouldn't need any mods to the BASIC code.
The only issue I can see is with conversion to/from strings. If I'm not mistaken the conversion to strings returns the mantissa as BCD in a buffer. I'm not sure about the exponent. Probably in a register.
For conversion to strings I have no idea off-hand of what's needed.
If that's a path your interested in then I can investigate more for you.
Hello,
Thanks all for your suggestions and help.
At this moment I works on a asm library useable into compiled Basic and Fortran (both Microsoft).
Its slow because I have other stuffs to do...
Its based on a work found on github (link above).
Because this library made a great use of B register and because I need B for IN-OUT statement I have to made some modifications.
I know that this is board is useless without a software.
If somebody want write something usable from Locomotive Basic he his welcome.
I even can send him a fpu pcb (without components) for free so test will be possible.
Regards.
Philippe
I don't have time available to write a library, but I have a lot of domain knowledge of the BASIC source code. If you're interested in patching the firmware routines so BASIC would run 'as-is' but using the hardware instead of software routines then I'd be willing to check through the BASIC code for any possible issues, and to assist if any changes are needed to the BASIC source.
Hello,
The library herejoined is the first working version. It is far from optimized but it works !
The basic test program inside the zip, compiled / linked with bascom and l80, run in 13s50 in normal mode and in 2s55 if linked with this library (and of course if C8231 is present, 4 MHz in my case).
The process is as follow :
1_ compile sources
m80 =am9511.mac/L --> am9511.rel
m80 =apu.mac/L --> apu.rel
2_ make the lib
lib80 libapu.rel=am9511.rel,apu.rel/e --> libapu.rel
3_ compile basic program
bascom =aputst.bas/o/l --> aputst.rel
4 link with or without the library (and then use or not the fpu)
(with) l80 aputst.rel,libapu.rel,aputst.com/n/y/e or (without) l80 aputst.rel,aputst.com/n/y/e --> aputst.com
There is some warnings about double definitions at linking but works well...
Have fun !
Philippe