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 \
|
||||
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\
|
||||
|
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);
|
||||
;
|
||||
; THIS IS A HACK!
|
||||
; int __fastcall__ read (int fd, void* buf, unsigned count);
|
||||
;
|
||||
|
||||
.constructor initprompt
|
||||
.export _read
|
||||
.import popax, _cputc, RDKEY
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.import rwprolog, rwcommon
|
||||
.import errnoexit
|
||||
.import RDKEY, COUT
|
||||
|
||||
_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
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
.include "fcntl.inc"
|
||||
.include "mli.inc"
|
||||
.include "filedes.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
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
|
||||
.segment "INIT"
|
||||
|
||||
; Done, return the count
|
||||
|
||||
L9: lda ptr3
|
||||
ldx ptr3+1
|
||||
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
|
||||
|
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
|
||||
;;
|
||||
;; int write (int fd, const void* buf, int count);
|
||||
;;
|
||||
;; for now will only write to fd = stdout
|
||||
;;
|
||||
;
|
||||
; Oliver Schmidt, 12.01.2005
|
||||
;
|
||||
; int __fastcall__ write (int fd, const void* buf, unsigned count);
|
||||
;
|
||||
|
||||
.export _write
|
||||
.import popax, COUT
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.import rwprolog, rwcommon, rwepilog
|
||||
.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
|
||||
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
|
||||
_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
|
||||
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
|
||||
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
|
||||
L2: lda ptr2
|
||||
bne L3
|
||||
dec ptr2
|
||||
|
||||
; Decrement count
|
||||
: dex
|
||||
bne next
|
||||
dec ptr2+1
|
||||
jmp L1
|
||||
L3: dec ptr2
|
||||
jmp L1
|
||||
bpl next
|
||||
|
||||
; No error, return count
|
||||
; Return success
|
||||
done: jmp rwepilog
|
||||
|
||||
L9: lda ptr3
|
||||
ldx ptr3+1
|
||||
rts
|
||||
; Load errno code
|
||||
einval: lda #EINVAL
|
||||
|
||||
.endproc
|
||||
; Return errno
|
||||
errno: jmp errnoexit
|
||||
|
||||
; Return oserror
|
||||
oserr: jmp oserrexit
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user