// File: /workspace/github_c_makefile_star2_O1/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 %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x60, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movabsq $0x23c346000, %r15      # imm = 0x23C346000
movq %r15, %rsi
callq 0x17d7
movq %rax, %rcx
movq %r14, %rax
xorl %edx, %edx
divq %rcx
movq %rax, %rsi
movq %r15, %rax
xorl %edx, %edx
divq %rcx
movq %rax, %r15
shlq $0x30, %rsi
movq %rsi, %rax
xorl %edx, %edx
divq %r15
movq %rax, %r14
movq %rdx, %r12
xorl %r13d, %r13d
movq %rdx, %rdi
movq %r15, %rsi
callq 0x17d7
movq %rax, %rsi
movq %r12, %rax
xorl %edx, %edx
divq %rsi
movq %rax, %rcx
movq %r15, %rax
xorl %edx, %edx
divq %rsi
movabsq $0x1130000000840, %rdx  # imm = 0x1130000000840
movq %rdx, (%rsp)
movl $0xff, %edx
movl %r14d, %esi
andl %edx, %esi
orl $0x11400, %esi          # imm = 0x11400
movl %esi, 0x8(%rsp)
movl %r14d, %esi
shrl $0x8, %esi
andl %edx, %esi
orl $0x11500, %esi          # imm = 0x11500
movl %esi, 0xc(%rsp)
movl %r14d, %esi
shrl $0x10, %esi
andl %edx, %esi
orl $0x11600, %esi          # imm = 0x11600
movl %esi, 0x10(%rsp)
movl %r14d, %esi
shrl $0x18, %esi
orl $0x11700, %esi          # imm = 0x11700
movl %esi, 0x14(%rsp)
movq %r14, %rsi
shrq $0x20, %rsi
andl %edx, %esi
orl $0x11800, %esi          # imm = 0x11800
movl %esi, 0x18(%rsp)
shrq $0x28, %r14
andl %edx, %r14d
orl $0x11900, %r14d         # imm = 0x11900
movl %r14d, 0x1c(%rsp)
movabsq $0x11d0000011c00, %rsi  # imm = 0x11D0000011C00
movq %rsi, 0x20(%rsp)
movl %eax, %esi
andl %edx, %esi
orl $0x12400, %esi          # imm = 0x12400
movl %esi, 0x28(%rsp)
movl %eax, %esi
shrl $0x8, %esi
andl %edx, %esi
orl $0x12500, %esi          # imm = 0x12500
movl %esi, 0x2c(%rsp)
movl %eax, %esi
shrl $0x10, %esi
andl %edx, %esi
orl $0x12600, %esi          # imm = 0x12600
movl %esi, 0x30(%rsp)
movl %eax, %esi
shrl $0x18, %esi
orl $0x12700, %esi          # imm = 0x12700
movl %esi, 0x34(%rsp)
shrq $0x20, %rax
orl $0x12800, %eax          # imm = 0x12800
movl %eax, 0x38(%rsp)
movl $0x12900, 0x3c(%rsp)    # imm = 0x12900
movl %ecx, %eax
andl %edx, %eax
orl $0x12a00, %eax          # imm = 0x12A00
movl %eax, 0x40(%rsp)
movl %ecx, %eax
shrl $0x8, %eax
andl %edx, %eax
orl $0x12b00, %eax          # imm = 0x12B00
movl %eax, 0x44(%rsp)
movl %ecx, %eax
shrl $0x10, %eax
andl %edx, %eax
orl $0x12c00, %eax          # imm = 0x12C00
movl %eax, 0x48(%rsp)
movl %ecx, %eax
shrl $0x18, %eax
orl $0x12d00, %eax          # imm = 0x12D00
movl %eax, 0x4c(%rsp)
shrq $0x20, %rcx
orl $0x12e00, %ecx          # imm = 0x12E00
movl %ecx, 0x50(%rsp)
movabsq $0x1130100012f00, %rax  # imm = 0x1130100012F00
movq %rax, 0x54(%rsp)
movl $0x80000020, (%rbx)     # imm = 0x80000020
movl $0x1, 0xcc(%rbx)
movl (%rsp,%r13,4), %eax
movl $0x80000021, (%rbx)     # imm = 0x80000021
movl %eax, 0xcc(%rbx)
movl $0x1f4, %edi            # imm = 0x1F4
callq 0x1130
incq %r13
cmpq $0x17, %r13
jne 0x1a28
addq $0x60, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq