// File: /workspace/github_c_makefile_star2_O0/Mikejmoffitt[P]romtools/namcosum/namcosum.c
// Function: main
int main(int argc, char **argv)
{
	int ret = -1;
	uint8_t *data = NULL;
	FILE *f = NULL;
	if (argc < 3)
	{
		printf("Usage: %s prg.bin rom_size <desired value>\n", argv[0]);
		ret = 0;
		goto done;
	}
	const char *fname = argv[1];
	const size_t rom_size = strtoul(argv[2], NULL, 0);
	uint8_t desired_value = 0;
	if (argc >= 4)
	{
		desired_value = strtoul(argv[3], NULL, 0);
	}
	// set up buffer
	f = fopen(fname, "rb");
	if (!f)
	{
		fprintf(stderr, "Couldn't open %s.\n", fname);
		goto done;
	}
	fseek(f, 0, SEEK_END);
	const size_t len = ftell(f);
	fseek(f, 0, SEEK_SET);
	data = malloc(len);
	if (!data)
	{
		fprintf(stderr, "Couldn't malloc %d bytes\n", (int)len);
		goto done;
	}
	// read the data
	const size_t read_bytes = fread(data, 1, len, f);
	if (read_bytes != len)
	{
		fprintf(stderr, "Read %d bytes but expected %d\n",
		        (int)read_bytes, (int)len);
		goto done;
	}
	fclose(f);
	f = NULL;
	// mark checksums at 1K boundaries
	uint8_t sum = 0;
	for (size_t i = 0; i < len; i++)
	{
		const int rom_idx = (i % rom_size);
		if (rom_idx == 0) sum = 0;
		if (rom_idx == rom_size - 1)
		{
			data[i] = (0x100 + desired_value - sum) & 0xFF;
			printf("$%X := $%02X\n", (int)i, data[i]);
		}
		else
		{
			sum += data[i];
		}
	}
	// write the file back
	f = fopen(fname, "wb");
	if (!f)
	{
		fprintf(stderr, "Couldn't open %s for writing.\n", fname);
		goto done;
	}
	const size_t written_bytes = fwrite(data, 1, len, f);
	fclose(f);
	f = NULL;
	if (written_bytes != len)
	{
		fprintf(stderr, "Wrote %d bytes but expected %d\n",
		        (int)written_bytes, (int)len);
		goto done;
	}
	ret = 0;
done:
	if (data) free(data);
	if (f) fclose(f);
	return ret;
}

// Assembly:
subq $0x78, %rsp
movl $0x0, 0x74(%rsp)
movl %edi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movl $0xffffffff, 0x64(%rsp) # imm = 0xFFFFFFFF
movq $0x0, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
cmpl $0x3, 0x70(%rsp)
jge 0x1239
movq 0x68(%rsp), %rax
movq (%rax), %rsi
leaq 0xddf(%rip), %rdi       # 0x2004
movb $0x0, %al
callq 0x1060
movl $0x0, 0x64(%rsp)
jmp 0x150c
movq 0x68(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x68(%rsp), %rax
movq 0x10(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x10c0
movq %rax, 0x40(%rsp)
movb $0x0, 0x3f(%rsp)
cmpl $0x4, 0x70(%rsp)
jl 0x1284
movq 0x68(%rsp), %rax
movq 0x18(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x10c0
movb %al, 0x3f(%rsp)
movq 0x48(%rsp), %rdi
leaq 0xda0(%rip), %rsi       # 0x2030
callq 0x10b0
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0x12c4
movq 0x2d4f(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movq 0x48(%rsp), %rdx
leaq 0xd7b(%rip), %rsi       # 0x2033
movb $0x0, %al
callq 0x1070
jmp 0x150c
movq 0x50(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x10a0
movq 0x50(%rsp), %rdi
callq 0x1080
movq %rax, 0x30(%rsp)
movq 0x50(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x10a0
movq 0x30(%rsp), %rdi
callq 0x1090
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x1331
movq 0x2ce4(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movq 0x30(%rsp), %rax
movl %eax, %edx
leaq 0xd21(%rip), %rsi       # 0x2046
movb $0x0, %al
callq 0x1070
jmp 0x150c
movq 0x58(%rsp), %rdi
movq 0x30(%rsp), %rdx
movq 0x50(%rsp), %rcx
movl $0x1, %esi
callq 0x1040
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x1386
movq 0x2c96(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movq 0x28(%rsp), %rax
movl %eax, %edx
movq 0x30(%rsp), %rax
movl %eax, %ecx
leaq 0xce6(%rip), %rsi       # 0x2060
movb $0x0, %al
callq 0x1070
jmp 0x150c
movq 0x50(%rsp), %rdi
callq 0x1050
movq $0x0, 0x50(%rsp)
movb $0x0, 0x27(%rsp)
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
cmpq 0x30(%rsp), %rax
jae 0x1462
movq 0x18(%rsp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq 0x40(%rsp)
movl %edx, %eax
movl %eax, 0x14(%rsp)
cmpl $0x0, 0x14(%rsp)
jne 0x13d7
movb $0x0, 0x27(%rsp)
movslq 0x14(%rsp), %rax
movq 0x40(%rsp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0x1434
movzbl 0x3f(%rsp), %eax
addl $0x100, %eax            # imm = 0x100
movzbl 0x27(%rsp), %ecx
subl %ecx, %eax
andl $0xff, %eax
movb %al, %dl
movq 0x58(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x18(%rsp), %rax
movl %eax, %esi
movq 0x58(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %edx
leaq 0xc54(%rip), %rdi       # 0x207f
movb $0x0, %al
callq 0x1060
jmp 0x144d
movq 0x58(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %ecx
movzbl 0x27(%rsp), %eax
addl %ecx, %eax
movb %al, 0x27(%rsp)
jmp 0x144f
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x13a7
movq 0x48(%rsp), %rdi
leaq 0xc1f(%rip), %rsi       # 0x208d
callq 0x10b0
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0x149f
movq 0x2b71(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movq 0x48(%rsp), %rdx
leaq 0xbfa(%rip), %rsi       # 0x2090
movb $0x0, %al
callq 0x1070
jmp 0x150c
movq 0x58(%rsp), %rdi
movq 0x30(%rsp), %rdx
movq 0x50(%rsp), %rcx
movl $0x1, %esi
callq 0x10d0
movq %rax, 0x8(%rsp)
movq 0x50(%rsp), %rdi
callq 0x1050
movq $0x0, 0x50(%rsp)
movq 0x8(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x1504
movq 0x2b15(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movq 0x8(%rsp), %rax
movl %eax, %edx
movq 0x30(%rsp), %rax
movl %eax, %ecx
leaq 0xbb4(%rip), %rsi       # 0x20af
movb $0x0, %al
callq 0x1070
jmp 0x150c
movl $0x0, 0x64(%rsp)
cmpq $0x0, 0x58(%rsp)
je 0x151e
movq 0x58(%rsp), %rdi
callq 0x1030
cmpq $0x0, 0x50(%rsp)
je 0x1530
movq 0x50(%rsp), %rdi
callq 0x1050
movl 0x64(%rsp), %eax
addq $0x78, %rsp
retq