]> git.sur5r.net Git - cc65/commitdiff
POSIX file I/O by Oliver Schmidt
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 12 Apr 2005 09:12:48 +0000 (09:12 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 12 Apr 2005 09:12:48 +0000 (09:12 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3457 b7a2c559-68d2-44c3-8de9-860c34a00d81

12 files changed:
libsrc/apple2/Makefile
libsrc/apple2/close.s [new file with mode: 0644]
libsrc/apple2/filedes.inc [new file with mode: 0644]
libsrc/apple2/filedes.s [new file with mode: 0644]
libsrc/apple2/fileerr.s [new file with mode: 0644]
libsrc/apple2/filename.s [new file with mode: 0644]
libsrc/apple2/open.s [new file with mode: 0644]
libsrc/apple2/oserror.s [new file with mode: 0644]
libsrc/apple2/read.s
libsrc/apple2/rwcommon.s [new file with mode: 0644]
libsrc/apple2/write.s
libsrc/apple2enh/Makefile

index 82da35128d34bb4e035c1f9827703336912c9e35..d5fa0553e746785a4d3e11fe3bfa15c45eb219fc 100644 (file)
@@ -43,6 +43,7 @@ OBJS= _scrsize.o      \
        cclear.o        \
        cgetc.o         \
        chline.o        \
+       close.o         \
        clrscr.o        \
        color.o         \
        cputc.o         \
@@ -57,6 +58,9 @@ OBJS= _scrsize.o      \
        diosectsize.o   \
        diowrite.o      \
        dosdetect.o     \
+       filedes.o       \
+       fileerr.o       \
+       filename.o      \
         get_ostype.o    \
         getenv.o        \
        gotoxy.o        \
@@ -65,7 +69,9 @@ OBJS= _scrsize.o      \
        kbhit.o         \
         mainargs.o      \
        mli.o           \
+       open.o          \
         oserrlist.o     \
+       oserror.o       \
         randomize.o     \
         rcout.o         \
        read.o          \
@@ -75,6 +81,7 @@ OBJS= _scrsize.o      \
         rpread.o        \
         rrdkey.o        \
         rvtabz.o        \
+       rwcommon.o      \
         systime.o       \
         sysuname.o      \
         tgi_mode_table.o\
diff --git a/libsrc/apple2/close.s b/libsrc/apple2/close.s
new file mode 100644 (file)
index 0000000..737e29d
--- /dev/null
@@ -0,0 +1,41 @@
+;
+; Oliver Schmidt, 30.12.2004
+;
+; int __fastcall__ close (int fd);
+;
+
+        .export        _close
+
+        .import                closedirect, freebuffer
+        .import        errnoexit, oserrexit
+        .import        return0
+
+        .include       "filedes.inc"
+
+_close:
+        ; Process fd
+        jsr    getfd           ; Returns A, Y and C
+        bcs    errno
+
+        ; Check for device
+        bmi    zerofd
+
+        ; Close file
+        jsr    closedirect     ; Preserves Y
+        bcs    oserr
+
+        ; Mark fdtab slot as free
+zerofd: lda    #$00
+        sta    fdtab + FD::REF_NUM,y
+
+        ; Cleanup I/O buffer
+        jsr    freebuffer
+
+        ; Return success
+        jmp    return0
+
+        ; Return errno
+errno:  jmp    errnoexit
+
+        ; Return oserror
+oserr:  jmp    oserrexit
diff --git a/libsrc/apple2/filedes.inc b/libsrc/apple2/filedes.inc
new file mode 100644 (file)
index 0000000..1922f46
--- /dev/null
@@ -0,0 +1,16 @@
+;
+; Oliver Schmidt, 30.12.2004
+;
+; File descriptor management for the POSIX I/O routines
+;
+
+.struct FD
+        REF_NUM        .byte
+        FLAGS  .byte
+        BUFFER .addr
+.endstruct
+
+        .global                fdtab
+        .global                getfd
+
+MAX_FDS = 8
diff --git a/libsrc/apple2/filedes.s b/libsrc/apple2/filedes.s
new file mode 100644 (file)
index 0000000..094783a
--- /dev/null
@@ -0,0 +1,64 @@
+;
+; Oliver Schmidt, 30.12.2004
+;
+; File descriptor management for the POSIX I/O routines
+;
+
+        .include       "errno.inc"
+        .include       "fcntl.inc"
+        .include       "filedes.inc"
+
+getfd:
+        ; Check for handle >= 256
+        cpx    #$00
+        bne    error
+
+        ; Check for handle >= MAX_FDS
+        cmp    #MAX_FDS
+        bcs    error
+
+        .if    .sizeof(FD) = 4
+
+        ; Convert handle to fdtab slot
+        asl
+        asl
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        ; Check for fdtab slot in use
+        tay
+        lda    fdtab + FD::REF_NUM,y
+        beq    error
+
+        ; Return success
+        clc
+        rts
+
+        ; Load errno code and return error
+error:  lda    #EINVAL
+        sec
+        rts
+
+        .data
+
+fdtab:  .if    .sizeof(FD) = 4
+
+        .byte  $80             ; STDIN_FILENO ::REF_NUM
+        .byte  O_RDONLY        ; STDIN_FILENO ::FLAGS
+        .addr  $0000           ; STDIN_FILENO ::BUFFER
+
+        .byte  $80             ; STDOUT_FILENO::REF_NUM
+        .byte  O_WRONLY        ; STDOUT_FILENO::FLAGS
+        .addr  $0000           ; STDOUT_FILENO::BUFFER
+
+        .byte  $80             ; STDERR_FILENO::REF_NUM
+        .byte  O_WRONLY        ; STDERR_FILENO::FLAGS
+        .addr  $0000           ; STDERR_FILENO::BUFFER
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        .res   (MAX_FDS - 3) * .sizeof(FD)
diff --git a/libsrc/apple2/fileerr.s b/libsrc/apple2/fileerr.s
new file mode 100644 (file)
index 0000000..91dbcbd
--- /dev/null
@@ -0,0 +1,18 @@
+;
+; Oliver Schmidt, 15.01.2004
+;
+; Error handling for ProDOS 8 file I/O
+;
+
+        .export                errnoexit, oserrexit
+
+        .include       "errno.inc"
+
+errnoexit:
+        jsr    __seterrno      ; Returns with A = 0
+
+oserrexit:
+        sta     __oserror
+        lda    #$FF
+        tax
+        rts
diff --git a/libsrc/apple2/filename.s b/libsrc/apple2/filename.s
new file mode 100644 (file)
index 0000000..f00ce24
--- /dev/null
@@ -0,0 +1,97 @@
+;
+; Oliver Schmidt, 30.12.2004
+;
+; File name handling for ProDOS 8 file I/O
+;
+
+        .export        pushname, popname
+        .import                subysp, addysp, decsp1
+
+        .include       "zeropage.inc"
+        .include       "mli.inc"
+
+pushname:
+        sta    ptr1
+        stx    ptr1+1
+
+        ; Alloc pathname buffer
+        ldy    #64+1           ; Max pathname length + zero
+        jsr    subysp
+
+        ; Check for full pathname
+        ldy    #$00
+        lda    (ptr1),y
+        cmp    #'/'
+        beq    copy
+
+        ; Check for system prefix
+        lda    PFIXPTR
+        bne    copy
+
+        ; Use unit number of most recent accessed device
+        lda    DEVNUM
+        sta    mliparam + MLI::ON_LINE::UNIT_NUM
+
+        ; Use allocated pathname buffer
+        lda    sp
+        ldx    sp+1
+        sta    mliparam + MLI::ON_LINE::DATA_BUFFER
+        stx    mliparam + MLI::ON_LINE::DATA_BUFFER+1
+
+        ; Get volume name
+        lda    #ON_LINE_CALL
+        ldx    #ON_LINE_COUNT
+        jsr    callmli
+        bcs    addsp65
+
+        ; Get volume name length
+        lda    (sp),y
+        and    #15             ; Max volume name length
+
+        ; Bracket volume name with slashes to form prefix
+        sta    tmp1
+        lda    #'/'
+        sta    (sp),y
+        ldy    tmp1
+        iny                    ; Leading slash
+        sta    (sp),y
+        iny                    ; Trailing slash
+
+        ; Adjust source pointer for copy
+        sty    tmp1
+        lda    ptr1
+        sec
+        sbc    tmp1
+        bcs    :+
+        dec    ptr1+1
+:       sta    ptr1
+
+        ; Copy source to allocated pathname buffer
+copy:   lda    (ptr1),y
+        sta    (sp),y
+        beq    setlen
+        iny
+        cpy    #64+1           ; Max pathname length + zero
+        bcc    copy
+
+        ; Load oserror code
+        lda    #$40            ; "Invalid pathname syntax"
+
+        ; Free pathname buffer
+addsp65:ldy     #64+1
+        bne    addsp           ; Branch always
+
+        ; Alloc and set length byte
+setlen: tya
+        jsr    decsp1          ; Preserves A
+        ldy    #$00
+        sta    (sp),y
+
+        ; Return success
+        tya
+        rts
+
+popname:
+        ; Cleanup stack
+        ldy    #1 + 64+1       ; Length byte + max pathname length + zero
+addsp:  jmp    addysp          ; Preserves A
diff --git a/libsrc/apple2/open.s b/libsrc/apple2/open.s
new file mode 100644 (file)
index 0000000..ca08735
--- /dev/null
@@ -0,0 +1,247 @@
+;
+; Oliver Schmidt, 30.12.2004
+;
+; int open (const char* name, int flags, ...);
+;
+; Be sure to keep the value priority of closeallfiles lower than that of
+; closeallstreams (which is the high level C file I/O counterpart and must be
+; called before closeallfiles).
+
+        .export        _open, closedirect, freebuffer
+        .destructor    closeallfiles, 17
+
+        .import                pushname, popname
+        .import        errnoexit, oserrexit
+        .import                __aligned_malloc, _free
+        .import        addysp, incsp4, pushax, popax
+
+        .include       "zeropage.inc"
+        .include       "errno.inc"
+        .include       "fcntl.inc"
+        .include       "mli.inc"
+        .include       "filedes.inc"
+
+_open:
+        ; Throw away all parameters except name
+        ; and flags occupying together 4 bytes
+        dey
+        dey
+        dey
+        dey
+        jsr    addysp
+
+        ; Start with first fdtab slot
+        ldy    #$00
+
+        ; Check for free fdtab slot
+:       lda    fdtab + FD::REF_NUM,y
+        beq    found
+
+        .if    .sizeof(FD) = 4
+
+        ; Advance to next fdtab slot
+        iny
+        iny
+        iny
+        iny
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        ; Check for end of fdtab
+        cpy    #MAX_FDS * .sizeof(FD)
+        bcc    :-
+
+        ; Load errno codes
+        lda    #ENOMEM ^ EMFILE
+enomem: eor    #ENOMEM
+
+        ; Cleanup stack
+        jsr    incsp4          ; Preserves A
+
+        ; Return errno
+        jmp    errnoexit
+
+        ; Save fdtab slot
+found:  tya
+        pha
+
+        ; Alloc I/O buffer
+        lda    #$00
+        ldx    #>$0400
+        jsr    pushax          ; Preserves A
+        ldx    #>$0100
+        jsr    __aligned_malloc
+
+        ; Restore fdtab slot
+        pla
+        tay
+
+        ; Get and check I/O buffer high byte
+        txa
+        beq    enomem
+
+        ; Set I/O buffer high byte (low byte remains zero)
+        sta    fdtab + FD::BUFFER+1,y
+
+        sty    tmp2            ; Save fdtab slot
+
+        ; Get and save flags
+        jsr    popax
+        sta    tmp3
+
+        ; Get and push name
+        jsr    popax
+        jsr    pushname
+        bne    oserr1
+
+        ; Set pushed name
+        lda    sp
+        ldx    sp+1
+        sta    mliparam + MLI::OPEN::PATHNAME
+        stx    mliparam + MLI::OPEN::PATHNAME+1
+
+        ; Check for create flag
+        lda    tmp3            ; Restore flags
+        and    #O_CREAT
+        beq    open
+
+        .if    MLI::CREATE::PATHNAME = MLI::OPEN::PATHNAME
+
+        ; PATHNAME already set
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        ; Set all other parameters from template
+        ldx    #(MLI::CREATE::CREATE_TIME+1) - (MLI::CREATE::PATHNAME+1) - 1
+:       lda    CREATE,x
+        sta    mliparam + MLI::CREATE::ACCESS,x
+        dex
+        bpl    :-
+
+        ; Create file
+        lda    #CREATE_CALL
+        ldx    #CREATE_COUNT
+        jsr    callmli
+        bcc    open
+
+        ; Check for ordinary errors
+        cmp    #$47            ; "Duplicate filename"
+        bne    oserr2
+
+        ; Check for exclusive flag
+        lda    tmp3            ; Restore flags
+        and    #O_EXCL
+        beq    open
+
+        lda    #$47            ; "Duplicate filename"
+        
+        ; Cleanup name
+oserr2: jsr    popname         ; Preserves A
+
+oserr1: ldy    tmp2            ; Restore fdtab slot
+
+        ; Cleanup I/O buffer
+        pha                    ; Save oserror code
+        jsr    freebuffer
+        pla                    ; Restore oserror code
+        
+        ; Return oserror
+        jmp    oserrexit
+
+open:   ldy    tmp2            ; Restore fdtab slot
+
+        ; Set allocated I/O buffer
+        ldx    fdtab + FD::BUFFER+1,y
+        sta    mliparam + MLI::OPEN::IO_BUFFER         ; A = 0
+        stx    mliparam + MLI::OPEN::IO_BUFFER+1
+
+        ; Open file
+        lda    #OPEN_CALL
+        ldx    #OPEN_COUNT
+        jsr    callmli
+        bcs    oserr2
+
+        ; Get and save fd
+        ldx    mliparam + MLI::OPEN::REF_NUM
+        stx    tmp1            ; Save fd
+
+        ; Set flags and check for truncate flag
+        lda    tmp3            ; Restore flags
+        sta    fdtab + FD::FLAGS,y
+        and    #O_TRUNC
+        beq    done
+
+        ; Set fd and zero size
+        stx    mliparam + MLI::EOF::REF_NUM
+        ldx    #$02
+        lda    #$00
+:       sta    mliparam + MLI::EOF::EOF,x
+        dex
+        bpl    :-
+
+        ; Set file size
+        lda    #SET_EOF_CALL
+        ldx    #EOF_COUNT
+        jsr    callmli
+        bcc    done
+
+        ; Cleanup file
+        pha                    ; Save oserror code
+        lda    tmp1            ; Restore fd
+        jsr    closedirect
+        pla                    ; Restore oserror code
+        bne    oserr2          ; Branch always
+
+        ; Store fd
+done:   lda    tmp1            ; Restore fd
+        sta    fdtab + FD::REF_NUM,y
+
+        .if    .sizeof(FD) = 4
+
+        ; Convert fdtab slot to handle
+        tya
+        lsr
+        lsr
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        ; Cleanup name
+        jsr    popname         ; Preserves A
+        
+        ; Return success
+        ldx    #$00
+        rts
+
+freebuffer:
+        ; Free I/O buffer
+        lda    #$00
+        ldx    fdtab + FD::BUFFER+1,y
+        jmp    _free
+
+closeallfiles:
+        ; All open files
+        lda    #$00
+
+closedirect:
+        ; Set fd
+        sta    mliparam + MLI::CLOSE::REF_NUM
+
+        ; Call close
+        lda    #CLOSE_CALL
+        ldx    #CLOSE_COUNT
+        jmp    callmli
+
+        .rodata
+
+CREATE: .byte  %11000011       ; ACCESS:       Standard full access
+        .byte  $06             ; FILE_TYPE:    Standard binary file
+        .word  $0000           ; AUX_TYPE:     Load address N/A
+        .byte  $01             ; STORAGE_TYPE: Standard seedling file
+        .word  $0000           ; CREATE_DATE:  Current date
+        .word  $0000           ; CREATE_TIME:  Current time
diff --git a/libsrc/apple2/oserror.s b/libsrc/apple2/oserror.s
new file mode 100644 (file)
index 0000000..88420a5
--- /dev/null
@@ -0,0 +1,62 @@
+;
+; Ullrich von Bassewitz, 17.05.2000
+;
+; int __fastcall__ _osmaperrno (unsigned char oserror);
+;
+
+        .export        __osmaperrno
+
+        .include       "errno.inc"
+
+__osmaperrno:
+        ldx    #ErrTabSize
+:       cmp    ErrTab-2,x      ; Search for the error code
+        beq    :+              ; Jump if found
+        dex
+        dex
+        bne    :-              ; Next entry
+
+        ; Code not found, return EUNKNOWN
+        lda    #<EUNKNOWN
+        ldx    #>EUNKNOWN
+        rts
+
+        ; Found the code
+:       lda    ErrTab-1,x
+        ldx    #$00            ; High byte always zero
+        rts
+
+        .rodata
+
+ErrTab: .byte   $01, ENOSYS    ; Invalid MLI function code number
+        .byte  $04, EINVAL     ; Incorrect parameter count
+        .byte  $25, ENOMEM     ; Interrupt table full
+        .byte  $27, EIO        ; I/O error
+        .byte  $28, ENODEV     ; No device connected
+        .byte  $2B, EACCES     ; Write protected
+;       .byte  $2E, EUNKNOWN   ; Disk switched
+        .byte  $2F, ENODEV     ; No disk in drive
+        .byte  $40, EINVAL     ; Invalid pathname syntax
+        .byte  $42, EMFILE     ; Too many files open
+        .byte  $43, EINVAL     ; Bad reference number
+        .byte  $44, ENOENT     ; Bad pathname
+        .byte  $45, ENOENT     ; Volume not mounted
+        .byte  $46, ENOENT     ; File not found
+        .byte  $47, EEXIST     ; File already exists
+        .byte  $48, ENOSPC     ; Disk full
+        .byte  $49, ENOSPC     ; Directory full
+;       .byte  $4A, EUNKNOWN   ; Incompatible ProDOS version
+        .byte  $4B, EINVAL     ; Unsupported storage type
+;       .byte  $4C, EUNKNOWN   ; End of file
+        .byte  $4D, ESPIPE     ; Position past EOF
+        .byte  $4E, EACCES     ; Access denied
+        .byte  $50, EINVAL     ; File already open
+;       .byte  $51, EUNKNOWN   ; File count bad
+        .byte  $52, ENODEV     ; Not a ProDOS disk
+        .byte  $53, ERANGE     ; Parameter out of range
+        .byte  $55, EMFILE     ; Too many devices mounted
+        .byte  $56, EINVAL     ; Bad buffer address
+;       .byte  $57, EUNKNOWN   ; Duplicate volume name
+;       .byte  $5A, EUNKNOWN   ; Damaged disk free space bit map
+
+ErrTabSize = (* - ErrTab)
index cfabdb1329f3d8b3d6c755f80246b5a62445f685..ed84e70e193827471e13218c29cdcbd9b2f5bf33 100644 (file)
 ;
-; Ullrich von Bassewitz, 30.05.1998
+; Oliver Schmidt, 12.01.2005
 ;
-; int read (int fd, void* buf, int count);
-;
-; THIS IS A HACK!
+; int __fastcall__ read (int fd, void* buf, unsigned count);
 ;
 
-       .export         _read
-       .import         popax, _cputc, RDKEY
-       .importzp       ptr1, ptr2, ptr3
-
-_read: jsr     popax           ; get count
-       sta     ptr2
-       stx     ptr2+1          ; save it for later
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard it
-       lda     #$00
-       sta     ptr3
-       sta     ptr3+1          ; set count
-
-L1:            lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       jsr     RDKEY
-       and     #$7F            ; clear high bit.
-       pha
-       jsr     _cputc
-       pla
-       ldy     #$00            ; offset into string
-       sta     (ptr1),y        ; save char
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:            inc     ptr3            ; increment count
-       bne     L3
-       inc     ptr3+1
-L3:    cmp     #$0D            ; CR?
-       bne     L1
-
-; Done, return the count
-
-L9:     lda    ptr3
-       ldx     ptr3+1
-       rts
+        .constructor   initprompt
+        .export                _read
+        .import                rwprolog, rwcommon
+        .import                errnoexit
+        .import                RDKEY, COUT
+
+        .include       "zeropage.inc"
+        .include       "errno.inc"
+        .include       "fcntl.inc"
+        .include       "mli.inc"
+        .include       "filedes.inc"
+        .include       "apple2.inc"
+
+        .segment       "INIT"
+
+initprompt:
+        ; Set prompt <> ']' to let DOS 3.3 know that we're
+        ; not in Applesoft immediate mode and thus keep it
+        ; from scanning our device I/O for DOS commands.
+        lda    #$80            ; Same value used at $D52C
+        sta    PROMPT
+        rts
+
+        .code
+
+_read:
+        ; Get parameters
+        jsr    rwprolog
+        bcs    errno
+        tax                    ; Save fd
+
+        ; Check for read access
+        lda    fdtab + FD::FLAGS,y
+        and    #O_RDONLY
+        beq    einval
+
+        ; Check for device
+        txa                    ; Restore fd
+        bmi    device
+
+        ; Do read
+        ldy    #READ_CALL
+        jmp    rwcommon
+
+        ; Set counter to zero
+device: lda    #$00
+        sta    ptr3
+        sta    ptr3+1
+
+        ; Check for zero count
+        lda    ptr2
+        ora    ptr2+1
+        beq    check
+
+        ; Read from device and echo to device
+next:   jsr    RDKEY
+        jsr    COUT
+
+        ; Clear hi bit and check for '\r'
+        and    #$7F
+        cmp    #$0D
+        bne    :+
+
+        ; Replace with '\n' and set count to zero
+        lda    #$0A
+        ldy    #$00
+        sty    ptr2
+        sty    ptr2+1
+
+        ; Put char into buf
+:       ldy    #$00
+        sta    (ptr1),y
+
+        ; Increment pointer
+        inc    ptr1
+        bne    :+
+        inc    ptr1+1
+
+        ; Increment counter
+:       inc    ptr3
+        bne    check
+        inc    ptr3+1
+
+        ; Check for counter less than count
+check:  lda    ptr3
+        cmp    ptr2
+        bcc    next
+        ldx    ptr3+1
+        cpx    ptr2+1
+        bcc    next
 
+        ; Return success, AX already set
+        rts
 
+        ; Load errno code
+einval: lda    #EINVAL
 
+        ; Return errno
+errno:  jmp    errnoexit
diff --git a/libsrc/apple2/rwcommon.s b/libsrc/apple2/rwcommon.s
new file mode 100644 (file)
index 0000000..06d7911
--- /dev/null
@@ -0,0 +1,59 @@
+;
+; Oliver Schmidt, 12.01.2005
+;
+
+        .export                rwprolog, rwcommon, rwepilog
+        .import                oserrexit
+        .import                popax
+
+        .include       "zeropage.inc"
+        .include       "fcntl.inc"
+        .include       "mli.inc"
+        .include       "filedes.inc"
+
+rwprolog:
+        ; Save count
+        sta    ptr2
+        stx    ptr2+1
+
+        ; Get and save buf
+        jsr    popax
+        sta    ptr1
+        stx    ptr1+1
+
+        ; Get and process fd
+        jsr    popax
+        jmp    getfd           ; Returns A, Y and C
+
+rwcommon:
+        ; Set fd
+        sta    mliparam + MLI::RW::REF_NUM
+
+        ; Set buf
+        lda    ptr1
+        ldx    ptr1+1
+        sta    mliparam + MLI::RW::DATA_BUFFER
+        stx    mliparam + MLI::RW::DATA_BUFFER+1
+
+        ; Set count
+        lda    ptr2
+        ldx    ptr2+1
+        sta    mliparam + MLI::RW::REQUEST_COUNT
+        stx    mliparam + MLI::RW::REQUEST_COUNT+1
+
+        ; Call read or write
+        tya
+        ldx    #RW_COUNT
+        jsr    callmli
+        bcc    rwepilog
+        cmp    #$4C            ; "End of file"
+        bne    oserr
+
+rwepilog:
+        ; Return success
+        lda    mliparam + MLI::RW::TRANS_COUNT
+        ldx    mliparam + MLI::RW::TRANS_COUNT+1
+        rts
+
+        ; Return oserror
+oserr:  jmp    oserrexit
index 3fa48203113a444edaa0a793c0b9c2ec73d57833..59a30b1e8a554ca8c3bb97238674ecade773f294 100644 (file)
-       ;;
-       ;; Kevin Ruland
-       ;;
-       ;; int write (int fd, const void* buf, int count);
-       ;;
-       ;; for now will only write to fd = stdout
-       ;;
-
-       .export         _write
-       .import         popax, COUT
-       .importzp       ptr1, ptr2, ptr3
-
-.proc   _write
-
-       sta     ptr2            ; Save count for later
-       stx     ptr2+1
-       sta     ptr3
-       sta     ptr3+1          ; save for result
-       jsr     popax           ; get buf
-       sta     ptr1
-       stx     ptr1+1
-       jsr     popax           ; get fd and discard
-L1:    lda     ptr2
-       ora     ptr2+1          ; count zero?
-       beq     L9
-       ldy     #$00
-       lda     (ptr1),y
-       cmp     #$0A            ; Check for \n = Crtl-j
-       bne     rawout
-       lda     #$0D            ; Issue cr
-rawout:
-       ora     #$80
-       jsr     COUT
-       inc     ptr1
-       bne     L2
-       inc     ptr1+1
-L2:    lda     ptr2
-       bne     L3
-       dec     ptr2
-       dec     ptr2+1
-       jmp     L1
-L3:    dec     ptr2
-       jmp     L1
-
-; No error, return count
-
-L9:    lda     ptr3
-       ldx     ptr3+1
-       rts
-
-.endproc
+;
+; Oliver Schmidt, 12.01.2005
+;
+; int __fastcall__ write (int fd, const void* buf, unsigned count);
+;
 
+        .export                _write
+        .import                rwprolog, rwcommon, rwepilog
+        .import                errnoexit, oserrexit
+        .import                COUT
+
+        .include       "zeropage.inc"
+        .include       "errno.inc"
+        .include       "fcntl.inc"
+        .include       "mli.inc"
+        .include       "filedes.inc"
+
+_write:
+        ; Get parameters
+        jsr    rwprolog
+        bcs    errno
+        tax                    ; Save fd
+
+        ; Check for write access
+        lda    fdtab + FD::FLAGS,y
+        and    #O_WRONLY
+        beq    einval
+
+        ; Check for device
+        txa                    ; Restore fd
+        bmi    device
+
+        ; Check        for append flag
+        lda    fdtab + FD::FLAGS,y
+        and    #O_APPEND
+        beq    write
+
+        ; Set fd
+        stx    mliparam + MLI::EOF::REF_NUM
+
+        ; Get file size
+        lda    #GET_EOF_CALL
+        ldx    #EOF_COUNT
+        jsr    callmli
+        bcs    oserr
+
+        .if    MLI::MARK::REF_NUM = MLI::EOF::REF_NUM
+
+        ; REF_NUM already set
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        .if    MLI::MARK::POSITION = MLI::EOF::EOF
+
+        ; POSITION already set
+
+        .else
+        .error "Assertion failed"
+        .endif
+
+        ; Set file pointer
+        lda    #SET_MARK_CALL
+        ldx    #MARK_COUNT
+        jsr    callmli
+        bcs    oserr
+
+        ; Do write
+write:  lda    fdtab + FD::REF_NUM,y
+        ldy    #WRITE_CALL
+        jmp    rwcommon
+
+        ; Save count for epilog
+device: ldx    ptr2
+        lda    ptr2+1
+        stx    mliparam + MLI::RW::TRANS_COUNT
+        sta    mliparam + MLI::RW::TRANS_COUNT+1
+
+        ; Check for zero count
+        ora    ptr2
+        beq    done
+
+        ; Get char from buf
+        ldy    #$00
+next:   lda    (ptr1),y
+
+        ; Replace '\n' with '\r'
+        cmp    #$0A
+        bne    :+
+        lda    #$0D
+
+        ; Set hi bit and write to device
+:       ora    #$80
+        .ifndef        __APPLE2ENH__
+        cmp    #$E0            ; Test for lowercase
+        bcc    output
+        and    #$DF            ; Convert to uppercase
+        .endif
+output: jsr    COUT            ; Preserves X and Y
+
+        ; Increment pointer
+        iny
+        bne    :+
+        inc    ptr1+1
+
+        ; Decrement count
+:       dex
+        bne    next
+        dec    ptr2+1
+        bpl    next
+
+        ; Return success
+done:   jmp    rwepilog
+
+        ; Load errno code
+einval: lda    #EINVAL
+
+        ; Return errno
+errno:  jmp    errnoexit
+
+        ; Return oserror
+oserr:  jmp    oserrexit
index dc809675b40e0f3c7fac5191a2c2fd8d7bc40642..406611f2c3a3b9ad9053d93c4f980d596d174526 100644 (file)
@@ -43,6 +43,7 @@ OBJS= _scrsize.o      \
        cclear.o        \
        cgetc.o         \
        chline.o        \
+       close.o         \
        clrscr.o        \
        color.o         \
        cputc.o         \
@@ -57,6 +58,9 @@ OBJS= _scrsize.o      \
        diosectsize.o   \
        diowrite.o      \
        dosdetect.o     \
+       filedes.o       \
+       fileerr.o       \
+       filename.o      \
         get_ostype.o    \
         getenv.o        \
        gotoxy.o        \
@@ -65,7 +69,9 @@ OBJS= _scrsize.o      \
        kbhit.o         \
         mainargs.o      \
        mli.o           \
+       open.o          \
         oserrlist.o     \
+       oserror.o       \
         randomize.o     \
         rcout.o         \
        read.o          \
@@ -75,6 +81,7 @@ OBJS= _scrsize.o      \
         rpread.o        \
         rrdkey.o        \
         rvtabz.o        \
+       rwcommon.o      \
         systime.o       \
         sysuname.o      \
        textframe.o     \