// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/bintext.c
// Function: thedrawcom_decrunch
static void thedrawcom_decrunch(deark *c, struct thedrawcom_ctx *tdc, u8 prescan_mode)
{
	i64 pos = tdc->data_pos;
	i64 endpos = tdc->data_pos + tdc->cmpr_len;
	struct thedrawcom_dcmpr_state *dc = &tdc->dc;

	de_zeromem(dc, sizeof(struct thedrawcom_dcmpr_state));
	dc->prescan_mode = prescan_mode;
	dc->curr_fg_code = 0xf;

	if(endpos > c->infile->len) {
		tdc->d->errflag = 1;
		tdc->d->need_errmsg = 1;
		goto done;
	}

	if(!tdc->unc_data) {
		tdc->unc_data = dbuf_create_membuf(c, 80*2*25, 0);
		dbuf_set_length_limit(tdc->unc_data,
			THEDRAWCOM_MAX_WIDTH*2*THEDRAWCOM_MAX_HEIGHT);
		dbuf_enable_wbuffer(tdc->unc_data);
	}

	while(1) {
		u8 b0, b1, b2;
		i64 k;

		if(tdc->d->errflag) goto done;
		if(pos >= endpos) break;

		b0 = de_getbyte_p(&pos);

		if(b0>=32) {
			tdc_decrunch_emit_char(c, tdc, b0);
			continue;
		}
		if(b0<=15) {
			dc->curr_fg_code = b0;
		}
		else if(b0<=23) {
			dc->curr_bg_code = (b0-16)<<4;
		}
		else if(b0==24) { // Newline

			dc->next_ypos++;
			dc->next_xpos = 0;

			if(!dc->prescan_mode) {
				i64 expected_len;
				i64 actual_len;

				// Make sure we're in the right place in the decompressed data.
				expected_len = tdc->d->csctx.width_in_chars * 2 * dc->next_ypos;
				actual_len = dbuf_get_length(tdc->unc_data);
				if(actual_len != expected_len) {
					// It would be better to pad with spaces, but in practice
					// this doesn't happen.
					dbuf_truncate(tdc->unc_data, expected_len);
				}
			}
		}
		else if(b0==25) { // Run of spaces
			b1 = de_getbyte_p(&pos);
			for(k=0; k<(i64)b1+1; k++) {
				tdc_decrunch_emit_char(c, tdc, 32);
			}
		}
		else if(b0==26) { // Run of an arbitrary character
			b1 = de_getbyte_p(&pos);
			b2 = de_getbyte_p(&pos);
			for(k=0; k<(i64)b1+1; k++) {
				tdc_decrunch_emit_char(c, tdc, b2);
			}
		}
		else if(b0==27) { // Toggle blink mode
			dc->curr_blink_code = (dc->curr_blink_code==0) ? 0x80 : 0x00;
		}
		else { // Unknown opcode
			tdc->d->errflag = 1;
			tdc->d->need_errmsg = 1;
			goto done;
		}
	}

	// Decompression finished normally

	if((dc->max_xpos+1 > THEDRAWCOM_MAX_WIDTH) ||
		(dc->max_ypos+1 > THEDRAWCOM_MAX_HEIGHT))
	{
		tdc->d->errflag = 1;
		tdc->d->need_errmsg = 1;
		goto done;
	}

	if(dc->prescan_mode && !tdc->d->errflag) {
		de_dbg(c, "number of rows: %d", (int)(dc->max_ypos+1));
		de_dbg(c, "last nonblank row: %d", (int)dc->ypos_of_last_nonblank);
		tdc->d->csctx.width_in_chars = dc->max_xpos + 1;

		if(dc->max_ypos>24) {
			tdc->d->csctx.height_in_chars = dc->ypos_of_last_nonblank + 1;
		}
		else {
			tdc->d->csctx.height_in_chars = dc->max_ypos + 1;
		}

		de_dbg_dimensions(c, tdc->d->csctx.width_in_chars, tdc->d->csctx.height_in_chars);
	}

done:
	dbuf_flush(tdc->unc_data);

	if(tdc->d->need_errmsg) {
		de_err(c, "Decompression failed");
		tdc->d->need_errmsg = 0;
		tdc->d->errflag = 1;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
addq 0x38(%rcx), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
addq $0x58, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x19140
movb -0x11(%rbp), %cl
movq -0x30(%rbp), %rax
movb %cl, (%rax)
movq -0x30(%rbp), %rax
movb $0xf, 0x1(%rax)
movq -0x28(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jle 0x4140e
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, (%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x1(%rax)
jmp 0x41783
movq -0x10(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x41453
movq -0x8(%rbp), %rdi
movl $0xfa0, %esi            # imm = 0xFA0
xorl %edx, %edx
callq 0x168020
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movl $0xfa00, %esi           # imm = 0xFA00
callq 0x168120
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x167b90
jmp 0x41455
movq -0x10(%rbp), %rax
movq (%rax), %rax
cmpb $0x0, (%rax)
je 0x41466
jmp 0x41783
movq -0x20(%rbp), %rax
cmpq -0x28(%rbp), %rax
jl 0x41475
jmp 0x41672
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x20(%rbp), %rsi
callq 0x165170
movb %al, -0x31(%rbp)
movzbl -0x31(%rbp), %eax
cmpl $0x20, %eax
jl 0x414a5
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movzbl -0x31(%rbp), %edx
callq 0x417d0
jmp 0x41455
movzbl -0x31(%rbp), %eax
cmpl $0xf, %eax
jg 0x414bd
movb -0x31(%rbp), %cl
movq -0x30(%rbp), %rax
movb %cl, 0x1(%rax)
jmp 0x4166d
movzbl -0x31(%rbp), %eax
cmpl $0x17, %eax
jg 0x414de
movzbl -0x31(%rbp), %eax
subl $0x10, %eax
shll $0x4, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movb %cl, 0x2(%rax)
jmp 0x4166b
movzbl -0x31(%rbp), %eax
cmpl $0x18, %eax
jne 0x4155a
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x30(%rbp), %rax
cmpb $0x0, (%rax)
jne 0x41555
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rax
shlq %rax
movq -0x30(%rbp), %rcx
imulq 0x10(%rcx), %rax
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x169790
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0x41553
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x168900
jmp 0x41555
jmp 0x41669
movzbl -0x31(%rbp), %eax
cmpl $0x19, %eax
jne 0x415b5
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x20(%rbp), %rsi
callq 0x165170
movb %al, -0x32(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzbl -0x32(%rbp), %ecx
addq $0x1, %rcx
cmpq %rcx, %rax
jge 0x415b0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x20, %edx
callq 0x417d0
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x4157f
jmp 0x41667
movzbl -0x31(%rbp), %eax
cmpl $0x1a, %eax
jne 0x41620
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x20(%rbp), %rsi
callq 0x165170
movb %al, -0x32(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x20(%rbp), %rsi
callq 0x165170
movb %al, -0x33(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movzbl -0x32(%rbp), %ecx
addq $0x1, %rcx
cmpq %rcx, %rax
jge 0x4161e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movzbl -0x33(%rbp), %edx
callq 0x417d0
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x415ee
jmp 0x41665
movzbl -0x31(%rbp), %eax
cmpl $0x1b, %eax
jne 0x41649
movq -0x30(%rbp), %rax
movzbl 0x3(%rax), %edx
xorl %eax, %eax
movl $0x80, %ecx
cmpl $0x0, %edx
cmovel %ecx, %eax
movb %al, %cl
movq -0x30(%rbp), %rax
movb %cl, 0x3(%rax)
jmp 0x41663
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, (%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x1(%rax)
jmp 0x41783
jmp 0x41665
jmp 0x41667
jmp 0x41669
jmp 0x4166b
jmp 0x4166d
jmp 0x41455
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
addq $0x1, %rax
cmpq $0xa0, %rax
jg 0x4169a
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
addq $0x1, %rax
cmpq $0xc8, %rax
jle 0x416b4
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, (%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x1(%rax)
jmp 0x41783
movq -0x30(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
je 0x41781
movq -0x10(%rbp), %rax
movq (%rax), %rax
cmpb $0x0, (%rax)
jne 0x41781
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
addq $0x1, %rax
movl %eax, %edx
leaq 0x161bbe(%rip), %rsi    # 0x1a32ab
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x28(%rax), %rax
movl %eax, %edx
leaq 0x161bb5(%rip), %rsi    # 0x1a32be
movb $0x0, %al
callq 0x15b0d0
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rcx
addq $0x1, %rcx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x50(%rax)
movq -0x30(%rbp), %rax
cmpq $0x18, 0x20(%rax)
jle 0x4174b
movq -0x30(%rbp), %rax
movq 0x28(%rax), %rcx
addq $0x1, %rcx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x58(%rax)
jmp 0x41762
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rcx
addq $0x1, %rcx
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x58(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x50(%rax), %rsi
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x58(%rax), %rdx
callq 0x15bba0
jmp 0x41783
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x167c30
movq -0x10(%rbp), %rax
movq (%rax), %rax
cmpb $0x0, 0x1(%rax)
je 0x417c4
movq -0x8(%rbp), %rdi
leaq 0x15d670(%rip), %rsi    # 0x19ee18
movb $0x0, %al
callq 0x15bfb0
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x0, 0x1(%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movb $0x1, (%rax)
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)