cclear.o \
cgetc.o \
chline.o \
+ close.o \
clrscr.o \
color.o \
cputc.o \
diosectsize.o \
diowrite.o \
dosdetect.o \
+ filedes.o \
+ fileerr.o \
+ filename.o \
get_ostype.o \
getenv.o \
gotoxy.o \
kbhit.o \
mainargs.o \
mli.o \
+ open.o \
oserrlist.o \
+ oserror.o \
randomize.o \
rcout.o \
read.o \
rpread.o \
rrdkey.o \
rvtabz.o \
+ rwcommon.o \
systime.o \
sysuname.o \
tgi_mode_table.o\
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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)
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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
--- /dev/null
+;
+; 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)
;
-; 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
--- /dev/null
+;
+; 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
- ;;
- ;; 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
cclear.o \
cgetc.o \
chline.o \
+ close.o \
clrscr.o \
color.o \
cputc.o \
diosectsize.o \
diowrite.o \
dosdetect.o \
+ filedes.o \
+ fileerr.o \
+ filename.o \
get_ostype.o \
getenv.o \
gotoxy.o \
kbhit.o \
mainargs.o \
mli.o \
+ open.o \
oserrlist.o \
+ oserror.o \
randomize.o \
rcout.o \
read.o \
rpread.o \
rrdkey.o \
rvtabz.o \
+ rwcommon.o \
systime.o \
sysuname.o \
textframe.o \