// File: /workspace/github_c_makefile_star2_O0/j-hoppe[P]tu58fs/tu58drive.c
// Function: tuwrite
static void tuwrite(tu_cmdpkt *pk) {
	int32_t count;
	int32_t status;
	tu_datpkt dk;
	image_t *img;

	// check unit number for validity
	img = tu58image_get(pk->unit);
	if (!img || !img->open) {
		error("tuwrite bad unit %d", pk->unit);
		endpacket(pk->unit, TUE_BADU, 0, 0);
		return;
	}

	// offline = no cartridges
	if (tu58_offline) {
		endpacket(pk->unit, TUE_BADF, 0, 0);
		return;
	}

	// seek to desired ending block offset
	if (image_blockseek(img, blocksize(pk->modifier), pk->block, pk->count - 1)) {
		error("tuwrite unit %d bad block 0x%04X", pk->unit, pk->block);
		endpacket(pk->unit, TUE_BADB, 0, 0);
		return;
	}

	// seek to desired starting block offset
	if (image_blockseek(img, blocksize(pk->modifier), pk->block, 0)) {
		error("tuwrite unit %d bad block 0x%04X", pk->unit, pk->block);
		endpacket(pk->unit, TUE_BADB, 0, 0);
		return;
	}

	// fake a seek time
	delay_ms(tudelay[opt_timing].seek);

	// keep looping if more data is expected
	for (count = pk->count; count > 0; count -= dk.length) {

		// send continue flag; we are ready for more data
		serial_devtxput(&tu58_serial, TUF_CONT);
		serial_devtxflush(&tu58_serial);
		if (opt_debug)
			info("sending <CONT>");

		uint8_t last;
		dk.flag = -1;

		// loop until we see data flag
		do {
			last = dk.flag;
			dk.flag = serial_devrxget(&tu58_serial);
			if (opt_debug)
				info("flag=0x%02X last=0x%02X", dk.flag, last);
			if (last == TUF_INIT && dk.flag == TUF_INIT) {
				// two in a row is special
				serial_devtxput(&tu58_serial, TUF_CONT); // send 'continue'
				serial_devtxflush(&tu58_serial); // send immediate
				if (opt_debug)
					info("<INIT><INIT> seen, sending <CONT>, abort write");
				return; // abort command
			} else if (dk.flag == TUF_CTRL) {
				error("protocol error, unexpected CTRL flag during write");
				endpacket(pk->unit, TUE_DERR, 0, 0);
				return;
			} else if (dk.flag == TUF_XOFF) {
				if (opt_debug)
					info("<XOFF> seen, stopping output");
				serial_devtxstop(&tu58_serial);
			} else if (dk.flag == TUF_CONT) {
				if (opt_debug)
					info("<CONT> seen, starting output");
				serial_devtxstart(&tu58_serial);
			}
		} while (dk.flag != TUF_DATA);

		// byte following data flag is packet data length
		dk.length = serial_devrxget(&tu58_serial);

		// get remainder of the data packet
		if (getpacket((tu_packet *) &dk)) {
			// whoops, checksum error, fail
			error("data checksum error");
			endpacket(pk->unit, TUE_DERR, 0, 0);
			return;
		}

		// write data packet to file
		if ((status = image_write(img, dk.data, dk.length)) != dk.length) {
			if (status == -2) {
				// whoops, unit is write protected
				error("tuwrite unit %d is write protected block 0x%04X count 0x%04X", pk->unit,
						pk->block, pk->count);
				endpacket(pk->unit, TUE_WPRO, pk->count - count, 0);
			} else {
				// whoops, some other data write error (like past EOF)
				error("tuwrite unit %d data write error block 0x%04X count 0x%04X", pk->unit,
						pk->block, pk->count);
				endpacket(pk->unit, TUE_PARO, pk->count - count, 0);
			}
			return;
		}

		// fake a write time
		delay_ms(tudelay[opt_timing].write);
	}

	// must fill out last block with zeros
	if ((count = pk->count % blocksize(pk->modifier)) > 0) {
		uint8_t buffer[TU58_BLOCKSIZE];
		bzero(buffer, (count = blocksize(pk->modifier) - count));
		if (opt_debug)
			info("tuwrite unit %d filling %d zeroes", pk->unit, count);
		if (image_write(img, buffer, count) != count) {
			// whoops, something bad happened
			error("tuwrite unit %d data error block 0x%04X count 0x%04X", pk->unit, pk->block,
					pk->count);
			endpacket(pk->unit, TUE_PARO, pk->count, 0);
			return;
		}
		// fake a write time
		delay_ms(tudelay[opt_timing].write);
	}

	// success if we get here
	endpacket(pk->unit, TUE_SUCC, pk->count, 0);

	return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %edi
callq 0x7aa0
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0xa0(%rbp)
je 0x8bcd
movq -0xa0(%rbp), %rax
cmpb $0x0, 0xf4(%rax)
jne 0x8bfe
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
leaq 0x12f1c(%rip), %rdi     # 0x1baf8
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movl $0xf8, %esi
xorl %ecx, %ecx
movzbl 0x4(%rax), %edi
movl %ecx, %edx
callq 0x8850
jmp 0x9148
movl 0x1c5c0(%rip), %eax     # 0x251c4
cmpl $0x0, %eax
je 0x8c24
movq -0x8(%rbp), %rax
movl $0xf7, %esi
xorl %ecx, %ecx
movzbl 0x4(%rax), %edi
movl %ecx, %edx
callq 0x8850
jmp 0x9148
movq -0xa0(%rbp), %rax
movq %rax, -0x2b8(%rbp)
movq -0x8(%rbp), %rax
movzbl 0x3(%rax), %edi
callq 0x9510
movq -0x2b8(%rbp), %rdi
movl %eax, %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %ecx
subl $0x1, %ecx
callq 0x9f00
cmpl $0x0, %eax
je 0x8c9e
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
leaq 0x12e90(%rip), %rdi     # 0x1bb0c
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movl $0xc9, %esi
xorl %ecx, %ecx
movzbl 0x4(%rax), %edi
movl %ecx, %edx
callq 0x8850
jmp 0x9148
movq -0xa0(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movq -0x8(%rbp), %rax
movzbl 0x3(%rax), %edi
callq 0x9510
movq -0x2c0(%rbp), %rdi
movl %eax, %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
xorl %ecx, %ecx
callq 0x9f00
cmpl $0x0, %eax
je 0x8d0f
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
leaq 0x12e1f(%rip), %rdi     # 0x1bb0c
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movl $0xc9, %esi
xorl %ecx, %ecx
movzbl 0x4(%rax), %edi
movl %ecx, %edx
callq 0x8850
jmp 0x9148
leaq 0x1b052(%rip), %rax     # 0x23d68
movslq (%rax), %rcx
leaq 0x1a8b0(%rip), %rax     # 0x235d0
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movzwl 0x6(%rax), %edi
callq 0xd2a0
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %eax
movl %eax, -0xc(%rbp)
cmpl $0x0, -0xc(%rbp)
jle 0x9022
leaq 0x1c47c(%rip), %rdi     # 0x251c8
movl $0x10, %esi
callq 0xa9b0
leaq 0x1c46b(%rip), %rdi     # 0x251c8
callq 0xa8a0
leaq 0x1b00b(%rip), %rax     # 0x23d74
cmpl $0x0, (%rax)
je 0x8d7c
leaq 0x12adc(%rip), %rdi     # 0x1b851
movb $0x0, %al
callq 0xcf60
movb $-0x1, -0x94(%rbp)
movb -0x94(%rbp), %al
movb %al, -0xa1(%rbp)
leaq 0x1c432(%rip), %rdi     # 0x251c8
callq 0xa940
movb %al, -0x94(%rbp)
leaq 0x1afcc(%rip), %rax     # 0x23d74
cmpl $0x0, (%rax)
je 0x8dc9
movzbl -0x94(%rbp), %esi
movzbl -0xa1(%rbp), %edx
leaq 0x12a58(%rip), %rdi     # 0x1b81a
movb $0x0, %al
callq 0xcf60
movzbl -0xa1(%rbp), %eax
cmpl $0x4, %eax
jne 0x8e1d
movzbl -0x94(%rbp), %eax
cmpl $0x4, %eax
jne 0x8e1d
leaq 0x1c3e0(%rip), %rdi     # 0x251c8
movl $0x10, %esi
callq 0xa9b0
leaq 0x1c3cf(%rip), %rdi     # 0x251c8
callq 0xa8a0
leaq 0x1af6f(%rip), %rax     # 0x23d74
cmpl $0x0, (%rax)
je 0x8e18
leaq 0x12d1c(%rip), %rdi     # 0x1bb2d
movb $0x0, %al
callq 0xcf60
jmp 0x9148
movzbl -0x94(%rbp), %eax
cmpl $0x2, %eax
jne 0x8e52
leaq 0x12d2c(%rip), %rdi     # 0x1bb5c
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movl $0xef, %esi
xorl %ecx, %ecx
movzbl 0x4(%rax), %edi
movl %ecx, %edx
callq 0x8850
jmp 0x9148
movzbl -0x94(%rbp), %eax
cmpl $0x13, %eax
jne 0x8e86
leaq 0x1af0f(%rip), %rax     # 0x23d74
cmpl $0x0, (%rax)
je 0x8e78
leaq 0x12a24(%rip), %rdi     # 0x1b895
movb $0x0, %al
callq 0xcf60
leaq 0x1c349(%rip), %rdi     # 0x251c8
callq 0xa680
jmp 0x8eba
movzbl -0x94(%rbp), %eax
cmpl $0x10, %eax
jne 0x8eb8
leaq 0x1aedb(%rip), %rax     # 0x23d74
cmpl $0x0, (%rax)
je 0x8eac
leaq 0x129d3(%rip), %rdi     # 0x1b878
movb $0x0, %al
callq 0xcf60
leaq 0x1c315(%rip), %rdi     # 0x251c8
callq 0xa6a0
jmp 0x8eba
jmp 0x8ebc
jmp 0x8ebe
jmp 0x8ec0
movzbl -0x94(%rbp), %eax
cmpl $0x1, %eax
jne 0x8d83
leaq 0x1c2f1(%rip), %rdi     # 0x251c8
callq 0xa940
movb %al, -0x93(%rbp)
leaq -0x94(%rbp), %rdi
callq 0x8770
cmpl $0x0, %eax
je 0x8f1c
leaq 0x12c94(%rip), %rdi     # 0x1bb8e
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movl $0xef, %esi
xorl %ecx, %ecx
movzbl 0x4(%rax), %edi
movl %ecx, %edx
callq 0x8850
jmp 0x9148
movq -0xa0(%rbp), %rdi
leaq -0x94(%rbp), %rsi
addq $0x2, %rsi
movzbl -0x93(%rbp), %edx
callq 0xa0f0
movl %eax, -0x10(%rbp)
movzbl -0x93(%rbp), %ecx
cmpl %ecx, %eax
je 0x8fed
cmpl $-0x2, -0x10(%rbp)
jne 0x8f9e
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %ecx
leaq 0x12c31(%rip), %rdi     # 0x1bba2
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movb 0x4(%rax), %dl
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %eax
subl -0xc(%rbp), %eax
movl $0xf5, %esi
xorl %ecx, %ecx
movzbl %dl, %edi
movzwl %ax, %edx
callq 0x8850
jmp 0x8fe8
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %ecx
leaq 0x12c22(%rip), %rdi     # 0x1bbdf
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movb 0x4(%rax), %dl
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %eax
subl -0xc(%rbp), %eax
movl $0xfe, %esi
xorl %ecx, %ecx
movzbl %dl, %edi
movzwl %ax, %edx
callq 0x8850
jmp 0x9148
leaq 0x1ad74(%rip), %rax     # 0x23d68
movslq (%rax), %rcx
leaq 0x1a5d2(%rip), %rax     # 0x235d0
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movzwl 0xa(%rax), %edi
callq 0xd2a0
movzbl -0x93(%rbp), %ecx
movl -0xc(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xc(%rbp)
jmp 0x8d3b
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %eax
movl %eax, -0x2c4(%rbp)
movq -0x8(%rbp), %rax
movzbl 0x3(%rax), %edi
callq 0x9510
movl %eax, %ecx
movl -0x2c4(%rbp), %eax
cltd
idivl %ecx
movl %edx, -0xc(%rbp)
cmpl $0x0, %edx
jle 0x912d
leaq -0x2b0(%rbp), %rax
movq %rax, -0x2d0(%rbp)
movq -0x8(%rbp), %rax
movzbl 0x3(%rax), %edi
callq 0x9510
movq -0x2d0(%rbp), %rdi
subl -0xc(%rbp), %eax
movl %eax, -0xc(%rbp)
movslq %eax, %rdx
xorl %esi, %esi
callq 0x3220
leaq 0x1ace7(%rip), %rax     # 0x23d74
cmpl $0x0, (%rax)
je 0x90ab
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
movl -0xc(%rbp), %edx
leaq 0x12b76(%rip), %rdi     # 0x1bc1a
movb $0x0, %al
callq 0xcf60
movq -0xa0(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
movl -0xc(%rbp), %edx
callq 0xa0f0
cmpl -0xc(%rbp), %eax
je 0x910c
movq -0x8(%rbp), %rax
movzbl 0x4(%rax), %esi
movq -0x8(%rbp), %rax
movzwl 0xa(%rax), %edx
movq -0x8(%rbp), %rax
movzwl 0x8(%rax), %ecx
leaq 0x12b57(%rip), %rdi     # 0x1bc3c
movb $0x0, %al
callq 0xce70
movq -0x8(%rbp), %rax
movb 0x4(%rax), %dl
movq -0x8(%rbp), %rax
movl $0xfe, %esi
xorl %ecx, %ecx
movzbl %dl, %edi
movzwl 0x8(%rax), %edx
callq 0x8850
jmp 0x9148
leaq 0x1ac55(%rip), %rax     # 0x23d68
movslq (%rax), %rcx
leaq 0x1a4b3(%rip), %rax     # 0x235d0
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movzwl 0xa(%rax), %edi
callq 0xd2a0
movq -0x8(%rbp), %rax
movb 0x4(%rax), %dl
movq -0x8(%rbp), %rax
xorl %ecx, %ecx
movzbl %dl, %edi
movl %ecx, %esi
movzwl 0x8(%rax), %edx
callq 0x8850
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
nopw %cs:(%rax,%rax)