;; #LAYOUT# STD *        #TAKE
;; #LAYOUT# *   KERNAL_0 #TAKE
;; #LAYOUT# *   *        #IGNORE


hw_entry_irq:

	; The IRQ is a commonly messed with thing on the C64,
	; so we need to handle entry points that are commonly
	; relied upon, including:
	; $EA31 - Standard IRQ routine
	; $EA61 - Check keyboard, but do not update timer? https://github.com/cc65/cc65/issues/324
	; $EA81 - https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb
	; Also the $0314 vector is widely used (e.g., https://www.lemon64.com/forum/viewtopic.php?t=2112&sid=6ea01982b26da69783120a7923ca46fb)

	; Save registers, sequence according to Computes Mapping the Commodore 64, page 73
	pha
	+phx_trash_a
	+phy_trash_a

!ifndef HAS_OPCODES_65CE02 { !ifdef CONFIG_BCD_SAFE_INTERRUPTS {

	cld                      ; clear decimal flag to allow using it without disabling interrupts
} }

	; Check if caused by BRK
	tsx
	lda $0104, x ; get the pre-interrupt processor state
	and #$10
	bne irq_handler_brk

	; Not caused by BRK - call interrupt routine (only if initialised)
	; Routine on zeropage = assuming not initialized
	lda CINV+1
	beq @1
	jmp (CINV)
@1:
	; Vector not initialized - call default interrupt routine
	jmp default_irq_handler

irq_handler_brk:

	; Store BRK adddress, to be displayed
	sec
	lda $0105, x
	sbc #$02
	sta CMP0+0
	lda $0106, x
	sbc #$00
	sta CMP0+1

	; Interrupt caused by BRK
	jmp (CBINV)
