// File: /workspace/github_cpp_makefile_star2_O2/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 $0x438, %rsp            # imm = 0x438
movq %rsi, %rbx
movl %edi, %ebp
leaq 0x8(%rsp), %rdi
pushq $0x9
popq %rsi
leaq 0x30(%rsp), %rdx
callq 0x382a
cmpl $0x3, %ebp
jne 0x374a
movq 0x8(%rbx), %rsi
leaq 0x30(%rsp), %rdi
pushq $0x8
popq %rdx
callq 0x33c0
movq 0x10(%rbx), %rsi
leaq 0x238(%rsp), %rdi
pushq $0x14
popq %rdx
callq 0x3260
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x387c
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0x3898
leaq 0x20(%rsp), %r14
leaq 0x4fcc(%rip), %r15      # 0x8596
leaq 0x4fdd(%rip), %r12      # 0x85ae
xorl %ebp, %ebp
cmpq $0x3, %rbp
je 0x377d
movq %r14, %rdi
leaq 0x4f98(%rip), %rsi      # 0x857f
callq 0x396a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3a8c
movq %rax, %rdi
callq 0x3be0
cvtss2sd %xmm0, %xmm0
divsd 0x49fd(%rip), %xmm0     # 0x8008
cvttsd2si %xmm0, %eax
cmpw $0xff, %ax
movl $0xff, %ecx
cmovael %ecx, %eax
movq 0x8(%rsp), %rcx
movb %al, (%rcx,%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x396a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3a8c
movq %rax, %rdi
movq %r12, %rsi
callq 0x396a
movq %rax, %rdi
callq 0x3bfc
testb %al, %al
je 0x372d
movq %r14, %rdi
movq %r15, %rsi
callq 0x396a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3a8c
movq %rax, %rdi
leaq 0x4f42(%rip), %rsi      # 0x85b6
callq 0x396a
movq %rax, %rdi
callq 0x3c16
xorl %edx, %edx
movw $0xa, %cx
divw %cx
movq 0x8(%rsp), %rcx
movb %al, 0x3(%rcx,%rbp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x396a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3a8c
movq %rax, %rdi
leaq 0x4f0c(%rip), %rsi      # 0x85bf
callq 0x396a
movq %rax, %rdi
callq 0x3c32
movl %eax, %r13d
movq %r14, %rdi
movq %r15, %rsi
callq 0x396a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3a8c
movq %rax, %rdi
leaq 0x4eed(%rip), %rsi      # 0x85d0
callq 0x396a
movq %rax, %rdi
callq 0x3bfc
movl %eax, %ebx
movq %r14, %rdi
movq %r15, %rsi
callq 0x396a
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3a8c
movq %rax, %rdi
movq %r12, %rsi
callq 0x396a
movq %rax, %rdi
callq 0x3bfc
xorb $0x1, %bl
shlb $0x3, %bl
orb %r13b, %bl
xorb $0x1, %al
shlb $0x4, %al
orb %bl, %al
jmp 0x3739
movq 0x8(%rsp), %rax
movb $-0x1, 0x3(%rax,%rbp)
movb $-0x1, %al
movq 0x8(%rsp), %rcx
movb %al, 0x6(%rcx,%rbp)
incq %rbp
jmp 0x35d3
movq 0xa887(%rip), %rdi      # 0xdfd8
leaq 0x4e0c(%rip), %rsi      # 0x8564
callq 0x3220
movq (%rbx), %rsi
movq %rax, %rdi
callq 0x3220
movq 0xa869(%rip), %rdi      # 0xdfd8
leaq 0x4df6(%rip), %rsi      # 0x856c
callq 0x3220
jmp 0x37c6
xorl %r14d, %r14d
leaq 0x238(%rsp), %rbx
cmpq $0x9, %r14
je 0x37a5
movq 0x8(%rsp), %rax
movsbl (%rax,%r14), %esi
movq %rbx, %rdi
callq 0x3280
incq %r14
jmp 0x3788
leaq 0x20(%rsp), %rdi
callq 0x3c4c
leaq 0x238(%rsp), %rdi
callq 0x3300
leaq 0x30(%rsp), %rdi
callq 0x3090
leaq 0x8(%rsp), %rdi
callq 0x3e70
xorl %eax, %eax
addq $0x438, %rsp            # imm = 0x438
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x37f4
movq %rax, %rbx
jmp 0x380e
jmp 0x37ed
movq %rax, %rbx
jmp 0x3818
jmp 0x37f4
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x3c4c
leaq 0x238(%rsp), %rdi
callq 0x3300
leaq 0x30(%rsp), %rdi
callq 0x3090
leaq 0x8(%rsp), %rdi
callq 0x3e70
movq %rbx, %rdi
callq 0x33b0