mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
387 lines
10 KiB
ArmAsm
387 lines
10 KiB
ArmAsm
*****************************************************************
|
||
* *
|
||
* Usual filename: BDOS10.S *
|
||
* Originally Written by W. B. Tyler, 1982. *
|
||
* Adapted by: Timothy M. Benson *
|
||
* Control: 5 May 83 15:25 (TMB) *
|
||
* Modified 18 March 1984 for extended exception handling WBT. *
|
||
* This version works with the 68010, not the 68000. *
|
||
* *
|
||
* initiate program execution *
|
||
* *
|
||
*****************************************************************
|
||
*
|
||
.globl _GO
|
||
.globl _STEP
|
||
.globl _BDOS
|
||
.globl _GETSSP
|
||
.globl _EXINIT
|
||
.globl _GETVBR
|
||
.globl _GETSFC
|
||
.globl _GETDFC
|
||
|
||
.text
|
||
*
|
||
*
|
||
_GO: clr.l errflag
|
||
movem.l d0-d7/a0-a5,regsave save register variables
|
||
movem.l a6/a7,asave
|
||
move.w #22,d0 set up illegal trap vector
|
||
move.w #iltv,d1
|
||
move.w d1,thvnum
|
||
move.l #th,d2
|
||
trap #3
|
||
move.l d0,savev
|
||
*
|
||
move.l 4(a7),a0 addr of state save area
|
||
*
|
||
move.w #62,d0 get supervisor mode
|
||
trap #2
|
||
*
|
||
move.l (a0),pctr pc to start at
|
||
move.w 12(a0),status starting status
|
||
move.l 4(a0),a1 set up stack pointers
|
||
move a1,usp user stack pointer
|
||
move.l 8(a0),a7 supervisor stack pointer
|
||
move.l 78(a0),d0 set up control registers...
|
||
movec d0,vbr
|
||
move.l 82(a0),d0
|
||
movec d0,sfc
|
||
move.l 86(a0),d0
|
||
movec d0,dfc
|
||
movem.l 14(a0),d0-d7/a0-a6 set up other registers
|
||
clr.w -(a7) format word
|
||
move.l pctr,-(a7) set up for rte
|
||
and.w #$7FFF,status
|
||
move.w status,-(a7)
|
||
rte begin executing
|
||
*
|
||
* trap handling for _GO and _STEP
|
||
*
|
||
th1: move.w (a7)+,status grab info from sys stack
|
||
move.l (a7)+,pctr (this one for exceptions)
|
||
movem.l d0-d1,bsave save registers
|
||
Move.W #62,D0 Back into supervisor mode
|
||
Trap #2 By using the BDOS call
|
||
movem.l bsave,d0-d1 restore registers
|
||
jmp th2
|
||
|
||
th: move.w (a7)+,status grab info from sys stack
|
||
Movem.L D0-D1/A0,bsave Save some stuff
|
||
Move.L #OLDVEC,A0 Get address of exception storage
|
||
Move.W #9,D0 Load exception vector count (-1)
|
||
Move.L (A7),D1 Get return address from stack
|
||
th3: Cmp.L (A0)+,D1 Is this the one we have?
|
||
Beq th4 Yep.
|
||
Dbf D0,th3 Are we done yet?
|
||
Movem.L bsave,D0-D1/A0 User exception vector
|
||
move.l (a7)+,pctr unstack PC
|
||
add.l #2,a7 unstack format word
|
||
th2: move.l a7,savessp
|
||
movem.l d0-d2,-(a7)
|
||
movec vbr,d0 save control registers
|
||
movec sfc,d1
|
||
movec dfc,d2
|
||
move.l d0,savevbr
|
||
move.l d1,savesfc
|
||
move.l d2,savedfc
|
||
movem.l (a7)+,d0-d2
|
||
move.l a0,savea0
|
||
move.l usp,a0
|
||
move.l a0,saveusp
|
||
move.l savea0,a0
|
||
andi $5fff,sr
|
||
movem.l a6/a7,bsave save regs
|
||
move.l asave+4,a7 get old regs
|
||
move.l 4(a7),a6
|
||
move.l pctr,(a6)
|
||
move.l saveusp,4(a6)
|
||
move.l savessp,8(a6)
|
||
move.w status,12(a6)
|
||
and.w #$7FFF,12(a6)
|
||
movem.l d0-d7/a0-a5,14(a6)
|
||
move.l savevbr,78(a6)
|
||
move.l savesfc,82(a6)
|
||
move.l savedfc,86(a6)
|
||
move.w #22,d0
|
||
move.w thvnum,d1
|
||
move.l savev,d2
|
||
trap #3
|
||
move.l bsave,70(a6)
|
||
move.l bsave+4,74(a6)
|
||
btst #5,status
|
||
beq wasusr
|
||
move.l savessp,74(a6)
|
||
wasusr: move.l asave,a6
|
||
movem.l regsave,d0-d7/a0-a5
|
||
move.l errflag,d0 return error flag
|
||
rts back to SID proper
|
||
|
||
th4: Movem.L bsave,D0-D1/A0 Restore registers (again)
|
||
Move.W status,-(SP) Save status register again
|
||
THRTE: Rte Continue processing as in GO.
|
||
|
||
*
|
||
*
|
||
*****************************************************************
|
||
* *
|
||
* execute one user instruction (trace or notrace) *
|
||
* *
|
||
*****************************************************************
|
||
*
|
||
_STEP: clr.l errflag
|
||
movem.l d0-d7/a0-a5,regsave save registers
|
||
movem.l a6/a7,asave save registers
|
||
*
|
||
move.w #62,d0 get supervisor mode
|
||
trap #2
|
||
*
|
||
move.w #22,d0
|
||
move.w #trv,d1
|
||
move.w d1,thvnum
|
||
move.l #th,d2
|
||
trap #3
|
||
move.l d0,savev Save previous trace exception pointer.
|
||
*
|
||
move.l asave+4,a0 caller's stack ptr
|
||
move.l 4(a0),a0 address of cpu state save area
|
||
move.l (a0),pctr starting pc
|
||
move.w 12(a0),d0 status
|
||
ori.w #$8000,d0 set trace bit
|
||
move.w d0,status starting status
|
||
move.l 4(a0),a1 user stack pointer
|
||
move.l a1,usp
|
||
move.l 8(a0),a7 system stack pointer
|
||
move.l 78(a0),d0
|
||
movec d0,vbr
|
||
move.l 82(a0),d0
|
||
movec d0,sfc
|
||
move.l 86(a0),d0
|
||
movec d0,dfc
|
||
movem.l 14(a0),d0-d7/a0-a6 registers
|
||
clr.w -(a7) format word
|
||
move.l pctr,-(a7) set up for rte
|
||
move.w status,-(a7)
|
||
rte
|
||
*
|
||
*
|
||
*****************************************************************
|
||
* *
|
||
* BDOS Call Subroutine -- C Callable *
|
||
* *
|
||
*****************************************************************
|
||
*
|
||
_BDOS: move.w 4(a7),d0
|
||
move.l d1,saved1
|
||
move.l 6(a7),d1
|
||
trap #2
|
||
move.l saved1,d1
|
||
rts
|
||
*
|
||
.bss
|
||
*
|
||
saved1: .ds.l 1
|
||
*
|
||
.text
|
||
*
|
||
*****************************************************************
|
||
* *
|
||
* GETSSP -- supplies system stack pointer to C *
|
||
* *
|
||
*****************************************************************
|
||
*
|
||
_GETSSP: move.w #62,d0
|
||
trap #2
|
||
move.l a7,d0
|
||
andi #$5fff,sr
|
||
rts
|
||
*
|
||
*
|
||
*****************************************************************
|
||
* *
|
||
* Routines for getting control register values from C *
|
||
* *
|
||
*****************************************************************
|
||
*
|
||
*
|
||
_GETVBR: move.w #62,d0
|
||
trap #2
|
||
movec vbr,d0
|
||
andi #$5fff,sr
|
||
rts
|
||
_GETSFC: move.w #62,d0
|
||
trap #2
|
||
movec sfc,d0
|
||
andi #$5fff,sr
|
||
rts
|
||
_GETDFC: move.w #62,d0
|
||
trap #2
|
||
movec dfc,d0
|
||
andi #$5fff,sr
|
||
rts
|
||
*
|
||
*
|
||
*****************************************************************
|
||
* *
|
||
* Exception Vector Setting *
|
||
* *
|
||
* This routine sets all the exception vectors handled by *
|
||
* DDT on behalf of the program being debugged. *
|
||
* *
|
||
*****************************************************************
|
||
*
|
||
*
|
||
_EXINIT:
|
||
Movem.L D0-D7/A0-A5,-(SP) * Save all them registers
|
||
Move.L #EPB,A0 * Initialize Exception Parameter
|
||
Move.W #2,(A0) * .. Block. 1st vector is #2,
|
||
Move.L #IBRVEC,2(A0) * Place to come to on interrupt
|
||
Move.L #OLDVEC,A1 * Make pointer to old vectors
|
||
EXINI1: Move.W #$3D,D0 * Func $3D == Set Exc. Vector
|
||
Move.L A0,D1 * Get address of block
|
||
Trap #2
|
||
|
||
Move.W #22,D0 * get BIOS exception vector call
|
||
Move.W (A0),D1 * Get the vector number
|
||
Move.L #THRTE,D2 * Temporary exception vector handler
|
||
Movem.L A0-A1,-(SP) * Save the address registers
|
||
Trap #3 * Call up the BIOS
|
||
Movem.L (SP)+,A0-A1 * Restore the address registers
|
||
Move.L D0,(A1)+ * Save the old BIOS vector
|
||
Move.L D0,D2 * restore the old vector in the BIOS
|
||
Move.W #22,D0 * The call (see above)
|
||
Move.W (A0),D1 * Das Vectornummer
|
||
Movem.L A0-A1,-(SP) * Take a guess
|
||
Trap #3
|
||
Movem.L (SP)+,A0-A1
|
||
|
||
Add.W #1,(A0) * Increase vector num. to change
|
||
Add.L #6,2(A0) * And set new exception handler
|
||
Cmp.W #12,(A0) * Done yet?
|
||
Bne EXINI1 * Nope, do it again
|
||
Movem.L (SP)+,D0-D7/A0-A5 * Restore all those registers
|
||
Rts
|
||
|
||
EXHANDL:
|
||
move.l #$ff,errflag * indicate error to caller
|
||
Move.L (SP)+,STKVAL * Save RA to IBRVEC
|
||
Move.L SP,ESTKSV * Save old user stack
|
||
Move.L #EXCSTK,SP * And get one of our own
|
||
Movem.L D0-D7/A0-A6,-(SP) * Plenty big enough to save regs
|
||
Move.L STKVAL,D1 * Get the IBRVEC RA again
|
||
Sub.L #IBRVEC+6,D1 * Make it an offset into IBRVEC
|
||
Divu.W #3,D1 * Get (EXV-2) * 2
|
||
And.L #$FFFF,D1 * Clear out the remainder
|
||
Lsl.L #1,D1 * Make it an offset into messages
|
||
|
||
Cmp.W #8,D1 * If Bus Error or Address Error
|
||
Bge EXHAN1
|
||
Add.L #8,ESTKSV * .. Then get rid of garbage
|
||
|
||
EXHAN1: Add.L #EXMSLT,D1 * Now a pointer to message pointer
|
||
Move.L D1,A0
|
||
Move.L (A0),D1 * Now a pointer to the message
|
||
Move.W #9,D0 * Good enough for printing
|
||
Trap #2
|
||
Move.L #ATMES,D1 * Print " at "
|
||
Move.W #9,D0
|
||
Trap #2
|
||
Move.L ESTKSV,A0 * Get exception RA
|
||
Move.L 2(A0),-(SP) * Throw it on the stack
|
||
Jsr _puthexl * And print it out
|
||
Move.L (SP)+,A0 * Clean up the stack
|
||
Move.L #ENDMES,D1 * Print out the <CR><LF>
|
||
Move.W #9,D0
|
||
Trap #2
|
||
Movem.L (SP)+,D0-D7/A0-A6 * Get old register values
|
||
Move.L ESTKSV,SP * And the old stack pointer
|
||
Jmp th1 * And return to DDT
|
||
*
|
||
*
|
||
.data
|
||
*
|
||
* Message Table contains all the exception handler messages
|
||
*
|
||
BUSERR: Dc.B "Bus Error$"
|
||
ADRERR: Dc.B "Address Error$"
|
||
ILLINS: Dc.B "Illegal Instruction$"
|
||
ZERDIV: Dc.B "Divide by Zero$"
|
||
CHKINS: Dc.B "'CHK' Exception$"
|
||
TPVINS: Dc.B "'TRAPV' Exception$"
|
||
PRVERR: Dc.B "Privilege Violation$"
|
||
XTRACE: Dc.B "Trace Exception$"
|
||
LN10EM: Dc.B "Line 1010 Emulator$"
|
||
LN15EM: Dc.B "Line 1111 Emulator$"
|
||
|
||
ATMES: Dc.B " at $"
|
||
ENDMES: Dc.B $0D,$0A,"$"
|
||
|
||
.even
|
||
|
||
OLDVEC: .Ds.L 10 * Old vector addresses
|
||
EXMSLT: .Dc.L BUSERR,ADRERR,ILLINS * Message addresses
|
||
.Dc.L ZERDIV,CHKINS,TPVINS
|
||
.Dc.L PRVERR,XTRACE,LN10EM
|
||
.Dc.L LN15EM
|
||
|
||
.data
|
||
IBRVEC: Jsr EXHANDL * This is where exceptions point
|
||
Jsr EXHANDL * Sole purpose: Put their return
|
||
Jsr EXHANDL * .. address on the stack so that
|
||
Jsr EXHANDL * .. the exception number can be
|
||
Jsr EXHANDL * .. calculated
|
||
Jsr EXHANDL
|
||
Jsr EXHANDL
|
||
Jsr EXHANDL
|
||
Jsr EXHANDL
|
||
Jsr EXHANDL
|
||
|
||
.bss
|
||
*
|
||
ESTKSV: .Ds.L 1 * One LONG for the old user stack
|
||
STKVAL: .Ds.L 1 * Value of pointer from IBRVEC
|
||
.Ds.B 256 * Plenty of room for Exception Stack
|
||
EXCSTK:
|
||
|
||
errflag: .ds.l 1
|
||
asave: .ds.l 2
|
||
bsave: .ds.l 3
|
||
regsave: .ds.l 14
|
||
savessp: .ds.l 1
|
||
saveusp: .ds.l 1
|
||
savea0: .ds.l 1
|
||
savevbr: .ds.l 1
|
||
savesfc: .ds.l 1
|
||
savedfc: .ds.l 1
|
||
iltv = $4 illegal instruction vector number
|
||
trv = $9 trace exception vector number
|
||
*
|
||
savev: .ds.l 1
|
||
thvnum: .ds.w 1
|
||
*
|
||
setexp = 61
|
||
setsup = 62
|
||
*
|
||
pctr: .ds.l 1
|
||
status: .ds.w 1
|
||
*
|
||
*
|
||
|
||
EPB:
|
||
vnum: .ds.w 1
|
||
newv: .ds.l 1
|
||
oldv: .ds.l 1
|
||
*
|
||
setexv=61
|
||
linef=11
|
||
buserr=2
|
||
*
|
||
*
|
||
.end
|
||
|