[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
MiNT patch: Coprocessor for plain 68000 modells
Hi all,
here is a little patch for all of you, who still have only an ST(E)
without an 68020 or 68030 accelerator card, but want to make use of
the 68881 mathematical coprocessor. The patch just adds a new global
variable sfp, to signal the presence of an 68881 coprocessor, which
must be accessed through its interface registers and provides the
necessary handshaking to save and restore the coprocessor state on a
context switch (if the processes use the FPU).
Have fun
Wolfgang
--- 1.1 1995/08/26 21:18:32
+++ main.c 1996/02/17 13:54:48
@@ -90,6 +90,12 @@
short fpu = 0;
/*
+ * WL: when using a co-processor on a 68000 machine, the variable sfp
+ * will be used instead of fpu for the same purpose.
+ */
+short sfp = 0;
+
+/*
* "mch" holds what kind of machine we are running on
*/
long mch = 0;
@@ -1073,9 +1079,13 @@
if (cookie) {
while (cookie->tag != 0) {
/* check for true FPU co-processor */
- if ((cookie->tag == COOKIE__FPU) &&
- (cookie->value >> 16) >= 2)
+ /* ... or for co-processor on a ST or Mega ST(E) */
+ if (cookie->tag == COOKIE__FPU) {
+ if ((cookie->value >> 16) >= 2)
fpu = 1;
+ else if (cookie->value & 0x10000)
+ sfp = 1;
+ }
/* check for _FLK cookie */
else if (cookie->tag == COOKIE__FLK)
flk = 1;
--- 1.1 1995/08/13 12:45:42
+++ context.spp 1996/02/19 11:23:56
@@ -42,6 +42,14 @@
; for a different process. Unlike restore_context, this one *does*
; flush the ATC.
+; co-processor interface registers
+%define FPU_RESPONSE ($fa40).w
+%define FPU_SAVE ($fa44).w
+%define FPU_RESTORE ($fa46).w
+%define FPU_COMMAND ($fa4a).w
+%define FPU_OPERAND ($fa50).w
+%define FPU_REGSELECT ($fa54).w
+
TEXT
XDEF _build_context
@@ -50,6 +58,7 @@
XDEF _change_context
XREF _fpu
+ XREF _sfp
XREF _framesizes
XREF _new_trace ; from intr.s
XREF _no_mem_prot
@@ -85,6 +94,55 @@
move.w d0,C_SR(a0) ; save it
move.l (a1)+,C_PC(a0) ; save PC of context
%ifndef ONLY030
+ tst.w _sfp ; is there a co-processor in the system
+ beq.s nosfp
+ lea C_FSTATE(a0),a2
+ move.w FPU_SAVE,(a2) ; save internal state frame
+ tst.b (a2)+ ; check for NULL frame
+ beq.s nosfp ; nothing more to save
+ moveq #0,d1
+ move.b (a2)+,d1
+ lsr.w #2,d1
+ subq.w #1,d1
+ lea FPU_OPERAND,a3
+sfp1: move.l (a3),(a2)+
+ dbf d1,sfp1
+ move.w #$f0ff,FPU_COMMAND ; fmovem.x fp0-fp7,C_FREGS(a0)
+ tst.w FPU_RESPONSE
+ lea C_FREGS(a0),a2
+ tst.w FPU_RESPONSE
+ tst.w FPU_REGSELECT
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ ; C_FCTRL is adjacent to C_FREGS, therefore no need to reload a2
+ move.w #$bc00,FPU_COMMAND ; fmovem.l fpcr/fpsr/fpiar,C_FCTRL(a0)
+ tst.w FPU_RESPONSE
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+ move.l (a3),(a2)+
+nosfp:
tst.w d7 ; test longframe (AKP)
beq.s short1 ; short
%endif
@@ -135,6 +193,7 @@
noprot2:
; if running with a true coprocessor we need to save the FPU state
+ clr.w C_FSTATE(a0)
tst.w _fpu ; is there a true FPU in the system
beq.s nofpu2
fsave C_FSTATE(a0) ; save internal state frame
@@ -212,7 +271,7 @@
rcover: dbf d1,rcint
rcovernc:
move.w d0,-(sp) ; frame format identifier
-; if running with a true coprocessor we need to restore the FPU state
+; if running with a (true) coprocessor we need to restore the FPU state
tst.w _fpu ; is there a true FPU in the system
beq.s short3
@@ -221,7 +280,65 @@
fmovem.l C_FCTRL(a0),fpcr/fpsr/fpiar ; restore control registers
fmovem.x C_FREGS(a0),fp0-fp7 ; and data registers
short4: frestore C_FSTATE(a0) ; finally the internal state
+%ifndef ONLY030
+ bra short32
+%endif
short3:
+%ifndef ONLY030
+ tst.w _sfp ; is there a co-processor in the system
+ beq.s short32
+ lea C_FSTATE(a0),a1
+ tst.b (a1) ; if NULL frame then the FPU is not in use
+ beq.s short31
+ move.w #$d0ff,FPU_COMMAND ; fmovem.x C_FREGS(a0),fp0-fp7
+ tst.w FPU_RESPONSE
+ lea C_FREGS(a0),a2
+ lea FPU_OPERAND,a3
+ tst.w FPU_RESPONSE
+ tst.w FPU_REGSELECT
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ ; C_FCTRL is adjacent to C_FREGS, therefore no need to reload a2
+ move.w #$9c00,FPU_COMMAND ; fmovem.l C_FCTRL(a0),fpcr/fpsr/fpiar
+ tst.w FPU_RESPONSE
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.w (a1)+,d0 ; restore fpu state
+ move.w d0,FPU_RESTORE
+ andi.w #$00ff,d0
+ adda.w d0,a1
+ lsr.w #2,d0
+ subq.w #1,d0
+sfp2: move.l -(a1),(a3)
+ dbf d0,sfp2
+ bra.s short32
+short31:
+ move.w (a1),FPU_RESTORE
+short32:
+%endif
move.l C_PC(a0),-(sp) ; push the PC
move.w C_SR(a0),-(sp) ; push the status register
tst.b C_PTRACE(a0) ; check for a pending trace
@@ -276,7 +393,7 @@
rcover2: dbf d1,rcint2
rcover2nc:
move.w d0,-(sp) ; frame format identifier
-; if running with a true coprocessor we need to restore the FPU state
+; if running with a (true) coprocessor we need to restore the FPU state
tst.w _fpu ; is there a true FPU in the system
beq.s short6
@@ -285,7 +402,65 @@
fmovem.l C_FCTRL(a0),fpcr/fpsr/fpiar ; restore control registers
fmovem.x C_FREGS(a0),fp0-fp7 ; and data registers
short5: frestore C_FSTATE(a0) ; finally the internal state
+%ifndef ONLY030
+ bra short62
+%endif
short6:
+%ifndef ONLY030
+ tst.w _sfp ; is there a co-processor in the system
+ beq.s short62
+ lea C_FSTATE(a0),a1
+ tst.b (a1) ; if NULL frame then the FPU is not in use
+ beq.s short61
+ move.w #$d0ff,FPU_COMMAND ; fmovem.x C_FREGS(a0),fp0-fp7
+ tst.w FPU_RESPONSE
+ lea C_FREGS(a0),a2
+ lea FPU_OPERAND,a3
+ tst.w FPU_RESPONSE
+ tst.w FPU_REGSELECT
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ ; C_FCTRL is adjacent to C_FREGS, therefore no need to reload a2
+ move.w #$9c00,FPU_COMMAND ; fmovem.l C_FCTRL(a0),fpcr/fpsr/fpiar
+ tst.w FPU_RESPONSE
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.l (a2)+,(a3)
+ move.w (a1)+,d0 ; restore fpu state
+ move.w d0,FPU_RESTORE
+ andi.w #$00ff,d0
+ adda.w d0,a1
+ lsr.w #2,d0
+ subq.w #1,d0
+sfp3: move.l -(a1),(a3)
+ dbf d0,sfp3
+ bra.s short62
+short61:
+ move.w (a1),FPU_RESTORE
+short62:
+%endif
move.l C_PC(a0),-(sp) ; push the PC
move.w C_SR(a0),-(sp) ; push status register
tst.b C_PTRACE(a0) ; check for a pending trace
----
Wolfgang Lux
WZH Heidelberg, IBM Germany Internet: lux@heidelbg.ibm.com
+49-6221-59-4546 VNET: LUX at HEIDELBG
+49-6221-59-3500 (fax) EARN: LUX at DHDIBMIP