mac-rom/OS/FPUEmulation/FPSPMain.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

486 lines
12 KiB
Plaintext

;
; File: FPSPMain.a
;
; Contains: Main entry point for the FPU Emulation Package
;
; Originally Written by: Motorola Inc.
; Adapted to Apple/MPW: Jon Okada
;
; Copyright: © 1990, 1991 by Apple Computer, Inc., all rights reserved.
;
; This file is used in these builds: Mac32
;
; Change History (most recent first):
;
; <2> 3/30/91 BG Rolling in Jon Okada's latest changes.
; <1> 12/14/90 BG First checked into TERROR/BBS.
;
; fpspmain.a
; Based upon Motorola file 'skeleton.sa'.
; Main entry points to FPSP functionality: ovfl, unfl, snan, operr, bsun, fline,
; and unsupp.
; CHANGE LOG:
; 03 Jan 91 JPO Removed branches to emulator routines and moved entry point
; labels to appropriate emulator routines. Removed dummy
; user exception routines 'real_XXX'. Removed routine
; 'fpsp_done' (RTE done in-line). Modified and flattened
; structure of 'mem_write' function. Removed 'mem_read'
; routine (to be done in-line).
*
* skeleton.sa 3.1 12/10/90
*
* This file contains code that is system dependent and will
* need to be modified to install the FPSP.
*
* Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
* Put any target system specific handling that must be done immediately
* before the jump instruction. If there no handling necessary, then
* the 'fpsp_xxxx' handler entry point should be placed in the exception
* table so that the 'jmp' can be eliminated. If the FPSP determines that the
* exception is one that must be reported then there will be a
* return from the package by a 'jmp real_xxxx'. At that point
* the machine state will be identical to the state before
* the FPSP was entered. In particular, whatever condition
* that caused the exception will still be pending when the FPSP
* package returns. Thus, there will be system specific code
* to handle the exception.
*
* If the exception was completely handled by the package, then
* the return will be via a 'jmp fpsp_done'. Unless there is
* OS specific work to be done (such as handling a context switch or
* interrupt) the user program can be resumed via 'rte'.
*
* In the following skeleton code, some typical 'real_xxxx' handling
* code is shown. This code may need to be moved to an appropriate
* place in the target system, or rewritten.
*
* Copyright (C) Motorola, Inc. 1990
* All Rights Reserved
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
* The copyright notice above does not evidence any
* actual or intended publication of such source code.
* SKELETON IDNT 2,1 Motorola 040 Floating Point Software Package
; section 15
*
* The following counters are used for standalone testing - DELETED <1/3/91, JPO>
*
;sigunimp dc.l 0
;sigbsun dc.l 0
;siginex dc.l 0
;sigdz dc.l 0
;sigunfl dc.l 0
;sigovfl dc.l 0
;sigoperr dc.l 0
;sigsnan dc.l 0
;sigunsupp dc.l 0
; section 8
; include fpsp.h
*
* Divide by Zero exception - DELETED <1/3/91, JPO>
*
* All dz exceptions are 'real', hence no fpsp_dz entry point.
*
;dz:
;real_dz:
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E1,E_BYTE(a6)
; frestore (sp)+
; unlk a6
;
; add.l #1,sigdz ;for standalone testing
;
; rte
*
* Inexact exception - DELETED <1/3/91, JPO>
*
* All inexact exceptions are real, but the 'real' handler
* will probably want to clear the pending exception.
* The provided code will clear the E3 exception (if pending),
* otherwise clear the E1 exception. The frestore is not really
* necessary for E1 exceptions.
*
* Code following the 'inex' label is to handle bug #1232. In this
* bug, if an E1 snan, ovfl, or unfl occured, and the process was
* swapped out before taking the exception, the exception taken on
* return was inex, rather than the correct exception. The snan, ovfl,
* and unfl exception to be taken must not have been enabled. The
* fix is to check for E1, and the existence of one of snan, ovfl,
* or unfl bits set in the fpsr. If any of these are set, branch
* to the appropriate handler for the exception in the fpsr. Note
* that this fix is only for d43b parts, and is skipped if the
* version number is not $40.
*
*
;inex:
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; cmpi.b #VER_40,(sp) ;test version number
; bne.b real_inex
; fmove.l fpsr,-(sp)
; btst.b #E1,E_BYTE(a6) ;test for E1 set
; beq.b not_b1232
; btst.b #snan_bit,2(sp) ;test for snan
; beq inex_ckofl
; add.l #4,sp
; frestore (sp)+
; unlk a6
; bra snan
;inex_ckofl:
; btst.b #ovfl_bit,2(sp) ;test for ovfl
; beq inex_ckufl
; add.l #4,sp
; frestore (sp)+
; unlk a6
; bra ovfl
;inex_ckufl:
; btst.b #unfl_bit,2(sp) ;test for unfl
; beq not_b1232
; add.l #4,sp
; frestore (sp)+
; unlk a6
; bra unfl
*
* We do not have the bug 1232 case. Clean up the stack and call
* real_inex.
*
;not_b1232:
; add.l #4,sp
; frestore (sp)+
; unlk a6
;real_inex:
; add.l #1,siginex ;for standalone testing
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
; beq.b inex_cke1
*
* Clear dirty bit on dest register in the frame before branching
* to b1238_fix.
*
; movem.l d0/d1,USER_DA(a6)
; bfextu CMDREG1B(a6){6:3},d0 ;get dest reg no
; bclr.b d0,FPR_DIRTY_BITS(a6) ;clr dest dirty bit
; bsr b1238_fix ;test for bug1238 case
; movem.l USER_DA(a6),d0/d1
; bra.b inex_done
;inex_cke1:
; bclr.b #E1,E_BYTE(a6)
;inex_done:
; frestore (sp)+
; unlk a6
; rte
*
* Overflow exception - DELETED <1/3/91, JPO>
*
;ovfl:
; jmp fpsp_ovfl
;real_ovfl:
; add.l #1,sigovfl ;for standalone testing
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
; bne.b ovfl_done
; bclr.b #E1,E_BYTE(a6)
;ovfl_done:
; frestore (sp)+
; unlk a6
; rte
*
* Underflow exception - DELETED <1/3/91, JPO>
*
;unfl:
; jmp fpsp_unfl
;real_unfl:
; add.l #1,sigunfl ;for standalone testing
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E3,E_BYTE(a6) ;clear and test E3 flag
; bne.b unfl_done
; bclr.b #E1,E_BYTE(a6)
;unfl_done:
; frestore (sp)+
; unlk a6
; rte
*
* Signalling NAN exception - DELETED <1/3/91, JPO>
*
;snan:
; jmp fpsp_snan
;real_snan:
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E1,E_BYTE(a6) ;snan is always an E1 exception
; frestore (sp)+
; unlk a6
; add.l #1,sigsnan ;for standalone testing
; rte
*
* Operand Error exception - DELETED <1/3/91, JPO>
*
;operr:
; jmp fpsp_operr
;real_operr:
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E1,E_BYTE(a6) ;operr is always an E1 exception
; frestore (sp)+
; unlk a6
; add.l #1,sigoperr ;for standalone testing
; rte
*
* BSUN exception - DELETED <1/3/91, JPO>
*
* This sample handler simply clears the nan bit in the FPSR.
*
;bsun:
; jmp fpsp_bsun
;real_bsun:
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E1,E_BYTE(a6) ;bsun is always an E1 exception
; fmove.l FPSR,-(sp)
; bclr.b #nan_bit,(sp)
; fmove.l (sp)+,FPSR
; frestore (sp)+
; unlk a6
; add.l #1,sigbsun ;for standalone testing
; rte
*
* F-line exception - DELETED <1/3/91, JPO>
*
* A 'real' F-line exception is one that the FPSP isn't supposed to
* handle. E.g. an instruction with a co-processor ID that is not 1.
*
*
;fline:
; jmp fpsp_fline
;real_fline:
; add.l #1,sigunimp ;for standalone testing
; rte
*
* Unsupported data type exception - DELETED <1/3/91, JPO>
*
;unsupp:
; jmp fpsp_unsupp
;real_unsupp:
; link a6,#-LOCAL_SIZE
; fsave -(sp)
; bclr.b #E1,E_BYTE(a6) ;unsupp is always an E1 exception
; frestore (sp)+
; unlk a6
; add.l #1,sigunsupp ;for standalone testing
; rte
*
* Trace exception - DELETED <1/3/91, JPO>
*
;real_trace:
; rte
*
* fpsp_fmt_error --- exit point for frame format error
*
* The fpu stack frame does not match the frames existing
* or planned at the time of this writing. The fpsp is
* unable to handle frame sizes not in the following
* version:size pairs:
*
* {4060, 4160} - busy frame
* {4028, 4130} - unimp frame
* {4000, 4100} - idle frame
*
* This entry point simply holds an f-line illegal value.
* Replace this with a call to your kernel panic code or
* code to handle future revisions of the fpu.
*
fpsp_fmt_error:
dc.l $f27f0000 ;f-line illegal
*
* fpsp_done --- FPSP exit point
*
* The exception has been handled by the package and we are ready
* to return to user mode, but there may be OS specific code
* to execute before we do. If there is, do it now.
*
*
;fpsp_done:
; rte
*
* mem_write --- write to user or supervisor address space - MODIFIED <1/3/91, JPO>
*
* Writes to memory while in supervisor mode. copyout accomplishes
* this via a 'moves' instruction. copyout is a UNIX SVR3 (and later) function.
* If you don't have copyout, use the local copy of the function below.
*
* a0 - supervisor source address
* a1 - user destination address
* d0 - number of bytes to write (maximum count is 12)
*
* The supervisor source address is guaranteed to point into the supervisor
* stack. The result is that a UNIX
* process is allowed to sleep as a consequence of a page fault during
* copyout. The probability of a page fault is exceedingly small because
* the 68040 always reads the destination address and thus the page
* faults should have already been handled.
*
* If the EXC_SR shows that the exception was from supervisor space,
* then just do a dumb (and slow) memory move. In a UNIX environment
* there shouldn't be any supervisor mode floating point exceptions.
*
mem_write:
; btst.b #5,EXC_SR(a6) ;check for supervisor state
; beq.b user_write
;super_write:
;moreout:
; move.b (a0)+,(a1)+
; subq.l #1,d0
; bne.b super_write
sub.l #1,d0 ; dec count by 1 for 'dbf' below <1/3/91, JPO>
moreout: ; <1/3/91, JPO>
move.b (a0)+,(a1)+ ; copy 1 byte <1/3/91, JPO>
dbf d0,moreout ; loop until done <1/3/91, JPO>
rts
;user_write:
; move.l d1,-(sp) ;preserve d1 just in case
; move.l d0,-(sp)
; move.l a1,-(sp)
; move.l a0,-(sp)
; jsr copyout
; add.w #12,sp
; move.l (sp)+,d1
; rts
*
* mem_read --- read from user or supervisor address space - DELETED <1/3/91, JPO>
*
* Reads from memory while in supervisor mode. copyin accomplishes
* this via a 'moves' instruction. copyin is a UNIX SVR3 (and later) function.
* If you don't have copyin, use the local copy of the function below.
*
* The FPSP calls mem_read to read the original F-line instruction in order
* to extract the data register number when the 'Dn' addressing mode is
* used.
*
*Input:
* a0 - user source address
* a1 - supervisor destination address
* d0 - number of bytes to read (maximum count is 12)
*
* Like mem_write, mem_read always reads with a supervisor
* destination address on the supervisor stack. Also like mem_write,
* the EXC_SR is checked and a simple memory copy is done if reading
* from supervisor space is indicated.
*
;mem_read:
; btst.b #5,EXC_SR(a6) ;check for supervisor state
; beq.b user_read
;super_read:
; move.b (a0)+,(a1)+
; subq.l #1,d0
; bne.b super_read
; rts
;user_read:
; move.l d1,-(sp) ;preserve d1 just in case
; move.l d0,-(sp)
; move.l a1,-(sp)
; move.l a0,-(sp)
; jsr copyin
; add.w #12,sp
; move.l (sp)+,d1
; rts
*
* Use these routines if your kernel doesn't have copyout/copyin equivalents.
* Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC,
* and copyin overwrites SFC.
*
;copyout: ; DELETED <1/3/91, JPO>
; move.l 4(sp),a0 ; source
; move.l 8(sp),a1 ; destination
; move.l 12(sp),d0 ; count
; sub.l #1,d0 ; dec count by 1 for dbra
; move.l #1,d1
; movec d1,DFC ; set dfc for user data space
;moreout:
; move.b (a0)+,d1 ; fetch supervisor byte
; moves.b d1,(a1)+ ; write user byte
; dbf.w d0,moreout
; rts
;
;copyin: ; DELETED <1/3/91, JPO>
; move.l 4(sp),a0 ; source
; move.l 8(sp),a1 ; destination
; move.l 12(sp),d0 ; count
; sub.l #1,d0 ; dec count by 1 for dbra
; move.l #1,d1
; movec d1,SFC ; set sfc for user space
;morein:
; moves.b (a0)+,d1 ; fetch user byte
; move.b d1,(a1)+ ; write supervisor byte
; dbf.w d0,morein
; rts
;