// File: /workspace/github_c_makefile_star2_O2/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 0x86b4
movb $0x6, %r12b
cmpb $0x0, 0x23(%rbx)
jne 0x896e
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 0x86c7
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, 0x10ac39(%rip)    # 0x113314
jne 0x8819
orl %ebp, %r13d
movzbl 0x10(%rbx), %r12d
testl %r12d, %r12d
je 0x876b
cmpb $0x40, %r12b
ja 0x876b
decl %r12d
movl %r12d, %eax
shlq $0x5, %rax
leaq 0x10ca0b(%rip), %rbp    # 0x115110
movq (%rax,%rbp), %rdi
testq %rdi, %rdi
je 0x876b
movl %ecx, 0x4(%rsp)
testb %r15b, %r15b
je 0x87b5
addq %rax, %rbp
cmpb $0x0, 0x19(%rbp)
jne 0x87b5
callq 0x20c0
leaq 0x10c3ac(%rip), %rdi    # 0x114ae0
movq %rbx, %rsi
callq 0x7c2a
testq %rax, %rax
je 0x8809
leaq 0x10c394(%rip), %rdi    # 0x114ae0
leaq 0x76e0(%rip), %rsi      # 0xfe33
callq 0x2340
movq %rax, (%rbp)
testq %rax, %rax
je 0x8809
andl $0x0, 0x8(%rbp)
jmp 0x87b5
testb %r15b, %r15b
jne 0x877c
movb $0x1, %r12b
cmpl %r13d, %r14d
jae 0x896e
xorl %esi, %esi
testb %r15b, %r15b
setne %sil
movq %rbx, %rdi
movl %ecx, 0x4(%rsp)
callq 0x82b7
movb $-0x1, %r12b
testb %al, %al
jne 0x896e
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 0x10c947(%rip), %rcx    # 0x115110
leaq (%rcx,%rax), %r12
cmpl 0x8(%rax,%rcx), %ebp
jne 0x87de
cmpb %r15b, 0x18(%r12)
je 0x8871
testb %r15b, %r15b
jne 0x87e8
cmpl %r13d, %r14d
ja 0x87f9
movq (%r12), %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0x22d0
testl %eax, %eax
je 0x886c
movq %rbx, %rdi
callq 0x8555
movb $0x1, %r12b
jmp 0x896e
movq %rbx, %rdi
callq 0x8555
movb $-0x1, %r12b
jmp 0x896e
testl %ecx, %ecx
movq 0xa7d6(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
leaq 0x76bd(%rip), %rax      # 0xfee9
leaq 0x7646(%rip), %rdx      # 0xfe79
cmoveq %rax, %rdx
testb %r15b, %r15b
leaq 0x7646(%rip), %rax      # 0xfe87
movl %ecx, %r12d
leaq 0x7636(%rip), %rcx      # 0xfe81
cmoveq %rax, %rcx
leaq 0x1(%rbx), %r8
leaq 0x7600(%rip), %rsi      # 0xfe5a
movl %r14d, %r9d
xorl %eax, %eax
callq 0x2200
movl %r12d, %ecx
jmp 0x86e1
movl %ebp, 0x8(%r12)
testb %r15b, %r15b
je 0x88b8
movw $0x101, 0x18(%r12)      # imm = 0x101
movzwl 0xa98d(%rip), %edi      # 0x13212
addq 0xa96c(%rip), %rdi      # 0x131f8
movq (%r12), %rcx
pushq $0x1
popq %rdx
movl $0x80, %esi
callq 0x23b0
movq %r12, %rcx
movb $0x1, %r12b
movl $0x80, %r15d
cmpq $0x1, %rax
movl 0x4(%rsp), %eax
je 0x8920
jmp 0x896e
movb $0x0, 0x18(%r12)
movzwl 0xa94d(%rip), %edi      # 0x13212
addq 0xa92c(%rip), %rdi      # 0x131f8
movq (%r12), %rcx
pushq $0x1
popq %rsi
movl $0x80, %edx
callq 0x20b0
movq %rax, %r15
testl %r15d, %r15d
jle 0x8980
cmpl $0x7f, %r15d
ja 0x8919
movzwl 0xa91c(%rip), %eax      # 0x13212
addq 0xa8fb(%rip), %rax      # 0x131f8
movl %r15d, %edi
andl $0x7f, %edi
addq %rax, %rdi
movl $0x80, %eax
subl %r15d, %eax
movzbl %al, %edx
pushq $0x1a
popq %rsi
callq 0x2150
movl 0x4(%rsp), %eax
movq %r12, %rcx
addl %r15d, 0x8(%rcx)
leal 0x1(%r14), %edx
testl %eax, %eax
jne 0x893b
movl %edx, %eax
andb $0x7f, %al
movb %al, 0x20(%rbx)
movl %edx, %eax
shrl $0x7, %eax
movb %al, 0xc(%rbx)
cmpl %r13d, %edx
jb 0x8952
cmpb $0x0, 0x19(%rcx)
jne 0x8952
movq %rbx, %rdi
movl %edx, %ebp
callq 0x8555
movl %ebp, %edx
cmpl %r13d, %r14d
jb 0x896b
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 0x896e
movq %rbx, %rdi
callq 0x8555
jmp 0x896e