// File: /workspace/github_c_makefile_star2_O3/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 0x9d75
movb $0x6, %r12b
cmpb $0x0, 0x23(%rbx)
jne 0xa03c
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 0x9d88
movzbl 0x20(%rbx), %eax
andl $0x7f, %eax
movzbl 0xc(%rbx), %r14d
shll $0x7, %r14d
orl %eax, %r14d
movzwl 0x11(%rbx), %ebp
movzbl 0x13(%rbx), %r13d
shll $0x10, %r13d
cmpl $0x0, 0x10a578(%rip)    # 0x114314
jne 0x9ee1
orl %ebp, %r13d
movzbl 0x10(%rbx), %r12d
testl %r12d, %r12d
je 0x9e33
cmpb $0x40, %r12b
ja 0x9e33
decl %r12d
movl %r12d, %eax
shlq $0x5, %rax
leaq 0x10c346(%rip), %rbp    # 0x116110
movq (%rax,%rbp), %rdi
testq %rdi, %rdi
je 0x9e33
movl %ecx, 0x4(%rsp)
testb %r15b, %r15b
je 0x9e7d
addq %rax, %rbp
cmpb $0x0, 0x19(%rbp)
jne 0x9e7d
callq 0x20c0
leaq 0x10bce7(%rip), %rdi    # 0x115ae0
movq %rbx, %rsi
callq 0x91e6
testq %rax, %rax
je 0x9ed1
leaq 0x10bccf(%rip), %rdi    # 0x115ae0
leaq 0x704b(%rip), %rsi      # 0x10e63
callq 0x2330
movq %rax, (%rbp)
testq %rax, %rax
je 0x9ed1
movl $0x0, 0x8(%rbp)
jmp 0x9e7d
testb %r15b, %r15b
jne 0x9e44
movb $0x1, %r12b
cmpl %r13d, %r14d
jae 0xa03c
xorl %esi, %esi
testb %r15b, %r15b
setne %sil
movq %rbx, %rdi
movl %ecx, 0x4(%rsp)
callq 0x9977
movb $-0x1, %r12b
testb %al, %al
jne 0xa03c
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 0x10c27f(%rip), %rcx    # 0x116110
leaq (%rcx,%rax), %r12
cmpl 0x8(%rax,%rcx), %ebp
jne 0x9ea6
cmpb %r15b, 0x18(%r12)
je 0x9f39
testb %r15b, %r15b
jne 0x9eb0
cmpl %r13d, %r14d
ja 0x9ec1
movq (%r12), %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0x22c0
testl %eax, %eax
je 0x9f34
movq %rbx, %rdi
callq 0x9c2f
movb $0x1, %r12b
jmp 0xa03c
movq %rbx, %rdi
callq 0x9c2f
movb $-0x1, %r12b
jmp 0xa03c
testl %ecx, %ecx
movq 0xa10e(%rip), %rax      # 0x13ff8
movq (%rax), %rdi
leaq 0x7025(%rip), %rax      # 0x10f19
leaq 0x6fae(%rip), %rdx      # 0x10ea9
cmoveq %rax, %rdx
testb %r15b, %r15b
leaq 0x6fae(%rip), %rax      # 0x10eb7
movl %ecx, %r12d
leaq 0x6f9e(%rip), %rcx      # 0x10eb1
cmoveq %rax, %rcx
leaq 0x1(%rbx), %r8
leaq 0x6f68(%rip), %rsi      # 0x10e8a
movl %r14d, %r9d
xorl %eax, %eax
callq 0x2200
movl %r12d, %ecx
jmp 0x9da2
movl %ebp, 0x8(%r12)
testb %r15b, %r15b
je 0x9f82
movw $0x101, 0x18(%r12)      # imm = 0x101
movzwl 0xa2bd(%rip), %edi      # 0x1420a
addq 0xa29c(%rip), %rdi      # 0x141f0
movq (%r12), %rcx
movl $0x80, %esi
movl $0x1, %edx
callq 0x23a0
movq %r12, %rcx
movb $0x1, %r12b
movl $0x80, %r15d
cmpq $0x1, %rax
movl 0x4(%rsp), %eax
je 0x9fee
jmp 0xa03c
movb $0x0, 0x18(%r12)
movzwl 0xa27b(%rip), %edi      # 0x1420a
addq 0xa25a(%rip), %rdi      # 0x141f0
movq (%r12), %rcx
movl $0x1, %esi
movl $0x80, %edx
callq 0x20b0
movq %rax, %r15
testl %r15d, %r15d
jle 0xa04e
cmpl $0x7f, %r15d
ja 0x9fe7
movzwl 0xa248(%rip), %eax      # 0x1420a
addq 0xa227(%rip), %rax      # 0x141f0
movl %r15d, %edi
andl $0x7f, %edi
addq %rax, %rdi
movl $0x80, %eax
subl %r15d, %eax
movzbl %al, %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 0xa009
movl %edx, %eax
andb $0x7f, %al
movb %al, 0x20(%rbx)
movl %edx, %eax
shrl $0x7, %eax
movb %al, 0xc(%rbx)
cmpl %r13d, %edx
jb 0xa020
cmpb $0x0, 0x19(%rcx)
jne 0xa020
movq %rbx, %rdi
movl %edx, %ebp
callq 0x9c2f
movl %ebp, %edx
cmpl %r13d, %r14d
jb 0xa039
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 0xa03c
movq %rbx, %rdi
callq 0x9c2f
jmp 0xa03c