// File: /workspace/github_cpp_makefile_star2_O3/SYZYGYfpga[P]syzygy-tools/dna-tools/sequencer-writer.cpp
// Function: main
int main(int argc, char *argv[])
{
	// The SYZYGY AVR Firmware sequencer configuration data is stored in 9
	// bytes in the AVR EEPROM.
	std::vector<uint8_t> sequencer_data(9);

	uint8_t temp_enable_config;

	// Print usage if there are not enough or too many arguments
	if ((argc < 3) || (argc > 3)) {
		std::cout << "USAGE: " << argv[0];
		std::cout << " in_file out_file\n";
		return 0;
	}

	std::ifstream input_file(argv[1]);
	std::ofstream output_file(argv[2], std::ios::out | std::ios::binary);

	json sequencer_json;

	// Parse the input data
	input_file >> sequencer_json;

	for (int i = 0; i < 3; i++) {
		// Scale the input threshold value for the ADCs input range
		uint16_t threshold = (uint16_t) (sequencer_json["sequencer_threshold_mv"][i].get<float>() / THRESHOLD_SCALE);

		// For any input threshold value above the ADCs input range, cap the value at the maximum allowed
		if (threshold > 0xFF) {
			threshold = 0xFF;
		}

		sequencer_data[i + SEQ_THRESHOLD_OFFSET] = (uint8_t) threshold;

		if (sequencer_json["sequencer_enable_config"][i]["enabled"].get<bool>()) {
			// Handle Enable output delay times
			// TODO: Check bounds and error...
			sequencer_data[i + SEQ_DELAY_OFFSET] =
				(uint8_t) (sequencer_json["sequencer_enable_config"][i]["delay_ms"].get<uint16_t>() / 10);

			// Handle Enable output configuration
			temp_enable_config = 0;
			temp_enable_config |=
				sequencer_json["sequencer_enable_config"][i]["input_dependency"].get<uint8_t>();

			temp_enable_config |=
				sequencer_json["sequencer_enable_config"][i]["active_high"].get<bool>() ? 0 : ENABLE_ACTIVE_LOW;

			temp_enable_config |=
				sequencer_json["sequencer_enable_config"][i]["enabled"].get<bool>() ? 0 : ENABLE_DISABLED;
			
			sequencer_data[i + SEQ_ENABLE_CONFIG_OFFSET] = temp_enable_config;
		} else {
			sequencer_data[i + SEQ_DELAY_OFFSET] = 0xFF;
			sequencer_data[i + SEQ_ENABLE_CONFIG_OFFSET] = 0xFF;
		}
	}

	for (int i = 0; i < 9; i++) {
		output_file << sequencer_data[i];
	}

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x428, %rsp            # imm = 0x428
movq %rsi, %r14
movl %edi, %ebp
movl $0x9, %edi
callq 0x3230
movq %rax, %rbx
movb $0x0, (%rax)
movq $0x0, 0x1(%rax)
cmpl $0x3, %ebp
jne 0x3a2d
movq 0x8(%r14), %rsi
leaq 0x220(%rsp), %rdi
movl $0x8, %edx
callq 0x33a0
movq 0x10(%r14), %rsi
leaq 0x20(%rsp), %rdi
movl $0x14, %edx
callq 0x3260
leaq 0x10(%rsp), %r14
movb $0x0, (%r14)
movq $0x0, 0x8(%r14)
movq %r14, %rdi
callq 0x3fde
movq %r14, %rdi
callq 0x3fde
leaq 0x220(%rsp), %rdi
movq %r14, %rsi
callq 0x3afc
xorl %r14d, %r14d
leaq 0x10(%rsp), %r12
leaq 0xc(%rsp), %r13
movq %r12, %rdi
leaq 0x5d5b(%rip), %rsi      # 0x956f
callq 0x3c80
movq %rax, %rdi
movq %r14, %rsi
callq 0x3e0c
movq %rax, %rdi
movq %r13, %rsi
callq 0x7ed8
xorps %xmm0, %xmm0
cvtss2sd 0xc(%rsp), %xmm0
divsd 0x57c8(%rip), %xmm0     # 0x9008
cvttsd2si %xmm0, %eax
movzwl %ax, %ecx
movl $0xff, %edx
cmpl %edx, %ecx
cmovael %edx, %eax
movb %al, (%rbx,%r14)
movq %r12, %rdi
leaq 0x5d27(%rip), %rsi      # 0x9586
callq 0x3c80
movq %rax, %rdi
movq %r14, %rsi
callq 0x3e0c
movq %rax, %rdi
leaq 0x5d25(%rip), %rsi      # 0x959e
callq 0x3c80
movq %rax, %rdi
movq %r13, %rsi
callq 0x8023
cmpb $0x1, 0xc(%rsp)
jne 0x399a
movq %r12, %rdi
leaq 0x5ce8(%rip), %rsi      # 0x9586
callq 0x3c80
movq %rax, %rdi
movq %r14, %rsi
callq 0x3e0c
movq %rax, %rdi
leaq 0x5cee(%rip), %rsi      # 0x95a6
callq 0x3c80
movq %rax, %rdi
movq %r13, %rsi
callq 0x811a
movzwl 0xc(%rsp), %eax
imull $0xcccd, %eax, %eax     # imm = 0xCCCD
shrl $0x13, %eax
movb %al, 0x3(%rbx,%r14)
movq %r12, %rdi
leaq 0x5ca1(%rip), %rsi      # 0x9586
callq 0x3c80
movq %rax, %rdi
movq %r14, %rsi
callq 0x3e0c
movq %rax, %rdi
leaq 0x5cb0(%rip), %rsi      # 0x95af
callq 0x3c80
movq %rax, %rdi
movq %r13, %rsi
callq 0x8238
movb 0xc(%rsp), %r15b
movq %r12, %rdi
leaq 0x5c68(%rip), %rsi      # 0x9586
callq 0x3c80
movq %rax, %rdi
movq %r14, %rsi
callq 0x3e0c
movq %rax, %rdi
leaq 0x5c88(%rip), %rsi      # 0x95c0
callq 0x3c80
movq %rax, %rdi
movq %r13, %rsi
callq 0x8023
movb 0xc(%rsp), %bpl
movq %r12, %rdi
leaq 0x5c2f(%rip), %rsi      # 0x9586
callq 0x3c80
movq %rax, %rdi
movq %r14, %rsi
callq 0x3e0c
movq %rax, %rdi
leaq 0x5c2d(%rip), %rsi      # 0x959e
callq 0x3c80
movq %rax, %rdi
movq %r13, %rsi
callq 0x8023
xorb $0x1, %bpl
shlb $0x3, %bpl
orb %r15b, %bpl
movb 0xc(%rsp), %al
xorb $0x1, %al
shlb $0x4, %al
orb %bpl, %al
jmp 0x39a2
movb $-0x1, 0x3(%rbx,%r14)
movb $-0x1, %al
movb %al, 0x6(%rbx,%r14)
incq %r14
cmpq $0x3, %r14
jne 0x380a
xorl %r12d, %r12d
leaq 0x20(%rsp), %r14
leaq 0xc(%rsp), %r15
movb (%rbx,%r12), %al
movb %al, 0xc(%rsp)
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rsi
callq 0x3280
incq %r12
cmpq $0x9, %r12
jne 0x39c1
leaq 0x10(%rsp), %rdi
callq 0x3fbc
movq 0xa5d5(%rip), %rax      # 0xdfc8
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x28(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x20(%rsp,%rcx)
callq 0x31e0
leaq 0x118(%rsp), %rdi
callq 0x30c0
leaq 0x220(%rsp), %rdi
callq 0x3080
jmp 0x3a9c
movq 0xa5a4(%rip), %r15      # 0xdfd8
leaq 0x5b19(%rip), %rsi      # 0x9554
movl $0x7, %edx
movq %r15, %rdi
callq 0x3280
movq (%r14), %r14
testq %r14, %r14
je 0x3a6c
movq %r14, %rdi
callq 0x3120
movq 0xa579(%rip), %rdi      # 0xdfd8
movq %r14, %rsi
movq %rax, %rdx
callq 0x3280
jmp 0x3a84
movq (%r15), %rax
movq -0x18(%rax), %rax
leaq (%r15,%rax), %rdi
movl 0x20(%r15,%rax), %esi
orl $0x1, %esi
callq 0x3350
movq 0xa54d(%rip), %rdi      # 0xdfd8
leaq 0x5aca(%rip), %rsi      # 0x955c
movl $0x12, %edx
callq 0x3280
movq %rbx, %rdi
callq 0x3210
xorl %eax, %eax
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x3ac8
movq %rax, %r14
jmp 0x3adf
jmp 0x3ac1
movq %rax, %r14
jmp 0x3aec
jmp 0x3ac8
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x3fbc
leaq 0x20(%rsp), %rdi
callq 0x32f0
leaq 0x220(%rsp), %rdi
callq 0x3080
movq %rbx, %rdi
callq 0x3210
movq %r14, %rdi
callq 0x3380