// File: /workspace/github_c_makefile_star2_O0/leiradel[P]zx48k-libretro/src/ay38910.h
// Function: ay38910_iorq
uint64_t ay38910_iorq(ay38910_t* ay, uint64_t pins) {
    if (pins & (AY38910_BDIR|AY38910_BC1)) {
        if (pins & AY38910_BDIR) {
            const uint8_t data = AY38910_DATA(pins);
            if (pins & AY38910_BC1) {
                /* latch address */
                ay->addr = data;
            }
            else {
                /* Write to register using the currently latched address.
                   The whole 8-bit address is considered, the low 4 bits
                   are the register index, and the upper bits are burned
                   into the chip as a 'chip select' and are usually 0
                   (this emulator assumes they are 0, so addresses greater
                   are ignored for reading and writing)
                */
                if (ay->addr < AY38910_NUM_REGISTERS) {
                    /* write register content, and update dependent values */
                    ay->reg[ay->addr] = data & _ay38910_reg_mask[ay->addr];
                    _ay38910_update_values(ay);
                    if (ay->addr == AY38910_REG_ENV_SHAPE_CYCLE) {
                        _ay38910_restart_env_shape(ay);
                    }
                    /* Handle port output:

                        If port A or B is in output mode, call the
                        port output callback to notify the outer world
                        about the new register value.

                        input/output mode is defined by bits 6 and 7 of
                        the 'enable' register
                            bit6 = 1: port A in output mode
                            bit7 = 1: port B in output mode
                    */
                    else if (ay->addr == AY38910_REG_IO_PORT_A) {
                        if (ay->enable & (1<<6)) {
                            if (ay->out_cb) {
                                ay->out_cb(AY38910_PORT_A, ay->port_a, ay->user_data);
                            }
                        }
                    }
                    else if (ay->addr == AY38910_REG_IO_PORT_B) {
                        if (ay->enable & (1<<7)) {
                            if (ay->out_cb) {
                                ay->out_cb(AY38910_PORT_B, ay->port_b, ay->user_data);
                            }
                        }
                    }
                }
            }
        }
        else {
            /* Read from register using the currently latched address.
               See 'write' for why the latched address must be in the
               valid register range to have an effect.
            */
            if (ay->addr < AY38910_NUM_REGISTERS) {
                /* Handle port input:

                    If port A or B is in input mode, first call the port
                    input callback to update the port register content.

                    input/output mode is defined by bits 6 and 7 of
                    the 'enable' register:
                        bit6 = 0: port A in input mode
                        bit7 = 0: port B in input mode
                */
                if (ay->addr == AY38910_REG_IO_PORT_A) {
                    if ((ay->enable & (1<<6)) == 0) {
                        if (ay->in_cb) {
                            ay->port_a = ay->in_cb(AY38910_PORT_A, ay->user_data);
                        }
                        else {
                            ay->port_a = 0xFF;
                        }
                    }
                }
                else if (ay->addr == AY38910_REG_IO_PORT_B) {
                    if ((ay->enable & (1<<7)) == 0) {
                        if (ay->in_cb) {
                            ay->port_b = ay->in_cb(AY38910_PORT_B, ay->user_data);
                        }
                        else {
                            ay->port_b = 0xFF;
                        }
                    }
                }
                /* read register content into data pins */
                const uint8_t data = ay->reg[ay->addr];
                AY38910_SET_DATA(pins, data);
            }
        }
        AY38910_SET_PA(pins, ay->port_a);
        AY38910_SET_PB(pins, ay->port_b);
        ay->pins = pins;
    }
    return pins;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movabsq $0x30000000000, %rax    # imm = 0x30000000000
andq -0x10(%rbp), %rax
cmpq $0x0, %rax
je 0x4039
movabsq $0x10000000000, %rax    # imm = 0x10000000000
andq -0x10(%rbp), %rax
cmpq $0x0, %rax
je 0x3ee6
movq -0x10(%rbp), %rax
shrq $0x10, %rax
movb %al, -0x11(%rbp)
movabsq $0x20000000000, %rax    # imm = 0x20000000000
andq -0x10(%rbp), %rax
cmpq $0x0, %rax
je 0x3dde
movb -0x11(%rbp), %cl
movq -0x8(%rbp), %rax
movb %cl, 0x24(%rax)
jmp 0x3ee1
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0x10, %eax
jge 0x3edf
movzbl -0x11(%rbp), %eax
movq -0x8(%rbp), %rcx
movzbl 0x24(%rcx), %ecx
movl %ecx, %edx
leaq 0x20bac(%rip), %rcx     # 0x249b0
movzbl (%rcx,%rdx), %ecx
andl %ecx, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rcx
movzbl 0x24(%rcx), %ecx
movb %dl, 0x25(%rax,%rcx)
movq -0x8(%rbp), %rdi
callq 0x37a0
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0xd, %eax
jne 0x3e40
movq -0x8(%rbp), %rdi
callq 0x38c0
jmp 0x3edd
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0xe, %eax
jne 0x3e8a
movq -0x8(%rbp), %rax
movzbl 0x2c(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x3e88
movq -0x8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x3e86
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rcx
movb 0x33(%rcx), %cl
movq -0x8(%rbp), %rdx
movq 0x18(%rdx), %rdx
xorl %edi, %edi
movzbl %cl, %esi
callq *%rax
jmp 0x3e88
jmp 0x3edb
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0xf, %eax
jne 0x3ed9
movq -0x8(%rbp), %rax
movzbl 0x2c(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x3ed7
movq -0x8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x3ed5
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rcx
movb 0x34(%rcx), %cl
movq -0x8(%rbp), %rdx
movq 0x18(%rdx), %rdx
movl $0x1, %edi
movzbl %cl, %esi
callq *%rax
jmp 0x3ed7
jmp 0x3ed9
jmp 0x3edb
jmp 0x3edd
jmp 0x3edf
jmp 0x3ee1
jmp 0x3fda
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0x10, %eax
jge 0x3fd8
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0xe, %eax
jne 0x3f4a
movq -0x8(%rbp), %rax
movzbl 0x2c(%rax), %eax
andl $0x40, %eax
cmpl $0x0, %eax
jne 0x3f48
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x3f3e
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rsi
xorl %edi, %edi
callq *%rax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x33(%rax)
jmp 0x3f46
movq -0x8(%rbp), %rax
movb $-0x1, 0x33(%rax)
jmp 0x3f48
jmp 0x3fa4
movq -0x8(%rbp), %rax
movzbl 0x24(%rax), %eax
cmpl $0xf, %eax
jne 0x3fa2
movq -0x8(%rbp), %rax
movzbl 0x2c(%rax), %eax
andl $0x80, %eax
cmpl $0x0, %eax
jne 0x3fa0
movq -0x8(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x3f96
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rsi
movl $0x1, %edi
callq *%rax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x34(%rax)
jmp 0x3f9e
movq -0x8(%rbp), %rax
movb $-0x1, 0x34(%rax)
jmp 0x3fa0
jmp 0x3fa2
jmp 0x3fa4
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rcx
movzbl 0x24(%rcx), %ecx
movb 0x25(%rax,%rcx), %al
movb %al, -0x12(%rbp)
movq -0x10(%rbp), %rax
andq $-0xff0001, %rax        # imm = 0xFF00FFFF
movzbl -0x12(%rbp), %ecx
andl $0xff, %ecx
shll $0x10, %ecx
movslq %ecx, %rcx
orq %rcx, %rax
movq %rax, -0x10(%rbp)
jmp 0x3fda
movabsq $-0xff000000000001, %rax # imm = 0xFF00FFFFFFFFFFFF
andq -0x10(%rbp), %rax
movq -0x8(%rbp), %rcx
movzbl 0x33(%rcx), %ecx
andq $0xff, %rcx
shlq $0x30, %rcx
orq %rcx, %rax
movq %rax, -0x10(%rbp)
movabsq $0xffffffffffffff, %rax # imm = 0xFFFFFFFFFFFFFF
andq -0x10(%rbp), %rax
movq -0x8(%rbp), %rcx
movzbl 0x34(%rcx), %ecx
andq $0xff, %rcx
shlq $0x38, %rcx
orq %rcx, %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x80(%rax)
movq -0x10(%rbp), %rax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)