A2osX/SYS/KERNEL.S.STDIO.txt
2018-12-21 15:32:45 +01:00

1328 lines
25 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
PREFIX
AUTO 4,1
*--------------------------------------
*K.PrintF.PadL .BS 1
*K.PrintF.PadC .BS 1
*HEXBUF .BS 4
*BCDBUF .BS 5 5, enough to handle 10 digits (32bits)
*--------------------------------------
HEXBUF .EQ FAC
K.PrintF.PadL .EQ FAC+4
K.PrintF.PadC .EQ FAC+5
BCDBUF .EQ ARG
HEXBUF.Signed .EQ ARG.SIGN
*/--------------------------------------
* # PutChar
* Print A (char) to StdOut
* ## C
* `int putchar ( int character );`
* ## ASM
* **In:**
* `lda caracter`
* `>SYSCALL putchar`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.PutChar >PUSHA
ldy #S.PS.hStdOut
lda (pPs),y
*/--------------------------------------
* # FPutC
* 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.FPutC.9
>PULLB K.IOBuf
ldy #1
K.FPutC.Y lda #0
>PUSHYA
>PUSHWI K.IOBuf
jmp IO.Write.I
K.FPutC.9 >RET 1
*/--------------------------------------
* # PutS
* 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 >PUSHYA
ldy #S.PS.hStdOut
lda (pPs),y
jsr K.FPutS
bcs K.PutS.RTS
lda #C.CR
sta K.IOBuf
lda #C.LF
sta K.IOBuf+1
ldy #2
bra K.FPutC.Y
K.PutS.RTS rts
*/--------------------------------------
* # FPutS
* Write Str to FILE
* ## 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 .9
>PULLYA Get String
>STYA ZPPtr2 Save Buffer
>SYSCALL strlen Get String len in Y,A
>PUSHYA push len
>PUSHW ZPPtr2 push buffer
jmp IO.Write.I
.9 >RET 2
*/--------------------------------------
* # PrintF/SPrintF/FPrintF
* 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`
* `...`
* `>PUSHBI bytecount`
* `>LDYAI format`
* `>SYSCALL printf`
* SPrintF :
* `>PUSHYA`
* `...`
* `>PUSHBI bytecount`
* `>PUSHWI format`
* `>LDYAI str`
* `>SYSCALL sprintf`
* FPrintF :
* `>PUSHYA`
* `...`
* `>PUSHBI bytecount`
* `>PUSHWI format`
* `lda hFILE`
* `>SYSCALL fprintf`
* ## RETURN VALUE
* CC : success, Y,A = bytes sent
* CS : error, A = code from Output
* Specifiers :
* + %b : pull 1 byte to Print BIN
* + %B : pull 2 bytes 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
* + %n : pull 1 byte to Print low Nibble HEX
* + %N : pull 1 byte to Print high Nibble HEX
* + %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)
* + \\\\ : Print \
* + \\% : Print %
* Modifiers for len and padding :
* + %d : '9' '12'
* + %2d : ' 9' '12'
* + %02d : '09' '12'
* + %11s : 'ABCDEFGH '
* + %011s : 'ABCDEFGH000'
* + %2f : '3.14'
*\--------------------------------------
K.SPrintF >STYA pIOBuf Out Buffer
>PULLW ZPPtr1 format
bra K.PrintF.1
K.FPrintF pha
>PULLW ZPPtr1 format
pla
bra K.PrintF.0
K.PrintF >STYA ZPPtr1 format
ldy #S.PS.hStdOut
lda (pPs),y
K.PrintF.0 sta PrintF.hFILE
>LDYAI K.IOBuf
>STYA pIOBuf
K.PrintF.1 stz PrintF.Cnt
stz PrintF.Cnt+1
stz PrintF.GetByte+1
.1 jsr MEM.GetCharPtr1
beq .8 end of format..
cmp #'%'
bne .10
stz K.PrintF.PadL
lda #' '
sta K.PrintF.PadC
.2 ldx #PrintFTBL2-PrintFTBL1-1
jsr MEM.GetCharPtr1
beq .99
.3 cmp PrintFTBL1,x do we have a %x command?
beq .6 yes, jmp to it!
dex
bpl .3 no valid letter...
cmp #'0' ...a 0...mmm... padding char?
bne .4
ldx K.PrintF.PadL K.PrintF.PadL is not nul, so this 0 is second digit
bne .5
* lda #'0'
sta K.PrintF.PadC no, this is the first 0, so make it K.PrintF.PadC
bra .2
.4 jsr MEM.IsDigit
bcs .99
.5 and #$0F we have a digit
pha save it...
lda K.PrintF.PadL starts K.PrintF.PadL * 10
asl
asl A=times 4
adc K.PrintF.PadL CC by ASL, A=times 5
asl times 10
sta K.PrintF.PadL
pla get back digit
adc K.PrintF.PadL
sta K.PrintF.PadL
bra .2 go get next char...
.6 txa
asl
tax
jsr PrintF.ESC
bcc .1
bcs .99
.8 lda pIOBuf+1
eor /K.IOBuf
bne .99
jsr PrintF.Flush
bra .99
.10 cmp #'\'
bne .20
ldx #PrintFTBL2.OUT-PrintFTBL2-1
jsr MEM.GetCharPtr1
beq .99
.12 cmp PrintFTBL2,x
beq .13
dex
bpl .12
bra .1
.13 lda PrintFTBL2.OUT,x
.20 jsr PrintF.COut
bcc .1
.99 php
pha
lda pStack
sec ByteCnt byte
adc (pStack) ... ByteCnt
sta pStack CC
pla
plp
bcs .9
>LDYA PrintF.Cnt
.9 rts
*--------------------------------------
PrintF.ESC jmp (.1,x)
.1 .DA PrintF.B,PrintF.BB
.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.N,PrintF.NN
.DA PrintF.S,PrintF.SS
*--------------------------------------
PrintFTBL1 .AS "bBdDuefhHiILnNsS"
PrintFTBL2 .AS "befnr\%"
PrintFTBL2.OUT .HS 08.1B.0C.0A.0D \b\e\f\n\r
.DA #'\' \\
.DA #'%' \%
*--------------------------------------
PrintF.BB jsr PrintF.GetByte
bcs PrintF.BB.RTS
pha
jsr PrintF.B
pla
bcc PrintF.B.1
PrintF.BB.RTS rts
*--------------------------------------
PrintF.B jsr PrintF.GetByte
bcs PrintF.BB.RTS
PrintF.B.1 ldx #8
.1 asl
pha
lda #'0'
adc #0 add Carry
jsr PrintF.COut
pla
bcs PrintF.BB.RTS
dex
bne .1
rts
*--------------------------------------
PrintF.I sec signed short
.HS 90 BCC
PrintF.D clc unsigned short (BYTE)
ror HEXBUF.Signed
jsr PrintF.GetByte
bcs PrintF.BB.RTS
sta HEXBUF
stz HEXBUF+1
ldx #0 one byte
bra PrintF.DD.1
PrintF.II sec signed int
.HS 90 BCC
PrintF.DD clc unsigned int (WORD)
ror HEXBUF.Signed
jsr PrintF.GetByte
bcs PrintF.BB.RTS
sta HEXBUF
jsr PrintF.GetByte
bcs PrintF.BB.RTS
sta HEXBUF+1
ldx #1 two bytes
PrintF.DD.1 stz HEXBUF+2
stz HEXBUF+3
bra PrintF.U.1
PrintF.L sec signed long
.HS 90 BCC
PrintF.U clc unsigned long (DWORD)
ror HEXBUF.Signed
ldx #$ff
.1 jsr PrintF.GetByte
bcs PrintF.BB.RTS
inx
sta HEXBUF,x
cpx #3
bne .1
* ldx #3 4 bytes
PrintF.U.1 clc
bit HEXBUF.Signed
bpl PrintF.Hex2Dec unsigned, nothing to check
lda HEXBUF,x get sign
bpl PrintF.Hex2Dec
sec
ldy #0
.1 lda HEXBUF,y two's complement of X bytes
eor #$ff
adc #0
sta HEXBUF,y
iny
dex
bpl .1
sec tell to print a "-" sign....
*--------------------------------------
* Convert HEXBUF to ASCBUF decimal padded with 0
*--------------------------------------
PrintF.Hex2Dec ror HEXBUF.Signed
ldx #4
.1 stz BCDBUF,x Clear all 5 bytes
dex
bpl .1
sed switch to BCD mode
ldx #32 let's roll 32 bits
.2 asl HEXBUF
rol HEXBUF+1
rol HEXBUF+2
rol HEXBUF+3
ldy #4
.3 lda BCDBUF,y
adc BCDBUF,y
sta BCDBUF,y
dey
bpl .3
dex
bne .2
cld
bit HEXBUF.Signed
bpl .9
lda #'-'
jsr PrintF.COut
.9 lda K.PrintF.PadL any Len format ?
beq .4 no
lda #10
sec yes, Print only digits starting at pos 10-K.PrintF.PadL
sbc K.PrintF.PadL
.4 tax x=0 if no K.PrintF.PadL, or x=10-K.PrintF.PadL
.5 txa X range 0 to 9
lsr CS if lo nibble (1,3,5,7,9)
tay
lda BCDBUF,y
bcs .6
lsr
lsr
lsr
lsr
.6 and #$0F
ora #$30
cmp #$30
beq .7 a zero?
inc K.PrintF.PadL found a non zero, Print all digits, even if 0, next time
ldy #'0'
sty K.PrintF.PadC
bra .8
.7 cpx #9 last digit ?
beq .8 Print always
ldy K.PrintF.PadL no pad to fill, do not Print 0
beq .10
lda K.PrintF.PadC fill with K.PrintF.PadC
.8 jsr PrintF.COut
bcs .99
.10 inx
cpx #10
bne .5
clc
.99 rts
*--------------------------------------
* 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.GetByte+1 get current stack Ptr
tay
clc at least 5 bytes remaining ?
adc #5
cmp (pStack)
bcc .1
bne .9
.1 tya
sec +1
adc pStack
sta INDEX
lda pStack+1
sta INDEX+1
ldx #ROM.SETFAC
jsr GP.ROMCALL
lda PrintF.GetByte+1
clc
adc #5
sta PrintF.GetByte+1
ldy #3 In order not to trash A2osX.SaveSM,A2osX.SaveSX
ldx #ROM.FOUT
jsr GP.ROMCALL
ldy #0
.2 lda $102,y
beq .8
jsr PrintF.COut
iny
bne .2
.8 clc
rts
.9 sec
PrintF.H.9 rts
*--------------------------------------
PrintF.HH jsr PrintF.GetByte
bcs PrintF.H.9
pha
jsr PrintF.H
pla
bra PrintF.H.1
*--------------------------------------
PrintF.H jsr PrintF.GetByte
bcs PrintF.H.9
PrintF.H.1 pha
jsr PrintF.NN.1
pla
bra PrintF.N.1
*--------------------------------------
PrintF.N jsr PrintF.GetByte
bcs PrintF.H.9
PrintF.N.1 and #$0F
bra PrintF.NN.2
PrintF.NN jsr PrintF.GetByte
bcs PrintF.H.9
PrintF.NN.1 lsr
lsr
lsr
lsr
PrintF.NN.2 ora #$30
cmp #$3A
bcc .1
adc #6
.1 jmp PrintF.COut
*--------------------------------------
PrintF.S ldy #$ff CSTR
.HS 2C bit abs
PrintF.SS ldy #$00 PSTR
jsr PrintF.GetByte
bcs .9
sta ZPPtr2
jsr PrintF.GetByte
bcs .9
sta ZPPtr2+1
lda (ZPPtr2) if CSTR:last char=0, if PSTR:len=0
beq .8
sty .1+1
.1 lda #$ff Self Modified
bne .11 CSTR
tya PSTR
cmp (ZPPtr2) len check
beq .2
.11 iny
lda (ZPPtr2),y
beq .2
jsr PrintF.COut
bcs .9
lda K.PrintF.PadL
beq .1
cpy K.PrintF.PadL
bne .1
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
.8 clc
.9 rts
*--------------------------------------
PrintF.GetByte lda #$FF SELF MODIFIED LStack Ptr
cmp (pStack)
beq .9 CS
phy
tay
iny
lda (pStack),y
sty PrintF.GetByte+1
ply
* clc
.9 rts
*--------------------------------------
PrintF.COut phy
ldy PrintF.Cnt
sta (pIOBuf),y
inc PrintF.Cnt
bne .8
lda pIOBuf+1
eor /K.IOBuf
bne .7
* we are printing to IObuf, flush!
lda PrintF.Cnt+1
pha
lda #1 Flush $100 bytes
sta PrintF.Cnt+1
jsr PrintF.Flush
pla
inc
sta PrintF.Cnt+1
.7 inc pIOBuf+1
inc PrintF.Cnt+1
.8 ply
clc
rts
*--------------------------------------
PrintF.Flush >PUSHW PrintF.Cnt
>PUSHWI K.IOBuf
lda PrintF.hFILE
jsr PFT.CheckNodeA
bcs .9
jmp IO.Write.I
.9 >RET 4
*--------------------------------------
PrintF.hFILE .BS 1
PrintF.Cnt .BS 2
*/--------------------------------------
* # FGetS
* 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
*\--------------------------------------
K.FGetS jsr PFT.CheckNodeA
bcs .90
>PULLW ZPPtr2 s
>PULLA
sec
sbc #2
eor #$ff
sta ZPPtr1 !n
>PULLA
sbc #0
eor #$ff
sta ZPPtr1+1 !n
jsr K.GetC.I
bcs .9
.1 lda K.IOBuf
cmp #C.CR
beq .8
jsr MEM.PutCharPtr2
jsr MEM.NextCharPtr1
beq .8
jsr K.GetC.I
bcc .1
.8 clc
.9 pha
lda #0
sta (ZPPtr2)
pla
.99 rts
.90 >RET 4
*/--------------------------------------
* # GetChar
* 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
* 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.9
K.GetC.I >PUSHWI 1
>PUSHWI K.IOBuf
jsr IO.READ.I
bcs K.GetC.9
lda K.IOBuf
K.GetC.9 rts
*/--------------------------------------
* # 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 >STYA ZPPtr2 String to Scan
>PULLW ZPPtr1 format
stz .5+1 reset LStack Ptr
stz .80+1 rest Arg processed
.1 jsr MEM.GetCharPtr1 End Of format?
beq .8
cmp #'%' Escape ?
beq .2
cmp #' ' Space ?
beq .12
cmp (ZPPtr2) Same char in string?
bne .9
inc ZPPtr2
bne .1
inc ZPPtr2+1
bra .1
.12 inc ZPPtr2 Space....
bne .14
inc ZPPtr2+1
.14 cmp (ZPPtr2) another one ?
beq .12
bne .1
.2 jsr MEM.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 jsr .8
lda #MLI.E.EOF
sec
rts
.4 jsr .5
bcs .9 out of Ptr on stack
bra .1
.8 lda pStack
sec ByteCnt byte
adc (pStack) ... ByteCnt
sta pStack CC
.80 lda #$ff SELF MODIFIED Arg porcessed
.99 rts
*--------------------------------------
.5 lda #$FF SELF MODIFIED LStack Ptr
cmp (pStack)
beq .99 CS
tay
iny
lda (pStack),y
sta ZPPtr3
iny
lda (pStack),y
sta ZPPtr3+1 get VAR Ptr
sty .5+1
inc .80+1 parsed one more arg!
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 STDLIB.GetDec
bra K.SScanF.GetVAL
*--------------------------------------
K.SScanF.HH
K.SScanF.H lda K.SScanFTBL+1,x Get VAR size
pha
jsr STDLIB.GetHex
K.SScanF.GetVAL jsr K.SScanF.Fwd Y=char count parsed
.1 ply get back VAL size
.2 lda STDLIB.32-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 tya Y=char count parsed
clc
adc ZPPtr2
sta ZPPtr2
bcc .8
clc
inc ZPPtr2+1
.8 rts
*/--------------------------------------
* # 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 .99
>PULLB K.Open.FLAGS
>PULLB K.Open.TYPE
>PULLW K.Open.AUXTYPE
jsr IO.Open.I
bcs .9
tax
stx .1+1 save hFD
>LDYAI K.Buf256
jsr STDIO.NewHFileYAX
bcc .9
pha save MLI error
.1 lda #$ff SELF MODIFIED
jsr K.Close
pla get back MLI error
sec
.9 rts
.99 >RET 4
*/--------------------------------------
* # FClose
* Close a file
* ## C
* int fclose ( hFILE stream );
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL fclose`
* ## RETURN VALUE
*\--------------------------------------
K.FClose jsr PFT.CheckNodeA
tax
lda OF.Table.hPath,x
beq .9
stz OF.Table.hPath,x
jsr K.FreeMem discard filename
lda OF.Table.hFD,x
stz OF.Table.hFD,x
jmp K.Close
.9 lda #E.INVH
sec
K.FClose.RTS rts
*/--------------------------------------
* # FRead
* 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.Write.9
jmp IO.Read.I
*/--------------------------------------
* # FWrite
* 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.Write.9
jmp IO.Write.I
K.Write.9 >RET 4
*/--------------------------------------
* # FFlush
* ## C
* int fflush(hFILE stream);
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL fflush`
*\--------------------------------------
K.FFlush jsr PFT.CheckNodeA
bcs .9
>MLICALL MLIFLUSH
.9 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 6
.11 >PULLA whence
tax
>PULLW ZPPtr1 offset LW
>PULLW ZPPtr2 offset HW
cpx #SEEK.END+1
bcs .98
jmp (.1,x)
.1 .DA .10
.DA .20
.DA .30
* SEEK.SET
.10 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
ldx #3 3 bytes, 24 bits!!!
clc
.81 lda K.MLI.PARAMS+2,y
adc ZPPtr1,y
sta K.MLI.PARAMS+2,y
iny
dex
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
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=0 EOF
* A !=0 NOT EOF
* CS :
*\--------------------------------------
K.FEOF jsr PFT.CheckNodeA
bcs .9
>MLICALL MLIGETMARK
bcs .9
ldy #2
.1 lda K.MLI.PARAMS+2,y
sta K.FEOF.MARK,y
dey
bpl .1
>MLICALL MLIGETEOF
bcs .9
ldy #2
.2 lda K.MLI.PARAMS+2,y
eor K.FEOF.MARK,y
bne .8
dey
bpl .2
.8 clc
.9 rts
K.FEOF.MARK .BS 3
*/--------------------------------------
* # 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 .1+1
ldy #0
.1 lda $ffff,y Self Modified
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
*--------------------------------------
* Y,A = filepath
* X = hFD
*--------------------------------------
STDIO.NewHFileYAX
pha
stx .4+1 Store hFD
ldx #0
.1 lda OF.Table.hFD,x
beq .2
inx
cpx #K.OF.MAX
bne .1
pla
lda #E.OOH
* sec
rts
.2 stx .3+1 Store hFILE
pla
>SYSCALL strdup
bcs .9
txa
.3 ldx #$ff SELF MODIFIED
sta OF.Table.hPath,x
.4 lda #$ff SELF MODIFIED
sta OF.Table.hFD,x
txa hFILE
clc
.9 rts
*--------------------------------------
STDIO.SetIOBUF >LDYAI 1024 get a ProDOS IOBUF
ldx #S.MEM.F.ALIGN+S.MEM.F.NOMOVE
jsr MEM.GetMem.YAX
bcs .9
>STYA K.MLI.PARAMS+3 Save Ptr to IOBUF for MLIOPEN call
txa
ldy #S.FD.REG.IOBUF
sta (pFD),y
.9 rts
*--------------------------------------
STDIO.IOERR lda #MLI.E.IO
sec
rts
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.STDIO
LOAD USR/SRC/SYS/KERNEL.S
ASM