// File: /workspace/github_c_makefile_star2_O0/leiradel[P]zx48k-libretro/src/ay38910.h
// Function: ay38910_tick
bool ay38910_tick(ay38910_t* ay) {
    ay->tick++;
    if ((ay->tick & 7) == 0) {
        /* tick the tone channels */
        for (int i = 0; i < AY38910_NUM_CHANNELS; i++) {
            ay38910_tone_t* chn = &ay->tone[i];
            if (++chn->counter >= chn->period) {
                chn->counter = 0;
                chn->bit ^= 1;
            }
        }

        /* tick the noise channel */
        if (++ay->noise.counter >= ay->noise.period) {
            ay->noise.counter = 0;
            ay->noise.bit ^= 1;
            if (ay->noise.bit) {
                // random number generator from MAME:
                // https://github.com/mamedev/mame/blob/master/src/devices/sound/ay8910.cpp
                // The Random Number Generator of the 8910 is a 17-bit shift
                // register. The input to the shift register is bit0 XOR bit3
                // (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips.
                ay->noise.rng ^= (((ay->noise.rng & 1) ^ ((ay->noise.rng >> 3) & 1)) << 17);
                ay->noise.rng >>= 1;
            }
        }
    }

    /* tick the envelope generator */
    if ((ay->tick & 15) == 0) {
        if (++ay->env.counter >= ay->env.period) {
            ay->env.counter = 0;
            if (!ay->env.shape_holding) {
                ay->env.shape_counter = (ay->env.shape_counter + 1) & 0x1F;
                if (ay->env.shape_hold && (0x1F == ay->env.shape_counter)) {
                    ay->env.shape_holding = true;
                }
            }
            ay->env.shape_state = _ay38910_shapes[ay->env_shape_cycle][ay->env.shape_counter];
        }
    }

    /* generate new sample? */
    ay->sample_counter -= AY38910_FIXEDPOINT_SCALE;
    if (ay->sample_counter <= 0) {
        ay->sample_counter += ay->sample_period;
        float sm = 0.0f;
        for (int i = 0; i < AY38910_NUM_CHANNELS; i++) {
            const ay38910_tone_t* chn = &ay->tone[i];
            float vol;
            if (0 == (ay->reg[AY38910_REG_AMP_A+i] & (1<<4))) {
                /* fixed amplitude */
                vol = _ay38910_volumes[ay->reg[AY38910_REG_AMP_A+i] & 0x0F];
            }
            else {
                /* envelope control */
                vol = _ay38910_volumes[ay->env.shape_state];
            }
            int vol_enable = (chn->bit|chn->tone_disable) & ((ay->noise.rng&1)|(chn->noise_disable));
            if (vol_enable) {
                sm += vol;
            }
        }
        ay->sample = _ay38910_dcadjust(ay, sm) * ay->mag;
        return true;    /* new sample is ready */
    }
    /* fallthrough: no new sample ready yet */
    return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl 0x20(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x20(%rax)
movq -0x10(%rbp), %rax
movl 0x20(%rax), %eax
andl $0x7, %eax
cmpl $0x0, %eax
jne 0x3aa8
movl $0x0, -0x14(%rbp)
cmpl $0x3, -0x14(%rbp)
jge 0x3a32
movq -0x10(%rbp), %rax
addq $0x38, %rax
movslq -0x14(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rcx
movw 0x2(%rcx), %ax
addw $0x1, %ax
movw %ax, 0x2(%rcx)
movzwl %ax, %eax
movq -0x20(%rbp), %rcx
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jl 0x3a25
movq -0x20(%rbp), %rax
movw $0x0, 0x2(%rax)
movq -0x20(%rbp), %rax
movl 0x4(%rax), %ecx
xorl $0x1, %ecx
movl %ecx, 0x4(%rax)
jmp 0x3a27
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x39d3
movq -0x10(%rbp), %rcx
movw 0x6a(%rcx), %ax
addw $0x1, %ax
movw %ax, 0x6a(%rcx)
movzwl %ax, %eax
movq -0x10(%rbp), %rcx
movzwl 0x68(%rcx), %ecx
cmpl %ecx, %eax
jl 0x3aa6
movq -0x10(%rbp), %rax
movw $0x0, 0x6a(%rax)
movq -0x10(%rbp), %rax
movl 0x70(%rax), %ecx
xorl $0x1, %ecx
movl %ecx, 0x70(%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x70(%rax)
je 0x3aa4
movq -0x10(%rbp), %rax
movl 0x6c(%rax), %ecx
andl $0x1, %ecx
movq -0x10(%rbp), %rax
movl 0x6c(%rax), %eax
shrl $0x3, %eax
andl $0x1, %eax
xorl %eax, %ecx
shll $0x11, %ecx
movq -0x10(%rbp), %rax
xorl 0x6c(%rax), %ecx
movl %ecx, 0x6c(%rax)
movq -0x10(%rbp), %rax
movl 0x6c(%rax), %ecx
shrl %ecx
movl %ecx, 0x6c(%rax)
jmp 0x3aa6
jmp 0x3aa8
movq -0x10(%rbp), %rax
movl 0x20(%rax), %eax
andl $0xf, %eax
cmpl $0x0, %eax
jne 0x3b56
movq -0x10(%rbp), %rcx
movw 0x76(%rcx), %ax
addw $0x1, %ax
movw %ax, 0x76(%rcx)
movzwl %ax, %eax
movq -0x10(%rbp), %rcx
movzwl 0x74(%rcx), %ecx
cmpl %ecx, %eax
jl 0x3b54
movq -0x10(%rbp), %rax
movw $0x0, 0x76(%rax)
movq -0x10(%rbp), %rax
testb $0x1, 0x78(%rax)
jne 0x3b2a
movq -0x10(%rbp), %rax
movzbl 0x7a(%rax), %eax
addl $0x1, %eax
andl $0x1f, %eax
movb %al, %cl
movq -0x10(%rbp), %rax
movb %cl, 0x7a(%rax)
movq -0x10(%rbp), %rax
testb $0x1, 0x79(%rax)
je 0x3b28
movq -0x10(%rbp), %rax
movzbl 0x7a(%rax), %ecx
movl $0x1f, %eax
cmpl %ecx, %eax
jne 0x3b28
movq -0x10(%rbp), %rax
movb $0x1, 0x78(%rax)
jmp 0x3b2a
movq -0x10(%rbp), %rax
movzbl 0x32(%rax), %eax
movl %eax, %ecx
leaq 0x20f55(%rip), %rax     # 0x24a90
shlq $0x5, %rcx
addq %rcx, %rax
movq -0x10(%rbp), %rcx
movzbl 0x7a(%rcx), %ecx
movb (%rax,%rcx), %cl
movq -0x10(%rbp), %rax
movb %cl, 0x7b(%rax)
jmp 0x3b56
movq -0x10(%rbp), %rax
movl 0x8c(%rax), %ecx
subl $0x10, %ecx
movl %ecx, 0x8c(%rax)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8c(%rax)
jg 0x3c9a
movq -0x10(%rbp), %rax
movl 0x88(%rax), %ecx
movq -0x10(%rbp), %rax
addl 0x8c(%rax), %ecx
movl %ecx, 0x8c(%rax)
xorps %xmm0, %xmm0
movss %xmm0, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
cmpl $0x3, -0x28(%rbp)
jge 0x3c6e
movq -0x10(%rbp), %rax
addq $0x38, %rax
movslq -0x28(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl -0x28(%rbp), %ecx
addl $0x8, %ecx
movslq %ecx, %rcx
movzbl 0x25(%rax,%rcx), %ecx
andl $0x10, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x3c0a
movq -0x10(%rbp), %rax
movl -0x28(%rbp), %ecx
addl $0x8, %ecx
movslq %ecx, %rcx
movzbl 0x25(%rax,%rcx), %eax
andl $0xf, %eax
movslq %eax, %rcx
leaq 0x20d72(%rip), %rax     # 0x24970
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x34(%rbp)
jmp 0x3c25
movq -0x10(%rbp), %rax
movzbl 0x7b(%rax), %eax
movl %eax, %ecx
leaq 0x20d55(%rip), %rax     # 0x24970
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0x34(%rbp)
movq -0x30(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x30(%rbp), %rcx
orl 0x8(%rcx), %eax
movq -0x10(%rbp), %rcx
movl 0x6c(%rcx), %ecx
andl $0x1, %ecx
movq -0x30(%rbp), %rdx
orl 0xc(%rdx), %ecx
andl %ecx, %eax
movl %eax, -0x38(%rbp)
cmpl $0x0, -0x38(%rbp)
je 0x3c5e
movss -0x34(%rbp), %xmm0
addss -0x24(%rbp), %xmm0
movss %xmm0, -0x24(%rbp)
jmp 0x3c60
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x3ba3
movq -0x10(%rbp), %rdi
movss -0x24(%rbp), %xmm0
callq 0x3cb0
movq -0x10(%rbp), %rax
mulss 0x90(%rax), %xmm0
movq -0x10(%rbp), %rax
movss %xmm0, 0x94(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x3c9e
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)