.text
#include "memmap.i65"
.byt "===HIPRINT==="
; input:
; print_count
; print_x
; print_y
; print_src
; print_bank
; print_pal
;
; output:
; print_done (# of chars printed)
; print_over (char after print_count)

hiprint:
	php
	sep #$20 : .as
	rep #$10 : .xl
	ldx print_src
	stx print_ptr
	lda print_bank
	sta print_ptr+2
	phb
	lda #$7e
	pha
	plb
	rep #$30 : .al : .xl
	lda print_pal
	and #$00ff
	xba
	asl
	asl
	ora #$2000
	sta print_temp
	lda print_count
	and #$00ff
	beq hiprint_end
	tay
	lda print_x
	and #$00ff
	sta print_x
	lda print_y
	and #$00ff
	asl
	asl
	asl
	asl
	asl
	asl
	clc
	adc print_x
	and #$fffe
	tax
	lda print_x
	lsr
	bcs hiprint_bg1
hiprint_bg2
	lda [print_ptr]
	and #$00ff
	beq hiprint_end
	inc print_ptr
	asl
	ora print_temp
	sta !BG2_TILE_BUF, x
	dey
	beq hiprint_end
hiprint_bg1
	lda [print_ptr]
	and #$00ff
	beq hiprint_end
	inc print_ptr
	asl
	ora print_temp
	sta !BG1_TILE_BUF, x
	inx
	inx
	dey
	beq hiprint_end
	bra hiprint_bg2
hiprint_end
	plb
	sep #$20 : .as
	lda [print_ptr]
	sta print_over
	tya
	sec
	sbc print_count
	eor #$ff
	inc
	sta print_done
	plp
	rts


loprint:
	rep #$30 : .xl : .al
	lda !print_x
	and #$00ff
	asl ;double the offset for WRAM addressing
	clc
	adc #!BG2_TILE_BUF
	sta !print_temp
	lda !print_y
	and #$00ff
	asl
	asl
	asl
	asl
	asl
	asl ;double the offset for WRAM addressing
	clc
	adc !print_temp
; we need to transfer to WRAM and from there to VRAM via DMA during VBLANK
; because VRAM can only be accessed during VBLANK and forced blanking.
	sta $2181
	sep #$20 : .as
	lda #$7f ;we really only need bit 0. full bank given for clarity
	sta $2183
	ldx !print_src
	lda !print_bank
	pha
	plb
loprint_loop_inner
	lda !0,x
	beq loprint_end
	sta @$2180
	lda #$00
	adc #$00
	ora #$20
	sta @$2180
	inx
	bra loprint_loop_inner
loprint_end
	lda #$00
	pha
	plb
	rts

backup_screen:
; MVN: X=source, Y=dest, A=count
;      imm1=srcbk, imm2=dstbk
	phb
	php
	rep #$30 : .xl : .al
	ldx #!BG1_TILE_BUF+64*9
	ldy #!BG1_TILE_BAK+64*9
	lda @textdmasize
	mvn ^BG1_TILE_BUF, ^BG1_TILE_BAK
	ldx #!BG2_TILE_BUF+64*9
	ldy #!BG2_TILE_BAK+64*9
	lda @textdmasize
	mvn ^BG2_TILE_BUF, ^BG2_TILE_BAK
	plp
	plb
	rts

restore_screen:
; MVN: X=source, Y=dest, A=count
;      imm1=srcbk, imm2=dstbk
	phb
	php
	rep #$30 : .xl : .al
	ldx #!BG1_TILE_BAK+64*9
	ldy #!BG1_TILE_BUF+64*9
	lda @textdmasize
	mvn ^BG1_TILE_BAK, ^BG1_TILE_BUF
	ldx #!BG2_TILE_BAK+64*9
	ldy #!BG2_TILE_BUF+64*9
	lda @textdmasize
	mvn ^BG2_TILE_BAK, ^BG2_TILE_BUF
	plp
	plb
	rts

draw_window:
	phb
	php
	sep #$20 : .as

; draw upper border
; upper left corner
	lda @window_nw
	sta stringbuf
	ldx #!stringbuf
	inx
	lda window_w
	sta window_tmp
	stz window_tmp+1
	ldy window_tmp
	dey
	dey
; upper edge
-
	lda @window_nh
	sta !0,x
	inx
	dey
	cpy #$0000
	bne -

; upper right corner
	lda @window_ne
	sta !0,x

; print to text buffer
	lda #$01
	sta print_pal
	lda window_x
	sta print_x
	lda window_y
	sta print_y
	lda #^stringbuf
	sta print_bank
	ldx #!stringbuf
	stx print_src
	lda window_w
	sta print_count
	jsr hiprint

; print window title
	lda print_x
	pha
	inc print_x
	inc print_x
	lda #^window_tl
	sta print_bank
	ldx #!window_tl
	stx print_src
	lda #$01
	sta print_count
	jsr hiprint
	inc print_x
	lda window_tbank
	sta print_bank
	ldx window_taddr
	stx print_src
	lda window_w
	sta print_count
	jsr hiprint
	lda print_done
	clc
	adc print_x
	sta print_x
	lda #^window_tr
	sta print_bank
	ldx #!window_tr
	stx print_src
	lda #$01
	sta print_count
	jsr hiprint
	lda window_w
	sta print_count
	pla
	sta print_x
; draw left+right borders + space inside window
	lda #^stringbuf
	sta print_bank
	ldx #!stringbuf
	stx print_src
	lda @window_wv
	sta stringbuf
	ldx #!stringbuf
	inx
	lda window_w
	sta window_tmp
	stz window_tmp+1
	ldy window_tmp
	dey
	dey
-
	lda @space64
	sta !0,x
	inx
	dey
	cpy #$0000
	bne -

	lda @window_ev
	sta !0,x

; print to text buffer multiple times
	lda window_h
	sta window_tmp
	stz window_tmp+1
	ldy window_tmp
	dey
	dey
-
	inc print_y
	phy
	jsr hiprint
	ply
	dey
	cpy #$0000
	bne -

; draw lower window border
; lower left corner
	lda @window_sw
	sta stringbuf
	ldx #!stringbuf
	inx
	lda window_w
	sta window_tmp
	stz window_tmp+1
	ldy window_tmp
	dey
	dey
; lower edge
-
	lda @window_sh
	sta !0,x
	inx
	dey
	cpy #$0000
	bne -
; lower right corner
	lda @window_se
	sta !0,x
; print to text buffer
	inc print_y
	jsr hiprint
	plp
	plb
	rts
