**************************************************************************** **************************************************************************** ** ** Platinum (Lowel-level initialization and crash handling) ** ** This software is in the public domain. There is no warranty. ** ** by Patrick Davidson (pad@calc.org, http://pad.calc.org/) ** ** Last updated August 3, 2001 ** **************************************************************************** **************************************************************************** ;_enablebreak set 1 ; Uncommented -> ON key breaks _main: movem.l d0-a6,-(sp) lea (LCD_MEM).w,a0 move.l #959,d0 lbd: move.l (a0)+,-(sp) dbra d0,lbd bclr #2,$600001 ; Unprotect low memory move.l ($64).w,originalint1 move.l ($74).w,originalint5 IFD _enablebreak move.l ($78).w,originalint6 move.l #break_handler,($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 move.l sp,originalsp ; Save stack pointer bsr start_program _exit: move.l originalsp(pc),sp bclr #2,$600001 ; Unprotect low memory bsr restore move.w #$b2,$600016 ; Set Int5 frequency to 30Hz move.l originalint1(pc),($64).w move.l originalint5(pc),($74).w IFD _enablebreak move.l originalint6(pc),($78).w ENDIF lea ($30).w,a1 ; Uninstall crash handler moveq #9,d0 loop_uninstall: move.l (sp)+,-(a1) dbra d0,loop_uninstall lea (LCD_MEM+3840).w,a0 move.l #959,d0 \lrd: move.l (sp)+,-(a0) dbra d0,\lrd bset #2,$600001 ; Unprotect low memory moveq #0,d0 ; Re-activate interrupts trap #1 move.w Timer_Delay+6(pc),d2 cmp.w #12,d2 beq.s \done move.w #$cc,$600016 \done: movem.l (sp)+,d0-a6 rts originalint1: dc.l 0 originalint5: dc.l 0 originalint6: dc.l 0 originalsp: dc.l 0 ******************************************* RESTORE IMPORTANT VARIABLES restore: move.w #$980,$600010 JMP_ROM PortRestore ******************************************* 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: move.b d0,$60001a rte 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 bsr restore 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 pea (1).w ; Set text to normal move.l ($c8).w,a0 add.w #FontSetSys*4,a0 move.l (a0),a0 jsr (a0) addq.l #2,sp 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) 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