Files

190 lines
4.2 KiB
ArmAsm

;
; Oliver Schmidt, 12.01.2005
; Robert Justice, 2026
;
; int __fastcall__ write (int fd, const void* buf, unsigned count);
;
.export _write
.import rwprolog, rwcommon, writeepilog
.import putcdirect, consref, setstdioscr, consscrflg
.include "zeropage.inc"
.include "errno.inc"
.include "fcntl.inc"
.include "sos.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 not device
txa ; Restore fd
cmp #$80
beq device
; Check for append flag
lda fdtab + FD::FLAGS,y
and #O_APPEND
beq write
; Set fd
stx sosparam + SOS::GET_EOF::REF_NUM
; Get file size
lda #GET_EOF_CALL
ldx #GET_EOF_COUNT
jsr callsos
bne oserr
; REF_NUM already set
.assert SOS::GET_MARK::REF_NUM = SOS::GET_EOF::REF_NUM, error
; POSITION already set
.assert SOS::GET_MARK::POSITION = SOS::GET_EOF::EOF, error
; Set file pointer
lda #SET_MARK_CALL
ldx #SET_MARK_COUNT
jsr callsos
bne oserr
; Do write
write: lda fdtab + FD::REF_NUM,y
write2: ldy #WRITE_CALL
jmp rwcommon
; Load errno code
einval: lda #EINVAL
; Set __errno
errno: jmp ___directerrno
; Set ___oserror
oserr: jmp ___mappederrno
; Save request count for return
device: ldx ptr2
stx tmp3
stx ptr3
lda ptr2+1
sta tmp4
sta ptr3+1
; Set console ref
ldy consref
sty sosparam + SOS::RW::REF_NUM
; Check for zero count
ora ptr2
beq done
; check for zero low byte with non zero high byte
txa
bne :+
dec ptr3+1
; Copy ptr1 to ptr4 to use for scan pos
: lda ptr1
sta ptr4
lda ptr1+1
sta ptr4+1
; Check char from buf
ldy #$00 ; y = chunk size low byte
sty ptr2+1 ; zero chunk size high byte
next: lda (ptr4),y
cmp #$0A ; test for \n = line feed
beq havelf
; Increment pointer
iny
bne :+
inc ptr4+1
inc ptr2+1
; Decrement count
: dex
bne next
lda ptr3+1
beq outdone
dec ptr3+1
ldx #$00
beq next
; Output when we get a lf
havelf: iny
jsr output
lda #$0D ; send carriage return
jsr putcdirect
; Update ptr1
lda ptr1
clc
adc ptr2
sta ptr1
lda ptr1+1
adc ptr2+1
sta ptr1+1
; ptr4 = new chunk start
lda ptr1
sta ptr4
lda ptr1+1
sta ptr4+1
; Restore X, Y
ldx ptr3
ldy #0
sty ptr2+1
; Dec count for lf, and exit if done
dex
bne next
lda ptr3+1
beq done
dec ptr3+1
ldx #$00
beq next
; Output whatever is left
outdone:
jsr output
; Return success
done: lda #$00
sta ___oserror ; A = 0
lda tmp3 ; original requested bytes
ldx tmp4
rts
; output to console
output: sty ptr2 ; save Y
stx ptr3 ; save X
ldx #$03
: lda ptr1,x
sta sosparam + SOS::RW::DATA_BUFFER,x
dex
bpl :-
bit consscrflg ; check if scroll is on
bne :+
jsr setstdioscr
:
lda #WRITE_CALL
ldx #WRITE_COUNT
jsr callsos
rts