// File: /workspace/github_c_makefile_star2_O1/serge-404[P]CPM32/cpm.c
// Function: cpm_file_rw
byte cpm_file_rw( byte *fcbaddr, byte wr, int rnd)
{
    int i, n, p, max;
    struct FCB *fcb = (struct FCB *)fcbaddr;


    if ( rnd) {
        if ( fcb->r2) return 6;
        p = fcb->r0 + ( fcb->r1 << 8);
        fcb->cr = (byte)(p & 0x7f); fcb->ex = (byte)(p >> 7);
    } else {
        p = (fcb->cr & 0x7f) + (fcb->ex << 7);
    }
    max = fcb->d[1] + (fcb->d[2] << 8) + (fcb->d[3] << 16);

DEBUGOUT( stderr, "BDOS: %s%s file '%11.11s'. @%d", 
      rnd ? "random ": "", wr ? "write" : "read", fcbaddr + 1, p);

    if (( i = fcb->d[ 0]) == 0 || --i >= MAXFCB || fcbs[ i].fp == NULL) {
        if ( !wr && p >= max) return 1;
        if ( cpm_file_open( fcbaddr, wr ? CF_WROPEN : CF_OPEN)) return 0xff;
        fcb->cr = (byte)(p & 0x7f); fcb->ex = (byte)(p >> 7); /* 2012.02 bugfix 8->7 */
        i = fcb->d[ 0] - 1;
    } else if ( !fcbs[ i].mod && wr) {
        fclose( fcbs[ i].fp);
        if ( !mk_filename( filename, fcbaddr) ||
             ( fcbs[ i].fp = fopen( filename, "r+b")) == NULL) {
            cpm_file_close( fcbaddr);
            return 0xff;
        }
        fcbs[ i].pos = 0;
    }

    if ((unsigned)(n = p << 7) != fcbs[ i].pos || fcbs[ i].wr != wr) {
        if (( !wr && p > max) ||
             fseek( fcbs[ i].fp, n, SEEK_SET)) {
            cpm_file_close( fcbaddr);
            return 1;
        }
        fcbs[ i].pos = n;
    }

    if ( wr) {
        fcbs[ i].mod = fcbs[ i].wr = TRUE;
        if ( fwrite( mem + cpm_dma_addr, 128, 1, fcbs[ i].fp) != 1)
             return 1;
        n = 128;
    } else {
        fcbs[ i].wr = FALSE;
        if (( n = fread( mem + cpm_dma_addr, 1, 128, fcbs[ i].fp)) <= 0) {
            if ( !fcbs[ i].mod) cpm_file_close( fcbaddr);
            return 1;
        }
        if ( n < 128) memset( mem + cpm_dma_addr + n, 0x1a, 128 - n);
    }
    fcbs[ i].pos += n;

    ++p;
    if ( !rnd) { fcb->cr = (byte)(p & 0x7f); fcb->ex = (byte)(p >> 7); }
    if ( p >= max && !fcbs[ i].mod) cpm_file_close( fcbaddr);
    if ( p > max) {
        fcb->d[ 1] = (byte)p;
        fcb->d[ 2] = (byte)(p >> 8);
        fcb->d[ 3] = (byte)(p >> 16);
        fcb->rc = (byte)(p & 0x7f);
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %ecx
movl %esi, %r15d
movq %rdi, %rbx
testl %edx, %edx
je 0x9953
movb $0x6, %r12b
cmpb $0x0, 0x23(%rbx)
jne 0x9c19
movzbl 0x21(%rbx), %eax
movzbl 0x22(%rbx), %r14d
shll $0x8, %r14d
orl %eax, %r14d
andb $0x7f, %al
movb %al, 0x20(%rbx)
movl %r14d, %eax
shrl $0x7, %eax
movb %al, 0xc(%rbx)
jmp 0x9966
movzbl 0x20(%rbx), %eax
andl $0x7f, %eax
movzbl 0xc(%rbx), %r14d
shll $0x7, %r14d
orl %eax, %r14d
movzwl 0x11(%rbx), %r13d
movzbl 0x13(%rbx), %ebp
shll $0x10, %ebp
cmpl $0x0, 0x10a99b(%rip)    # 0x114314
jne 0x9abe
orl %ebp, %r13d
movzbl 0x10(%rbx), %r12d
testl %r12d, %r12d
je 0x9a10
cmpb $0x40, %r12b
ja 0x9a10
decl %r12d
movl %r12d, %eax
shlq $0x5, %rax
leaq 0x10c769(%rip), %rbp    # 0x116110
movq (%rax,%rbp), %rdi
testq %rdi, %rdi
je 0x9a10
movl %ecx, 0x4(%rsp)
testb %r15b, %r15b
je 0x9a5a
addq %rax, %rbp
cmpb $0x0, 0x19(%rbp)
jne 0x9a5a
callq 0x20c0
leaq 0x10c10a(%rip), %rdi    # 0x115ae0
movq %rbx, %rsi
callq 0x8dfc
testq %rax, %rax
je 0x9aae
leaq 0x10c0f2(%rip), %rdi    # 0x115ae0
leaq 0x743e(%rip), %rsi      # 0x10e33
callq 0x2340
movq %rax, (%rbp)
testq %rax, %rax
je 0x9aae
movl $0x0, 0x8(%rbp)
jmp 0x9a5a
testb %r15b, %r15b
jne 0x9a21
movb $0x1, %r12b
cmpl %r13d, %r14d
jge 0x9c19
xorl %esi, %esi
testb %r15b, %r15b
setne %sil
movq %rbx, %rdi
movl %ecx, 0x4(%rsp)
callq 0x9564
movb $-0x1, %r12b
testb %al, %al
jne 0x9c19
movl %r14d, %eax
andb $0x7f, %al
movb %al, 0x20(%rbx)
movl %r14d, %eax
shrl $0x7, %eax
movb %al, 0xc(%rbx)
movzbl 0x10(%rbx), %r12d
decl %r12d
movl %r14d, %ebp
shll $0x7, %ebp
movslq %r12d, %rax
shlq $0x5, %rax
leaq 0x10c6a2(%rip), %rcx    # 0x116110
leaq (%rcx,%rax), %r12
cmpl 0x8(%rax,%rcx), %ebp
jne 0x9a83
cmpb %r15b, 0x18(%r12)
je 0x9b16
testb %r15b, %r15b
jne 0x9a8d
cmpl %r13d, %r14d
jg 0x9a9e
movq (%r12), %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0x22d0
testl %eax, %eax
je 0x9b11
movq %rbx, %rdi
callq 0x97fc
movb $0x1, %r12b
jmp 0x9c19
movq %rbx, %rdi
callq 0x97fc
movb $-0x1, %r12b
jmp 0x9c19
testl %ecx, %ecx
movq 0xa531(%rip), %rax      # 0x13ff8
movq (%rax), %rdi
leaq 0x7418(%rip), %rax      # 0x10ee9
leaq 0x73a1(%rip), %rdx      # 0x10e79
cmoveq %rax, %rdx
testb %r15b, %r15b
leaq 0x73a1(%rip), %rax      # 0x10e87
movl %ecx, %r12d
leaq 0x7391(%rip), %rcx      # 0x10e81
cmoveq %rax, %rcx
leaq 0x1(%rbx), %r8
leaq 0x735b(%rip), %rsi      # 0x10e5a
movl %r14d, %r9d
xorl %eax, %eax
callq 0x2210
movl %r12d, %ecx
jmp 0x997f
movl %ebp, 0x8(%r12)
testb %r15b, %r15b
je 0x9b5f
movw $0x101, 0x18(%r12)      # imm = 0x101
movzwl 0xa6e8(%rip), %edi      # 0x14212
addq 0xa6c7(%rip), %rdi      # 0x141f8
movq (%r12), %rcx
movl $0x80, %esi
movl $0x1, %edx
callq 0x23b0
movq %r12, %rcx
movb $0x1, %r12b
movl $0x80, %r15d
cmpq $0x1, %rax
movl 0x4(%rsp), %eax
je 0x9bcb
jmp 0x9c19
movb $0x0, 0x18(%r12)
movzwl 0xa6a6(%rip), %edi      # 0x14212
addq 0xa685(%rip), %rdi      # 0x141f8
movq (%r12), %rcx
movl $0x1, %esi
movl $0x80, %edx
callq 0x20b0
movq %rax, %r15
testl %r15d, %r15d
jle 0x9c2b
cmpl $0x7f, %r15d
jg 0x9bc4
movzwl 0xa673(%rip), %eax      # 0x14212
addq 0xa652(%rip), %rax      # 0x141f8
movl %r15d, %edi
andl $0x7fffffff, %edi       # imm = 0x7FFFFFFF
addq %rax, %rdi
movl $0x80, %edx
subl %r15d, %edx
movl $0x1a, %esi
callq 0x2150
movl 0x4(%rsp), %eax
movq %r12, %rcx
addl %r15d, 0x8(%rcx)
leal 0x1(%r14), %edx
testl %eax, %eax
jne 0x9be6
movl %edx, %eax
andb $0x7f, %al
movb %al, 0x20(%rbx)
movl %edx, %eax
shrl $0x7, %eax
movb %al, 0xc(%rbx)
cmpl %r13d, %edx
jl 0x9bfd
cmpb $0x0, 0x19(%rcx)
jne 0x9bfd
movq %rbx, %rdi
movl %edx, %ebp
callq 0x97fc
movl %ebp, %edx
cmpl %r13d, %r14d
jl 0x9c16
movb %dl, 0x11(%rbx)
movb %dh, 0x12(%rbx)
movl %edx, %eax
shrl $0x10, %eax
movb %al, 0x13(%rbx)
andb $0x7f, %dl
movb %dl, 0xf(%rbx)
xorl %r12d, %r12d
movl %r12d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r12, %rax
movb $0x1, %r12b
cmpb $0x0, 0x19(%rax)
jne 0x9c19
movq %rbx, %rdi
callq 0x97fc
jmp 0x9c19