A2osX/SYS/KERNEL.S.STDIO.txt
2020-02-14 17:32:52 +01:00

684 lines
13 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
*/--------------------------------------
* # 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
K.FPutS.RTS 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 K.FPutS.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
*/--------------------------------------
* # FOpen
* Open a file
* ## C
* `short int fopen ( const char *filename, short int flags, short int ftype, int auxtype );`
* **In:**
* ## ASM
* `>PUSHW filename`
* `>PUSHB 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
* `>PUSHB ftype`
* `>PUSHW auxtype`
* 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
* ## RETURN VALUE
* CC : A = hFILE
* CS : A = EC
*\--------------------------------------
K.FOpen jsr PFT.CheckPath4
bcs K.FOpen.RET4
>PULLW IO.Open.AUXTYPE
>PULLB IO.Open.TYPE
>PULLB IO.Open.FLAGS
inc pStack discard filename
inc pStack
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:**
* `>PUSHW pathname`
* `>SYSCALL remove`
* ## RETURN VALUE
*\--------------------------------------
K.Remove jsr PFT.CheckPath0
bcs .9
>MLICALL MLIDESTROY
.9 rts
*/--------------------------------------
* # Rename
* Rename a file
* ## C
* `int rename(const char *oldpath, const char *newpath);`
* ## ASM
* **In:**
* `>PUSHW oldpath`
* `>PUSHW newpath`
* `>SYSCALL rename`
* ## RETURN VALUE
*\--------------------------------------
K.Rename jsr PFT.CheckPath2
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