[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