/**
	\file shellAsm.s
	
*/
#include <vsrv.h>
#include <vstypes.h>
#include "sdram.h"

#ifdef ASM
/*
int SdRamWrite32N(register const u_int16 __i0 *d, register u_int16 __reg_a1 n);
*/
	.sect code,SdRamWrite32N
	.export _SdRamWrite32N
_SdRamWrite32N:
	add a1,ones,a1;	ldy (i6)+1,null
	stx c0,(I6)+1;	sty lc,(I6)
	stx le,(I6)+1;	sty ls,(I6)

	ldc SDRAM_WRITE_LWORDS-1-1,i7
	loop i7,$7-1
	ldc $3,ls
	stx c1,(i6);	sty lc,(i6)

	ldc SDRAM_ST_TX_EMPTY,c0
	jns $9
	ldc SDRAM_ST,i7

	ldy (i7),a0
	and a0,c0,a0

$1:
	ldy (i7),a0
	jzs $1
	and a0,c0,a0;	ldy (i6),lc

	ldx (i0)+1,a0; ldy (i7)+(SDRAM_DATA_HI-SDRAM_ST),null

	// Even though it might not look like it,
	// between $3 and $7 is a 2-instruction hardware loop
	// that is run 7 times
$3:
	sty a0,(i7)+(SDRAM_DATA_LO-SDRAM_DATA_HI);	ldx (i0)+1,a0
	sty a0,(i7)+(SDRAM_DATA_HI-SDRAM_DATA_LO);	ldx (i0)+1,a0
$7:

	add a1,ones,a1;	sty a0,(i7)+(SDRAM_ST-SDRAM_DATA_HI)
	ldy (i7)+(SDRAM_DATA_LO-SDRAM_ST),c1;	ldx (i0)+1,a0
	jnc $1
	and c1,c0,a0; sty a0,(i7)+(SDRAM_ST-SDRAM_DATA_LO)

$9:
	and a0,null,a0;	ldx (i6)-1,c1

	ldx (I6)-1,le;	ldy (I6),ls
	jr
	ldx (I6)-1,c0;	ldy (I6),lc




/*
int SdRamRead32N(register __reg_c u_int32 wAddr, register __i0 u_int16 *d, register __a1 u_int16 n);
*/
 	.sect code,SdRamRead32N
	.export _SdRamRead32N
_SdRamRead32N:
	ldc SDRAM_CA_LO_ADDRLO_B,a0
	ashl c,a0,c;	ldx (i6)+1,null // addr <<= SDRAM_CA_LO_ADDRLO_B
	stx b0,(I6)+1;	sty b1,(I6)
	stx le,(I6)+1;	sty ls,(I6)
	stx i2,(I6)+1;	sty lc,(I6)
	stx d0,(I6)+1;	sty d1,(I6)
	and b1,null,b1
	ldc 16<<SDRAM_CA_LO_ADDRLO_B,b0

	ldc 7-1,a0
	loop a0,$8-1
	ldc $4,ls
	ldc MR_INT|MR_ZERO,mr0
	stx mr0,(i6);	sty lc,(i6)

	ldc SDRAM_CA_LO_CMD_READ,a0

	ldc SDRAM_DATA_HI,i5
	ldc SDRAM_CA_HI,i7

	add a1,ones,a1
	jns $9
	ldc SDRAM_ST_RX_32BIT_WORDS_AVAILABLE_MASK,d1
	
	or c0,a0,d0
$1:
	add c,b,c;	sty c1,(i7)+(SDRAM_CA_LO-SDRAM_CA_HI)	// wAddr += 16;
	ldx (i6),mr0;	sty d0,(i7)+(SDRAM_ST-SDRAM_CA_LO)	// mr0 zero set
	
$3:
	ldy (i7),d0
	jzs $3
	and d0,d1,d0;	ldy (i6),lc

	ldy (i5)+(SDRAM_DATA_LO-SDRAM_DATA_HI),d0;	ldx (i7)+(SDRAM_CA_HI-SDRAM_ST),null	

	// Even though it might not look like it,
	// between $4 and $8 is a 2-instruction hardware loop
	// that is run 7 times
$4:
	ldy (i5)+(SDRAM_DATA_HI-SDRAM_DATA_LO),d0;	stx d0,(i0)+1
	ldy (i5)+(SDRAM_DATA_LO-SDRAM_DATA_HI),d0;	stx d0,(i0)+1
$8:
	add a1,ones,a1;	stx d0,(i0)+1
	ldy (i5)+(SDRAM_DATA_HI-SDRAM_DATA_LO),d0
	jnc $1
	or c0,a0,d0;	stx d0,(i0)+1

$9:
	and a0,null,a0;	ldx (I6)-1,null
	ldx (I6)-1,d0;	ldy (I6),d1
	ldx (I6)-1,i2;	ldy (I6),lc
	ldx (I6)-1,le;	ldy (I6),ls
	jr
	ldx (I6)-1,b0;	ldy (I6),b1



	.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
