// File: /workspace/github_c_makefile_star2_O1/aap[P]pdp11/kd11b.c
// Function: dati
int
dati(KD11B *cpu, int b, int pse)
{
trace("dati %06o: ", cpu->ba);
	if(cpu->bus->pause)
		printf("XXXX: DATIP not ended properly\n");
	cpu->bus->pause = pse;

	/* 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){
			cpu->bus->data = cpu->r[cpu->ba&017];
			goto ok;
		}
		switch(cpu->ba&0377){
		/* Line clock */
		case 0146:
			cpu->bus->data = cpu->lc_int_enab<<6 |
				cpu->lc_clock<<7;
			goto ok;
		/* Receive */
		case 0160:
			cpu->bus->data = cpu->rcd_int_enab<<6 |
				cpu->rcd_da<<7 |
				cpu->rcd_busy<<11;
			goto ok;
		case 0162:
			cpu->bus->data = cpu->rcd_b;
			cpu->rcd_b = 0;
			cpu->rcd_da = 0;
			cpu->rcd_int = 0;
			goto ok;
		/* Transmit */
		case 0164:
			cpu->bus->data = cpu->xmit_maint<<2 |
				cpu->xmit_int_enab<<6 |
				cpu->xmit_tbmt<<7;
			goto ok;
		case 0166:
			/* write only */
			cpu->bus->data = 0;
			goto ok;
		case 0170: case 0171:
			cpu->bus->data = cpu->sw;
			goto ok;
		case 0376: case 0377:
			cpu->bus->data = cpu->psw;
			goto ok;

		/* respond but don't return real data */
		case 0147:
		case 0161:
		case 0163:
		case 0165:
		case 0167:
			cpu->bus->data = 0;
			goto ok;
		}
	}

	cpu->bus->addr = ubxt(cpu->ba)&~1;
	if(dati_bus(cpu->bus))
		goto be;
ok:
	trace("%06o\n", cpu->bus->data);
	cpu->be = 0;
	return 0;
be:
	trace("BE\n");
	cpu->bus->pause = 0;
	cpu->be++;
	return 1;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movl %edx, %r14d
movl %esi, %ebp
movq %rdi, %rbx
movq 0x28(%rdi), %rax
cmpl $0x0, 0x10(%rax)
je 0x1b63
leaq 0x373b(%rip), %rdi      # 0x5299
callq 0x1040
movq 0x28(%rbx), %rdi
movl %r14d, 0x10(%rdi)
testl %ebp, %ebp
jne 0x1b87
movzwl 0x22(%rbx), %eax
movl %eax, %ecx
andl $-0x10, %ecx
cmpw $-0x40, %cx
setne %cl
testb %al, %cl
jne 0x1c13
movzwl 0x22(%rbx), %eax
movl %eax, %ecx
notl %ecx
testl $0xff00, %ecx           # imm = 0xFF00
jne 0x1bf1
movl %eax, %edx
andl $0xf0, %edx
cmpl $0xc0, %edx
jne 0x1bb7
andl $0xf, %eax
movzwl (%rbx,%rax,2), %eax
movw %ax, 0xc(%rdi)
jmp 0x1caf
movzbl %al, %edx
leal -0x66(%rdx), %esi
cmpl $0x13, %esi
ja 0x1bdd
leaq 0x347f(%rip), %rdx      # 0x5048
movslq (%rdx,%rsi,4), %rsi
addq %rdx, %rsi
jmpq *%rsi
movw $0x0, 0xc(%rdi)
jmp 0x1caf
addl $0xffffff02, %edx       # imm = 0xFFFFFF02
cmpl $0x2, %edx
jae 0x1bf1
movzbl 0x30(%rbx), %eax
jmp 0x1c86
leal 0x30000(%rax), %edx
testl $0xe000, %ecx           # imm = 0xE000
cmovnel %eax, %edx
andl $-0x2, %edx
movl %edx, 0x8(%rdi)
callq 0x1472
testl %eax, %eax
je 0x1caf
movq 0x28(%rbx), %rax
movl $0x0, 0x10(%rax)
incl 0x38(%rbx)
movl $0x1, %eax
jmp 0x1cb8
movzwl 0x80(%rbx), %eax
jmp 0x1bae
movl 0x84(%rbx), %eax
movl 0x88(%rbx), %ecx
shll $0x6, %eax
jmp 0x1ca6
movzbl 0xa4(%rbx), %eax
movw %ax, 0xc(%rdi)
movb $0x0, 0xa4(%rbx)
movq $0x0, 0x9c(%rbx)
jmp 0x1caf
movl 0x90(%rbx), %eax
movl 0x98(%rbx), %ecx
shll $0x6, %ecx
movl 0xa0(%rbx), %edx
shll $0x7, %edx
orl %ecx, %edx
shll $0xb, %eax
orl %edx, %eax
movw %ax, 0xc(%rdi)
jmp 0x1caf
movl 0xa8(%rbx), %eax
movl 0xac(%rbx), %ecx
shll $0x2, %ecx
shll $0x6, %eax
orl %ecx, %eax
movl 0xb4(%rbx), %ecx
shll $0x7, %ecx
orl %eax, %ecx
movw %cx, 0xc(%rdi)
movl $0x0, 0x38(%rbx)
xorl %eax, %eax
popq %rbx
popq %r14
popq %rbp
retq