#include <vstypes.h>
#include <vsrv.h>


/*
   UARTRX interrupt routine.
   Never call explicitly!
   This routine calls void IntUartRxC(void);

   Set the interrupt vector from C as follows:

   extern u_int16 IntUartRxVector;
   [...]
   WriteIMem((void *)(0x20+INTV_UARTRX), ReadIMem((void *)(&IntUartRxVector)));

   After setting the interrupt vector, activate the interrupt as follows
     (example for interrupt priority 1):
   PERIP(INT_ENABLE0_LP) |= INTF_UARTRX;
   PERIP(INT_ENABLE0_HP) &= ~INTF_UARTRX;

   Before exiting your application, deactivate the interrupt as follows:
   PERIP(INT_ENABLE0_LP) &= ~INTF_UARTRX;
   PERIP(INT_ENABLE0_HP) &= ~INTF_UARTRX;
*/
	.sect code,IntEthVector
	.export _IntEthVector
_IntEthVector:
	jmpi _IntEthAsm,(i6)+1

	.sect code,IntEthAsm
	.export _IntEthAsm
_IntEthAsm:
#if 1
	stx i7,(i6)+1;  sty lr0,(i6)
        STNP lr1,(i6)+1
        stx le,(i6)+1;  sty lc,(i6)
        stx mr1,(i6)+2; sty i5,(i6)     // Save MR1, align pad
        ldc MR_INT|MR_LONG,mr0
        stx a2,(i6)+2;  sty b2,(i6)
        stx c2,(i6)+2;  sty d2,(i6)
        stx a0,(i6)+2;  sty a1,(i6)     // i7,i5,lr0 i0,i1,a0,a1,P
        stx b0,(i6)+2;  sty b1,(i6)
        stx c0,(i6)+2;  sty c1,(i6)
        stx d0,(i6)+2;  sty d1,(i6)
        add null,p,a
        stx a0,(i6)+2;  sty a1,(i6)
        stx i0,(i6)+1;  sty i1,(i6)

	.import _IntEthC
	call _IntEthC
	ldc MR_INT,mr0

	ldx (i6)-1,null
        ldx (i6)-2,i0;  ldy (i6),i1
        ldc MR_INT|MR_LONG,mr0  //wide mode, restore all bits
        ldx (i6)-2,a0;  ldy (i6),a1
        resp a0,a1
        ldx (i6)-2,d0;  ldy (i6),d1
        ldx (i6)-2,c0;  ldy (i6),c1
        ldx (i6)-2,b0;  ldy (i6),b1
        ldx (i6)-2,a0;  ldy (i6),a1
        ldx (i6)-2,c2;  ldy (i6),d2
        ldx (i6)-2,a2;  ldy (i6),b2
        //no ALU regs afterwards, so wide mode doesn't affect it
        ldx (i6)-1,mr0; ldy (i6),i5
        ldx (i6)-1,le;  ldy (i6),lc
        ldc INT_GLOB_ENA,i7
        STP i7,(i7);    LDNP (i6)-1,lr0   // lr1
        jr
        ldx (i6)-1,i7   ; ldy (i6),lr0  // i7  lr0
#else

	stx i7,(i6)+1;	sty mr0,(i6)
	stx lr0,(i6)+1;	sty i5,(i6)
	stx a2,(i6)+1;	sty b2,(i6)
	stx c2,(i6)+1;	sty d2,(i6)
	stx a1,(i6)+1;	sty a0,(i6)
	add null,p,a
	stx a1,(i6);	sty a0,(i6)

	.import _IntEthC
	call _IntEthC
	ldc MR_INT,mr0

	ldx (i6)-1,a1;	ldy (i6),a0
	resp a0,a1
	ldx (i6)-1,a1;	ldy (i6),a0
	ldx (i6)-1,c2;	ldy (i6),d2
	ldx (i6)-1,a2;	ldy (i6),b2
	ldx (i6)-1,lr0;	ldy (i6),i5
	ldy (I6),mr0
	ldc INT_GLOB_ENA,i7
	reti
	ldx (i6)-1,I7;	sty i7,(i7)
#endif


	.sect code,IntI2sVector
	.export _IntI2sVector
_IntI2sVector:
	jmpi _IntI2sAsm,(i6)+1

	.sect code,IntI2sAsm
	.export _IntI2sAsm
_IntI2sAsm:
	stx i7,(i6)+1;  sty lr0,(i6)
        STNP lr1,(i6)+1
        stx le,(i6)+1;  sty lc,(i6)
        stx mr1,(i6)+2; sty i5,(i6)     // Save MR1, align pad
        ldc MR_INT|MR_LONG,mr0
        stx a2,(i6)+2;  sty b2,(i6)
        stx c2,(i6)+2;  sty d2,(i6)
        stx a0,(i6)+2;  sty a1,(i6)     // i7,i5,lr0 i0,i1,a0,a1,P
        stx b0,(i6)+2;  sty b1,(i6)
        stx c0,(i6)+2;  sty c1,(i6)
        stx d0,(i6)+2;  sty d1,(i6)
        add null,p,a
        stx a0,(i6)+2;  sty a1,(i6)
        stx i0,(i6)+1;  sty i1,(i6)

	.import _IntI2sC
	call _IntI2sC
	ldc MR_INT,mr0

	ldx (i6)-1,null
        ldx (i6)-2,i0;  ldy (i6),i1
        ldc MR_INT|MR_LONG,mr0  //wide mode, restore all bits
        ldx (i6)-2,a0;  ldy (i6),a1
        resp a0,a1
        ldx (i6)-2,d0;  ldy (i6),d1
        ldx (i6)-2,c0;  ldy (i6),c1
        ldx (i6)-2,b0;  ldy (i6),b1
        ldx (i6)-2,a0;  ldy (i6),a1
        ldx (i6)-2,c2;  ldy (i6),d2
        ldx (i6)-2,a2;  ldy (i6),b2
        //no ALU regs afterwards, so wide mode doesn't affect it
        ldx (i6)-1,mr0; ldy (i6),i5
        ldx (i6)-1,le;  ldy (i6),lc
        ldc INT_GLOB_ENA,i7
        STP i7,(i7);    LDNP (i6)-1,lr0   // lr1
        jr
        ldx (i6)-1,i7   ; ldy (i6),lr0  // i7  lr0

	.end
