/*
todo:
add a special case for uploading 2 vertical rows of the tilemap.
doing this with 32 dma transfers of 4 bytes each is incredibly slow.
better make a tight loop using vram acces 32byte increment that uploads the tilemap rows manually.


guesstimate is that the dma fifo routine can transfer 130 bytes per scanline on average.
normal transfers shouldnt be smaller than 128 bytes or so, otherwise the time needed to set up a dma transfer throws
our timing off way too much.

scanlines 200-261 can be used for uploads.
maximum transfer length should be 2048 bytes.
nmi eats about 8 scanlines.

current guesstimate is 6784/$1a80 bytes per frame.

this routine is used to dma transfer data to vram in bulk.
other routines can queue writes into a fifo buffer and these then get transferred to vram during nmi or forced blank.

;this only works for transfers from a-bus to vram to keep things simple
;a transfer length of 0 marks the end of the buffer

;WARNING!
;this routine MUST have finished till nmi starts or it will produce glitched transfers! no longer true. was caused by some status stuff not being pushed to stack during irq entry.
;overscan is enabled to lengthen the time available for dma'ing stuff from the dma fifo to vram
;glitched transfer risk can be minimized by writing the dma count value last!!

number of scanlines:	irq trigger:	nmi trigger normal:	irq trigger overscan:	
ntsc: 261		200		225			240
pal:  311		200		225			240




maximum number of entries: 128


dma queue format:
offset:	length:	function:
00	2	transfer length
02	2	vram target
04	2	a-bus source offset	
06	1	a-bus source bank

areas needed:
DmaFifoBuffer	ds $1c0


variables needed:
DmaFifoPointer		dw		;relative pointer to current free entry in buffer
DmaFifoSourcePointerLo	dw	
DmaFifoSourcePointerBa	db

fixed variable needed:
.define DmaFifoEntryLength	7

routine features:

InitDmaFifo:
	-clear dma fifo buffer
	
ProcessDmaFifo:
	-setup initial dma regs
	-process the list until a length of 0 is encountered
	-reset DmaFifoPointer to 0

transfer types:

00=void, no transfer
01=normal dma from a-bus adress to vram
02=special manual transfer mode to upload vertical tilemap rows 
03=special transfer,16x16 sprite
04=special transfer, 32x32 sprite
05=special transfer, 64x64 sprite
06=special vwf transfer, converts 2bpp tiles to 4bpp. transfer length is number of tiles, not bytelength

how to write entries into table, m/x=16bit, new:

;transfer type 1, normal a-bus to vram dma:
ldx.b DmaFifoPointer
lda #1					;transfer type
sta.l DmaFifoEntryType,x
sta.l DmaFifoEntryCount,x		;length 4305
sta.l DmaFifoEntryTarget,x		;vram target 2116
sta.l DmaFifoEntrySrcLo,x		;source 4302
sta.l DmaFifoEntrySrcHi,x		;source 4303
sta.l DmaFifoEntrySrcBank,x		;source 4304

	txa						;update fifo entry pointer
	clc
	adc.w #DmaFifoEntryLength
	sta.b DmaFifoPointer

;transfer type 2, upload vertical tilemap row from wram bank 7e to vram
ldx.b DmaFifoPointer
lda #2					;transfer type
sta.l DmaFifoEntryType,x
sta.l DmaFifoEntryTarget,x		;vram target 2116
sta.l DmaFifoEntryCount,x		;number of lines to upload (one line has 32 entries), maximum 32 lines
sta.l DmaFifoEntrySrcLo,x		;source 4302
sta.l DmaFifoEntrySrcHi,x		;source 4303
;sta.l DmaFifoEntrySrcBank,x		;source 4304


	
*/

;waits for all dma transfers to be done and then one frame
WaitDmaTransfersDone:
	php
	rep #$31
WaitDmaTransfersDoneLoop:
	lda.b DmaFifoPointer
	bne WaitDmaTransfersDoneLoop


	plp
	rts

;waits 2 frames to be sure all settings have been written to the video regs
WaitFrame:
;	rts
	php
	rep #$31

WaitFrameIncDone:
	lda.b FrameCounterLo
	cmp.b FrameCounterLo
	beq WaitFrameIncDone
/*
WaitFrameIncDone1:
	lda.b FrameCounterLo
	cmp.b FrameCounterLo
	beq WaitFrameIncDone1
*/

	plp
	rts
	
InitDmaFifo:
	php
	rep #$31
	lda.w #0		;clear word: $0000
	sta.l (DmaFifoPointer+$7e0000)			;reset fifo pointer
	sta.l (DmaFifoPointerIrq+$7e0000)			;reset fifo pointer
	ldy.w #DmaFifoEntryLength*256
	ldx.w #DmaFifoBuffer&$ffff
	jsr ClearWRAM		
	
	
;	sta.l (DmaFifoOverhang+$7e0000)
;	sta.l (DmaFifoTotalBytesTransferred+$7e0000)

	plp
	rts

ProcessDmaFifoTypeLUT:
	.dw ProcessDmaFifoTypeVoid
	.dw ProcessDmaFifoTypeNormalDma
	.dw ProcessDmaFifoTypeVTilemapRow
	.dw ProcessDmaFifoType16x16Sprite
	.dw ProcessDmaFifoType32x32Sprite
	.dw ProcessDmaFifoType64x64Sprite
	.dw ProcessDmaFifoTypeVwf2bppTo4bpp
	.dw UploadBg1Tilemap
	.dw UploadBg2Tilemap

	.dw UploadBg3Tilemap
	.dw NMIUploadPal
	.dw NMIUploadOAM
	.dw ProcessDmaFifoTypeVoid	
	.dw ProcessDmaFifoTypeVoid
	.dw ProcessDmaFifoTypeVoid
	.dw ProcessDmaFifoTypeVoid
	.dw ProcessDmaFifoTypeVoid	

ProcessDmaFifoTypeVoid:
;	sec
	rts

ProcessDmaFifoTypeVwf2bppTo4bpp:
;setup some dma regs that always stay the same on all transfers:	
	lda.w #$1801			;Set the DMA mode (word, normal increment)
	sta.w $4300 
	
	lda.b [DmaFifoSourcePointerLo],y
	and.w #$7f								;128 tiles max(vram vwf buffer size)
	beq ProcessDmaFifoTypeVwf2bppTo4bppAbort	
	
	sta.b TempBufferIrq						;number of tiles to transfer, counter
/*	
	asl a									;multiply by 16(length of one 2bpp tile)
	asl a
	asl a
	asl a
	clc
	adc.b DmaFifoTotalBytesTransferred
	sta.b DmaFifoTotalBytesTransferred
*/
	lda.w #16								;transfer length, one tile
	sta.w $4305
	
	
	
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq+2			;vram target
	sta.w $2116
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq+4			;dma source
	sta.w $4302
	iny
	lda.b [DmaFifoSourcePointerLo],y	;dma source, high byte and bank
	iny
	iny
;	iny
	sta.w $4303

ProcessDmaFifoTypeVwf2bppTo4bppLoop:
	sep #$20
	lda #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1

	lda.b #$01
	sta.w $420b

	dec.b TempBufferIrq			;counter
	beq ProcessDmaFifoTypeVwf2bppTo4bppAbort		;all tiles uploaded?

	
	rep #$31
	
	lda.b TempBufferIrq+2
;	clc
	adc.w #32/2					;add one 4bpp tile to vram target
	sta.b TempBufferIrq+2
	sta.w $2116
	lda.b TempBufferIrq+4
	clc
	adc.w #16					;add one 2bpp tile to wram source
	sta.b TempBufferIrq+4
	sta.w $4302
	lda.w #16				;transfer length, one line
	sta.w $4305
	bra ProcessDmaFifoTypeVwf2bppTo4bppLoop
	
ProcessDmaFifoTypeVwf2bppTo4bppAbort:
	rts

ProcessDmaFifoType16x16Sprite:
	lda.w #$1801			;Set the DMA mode (word, normal increment)
	sta.w $4300 
	
	lda.w #64				;transfer length, one line
	sta.w $4305
/*
	lda.w #64*8
	clc
	adc.b DmaFifoTotalBytesTransferred
	sta.b DmaFifoTotalBytesTransferred
*/	
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq			;vram target
	sta.w $2116
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq+2			;dma source
	sta.w $4302
	iny
	lda.b [DmaFifoSourcePointerLo],y	;dma source, high byte and bank
	iny
	iny
;	iny
	sta.w $4303
     

	sep #$20
	lda #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1

	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #64					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #64				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b
	rts

ProcessDmaFifoType32x32Sprite:
	lda.w #$1801			;Set the DMA mode (word, normal increment)
	sta.w $4300 

	lda.w #128				;transfer length, one line
	sta.w $4305
/*
	lda.w #128*8
	clc
	adc.b DmaFifoTotalBytesTransferred
	sta.b DmaFifoTotalBytesTransferred
*/	
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq			;vram target
	sta.w $2116
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq+2			;dma source
	sta.w $4302
	iny
	lda.b [DmaFifoSourcePointerLo],y	;dma source, high byte and bank
	iny
	iny
;	iny
	sta.w $4303
     

	sep #$20
	lda #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1

	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #128					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #128				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #128					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #128				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #128					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #128				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b	
	rts

;takes 19 lines for 2048 bytes. a single 2048 byte transfer takes 12 lines, so this could be sped up a bit still
ProcessDmaFifoType64x64Sprite:
	lda.w #$1801			;Set the DMA mode (word, normal increment)
	sta.w $4300 

;	lda.b [DmaFifoSourcePointerLo],y
;	beq ProcessDmaFifoTypeNormalDmaAbort
	lda.w #256				;transfer length, one line
	sta.w $4305
/*
	lda.w #256*8
	clc
	adc.b DmaFifoTotalBytesTransferred
	sta.b DmaFifoTotalBytesTransferred
*/	
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq			;vram target
	sta.w $2116
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.b TempBufferIrq+2			;dma source
	sta.w $4302
	iny
	lda.b [DmaFifoSourcePointerLo],y	;dma source, high byte and bank
	iny
	iny
;	iny
	sta.w $4303
     

	sep #$20
	lda #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1

	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b
	
	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b

	rep #$31
	lda.b TempBufferIrq
;	clc
	adc.w #32*16/2					;add one 16tile-line to vram target
	sta.b TempBufferIrq
	sta.w $2116
	lda.b TempBufferIrq+2
	clc
	adc.w #256					;add one tileline in source
	sta.b TempBufferIrq+2
	sta.w $4302
	lda.w #256				;transfer length, one line
	sta.w $4305
	sep #$20
	lda.b #$01
	sta.w $420b					
	rep #$31			;clear carry, dont abort processing fifo list
	rts


ProcessDmaFifoTypeNormalDma:
	lda.w #$1801			;Set the DMA mode (word, normal increment)
	sta.w $4300 

	lda.b [DmaFifoSourcePointerLo],y
	beq ProcessDmaFifoTypeNormalDmaAbort
	sta.w $4305
/*	
	cmp.w #DmaFifoMinTransferSize				;check if transfer is lower than 64 and load 64 for counter if it is. otherwise, these transfers screw up our calculation
	bcs ProcessDmaFifoTypeNormalDmaBigEnough

	lda.w #DmaFifoMinTransferSize				;load minimum length
ProcessDmaFifoTypeNormalDmaBigEnough:
	clc
	adc.b DmaFifoTotalBytesTransferred
	sta.b DmaFifoTotalBytesTransferred
*/	
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.w $2116
	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.w $4302
	iny
	lda.b [DmaFifoSourcePointerLo],y
	iny
	iny
;	iny
	sta.w $4303
;	lda #$18  			;Set the destination register (VRAM gate)
;	sta $4301      

	sep #$20
	lda #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1

	lda.b #$01
	sta.w $420b

	rep #$31			;clear carry, dont abort processing fifo list
	rts

ProcessDmaFifoTypeNormalDmaAbort:	;abort and go to next entry if a transfer length of 0 is encountered
	iny
	iny
	iny
	iny
	iny
	iny
	iny
	rts

ProcessDmaFifoTypeVTilemapRow:
	lda.w #$1801			;Set the DMA mode (word, normal increment)
	sta.w $4300 

	sep #$20
	lda #%10000001
	sta $2115			;set VRAM transfer mode to word-access, increment by 64

	rep #$31
;	lda.b [DmaFifoSourcePointerLo],y	;get number of lines to transfer
;	and #31					;maximum number of lines:32
;	tax

	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	sta.w $2116				;store vram target

	iny
	iny
	lda.b [DmaFifoSourcePointerLo],y
	tax					;source offset in bank $7e
	iny
	iny
	iny
	lda.l $7e0000,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$40,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$80,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$100,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$140,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$180,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$1c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$200,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$240,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$280,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$2c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$300,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$340,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$380,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$3c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$400,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$440,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$480,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$4c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$500,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$540,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$580,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$5c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$600,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$640,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$680,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$6c0,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$700,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$740,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$780,x	
	sta $2118			;write data to vram
	lda.l $7e0000+$7c0,x	
	sta $2118			;write data to vram
	rts
	


/*	
pointer
pointerirq

-if pointer=0, exit immediately
-get pointerirq and do transfer its pointing to, then increase pointerirq by one entry
-if pointerirq is equal or bigger than pointer, clear pointer and pointerirq

*/
ProcessDmaFifo:
	php
	sep #$20
;setup pointer to fifo buffer
	lda.b #$7e
	sta.b DmaFifoSourcePointerBa
	rep #$31
	lda.w #DmaFifoBuffer&$ffff
	sta.b DmaFifoSourcePointerLo
;	ldy.b DmaFifoOverhang			;normally 0. if the list wasnt finished last frame, we finish it now

	ldy.b DmaFifoPointer
	beq ProcessDmaFifoExit

	
ProcessDmaFifoLoop:
	ldy.b DmaFifoPointerIrq	
	lda.b [DmaFifoSourcePointerLo],y	;get transfer type
	phy													;save for later
	
	and.w #$000f								;16 different transfer types only

	asl a
	tax
	iny													;prepare pointer for dma upload routine
	php
	jsr (ProcessDmaFifoTypeLUT,x)
	plp
	
	ply

	lda.w #0
	sta.b [DmaFifoSourcePointerLo],y		;clear this transfer type to be on the safe side
	iny
	iny
	sta.b [DmaFifoSourcePointerLo],y
	iny
	iny
	sta.b [DmaFifoSourcePointerLo],y
	iny
	iny
	sta.b [DmaFifoSourcePointerLo],y
	iny
	iny
	tya
	sta.b DmaFifoPointerIrq						;update process pointer
	cmp.b DmaFifoPointer
	bcc ProcessDmaFifoNotDone					;done when process pointer is bigger than queue pointer			
	
	stz.b DmaFifoPointerIrq						;clear both pointers
	stz.b DmaFifoPointer
	bra ProcessDmaFifoExit


ProcessDmaFifoNotDone:
;	cpy.w #DmaFifoEntryLength*128	;check if whole list was processed
	


;check if scanline 238 has been passed:
	sep #$20

	lda.b #$80
	sta.w $4201							;reset latch
	nop
	nop
	nop
	nop
	lda.w $2137							;latch current scanline
	lda.w $213f							;reset $213d lo/hi byte counter
	lda.w $213d							;get low byte
	xba
	lda.w $213d							;get high byte
	xba	
	rep #$31
	and.w #$1ff
	cmp.w #199
	bcc ProcessDmaFifoExit	;exit if lower than scanline 200 (wrapped around)
	cmp.w #239
	bcc ProcessDmaFifoLoop	;exit if bigger than scanline 237 (nearly at end of irq timeframe)

	
ProcessDmaFifoExit:

;	jsr InitDmaFifo
;	sty.b DmaFifoPointer		;should always be zero
	plp
	rts



/*
UploadBg1TilemapFifo:
	php
	rep #$31
	ldx.b DmaFifoPointer
	lda #1					;transfer type normal dma
	sta.l DmaFifoEntryType,x
	lda.b VramBg1Tilemap
	sta.l DmaFifoEntryTarget,x		;vram target 2116
	lda.w #Bg1MapBuffer & $ffff
	sta.l DmaFifoEntrySrcLo,x		;source 4302
	lda.w #$800
	sta.l DmaFifoEntryCount,x		;length 4305
	sep #$20
	lda.b #(Bg1MapBuffer >> 16)
	sta.l DmaFifoEntrySrcBank,x		;source 4304
	rep #$31
	txa						;update fifo entry pointer
	adc.w #DmaFifoEntryLength
	sta.b DmaFifoPointer


	plp
	rts
*/



NMIUploadPal:
;transfer palette buffer to cgram
	sep #$20
	stz.w $2121			;upload colour-palette buffer at $7e:0e00 to cg-ram every frame
	ldx #PaletteBuffer&$ffff			;start at color 0 
	stx.w $4302			;Store the data offset into DMA source offset
	ldx #$0200
	stx.w $4305   			;Store the size of the data block
	lda.b #$7e
	sta.w $4304			;Store the data bank holding the tile data
	lda.b #$00			;Set the DMA mode (byte, normal increment)
	sta.w $4300       
	lda.b #$22    			;Set the destination register ( $2122: CG-RAM Write )
	sta.w $4301      
	lda.b #$01    			;Initiate the DMA transfer
	sta.w $420B
;	stz.b NMIPaletteUploadFlag
	rts

NMIUploadOAM:
;transfer sprite buffer to oamram
	sep #$20
	stz.w $2102			;upload to oam adress 0
	stz.w $2103
	ldx.w #OamBuffer&$ffff			;start at color 0 
	stx.w $4302			;Store the data offset into DMA source offset
	ldx.w #$0220
	stx.w $4305   			;Store the size of the data block
	lda.b #$7e
	sta.w $4304			;Store the data bank holding the tile data
	lda.b #$00			;Set the DMA mode (byte, normal increment)
	sta.w $4300       
	lda.b #$04    			;Set the destination register ( $2122: CG-RAM Write )
	sta.w $4301      
	lda.b #$01    			;Initiate the DMA transfer
	sta.w $420B
;	stz.b NMIOamUploadFlag		;clear upload flag
	rts
	
BgTilemapSizeLUT:
	.dw $800
	.dw $1000
	.dw $1000
	.dw $2000
	
;NMIUploadBg1:
UploadBg1Tilemap:
	rep #$31
	lda.b BG1TilemapVram
	and.w #%11					;get tilemap size
	asl a
	tax
	lda.l (BgTilemapSizeLUT+BaseAdress),x
	sta.w $4305   			;Store the size of the data block
;transfer bg1 tilemap to vram if needed:
	sep #$20
	ldx.b VramBg1Tilemap
	stx.w $2116			;vram adress $0000
	ldx.w #Bg1MapBuffer & $ffff
	stx.w $4302			;Store the data offset into DMA source offset
	
	lda.b #(Bg1MapBuffer >> 16)
	sta.w $4304			;Store the data bank of the source data
	lda.b #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1
	lda.b #$01			;Set the DMA mode (word, normal increment)
	sta.w $4300       
	lda.b #$18    			;Set the destination register (VRAM gate)
	sta.w $4301      
	lda.b #$01    			;Initiate the DMA transfer
	sta.w $420B
;	stz.b NMIBg1UploadFlag
	rts
	
;NMIUploadBg2:	
UploadBg2Tilemap:
;transfer bg2 tilemap to vram if needed:
	rep #$31
	lda.b BG2TilemapVram
	and.w #%11					;get tilemap size
	asl a
	tax
	lda.l (BgTilemapSizeLUT+BaseAdress),x
	sta.w $4305   			;Store the size of the data block
	sep #$20
	ldx.b VramBg2Tilemap
	stx.w $2116			;vram adress $0000
	ldx.w #Bg2MapBuffer & $ffff
	stx.w $4302			;Store the data offset into DMA source offset
;	ldx.w #$800
;	stx.w $4305   			;Store the size of the data block
	lda.b #(Bg2MapBuffer >> 16)
	sta.w $4304			;Store the data bank of the source data
	lda.b #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1
	lda.b #$01			;Set the DMA mode (word, normal increment)
	sta.w $4300       
	lda.b #$18    			;Set the destination register (VRAM gate)
	sta.w $4301      
	lda.b #$01    			;Initiate the DMA transfer
	sta.w $420B
;	stz.b NMIBg2UploadFlag
	rts	


UploadBg3Tilemap:
;transfer bg3 tilemap to vram if needed:
	rep #$31
	lda.b BG3TilemapVram
	and.w #%11					;get tilemap size
	asl a
	tax
	lda.l (BgTilemapSizeLUT+BaseAdress),x
	sta.w $4305   			;Store the size of the data block
	sep #$20
	ldx.b VramBg3Tilemap
	stx.w $2116			;vram adress $0000
	ldx.w #Bg3MapBuffer & $ffff
	stx.w $4302			;Store the data offset into DMA source offset
;	ldx.w #$800
;	stx.w $4305   			;Store the size of the data block
	lda.b #(Bg3MapBuffer >> 16)
	sta.w $4304			;Store the data bank of the source data
	lda.b #$80
	sta.w $2115			;set VRAM transfer mode to word-access, increment by 1
	lda.b #$01			;Set the DMA mode (word, normal increment)
	sta.w $4300       
	lda.b #$18    			;Set the destination register (VRAM gate)
	sta.w $4301      
	lda.b #$01    			;Initiate the DMA transfer
	sta.w $420B
;	stz.b NMIBg3UploadFlag
	rts	







	