mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-01 11:29:27 +00:00
0ba83392d4
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.
328 lines
10 KiB
Plaintext
328 lines
10 KiB
Plaintext
;
|
|
; File: XStore.a
|
|
;
|
|
; Contains: Routines to store operands to memory or registers
|
|
;
|
|
; 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.
|
|
|
|
; xstore.a
|
|
|
|
; Based upon Motorola file 'x_store.sa'.
|
|
|
|
; CHANGE LOG:
|
|
; 09 Jan 91 JPO Deleted unreferenced label "E3_sto". Renamed labels
|
|
; "opc011" and "sinf" to "stopc011" and "stsinf",
|
|
; respectively. Replaced "bsr mem_write" with in-line
|
|
; code in subroutines 'dest_dbl', 'dest_sgl', and
|
|
; 'dest_ext'. Replaced "bsr get_fline" with in_line
|
|
; code in subroutine 'dest_sgl'.
|
|
; 24 Jan 91 JPO Corrected code to store result if destination is FP2
|
|
; or FP3 (see routine 'sto_fp' below).
|
|
; 18 Feb 91 JPO Modified routine 'sto_fp' to normalize unnormalized
|
|
; results prior to storing in dst FP register.
|
|
;
|
|
|
|
*
|
|
* x_store.sa 3.1 12/10/90
|
|
*
|
|
* store --- store operand to memory or register
|
|
*
|
|
* Used by underflow and overflow handlers.
|
|
*
|
|
* a0 = points to fp value to be stored.
|
|
*
|
|
|
|
* 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.
|
|
|
|
* X_STORE IDNT 2,1 Motorola 040 Floating Point Software Package
|
|
|
|
|
|
fpreg_mask:
|
|
dc.b $80,$40,$20,$10,$08,$04,$02,$01
|
|
|
|
|
|
store:
|
|
btst.b #E3,E_BYTE(a6)
|
|
beq E1_sto
|
|
;E3_sto: ; label DELETED <1/9/91, JPO>
|
|
move.l CMDREG3B(a6),d0
|
|
bfextu d0{6:3},d0 ;isolate dest. reg from cmdreg3b
|
|
;
|
|
; First normalize any unnormalized result; lack of normalization is due
|
|
; to underflow for single- or double-precision rounding, so result is
|
|
; guaranteed to be zero or normal to extended precision.
|
|
;
|
|
sto_fp:
|
|
move.w LOCAL_EX(a0),d1 ; isolate exponent <2/18/91, JPO>
|
|
andi.w #$7fff,d1 ; <2/18/91, JPO>
|
|
beq.b @2 ; zero exponent <2/18/91, JPO>
|
|
cmpi.w #$7fff,d1 ; <2/18/91, JPO>
|
|
beq.b @2 ; infinity <2/18/91, JPO>
|
|
tst.l LOCAL_HI(a0) ; test high mantissa <2/18/91, JPO>
|
|
bmi.b @2 ; normal <2/18/91, JPO>
|
|
bne.b @1 ; unnormalized <2/18/91, JPO>
|
|
|
|
tst.l LOCAL_LO(a0) ; test low mantissa <2/18/91, JPO>
|
|
bne.b @1 ; unnormalized <2/18/91, JPO>
|
|
|
|
clr.w LOCAL_EX(a0) ; zero result. zero exponent <2/18/91, JPO>
|
|
bra.b @2 ; <2/18/91, JPO>
|
|
|
|
@1: ; label ADDED <2/18/91, JPO>
|
|
move.l d0,-(sp) ; save d0 <2/18/91, JPO>
|
|
bsr.w nrm_set ; normalize <2/18/91, JPO>
|
|
move.l (sp)+,d0 ; restore d0 <2/18/91, JPO>
|
|
|
|
@2: ; label ADDED <2/18/91, JPO>
|
|
lea fpreg_mask,a1
|
|
move.b (a1,d0.w),d0 ;convert reg# to dynamic register mask
|
|
tst.b LOCAL_SGN(a0)
|
|
beq.b is_pos
|
|
bset.b #sign_bit,LOCAL_EX(a0)
|
|
is_pos:
|
|
fmovem.x (a0),d0 ;move to correct register
|
|
*
|
|
* if fp0-fp3 is being modified, we must put a copy
|
|
* in the USER_FPn variable on the stack because all exception
|
|
* handlers restore fp0-fp3 from there.
|
|
*
|
|
cmp.b #$80,d0
|
|
bne.b not_fp0
|
|
fmovem.x fp0,USER_FP0(a6)
|
|
rts
|
|
not_fp0:
|
|
cmp.b #$40,d0
|
|
bne.b not_fp1
|
|
fmovem.x fp1,USER_FP1(a6)
|
|
rts
|
|
not_fp1:
|
|
cmp.b #$20,d0
|
|
bne.b not_fp2
|
|
; fmovem.x fp1,USER_FP2(a6) ; DELETED <1/24/91, JPO>
|
|
fmovem.x fp2,USER_FP2(a6) ; copy fp2 to stack storage <1/24/91, JPO>
|
|
rts
|
|
not_fp2:
|
|
cmp.b #$10,d0
|
|
bne.b not_fp3
|
|
; fmovem.x fp1,USER_FP3(a6) ; DELETED <1/24/91, JPO>
|
|
fmovem.x fp3,USER_FP3(a6) ; copy fp3 to stack storage <1/24/91, JPO>
|
|
rts
|
|
not_fp3:
|
|
rts
|
|
|
|
E1_sto:
|
|
bsr g_opcls ;returns opclass in d0
|
|
cmpi.b #3,d0
|
|
beq.b stopc011 ;branch if opclass 3 - label renamed <1/9/91, JPO>
|
|
move.l CMDREG1B(a6),d0
|
|
bfextu d0{6:3},d0 ;extract destination register
|
|
bra sto_fp
|
|
|
|
stopc011: ; label renamed <1/9/91, JPO>
|
|
bsr g_dfmtou ;returns dest format in d0
|
|
* ;ext=00, sgl=01, dbl=10
|
|
move.l a0,a1 ;save source addr in a1
|
|
move.l EXC_EA(a6),a0 ;get the address
|
|
; cmpi.l #0,d0 ;if dest format is extended - DELETED <1/9/91, JPO>
|
|
tst.l d0 ; replaces "cmpi.l #0,d0" <1/9/91, JPO>
|
|
beq.w dest_ext ;then branch
|
|
cmpi.l #1,d0 ;if dest format is single
|
|
beq.b dest_sgl ;then branch
|
|
*
|
|
* fall through to dest_dbl
|
|
*
|
|
|
|
*
|
|
* dest_dbl --- write double precision value to user space
|
|
*
|
|
*Input
|
|
* a0 -> destination address
|
|
* a1 -> source in extended precision
|
|
*Output
|
|
* a0 -> destroyed
|
|
* a1 -> destroyed
|
|
* d0 -> 0
|
|
*
|
|
*Changes extended precision to double precision.
|
|
* Note: no attempt is made to round the extended value to double.
|
|
* dbl_sign = ext_sign
|
|
* dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
|
|
* get rid of ext integer bit
|
|
* dbl_mant = ext_mant{62:12}
|
|
*
|
|
* --------------- --------------- ---------------
|
|
* extended -> |s| exp | |1| ms mant | | ls mant |
|
|
* --------------- --------------- ---------------
|
|
* 95 64 63 62 32 31 11 0
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* v v
|
|
* --------------- ---------------
|
|
* double -> |s|exp| mant | | mant |
|
|
* --------------- ---------------
|
|
* 63 51 32 31 0
|
|
*
|
|
dest_dbl:
|
|
clr.l d0 ;clear d0
|
|
move.w LOCAL_EX(a1),d0 ;get exponent
|
|
sub.w #$3fff,d0 ;subtract extended precision bias
|
|
cmp.w #$4000,d0 ;check if inf
|
|
beq.b inf ;if so, special case
|
|
add.w #$3ff,d0 ;add double precision bias
|
|
swap d0 ;d0 now in upper word
|
|
lsl.l #4,d0 ;d0 now in proper place for dbl prec exp
|
|
tst.b LOCAL_SGN(a1)
|
|
beq.b get_mant ;if postive, go process mantissa
|
|
bset.l #31,d0 ;if negative, put in sign information
|
|
* ; before continuing
|
|
bra.b get_mant ;go process mantissa
|
|
inf:
|
|
move.l #$7ff00000,d0 ;load dbl inf exponent
|
|
clr.l LOCAL_HI(a1) ;clear msb
|
|
tst.b LOCAL_SGN(a1)
|
|
beq.b dbl_inf ;if positive, go ahead and write it
|
|
bset.l #31,d0 ;if negative put in sign information
|
|
dbl_inf:
|
|
move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack
|
|
bra.b dbl_wrt
|
|
get_mant:
|
|
move.l LOCAL_HI(a1),d1 ;get ms mantissa
|
|
bfextu d1{1:20},d1 ;get upper 20 bits of ms
|
|
or.l d1,d0 ;put these bits in ms word of double
|
|
move.l d0,LOCAL_EX(a1) ;put the new exp back on the stack
|
|
move.l LOCAL_HI(a1),d1 ;get ms mantissa
|
|
move.l #21,d0 ;load shift count
|
|
lsl.l d0,d1 ;put lower 11 bits in upper bits
|
|
move.l d1,LOCAL_HI(a1) ;build lower lword in memory
|
|
move.l LOCAL_LO(a1),d1 ;get ls mantissa
|
|
bfextu d1{0:21},d0 ;get ls 21 bits of double
|
|
or.l d0,LOCAL_HI(a1) ;put them in double result
|
|
dbl_wrt:
|
|
; move.l #$8,d0 ;byte count for double precision number - DELETED <1/9/91, JPO>
|
|
; exg a0,a1 ;a0=supervisor source, a1=user dest - DELETED <1/9/91, JPO>
|
|
; bsr.l mem_write ;move the number to the user's memory - DELETED <1/9/91, JPO>
|
|
|
|
move.l (a1)+,(a0)+ ; move d.p. number to user memory <1/9/91, JPO>
|
|
move.l (a1),(a0) ; <1/9/91, JPO>
|
|
|
|
rts
|
|
*
|
|
* dest_sgl --- write single precision value to user space
|
|
*
|
|
*Input
|
|
* a0 -> destination address
|
|
* a1 -> source in extended precision
|
|
*
|
|
*Output
|
|
* a0 -> destroyed
|
|
* a1 -> destroyed
|
|
* d0 -> 0
|
|
*
|
|
*Changes extended precision to single precision.
|
|
* sgl_sign = ext_sign
|
|
* sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
|
|
* get rid of ext integer bit
|
|
* sgl_mant = ext_mant{62:12}
|
|
*
|
|
* --------------- --------------- ---------------
|
|
* extended -> |s| exp | |1| ms mant | | ls mant |
|
|
* --------------- --------------- ---------------
|
|
* 95 64 63 62 40 32 31 12 0
|
|
* | |
|
|
* | |
|
|
* | |
|
|
* v v
|
|
* ---------------
|
|
* single -> |s|exp| mant |
|
|
* ---------------
|
|
* 31 22 0
|
|
*
|
|
dest_sgl:
|
|
clr.l d0
|
|
move.w LOCAL_EX(a1),d0 ;get exponent
|
|
sub.w #$3fff,d0 ;subtract extended precision bias
|
|
cmp.w #$4000,d0 ;check if inf
|
|
beq.b stsinf ;if so, special case - label renamed <1/9/91, JPO>
|
|
add.w #$7f,d0 ;add single precision bias
|
|
swap d0 ;put exp in upper word of d0
|
|
lsl.l #7,d0 ;shift it into single exp bits
|
|
tst.b LOCAL_SGN(a1)
|
|
beq.b get_sman ;if positive, continue
|
|
bset.l #31,d0 ;if negative, put in sign first
|
|
bra.b get_sman ;get mantissa
|
|
stsinf: ; label renamed <1/9/91, JPO>
|
|
move.l #$7f800000,d0 ;load single inf exp to d0
|
|
tst.b LOCAL_SGN(a1)
|
|
beq.b sgl_wrt ;if positive, continue
|
|
bset.l #31,d0 ;if negative, put in sign info
|
|
bra.b sgl_wrt
|
|
|
|
get_sman:
|
|
move.l LOCAL_HI(a1),d1 ;get ms mantissa
|
|
bfextu d1{1:23},d1 ;get upper 23 bits of ms
|
|
or.l d1,d0 ;put these bits in ms word of single
|
|
|
|
sgl_wrt:
|
|
move.l d0,L_SCR1(a6) ;put the new exp back on the stack
|
|
move.l #$4,d0 ;byte count for single precision number
|
|
tst.l a0 ;users destination address
|
|
beq.b sgl_Dn ;destination is a data register
|
|
|
|
; exg a0,a1 ;a0=supervisor source, a1=user dest - DELETED <1/9/91, JPO>
|
|
; lea.l L_SCR1(a6),a0 ;point a0 to data - DELETED <1/9/91, JPO>
|
|
; bsr.l mem_write ;move the number to the user's memory - DELETED <1/9/91, JPO>
|
|
|
|
lea.l L_SCR1(a6),a1 ; point a1 to data <1/9/91, JPO>
|
|
move.l (a1),(a0) ; move the number to user memory <1/9/91, JPO>
|
|
|
|
rts
|
|
sgl_Dn:
|
|
; bsr.l get_fline ;returns fline word in d0 - DELETED <1/9/91, JPO>
|
|
; and.w #$7,d0 ;isolate register number - DELETED <1/9/91, JPO>
|
|
; move.l d0,d1 ;d1 has size:reg formatted for reg_dest - DELETED <1/9/91, JPO>
|
|
; or.l #$10,d1 ;reg_dest wants size added to reg# - DELETED <1/9/91, JPO>
|
|
|
|
move.l USER_FPIAR(a6),a0 ; read opcode into d1.w <1/9/91, JPO>
|
|
sub.l d1,d1 ; with d1 high word cleared <1/9/91, JPO>
|
|
move.w (a0),d1 ; <1/9/91, JPO>
|
|
and.w #7,d1 ; isolate register number <1/9/91, JPO>
|
|
or.b #$10,d1 ; set size to 32 bits <1/9/91, JPO>
|
|
|
|
bra reg_dest ;size is X, rts in reg_dest will
|
|
* ;return to caller of dest_sgl
|
|
|
|
dest_ext:
|
|
tst.b LOCAL_SGN(a1) ;put back sign into exponent word
|
|
beq.b dstx_cont
|
|
bset.b #sign_bit,LOCAL_EX(a1)
|
|
dstx_cont:
|
|
clr.b LOCAL_SGN(a1) ;clear out the sign byte
|
|
|
|
; move.l #$0c,d0 ;byte count for extended number - DELETED <1/9/91, JPO>
|
|
; exg a0,a1 ;a0=supervisor source, a1=user dest - DELETED <1/9/91, JPO>
|
|
; bsr.l mem_write ;move the number to the user's memory - DELETED <1/9/91, JPO>
|
|
|
|
move.l (a1)+,(a0)+ ; move the number to user's memory <1/9/91, JPO>
|
|
move.l (a1)+,(a0)+
|
|
move.l (a1),(a0)
|
|
|
|
rts
|
|
|
|
|