/**
	\file auiadcAsm.s

*/
#include <vs1005h.h>
#include <vstypes.h>
#include <aucommon.h>

#ifdef ASM


#define IWR AIN_WR_OFFSET
#define IRD AIN_RD_OFFSET
#define IBUF AIN_BUF_OFFSET
#define IBUFSIZE AIN_BUFSIZE_OFFSET
#define IMODIFIER AIN_MODIFIER_OFFSET
#define IFLAGS AIN_FLAGS_OFFSET
#define IERROR0 AIN_ERROR0_OFFSET
#define IERROR1 AIN_ERROR1_OFFSET
#define IRATEL AIN_SAMPLE_RATE_OFFSET
#define IRATEH AIN_SAMPLE_RATE_OFFSET
#define ICOUNTERL AIN_SAMPLE_COUNTERL_OFFSET
#define ICOUNTERH AIN_SAMPLE_COUNTERH_OFFSET
#define IOVERL AIN_OVERFLOWL_OFFSET
#define IOVERH AIN_OVERFLOWH_OFFSET


#if 0
	.sect data_x,auxi_x
	.export _auxi
_auxi:
	.word 0,0

	.sect code,GetI6
	.export _GetI6
_GetI6:
	jr
	mv i6,a0
#endif



	.sect code,AdcInterrupt
	.export _AdcInterruptVector
_AdcInterruptVector:
	jmpi _AdcInterrupt,(i6)+1
	.export _AdcInterrupt
_AdcInterrupt:
	stx I2,(I6)+1;	sty MR0,(i6)
	stx I0,(I6)+1;	sty I7,(i6)
	ldc FAUDIO_SEL_AD12_LO,i7
	.import _audioIn, _audioOut
CommonInterrupt:
	ldc _audioIn+IFLAGS,i0
	stx A2,(I6)+1;	sty B2,(i6)
	stx A0,(I6)+1;	sty A1,(i6)
	stx B0,(I6)+1;	sty B1,(i6)
	stx I5,(I6);	sty i3,(I6)

	ldc MR_INT,mr0

	ldc AIN_32BIT,b0
	ldc FAUDIO_SEL,i5
	ldx (i0)+(-IFLAGS+IWR),a0; sty i7,(i5)+(FAUDIO_L-FAUDIO_SEL)	// a0 = flags
	and a0,b0,a0; ldx (i7)+(FAUDIO_SEL_AD12_HI-FAUDIO_SEL_AD12_LO),null
	ldx (i0)+(-IWR+IMODIFIER),i2; ldy (i5)+(FAUDIO_R-FAUDIO_L),b0 // i2 = wr
	ldx (i0)+(-IMODIFIER+IERROR0),i3; ldy (i5)+(FAUDIO_SEL-FAUDIO_R),a0 // i3=mod
	jzs $11	// Jump if 16-bit samples
	sty i7,(i5)+(FAUDIO_L-FAUDIO_SEL)

$10:
	// 32-bit samples
	ldy (i5)+(FAUDIO_R-FAUDIO_L),b1; ldx (i0)+(-IERROR0+ICOUNTERL),null
	sty b0,(i2)*;	ldx (i0)+(-ICOUNTERL+ICOUNTERH),b0
	sty b1,(i2)*;	ldx (i0)+(-ICOUNTERH+ICOUNTERH),b1
	ldy (i5)+(FAUDIO_SEL-FAUDIO_R),a1;	sub b,ones,b
	sty a0,(i2)*;	stx b1,(i0)+(-ICOUNTERH+ICOUNTERL)
	j $12
	sty a1,(i2)*;	stx b0,(i0)+(-ICOUNTERL+IRD)

$11:
	// 16-bit samples
	mv a0,i7
	ldy (i5)+(FAUDIO_R-FAUDIO_L),b1
	and a1,null,a1;	ldx (i0),a0	// a0 = error[0]
	add b,a,a;	ldy (i5)+(FAUDIO_SEL-FAUDIO_R),b1 // Error propagation
	sat a,a;	mv i7,b0	// Needs to saturate result
	sty a1,(i2)*;	stx a0,(i0)+(-IERROR0+IERROR1)
	and a1,null,a1;	ldx (i0)+(-IERROR1+ICOUNTERL),a0	// a0 = error[1]
	add b,a,a;	ldx (i0)+(-ICOUNTERL+ICOUNTERH),b0	// Error propagation
	sat a,a;	ldx (i0)+(-ICOUNTERH+IERROR1),b1	// Needs to saturate result
	sub b,ones,b;	stx a0,(i0)+(-IERROR1+ICOUNTERH)
	sty a1,(i2)*;	stx b1,(i0)+(-ICOUNTERH+ICOUNTERL)
	stx b0,(i0)+(-ICOUNTERL+IRD)

$12:
	ldx (i0)+(-IRD+IWR),a0;	ldy (I6),I3
	mv i2,b1
	
	sub a0,b1,b1;	ldx (I6)-1,I5
	ldx (I6)-1,B0	; ldy (I6),B1
	jzs $20
	ldx (I6)-1,A0	; ldy (I6),A1

	stx i2,(i0)	// Update audioIn.wr if buffer not full

$13:
	ldx (I6)-1,A2	; ldy (I6),B2
	ldx (I6)-1,I0	; ldy (I6),I7
	ldy (I6),MR0
	ldc INT_GLOB_ENA,i2
	reti
	ldx (i6)-1,I2;	sty i2,(i2)

	// Overflow
$20:
	ldx (i6)+1,null;	ldy (i0)+(-IWR+IERROR1),null
	stx a0,(i6);		ldy (i0)+(-IERROR1+IOVERL),null
	ldx (i0)+(-IOVERL+IOVERH),a0;	sty a1,(i6)
	sub a0,ones,a0;		ldx (i0)+(-IOVERH+IOVERL),a1
	addc a1,null,a1;	stx a0,(i0)+(-IOVERL+IOVERH)
	     			stx a1,(i0)+(-IOVERH+IOVERL)
	j $13
	ldx (i6)-1,a0;	ldy (i6),a1


	.sect code,Dec6Interrupt
	.export _Dec6InterruptVector
_Dec6InterruptVector:
	jmpi _Dec6Interrupt,(i6)+1
	.export _Dec6Interrupt
_Dec6Interrupt:
	stx I2,(I6)+1;	sty MR0,(i6)
	stx I0,(I6)+1;	sty I7,(i6)
	j CommonInterrupt
	ldc FAUDIO_SEL_DEC6_L,i7




#endif /* ASM */

	.end

#if 0
	/********* EVERYTHING FROM NOW ON IS PURELY DECORATIONAL!!! **********/

/*
	void Generic(void) - 2018 edition
*/
 	.sect code,Generic
	.export _Generic
_Generic:
	ldx (i6)+1,null
	stx i0,(I6)+1;	sty i1,(I6)
	stx i2,(I6)+1;	sty i3,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	stx lr0,(I6)+1;	sty lc,(I6)
	stx a0,(I6)+1;	sty a1,(I6)
	stx b0,(I6)+1;	sty b1,(I6)
	stx c0,(I6)+1;	sty c1,(I6)
	stx d0,(I6)+1;	sty d1,(I6)
	stx i4,(I6)

	ldx (I6)-1,i4
	ldx (I6)-1,d0;	ldy (I6),d1
	ldx (I6)-1,c0;	ldy (I6),c1
	ldx (I6)-1,b0;	ldy (I6),b1
	ldx (I6)-1,a0;	ldy (I6),a1
	ldx (I6)-1,lr0;	ldy (I6),lc
	ldx (I6)-1,le;	ldy (I6),ls
	ldx (I6)-1,i2;	ldy (I6),i3
	jr
	ldx (I6)-1,i0;	ldy (I6),i1
#endif
