A2osX/SYS/KERNEL.S.STDIO.txt
2020-09-09 14:47:18 +02:00

731 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 ( short 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 .8
tay
bne .8
>PULLA CS,A=0:BLOCKING, restore A
.8 rts
*/--------------------------------------
* # fputc (BLOCKING)
* Print A (char) to hFILE
* ## C
* `int fputc ( hFILE stream , short int character );`
* ## ASM
* **In:**
* `>PUSHB character`
* `lda stream`
* `>SYSCALL fputc`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.FPutC jsr PFT.CheckNodeA
bcs .8
lda (pStack) character
sta K.IOBuf
lda #0
>PUSHA
inc write 1 byte
>PUSHA
>PUSHWI K.IOBuf buf
jsr UNISTD.Write
bcc .8 pop char...
cmp #E.NODATA
sec
bne .8
inc CS,A=0:BLOCKING
rts
.8 >POP 1
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 .1+1
ldy #0
.1 lda $FFFF,y SELF MODIFIED
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
ldy #S.PS.hStdOut
lda (pPS),y
>PUSHA
>PUSHWI K.IOBuf
jsr K.FPutS
bcc K.PutS.RTS
tay
bne K.PutS.RTS
>LDYA .1+1 CS,A=0:BLOCKING, restore Y,A
K.PutS.RET3 >POP 3 pop StdOut & buffer
K.PutS.RTS rts
*/--------------------------------------
* # fputs (BLOCKING)
* Write Str to hFILE
* ## C
* `int fputs (hFILE stream, const char * str );`
* ## ASM
* **In:**
* `>PUSHB stream`
* `>PUSHW str`
* `>SYSCALL fputs`
* ## RETURN VALUE
* CC = success
*\--------------------------------------
K.FPutS jsr PFT.CheckNode2 set IO.hFD
bcs K.PutS.RET3
lda (pStack)
sta ZPPtr2 Get String
ldy #1
lda (pStack),y
sta ZPPtr2+1
ldy #0
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.RET3
cmp #E.NODATA
sec
bne K.PutS.RET3 IO Error
inc FF-> 0 = BLOCKING
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.Get.1
bcc .2
cmp #E.NODATA
sec
bne .9 IO error
.11 lda #0 BLOCKING
rts
.2 lda K.IOBuf
cmp #C.LF Discard any leading LF from a previous CR/LF
* beq .8 returns as empty string
beq .11 CS -> NODATA -> BLOCKING
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.Get.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
cmp #E.NODATA
sec
bne .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
* `short 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
* `short int getc ( short int stream );`
* ## ASM
* **In:**
* `lda stream`
* `>SYSCALL getc`
* ## RETURN VALUE
* CC = success
* A = char
*\--------------------------------------
K.GetC jsr PFT.CheckNodeA
bcs K.GetC.RTS
jsr STDIO.Get.1
bcc .8
cmp #E.NODATA
sec
bne K.GetC.RTS I/O error
inc 0 = BLOCKING
rts
.8 lda K.IOBuf
K.GetC.RTS rts
*--------------------------------------
STDIO.Get.1 lda #0
>PUSHA
inc read 1 byte
>PUSHA
>PUSHWI K.IOBuf
jmp UNISTD.READ
*/--------------------------------------
* # ungetc
* push byte back into input stream
* ## C
* `short int ungetc(short int c, short int stream);`
* ## ASM
* `>PUSHB c`
* `>PUSHB stream`
* `>SYSCALL ungetc`
* ## RETURN VALUE
* CC = success
* A = char
*\--------------------------------------
K.UngetC clc
rts
*/--------------------------------------
* # 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 .9
>PULLW IO.Open.AUXTYPE
>PULLB IO.Open.TYPE
>PULLB IO.Open.FLAGS
inc pStack discard filename
inc pStack
jsr UNISTD.Open
bcs .99
jsr STDIO.NewHFile
bcc .99
pha Save Error Code
lda IO.hFD
jsr K.Close
pla
sec
.9 >POP 6
.99 rts
*/--------------------------------------
* # FClose
* Close a file
* ## C
* `int fclose ( short int 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 (short int 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.FWrite.RET4
jsr UNISTD.Read
bcs K.FWrite.9
K.FClose.RTS rts
*/--------------------------------------
* # FWrite (BLOCKING)
* Write bytes to file
* ## C
* `int fwrite ( short int 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.FWrite.RET4
jsr UNISTD.Write
bcc K.FWrite.RTS
K.FWrite.9 cmp #E.NODATA
sec
bne K.FWrite.RTS IO Error
dec pStack FF = NODATA
dec pStack
dec pStack
dec pStack keep ptr & count on stack
inc 0 = BLOCKING
* sec
K.FWrite.RTS rts
K.FWrite.RET4 >RET 4
*/--------------------------------------
* # FFlush
* ## C
* `int fflush( short int 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( short int 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( short int 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 FS.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( short int 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 oldpath`
* `>PUSHW newpath`
* `>SYSCALL rename`
* ## RETURN VALUE
*\--------------------------------------
K.Rename jsr PFT.CheckPath2
bcs .9
lda (pStack)
sta ZPPtr1
ldy #1
lda (pStack),y
sta ZPPtr1+1
dey 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
.9 >RET 4
*--------------------------------------
* K.Buf256 = filepath
* X = hFD
*--------------------------------------
STDIO.NewHFile 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 .4+1
ldx #0
lda (pFD)
cmp #S.FD.T.CDEV
beq .3
cmp #S.FD.T.BDEV
beq .3 No hPath for DEV
>LDYAI K.buf256
>SYSCALL2 StrDup
bcs .9
.3 txa
.4 ldx #$ff SELF MODIFIED
sta OF.Table.hPath-1,x
lda IO.hFD
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