
;*********************************************************************	
; includes
;*********************************************************************	

	.incdir	"F:\git\goldmomo_endlos\assembler_files\ucore\"
	.include "include\ucore_ctrl.i"

;*********************************************************************	
; sd header is placed here
;*********************************************************************	

	.include "boot_level_sdHeader.s"

;*********************************************************************
;* start at address 32 here
;*********************************************************************

start	
	;setup irq vector
	
	movei	r0,irq
	nop
	moveih	r0,>irq
	nop
	setssr	r0,2

	;setup video (720x450)
	
	movei	r0,setupVideo
	nop
	moveih	r0,>setupVideo
	gpci	r7,2		;next 4 + X
	jmpi	r0,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;copy font (rom -> ram)
		
	movei	r0,fontDataROM	;source
	movei	r1,>>fontDataROM
	moveih	r0,>fontDataROM
	moveih	r1,>>>fontDataROM
		
	movei	r2,fontDataRAM	;destination 
	movei	r3,>>fontDataRAM
	moveih	r2,>fontDataRAM
	moveih	r3,>>>fontDataRAM	
	
	movei	r5,extCopy8
	nop
	moveih	r5,>extCopy8
	gpci	r7,2	;next 4 + X
	jmpi	r5,0
	movei	r4,$df	;delay slot (copy 0x2f00 words -> $5df+1)	
	nop		;delay slot
	moveih	r4,$05	;delay slot
	nop		;delay slot
	
	;clear screen
	
	movei	r2,$00	;destination 
	movei	r3,$00
	moveih	r2,$00
	moveih	r3,$f0	;p(0,0) = f000 0000
	
	gpci	r7,2	;next 4 + X
	br	memset
	movei	r1,$33	; count		delay slot	
	movei	r0,$00	; value		delay slot
	moveih	r1,$9e	; count		delay slot
	nop		;		delay slot
	
	;copy sample into sram

	movei	r4,$e4
	movei	r2,>>sampleData
	moveih	r4,$6
	moveih	r2,>>>sampleData
	movei	r5,iToECopy
	nop
	moveih	r5,>iToECopy
	gpci	r7,2	;next 4 + X
	jmpi	r5,0	;br	iToECopy
	movei	r0,sampleDataIRAM	;delay slot	
	movei	r1,sampleData		;delay slot
	moveih	r0,>sampleDataIRAM	;delay slot
	moveih	r1,>sampleData		;delay slot	
	
	;reset PS2 buffer
	
	gpci	r7,2	;next 4 + X
	br	PS2Reset
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;setup audio
	
	gpci	r7,2		;next 4 + X
	br	initAudio
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
	;setup audio irq
	
	movei	r0,UcIrqMsk
	movei	r1,$4			;enable audio irq
	moveih	r0,>UcIrqMsk
	nop
	st	r0,r1			;
	
	;set audio dac counter = 2 (96/3 = 32KHz)
	
	movei	r6,UcAudioDACBase
	nop
	moveih	r6,>UcAudioDACBase
	movei	r1,$2
	movei	r0,0
	moveih	r1,$2	;address 2
	
	
	stinc	r6,r0	;dac left high = 0
	nop
	stinc	r6,r0	;dac left low = 0
	nop
	stinc	r6,r0	;dac right high = 0
	nop
	stinc	r6,r0	;dac right low = 0	
	nop
	st	r6,r1	;dac address/ctrl = $0201	;dac counter = 2
	

	;enable irqs
	
	sei
	
	;*********************************************************************
	;* main loop
	;*********************************************************************
	
mainLoop	

	;switch and clear frames
	
	movei	r0,switchAndClearFrame
	nop
	moveih	r0,>switchAndClearFrame
	gpci	r7,2
	jmpi	r0,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;draw header
	
	gpci	r7,2		;next 4 + X
	br	drawTextFormated
	movei	r0,textHeader	;delay slot
	movei	r1,0		;delay slot
	moveih	r0,>textHeader	;delay slot
	movei	r2,0		;delay slot
	
	;process ps2 keys
	
	gpci	r7,2		;next 4 + X
	br	PS2Process
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	;process ps2 pressed key to value
	
	gpci	r7,2		;next 4 + X
	br	PS2KeyToPeriode
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
	; ;draw result	
		
	push	r0	
	
	gpci	r7,2		;next 4 + X
	br	drawTextFormated
	movei	r0,textPeriode	;delay slot
	movei	r1,0		;delay slot
	moveih	r0,>textPeriode	;delay slot
	movei	r2,2		;delay slot	
	
	rqpop
	nop
	nop
	pop	r0	;periode
	
	;set periode to channels
	
	gpci	r7,2		;next 4 + X
	br	setPeriodeToChannels
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
		
	;draw channel buffer
	
	movei	r2,channel0Buffer
	gpci	r7,2		;next 4 + X
	br	drawChannelBuffer
	movei	r0,12		;delay slot
	movei	r1,100		;delay slot
	moveih	r2,>channel0Buffer			;delay slot
	movei	r3,95		;delay slot
	
	;draw channel buffer
	
	movei	r2,channel1Buffer
	gpci	r7,2		;next 4 + X
	br	drawChannelBuffer
	movei	r0,132		;delay slot
	movei	r1,100		;delay slot
	moveih	r2,>channel1Buffer			;delay slot
	movei	r3,95		;delay slot
	
	;draw channel buffer
	
	movei	r2,channel2Buffer
	gpci	r7,2		;next 4 + X
	br	drawChannelBuffer
	movei	r0,252		;delay slot
	movei	r1,100		;delay slot
	moveih	r2,>channel2Buffer			;delay slot
	movei	r3,95		;delay slot
	
	;draw channel buffer
	
	movei	r0,$74
	movei	r2,channel3Buffer
	gpci	r7,2		;next 4 + X
	br	drawChannelBuffer
	moveih	r0,1		;delay slot
	movei	r1,100		;delay slot
	moveih	r2,>channel3Buffer			;delay slot
	movei	r3,95		;delay slot
	
	;draw channel buffer
	
	movei	r0,$ec
	movei	r2,channel4Buffer
	gpci	r7,1		;next 4 + X
	br	drawChannelBuffer
	moveih	r0,1		;delay slot
	movei	r1,100		;delay slot
	moveih	r2,>channel4Buffer			;delay slot
	movei	r3,95		;delay slot
	
	;draw channel buffer
	
	movei	r0,$64
	movei	r2,channel5Buffer
	gpci	r7,1		;next 4 + X
	br	drawChannelBuffer
	moveih	r0,2		;delay slot
	movei	r1,100		;delay slot
	moveih	r2,>channel5Buffer			;delay slot
	movei	r3,95		;delay slot
	
	;debug output
	
	gpci	r7,2
	br	debugOutput
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	br	mainLoop
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot

;*********************************************************************
;* functions
;*********************************************************************

	.include	"components\i2c.s"
	.include	"components\drawText.s"
	.include	"components\audioChannel.s"
	.include	"components\ps2keyboard.s"	
	.include	"components\binSearch.s"

;******************************
;*	
;* setPeriodeToChannels
;*	
;* r0 = periode
;*
;*	

setPeriodeToChannels	
	
	cmpeqi	r0,0
	brts	setPeriodeToChannelsNothingToDo
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	push	r7
	
	movei	r1,channelActive
	movei	r2,channelArray
	moveih	r1,>channelActive
	moveih	r2,>channelArray
	
	rqldi	r1,0
	nop
	nop
	ld	r3
	nop
	add	r6,r2,r3	;get real pointer channel struct
	addi	r3,1		;set to next channel
	movei	r2,0
	cmploi	r3,6		;0..5
	movets	r3,r3,r2
	nop
	st	r1,r3		;store active channel back
	
	rqldi	r6,0
	nop
	nop
	ld	r6
	
	;set periode (r0) to channel (r6)
	
	gpci	r7,2
	br	channelSetPeriode
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;set channel start to 0
	
	movei	r0,0
	gpci	r7,2
	br	channelSetSampleStart
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	rqpop
	nop
	nop
	pop	r7
	nop
	
setPeriodeToChannelsNothingToDo	
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	

channelActive

	word	0

channelArray	
	
	word	channel0
	word	channel1
	word	channel2
	word	channel3
	word	channel4
	word	channel5
	
;******************************
;*	
;* PS2KeyToPeriode
;*
;* return
;*
;* r0 = periode value (0 if no key) 
;*	

PS2KeyToPeriode
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r7
	
	;clean up valid keys
	
	movei	r0,mPSNormalKeys	;keys current
	movei	r1,rawKeyMask		;ascii mask
	movei	r2,mCleanNormalKeys	;destination
	moveih	r0,>mPSNormalKeys
	moveih	r1,>rawKeyMask
	moveih	r2,>mCleanNormalKeys	
	movei	r3,8			;9 words -1
	
keyToAsciiAndLoop

	rqldi	r0,0
	rqldi	r1,0
	addi	r0,1
	ld	r4
	ld	r5
	addi	r1,1
	and	r4,r4,r5

	subi	r3,1
	brts	keyToAsciiAndLoop
	st	r2,r4	;delay slot
	nop		;delay slot
	addi	r2,1	;delay slot
	nop		;delay slot
	
	;find first key
	
	movei	r2,mCleanNormalKeys	;source to find
	movei	r3,$0			;counter for bits
	movei	r4,8			;9 words
	moveih	r2,>mCleanNormalKeys	
	nop
	
keyToAsciiFindFirst

	rqldi	r2,0
	addi	r2,1
	nop
	ld	r0	;word
	nop
	bffo	r1,r0	;r1 is value of first bit (t=true if found)
	brts	keyToAsciiFoundFirst
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	subi	r4,1	
	brts	keyToAsciiFindFirst
	addi	r3,16	;next word		delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
		
keyToAsciiFoundFirst
	
	;search value in keytable
		
	gpci	r7,2
	br	binSearch
	add	r0,r1,r3			;bit count + word count * 16	delay slot
	movei	r2,rawToPeriodeTable		;				delay slot
	movei	r1,rawToPeriodeTableLength	;length				delay slot
	moveih	r2,>rawToPeriodeTable		;				delay slot
	
	movei	r1,$ff
	or	r4,r0,r0		;save bit pos
	moveih	r1,$ff		;
	
	;test found
	
	nop
	
	cmpeq	r1,r5	;$ffff means no found 
	brts	keyToAsciiInvalidKey
	movei	r0,0	;invalid value	delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;remove this key from ps2 buffer
	
	gpci	r7,2
	br	PS2ClearKey		;fixme
	or	r0,r4,r4		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;get value from periode table
	
	movei	r0,periodeFromKey
	nop
	moveih	r0,>periodeFromKey
	nop
	add	r0,r0,r5
	nop
	rqldi	r0,0
	nop
	nop
	ld	r0
	
keyToAsciiInvalidKey	
	
	rqpop
	rqpop
	rqpop
	pop	r7
	pop	r5
	pop	r4
	
	rqpop
	rqpop
	rqpop
	pop	r3
	pop	r2
	pop	r1
	
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	
mCleanNormalKeys
	
	.space	9	;16 * 9 = 144 bit	
	
;keys which usable for periode [yxcvbnm,.-]
	
rawKeyMask
	.data	$0000,$0400,$0406,$0406,$4202,$0000,$0000,$0000,$0000,$0000

	
	
	.def	rawToPeriodeTableLength	9
	
rawToPeriodeTable	
	word	$001a	;y
	word	$0021	;c
	word	$0022	;x
	word	$002A	;v
	word	$0031	;n
	word	$0032	;b
	word	$003A	;m
	word	$0041	;,
	word	$0049	;.
	word	$004E	;-
	

periodeFromKey

	word	428  ;y x
	word	381  ;c x
	word	404  ;x x
	word	360  ;v x
	word	320  ;n x
	word	339  ;b x
	word	302  ;m x
	word	285  ;, ?
	word	269  ;. ?
	word	254  ;- ?
		
;******************************
;*
;* drawChannelBuffer
;*
;* return
;*
;* r0 = x
;* r1 = y
;* r2 = channelBuffer
;* r3 = channelBuffer length -1
;*

drawChannelBuffer
	
	addi	r1,64
drCLoop
	rqldi	r2,0
	addi	r2,1		;next value
	nop
	ld	r4
	movei	r6,$d0
	asri	r4,6
	moveih	r6,$2		;r6 = 720
	sub	r4,r1,r4	;r4 = y	
	nop
	mul	r5,r4,r6	;y*width
	gmulhi	r6
	add	r5,r5,r0	;+x
	addtqi	r6,r6,0		;
	
	push	r1
	push	r2
	push	r3
	
	movei	r1,drawFrame
	nop
	moveih	r1,>drawFrame
	nop
	rqldi	r1,1	;low
	rqldi	r1,0	;high
	nop
	ld	r2
	ld	r3
	
	add	r2,r2,r5
	addt	r3,r3,r6
	
	movei	r1,$ff
	esadr	r3,r2
	moveih	r1,$ff
	nop
	est	r1,0	
	
	rqpop	
	rqpop
	rqpop
	pop	r3
	pop	r2
	pop	r1
	
	subi	r3,1
	brts	drCLoop
	addi	r0,1		;x++ delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	jmpi	r7,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	

;******************************
;* switchAndClearFrame
;*	
;*
;*

switchAndClearFrame	
	
	push	r7
	
	;wait vpos (930)

	gpci	r7,2	;next 4 + X
	br	waitVPos
	movei	r0,$a1	;delay slot
	nop		;delay slot
	moveih	r0,$3	;delay slot
	nop		;delay slot
	
	;switch frames
	
	gpci	r7,2	;next 4 + X
	br	switchFrames
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	;set display address to video
	
	movei	r0,displayFrame	
	movei	r1,UcVideoMEMStartAdrLow
	movei	r2,UcVideoMEMLatch
	moveih	r0,>displayFrame
	moveih	r1,>UcVideoMEMStartAdrLow	;low memstart
	moveih	r2,>UcVideoMEMLatch		;latch out
	
	rqldi	r0,1
	rqldi	r0,0
	nop
	ld	r3
	ld	r4
	
	st	r1,r3
	addi	r1,1
	nop
	st	r1,r4
	st	r2,r7		;latch out
	
	;clear draw frame
	
	movei	r0,drawFrame	
	movei	r1,$33		;clear 
	moveih	r0,>drawFrame
	moveih	r1,$9e
	
	rqldi	r0,1
	rqldi	r0,0
	nop
	ld	r2
	ld	r3
	
	gpci	r7,2
	br	memset
	movei	r0,0	;clear value delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	rqpop
	nop
	nop
	pop	r7
	nop
	
	jmpi	r7,0
	nop		;delay slot
	nop	     	;delay slot
	nop		;delay slot
	nop		;delay slot
	
;******************************
;* switchFrames
;*

switchFrames

	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5

	movei	r0,displayFrame
	movei	r1,drawFrame
	moveih	r0,>displayFrame	
	moveih	r1,>drawFrame
	
	rqldi	r0,0
	rqldi	r0,1
	nop
	ld	r2
	ld	r3
	
	rqldi	r1,0
	rqldi	r1,1
	nop
	ld	r4
	ld	r5

	st	r0,r4
	addi	r0,1
	nop
	st	r0,r5
	
	st	r1,r2
	addi	r1,1
	nop
	st	r1,r3
	
	rqpop
	rqpop
	rqpop
	pop	r5
	pop	r4
	pop	r3
	
	rqpop
	rqpop
	rqpop
	pop	r2
	pop	r1
	pop	r0
	
	jmpi	r7,0
	nop		;delay slot
	nop	     	;delay slot
	nop		;delay slot
	nop		;delay slot	
	
;******************************
;*	
;* debugOutput
;*

debugOutput
	
	push	r7

	movei	r0,UcRSwichtWLedG
	nop
	moveih	r0,>UcRSwichtWLedG
	nop
	rqldi	r0,0
	nop
	nop
	ld	r0	;sw
	nop
	extri	r0,0
	brtc	debugModeDisabled
	movei	r0,UcVideoRVCountWHSYNC	;		delay slot
	nop		;		delay slot
	moveih	r0,>UcVideoRVCountWHSYNC	;vblank address	delay slot
	nop		;delay slot
	
	rqldi	r0,0	;vcount
	nop
	nop
	ld	r0
	nop
	subi	r0,30
	nop
	lsri	r0,2	;/4
	
	movei	r1,$d0
	nop
	moveih	r1,$2
	
	movei	r3,drawFrame
	mul	r0,r1,r0	;r0 = low
	moveih	r3,>drawFrame
	gmulhi	r1		;r1 = high 
	
	rqldi	r3,0	;high
	rqldi	r3,1	;low
	nop
	ld	r3	;high
	ld	r2	;low
	
	nop
	add	r2,r2,r0	;low
	addt	r3,r3,r1	;high
	movei	r0,$e0
	nop
	moveih	r0,$ff
	esadr	r3,r2
	est	r0,0
	est	r0,1
	est	r0,2
	est	r0,3
	est	r0,4
	est	r0,5
	est	r0,6
	est	r0,7
	
	addi	r2,8
	addtqi	r3,r3,0
	nop
	esadr	r3,r2
	est	r0,0
	est	r0,1
	est	r0,2
	est	r0,3
	est	r0,4
	est	r0,5
	est	r0,6
	est	r0,7
	
debugModeDisabled	
	
	rqpop
	nop
	nop
	pop	r7
	nop
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot	
	
;******************************
;* waitVPos
;*
;* r0 pos
;* 

waitVPos	
	
	push	r1
	push	r2
	
	;check emulator to prevent face freez .....
	
	movei	r1,UuLedR
	nop
	moveih	r1,>UuLedR	
	nop
	rqldi	r1,0
	nop
	nop
	ld	r2
	nop
	cmpeqi	r2,1
	brts	waitVEmulator
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	
waitVRealHardWare
	
	movei	r1,UcVideoRVCountWHSYNC
	nop
	moveih	r1,>UcVideoRVCountWHSYNC	;vcount	
	nop
		
waitV	
	rqldi	r1,0
	nop
	nop
	ld	r2	;get vcount
	nop
	cmpeq	r0,r2
	brtc	waitV
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot

	rqpop
	rqpop
	jmpi	r7,0
	pop	r2	;delay slot
	pop	r1     	;delay slot
	nop		;delay slot
	nop		;delay slot
	
waitVEmulator
	
	movei	r1,UcVideoRVCountWHSYNC
	nop
	moveih	r1,>UcVideoRVCountWHSYNC	;vcount	
	nop
		
waitVE	
	rqldi	r1,0
	nop
	nop
	ld	r2	;get vcount
	nop
	cmplo	r0,r2
	brts	waitVE
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot

	rqpop
	rqpop
	jmpi	r7,0
	pop	r2	;delay slot
	pop	r1     	;delay slot
	nop		;delay slot
	nop		;delay slot		

	
;***********************************************************************
;* irq code start
;***********************************************************************
	
irq
	cli
	
	;save all register
	
	push	r0
	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
		
	;irq begin
	
	;push leds on
	
	movei	r0,UcRSwichtWLedG
	movei	r1,$ff
	moveih	r0,>UcRSwichtWLedG
	moveih	r1,$ff
	nop
	st	r0,r1	
		
	
	;copy 96 values from channel 0	

	movei	r7,channel0
	gpci	r5,2
	br	channelBufferdCopy
	movei	r0,95			;value count samples
	movei	r6,channel0Buffer	;out buffer
	moveih	r7,>channel0		;data struct
	moveih	r6,>channel0Buffer
	
	;copy 96 values from channel 1	

	movei	r7,channel1
	gpci	r5,2
	br	channelBufferdCopy
	movei	r0,95			;value count samples
	movei	r6,channel1Buffer	;out buffer
	moveih	r7,>channel1		;data struct
	moveih	r6,>channel1Buffer
	
	;copy 96 values from channel 2	

	movei	r7,channel2
	gpci	r5,2
	br	channelBufferdCopy
	movei	r0,95			;value count samples
	movei	r6,channel2Buffer	;out buffer
	moveih	r7,>channel2		;data struct
	moveih	r6,>channel2Buffer
	
	;copy 96 values from channel 3	

	movei	r7,channel3
	gpci	r5,2
	br	channelBufferdCopy
	movei	r0,95			;value count samples
	movei	r6,channel3Buffer	;out buffer
	moveih	r7,>channel3		;data struct
	moveih	r6,>channel3Buffer
	
	;copy 96 values from channel 4	

	movei	r7,channel4
	gpci	r5,2
	br	channelBufferdCopy
	movei	r0,95			;value count samples
	movei	r6,channel4Buffer	;out buffer
	moveih	r7,>channel4		;data struct
	moveih	r6,>channel4Buffer
	
	;copy 96 values from channel 5	

	movei	r7,channel5
	gpci	r5,2
	br	channelBufferdCopy
	movei	r0,95			;value count samples
	movei	r6,channel5Buffer	;out buffer
	moveih	r7,>channel5		;data struct
	moveih	r6,>channel5Buffer
	
	;push dac data
	
	movei	r1,channel0Buffer
	movei	r2,channel1Buffer
	movei	r3,channel2Buffer
	movei	r4,channel3Buffer
	movei	r5,channel4Buffer
	movei	r6,channel5Buffer
	moveih	r1,>channel0Buffer
	moveih	r2,>channel1Buffer
	moveih	r3,>channel2Buffer
	moveih	r4,>channel3Buffer
	moveih	r5,>channel4Buffer
	moveih	r6,>channel5Buffer
	
	movei	r0,95			;95 values to DAC
	
fillDACBuffer

	push	r1
	push	r2
	push	r3
	push	r4

	rqldi	r1,0
	rqldi	r2,0
	rqldi	r3,0
	ld	r1
	ld	r2
	ld	r3
	add	r1,r1,r2
	nop
	add	r1,r1,r3
	
	rqldi	r4,0
	rqldi	r5,0
	rqldi	r6,0
	ld	r4
	ld	r2
	ld	r3
	add	r4,r4,r2
	movei	r2,UcAudioDACBase
	add	r4,r4,r3
			
	moveih	r2,>UcAudioDACBase
	movei	r3,0			;zero
	
	
	stinc	r2,r1	;dac left high = value
	movei	r7,$1
	stinc	r2,r3	;dac left low = 0
	moveih	r7,$1
	stinc	r2,r4	;dac right high = value
	nop
	stinc	r2,r3	;dac right low = 0
	nop
	st	r2,r7	;dac address/ctrl = $0101	;ctrl = enable audio
	
	rqpop	
	rqpop
	rqpop
	pop	r4
	pop	r3
	pop	r2
	
	rqpop
	addi	r6,1
	addi	r5,1
	pop	r1

	subi	r0,1
	brts	fillDACBuffer
	addi	r1,1		;delay slot						
	addi	r4,1		;delay slot
	addi	r3,1		;delay slot
	addi	r2,1		;delay slot
	
	;push leds off
	
	movei	r7,UcRSwichtWLedG
	movei	r6,$0
	moveih	r7,>UcRSwichtWLedG
	nop
	st	r7,r6	
	
	;clear stored audio irq
	
	movei	r7,UcIrqMemory
	movei	r0,4
	moveih	r7,>UcIrqMemory
	nop
	st	r7,r0	
	
	;restore all used register and go back
	
	rqpop		
	rqpop	
	rqpop	
	pop	r7
	pop	r6
	pop	r5
	
	rqpop		
	rqpop	
	rqpop	
	pop	r4
	pop	r3
	pop	r2
	
	rqpop		
	rqpop	
	rti
	pop	r1	;delay slot
	pop	r0	;delay slot
	nop		;delay slot
	sei		;delay slot
	
;******************************
;*
;* initAudio
;*
;* return
;*
;* r0 = 0 (PASS)
;*

initAudio	

	push	r7
	
	movei	r6,audioDefault	
	movei	r5,2			;y cursor	
	moveih	r6,>audioDefault
	nop
	
initAudioI2CWriteLoop
	
	rqldi	r6,0
	rqldi	r6,1
	nop
	ld	r2		;address
	ld	r3		;data
	
	cmpeqi	r2,$ff		;stop at sentinel ($ff)
	brts	initAudioI2CWriteFinish
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	
	gpci	r7,2		;next 4 + X
	br	i2cWM8731WriteWord	;r2 = address;	r3 = data; return r0 = result
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	push	r0	;result
	push	r2	;address
	push	r3	;value
	
	gpci	r7,2			;next 4 + X
	br	drawTextFormated	;r0 = text; r1 = cursor x; r2 = cursor y	
	movei	r0,i2cSetupString	;delay slot
	movei	r1,0			;x = 0		delay slot
	moveih	r0,>i2cSetupString	;delay slot
	movei	r2,2;or	r2,r5,r5		;y = y + 2	delay slot
	
	rqpop
	rqpop
	rqpop
	pop	r3
	pop	r2
	pop	r0
		
	br	initAudioI2CWriteLoop
	addi	r6,2		;next lut address	delay slot
	addi	r5,1		;next y counter		delay slot
	nop			;delay slot
	nop			;delay slot

	movei	r0,0
	
initAudioI2CWriteFinish	
	
	rqpop
	nop
	nop
	pop	r7
	nop
	
	jmpi	r7,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
;******************************
;*
;* i2cWM8731WriteWord
;*
;* r2 = address
;* r3 = data
;* 
;* return:
;*
;* r0 = result
;*

i2cWM8731WriteWord

	push	r1
	push	r6
	push	r7
	
	;start
	
	gpci	r7,2	;next 4 + X
	br	i2cSendStart
	movei	r6,UcI2CSoftPortBCtrl		;delay slot
	nop					;delay slot
	moveih	r6,>UcI2CSoftPortBCtrl		;I2C ports b	;delay slot
	nop					;delay slot
	
	;write id
	
	gpci	r7,2	;next 4 + X
	br	i2cSend8WACK
	movei	r1,$34		;WRITE			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0
	brtc	i2cSend8WACKFailsWr
	movei	r0,$ff		;delay slot
	nop			;delay slot
	moveih	r0,$01		;delay slot
	nop			;delay slot
	
	;write address
	
	add	r1,r2,r2	;adr*2
	extri	r3,8
	addtqi	r1,r1,0		;+ bit8 of data
	
	gpci	r7,2	;next 4 + X
	br	i2cSend8WACK
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0
	brtc	i2cSend8WACKFailsWr
	movei	r0,$ff		;delay slot
	nop			;delay slot
	moveih	r0,$02		;delay slot
	nop			;delay slot
		
	;write data low

	gpci	r7,2	;next 4 + X
	br	i2cSend8WACK
	or	r1,r3,r3	;WRITE		;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	cmpeqi	r0,0
	brtc	i2cSend8WACKFailsWr
	movei	r0,$ff		;delay slot
	nop			;delay slot
	moveih	r0,$04		;delay slot
	nop			;delay slot
	
	;finished without fail
	
	movei	r0,0		;all fine
	
	;stop
	
i2cSend8WACKFailsWr

	gpci	r7,2	;next 4 + X
	br	i2cSendStop
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
	gpci	r7,2	;next 4 + X
	br	i2cWaitHalfPeriode
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	gpci	r7,2	;next 4 + X
	br	i2cWaitHalfPeriode
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	gpci	r7,2	;next 4 + X
	br	i2cWaitHalfPeriode
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	gpci	r7,2	;next 4 + X
	br	i2cWaitHalfPeriode
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	
	
	
	rqpop
	rqpop
	rqpop
	pop	r7
	pop	r6
	pop	r1

	jmpi	r7,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot	

;******************************
;*
;* drawChar
;* 
;* r0 	 	value
;* r1		x 	
;* r2		y
;*
;* trash r0

drawChar	

	push	r1
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	
	;destination base (sram base 0)
	
	movei	r3,drawFrame
	muli	r1,8
	moveih	r3,>drawFrame
	nop
	rqldi	r3,1	;low
	rqldi	r3,0	;high
	nop
	ld	r4
	ld	r5
	
	;
	
	add	r4,r4,r1
	addtqi	r5,r5,0
	
	movei	r1,$00
	nop
	moveih	r1,$2d	;720*16
	nop
	
	mul	r1,r1,r2;*y
	gmulhi	r2
	
	add	r4,r4,r1
	addt	r5,r5,r2
		
	;font source
	
	movei	r2,fontDataRAM		;source 
	movei	r3,>>fontDataRAM
	moveih	r2,>fontDataRAM
	moveih	r3,>>>fontDataRAM	;
	
	muli	r0,8		;value * 8
	nop
	add	r2,r2,r0	;source 
	addtqi	r3,r3,0		;

	;

	movei	r0,15		;16 [y]
dcYloop	
	
	movei	r1,7		;8 [x]
dcXloop
	esadr	r3,r2
	erqldi	0
	eld	r6
	nop
	
	extri	r6,15
	brts	dcNoTransp
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
	movei	r6,0
	
dcNoTransp	
	
		
	esadr	r5,r4
	est	r6,0
	
	subi	r1,1		;x-
	brts	dcXloop
	addi	r4,1		;delay slot
	addtqi	r5,r5,0		;delay slot
	addi	r2,1		;delay slot
	addtqi	r3,r3,0		;delay slot
	
	;
		
	movei	r1,$c8
	nop
	moveih	r1,$2		;r1 = 720-8
	nop
	
	add	r4,r4,r1	;dest + 720-8
	addtqi	r5,r5,0		;
	
	movei	r1,$e8
	nop
	moveih	r1,$2		;r1 = 752-8
	nop	
	
	subi	r0,1		;y-
	brts	dcYloop
	add	r2,r2,r1	;source + 752-8		delay slot
	addtqi	r3,r3,0		;			delay slot
	nop			;delay slot
	nop			;delay slot
	
	;
	
	rqpop
	rqpop
	rqpop
	pop	r6
	pop	r5
	pop	r4
	
	rqpop
	nop
	nop
	pop	r3
	
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r2	;delay slot
	pop	r1	;delay slot
	nop		;delay slot
	nop		;delay slot

;******************************
;*
;* r0 	 	value
;* r1		count-1 (8 words))
;* r3:r2	dest
;
memset

clearLoop

	esadr	r3,r2
	est	r0,0
	est	r0,1
	est	r0,2
	est	r0,3
	est	r0,4
	est	r0,5
	est	r0,6
	est	r0,7
	subi	r1,1
	brts	clearLoop
	addi	r2,8	;delay slot
	addtqi	r3,r3,0	;delay slot
	nop		;delay slot
	nop		;delay slot
	
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	
;******************************
;*
;* setupVideo
;*

setupVideo

	
	movei	r0,videoDefault		;source
	movei	r1,UcTimer2Ctrl		;dest-1
	moveih	r0,>videoDefault
	moveih	r1,>UcTimer2Ctrl			
	movei	r2,26			;27-1
	
setupVideoLoop

	rqldi	r0,0
	addi	r0,1
	addi	r1,1
	ld	r3
	subi	r2,1
	brts	setupVideoLoop
	st	r1,r3	;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
		
	jmpi	r7,0
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot
	nop		;delay slot	
	
;*********************************************************************
;* data
;*********************************************************************
	
videoDefault		;AD NAME					NEW				DEFAULT
	
	word	$0001	;10 VIDEO_ON					1				1 (ON)
	word	$0097	;11 HSYNC (D = 11 .. 0)				152-1				152-1
	word	$017f	;12 HSTART (D = 11 .. 0)			384-1				384-1
	word	$017d	;13 HMEMSTART (D = 11 .. 0)			382-1				382-1
	word	$071f	;14 HSTOP (D = 11 .. 0)				1824-1				1824-1
	word	$076f	;15 HTOTAL (D = 11 .. 0)			1904-1				1904-1
	word	$0002	;16 VSYNC (D = 10 .. 0)				3-1				3-1
	word	$001e	;17 VSTART (D = 10 .. 0)			31-1				31-1
	word	$03a2	;18 VSTOP  (D = 10 .. 0)			931-1				931-1
	word	$03a3	;19 VTOTAL  (D = 10 .. 0)			932-1				932-1
	word	$0000	;1a LC ADDER LOW				$0000				$0000
	word	$0080	;1b LC ADDER HIGH				$0080				$0040	
	word	$0000	;1c LC ADDER LATCH				X				X
	word	$0000	;1d LC START (10 .. 0) Pixeloffset		$0000				$0000	
	word	$0000	;1e						X				X
	word	$0000	;1f						X				X
	word	$0008	;20 HLOADSTART 					8				8
	word	$0170	;21 HLOADSTOP					360+8				180+8
	word	$001e	;22 VLOADSTART 					31-1				31-1
	word	$03a2	;23 VLOADSTOP 					931-1				931-1
	word	$0002	;24 VLOADNEXT					2				4
	word	$0000	;25 MEM_STARTADR_store low			$0000				$0000
	word	$f000	;26 MEM_STARTADR_store high			$f000				$f000
	word	$0000	;27 MEM_LINEOFFSET_store low			$0000				$0000
	word	$0000	;28 MEM_LINEOFFSET_store high			$0000				$0000
	word	$0002	;29 MEM_MODE_store 				2				2 (X1R5G5B5X1R5G5B5)
	word	$0000	;2a LATCH MEM_STARTADR/LINEOFFSET/MODE		X				X
	

audioDefault
	
	;
				;A =  8 7654 3210
	.data   $9,$0000	;9 =  0 0000 0000 	(inactivate interface)
	.data	$0,$0097	;0 =  0 1001 0111	;left line in mute
	.data	$1,$0097	;1 =  0 1001 0111	;right line in mute
	.data	$2,$0079	;2 =  0 0111 1001	;+6db left out
	.data	$3,$0079	;3 =  0 0111 1001	;0db right out
	.data	$4,$0012	;4 =  0 0001 0010	;0=0 mic boost off;
							;1=1 enable line input mute
							;2=1 line input to adc
							;3=0 disable bypass
							;4=1 DAC select
							;5=0 side tone disable
							;76=0 -6db sidetone						
	.data	$5,$0000	;5 =  0 0000 0000	;DAC soft Mute off, no Filer
	.data	$6,$0067	;6 =  0 0110 0111 	;DAC Power, Output Power, Device Power on
	.data	$7,$0009	;7 =  0 0000 1001 	;left justified, 24 bit
	.data	$8,$001e	;8 =  0 0001 1110	;0=0 normal mode
							;1=1 bosr (384/192)
							;5432=0111 96khz
							;78=00 no clk dividing	
	.data   $9,$0001	;9 =  0 0000 0001 	(activate interface)
	.data	$ff,$0000	;stop
	
;******************************
;* iToECopy
;*
;* r0 source
;* r2:r1	dest
;* r4 count - 1 
;* 
;* waste r0 .. r4
;*	

iToECopy

	
iToECopyLoop
	
	rqldi	r0,0
	addi	r0,1
	subi	r4,1
	ld	r3
	brts	iToECopyLoop
	esadr	r2,r1		;delay slot
	est	r3,0		;delay slot
	addi	r1,1		;delay slot
	addtqi	r2,r2,0		;delay slot
	
	jmpi	r7,0
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	nop			;delay slot
	
;******************************
;* extCopy8
;*
;* r1:r0 source
;* r3:r2	dest
;* r4 count - 1 (8 words per count)
;* 
		
extCopy8	

	push	r5
	push	r6
	
extCopy8Loop
	esadr	r1,r0
	erqldi	0
	erqldi	1
	erqldi	2
	erqldi	3
	erqldi	4
	erqldi	5
	erqldi	6
	erqldi	7
	
	esadr	r3,r2
	eld	r5
	eld	r6
	est	r5,0
	est	r6,1
	eld	r5
	eld	r6
	est	r5,2
	est	r6,3
	eld	r5
	eld	r6
	est	r5,4
	est	r6,5
	eld	r5
	eld	r6
	est	r5,6
	est	r6,7
	

	subi	r4,1
	brts	extCopy8Loop
	addi	r0,8		;delay slot
	addtqi	r1,r1,0		;delay slot
	addi	r2,8		;delay slot
	addtqi	r3,r3,0		;delay slot
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r6	;delay slot
	pop	r7     	;delay slot
	nop		;delay slot
	nop		;delay slot	
	
;******************************
;*
;* udiv16
;* 
;* r0 	 	divident
;* r1		divisor
;*
;* return
;*
;* r2		qoutient
;* r3		remainder
;*
;* needs 34 cycles
;*
	
udiv16	
	udivinit	15
	udivsdd		r0
	udivsdv		r1
	
	movei	r0,3	;(3+1)*4 = 16
	cli		;disable irq
udiv16Loop	
	subi	r0,1
	brts	udiv16Loop
	udivstep	;delay slot	!!!! note udivstep is not irq save, so use cli/sei lock
	udivstep        ;delay slot
	udivstep        ;delay slot
	udivstep        ;delay slot

	jmpi	r7,0
	nop			;delay slot
	udivgq		r2	;delay slot		get qoutient
	udivgr		r3	;delay slot		get remainder
	sei			;delay slot		enable irqs	
	
;******************************
;*
;* drawPixel
;* 
;* r0 	 	x
;* r1		y (wasted)
;* r2		low screen adr (wasted) 
;* r3		high screen adr (wasted)
;* r4		pixel value	
;* r5		screen width (wasted)
;*

drawPixel
	
	
	nop
	mul	r1,r1,r5	;y*width
	gmulhi	r5			
	add	r2,r2,r1	
	addt	r3,r3,r5
	add	r2,r2,r0
	jmpi	r7,0
	addtqi	r3,r3,0		;delay slot
	nop			;delay slot
	esadr	r3,r2		;delay slot
	est	r4,0		;delay slot
	
;*********************************************************************
;* data
;*********************************************************************

	


	
channel0
	
	word	$ffff				;channelRepeatStart		
	word	0                            	 ;channelRepeatLength		
	word	$3fff                           ;channelIncrement		
	word	63                              ;channelVolume			
	word	3530                            ;channelLength			
	word	0	;fractation             ;channelCurrentPositionLow	
	word	0	;position               ;channelCurrentPositionHigh	
	word	$e340                     	;channelSampleAdrLow		
	word	$f009                    	;channelSampleAdrHigh		

channel0Buffer

	.space	96
	
channel1
	
	word	$ffff				;channelRepeatStart		
	word	0                             ;channelRepeatLength		
	word	$3eff                           ;channelIncrement		
	word	63                              ;channelVolume			
	word	3530                            ;channelLength			
	word	0	;fractation             ;channelCurrentPositionLow	
	word	0	;position               ;channelCurrentPositionHigh	
	word	$e340                     	;channelSampleAdrLow		
	word	$f009                    	;channelSampleAdrHigh		

channel1Buffer

	.space	96

channel2
	
	word	$ffff				;channelRepeatStart		
	word	0                             ;channelRepeatLength		
	word	$3cff                           ;channelIncrement		
	word	63                              ;channelVolume			
	word	3530                            ;channelLength			
	word	0	;fractation             ;channelCurrentPositionLow	
	word	0	;position               ;channelCurrentPositionHigh	
	word	$e340                     	;channelSampleAdrLow		
	word	$f009                    	;channelSampleAdrHigh		

channel2Buffer

	.space	96

channel3
	
	word	$ffff				;channelRepeatStart		
	word	0                             ;channelRepeatLength		
	word	$3dff                           ;channelIncrement		
	word	63                              ;channelVolume			
	word	3530                            ;channelLength			
	word	0	;fractation             ;channelCurrentPositionLow	
	word	0	;position               ;channelCurrentPositionHigh	
	word	$e340                    	;channelSampleAdrLow		
	word	$f009                    	;channelSampleAdrHigh		

channel3Buffer

	.space	96

channel4
	
	word	$ffff				;channelRepeatStart		
	word	0                             ;channelRepeatLength		
	word	$3bff                           ;channelIncrement		
	word	63                              ;channelVolume			
	word	3530                            ;channelLength			
	word	0	;fractation             ;channelCurrentPositionLow	
	word	0	;position               ;channelCurrentPositionHigh	
	word	$e340                     	;channelSampleAdrLow		
	word	$f009                    	;channelSampleAdrHigh		

channel4Buffer

	.space	96

channel5
	
	word	$ffff				;channelRepeatStart		
	word	0                            	;channelRepeatLength		
	word	$3aff                           ;channelIncrement		
	word	63                              ;channelVolume			
	word	3530                            ;channelLength			
	word	0	;fractation             ;channelCurrentPositionLow	
	word	0	;position               ;channelCurrentPositionHigh	
	word	$e340                     	;channelSampleAdrLow		
	word	$f009                    	;channelSampleAdrHigh		

channel5Buffer

	.space	96	

textHeader	

	.string		"Sound Test 6 channels (3->L 3->R) 32KHz"
	word	0

i2cSetupString
	.string		"i2c write value %x to address %x result %x"
	word	0

textPeriode

	.string		"periode %u"
	word	0
	
textReaded
	.space	32	
	
displayFrame	

	.data	$f000,$0000

drawFrame	

	.data	$f004,$f1a0	
	
sampleDataIRAM
	
	.incdir	"F:\git\goldmomo_endlos\sfx"
	.incbin	"sample_length_3530_repeatStart_3372_repeatLength_158"
	
		
	.def	sampleData	$f009e340
	.def	sampleLength	1765
	.def	fontDataROM	$e0017f68
	.def	fontDataRAM	$f009ea25
	
