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.
273 lines
7.0 KiB
Plaintext
273 lines
7.0 KiB
Plaintext
;---------------------------------------------------------------------------
|
|
; File: ExceptionSupport.a
|
|
;
|
|
; Contains: This file contains routines which are used to install, de-install
|
|
; exception handlers and set interrupt levels.
|
|
;
|
|
; Written by: Test Engineering and CPU diagnostics
|
|
;
|
|
; Copyright: © 1990, 1992 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM2> 5/16/92 kc Roll in Horror changes. Comments follow:
|
|
; <2> 1/24/91 CCH Rolled in changes from Scott Smyers.
|
|
; <1> 8/31/90 SS first checked in
|
|
;
|
|
;
|
|
;---------------------------------------------------------------------------
|
|
|
|
include 'STDMacros.a'
|
|
include 'USTMacros.a'
|
|
|
|
IF &TYPE('LUCY')='UNDEFINED' THEN
|
|
LUCY EQU 0
|
|
ENDIF
|
|
IF &TYPE('LINUS')='UNDEFINED' THEN
|
|
LINUS EQU 0
|
|
ENDIF
|
|
IF LUCY OR LINUS THEN
|
|
CPU EQU 00
|
|
ENDIF
|
|
IF &TYPE('CPU')='UNDEFINED' THEN
|
|
CPU EQU 20
|
|
ENDIF
|
|
|
|
IF CPU = 20 THEN
|
|
MACHINE MC68020
|
|
ELSE
|
|
MACHINE MC68000
|
|
ENDIF
|
|
CASE ON
|
|
|
|
;
|
|
; ExceptionSupport.a
|
|
;
|
|
|
|
; When stub is called, address on stack will point to globs field of Exception Info
|
|
ExceptionInfo RECORD 0 ;typedef struct ExceptionInfo
|
|
;{
|
|
; instruction ds.w 1 ; UWORD instruction ; // JSR instruction
|
|
; stubAddress ds.l 1 ; void *stubAddress ; // stub address
|
|
globs ds.l 1 ; struct CTEGlobals *globs ; // pointer to globals.
|
|
handler ds.l 1 ; void (*handler)(void *info) ; // pointer to exception handler.
|
|
argPtr ds.l 1 ; void *argPtr ; // pointer to SubtestInfo structure.
|
|
oldVector ds.l 1 ; void *oldVector ; // vector from Exception Vector Table which
|
|
; // was replaced when this handler was installed.
|
|
oldInfoPtr ds.l 1 ; ExceptionInfo *oldInfoPtr ; // pointer from the ExceptionInfoPtrTable which
|
|
; // was replaced when this handler was installed.
|
|
vectorNumber ds.w 1 ; unsigned short vectorNumber ; //
|
|
ENDR ;} ExceptionInfo ;
|
|
|
|
frameFormat68K0 EQU $10000
|
|
frameFormat68K1 EQU $10001
|
|
|
|
Cpu68000 EQU $00000000 ;Vanilla 68000
|
|
CpuLucy EQU $00000002 ;Woodstock NT
|
|
CpuLinus EQU $00000003 ;Woodstock SC
|
|
CpuWoodstockBit EQU $01 ;Bit 1 set for woodstock
|
|
Cpu68020 EQU $00002000 ;Vanilla 68020
|
|
|
|
;
|
|
; int SetInterruptLevel(int newLevel) ;
|
|
;
|
|
SetInterruptLevel PROC EXPORT
|
|
IMPORT GetInterruptLevel
|
|
jsr GetInterruptLevel
|
|
move.l 4(sp),d1
|
|
lsl.w #8,d1
|
|
move sr,d2
|
|
and.w #$f8ff,d2
|
|
or.w d1,d2
|
|
move d2,sr
|
|
rts
|
|
ENDPROC
|
|
|
|
;
|
|
; int GetInterruptLevel(void) ;
|
|
;
|
|
GetInterruptLevel PROC EXPORT
|
|
move sr,d0
|
|
lsr.w #8,d0
|
|
and.w #$00000007,d0
|
|
rts
|
|
ENDPROC
|
|
|
|
;
|
|
; void *InstallExceptionVector(void *newHandler, int vecNumber) ;
|
|
;
|
|
InstallExceptionVector PROC EXPORT
|
|
IMPORT FindVectorEntry
|
|
|
|
move.l 8(sp),d0 ; push new vector.
|
|
jsr FindVectorEntry ; go find correct entry
|
|
|
|
move.l (a0),d0 ; get current vector.
|
|
move.l 4(sp),(a0) ; install new vector.
|
|
rts
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
;
|
|
; interrupt void ExceptionHandlerStub(void) ;
|
|
;
|
|
ExceptionHandlerStub PROC EXPORT
|
|
movem.l d0-d3/a0-a1,-(sp) ;save scratch registers.
|
|
|
|
WITH ExceptionInfo
|
|
move.l 24(sp),a1 ;get exceptionInfo ptr
|
|
|
|
IF CPU <> 00 THEN
|
|
@Exception68020
|
|
move.w 34(sp),d3 ;get vector/format from exception stack frame
|
|
rol.w #4,d3 ;get format nibble
|
|
and.l #$000f,d3
|
|
|
|
ELSE
|
|
|
|
IF NOT (LUCY OR LINUS) THEN
|
|
@Exception68000
|
|
move.w vectorNumber(a1),d3 ;have to use vector number from exception info
|
|
cmp.w #2,d3 ;If this is bus error or address error,
|
|
beq.s @68000Format1
|
|
cmp.w #3,d3
|
|
bne.s @68000Format0
|
|
@68000Format1
|
|
move.l #frameFormat68K1,d3 ; use frame format 1
|
|
bra.s @CallTheHandler
|
|
ENDIF
|
|
|
|
@ExceptionWoodstock
|
|
@68000Format0
|
|
move.l #frameFormat68K0,d3 ;Otherwise, frame format 0
|
|
|
|
ENDIF ;else CPU = 00
|
|
|
|
@CallTheHandler
|
|
move.l argPtr(a1),-(sp) ;push the interrupt argument onto the stack.
|
|
IF LUCY OR LINUS THEN
|
|
pea 52(sp) ;For Woodstock, have to dig deeper for exception stack frame onto the stack.
|
|
ELSE
|
|
pea 32(sp) ;push the address of the exception stack frame onto the stack.
|
|
ENDIF
|
|
move.l d3,-(sp) ;push frame format
|
|
move.l globs(a1),-(sp) ;push globals ptr
|
|
move.l handler(a1),a0
|
|
jsr (a0) ;call the interrupt handler.
|
|
add #16,sp ;clean up the stack.
|
|
|
|
ENDWITH
|
|
|
|
IF CPU = 00 AND NOT (LUCY OR LINUS) THEN
|
|
cmp.l #frameFormat68K1,d3 ;If this is 68000 type 1,
|
|
bne.s @ExceptionRte
|
|
movem.l (sp)+,d0-d3/a0-a1 ; we have to pop extra stuff before rte
|
|
add.l #12,sp ; pop exceptionInfo & Bus/Addr err info
|
|
rte ; now we're out of here
|
|
ENDIF
|
|
|
|
@ExceptionRte
|
|
movem.l (sp)+,d0-d3/a0-a1 ;restore registers
|
|
add.l #4,sp ;pop exceptionInfo pointer
|
|
IF NOT (LUCY OR LINUS) THEN
|
|
rte ;return from exception.
|
|
ELSE
|
|
rts ;Woodstock, back to ROM-based ISR
|
|
ENDIF
|
|
ENDP
|
|
|
|
;
|
|
; FakeExceptionCall(int vectorNumber) ;
|
|
;
|
|
FakeExceptionCall PROC EXPORT
|
|
IMPORT FindVectorEntry,CalcVectorEntry
|
|
|
|
move.l 4(sp),d0 ;get new vector
|
|
IF NOT (LUCY OR LINUS) THEN
|
|
jsr FindVectorEntry ;go find correct entry
|
|
ELSE
|
|
moveq.l #0,a0 ;Find real vector address for Woodstock, this time
|
|
jsr CalcVectorEntry
|
|
ENDIF
|
|
move.l (a0),a0 ;Get Service Routine address
|
|
|
|
IF CPU <> 00 THEN
|
|
move.l 4(sp),d1 ; get vector number
|
|
asl.w #2,d1 ; mult. by 4 to get vector offset.
|
|
move.w d1,-(sp) ; push the vector offset.
|
|
ENDIF
|
|
|
|
pea @1 ;push the return program counter
|
|
move sr,-(sp) ;push the status register.
|
|
jmp (a0) ;jump to exception handler.
|
|
@1
|
|
rts
|
|
|
|
ENDP
|
|
|
|
IF LUCY THEN
|
|
WoodstockLevel1 EQU $00700020 ;Level 1 ISR addr goes here
|
|
WoodstockLevel2 EQU $00700024 ;Level 2 or above ISR addr goes here
|
|
ENDIF
|
|
|
|
IF LINUS THEN
|
|
WoodstockLevel1 EQU $0098000C ;Level 1 ISR addr goes here
|
|
WoodstockLevel2 EQU $00980010 ;Level 2 or above ISR addr goes here
|
|
ENDIF
|
|
|
|
;
|
|
; FindVectorEntry (d0 = vecNumber) ;
|
|
; return a0 = vector Address
|
|
; CalcVectorEntry (d0 = vecNumber, a0 = vector base) ;
|
|
; return a0 = vector Address
|
|
|
|
FindVectorEntry PROC EXPORT
|
|
EXPORT CalcVectorEntry
|
|
|
|
IF CPU <> 00 THEN
|
|
MACHINE MC68020
|
|
@Get68020VBase ; 68020, use vbr
|
|
movec vbr,a0 ; get base of exception vector table.
|
|
|
|
ELSEIF NOT (LUCY OR LINUS) THEN
|
|
@Get68000VBase ; 68000, assume 0 is ram
|
|
move.l #0,a0 ; get base of exception vector table.
|
|
|
|
ELSE
|
|
@GetWoodstockVBase ; Woodstock has RAM-based vector pointers
|
|
cmp.w #25,d0
|
|
bne.s @10
|
|
move.l #WoodstockLevel1,a0 ; Only have access to level 1 and 2 ints
|
|
rts
|
|
@10 move.l #WoodstockLevel2,a0
|
|
rts
|
|
ENDIF
|
|
|
|
CalcVectorEntry
|
|
lsl.w #2,d0
|
|
lea (a0,d0.w),a0 ; point to vector table entry.
|
|
rts
|
|
|
|
|
|
ENDP
|
|
|
|
;----------------------------------------------------------------------
|
|
;
|
|
; This routine needs to return a pointer to the CTE globals in d0
|
|
;
|
|
; Input: a5 - pointer to the UST globals
|
|
;
|
|
; Output: d0 - pointer to the CTE globals
|
|
;
|
|
;----------------------------------------------------------------------
|
|
|
|
CASE ON
|
|
|
|
GetCTEGlobals PROC EXPORT
|
|
|
|
move.l USTGlobals.CTEGlobals(a5),d0 ;Get the CTE globals pointer
|
|
rts ;and return
|
|
|
|
ENDPROC |