// File: chenhn123[P]wdt_util_src/wdt_ct/w8755_funcs.cpp
// Function: wh_w8755_dev_flash_write_data_page(WdtDevice*, unsigned char*, unsigned int, int)
int wh_w8755_dev_flash_write_data_page(WDT_DEV* pdev, BYTE* data, UINT32 address, int length)
{
	int	addr_start, data_len, packet_size;
	BYTE*	psource_data = 0;
	int	count = 0;
	int	retval = 1;

	if (!data)
		return 0;

	/* address and length should be align to 4 */
	if ((address & 0x3) != 0 || (length & 0x3) != 0)
		return 0;

	/* to make sure the data not exceed a sector */
	if ((address >> 8) != ((address + length - 1) >> 8))		
		return 0;

	data_len = length;
	addr_start = address;
	psource_data = data;

	packet_size = W8755_PACKET_SIZE;
	
	/* set the address to the device first */
	retval = wh_w8755_dev_exec_report_type_write(pdev, W8755_ISP_SET_FLASH_ADDRESS,
						     (BYTE *) &addr_start, 4);
	if (!retval)
		return 0;

	/* since the address is incremental, the following step just keep writting the flash data */
	while(data_len)	{		
		if (data_len < W8755_PACKET_SIZE)
			packet_size = data_len;

		if (!wh_w8755_dev_exec_report_type_write(pdev, W8755_ISP_SET_FLASH,
							 psource_data, packet_size)) {
			printf("can't set flash: 0x%x\n", addr_start);
			retval = 0;
			break;			
		}

		data_len = data_len - packet_size;
		psource_data = psource_data + packet_size;
		addr_start = addr_start + packet_size;


		wh_udelay(FLASH_PAGE_WRITE_DELAY_US);
		count++;
	}

	return retval; 
}

// 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)
movq $0x0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x1, -0x40(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x2e8f
movl $0x0, -0x4(%rbp)
jmp 0x2f9e
movl -0x1c(%rbp), %eax
andl $0x3, %eax
cmpl $0x0, %eax
jne 0x2ea5
movl -0x20(%rbp), %eax
andl $0x3, %eax
cmpl $0x0, %eax
je 0x2eb1
movl $0x0, -0x4(%rbp)
jmp 0x2f9e
movl -0x1c(%rbp), %eax
shrl $0x8, %eax
movl -0x1c(%rbp), %ecx
addl -0x20(%rbp), %ecx
subl $0x1, %ecx
shrl $0x8, %ecx
cmpl %ecx, %eax
je 0x2ed3
movl $0x0, -0x4(%rbp)
jmp 0x2f9e
movl -0x20(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x1c(%rbp), %eax
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
movl $0x3c, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
movl $0x87, %esi
leaq -0x24(%rbp), %rdx
movl $0x4, %ecx
callq 0x2af0
movl %eax, -0x40(%rbp)
cmpl $0x0, -0x40(%rbp)
jne 0x2f1a
movl $0x0, -0x4(%rbp)
jmp 0x2f9e
jmp 0x2f1c
cmpl $0x0, -0x28(%rbp)
je 0x2f98
cmpl $0x3c, -0x28(%rbp)
jge 0x2f2e
movl -0x28(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rdx
movl -0x2c(%rbp), %ecx
movl $0x83, %esi
callq 0x2af0
cmpl $0x0, %eax
jne 0x2f62
movl -0x24(%rbp), %esi
leaq 0xc56c(%rip), %rdi      # 0xf4be
movb $0x0, %al
callq 0x2050
movl $0x0, -0x40(%rbp)
jmp 0x2f98
movl -0x28(%rbp), %eax
subl -0x2c(%rbp), %eax
movl %eax, -0x28(%rbp)
movq -0x38(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movl -0x24(%rbp), %eax
addl -0x2c(%rbp), %eax
movl %eax, -0x24(%rbp)
movl $0x64, %edi
callq 0x25b0
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x2f1c
movl -0x40(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)