home *** CD-ROM | disk | FTP | other *** search
- ⓪ IMPLEMENTATION MODULE FPUSupport;
- ⓪ (*$Y+,X+,F-*)
- ⓪
- ⓪ (*
- ⓪!* 27.11.90 Routinen laufen auch, wenn Aufrufer schon im Supervisormode ist.
- ⓪!* 29.07.91 keine Privilegsverletzung mehr, wenn im Usermode (hyperCACHE030);
- ⓪!* Sprung in Supervisormode nun korrekt (ging bisher gar nicht?!).
- ⓪!* FSAVE bei externalFPU rettet nun Frame in umgekehrter Reihenfolge,
- ⓪!* so daß es nun endlich korrekt funktioniert.
- ⓪!* 15.02.94 Keine Low-Byte-Zugriffe mehr auf fpstat wg. Mega STE
- ⓪!*
- ⓪!* >> Konzept noch nicht perfekt: Wenn Coroutinen ggf.automatisch den
- ⓪!* FPU-Context switchen sollen, würden noch Low-Level-versionen
- ⓪!* von Save/RestoreContext benötigt. Ggf. "usedFPU", "MaxContextSize"
- ⓪!* und diese Low-Level Routinen in ein Modul "FPUBase" packen.
- ⓪!* Die Low-Level-Routinen f. Runtime können hier nicht rein, weil
- ⓪!* hier Storage importiert wird und das zu zirkul. Importen führt.
- ⓪!*)
- ⓪
- ⓪ FROM SYSTEM IMPORT ASSEMBLER, BYTE;
- ⓪
- ⓪ FROM Storage IMPORT ALLOCATE, DEALLOCATE;
- ⓪
- ⓪ IMPORT MOSGlobals, SFP004;
- ⓪
- ⓪ FROM SysInfo IMPORT FPUType, FPU, FPUModel;
- ⓪
- ⓪ VAR usedFPU: FPUType; (* zeigt die verwendete FPU an *)
- ⓪$model: CARDINAL;
- ⓪
- ⓪ CONST movemSize = 8*12 + 3*4;
- ⓪&contextSize = movemSize + 2 + 2 + 256 + 4;
- ⓪
- ⓪ (* Die Größe errechnet sich aus:
- ⓪!* 8 * FPn (je 12 Byte)
- ⓪!* je 4 für FPCR/SR/IAR
- ⓪!* 2 für evtl. nicht-Null-Flag
- ⓪!* 2 für Frame-Word von FSAVE
- ⓪!* interne Daten bei Busy State Frame (256 max. möglich)
- ⓪!* 4 zur Sicherheit *)
- ⓪
- ⓪ TYPE FPUContext = POINTER TO ARRAY [1..contextSize] OF BYTE;
- ⓪
- ⓪
- ⓪ PROCEDURE NewContext (VAR context: FPUContext);
- ⓪"BEGIN
- ⓪$NEW (context);
- ⓪$IF context = NIL THEN
- ⓪&ASSEMBLER
- ⓪(TRAP #6
- ⓪(DC.W MOSGlobals.OutOfMemory
- ⓪&END;
- ⓪$ELSE
- ⓪&ASSEMBLER
- ⓪(; Illegales State Frame erzeugen
- ⓪(MOVE.L context(A6),A1
- ⓪(MOVE.L (A1),A0
- ⓪(MOVE.W #$FFFF,movemSize(A0)
- ⓪&END;
- ⓪$END;
- ⓪"END NewContext;
- ⓪
- ⓪ PROCEDURE DisposeContext (VAR context: FPUContext);
- ⓪"BEGIN
- ⓪$DISPOSE (context)
- ⓪"END DisposeContext;
- ⓪
- ⓪ (*$L-*)
- ⓪
- ⓪ PROCEDURE FPUInit;
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(CMPI #externalFPU,usedFPU
- ⓪(BNE intern
- ⓪(JMP SFP004.FPUReset
- ⓪$intern:
- ⓪(CMPI #internalFPU,usedFPU
- ⓪(BNE none
- ⓪(FMOVE #$0000F400,FPCR ; s. 'Runtime'
- ⓪$none:
- ⓪$END
- ⓪"END FPUInit;
- ⓪
- ⓪ (* wird nicht exportiert, da FPUContext eh nur opaque ist und ein manuelles
- ⓪!* allozieren damit gar nicht möglich ist.
- ⓪ PROCEDURE MaxContextSize (): LONGCARD;
- ⓪!(*
- ⓪"* Liefert die maximal nötige Größe des Context-Puffers in Byte.
- ⓪"* Damit kann der Bereich notfalls auf eine andere Weise reserviert
- ⓪"* werden, statt 'NewContext' zu benutzen.
- ⓪"* Dann sollte der für 'FPUContext' angelegte Pu
- ⓪"*)
- ⓪ PROCEDURE MaxContextSize (): LONGCARD;
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE.L #contextSize,(A3)+
- ⓪$END
- ⓪"END MaxContextSize;
- ⓪ *)
- ⓪
- ⓪ PROCEDURE AcknowledgeException (context: FPUContext);
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(; Setze Bit 27 im BIU
- ⓪(MOVE.L -(A3),A1
- ⓪(CMPI #internalFPU,usedFPU
- ⓪(BNE noAckn
- ⓪(LEA movemSize(A1),A1
- ⓪(TST.B (A1)
- ⓪(BEQ noAckn ; kein Ackn bei Null-State
- ⓪(CLR D0
- ⓪(MOVE.B 1(A1),D0
- ⓪(BSET #3,(A1,D0.W)
- ⓪&noAckn
- ⓪$END
- ⓪"END AcknowledgeException;
- ⓪
- ⓪
- ⓪ CONST A2stat = 0; (* Response word of MC68881 read *)
- ⓪(A2ctrl = 2; (* Control word of MC68881 write *)
- ⓪(A2save = 4; (* Save word of MC68881 read *)
- ⓪(A2restore= 6; (* Restore word of MC68881 r/w *)
- ⓪(A2cmd = 10; (* Command word of MC68881 write *)
- ⓪(A2cond = 14; (* Condition word of MC68881 write *)
- ⓪(A2op = 16; (* Operand long of MC68881 read/write *)
- ⓪(A2regsel= $14; (* register select long read *)
- ⓪
- ⓪ PROCEDURE SaveContext (context: FPUContext);
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVEQ #1,D0
- ⓪(MOVE.L D0,-(A7)
- ⓪(MOVE #$20,-(A7)
- ⓪(TRAP #1 ;Super(1)
- ⓪(MOVEQ #-1,D2
- ⓪(TST D0 ; sind wir schon im Supervisormode ?
- ⓪(BNE supv
- ⓪(
- ⓪(MOVE.W D0,4(A7)
- ⓪(TRAP #1 ;Super(0)
- ⓪(MOVE.L D0,A7 ; SSP wiederherstellen
- ⓪(MOVE #$CFFF,D2
- ⓪&supv
- ⓪(MOVE SR,D1
- ⓪(AND D2,D1
- ⓪(MOVE.W D1,-(A7)
- ⓪(
- ⓪(MOVE.L -(A3),A1
- ⓪(MOVE.L A1,A0
- ⓪(ADDA.W #movemSize,A1
- ⓪(
- ⓪(CMPI #externalFPU,usedFPU
- ⓪(BNE.W intern
- ⓪(
- ⓪(MOVE.L A3,D1
- ⓪(MOVEA.W #$FA40,A2
- ⓪(MOVEA.W #$FA50,A3 ; fpop
- ⓪(
- ⓪ wait MOVE.W A2save(A2),D0
- ⓪(CMPI.W #$300,D0
- ⓪(BCC start ; > $300
- ⓪(CMPI.W #$100,D0
- ⓪(BCS nullstate ; < $100
- ⓪(CMPI.W #$200,D0
- ⓪(BCS wait
- ⓪(; Format Error
- ⓪(CLR.W (A1) ; IDLE-format word sichern
- ⓪(MOVE.L D1,A3
- ⓪(MOVE.W (A7)+,SR
- ⓪(ADDQ.L #6,A7
- ⓪(LINK A5,#0
- ⓪(JSR SFP004.FPUError
- ⓪(UNLK A5
- ⓪(RTS
- ⓪ nullstate:
- ⓪(MOVE.W D0,(A1) ; null-format word sichern
- ⓪(BRA.W endextern
- ⓪
- ⓪ start MOVE.W D0,(A1)+ ; format word sichern
- ⓪(; Anzahl der Bytes im Lower Byte -> Anz. der Longs berechnen
- ⓪(ANDI #$FF,D0
- ⓪(ADDA.W D0,A1
- ⓪(LSR #2,D0
- ⓪(SUBQ #1,D0
- ⓪(; während der Datenübertragung des FSAVE keine Interrupts zulassen
- ⓪(MOVE SR,D2
- ⓪(MOVE #$2700,SR
- ⓪ loop MOVE.L (A3),-(A1)
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪(DBRA D0,loop
- ⓪(MOVE D2,SR
- ⓪(
- ⓪(; FMOVEM FP0-FP7,(A0)+
- ⓪(TST.W (A2)
- ⓪(MOVE.W #1111000011111111%,A2cmd(A2)
- ⓪(TST.W (A2)
- ⓪(TST.W (A2)
- ⓪(TST.W A2regsel(A2)
- ⓪(TST.W (A2)
- ⓪(MOVEQ #7,D0
- ⓪ again MOVE.L (A3),(A0)+
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪(MOVE.L (A3),(A0)+
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪(MOVE.L (A3),(A0)+
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪(DBRA D0,again
- ⓪(
- ⓪(; FMOVEM FPCR/FPSR/FPIAR,(A0)+
- ⓪(MOVE.W #1011110000000000%,A2cmd(A2) ;$BC00
- ⓪(TST.W (A2)
- ⓪(;TST.W (A2)
- ⓪(;TST.W A2regsel(A2)
- ⓪(;TST.W (A2)
- ⓪(MOVE.L (A3),(A0)+
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪(MOVE.L (A3),(A0)+
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪(MOVE.L (A3),(A0)+
- ⓪(TST.W (A2) ; fpstat wg. Synchr. lesen
- ⓪$endextern:
- ⓪(MOVE.L D1,A3
- ⓪(BRA none
- ⓪
- ⓪$intern:
- ⓪(CMPI #internalFPU,usedFPU
- ⓪(BNE none
- ⓪(FSAVE (A1)
- ⓪(TST.B (A1)
- ⓪(BEQ none
- ⓪(FMOVEM FP0-FP7,-(A1)
- ⓪(FMOVEM FPCR/FPSR/FPIAR,-(A1)
- ⓪$none:
- ⓪(MOVE.W (A7)+,SR
- ⓪(ADDQ.L #6,A7
- ⓪$END
- ⓪"END SaveContext;
- ⓪
- ⓪ PROCEDURE RestoreContext (context: FPUContext);
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVEQ #1,D0
- ⓪(MOVE.L D0,-(A7)
- ⓪(MOVE #$20,-(A7)
- ⓪(TRAP #1 ;Super(1)
- ⓪(MOVEQ #-1,D2
- ⓪(TST D0 ; sind wir schon im Supervisormode ?
- ⓪(BNE supv
- ⓪(
- ⓪(MOVE.W D0,4(A7)
- ⓪(TRAP #1 ;Super(0)
- ⓪(MOVE.L D0,A7 ; SSP wiederherstellen
- ⓪(MOVE #$CFFF,D2
- ⓪&supv
- ⓪(MOVE SR,D1
- ⓪(AND D2,D1
- ⓪(MOVE.W D1,-(A7)
- ⓪(
- ⓪(MOVE.L -(A3),A1
- ⓪(MOVE.L A1,A0
- ⓪(ADDA.W #movemSize,A1
- ⓪(
- ⓪(CMPI #externalFPU,usedFPU
- ⓪(BNE.W intern
- ⓪(
- ⓪(TST.B (A1)
- ⓪(BEQ.W nullstate
- ⓪(
- ⓪(MOVE.L A3,D1
- ⓪(MOVEA.W #$FA40,A2
- ⓪(MOVEA.W #$FA50,A3
- ⓪(
- ⓪(; first reset FPU to be able to transfer the regs
- ⓪(MOVE.W #3,A2ctrl(A2) ; write abort-cmd
- ⓪(
- ⓪(; FMOVEM (A0)+,FP0-FP7
- ⓪(MOVE.W #1101000011111111%,A2cmd(A2)
- ⓪(TST.W (A2)
- ⓪(TST.W (A2)
- ⓪(TST.W A2regsel(A2)
- ⓪(TST.W (A2)
- ⓪(MOVEQ #7,D0
- ⓪ again MOVE.L (A0)+,(A3)
- ⓪(TST.W (A2)
- ⓪(MOVE.L (A0)+,(A3)
- ⓪(TST.W (A2)
- ⓪(MOVE.L (A0)+,(A3)
- ⓪(TST.W (A2)
- ⓪(DBRA D0,again
- ⓪(
- ⓪(; FMOVEM (A0)+,FPCR/FPSR/FPIAR
- ⓪(MOVE.W #1001110000000000%,A2cmd(A2)
- ⓪(TST.W (A2)
- ⓪(;TST.W (A2)
- ⓪(;TST.W A2regsel(A2)
- ⓪(;TST.W (A2)
- ⓪(MOVE.L (A0)+,(A3)
- ⓪(TST.W (A2)
- ⓪(MOVE.L (A0)+,(A3)
- ⓪(TST.W (A2)
- ⓪(MOVE.L (A0)+,(A3)
- ⓪(TST.W (A2)
- ⓪
- ⓪(; FRESTORE (A1)
- ⓪(MOVE.W (A1)+,D0
- ⓪(MOVE.W D0,A2restore(A2)
- ⓪(CMP.W A2restore(A2),D0
- ⓪(BEQ start
- ⓪(
- ⓪(MOVE.L D1,A3
- ⓪(
- ⓪(; Format Error
- ⓪ error MOVE.W (A7)+,SR
- ⓪(ADDQ.L #6,A7
- ⓪(LINK A5,#0
- ⓪(JSR SFP004.FPUError
- ⓪(UNLK A5
- ⓪(RTS
- ⓪
- ⓪ nullstate:
- ⓪(MOVEA.W #$FA46,A2 ; fprestore
- ⓪(MOVE.W (A1),D0
- ⓪(MOVE.W D0,(A2) ; FRESTORE
- ⓪(CMP.W (A2),D0
- ⓪(BEQ none
- ⓪(BRA error
- ⓪(
- ⓪ start ; Anzahl der Bytes im Lower Byte -> Anz. der Longs berechnen
- ⓪(ANDI #$FF,D0
- ⓪(LSR #2,D0
- ⓪(SUBQ #1,D0
- ⓪(; während der Datenübertragung keine Interrupts zulassen
- ⓪(MOVE SR,D2
- ⓪(MOVE #$2700,SR
- ⓪ loop MOVE.L (A1)+,(A3)
- ⓪(TST.W (A2)
- ⓪(DBRA D0,loop
- ⓪(MOVE D2,SR
- ⓪(MOVE.L D1,A3
- ⓪(BRA none
- ⓪(
- ⓪$intern:
- ⓪(CMPI #internalFPU,usedFPU
- ⓪(BNE none
- ⓪(TST.B (A1)
- ⓪(BEQ null_rst
- ⓪(FMOVEM (A0)+,FPCR/FPSR/FPIAR
- ⓪(FMOVEM (A0)+,FP0-FP7
- ⓪$null_rst:
- ⓪(FRESTORE (A1)
- ⓪$none:
- ⓪(MOVE.W (A7)+,SR
- ⓪(ADDQ.L #6,A7
- ⓪$END
- ⓪"END RestoreContext;
- ⓪
- ⓪ BEGIN
- ⓪"usedFPU:= FPU ();
- ⓪$(* egal, ob die vorhandene FPU auch wirklich benutzt wird: wenn hier
- ⓪%* eine der Funktionen aufgerufen wird, ists auf jeden Fall nicht die
- ⓪%* falsche. *)
- ⓪"model:= FPUModel ();
- ⓪ END FPUSupport.
- ⓪ ə
- (* $FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$000001F9$FFEE3A76$00002226$FFEE3A76$00000893$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76$FFEE3A76Ç$000001F3T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00001588$00001625$00001715$00001ACA$00001BC4$00001C48$00001CB5$00001D59$00001FFB$0000165D$00001CED$0000003E$000001F9$000001C0$000001F6$000001D4ÇÇé*)
-