68k exception handling

From NeoGeo Development Wiki
Jump to navigation Jump to search
The Universe BIOS provides some exception handling.

A 68k program may produce exceptions, often caused by bugs. For debugging, an exception handler can be of great use.

Some games were published with their exception handler, while some others just reset the system.

Generic exception handler

Allocate a longword variable called "PCERROR". Make the appropriate vectors point to the related routines below.

Divide by zero/Illegal instruction

Cause: See 68k vector table.

6 bytes stack frame: 0:SR.w, 2:PC.l

ErrDivZero:
    move.l  2(a7),PCERROR       ; Store PC from stack frame
    movem.l d0-d7/a0-a6,-(a7)   ; Store registers
    lea     ERR_DIVZERO,a0
    jmp     DispErr

Address error/Bus error

Cause: See 68k vector table.

14 bytes stack frame: 0:R/W.w, 2:Access address.l, 6:Instruction.l, 8:SR.w, 10:PC.l

ErrAddr:
    move.l  10(a7),PCERROR      ; Store PC from stack frame
    movem.l d0-d7/a0-a6,-(a7)   ; Store registers
    lea     ERR_ADDR,a0
    jmp     DispErr

Display for debug

Exception screen showing the PC where it was raised: Always better than a quiet reset !

Don't forget to mask out all interrupts as soon as an exception is raised:

    ori.w   #$0700,sr

All register values can be retrieved from the previous MOVEMs and displayed on the fix layer:

;D0: 32bit value to display
;VRAM address needs to be set before call
Write32bit:
    move.w  #32,VRAM_MOD   ; Write char-by-char
    move.b  #8,d7
.writerlp:
    move.b  d0,REG_DIPSW   ; Kick watchdog
    rol.l   #4,d0          ; BCDEFGHA
    move.b  d0,d1
    andi.w  #$F,d1         ; xxxx000A
    jsr     .hexshift
    add.w   #ASCIISTART,d1
    ori.w   #$F000,d1      ; Palette $F
    move.w  d1,VRAM_RW
    subq.b  #1,d7
    bne     .writerlp
    rts

.hexshift:
    cmp.b   #10,d1
    blt.b   .r
    addq.b  #7,d1
.r:
    rts

Don't forget to set up a palette.