.import _split_list

.segment "ZEROPAGE"

NMI_CALL:				.res 3

.segment "FIXED"

nmi_handlers_list:

	.word nmi_empty							;0
	.word nmi_normal						;1
	.word nmi_title							;2
	.word nmi_vid_dmc						;2
	
	

;------------------------------------------------------------------------------

;void __fastcall__ set_nmi_handler(unsigned char id);

.export _set_nmi_handler

_set_nmi_handler:

	asl a
	tax
	lda nmi_handlers_list+0,x
	ldy nmi_handlers_list+1,x
	ldx #$40					;RTI
	stx <NMI_CALL+0
	sta <NMI_CALL+1
	sty <NMI_CALL+2
	lda #$4c					;JMP
	sta <NMI_CALL+0

	rts

	

;------------------------------------------------------------------------------

nmi_empty:

	inc <FRAME_CNT1
	rti
	
	
;------------------------------------------------------------------------------

nmi_normal:

	sta MMC3_IRQ_DISABLE
	
	pha
	txa
	pha
	tya
	pha

	lda <PPU_MASK_VAR	;if rendering is disabled, do not access the VRAM at all
	and #%00011000
	bne @doUpdate
	jmp	@skipAll

@doUpdate:

	lda <OAM_UPDATE
	beq @skipOAM
	dec <OAM_UPDATE

	lda #>OAM_BUF
	sta PPU_OAM_DMA

@skipOAM:

	lda <PAL_UPDATE			;update palette if needed
	bne @updPal
	jmp @updVRAM

@updPal:

	ldx #0
	stx <PAL_UPDATE

	lda #$3f
	sta PPU_ADDR
	stx PPU_ADDR			;X has to be zero

	.repeat 4,I
	ldy PAL_BUF+I
	lda (PAL_BG_PTR),y
	sta PPU_DATA
	.endrepeat

	ldy PAL_BUF
	lda (PAL_BG_PTR),y
	tax
	
	.repeat 3,J
	stx PPU_DATA
	.repeat 3,I
	ldy PAL_BUF+5+(J*4)+I
	lda (PAL_BG_PTR),y
	sta PPU_DATA
	.endrepeat
	.endrepeat

	.repeat 4,J
	stx PPU_DATA
	.repeat 3,I
	ldy PAL_BUF+17+(J*4)+I
	lda (PAL_SPR_PTR),y
	sta PPU_DATA
	.endrepeat
	.endrepeat
	

@updVRAM:

	lda <NAME_UPD_ENABLE
	beq @skipUpd
	
	jsr _flush_vram_update_nmi
	
	lda #0
	sta <NAME_UPD_ENABLE

@skipUpd:

	lda #0
	sta PPU_ADDR
	sta PPU_ADDR

	lda <SCROLL_X
	sta PPU_SCROLL
	lda <SCROLL_Y
	sta PPU_SCROLL

	lda <PPU_CTRL_VAR
	sta PPU_CTRL

@skipAll:

	ldx <IRQ_START_LINE
	beq :+
	stx MMC3_IRQ_DISABLE	;any value to disable
	stx MMC3_IRQ_LATCH		;line number
	stx MMC3_IRQ_RELOAD		;line number
	stx MMC3_IRQ_DISABLE
	stx MMC3_IRQ_ENABLE	
:

	;set CHR

	ldx #0					;first 4K
	lda <MMC3_CHR_SLOTS+0
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+1
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+2
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+3
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+4
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+5
	stx MMC3_CTRL
	sta MMC3_DATA

	lda <MMC3_CTRL_VAR
	sta MMC3_CTRL

	lda <PPU_MASK_VAR
	sta <PPU_MASK_VAR1
	sta PPU_MASK
	
	jsr IRQ_INIT

	inc <FRAME_CNT1

	jsr playdump_update
	
	pla
	tay
	pla
	tax
	pla

    rti

;------------------------------------------------------------------------------

nmi_title:

	sta MMC3_IRQ_DISABLE
	
	pha
	txa
	pha
	tya
	pha

	lda <PPU_MASK_VAR	;if rendering is disabled, do not access the VRAM at all
	and #%00011000
	bne @doUpdate
	jmp	@skipAll

@doUpdate:

	lda #>OAM_BUF
	sta PPU_OAM_DMA
	lda <PAL_UPDATE			;update palette if needed
	bne @updPal
	jmp @updVRAM

@updPal:

	ldx #0
	stx <PAL_UPDATE

	lda #$3f
	sta PPU_ADDR
	stx PPU_ADDR			;X has to be zero

	.repeat 4,I
	lda PAL_BUF+I
	sta PPU_DATA
	.endrepeat

	ldx PAL_BUF
	
	.repeat 3,J
	stx PPU_DATA
	.repeat 3,I
	lda PAL_BUF+5+(J*4)+I
	sta PPU_DATA
	.endrepeat
	.endrepeat

	.repeat 4,J
	stx PPU_DATA
	.repeat 3,I
	lda PAL_BUF+17+(J*4)+I
	sta PPU_DATA
	.endrepeat
	.endrepeat
	

@updVRAM:

	lda <NAME_UPD_ENABLE
	beq @skipUpd
	
	jsr _flush_vram_update_nmi_title
	
	lda #0
	sta <NAME_UPD_ENABLE

@skipUpd:

	lda #0
	sta PPU_ADDR
	sta PPU_ADDR

	lda <SCROLL_X
	sta PPU_SCROLL
	lda <SCROLL_Y
	sta PPU_SCROLL

	lda <PPU_CTRL_VAR
	sta PPU_CTRL

@skipAll:

	ldx <IRQ_START_LINE
	beq :+
	stx MMC3_IRQ_DISABLE	;any value to disable
	stx MMC3_IRQ_LATCH		;line number
	stx MMC3_IRQ_RELOAD		;line number
	stx MMC3_IRQ_DISABLE
	stx MMC3_IRQ_ENABLE	
:

	;set CHR

	ldx #0					;first 4K
	lda <MMC3_CHR_SLOTS+0
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+1
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+2
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+3
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+4
	stx MMC3_CTRL
	sta MMC3_DATA
	inx
	lda <MMC3_CHR_SLOTS+5
	stx MMC3_CTRL
	sta MMC3_DATA

	lda <MMC3_CTRL_VAR
	sta MMC3_CTRL

	lda <PPU_MASK_VAR
	sta <PPU_MASK_VAR1
	sta PPU_MASK
	
	jsr IRQ_INIT

	inc <FRAME_CNT1

	jsr playdump_update
	
	pla
	tay
	pla
	tax
	pla

    rti
	
;------------------------------------------------------------------------------

nmi_vid_dmc:
	
	pha
	txa
	pha

	;set CHR

	ldx #2					;second 4K
	lda <MMC3_CHR_SLOTS+2
	stx MMC3_CTRL
	sta MMC3_DATA
	eor #2
	sta <MMC3_CHR_SLOTS+2
	inx
	lda <MMC3_CHR_SLOTS+3
	stx MMC3_CTRL
	sta MMC3_DATA
	eor #2
	sta <MMC3_CHR_SLOTS+3

	lda <MMC3_CTRL_VAR
	sta MMC3_CTRL

	inc <FRAME_CNT1

	lda <PPU_MASK_VAR
	sta <PPU_MASK_VAR1
	sta PPU_MASK
	
	pla
	tax
	pla

    rti
