// File: /workspace/github_c_makefile_star2_O0/eridanhq[P]miraclelib/miraclelib.c
// Function: ad9173_freq
void ad9173_freq(uint64_t fLO, void *mapped_base)
{
	//uint64_t fDAC, c1, c2, M, N, X, Y, A, B; // need 64-bit computation
	uint64_t X, A, B; // need 64-bit computation
	int i;

	ad9173_freq_calc(fLO, &A, &B, &X); // frequency parameter calculations

	// spi words structure
	unsigned int spi_words[]  = {
		0x000840, 			// DAC0 page
		0x011300, 			// Clear DDSM_FTW_LOAD_ACK
		0x011400 | ( X        & 0xFF),  // X: DDSM_FTW[ 7: 0]
		0x011500 | ((X >>  8) & 0xFF),  // X: DDSM_FTW[15: 8]
		0x011600 | ((X >> 16) & 0xFF),  // X: DDSM_FTW[23:16]
		0x011700 | ((X >> 24) & 0xFF),  // X: DDSM_FTW[31:24]
		0x011800 | ((X >> 32) & 0xFF),  // X: DDSM_FTW[39:32]
		0x011900 | ((X >> 40) & 0xFF),  // X: DDSM_FTW[47:40]
		0x011C00, 			// DDSM_NCO_PHASE_OFFSET[ 7:0]
		0x011D00, 			// DDSM_NCO_PHASE_OFFSET[15:8]
		0x012400 | ( B        & 0xFF),	// B: DDSM_ACC_MODULUS[ 7: 0]
		0x012500 | ((B >>  8) & 0xFF),	// B: DDSM_ACC_MODULUS[15: 8]
		0x012600 | ((B >> 16) & 0xFF),	// B: DDSM_ACC_MODULUS[23:16]
		0x012700 | ((B >> 24) & 0xFF),	// B: DDSM_ACC_MODULUS[31:24]
		0x012800 | ((B >> 32) & 0xFF),	// B: DDSM_ACC_MODULUS[39:32]
		0x012900 | ((B >> 40) & 0xFF),	// B: DDSM_ACC_MODULUS[47:40]
		0x012A00 | ( A        & 0xFF),	// A: DDSM_ACC_DELTA[ 7: 0]
		0x012B00 | ((A >>  8) & 0xFF),	// A: DDSM_ACC_DELTA[15: 8]
		0x012C00 | ((A >> 16) & 0xFF),	// A: DDSM_ACC_DELTA[23:16]
		0x012D00 | ((A >> 24) & 0xFF),	// A: DDSM_ACC_DELTA[31:24]
		0x012E00 | ((A >> 32) & 0xFF),	// A: DDSM_ACC_DELTA[39:32]
		0x012F00 | ((A >> 40) & 0xFF),	// A: DDSM_ACC_DELTA[47:40]
		0x011301, 			// update datapath NCO & FTW words
	};

	int n = NELEMS(spi_words);
	write_reg_tx(32,0x1,mapped_base); // CS select bit
	for (i = 0; i<n; i++)
	{
		//printf("%2d: 0x%X\n", i, spi_words[i]);
		write_reg_tx(33,spi_words[i],mapped_base);
		usleep(500); // 500 usec pause
	}

	/*
	// Debug print statements
	printf("GCD of %" PRIu64 " and %" PRIu64 ": %" PRIu64 "\n", fLO, fDAC, c1);
	printf("M=%" PRIu64 " and N=%" PRIu64 "\n", M,N);
	printf("X=0x%" PRIx64 "\n", X);
	printf("M*2^48 = 0x%" PRIx64 "\n", (M<<48));
	printf("X*N    = 0x%" PRIx64 "\n", X*N);
	printf("Y=0x%" PRIx64 "\n", Y);
	printf("GCD of %" PRIu64 " and %" PRIu64 ": %" PRIu64 "\n", Y, N, c2);

	printf("A=0x%" PRIx64 "\n", A);
	printf("B=0x%" PRIx64 "\n", B);

	printf("Size of int64_t: %d bytes\n", sizeof(c1));
	*/
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
leaq -0x20(%rbp), %rsi
leaq -0x28(%rbp), %rdx
leaq -0x18(%rbp), %rcx
callq 0x1b40
movl $0x840, -0x90(%rbp)     # imm = 0x840
movl $0x11300, -0x8c(%rbp)   # imm = 0x11300
movq -0x18(%rbp), %rax
andq $0xff, %rax
orq $0x11400, %rax          # imm = 0x11400
movl %eax, -0x88(%rbp)
movq -0x18(%rbp), %rax
shrq $0x8, %rax
andq $0xff, %rax
orq $0x11500, %rax          # imm = 0x11500
movl %eax, -0x84(%rbp)
movq -0x18(%rbp), %rax
shrq $0x10, %rax
andq $0xff, %rax
orq $0x11600, %rax          # imm = 0x11600
movl %eax, -0x80(%rbp)
movq -0x18(%rbp), %rax
shrq $0x18, %rax
andq $0xff, %rax
orq $0x11700, %rax          # imm = 0x11700
movl %eax, -0x7c(%rbp)
movq -0x18(%rbp), %rax
shrq $0x20, %rax
andq $0xff, %rax
orq $0x11800, %rax          # imm = 0x11800
movl %eax, -0x78(%rbp)
movq -0x18(%rbp), %rax
shrq $0x28, %rax
andq $0xff, %rax
orq $0x11900, %rax          # imm = 0x11900
movl %eax, -0x74(%rbp)
movl $0x11c00, -0x70(%rbp)   # imm = 0x11C00
movl $0x11d00, -0x6c(%rbp)   # imm = 0x11D00
movq -0x28(%rbp), %rax
andq $0xff, %rax
orq $0x12400, %rax          # imm = 0x12400
movl %eax, -0x68(%rbp)
movq -0x28(%rbp), %rax
shrq $0x8, %rax
andq $0xff, %rax
orq $0x12500, %rax          # imm = 0x12500
movl %eax, -0x64(%rbp)
movq -0x28(%rbp), %rax
shrq $0x10, %rax
andq $0xff, %rax
orq $0x12600, %rax          # imm = 0x12600
movl %eax, -0x60(%rbp)
movq -0x28(%rbp), %rax
shrq $0x18, %rax
andq $0xff, %rax
orq $0x12700, %rax          # imm = 0x12700
movl %eax, -0x5c(%rbp)
movq -0x28(%rbp), %rax
shrq $0x20, %rax
andq $0xff, %rax
orq $0x12800, %rax          # imm = 0x12800
movl %eax, -0x58(%rbp)
movq -0x28(%rbp), %rax
shrq $0x28, %rax
andq $0xff, %rax
orq $0x12900, %rax          # imm = 0x12900
movl %eax, -0x54(%rbp)
movq -0x20(%rbp), %rax
andq $0xff, %rax
orq $0x12a00, %rax          # imm = 0x12A00
movl %eax, -0x50(%rbp)
movq -0x20(%rbp), %rax
shrq $0x8, %rax
andq $0xff, %rax
orq $0x12b00, %rax          # imm = 0x12B00
movl %eax, -0x4c(%rbp)
movq -0x20(%rbp), %rax
shrq $0x10, %rax
andq $0xff, %rax
orq $0x12c00, %rax          # imm = 0x12C00
movl %eax, -0x48(%rbp)
movq -0x20(%rbp), %rax
shrq $0x18, %rax
andq $0xff, %rax
orq $0x12d00, %rax          # imm = 0x12D00
movl %eax, -0x44(%rbp)
movq -0x20(%rbp), %rax
shrq $0x20, %rax
andq $0xff, %rax
orq $0x12e00, %rax          # imm = 0x12E00
movl %eax, -0x40(%rbp)
movq -0x20(%rbp), %rax
shrq $0x28, %rax
andq $0xff, %rax
orq $0x12f00, %rax          # imm = 0x12F00
movl %eax, -0x3c(%rbp)
movl $0x11301, -0x38(%rbp)   # imm = 0x11301
movl $0x17, -0x94(%rbp)
movq -0x10(%rbp), %rdx
movl $0x20, %edi
movl $0x1, %esi
callq 0x1640
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x94(%rbp), %eax
jge 0x1e56
movslq -0x2c(%rbp), %rax
movl -0x90(%rbp,%rax,4), %esi
movq -0x10(%rbp), %rdx
movl $0x21, %edi
callq 0x1640
movl $0x1f4, %edi            # imm = 0x1F4
callq 0x1120
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1e1d
addq $0xa0, %rsp
popq %rbp
retq
nop