mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-22 16:04:18 +00:00
292 lines
6.0 KiB
ArmAsm
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
|