***************************************************************** * * * Usual filename: BDOS00.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 68000, not the 68010. * * * * initiate program execution * * * ***************************************************************** * .globl _GO .globl _STEP .globl _BDOS .globl _GETSSP .globl _EXINIT .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 movem.l 14(a0),d0-d7/a0-a6 set up other registers 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 Move.W #62,D0 Back into supervisor mode Trap #2 By using the BDOS call movem.l bsave,d0-d1 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 th2: move.l a7,savessp 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.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 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 movem.l 14(a0),d0-d7/a0-a6 registers 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 * * ***************************************************************** * * * 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 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 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  .end