SCREEN_HEIGHT   = 200
 SCREEN_WIDTH    = 320
 
-;----------------------------------------------------------------------------
-; data segment
-
-.data
-
-chainIRQ:
-        .byte   $4c                     ; JMP opcode
-        .word   0                       ; pointer to ROM IRQ handler (will be set at runtime)
-
 ;----------------------------------------------------------------------------
 ; Global variables. The bounding box values are sorted so that they can be
 ; written with the least effort in the SETBOX and GETBOX routines, so don't
 
 old_key_count:  .res    1
 
+; original IRQ vector
+
+old_irq:        .res    2
+
 .rodata
 
 ; Default values for above variables
 
 ; Initialize our IRQ magic
 
-        lda     IRQInd+1
-        sta     chainIRQ+1
+        ; remember ROM IRQ continuation address
         lda     IRQInd+2
-        sta     chainIRQ+2
+        sta     old_irq+1
+        lda     IRQInd+1
+        sta     old_irq
+
         lda     libref
         sta     ptr3
         lda     libref+1
         sta     ptr3+1
+
+        ; set ROM IRQ continuation address to point to the provided routine
         ldy     #2
         lda     (ptr3),y
         sta     IRQInd+1
         iny
         lda     (ptr3),y
         sta     IRQInd+2
+
+        ; set address of our IRQ callback routine
+        ; since it's called via "rts" we have to use "address-1"
         iny
         lda     #<(callback-1)
         sta     (ptr3),y
         lda     #>(callback-1)
         sta     (ptr3),y
         iny
-        lda     #<(chainIRQ-1)
+
+        ; set ROM entry point vector
+        ; since it's called via "rts" we have to decrement it by one
+        lda     old_irq
+        sec
+        sbc     #1
         sta     (ptr3),y
         iny
-        lda     #>(chainIRQ-1)
+        lda     old_irq+1
+        sbc     #0
         sta     (ptr3),y
         cli
 
 ; No return code required (the driver is removed from memory on return).
 
 UNINSTALL:
-        lda     chainIRQ+1
+        lda     old_irq
         sei
         sta     IRQInd+1
-        lda     chainIRQ+2
+        lda     old_irq+1
         sta     IRQInd+2
         cli
 
 
         FIRE    = $10
 .endenum
 
-;----------------------------------------------------------------------------
-; data segment
-
-.data
-
-chainIRQ:
-        .byte   $4c                     ; JMP opcode
-        .word   0                       ; pointer to ROM IRQ handler (will be set at runtime)
-
 ;----------------------------------------------------------------------------
 ; Global variables. The bounding box values are sorted so that they can be
 ; written with the least effort in the SETBOX and GETBOX routines, so don't
 
 old_key_count:  .res    1
 
+; original IRQ vector
+
+old_irq:        .res    2
+
 .rodata
 
 ; Default values for above variables
 
 ; Initialize our IRQ magic
 
-        lda     IRQInd+1
-        sta     chainIRQ+1
+        ; remember ROM IRQ continuation address
         lda     IRQInd+2
-        sta     chainIRQ+2
+        sta     old_irq+1
+        lda     IRQInd+1
+        sta     old_irq
+
         lda     libref
         sta     ptr3
         lda     libref+1
         sta     ptr3+1
+
+        ; set ROM IRQ continuation address to point to the provided routine
         ldy     #2
         lda     (ptr3),y
         sta     IRQInd+1
         iny
         lda     (ptr3),y
         sta     IRQInd+2
+
+        ; set address of our IRQ callback routine
+        ; since it's called via "rts" we have to use "address-1"
         iny
         lda     #<(callback-1)
         sta     (ptr3),y
         lda     #>(callback-1)
         sta     (ptr3),y
         iny
-        lda     #<(chainIRQ-1)
+
+        ; set ROM entry point vector
+        ; since it's called via "rts" we have to decrement it by one
+        lda     old_irq
+        sec
+        sbc     #1
         sta     (ptr3),y
         iny
-        lda     #>(chainIRQ-1)
+        lda     old_irq+1
+        sbc     #0
         sta     (ptr3),y
         cli
 
 ; No return code required (the driver is removed from memory on return).
 
 UNINSTALL:
-        lda     chainIRQ+1
+        lda     old_irq
         sei
         sta     IRQInd+1
-        lda     chainIRQ+2
+        lda     old_irq+1
         sta     IRQInd+2
         cli
 
 
         .addr   IRQStub2
 callback:                       ; callback into mouse driver after ROM IRQ handler has been run
         .addr   $0000           ; (filled in by mouse driver)
-jmp_rom_hdlr:                   ; "trampoline" to jump to ROM IRQ handler
+jmp_rom_hdlr:                   ; original ROM indirect IRQ handler address
         .addr   $0000           ; (filled in by mouse driver)
 
 
         lda     #MMU_CFG_CC65   ; MMU configuration which will be active after the ROM handler returns
         pha
 
+        ; map out ROM
+        ldy     MMU_CR
+        sta     MMU_CR
+
         ; push address of ROM handler on stack and jump to it
         lda     jmp_rom_hdlr+1
         pha
         lda     jmp_rom_hdlr
         pha
+
+        sty     MMU_CR          ; map in ROM
         rts                     ; jump to ROM handler
 
         ; our MMU configuration byte we pushed on the stack before (MMU_CFG_CC65) is now active