A2osX/SYS/KERNEL.S.STDIO.txt
2019-10-10 12:23:02 +02:00

1260 lines
24 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
*--------------------------------------
K.PrintF.PadL .EQ FAC+5
K.PrintF.PadC .EQ ARG.SIGN
*/--------------------------------------
* # putchar (BLOCKING)
* Print A (char) to StdOut
* ## C
* `int putchar ( int character );`
* ## ASM
* **In:**
* `lda character`
* `>SYSCALL putchar`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.PutChar >PUSHA character
ldy #S.PS.hStdOut
lda (pPs),y
jsr K.FPutC
bcc K.PutChar.RTS
tay E.NODATA
bpl K.PutChar.RTS
inc 0 = BLOCKING
K.PutChar.RET1 inc pStack
K.PutChar.RTS rts
*/--------------------------------------
* # fputc (BLOCKING)
* Print A (char) to hFILE
* ## C
* `int fputc ( hFILE stream , int character );`
* ## ASM
* **In:**
* `>PUSHB character`
* `lda stream`
* `>SYSCALL fputc`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.FPutC jsr PFT.CheckNodeA
bcs K.PutChar.RET1
lda (pStack) character
sta K.IOBuf
lda #0
>PUSHA
inc write 1 byte
>PUSHA
>PUSHWI K.IOBuf buf
jsr UNISTD.Write
bcc K.PutChar.RET1 pop char...
tay E.NODATA
bpl K.PutChar.RET1
inc 0 = BLOCKING
* sec
rts
*/--------------------------------------
* # puts (BLOCKING)
* Write Str to StdOut, appends '\r\n'
* ## C
* `int puts ( const char * str );`
* **In:**
* ## ASM
* `>LDYAI str`
* `>SYSCALL puts`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.PutS >STYA ZPPtr2
ldy #0
.1 lda (ZPPtr2),y
beq .2
sta K.IOBuf,y
iny
bne .1
.9 lda #E.BUF
sec
rts
.2 lda #C.CR
sta K.IOBuf,y
iny
beq .9
lda #C.LF
sta K.IOBuf,y
iny
beq .9
lda #0
sta K.IOBuf,y
>PUSHWI K.IOBuf
ldy #S.PS.hStdOut
lda (pPs),y
jsr K.FPutS
bcc K.PutS.RTS
tay
bne K.PutS.RTS 0 = BLOCKING
* sec
K.PutS.RET2 >POP 2 pop K.IOBuf
K.PutS.RTS rts
*/--------------------------------------
* # fputs (BLOCKING)
* Write Str to hFILE
* ## C
* `int fputs (hFILE stream, const char * str );`
* ## ASM
* **In:**
* `>PUSHW str`
* `lda stream`
* `>SYSCALL fputs`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.FPutS jsr PFT.CheckNodeA set IO.hFD
bcs K.PutS.RET2
lda (pStack)
sta ZPPtr2 Get String
ldy #1
lda (pStack),y
sta ZPPtr2+1
* ldy #0
dey
ldx #0
.1 lda (ZPPtr2),y
beq .2
iny
bne .1
inx
bra .1
.2 txa
>PUSHA push len HI
tya
>PUSHA push len LO
>PUSHW ZPPtr2
jsr UNISTD.Write
bcc K.PutS.RET2
tay
bpl K.PutS.RET2 IO Erorr
inc 0 = BLOCKING
* sec
rts
*/--------------------------------------
* # PrintF (BLOCKING)
* # FPrintF (BLOCKING)
* # SPrintF
* Prints C-Style String
* ## C
* `int printf ( const char * format, ... );`
* `int fprintf ( hFILE stream, const char * format, ... );`
* `int sprintf ( char * str, const char * format, ... );`
* ## ASM
* **In:**
* PrintF : (example is for printing Y,A as integer : format="%I", 2 bytes)
* `>PUSHYA` #I
* `>PUSHBI 2` #bytecount
* `...`
* `>LDYAI format`
* `>SYSCALL printf`
* FPrintF :
* `>PUSHYA` #I
* `>PUSHBI 2` #bytecount
* `...`
* `>PUSHWI format`
* `lda hFILE`
* `>SYSCALL fprintf`
* SPrintF :
* `>PUSHYA` #I
* `>PUSHBI 2` #bytecount
* `...`
* `>PUSHWI format`
* `>LDYAI str`
* `>SYSCALL sprintf`
* ## RETURN VALUE
* CC : success, Y,A = bytes sent
* CS : error, A = code from Output
* Specifiers :
* + %b : pull 1 byte to Print BIN
* + %d : pull 1 byte unsigned DEC 0..255
* + %D : pull 2 bytes unsigned DEC 0..65535
* + %u : pull 4 bytes long unsigned DEC 0..4294967295
* + %e : pull 5 Bytes float (-)1.23456789e+12
* + %f : pull 5 Bytes float (-)3.1415
* + %h : pull 1 byte to Print HEX
* + %H : pull 2 bytes to Print HEX
* + %i : pull 1 byte to Print signed DEC -128..127
* + %I : pull 2 bytes to Print signed DEC -32768..32767
* + %L : pull 4 bytes signed DEC -2147483648..2147483647
* + %s : pull 2 bytes ptr to C-Style String
* + %S : pull 2 bytes ptr to P-Style String
* + \b : Print 'BS' (08)
* + \e : Print 'ESC' ($1B,27)
* + \f : Print 'FF' ($0C,12)
* + \n : Print 'LF' ($0A,10)
* + \r : Print 'CR' ($0D,13)
* + \t : Print 'TAB' ($09,09)
* + \v : Print 'VT' ($0B,11)
* + \xHH : Print byte with hexadecimal value HH (1 to 2 digits)
* + \\\\ : Print \
* + \\% : Print %
* Modifiers for len and padding :
* + %d : '9' '12'
* + %2d : ' 9' '12'
* + %02d : '09' '12'
* + %11s : 'ABCDEFGH '
* + %011s : 'ABCDEFGH000'
* + %2f : '3.14'
*\--------------------------------------
.DUMMY
.OR ZPTMP+5 3 Bytes
PrintF.Cnt .BS 2
PrintF.hFILE .BS 1
.ED
*--------------------------------------
K.SPrintF stz PrintF.hFILE
>STYA pIOBuf str
jsr K.PrintF.GetFormat
bra K.PrintF.1
K.FPrintF sta PrintF.hFILE
jsr K.PrintF.GetFormat
bra K.PrintF.0
K.PrintF >STYA ZPPtr2 format
lda pStack
sta pLocal
ldy #S.PS.hStdOut
lda (pPs),y
sta PrintF.hFILE
K.PrintF.0 >LDYAI K.IOBuf
>STYA pIOBuf
K.PrintF.1 stz PrintF.Cnt
stz PrintF.Cnt+1
stz PrintF.LocalGetByte+1
.1 jsr SHARED.GetCharPtr2
bne .22
jmp .8 end of format..
.22 cmp #'%'
bne .10
stz K.PrintF.PadL
stz K.PrintF.PadC
lda (ZPPtr2)
beq .7 end of format... print % and exit
jsr ZP.IsDigit
bcs .6 no digit....go check specifier
cmp #'0' ...a 0...mmm... padding char?
bne .4
sta K.PrintF.PadC
jsr SHARED.NextCharPtr2 skip 0 ...
lda (ZPPtr2)
beq .7
jsr ZP.IsDigit
bcs .6 %0x ??????
.4 jsr MATH.Dec2ACC32
bcs .99
lda ACC32
sta K.PrintF.PadL
lda K.PrintF.PadC
bne .5
lda #C.SPACE
sta K.PrintF.PadC
.5 jsr SHARED.AddYToPtr2 skip all processed chars
lda (ZPPtr2)
beq .7
.6 ldx #PrintFTBL1.Cnt-1 do we have a %x command?
.61 cmp PrintFTBL1,x
beq .62
dex
bpl .61
bra .20 unknown ...
.62 jsr SHARED.NextCharPtr2
txa yes, jmp to it!
asl
tax
jsr PrintF.ESC
.11 bcc .1
bra .99
.7 lda #'%'
bra .20
*--------------------------------------
.10 cmp #'\'
bne .20
jsr SHARED.GetCharPtr2
beq .99
ldx #PrintFTBL2.Cnt-1
.12 cmp PrintFTBL2,x
beq .19
dex
bpl .12
cmp #'x' \xHH
bne .1
jsr MATH.Hex2ACC32
bcs .99
jsr SHARED.AddYToPtr2
.14 lda ACC32
bra .20
.19 lda PrintFTBL2.OUT,x
.20 jsr PrintF.COut
bcc .11
*--------------------------------------
.99 bra PrintF.LocalCleanUp
*--------------------------------------
.8 ldx PrintF.hFILE
beq .80 Writing to buffer, append \0
>PUSHW PrintF.Cnt Writing to File/dev...
>PUSHWI K.IOBuf
txa
jsr K.FWrite
bcc .81
tay
bne .99
>RET 4 0=BLOCKING
.80 ldy PrintF.Cnt A=0, Writing to buffer, append \0
sta (pIOBuf),y
.81 >LDYA PrintF.Cnt
* clc
*--------------------------------------
PrintF.LocalCleanUp
php
pha
lda pLocal
sec ByteCnt byte
adc (pLocal) ... ByteCnt
sta pStack CC
pla
plp
PrintF.LocalCleanUp.RTS
rts
*--------------------------------------
PrintF.LocalGetPtr
jsr PrintF.LocalGetByte
bcs PrintF.LocalCleanUp.RTS
tay
*--------------------------------------
PrintF.LocalGetByte
lda #$FF SELF MODIFIED LStack Ptr
cmp (pLocal)
beq .9 CS
phy
tay
iny
lda (pLocal),y
sty PrintF.LocalGetByte+1
ply
* clc
rts
.9 lda #E.STACK
* sec
rts
*--------------------------------------
PrintF.ESC jmp (.1,x)
.1 .DA PrintF.B
.DA PrintF.D,PrintF.DD,PrintF.U
.DA PrintF.E,PrintF.F
.DA PrintF.H,PrintF.HH
.DA PrintF.I,PrintF.II,PrintF.L
.DA PrintF.S,PrintF.SS
*--------------------------------------
PrintFTBL1 .AS "bdDuefhHiILsS"
PrintFTBL1.Cnt .EQ *-PrintFTBL1
PrintFTBL2 .AS "befnrtv\%"
PrintFTBL2.Cnt .EQ *-PrintFTBL2
PrintFTBL2.OUT .HS 08.1B.0C.0A.0D.09.0B \b\e\f\n\r\t\v
.DA #'\' \\
.DA #'%' \%
*--------------------------------------
PrintF.B jsr PrintF.LocalGetByte
bcs PrintF.B.RTS
ldy #8
.1 asl
pha
lda #'0'/2
rol
jsr PrintF.COut
bcs .9
pla
dey
bne .1
rts
.9 ply
PrintF.B.RTS
rts
*--------------------------------------
PrintF.I sec signed short
.HS 90 BCC
PrintF.D clc unsigned short (BYTE)
ldy #1
bra PrintF.NUM
PrintF.II sec signed int
.HS 90 BCC
PrintF.DD clc unsigned int (WORD)
ldy #2
bra PrintF.NUM
PrintF.L sec signed long
.HS 90 BCC
PrintF.U clc unsigned long (DWORD)
ldy #4
PrintF.NUM ror ACC32.Sign
ldx #0
.1 jsr PrintF.LocalGetByte
bcs PrintF.B.RTS
sta ACC32,x
inx
dey
bne .1
.2 cpx #4
beq .3
stz ACC32,x
inx
bra .2
.3 ldx K.PrintF.PadL
ldy K.PrintF.PadC
rol ACC32.Sign
jsr MATH.ACC322STR10
bra PrintF.StrNum
*--------------------------------------
* EXP(8) 1(s) 1significants(31)
* http://apple2.org.za/gswv/a2zine/GS.WorldView/Resources/GS.TECH.INFO/AppleSoft/
*--------------------------------------
PrintF.E sec Force "E+12"
.HS 90 BCC
PrintF.F clc
lda PrintF.LocalGetByte+1 get current stack Ptr
tay
clc at least 5 bytes remaining ?
adc #5
cmp (pStack)
bcc .1
bne PrintF.StrNum.RTS
.1 sta PrintF.LocalGetByte+1
tya
sec +1 for bytecount byte
adc pStack
ldy pStack+1 A,Y = float
ldx #FPU.SETFAC
jsr GP.ROMCALL
ldy #A2osX.NumStrBuf+1 FOUT.1 will do a DEY
ldx #FPU.FOUT
jsr GP.ROMCALL
PrintF.StrNum ldy #0
.2 lda A2osX.NumStrBuf,y
beq .8
iny
jsr PrintF.COut
bcc .2
.9 rts
.8 clc
PrintF.StrNum.RTS
rts
*--------------------------------------
PrintF.S ldy #$ff CSTR
.HS 2C bit abs
PrintF.SS ldy #$00 PSTR
sty .1+1
jsr PrintF.LocalGetPtr
bcs .9
sty ZPPtr1
sta ZPPtr1+1
lda (ZPPtr1) if CSTR:last char=0, if PSTR:len=0
beq .8
ldy .1+1
.1 lda #$ff Self Modified
bne .11 CSTR
tya PSTR
cmp (ZPPtr1) len check
beq .2
.11 iny
lda (ZPPtr1),y
beq .2
jsr PrintF.COut
bcs .9
lda K.PrintF.PadL
beq .1
cpy K.PrintF.PadL
bne .1
.8 clc
rts
.2 lda K.PrintF.PadL
beq .8
.3 cpy K.PrintF.PadL
beq .8
lda K.PrintF.PadC
jsr PrintF.COut
bcs .9
iny
bne .3
* clc
.9 rts
*--------------------------------------
PrintF.HH jsr PrintF.LocalGetByte
bcs PrintF.COut.RTS
pha LO byte
jsr PrintF.H
plx
bcs PrintF.COut.RTS
txa
bra PrintF.H.1
*--------------------------------------
PrintF.H jsr PrintF.LocalGetByte
bcs PrintF.COut.RTS
PrintF.H.1 jsr MATH.AToHexAX
jsr PrintF.COut
bcs PrintF.COut.RTS
txa
*--------------------------------------
PrintF.COut phy
ldy PrintF.Cnt
sta (pIOBuf),y
ply
inc PrintF.Cnt
bne .8
lda PrintF.hFILE
bne .9
inc pIOBuf+1
inc PrintF.Cnt+1
.8 clc
rts
.9 lda #E.BUF
sec
PrintF.COut.RTS rts
*--------------------------------------
K.PrintF.GetFormat
lda (pStack)
sta ZPPtr2
ldy #1
lda (pStack),y
sta ZPPtr2+1
lda pStack
inc
inc
sta pLocal
rts
*/--------------------------------------
* # fgets (BLOCKING)
* read bytes from stream into the array
* pointed to by s, until n-1 bytes are read, or a <newline> is read and
* transferred to s, or an end-of-file condition is encountered. The
* string is then terminated with a null byte.
* ## C
* `char *fgets(hFILE stream, char * s, int n);`
* ## ASM
* **In:**
* `>PUSHW n`
* `>PUSHW s`
* `lda hFILE`
* `>SYSCALL fgets`
* ## RETURN VALUE
* Y,A: s
* CC = success
*\--------------------------------------
* (pStack)+2 n
* (pStack)+0 s
*--------------------------------------
K.FGetS jsr PFT.CheckNodeA
bcs PrintF.COut.RTS
lda (pStack)
sta ZPPtr2 s LO
ldy #1
lda (pStack),y
sta ZPPtr2+1 s HI
iny
lda (pStack),y n LO
sta ZPPtr1
iny
lda (pStack),y n HI
sta ZPPtr1+1
bmi .3 already something in buffer
.1 jsr STDIO.Read.1
bcc .2
cmp #MLI.E.EOF
beq .9
tay
bpl .9 IO error
inc NO DATA -> BLOCKING
rts
.2 lda K.IOBuf
cmp #C.LF Discard any leading LF
beq .1
cmp #C.CR
beq .8 empty string
jsr SHARED.PutCharPtr2
lda ZPPtr1
eor #$ff
sta ZPPtr1
lda ZPPtr1+1
eor #$ff
sta ZPPtr1+1
.3 inc ZPPtr1
bne .4
inc ZPPtr1+1
beq .8 Buffer full
.4 jsr STDIO.Read.1
bcs .5
lda K.IOBuf
cmp #C.CR
beq .8
jsr SHARED.PutCharPtr2
bra .3
.5 cmp #MLI.E.EOF
beq .8 String terminated by EOF
tay
bpl .9 I/O error
lda ZPPtr2 NO DATA, but string not yet terminated
sta (pStack) s
ldy #1
lda ZPPtr2+1
sta (pStack),y s
iny
lda ZPPtr1
sta (pStack),y !n LO
iny
lda ZPPtr1+1
sta (pStack),y !n HI
lda #0 BLOCKING
sec
rts
.8 lda #0
sta (ZPPtr2) terminate string
clc
.9 >RET 4
*/--------------------------------------
* # getchar (BLOCKING)
* Get char from StdIn
* ## C
* `int getchar ();`
* ## ASM
* **In:**
* `>SYSCALL getchar`
* ## RETURN VALUE
* CC = success
* A = char
*\--------------------------------------
K.GetChar ldy #S.PS.hStdIn
lda (pPs),y
*/--------------------------------------
* # getc (BLOCKING)
* Get char from Node
* ## C
* `int getc ( hFILE stream );`
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL getc`
* ## RETURN VALUE
* CC = success
* A = char
*\--------------------------------------
K.GetC jsr PFT.CheckNodeA
bcs K.GetC.RTS
jsr STDIO.Read.1
bcc .8
tay
bpl K.GetC.RTS I/O error
inc 0 = BLOCKING
rts
.8 lda K.IOBuf
K.GetC.RTS rts
*--------------------------------------
STDIO.Read.1 lda #0
>PUSHA
inc read 1 byte
>PUSHA
>PUSHWI K.IOBuf
jmp UNISTD.READ
*/--------------------------------------
* # SScanF
* Read formatted data from string
* ## C
* `int sscanf ( const char * s, const char * format, ... );`
* ## ASM
* **In:**
* `>PUSHW ptr`
* `...`
* `>PUSHBI bytecount`
* `>PUSHWI format`
* + %i : short int
* + %d : byte
* + %I : int
* + %D : word
* + %L : long int
* + %U : dword
* + %h : HEX byte
* + %H : HEX word
* + %s : string
* TODO : %10s
* `>LDYA s`
* `>SYSCALL sscanf`
* ## RETURN VALUE
* A = Number of arguments filled.
*\--------------------------------------
K.SScanF jsr SHARED.SPtr2PPtr1 ptr2=String to Scan,Ptr1=format
lda pStack
sta pLocal
stz .8+1 rest Arg processed
stz PrintF.LocalGetByte+1
.1 jsr SHARED.GetCharPtr1 End Of format?
beq .8
cmp #'%' Escape ?
beq .2
cmp #' ' Space ?
beq .12
cmp (ZPPtr2) Same char in string?
bne .9
jsr SHARED.NextCharPtr2
bra .1
.12 jsr SHARED.NextCharPtr2 Space....
cmp (ZPPtr2) another one ?
beq .12
bne .1
.2 jsr SHARED.GetCharPtr1 Get specifier after %
beq .9 unexpected End of format after "%" ?
ldx #K.SScanFJMP-K.SScanFTBL-2
.3 cmp K.SScanFTBL,x
beq .4
dex
dex
bpl .3
.9 lda #MLI.E.EOF
sec
jmp PrintF.LocalCleanUp
.4 jsr PrintF.LocalGetPtr
bcs .9
sty ZPPtr3
sta ZPPtr3+1
jsr .5
bcs .9 out of Ptr on stack
inc .8+1 parsed one more arg!
bra .1
.8 lda #$ff SELF MODIFIED Arg processed
clc
jmp PrintF.LocalCleanUp
*--------------------------------------
.5 jmp (K.SScanFJMP,x)
*--------------------------------------
K.SScanFTBL .DA #'i,#1,#'d,#1,#'I,#2,#'D,#2,#'l,#4,#'u,#4,#'h,#1,#'H,#2,#'s,#2
K.SScanFJMP .DA K.SScanF.I
.DA K.SScanF.D
.DA K.SScanF.II
.DA K.SScanF.DD
.DA K.SScanF.L
.DA K.SScanF.U
.DA K.SScanF.H
.DA K.SScanF.HH
.DA K.SScanF.S
*--------------------------------------
K.SScanF.I
K.SScanF.D
K.SScanF.II
K.SScanF.DD
K.SScanF.L
K.SScanF.U lda K.SScanFTBL+1,x Get VAR size
pha Save VAL size
jsr MATH.Dec2ACC32
bra K.SScanF.GetVAL
*--------------------------------------
K.SScanF.HH
K.SScanF.H lda K.SScanFTBL+1,x Get VAR size
pha
jsr MATH.Hex2ACC32
K.SScanF.GetVAL jsr SHARED.AddYToPtr2 Y=char count parsed
.1 ply get back VAL size
.2 lda ACC32-1,y
dey
sta (ZPPtr3),y
bne .2
.9 rts
*--------------------------------------
K.SScanF.S ldy #$ff
.1 iny
lda (ZPPtr2),y Get char in string to scan
sta (ZPPtr3),y store in param ptr
beq K.SScanF.Fwd end of string to scan ?
cmp (ZPPtr1) match format next char ?
beq .2
cmp #' ' is it a space ?
bne .1
.2 lda #0 add \0 to param ptr
sta (ZPPtr3),y
K.SScanF.Fwd jmp SHARED.AddYToPtr2 Y=char count parsed
*/--------------------------------------
* # FOpen
* Open a file
* ## C
* `hFILE fopen ( const char * filename, short int flags, short int ftype, int auxtype );`
* **In:**
* ## ASM
* `>PUSHWI auxtype`
* `>PUSHBI ftype`
* `>PUSHBI flags`
* + O.RDONLY : if R and !exists -> ERROR
* + O.WRONLY : if W and !exists -> CREATE
* + O.TRUNC : Reset Size To 0
* + O.APPEND : Append
* + O.TEXT : Open/Append in Text mode
* + O.CREATE : Create if not exists
* TODO: replace flags/ftype/auxtype with mode="w+,t=TYP,x=AUXTYPE"
* + r = O_RDONLY
* + r+ = O_RDWR
* + w = O_WRONLY | O_CREAT | O_TRUNC
* + w+ = O_RDWR | O_CREAT | O_TRUNC
* + a = O_WRONLY | O_CREAT | O_APPEND
* + a+ = O_RDWR | O_CREAT | O_APPEND
* + ,t=123 or t=$ff or t=TXT
* + ,x=12345 or x=$ffff
* `>LDYAI filename`
* ## RETURN VALUE
* CC : A = hFILE
* CS : A = EC
*\--------------------------------------
K.FOpen jsr PFT.CheckPathYA
bcs K.FOpen.RET4
>PULLB IO.Open.FLAGS
>PULLB IO.Open.TYPE
>PULLW IO.Open.AUXTYPE
jsr UNISTD.Open
bcs K.FClose.RTS
jsr STDIO.NewHFile
bcc K.FClose.RTS
jmp IO.Open.ERR
K.FOpen.RET4 >RET 4
*/--------------------------------------
* # FClose
* Close a file
* ## C
* int fclose ( hFILE stream );
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL fclose`
* ## RETURN VALUE
*\--------------------------------------
K.FClose jsr PFT.CheckNodeA
bcs K.FClose.RTS
sta .1+1 store hFile
jsr UNISTD.Close
bcs K.FClose.RTS
.1 ldx #$ff SELF MODIFIED
stz OF.Table.hFD-1,x
lda OF.Table.hPath-1,x
beq K.FClose.RTS special files have no path
stz OF.Table.hPath-1,x
jmp K.FreeMem discard filename
*/--------------------------------------
* # FRead (BLOCKING)
* Read bytes from file
* ## C
* int fread (hFILE stream, void * ptr, int count );
* ## ASM
* **In:**
* `>PUSHWI count`
* `>PUSHW ptr`
* `lda stream`
* `>SYSCALL fread`
* ## RETURN VALUE
* Y,A = Bytes Read
*\--------------------------------------
K.FRead jsr PFT.CheckNodeA
bcs K.FOpen.RET4
jsr UNISTD.Read
bcs K.FWrite.9
K.FClose.RTS rts
*/--------------------------------------
* # FWrite (BLOCKING)
* Write bytes to file
* ## C
* `int fwrite (hFILE stream, const void * ptr, int count );`
* ## ASM
* **In:**
* `>PUSHWI count`
* `>PUSHW ptr`
* `lda stream`
* `>SYSCALL fwrite`
* ## RETURN VALUE
* Y,A = Bytes Written
*\--------------------------------------
K.FWrite jsr PFT.CheckNodeA
bcs K.FOpen.RET4
jsr UNISTD.Write
bcc K.FWrite.RTS
K.FWrite.9 tay
bpl K.FWrite.RTS
dec pStack FF = NODATA
dec pStack
dec pStack
dec pStack keep ptr & count on stack
inc 0 = BLOCKING
K.FWrite.RTS rts
*/--------------------------------------
* # FFlush
* ## C
* int fflush(hFILE stream);
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL fflush`
*\--------------------------------------
K.FFlush jsr PFT.CheckNodeA
bcs .9
lda (pFD)
bne STDIO.IOERR
>MLICALL MLIFLUSH
.9 rts
*--------------------------------------
STDIO.IOERR lda #MLI.E.IO
sec
rts
*/-------------------------------------
* # FSeek
* Set the file-position indicator for hFILE
* ## C
* `int fseek(hFILE stream, long offset, short int whence);`
* ## ASM
* **In:**
* `>PUSHBI whence`
* `>PUSHL offset`
* `lda stream`
* `>SYSCALL fseek`
*\-------------------------------------
K.FSeek jsr PFT.CheckNodeA
bcc .11
>RET 5
.11 lda (pFD)
bne STDIO.IOERR
>PULLL ACC32
>PULLA whence
cmp #SEEK.END
beq .30
bcs .98
dec
beq .20
stz K.MLI.PARAMS+2
stz K.MLI.PARAMS+3
stz K.MLI.PARAMS+4
bra .8
* SEEK.CUR
.20 >MLICALL MLIGETMARK
bcc .8
rts
* SEEK.END
.30 >MLICALL MLIGETEOF
bcs .9
.8 ldy #0
clc
.81 lda K.MLI.PARAMS+2,y
adc ACC32,y
sta K.MLI.PARAMS+2,y
iny
tya 3 bytes, 24 bits!!!
eor #3
bne .81
bcs .99 Offset out of range!
.82 >MLICALL MLISETMARK
bcc .9
cmp #MLI.E.BEYEOF
bne .9
>MLICALL MLISETEOF
bcc .82
.9 rts
.98 lda #E.BADARG
.HS 2C bit abs
.99 lda #E.FTB
* sec
K.FSeek.RTS rts
*/--------------------------------------
* # FEOF
* Test the end-of-file indicator for hFILE
* ## C
* `int feof(hFILE stream);`
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL feof`
* ## RETURN VALUE
* CC :
* A = $ff EOF
* A = 0 NOT EOF
* CS :
*\--------------------------------------
K.FEOF jsr PFT.CheckNodeA
bcs K.FSeek.RTS
IO.EOF lda (pFD)
tax
jmp (.1,x)
.1 .DA IO.EOF.REG
.DA STDIO.IOERR DIR
.DA IO.EOF.CDEV
.DA STDIO.IOERR BDEV
.DA STDIO.IOERR LNK
.DA STDIO.IOERR DSOCK
.DA IO.EOF.SSOCK
.DA IO.EOF.PIPE
*/--------------------------------------
* # FTell
* Return the current value of the file-position indicator
* ## C
* `long ftell(hFILE stream);`
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL ftell`
* ## RETURN VALUE
* On stack (long)
*\--------------------------------------
K.FTell jsr PFT.CheckNodeA
bcs .9
>MLICALL MLIGETMARK
bcs .9
lda #0
>PUSHA
ldy #2
.1 lda K.MLI.PARAMS+2,y
>PUSHA
dey
bpl .1
.9 rts
*/--------------------------------------
* # Remove
* Remove a file or directory
* ## C
* int remove(const char *pathname);
* ## ASM
* **In:**
* `>LDYA pathname`
* `>SYSCALL remove`
* ## RETURN VALUE
*\--------------------------------------
K.Remove jsr PFT.CheckPathYA
bcs .9
>MLICALL MLIDESTROY
.9 rts
*/--------------------------------------
* # Rename
* Rename a file
* ## C
* `int rename(const char *oldpath, const char *newpath);`
* ## ASM
* **In:**
* `>PUSHW newpath`
* `>LDYA oldpath`
* `>SYSCALL rename`
* ## RETURN VALUE
*\--------------------------------------
K.Rename jsr PFT.CheckPathYA
bcs .9
>PULLW ZPPtr1
ldy #0
.1 lda (ZPPtr1),y
beq .8
iny
sta K.Buf256,y
cpy #MLI.MAXPATH
bne .1
.8 sty K.Buf256
>LDYAI K.Buf256
>STYA K.MLI.PARAMS+3
>MLICALL MLIRENAME
rts
.9 >RET 2
*--------------------------------------
* K.Buf256 = filepath
* X = hFD
*--------------------------------------
STDIO.NewHFile sta .4+1 Store hFD
ldx #1
.1 lda OF.Table.hFD-1,x
beq .2
inx
cpx #K.OF.MAX+1
bne .1
lda #E.OOH
* sec
rts
.2 stx .3+1 Store hFILE
lda (pFD)
cmp #S.FD.T.CDEV
beq .20
cmp #S.FD.T.BDEV
bne .21
.20 lda #0 No hPath for DEV
bra .3
.21 >LDYAI K.buf256
ldx #SYS.strdup
jsr K.SYSCALL2
bcs .9
txa
.3 ldx #$ff SELF MODIFIED
sta OF.Table.hPath-1,x
.4 lda #$ff SELF MODIFIED
sta OF.Table.hFD-1,x
txa hFILE
clc
.9 rts
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.STDIO
LOAD USR/SRC/SYS/KERNEL.S
ASM