changeset 15:686b600a62ee

Add safety FIRQ handler and initialize other interrupt vectors Make sure if FIRQ occurs, or if IRQ or FIRQ happens from a GIME source on the Coco3, that the interrupt controller state is cleared. Additionally, actually disable the PIA FIRQ interrupt sources if an FIRQ occurs. This isn't enough to completely prevent freezing the system due to improper interrupt controller configuration, but it does make it significantly less likely.
author William Astle <lost@l-w.ca>
date Sun, 06 Nov 2022 14:57:32 -0700
parents 2ec8c5ea5ed2
children d5ae140d19d4
files src/lwbasic.s
diffstat 1 files changed, 32 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lwbasic.s	Sun Nov 06 13:48:11 2022 -0700
+++ b/src/lwbasic.s	Sun Nov 06 14:57:32 2022 -0700
@@ -403,10 +403,17 @@
                 stx RSTVEC
                 lda #0x55                       ; activate warm start handler
                 sta RSTFLG
+                ldd #0x7e3b                     ; opcodes for JMP extended and RTI
                 ldx #irqhandler                 ; enable IRQ handler with a JMP at the vector
-                lda #0x7e
-                sta IRQVEC                      ; set JMP instruction
-                stx IRQVEC+1                    ; set address
+                sta IRQVEC
+                stx IRQVEC+1
+                sta FRQVEC                      ; initialize FIRQ handler with JMP
+                ldx #firqhandler
+                stx FRQVEC+1
+                stb NMIVEC                      ; initialize NMI to RTI
+                stb SW3VEC                      ; initialize SWI3 to RTI
+                stb SW2VEC                      ; initialize SWI2 to RTI
+                stb SWIVEC                      ; initialize SWI to RTI
                 ldx #greeting                   ; display greeting
                 jsr console_outstr
                 bra warmstartb                  ; finish up initialization
@@ -440,11 +447,33 @@
 irqhandler      lda PIA0.CB                     ; was it VSYNC?
                 bmi irqhandler0                 ; brif so
                 lda PIA0.DA                     ; clear HSYNC flag so we don't get stuck if it gets enabled
+                ifdef COCO3
+                lda GIME.IRQ                    ; clear GIME IRQ state flags
+                endc
                 rti
 irqhandler0     lda PIA0.DB                     ; clear VSYNC flag
                 bsr keyb_read                   ; go handle the keyboard
                 rti
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; FIRQ handler
+;
+; This handler is present to prevent accidentally enabling the interrupt and thus hanging to system. It may seem to be
+; a waste of code space, but consider it a self defense situation.
+firqhandler     pshs a                          ; need a scratch register
+                ifdef COCO3
+                lda GIME.FIRQ                   ; clear GIME FIRQ state flags
+                endc
+                lda PIA1.DA                     ; clear interrupt flags
+                lda PIA1.DB
+                lda PIA1.CA                     ; disable interrupts to prevent system hang
+                anda #0xfe
+                sta PIA1.CA
+                lda PIA1.CB
+                anda #0xfe
+                sta PIA1.CB
+                puls a                          ; restore register
+                rti
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Console keyboard input driver
 ;
 ; Reset the keyboard state, which means clearing the buffer and state flags