// File: chenhn123[P]wdt_util_src/wdt_ct/w8790_funcs.cpp
// Function: w8790_dev_flash_write_4k(WdtDevice*, unsigned char*, unsigned int, int)
int w8790_dev_flash_write_4k(WDT_DEV* pdev, BYTE* data, UINT32 address, int size) {
	int retval = 0;
	int page_size;
	int retry_count = 0;
	int start_addr = address;
	UINT32 calc_checksum, read_checksum;

	BYTE* pdata = data;


	while (size) {
		if (size > (int)WDT_PAGE_SIZE) {
			page_size = WDT_PAGE_SIZE;
			size = size - WDT_PAGE_SIZE;
		} else {

			page_size = size;
			size = 0;
		}

		for (retry_count = 0; retry_count < RETRY_COUNT; retry_count++) {

			if(retry_count > 0)
				wh_w8790_dev_send_commands(pdev, WH_CMD_FLASH_ERASE4K, start_addr);


			retval = wh_w8790_dev_write_flash_page(pdev, pdata, start_addr, page_size);
			if (!retval)
				continue;

			calc_checksum = misr_for_bytes(0, pdata, 0, page_size);

			retval = wh_w8790_dev_flash_get_checksum(pdev, &read_checksum, start_addr, page_size, 0);
			if (read_checksum == calc_checksum)
				break;
			else
				printf("checksum failed (%d): %d <> %d\n", retry_count, read_checksum, calc_checksum);

		}


		if (retry_count == RETRY_COUNT) {
			printf("***** retry failed *****\n");
			break;
		}
		start_addr = start_addr + page_size;
		pdata = pdata + page_size;
	}

	if (retry_count == RETRY_COUNT) {
		printf("stop 4k chunk program : fail \n");
		return 0;
	}
	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x20(%rbp)
je 0x81af
cmpl $0x1000, -0x20(%rbp)    # imm = 0x1000
jle 0x80c9
movl $0x1000, -0x28(%rbp)    # imm = 0x1000
movl -0x20(%rbp), %eax
subl $0x1000, %eax           # imm = 0x1000
movl %eax, -0x20(%rbp)
jmp 0x80d6
movl -0x20(%rbp), %eax
movl %eax, -0x28(%rbp)
movl $0x0, -0x20(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0x3, -0x2c(%rbp)
jge 0x817c
cmpl $0x0, -0x2c(%rbp)
jle 0x80fe
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %edx
movl $0x13, %esi
callq 0x81e0
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movl -0x30(%rbp), %edx
movl -0x28(%rbp), %ecx
callq 0x7af0
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x811c
jmp 0x816e
movq -0x40(%rbp), %rsi
movl -0x28(%rbp), %ecx
xorl %edx, %edx
movl %edx, %edi
callq 0xb780
movzwl %ax, %eax
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rdi
movl -0x30(%rbp), %edx
movl -0x28(%rbp), %ecx
leaq -0x38(%rbp), %rsi
xorl %r8d, %r8d
callq 0x7ca0
movl %eax, -0x24(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x34(%rbp), %eax
jne 0x8155
jmp 0x817c
movl -0x2c(%rbp), %esi
movl -0x38(%rbp), %edx
movl -0x34(%rbp), %ecx
leaq 0x758c(%rip), %rdi      # 0xf6f1
movb $0x0, %al
callq 0x2050
jmp 0x816e
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x80dd
cmpl $0x3, -0x2c(%rbp)
jne 0x8192
leaq 0x7588(%rip), %rdi      # 0xf711
movb $0x0, %al
callq 0x2050
jmp 0x81af
movl -0x30(%rbp), %eax
addl -0x28(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x40(%rbp), %rax
movslq -0x28(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
jmp 0x80a2
cmpl $0x3, -0x2c(%rbp)
jne 0x81cc
leaq 0x756f(%rip), %rdi      # 0xf72b
movb $0x0, %al
callq 0x2050
movl $0x0, -0x4(%rbp)
jmp 0x81d3
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)