**************************************************************************** **************************************************************************** ** ** Phoenix (Lowel-level initialization and crash handling) ** ** Copyright 2004 by Patrick Davidson. This software may be freely ** modified and/or copied with no restrictions. There is no warranty. ** ** by Patrick Davidson (pad@calc.org, http://pad.calc.org/) ** ** Last updated September 14, 2004 ** **************************************************************************** **************************************************************************** ;_enablebreak set 1 ; Uncommented -> ON key breaks _main: IFD _nostub ; Backup data (nostub only) movem.l d0-a6,-(sp) lea LCD_MEM,a0 move.l #959,d0 lbd: move.l (a0)+,-(sp) dbra d0,lbd ENDIF bclr #2,$600001 ; Unprotect low memory move.l ($74).w,-(sp) ; Save interrupt 5 IFD _enablebreak move.l ($78).w,-(sp) lea break_handler(pc),a0 move.l a0,($78).w ENDIF lea crash_handler(pc),a0 ; Install crash handler moveq #9,d0 lea ($8).w,a1 loop_install: move.l (a1),-(sp) ; Push old handler on stack move.l a0,(a1)+ ; Install new one addq.l #6,a0 dbra d0,loop_install lea originalsp(pc),a0 move.l sp,(a0) ; Save stack pointer bsr _program _exit: move.l originalsp(pc),sp lea ($30).w,a1 ; Uninstall crash handler moveq #9,d0 loop_uninstall: move.l (sp)+,-(a1) dbra d0,loop_uninstall IFD _enablebreak move.l (sp)+,($78).w ENDIF move.l (sp)+,($74).w ; Restore interrupt 5 moveq #0,d0 ; Re-activate interrupts trap #1 IFD _nostub ; Restore data (nostub only) lea LCD_MEM+3840,a0 move.l #959,d0 lrd: move.l (sp)+,-(a0) dbra d0,lrd movem.l (sp)+,d0-a6 ENDIF bset #2,$600001 ; Unprotect low memory move.b #$b2,d0 bra Set_Speed originalsp: dc.l 0 ******************************************* CRASH HANDLING ROUTINES * * Register allocations throughout most of handler: * * A7 -> temporary stack (at end of LCD_MEM) * A5 -> position of SR in exception stack frame * D7 = exception number * A3 -> temporary buffer for sprintf * * Original registers kept at LCD_MEM+3746 to LCD_MEM+3809 * ******** IFD _enablebreak break_handler: pea ($1e).w bra.s crash_handler_main ENDIF crash_handler: ; Crash handlers pea (2).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (3).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (4).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (5).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (6).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (7).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (8).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (9).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (10).w ; Store exception number bra.s crash_handler_main ; Go to main handler pea (11).w ; Store exception number crash_handler_main: move.w #$2700,sr ; Stop interrupts move.l a7,LCD_MEM+3806 ; Save exception stack pointer lea LCD_MEM+3806,a7 ; Switch to temporary stack movem.l d0-a6,-(sp) ; Save registers at crash move.l LCD_MEM+3806,a5 ; A5 -> exception stack frame move.l (a5)+,d7 ; D7 = exception number cmp.w #3,d7 bgt.s not_long_frame addq.l #8,a5 not_long_frame: ; A5 -> SR on stack frame lea (LCD_MEM),a0 ; Clear the screen move.w #929,d0 lcc: clr.l (a0)+ dbra d0,lcc moveq #1,d0 ; Set text to normal bsr Set_Font lea LCD_MEM+3810,a3 ;Temporary buffer for sprintf move.l 2(a5),-(sp) ;Display error#, PC move.w d7,-(sp) pea firsterrortext(pc) pea (a3) bsr ____sprintf lea (a3),a0 moveq #1,d0 moveq #1,d1 bsr _Display_String pea _main(pc) ;Display prog start, SR move.w (a5),-(sp) pea seconderrortext(pc) pea (a3) bsr ____sprintf lea 28(sp),sp lea (a3),a0 moveq #9,d0 moveq #1,d1 bsr Display_String moveq #91,d0 ;"Press ON to exit" moveq #1,d1 lea thirderrortext(pc),a0 bsr _Display_String lea LCD_MEM+3746,a6 moveq #0,d7 ;D7 = n moveq #18,d6 ;D6 = line loopshowregs: move.l 32(a6),-(sp) ;An move.w d7,-(sp) move.l (a6)+,-(sp) ;Dn move.w d7,-(sp) pea reglisttext(pc) pea (a3) bsr ____sprintf lea 20(sp),sp lea (a3),a0 move.w d6,d0 moveq #1,d1 bsr _Display_String addq.w #8,d6 ;Next row addq.w #1,d7 cmp.w #7,d7 bne.s loopshowregs move.w (a6),-(sp) pea d7text(pc) pea (a3) bsr ____sprintf lea (a3),a0 moveq #74,d0 moveq #1,d1 bsr _Display_String move.l usp,a2 lea 12(a2),a2 move.l -(a2),-(sp) move.l -(a2),-(sp) move.l -(a2),-(sp) pea stacktext(pc) pea (a3) bsr ____sprintf lea (a3),a0 moveq #82,d0 moveq #1,d1 bsr _Display_String IFD _enablebreak wait_off: btst #1,$60001a beq.s wait_off ENDIF wait_on: btst #1,$60001a bne.s wait_on move.l a5,a7 ; A7 -> position of SR in crash stack move.w #$700,(sp) ; Set SR to user mode, no interrupts lea _exit(pc),a0 ; Set return address to exit code move.l a0,2(sp) rte ; Return (to exit code) _Display_String: ; Display (A0) at (D1,D0) move.w #4,-(sp) pea (a0) move.w d0,-(sp) move.w d1,-(sp) IFND _nostub jsr tios::DrawStrXY ENDIF IFD _nostub move.l ($c8).w,a0 add.l #$1a9*4,a0 move.l (a0),a0 jsr (a0) ENDIF lea 10(sp),sp rts firsterrortext: dc.b 'Exception %02x at %08lx',0 seconderrortext: dc.b 'SR=%04x _main=%08lx',0 thirderrortext: dc.b 'Press [ON] to exit',0 reglisttext: dc.b 'D%d=%08lx A%d=%08lx',0 d7text: dc.b 'D7=%08lx Stack:',0 stacktext: dc.b '%08lx%08lx%08lx',0 EVEN _program: