A2osX/SYS/KERNEL.S.STDIO.txt
2020-07-10 15:59:56 +02:00

722 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 K.PutChar.RTS
cmp #E.NODATA
sec
bne 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 , short 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...
cmp #E.NODATA
sec
bne 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
cmp #E.NODATA
sec
bne K.PutS.RTS
inc 0 = BLOCKING
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
cmp #E.NODATA
sec
bne K.PutS.RET2 IO Error
inc FF-> 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.Get.1
bcc .2
cmp #E.NODATA
sec
bne .9 IO error
inc NO DATA -> BLOCKING
rts
.2 lda K.IOBuf
cmp #C.LF Discard any leading LF from a previous CR/LF
beq .8 returns as empty string
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
* `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.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
* `int ungetc(short int c, hFILE 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
jmp UNISTD.Open.ERR
.9 >POP 6
.99 rts
*/--------------------------------------
* # 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.FWrite.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.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(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 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