Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v101/bdos/exceptn.s
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

292 lines
6.0 KiB
ArmAsm

*************************************************
* *
* 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 *
* *
*************************************************
.globl _initexc
.globl _tpa_lp
.globl _tpa_hp
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
exchndl:
bsr.w except
excrtn0:
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
bsr.w except
except:
clr.w -(sp)
movem.l a0/d0,-(sp) * 10 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__________|
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
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
move.l (a0),10(sp) * put user handler address on our stack
move.l usp,a0 * user stack pointer to a0
cmpi #8,d0 * address or bus error?
blt addrexc * if yes, skip
btst #13,14(sp) * exception occured in user state?
bne supstat1 * if no, go to supervisor handler
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
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 supstat2 * if no, go to supervisor handler
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
adda #14,sp * clear junk from stack
andi #$7fff,(sp) * clear trace bit
rte * go to user handler
supstat1:
move.w 14(sp),8(sp) * move SR to our exception return
bra supstat3
supstat2:
move.w 22(sp),8(sp)
supstat3:
movem.l (sp)+,a0/d0
rte
*
* 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