// File: /workspace/github_c_makefile_star2_O3/aap[P]pdp11/kd11b.c
// Function: dato
int
dato(KD11B *cpu, int b)
{
trace("dato %06o %06o %d\n", cpu->ba, cpu->bus->data, b);
	cpu->bus->pause = 0;

	/* allow odd addresses for bytes and registers */
	int alodd = b || cpu->ba >= 0177700 && cpu->ba < 0177720;

	if(!alodd && cpu->ba&1)
		goto be;

	/* internal registers */
	if((cpu->ba&0177400) == 0177400){
		if((cpu->ba&0360) == 0300){
			/* no idea if byte access even makes sense here */
			cpu->r[cpu->ba&017] = cpu->bus->data;
			goto ok;
		}
		switch(cpu->ba&0377){
		/* Line clock */
		case 0146:
			cpu->lc_int_enab = cpu->bus->data>>6 & 1;
			if((cpu->bus->data & 0200) == 0){
				cpu->lc_clock = 0;
				cpu->lc_int = 0;
			}
			goto ok;
		/* Receive */
		case 0160:
			// TODO: RDR ENAB
			cpu->rcd_rdr_enab = cpu->bus->data & 1;
			if(!cpu->rcd_int_enab && cpu->bus->data&0100 && cpu->rcd_da)
				cpu->rcd_int = 1;
			cpu->rcd_int_enab = cpu->bus->data>>6 & 1;
			goto ok;
		case 0162:
			/* read only */
			goto ok;
		/* Transmit */
		case 0164:
			// TODO: MAINT
			cpu->xmit_maint = cpu->bus->data>>2 & 1;
			if(!cpu->xmit_int_enab && cpu->bus->data&0100 && cpu->xmit_tbmt)
				cpu->xmit_int = 1;
			cpu->xmit_int_enab = cpu->bus->data>>6 & 1;
			goto ok;
		case 0166:
			cpu->xmit_b = cpu->bus->data;
			cpu->xmit_tbmt = 0;
			cpu->xmit_int = 0;
			goto ok;
		case 0170: case 0171:
			/* can't write switches */
			goto ok;
		case 0376: case 0377:
			/* writes 0 for the odd byte.
			   I think this is correct. */
			cpu->psw = cpu->bus->data;
			goto ok;

		/* respond but don't do anything */
		case 0147:
		case 0161:
		case 0163:
		case 0165:
		case 0167:
			goto ok;
		}
	}

	if(b){
		cpu->bus->addr = ubxt(cpu->ba);
		if(datob_bus(cpu->bus))
			goto be;
	}else{
		cpu->bus->addr = ubxt(cpu->ba)&~1;
		if(dato_bus(cpu->bus))
			goto be;
	}
ok:
	cpu->be = 0;
	return 0;
be:
	cpu->be++;
	return 1;
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movq 0x28(%rdi), %rdi
movl $0x0, 0x10(%rdi)
movzwl 0x22(%rbx), %eax
testl %esi, %esi
jne 0x1bc6
movl %eax, %ecx
andl $-0x10, %ecx
cmpw $-0x40, %cx
setne %cl
testb %al, %cl
jne 0x1c7f
movl %eax, %ecx
notl %ecx
testl $0xff00, %ecx           # imm = 0xFF00
jne 0x1c4f
movl %eax, %edx
andl $0xf0, %edx
cmpl $0xc0, %edx
jne 0x1bf2
movzwl 0xc(%rdi), %ecx
andl $0xf, %eax
movw %cx, (%rbx,%rax,2)
jmp 0x1d23
movzbl %al, %edx
leal -0x66(%rdx), %r8d
cmpl $0x13, %r8d
ja 0x1c39
leaq 0x34ba(%rip), %rdx      # 0x50c0
movslq (%rdx,%r8,4), %r8
addq %rdx, %r8
jmpq *%r8
movl 0xc(%rdi), %eax
movl %eax, %ecx
shrl $0x6, %ecx
andl $0x1, %ecx
movl %ecx, 0x84(%rbx)
testb %al, %al
js 0x1d23
movq $0x0, 0x88(%rbx)
jmp 0x1d23
addl $0xffffff02, %edx       # imm = 0xFFFFFF02
cmpl $0x2, %edx
jae 0x1c4f
movb 0xc(%rdi), %al
movb %al, 0x30(%rbx)
jmp 0x1d23
leal 0x30000(%rax), %edx
testl $0xe000, %ecx           # imm = 0xE000
cmovnel %eax, %edx
testl %esi, %esi
je 0x1c6c
movl %edx, 0x8(%rdi)
callq 0x13d6
jmp 0x1c77
andl $-0x2, %edx
movl %edx, 0x8(%rdi)
callq 0x13a4
testl %eax, %eax
je 0x1d23
incl 0x38(%rbx)
movl $0x1, %eax
jmp 0x1d2c
movzwl 0xc(%rdi), %eax
movl %eax, %ecx
shrl $0x2, %ecx
andl $0x1, %ecx
movl %ecx, 0xac(%rbx)
cmpl $0x0, 0xa8(%rbx)
jne 0x1cc1
movl %eax, %ecx
andl $0x40, %ecx
je 0x1cc1
cmpl $0x0, 0xb4(%rbx)
je 0x1cc1
movl $0x1, 0xb0(%rbx)
shrl $0x6, %eax
andl $0x1, %eax
movl %eax, 0xa8(%rbx)
jmp 0x1d23
movb 0xc(%rdi), %al
movb %al, 0xb8(%rbx)
movq $0x0, 0xb0(%rbx)
jmp 0x1d23
movzwl 0xc(%rdi), %eax
movl %eax, %ecx
andl $0x1, %ecx
movl %ecx, 0x94(%rbx)
cmpl $0x0, 0x98(%rbx)
jne 0x1d17
movl %eax, %ecx
andl $0x40, %ecx
je 0x1d17
cmpl $0x0, 0xa0(%rbx)
je 0x1d17
movl $0x1, 0x9c(%rbx)
shrl $0x6, %eax
andl $0x1, %eax
movl %eax, 0x98(%rbx)
movl $0x0, 0x38(%rbx)
xorl %eax, %eax
popq %rbx
retq