mirror of
https://github.com/cc65/cc65.git
synced 2024-12-24 11:31:31 +00:00
POSIX file I/O by Oliver Schmidt
git-svn-id: svn://svn.cc65.org/cc65/trunk@3457 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
49d1b8f553
commit
feacac1394
@ -43,6 +43,7 @@ OBJS= _scrsize.o \
|
|||||||
cclear.o \
|
cclear.o \
|
||||||
cgetc.o \
|
cgetc.o \
|
||||||
chline.o \
|
chline.o \
|
||||||
|
close.o \
|
||||||
clrscr.o \
|
clrscr.o \
|
||||||
color.o \
|
color.o \
|
||||||
cputc.o \
|
cputc.o \
|
||||||
@ -57,6 +58,9 @@ OBJS= _scrsize.o \
|
|||||||
diosectsize.o \
|
diosectsize.o \
|
||||||
diowrite.o \
|
diowrite.o \
|
||||||
dosdetect.o \
|
dosdetect.o \
|
||||||
|
filedes.o \
|
||||||
|
fileerr.o \
|
||||||
|
filename.o \
|
||||||
get_ostype.o \
|
get_ostype.o \
|
||||||
getenv.o \
|
getenv.o \
|
||||||
gotoxy.o \
|
gotoxy.o \
|
||||||
@ -65,7 +69,9 @@ OBJS= _scrsize.o \
|
|||||||
kbhit.o \
|
kbhit.o \
|
||||||
mainargs.o \
|
mainargs.o \
|
||||||
mli.o \
|
mli.o \
|
||||||
|
open.o \
|
||||||
oserrlist.o \
|
oserrlist.o \
|
||||||
|
oserror.o \
|
||||||
randomize.o \
|
randomize.o \
|
||||||
rcout.o \
|
rcout.o \
|
||||||
read.o \
|
read.o \
|
||||||
@ -75,6 +81,7 @@ OBJS= _scrsize.o \
|
|||||||
rpread.o \
|
rpread.o \
|
||||||
rrdkey.o \
|
rrdkey.o \
|
||||||
rvtabz.o \
|
rvtabz.o \
|
||||||
|
rwcommon.o \
|
||||||
systime.o \
|
systime.o \
|
||||||
sysuname.o \
|
sysuname.o \
|
||||||
tgi_mode_table.o\
|
tgi_mode_table.o\
|
||||||
|
41
libsrc/apple2/close.s
Normal file
41
libsrc/apple2/close.s
Normal file
@ -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
|
16
libsrc/apple2/filedes.inc
Normal file
16
libsrc/apple2/filedes.inc
Normal file
@ -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
|
64
libsrc/apple2/filedes.s
Normal file
64
libsrc/apple2/filedes.s
Normal file
@ -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)
|
18
libsrc/apple2/fileerr.s
Normal file
18
libsrc/apple2/fileerr.s
Normal file
@ -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
|
97
libsrc/apple2/filename.s
Normal file
97
libsrc/apple2/filename.s
Normal file
@ -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
|
247
libsrc/apple2/open.s
Normal file
247
libsrc/apple2/open.s
Normal file
@ -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
|
62
libsrc/apple2/oserror.s
Normal file
62
libsrc/apple2/oserror.s
Normal file
@ -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)
|
@ -1,50 +1,105 @@
|
|||||||
;
|
;
|
||||||
; Ullrich von Bassewitz, 30.05.1998
|
; Oliver Schmidt, 12.01.2005
|
||||||
;
|
;
|
||||||
; int read (int fd, void* buf, int count);
|
; int __fastcall__ read (int fd, void* buf, unsigned count);
|
||||||
;
|
|
||||||
; THIS IS A HACK!
|
|
||||||
;
|
;
|
||||||
|
|
||||||
.export _read
|
.constructor initprompt
|
||||||
.import popax, _cputc, RDKEY
|
.export _read
|
||||||
.importzp ptr1, ptr2, ptr3
|
.import rwprolog, rwcommon
|
||||||
|
.import errnoexit
|
||||||
|
.import RDKEY, COUT
|
||||||
|
|
||||||
_read: jsr popax ; get count
|
.include "zeropage.inc"
|
||||||
sta ptr2
|
.include "errno.inc"
|
||||||
stx ptr2+1 ; save it for later
|
.include "fcntl.inc"
|
||||||
jsr popax ; get buf
|
.include "mli.inc"
|
||||||
sta ptr1
|
.include "filedes.inc"
|
||||||
stx ptr1+1
|
.include "apple2.inc"
|
||||||
jsr popax ; get fd and discard it
|
|
||||||
lda #$00
|
|
||||||
sta ptr3
|
|
||||||
sta ptr3+1 ; set count
|
|
||||||
|
|
||||||
L1: lda ptr2
|
.segment "INIT"
|
||||||
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
|
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
|
||||||
|
|
||||||
L9: lda ptr3
|
.code
|
||||||
ldx ptr3+1
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
_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
|
||||||
|
59
libsrc/apple2/rwcommon.s
Normal file
59
libsrc/apple2/rwcommon.s
Normal file
@ -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
|
@ -1,52 +1,123 @@
|
|||||||
;;
|
;
|
||||||
;; Kevin Ruland
|
; Oliver Schmidt, 12.01.2005
|
||||||
;;
|
;
|
||||||
;; int write (int fd, const void* buf, int count);
|
; int __fastcall__ write (int fd, const void* buf, unsigned count);
|
||||||
;;
|
;
|
||||||
;; for now will only write to fd = stdout
|
|
||||||
;;
|
|
||||||
|
|
||||||
.export _write
|
.export _write
|
||||||
.import popax, COUT
|
.import rwprolog, rwcommon, rwepilog
|
||||||
.importzp ptr1, ptr2, ptr3
|
.import errnoexit, oserrexit
|
||||||
|
.import COUT
|
||||||
|
|
||||||
.proc _write
|
.include "zeropage.inc"
|
||||||
|
.include "errno.inc"
|
||||||
|
.include "fcntl.inc"
|
||||||
|
.include "mli.inc"
|
||||||
|
.include "filedes.inc"
|
||||||
|
|
||||||
sta ptr2 ; Save count for later
|
_write:
|
||||||
stx ptr2+1
|
; Get parameters
|
||||||
sta ptr3
|
jsr rwprolog
|
||||||
sta ptr3+1 ; save for result
|
bcs errno
|
||||||
jsr popax ; get buf
|
tax ; Save fd
|
||||||
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
|
; Check for write access
|
||||||
|
lda fdtab + FD::FLAGS,y
|
||||||
|
and #O_WRONLY
|
||||||
|
beq einval
|
||||||
|
|
||||||
L9: lda ptr3
|
; Check for device
|
||||||
ldx ptr3+1
|
txa ; Restore fd
|
||||||
rts
|
bmi device
|
||||||
|
|
||||||
.endproc
|
; 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
|
||||||
|
@ -43,6 +43,7 @@ OBJS= _scrsize.o \
|
|||||||
cclear.o \
|
cclear.o \
|
||||||
cgetc.o \
|
cgetc.o \
|
||||||
chline.o \
|
chline.o \
|
||||||
|
close.o \
|
||||||
clrscr.o \
|
clrscr.o \
|
||||||
color.o \
|
color.o \
|
||||||
cputc.o \
|
cputc.o \
|
||||||
@ -57,6 +58,9 @@ OBJS= _scrsize.o \
|
|||||||
diosectsize.o \
|
diosectsize.o \
|
||||||
diowrite.o \
|
diowrite.o \
|
||||||
dosdetect.o \
|
dosdetect.o \
|
||||||
|
filedes.o \
|
||||||
|
fileerr.o \
|
||||||
|
filename.o \
|
||||||
get_ostype.o \
|
get_ostype.o \
|
||||||
getenv.o \
|
getenv.o \
|
||||||
gotoxy.o \
|
gotoxy.o \
|
||||||
@ -65,7 +69,9 @@ OBJS= _scrsize.o \
|
|||||||
kbhit.o \
|
kbhit.o \
|
||||||
mainargs.o \
|
mainargs.o \
|
||||||
mli.o \
|
mli.o \
|
||||||
|
open.o \
|
||||||
oserrlist.o \
|
oserrlist.o \
|
||||||
|
oserror.o \
|
||||||
randomize.o \
|
randomize.o \
|
||||||
rcout.o \
|
rcout.o \
|
||||||
read.o \
|
read.o \
|
||||||
@ -75,6 +81,7 @@ OBJS= _scrsize.o \
|
|||||||
rpread.o \
|
rpread.o \
|
||||||
rrdkey.o \
|
rrdkey.o \
|
||||||
rvtabz.o \
|
rvtabz.o \
|
||||||
|
rwcommon.o \
|
||||||
systime.o \
|
systime.o \
|
||||||
sysuname.o \
|
sysuname.o \
|
||||||
textframe.o \
|
textframe.o \
|
||||||
|
Loading…
Reference in New Issue
Block a user