// File: 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
movq %rsp, %rbp
subq $0x560, %rsp            # imm = 0x560
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x29(%rbp), %rdi
movq %rdi, -0x478(%rbp)
callq 0x3ca0
movq -0x478(%rbp), %rdx
leaq -0x28(%rbp), %rdi
movl $0x9, %esi
callq 0x3cc0
jmp 0x36c0
leaq -0x29(%rbp), %rdi
callq 0x3d30
cmpl $0x3, -0x8(%rbp)
jl 0x36d9
cmpl $0x3, -0x8(%rbp)
jle 0x375d
movq 0x1d8f8(%rip), %rdi     # 0x20fd8
leaq 0x11239(%rip), %rsi     # 0x14920
callq 0x32d0
movq %rax, -0x480(%rbp)
jmp 0x36f5
movq -0x480(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x32d0
jmp 0x370a
movq 0x1d8c7(%rip), %rdi     # 0x20fd8
leaq 0x11210(%rip), %rsi     # 0x14928
callq 0x32d0
jmp 0x371f
movl $0x0, -0x4(%rbp)
movl $0x1, -0x44(%rbp)
jmp 0x3c77
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x29(%rbp), %rdi
callq 0x3d30
jmp 0x3c95
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x3c8c
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x250(%rbp), %rdi
movl $0x8, %edx
callq 0x34d0
jmp 0x3778
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x490(%rbp)
movl $0x10, %edi
movl $0x4, %esi
callq 0x3d50
movl %eax, -0x484(%rbp)
jmp 0x379e
movl -0x484(%rbp), %edx
movq -0x490(%rbp), %rsi
leaq -0x450(%rbp), %rdi
callq 0x3320
jmp 0x37b9
xorl %eax, %eax
movl %eax, %esi
leaq -0x460(%rbp), %rdi
movq %rdi, -0x498(%rbp)
callq 0x3d70
movq -0x498(%rbp), %rsi
leaq -0x250(%rbp), %rdi
callq 0x3db0
jmp 0x37e5
movl $0x0, -0x464(%rbp)
cmpl $0x3, -0x464(%rbp)
jge 0x3bee
leaq 0x11138(%rip), %rsi     # 0x1493b
leaq -0x460(%rbp), %rdi
callq 0x3ef0
movq %rax, -0x4a0(%rbp)
jmp 0x3818
movq -0x4a0(%rbp), %rdi
movslq -0x464(%rbp), %rsi
callq 0x4130
movq %rax, -0x4a8(%rbp)
jmp 0x3834
movq -0x4a8(%rbp), %rdi
callq 0x43c0
movss %xmm0, -0x4ac(%rbp)
jmp 0x384a
movss -0x4ac(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0x107aa(%rip), %xmm1    # 0x14008
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, -0x466(%rbp)
movzwl -0x466(%rbp), %eax
cmpl $0xff, %eax
jle 0x38c0
movw $0xff, -0x466(%rbp)
jmp 0x38c0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x3c69
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x460(%rbp), %rdi
callq 0x44a0
leaq -0x450(%rbp), %rdi
callq 0x33e0
jmp 0x3c69
movb -0x466(%rbp), %al
movb %al, -0x4b9(%rbp)
movslq -0x464(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x43f0
movb -0x4b9(%rbp), %cl
movb %cl, (%rax)
leaq 0x11067(%rip), %rsi     # 0x14952
leaq -0x460(%rbp), %rdi
callq 0x3ef0
movq %rax, -0x4b8(%rbp)
jmp 0x3900
movq -0x4b8(%rbp), %rdi
movslq -0x464(%rbp), %rsi
callq 0x4130
movq %rax, -0x4c8(%rbp)
jmp 0x391c
movq -0x4c8(%rbp), %rdi
leaq 0x11040(%rip), %rsi     # 0x1496a
callq 0x3ef0
movq %rax, -0x4d0(%rbp)
jmp 0x3938
movq -0x4d0(%rbp), %rdi
callq 0x4410
movb %al, -0x4d1(%rbp)
jmp 0x394c
movb -0x4d1(%rbp), %al
testb $0x1, %al
jne 0x395b
jmp 0x3ba8
leaq 0x10ff0(%rip), %rsi     # 0x14952
leaq -0x460(%rbp), %rdi
callq 0x3ef0
movq %rax, -0x4e0(%rbp)
jmp 0x3977
movq -0x4e0(%rbp), %rdi
movslq -0x464(%rbp), %rsi
callq 0x4130
movq %rax, -0x4e8(%rbp)
jmp 0x3993
movq -0x4e8(%rbp), %rdi
leaq 0x10fd1(%rip), %rsi     # 0x14972
callq 0x3ef0
movq %rax, -0x4f0(%rbp)
jmp 0x39af
movq -0x4f0(%rbp), %rdi
callq 0x4440
movw %ax, -0x4f2(%rbp)
jmp 0x39c4
movw -0x4f2(%rbp), %ax
movzwl %ax, %eax
imulq $0x1999999a, %rax, %rax # imm = 0x1999999A
shrq $0x20, %rax
movb %al, -0x501(%rbp)
movl -0x464(%rbp), %eax
addl $0x3, %eax
movslq %eax, %rsi
leaq -0x28(%rbp), %rdi
callq 0x43f0
movb -0x501(%rbp), %cl
movb %cl, (%rax)
movb $0x0, -0x3d(%rbp)
leaq 0x10f4b(%rip), %rsi     # 0x14952
leaq -0x460(%rbp), %rdi
callq 0x3ef0
movq %rax, -0x500(%rbp)
jmp 0x3a1c
movq -0x500(%rbp), %rdi
movslq -0x464(%rbp), %rsi
callq 0x4130
movq %rax, -0x510(%rbp)
jmp 0x3a38
movq -0x510(%rbp), %rdi
leaq 0x10f35(%rip), %rsi     # 0x1497b
callq 0x3ef0
movq %rax, -0x518(%rbp)
jmp 0x3a54
movq -0x518(%rbp), %rdi
callq 0x4470
movb %al, -0x519(%rbp)
jmp 0x3a68
movb -0x519(%rbp), %al
movzbl %al, %ecx
movzbl -0x3d(%rbp), %eax
orl %ecx, %eax
movb %al, -0x3d(%rbp)
leaq 0x10ed1(%rip), %rsi     # 0x14952
leaq -0x460(%rbp), %rdi
callq 0x3ef0
movq %rax, -0x528(%rbp)
jmp 0x3a96
movq -0x528(%rbp), %rdi
movslq -0x464(%rbp), %rsi
callq 0x4130
movq %rax, -0x530(%rbp)
jmp 0x3ab2
movq -0x530(%rbp), %rdi
leaq 0x10ecc(%rip), %rsi     # 0x1498c
callq 0x3ef0
movq %rax, -0x538(%rbp)
jmp 0x3ace
movq -0x538(%rbp), %rdi
callq 0x4410
movb %al, -0x539(%rbp)
jmp 0x3ae2
movb -0x539(%rbp), %al
notb %al
movzbl %al, %ecx
andl $0x1, %ecx
shll $0x3, %ecx
movzbl -0x3d(%rbp), %eax
orl %ecx, %eax
movb %al, -0x3d(%rbp)
leaq 0x10e4f(%rip), %rsi     # 0x14952
leaq -0x460(%rbp), %rdi
callq 0x3ef0
movq %rax, -0x548(%rbp)
jmp 0x3b18
movq -0x548(%rbp), %rdi
movslq -0x464(%rbp), %rsi
callq 0x4130
movq %rax, -0x550(%rbp)
jmp 0x3b34
movq -0x550(%rbp), %rdi
leaq 0x10e28(%rip), %rsi     # 0x1496a
callq 0x3ef0
movq %rax, -0x558(%rbp)
jmp 0x3b50
movq -0x558(%rbp), %rdi
callq 0x4410
movb %al, -0x559(%rbp)
jmp 0x3b64
movb -0x559(%rbp), %dl
movl $0x10, %ecx
xorl %eax, %eax
testb $0x1, %dl
cmovnel %eax, %ecx
movzbl -0x3d(%rbp), %eax
orl %ecx, %eax
movb %al, -0x3d(%rbp)
movb -0x3d(%rbp), %al
movb %al, -0x55a(%rbp)
movl -0x464(%rbp), %eax
addl $0x6, %eax
movslq %eax, %rsi
leaq -0x28(%rbp), %rdi
callq 0x43f0
movb -0x55a(%rbp), %cl
movb %cl, (%rax)
jmp 0x3bd8
movl -0x464(%rbp), %eax
addl $0x3, %eax
movslq %eax, %rsi
leaq -0x28(%rbp), %rdi
callq 0x43f0
movb $-0x1, (%rax)
movl -0x464(%rbp), %eax
addl $0x6, %eax
movslq %eax, %rsi
leaq -0x28(%rbp), %rdi
callq 0x43f0
movb $-0x1, (%rax)
jmp 0x3bda
movl -0x464(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x464(%rbp)
jmp 0x37ef
movl $0x0, -0x46c(%rbp)
cmpl $0x9, -0x46c(%rbp)
jge 0x3c35
movslq -0x46c(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x43f0
movzbl (%rax), %esi
leaq -0x450(%rbp), %rdi
callq 0x33f0
jmp 0x3c22
jmp 0x3c24
movl -0x46c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x46c(%rbp)
jmp 0x3bf8
movl $0x0, -0x4(%rbp)
movl $0x1, -0x44(%rbp)
leaq -0x460(%rbp), %rdi
callq 0x44a0
leaq -0x450(%rbp), %rdi
callq 0x33e0
leaq -0x250(%rbp), %rdi
callq 0x30b0
jmp 0x3c77
leaq -0x250(%rbp), %rdi
callq 0x30b0
jmp 0x3c8c
leaq -0x28(%rbp), %rdi
callq 0x44e0
movl -0x4(%rbp), %eax
addq $0x560, %rsp            # imm = 0x560
popq %rbp
retq
leaq -0x28(%rbp), %rdi
callq 0x44e0
movq -0x38(%rbp), %rdi
callq 0x34b0
nop