.segment "ZEROPAGE"

SPR_X:					.res 2
SPR_Y:					.res 2
SPR_XOFF:				.res 2
SPR_YOFF:				.res 2
SPR_PAL:				.res 1
SPR_PTR:				.res 2



.importzp _upd_off,_oam_off,_oam_step

.segment "FIXED"

;void __fastcall__ ovl_call(unsigned char prg,void (*func)(void));

.export _ovl_call

_ovl_call:

	sta <TEMP+1
	stx <TEMP+2
	
	lda #$4c			;JMP
	sta <TEMP+0
	
	jsr popa
	jsr mmc3_set_prg

	jsr TEMP

	lda #PRG_MAIN
	jmp mmc3_set_prg	;jsr:rts

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

;void __fastcall__ oam_clear_fast(void);

.export _oam_clear_fast

_oam_clear_fast:

	lda #240

	.repeat 64,I
	sta OAM_BUF+I*4
	.endrepeat

	rts

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

;void __fastcall__ oam_meta_clip_y(int sx,int sy,unsigned char pal,const unsigned char *meta);

.export _oam_meta_clip_y

_oam_meta_clip_y:

	sta <SPR_PTR+0			;pointer
	stx <SPR_PTR+1

	jsr popa			;pal
	sta <SPR_PAL

	jsr popax			;sy

	sta <SPR_Y+0
	stx <SPR_Y+1

	jsr popax			;sx

	sta <SPR_X+0

	ldx <_oam_off
	ldy #0

@loop:

	lda (SPR_PTR),y			;x
	cmp #128
	beq @done
	iny

	clc
	adc <SPR_X+0
	sta <SPR_XOFF+0

	lda <SPR_Y+0
	clc
	adc (SPR_PTR),y			;y
	sta <SPR_YOFF+0

	lda (SPR_PTR),y
	iny

	ora #$7f
	bmi :+
	lda #0
:

	adc <SPR_Y+1
	bne @skip

	lda <SPR_YOFF+0
	sta OAM_BUF+0,x

	lda <SPR_XOFF+0
	sta OAM_BUF+3,x

	lda (SPR_PTR),y			;tile
	iny

	sta OAM_BUF+1,x

	lda (SPR_PTR),y			;attr
	ora <SPR_PAL
	iny

	sta OAM_BUF+2,x

	txa
	clc
	adc <_oam_step
	tax

	jmp @loop

@skip:

	iny
	iny
	jmp @loop

@done:

	stx <_oam_off

	rts

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

;can also be called through _asm version, parameters passed through zeropage
;SPR_PTR=pointer word, SPR_PAL=palette byte, SPR_Y=sy byte, SPR_X=sx word

;void __fastcall__ oam_meta_clip_x(int sx,int sy,unsigned char pal,const unsigned char *meta);

.export _oam_meta_clip_x

_oam_meta_clip_x:

	sta <SPR_PTR+0		;pointer
	stx <SPR_PTR+1

	jsr popa		;pal
	sta <SPR_PAL

	jsr popax		;sy

	sta <SPR_Y+0

	jsr popax		;sx

	sta <SPR_X+0
	stx <SPR_X+1

oam_meta_clip_x_asm:

	ldx <_oam_off
	ldy #0

@loop:

	lda (SPR_PTR),y		;x
	cmp #128
	beq @done
	iny

	sta <SPR_XOFF+0
	clc
	adc <SPR_X+0
	sta <SPR_XOFF+1

	lda <SPR_XOFF+0
	ora #$7f
	bmi :+
	lda #0
:

	adc <SPR_X+1
	bne @skip

	lda <SPR_XOFF+1
	sta OAM_BUF+3,x

	lda (SPR_PTR),y		;y
	iny

	clc
	adc <SPR_Y+0
	sta OAM_BUF+0,x

	lda (SPR_PTR),y		;tile
	iny

	sta OAM_BUF+1,x

	lda (SPR_PTR),y		;attr
	ora <SPR_PAL
	iny

	sta OAM_BUF+2,x

	txa
	clc
	adc <_oam_step
	tax

	jmp @loop

@skip:

	iny
	iny
	iny
	jmp @loop

@done:

	stx <_oam_off

	rts
	
;------------------------------------------------------------------------------	
	
timing_delay:

;;;;;;;;;;;;;;;;;;;;;;;;
; Delays A clocks + overhead
; Clobbers A. Preserves X,Y.
; Time: A+25 clocks (including JSR)
;;;;;;;;;;;;;;;;;;;;;;;;
                  ;       Cycles              Accumulator         Carry flag
                  ; 0  1  2  3  4  5  6          (hex)           0 1 2 3 4 5 6
                  ;
                  ; 6  6  6  6  6  6  6   00 01 02 03 04 05 06
:      sbc #7     ; carry set by CMP
delay_a_25_clocks:
       cmp #7     ; 2  2  2  2  2  2  2   00 01 02 03 04 05 06   0 0 0 0 0 0 0
       bcs :-     ; 2  2  2  2  2  2  2   00 01 02 03 04 05 06   0 0 0 0 0 0 0
       lsr        ; 2  2  2  2  2  2  2   00 00 01 01 02 02 03   0 1 0 1 0 1 0
       bcs *+2    ; 2  3  2  3  2  3  2   00 00 01 01 02 02 03   0 1 0 1 0 1 0
       beq :+     ; 3  3  2  2  2  2  2   00 00 01 01 02 02 03   0 1 0 1 0 1 0
       lsr        ;       2  2  2  2  2         00 00 01 01 01       1 1 0 0 1
       beq @rts   ;       3  3  2  2  2         00 00 01 01 01       1 1 0 0 1
       bcc @rts   ;             3  3  2               01 01 01           0 0 1
:      bne @rts   ; 2  2              3   00 00             01   0 1         0
@rts:  rts        ; 6  6  6  6  6  6  6   00 00 00 00 01 01 01   0 1 1 1 0 0 1
; Total cycles:    25 26 27 28 29 30 31

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

;void __fastcall__ dungeon_copy_frame(unsigned char prg,unsigned int off);

.export _dungeon_copy_frame

_dungeon_copy_frame:

	sta <PTR+0
	txa
	clc
	adc #$80
	sta <PTR+1
	
	jsr popa
	
	jsr mmc3_set_prg_temp
	
	ldy #0
:
	lda (PTR),y
	sta _update_list,y
	iny
	cpy #252
	bne :-
	
	lda <PTR+0
	clc
	adc #252
	sta <PTR+0
	bcc :+
	inc <PTR+1
:
	ldy #0
:
	lda (PTR),y
	sta _split_list,y
	iny
	cpy #252
	bne :-
	
	jmp mmc3_restore_prg	;jsr:rts