Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.2 SOURCE/2/EXCEPTN.S
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

379 lines
9.4 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

*************************************************
* *
* CP/M-68k Basic Disk Operating System *
* Exception Handling Module *
* *
* Version 0.0 -- July 21, 1982 *
* Version 0.1 -- July 25, 1982 *
* Version 0.2 -- October 6, 1982 *
* Version 0.3 -- December 21, 1982 *
* *
* Modified 2/15/84 sw for 68010 support *
* *
*************************************************
.globl _initexc
.globl _tpa_lp
.globl _tpa_hp
.globl gouser *sw RTE routine
bgetseg = 18
bsetexc = 22
buserr = 2
spurious = 24
trap0 = 32
trap2 = 34
trap3 = 35
endvec = 48
_initexc:
* Initialize Exception Vector Handlers
* It has 1 passed parameter: the address of the exception vector array
move #bsetexc,d0
moveq #2,d1
move.l #exchndl,d2
init1:
movem.l d0-d2,-(sp)
trap #3 * BIOS call to set exception vector
movem.l (sp)+,d0-d2
init2: addq #1,d1
add.l #4,d2
cmpi #spurious,d1
bne init3
move #trap0,d1
init3: cmpi #trap2,d1
beq init2 * don't init trap 2 or trap 3
cmpi #trap3,d1
beq init2
cmpi #endvec,d1
blt init1
* initialize the exception vector array
moveq #bgetseg,d0
trap #3 * get the original TPA limits
movea.l d0,a0
tst.w (a0)+
move.l (a0)+,d1 * d1 = original low TPA limit
move.l d1,d2
add.l (a0),d2 * d2 = original high TPA limit
move.l _tpa_lp,d3 * d3 = new low TPA limit
move.l _tpa_hp,d4 * d4 = new high TPA limit
move #17,d0
movea.l 4(sp),a0
move.l a0,evec_adr * save exception vector address
init4:
cmp.l (a0),d1
bhi do_init * if old exception outside orig TPA, clear it
cmp.l (a0),d2
bls do_init
* current exception array entry is in original TPA
cmp.l (a0),d3
bhi dontinit * if old exception in old TPA but outside new
cmp.l (a0),d4 * TPA, don't clear it
bls dontinit
do_init:
clr.l (a0)
dontinit:
tst.l (a0)+
dbf d0,init4
rts
.page
exchndl:.equ *
#ifndef M68010
bsr.w except * 2 Buserr
excrtn0:
bsr.w except * 3 Addressing error
bsr.w except * 4 Illegal Instruction
#else
.globl m68010 * Note case difference!
m68010: * For build process
bsr.w berr * 2 Buserr
excrtn0:
bsr.w berr * 3 Addressing error
bsr.w except * 4 Illegal Instruction
#endif
bsr.w except * 5
bsr.w except * 6
bsr.w except * 7
#ifndef M68010
bsr.w except * 8
#else * Privilege violation
bsr.w privviol * 8
#endif
bsr.w except * 9
bsr.w except * 10
bsr.w except * 11
bsr.w except * 12
bsr.w except * 13
bsr.w except * 14
bsr.w except * 15
bsr.w except * 16
bsr.w except * 17
bsr.w except * 18
bsr.w except * 19
bsr.w except * 20
bsr.w except * 21
bsr.w except * 22
bsr.w except * 23
bsr.w except * 24
bsr.w except * 25
bsr.w except * 26
bsr.w except * 27
bsr.w except * 28
bsr.w except * 29
bsr.w except * 30
bsr.w except * 31
bsr.w except * 32
bsr.w except * 33
bsr.w except * 34
bsr.w except * 35
bsr.w except * 36
bsr.w except * 37
bsr.w except * 38
bsr.w except * 39
.page
#ifdef M68010
*
* Here if the exception in question was a buserr/addressing error.
* We reformat the stack to look like a 68000.
*
* Entered with a standard 68010 exception stack frame with a return
* address on top (at 0(sp)).
*
berr:
move.l $0(sp),$2a(sp) * Move return address
move.w $0c(sp),$2e(sp) * Move Status word
andi.w #7,$2e(sp) * Clear all but FC0-2
move.l $0e(sp),$30(sp) * Copy Fault address
move.w $1c(sp),$34(sp) * Move IR
move.w $4(sp),$36(sp) * Move SR
move.l $6(sp),$38(sp) * Move PC
move.w $0a(sp),$3c(sp) * Move format word
adda.l #$2a,sp * Make sp -> new frame
bra except * Merge
******************************************************************************
* Here we make up for a faux pas in the C compiler. Change all *
* move from SR instructions ($40CX) to move from CCR ($42CX). *
* Precludes executing 68000 programs in ROM on a 68010. *
* *
* Relies on the fact that the exception PC (Stack offset 0E below) *
* points to the instruction on an illegal instruction exception. *
******************************************************************************
privviol:
movem.l d0/a0,-(sp) * Save some regs
move.l $0e(sp),a0 * A0 -> Instruction
move.w (a0),d0 * d0 = Instruction
andi.w #$FFC0,d0 * Mask off <EA> field
cmpi.w #$40C0,d0 * Move from SR?
bne notsr * No, handle normally
ori.w #$0200,(a0) * Change to move from CCR
movem.l (sp)+,d0/a0 * Restore regs
tst.l (sp)+ * Pop return address
rte * Try it again
notsr: movem.l (sp)+,d0/a0 * Abandon hope, all ye ..
.page
#endif
except:
clr.w -(sp)
movem.l a0/d0,-(sp) * 10 (11) words now on stack in following order
* _______________________________
* |____________D0.L_______________|
* |____________A0.L_______________|
* |____0000______|________________
* |_______Handler Return__________|
* If bus error, extra 2 longs are here
* ______________
* |__Status Reg__|________________
* |_____Exception Return__________|
* |_(format word)|
move.l 10(sp),d0 * get return address from above array
sub.l #excrtn0,d0 * d0 now has 4 * (encoded excptn nmbr), where
* encoded excptn nmbr is in [0..21,22..37]
* representing [2..23,32..47]
cmpi #36,d0 * if d0/4 is in [0..9,22..29] then
ble chkredir * the exception may be redirected
cmpi #88,d0
blt dfltexc
cmpi #116,d0
bgt dfltexc
* in range of redirected exceptions
subi #48,d0 * subtract 4*12 to normalize [0..9,22..29]
* into [0..9,10..17]
chkredir:
movea.l evec_adr,a0
adda d0,a0 * index into exception vector array
tst.l (a0) * if 00000000, then not redirected
bne usrexc
* not redirected, do default handler
supexc: * Here for supervisor state
cmpi #40,d0
blt dfltexc
addi #48,d0 * add 4*12 that was sub'd above
dfltexc:
adda #14,sp * throw away 7 words that we added to stack
asr #2,d0 * divide d0 by 4
* now d0 is in [0..21,22..37]
* to represent [2..23,32..47]
cmpi #2,d0 * bus or address error?
bge nobusexc
movem.l (sp)+,a0-a1 * if yes, throw away 4 words from stack
nobusexc:
tst.w (sp)+ * throw away stacked SR
addi #2,d0
cmpi #23,d0 * get back real excptn nmbr in [2..23,32..47]
ble lowexc
addi #8,d0
lowexc: move d0,-(sp) * save excptn nmbr
lea excmsg1,a0
bsr print * print default exception message
move (sp)+,d0
bsr prtbyte
lea excmsg2, a0
bsr print
move.l (sp)+,d0
bsr prtlong
lea excmsg3, a0
bsr print
clr.l d0
trap #2 * warm boot
rte
usrexc:
* Call user exception handler
* make sure exception information is on his stack
cmpi #8,d0 * address or bus error?
blt addrexc * if yes, skip
btst #13,14(sp) * exception occured in user state?
bne supexc *sw if no, go to supervisor handler
move.l (a0),10(sp) * put user handler address on our stack
move.l usp,a0 * user stack pointer to a0
move.l 16(sp),-(a0) * put exception return on user stack
move.w 14(sp),-(a0) * put SR on user stack
move.l a0,usp * update user stack pointer
movem.l (sp)+,a0/d0 * restore regs
move.l 2(sp),8(sp) * move address of user handler to excptn rtn
#ifdef M68010
clr.w 12(sp) *sw Clear out the format word
#endif
addq #6,sp * clear junk from stack
andi #$7fff,(sp) * clear trace bit
rte * go to user handler
addrexc:
btst #13,22(sp) * exception occured in user state?
bne supexc *sw if no, go to supervisor handler
move.l (a0),10(sp) * put user handler address on our stack
move.l usp,a0 * user stack pointer to a0
move.l 24(sp),-(a0) * put exception return on user stack
move.w 22(sp),-(a0) * put SR on user stack
move.l 18(sp),-(a0) * put extra 2 longs on user stack
move.l 14(sp),-(a0)
move.l a0,usp * update user stack pointer
movem.l (sp)+,a0/d0 * restore regs
move.l 2(sp),16(sp) * move address of user handler to excptn rtn
#ifdef M68010
clr.w 20(sp) *sw Clear format word
#endif
adda #14,sp * clear junk from stack
andi #$7fff,(sp) * clear trace bit
rte * go to user handler
.page
*******************************************************************************
*
* gouser routine. This routine performs an RTE to go to the user program
* User EPA is passed in A0.L.
*
*******************************************************************************
gouser:
#ifdef M68010
clr.w -(sp) * Push format word
#endif
move.l a0,-(sp) * Push epa
clr.w -(sp) * and SR
rte * Do it. Into user program.
.page
*
* Subroutines
*
print:
clr.l d1
move.b (a0)+, d1
beq prtdone
move #2, d0
trap #2
bra print
prtdone:
rts
prtlong:
* Print d0.l in hex format
move d0,-(sp)
swap d0
bsr prtword
move (sp)+,d0
prtword:
* Print d0.w in hex format
move d0,-(sp)
lsr #8,d0
bsr prtbyte
move (sp)+,d0
prtbyte:
* Print d0.b in hex format
move d0,-(sp)
lsr #4,d0
bsr prtnib
move (sp)+,d0
prtnib:
andi #$f,d0
cmpi #10,d0
blt lt10
addi.b #'A'-'9'-1,d0
lt10:
addi.b #'0',d0
move d0,d1
move #2,d0
trap #2
rts
.data
excmsg1:
.dc.b 13,10,10,'Exception $',0
excmsg2:
.dc.b ' at user address $',0
excmsg3:
.dc.b '. Aborted.',0
.bss
evec_adr:
.ds.l 1
.end
0
excmsg2:
.dc.b ' at user address $',0
excmsg3:
.dc.b '. Aborted.',0
.bss
evec_adr:
.ds.l 1
.end