mirror of
https://github.com/A2osX/A2osX.git
synced 2024-11-22 00:32:44 +00:00
1438 lines
26 KiB
Plaintext
1438 lines
26 KiB
Plaintext
NEW
|
||
AUTO 3,1
|
||
*/--------------------------------------
|
||
* # fputc (BLOCKING)
|
||
* Print A (char) to hFILE
|
||
* ## C
|
||
* `int fputc ( hFILE stream , short int character );`
|
||
* ## ASM
|
||
* `>PUSHB stream`
|
||
* `>PUSHB character`
|
||
* `>SYSCALL fputc`
|
||
* ## RETURN VALUE
|
||
* CC = success
|
||
*\--------------------------------------
|
||
K.FPutC lda (pStack) character
|
||
sta K.IOBuf
|
||
|
||
ldy #1
|
||
lda (pStack),y hFile
|
||
>PUSHA
|
||
|
||
jsr STDIO.Put1
|
||
bcc .8
|
||
|
||
tay
|
||
beq .9 BLOCKING, keep parms on stack
|
||
|
||
.8 >POP 2
|
||
|
||
.9 rts
|
||
*/--------------------------------------
|
||
* # putchar (BLOCKING)
|
||
* Print A (char) to StdOut
|
||
* ## C
|
||
* `int putchar ( short int character );`
|
||
* ## ASM
|
||
* `lda character`
|
||
* `>SYSCALL putchar`
|
||
* ## RETURN VALUE
|
||
* CC = success
|
||
*\--------------------------------------
|
||
K.PutChar sta K.IOBuf character
|
||
|
||
ldy #S.PS.hStdOut
|
||
lda (pPS),y
|
||
>PUSHA
|
||
*--------------------------------------
|
||
STDIO.Put1 >PUSHWI K.IOBuf buf
|
||
|
||
lda #0
|
||
>PUSHA
|
||
inc write 1 byte
|
||
>PUSHA
|
||
|
||
STDIO.Write jsr K.FWrite.PFT
|
||
bcc .9
|
||
|
||
tay
|
||
bne .9
|
||
|
||
>POP 5
|
||
|
||
.9 rts
|
||
*/--------------------------------------
|
||
* # puts (BLOCKING)
|
||
* Write Str to StdOut, appends '\r\n'
|
||
* ## C
|
||
* `int puts ( const char * str );`
|
||
* ## ASM
|
||
* `>LDYAI str`
|
||
* `>SYSCALL PutS`
|
||
* ## RETURN VALUE
|
||
* CC = success
|
||
*\--------------------------------------
|
||
K.PutS >STYA .1+1
|
||
|
||
ldx #0
|
||
|
||
.1 lda $FFFF,x SELF MODIFIED
|
||
beq .2
|
||
|
||
sta K.IOBuf,x
|
||
inx
|
||
bne .1
|
||
|
||
.9 lda #E.BUF
|
||
sec
|
||
rts
|
||
|
||
.2 lda #C.CR
|
||
sta K.IOBuf,x
|
||
inx
|
||
beq .9
|
||
|
||
lda #C.LF
|
||
sta K.IOBuf,x
|
||
inx
|
||
beq .9
|
||
|
||
ldy #S.PS.hStdOut
|
||
lda (pPS),y
|
||
>PUSHA
|
||
>PUSHWI K.IOBuf
|
||
>PUSHBI 0
|
||
txa
|
||
>PUSHA
|
||
|
||
bra STDIO.Write
|
||
*/--------------------------------------
|
||
* # fputs (BLOCKING)
|
||
* Write Str to hFILE
|
||
* ## C
|
||
* `int fputs (hFILE stream, const char * str );`
|
||
* ## ASM
|
||
* `>PUSHB stream`
|
||
* `>PUSHW str`
|
||
* `>SYSCALL fputs`
|
||
* ## RETURN VALUE
|
||
* CC = success
|
||
*\--------------------------------------
|
||
K.FPutS lda (pStack)
|
||
sta ZPPtr1 Get String
|
||
sta ZPPtr2
|
||
|
||
ldy #1
|
||
lda (pStack),y
|
||
sta ZPPtr1+1
|
||
sta ZPPtr2+1
|
||
|
||
ldy #0
|
||
ldx #0
|
||
|
||
.1 lda (ZPPtr1),y
|
||
beq .2
|
||
|
||
iny
|
||
bne .1
|
||
|
||
inx
|
||
inc ZPPtr1+1
|
||
bra .1
|
||
|
||
.2 phy
|
||
|
||
ldy #2
|
||
lda (pStack),y
|
||
>PUSHA
|
||
|
||
>PUSHW ZPPtr2
|
||
|
||
txa
|
||
>PUSHA push len HI
|
||
|
||
pla
|
||
>PUSHA push len LO
|
||
|
||
jsr STDIO.Write
|
||
bcs .9
|
||
|
||
>POP 3
|
||
|
||
.9 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
|
||
* `>PUSHB hFILE`
|
||
* `>PUSHW s`
|
||
* `>PUSHW n`
|
||
* `>SYSCALL fgets`
|
||
* ## RETURN VALUE
|
||
* Y,A: s
|
||
* CC = success
|
||
*\--------------------------------------
|
||
* (pStack)+4 h
|
||
* (pStack)+2 s -> ZPPtr2
|
||
* (pStack)+0 n -> ZPPtr1
|
||
*--------------------------------------
|
||
K.FGetS ldy #3
|
||
|
||
.1 lda (pStack),y
|
||
sta ZPPtr1,y
|
||
dey
|
||
bpl .1
|
||
|
||
lda ZPPtr1+1
|
||
bmi .4 already something in buffer
|
||
|
||
.2 ldy #4
|
||
lda (pStack),y
|
||
jsr STDIO.Get1
|
||
bcs .9
|
||
|
||
* BLOCKING > POP 5 FREAD parms
|
||
* EOF or IOERR.... > POP 5 FGETS parms
|
||
|
||
.3 lda K.IOBuf
|
||
cmp #C.LF Discard any leading LF from a prev CR/LF
|
||
beq .2
|
||
|
||
clc set n = !n + 1
|
||
lda ZPPtr1
|
||
eor #$ff
|
||
adc #1
|
||
sta ZPPtr1
|
||
|
||
lda ZPPtr1+1
|
||
eor #$ff
|
||
adc #0
|
||
sta ZPPtr1+1
|
||
|
||
bra .5
|
||
*--------------------------------------
|
||
.4 ldy #4
|
||
lda (pStack),y
|
||
jsr STDIO.Get1
|
||
bcs .6
|
||
|
||
.5 lda K.IOBuf
|
||
cmp #C.CR
|
||
beq .8
|
||
|
||
jsr SHARED.PutCP2
|
||
|
||
inc ZPPtr1
|
||
bne .4
|
||
|
||
inc ZPPtr1+1
|
||
bne .4
|
||
|
||
beq .8 Buffer full
|
||
|
||
.6 tay
|
||
beq .70
|
||
|
||
cmp #MLI.E.EOF
|
||
beq .8 String terminated by EOF
|
||
|
||
bra .9 I/O error > POP 5 FGETS parms
|
||
|
||
.70 jsr .9 > POP 5 FREAD parms
|
||
|
||
ldy #3
|
||
|
||
.7 lda ZPPtr1,y NO DATA, but string not yet terminated
|
||
sta (pStack),y
|
||
dey
|
||
bpl .7
|
||
|
||
lda #0 BLOCKING
|
||
* sec
|
||
rts
|
||
|
||
.8 lda #0
|
||
sta (ZPPtr2) terminate string
|
||
tay return NULL (TODO: return s)
|
||
clc
|
||
.9 >RET 5
|
||
*/--------------------------------------
|
||
* # getchar (BLOCKING)
|
||
* Get char from StdIn
|
||
* ## C
|
||
* `short int getchar ( );`
|
||
* ## ASM
|
||
* `>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
|
||
* `lda stream`
|
||
* `>SYSCALL getc`
|
||
* ## RETURN VALUE
|
||
* CC = success
|
||
* A = char
|
||
*\--------------------------------------
|
||
K.GetC jsr STDIO.Get1
|
||
bcc .8
|
||
|
||
tay
|
||
bne .9 I/O error
|
||
|
||
>POP 5 BLOCKING
|
||
rts
|
||
|
||
.8 lda K.IOBuf
|
||
|
||
.9 rts
|
||
*--------------------------------------
|
||
STDIO.Get1 >PUSHA
|
||
|
||
>PUSHWI K.IOBuf
|
||
lda #0
|
||
>PUSHA
|
||
inc read 1 byte
|
||
>PUSHA
|
||
ldx #_FRead
|
||
jmp K.FRead
|
||
*/--------------------------------------
|
||
* # 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 );`
|
||
* ## 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.9
|
||
|
||
>PULLW IO.Open.AUXTYPE
|
||
>PULLB IO.Open.TYPE
|
||
>PULLB IO.Open.FLAGS
|
||
|
||
inc pStack discard filename
|
||
inc pStack
|
||
|
||
jsr UNISTD.Open
|
||
bcs K.FOpen.99
|
||
|
||
lda (pFD)
|
||
cmp #S.FD.T.DSOCK
|
||
bcc .1
|
||
|
||
lda IO.hFILE don't create file for SOCK/PIPE
|
||
tax
|
||
inc FILEs.oCnt-1,x
|
||
|
||
clc
|
||
|
||
rts
|
||
|
||
.1 >LDYAI K.Buf256
|
||
>STYA ZPPtr1
|
||
|
||
K.FOpen.REGDIR jsr K.MkNod.I
|
||
bcs K.FOpen.90
|
||
|
||
* tax
|
||
inc FILEs.oCnt-1,x
|
||
|
||
* clc
|
||
|
||
rts
|
||
|
||
K.FOpen.90 pha
|
||
jsr UNISTD.Close
|
||
pla
|
||
sec
|
||
rts
|
||
|
||
K.FOpen.9 >POP 6
|
||
|
||
K.FOpen.99 rts
|
||
*/--------------------------------------
|
||
* # FClose
|
||
* Close a file
|
||
* ## C
|
||
* `int fclose ( short int stream );`
|
||
* ## ASM
|
||
* `lda stream`
|
||
* `>SYSCALL FClose`
|
||
* ## RETURN VALUE
|
||
*\--------------------------------------
|
||
K.FClose jsr PFT.CheckNodeA
|
||
bcs K.FRead.RTS
|
||
|
||
jsr UNISTD.Close
|
||
bcs K.FRead.RTS
|
||
|
||
ldx IO.hFILE
|
||
dec FILEs.oCnt-1,x
|
||
|
||
* clc
|
||
|
||
bne K.FRead.RTS
|
||
|
||
stz FILEs.hFD-1,x
|
||
|
||
lda FILEs.hName-1,x
|
||
|
||
* clc
|
||
|
||
beq K.FRead.RTS
|
||
|
||
stz FILEs.hName-1,x
|
||
jmp K.FreeMem
|
||
*/--------------------------------------
|
||
* # FRead (BLOCKING)
|
||
* Read bytes from file
|
||
* ## C
|
||
* `int fread (short int stream, void * ptr, int count );`
|
||
* ## ASM
|
||
* `>PUSHB stream`
|
||
* `>PUSHW ptr`
|
||
* `>PUSHW count`
|
||
* `>SYSCALL fread`
|
||
* ## RETURN VALUE
|
||
* Y,A = Bytes Read
|
||
*\--------------------------------------
|
||
K.FRead jsr PFT.CheckNode4
|
||
bcs K.FWrite.RET5
|
||
|
||
jsr UNISTD.Read
|
||
bcs K.FWrite.9
|
||
|
||
K.FRead.RTS rts
|
||
*/--------------------------------------
|
||
* # FWrite (BLOCKING)
|
||
* Write bytes to file
|
||
* ## C
|
||
* `int fwrite ( short int stream, const void * ptr, int count );`
|
||
* ## ASM
|
||
* `>PUSHB stream`
|
||
* `>PUSHW ptr`
|
||
* `>PUSHW count`
|
||
* `>SYSCALL fwrite`
|
||
* ## RETURN VALUE
|
||
* Y,A = Bytes Written
|
||
*\--------------------------------------
|
||
K.FWrite.PFT ldx #_FWrite Needed by PFT
|
||
|
||
K.FWrite jsr PFT.CheckNode4
|
||
bcs K.FWrite.RET5
|
||
|
||
jsr UNISTD.Write
|
||
|
||
bcc K.FRead.RTS
|
||
|
||
K.FWrite.9 cmp #E.NODATA
|
||
sec
|
||
bne K.FRead.RTS IO Error
|
||
|
||
dec pStack FF = NODATA
|
||
dec pStack
|
||
dec pStack
|
||
dec pStack
|
||
dec pStack keep stream, ptr & count on stack
|
||
inc 0 = BLOCKING
|
||
* sec
|
||
rts
|
||
|
||
K.FWrite.RET5 >RET 5
|
||
*/--------------------------------------
|
||
* # FFlush
|
||
* ## C
|
||
* `int fflush( short int stream );`
|
||
* ## ASM
|
||
* `lda stream`
|
||
* `>SYSCALL fflush`
|
||
*\--------------------------------------
|
||
K.FFlush jsr PFT.CheckNodeA
|
||
bcs .9
|
||
|
||
lda (pFD)
|
||
bne STDIO.IOERR
|
||
>MLICALL MLI.FLUSH
|
||
|
||
.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
|
||
* `>PUSHB stream`
|
||
* `>PUSHL offset`
|
||
* `>PUSHB whence`
|
||
* `>SYSCALL fseek`
|
||
*\-------------------------------------
|
||
K.FSeek ldy #5
|
||
jsr PFT.CheckNodeY
|
||
bcc .11
|
||
|
||
>RET 6
|
||
|
||
.11 >PULLA whence
|
||
tax
|
||
|
||
>PULLL ACC32 offset
|
||
|
||
inc pStack discard hFile
|
||
|
||
lda (pFD)
|
||
bne STDIO.IOERR
|
||
|
||
cpx #SEEK.END
|
||
beq .30
|
||
|
||
bcs .98
|
||
|
||
dex
|
||
beq .20
|
||
|
||
stz K.MLI.PARAMS+2
|
||
stz K.MLI.PARAMS+3
|
||
stz K.MLI.PARAMS+4
|
||
bra .8
|
||
|
||
* SEEK.CUR
|
||
.20 >MLICALL MLI.GETMARK
|
||
bcc .8
|
||
rts
|
||
|
||
* SEEK.END
|
||
.30 >MLICALL MLI.GETEOF
|
||
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 MLI.SETMARK
|
||
bcc .9
|
||
|
||
cmp #MLI.E.BEYEOF
|
||
bne .9
|
||
|
||
>MLICALL MLI.SETEOF
|
||
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
|
||
* `short int feof( short int stream );`
|
||
* ## ASM
|
||
* `lda stream`
|
||
* `>SYSCALL feof`
|
||
* ## RETURN VALUE
|
||
* CC :
|
||
* A = $ff EOF
|
||
* A = 0 NOT EOF
|
||
* CS :
|
||
*\--------------------------------------
|
||
K.FEOF jsr PFT.CheckNodeA
|
||
bcs K.FSeek.RTS
|
||
|
||
lda (pFD)
|
||
tax
|
||
jmp (.1,x)
|
||
|
||
.1 .DA FS.EOF.REG
|
||
.DA STDIO.IOERR DIR
|
||
.DA DEV.EOF
|
||
.DA STDIO.IOERR BDEV
|
||
.DA STDIO.IOERR LNK
|
||
.DA STDIO.IOERR DSOCK
|
||
.DA SOCK.EOF
|
||
.DA PIPE.EOF
|
||
*/--------------------------------------
|
||
* # FTell
|
||
* Return the current value of the file-position indicator
|
||
* ## C
|
||
* `long ftell( short int stream );`
|
||
* ## ASM
|
||
* `lda stream`
|
||
* `>SYSCALL ftell`
|
||
* ## RETURN VALUE
|
||
* On stack (long)
|
||
*\--------------------------------------
|
||
K.FTell jsr PFT.CheckNodeA
|
||
bcs .9
|
||
|
||
>MLICALL MLI.GETMARK
|
||
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
|
||
* `>LDYA pathname`
|
||
* `>SYSCALL remove`
|
||
* ## RETURN VALUE
|
||
*\--------------------------------------
|
||
K.Remove jsr PFT.CheckPathYA
|
||
bcs .9
|
||
|
||
>MLICALL MLI.DESTROY
|
||
.9 rts
|
||
*/--------------------------------------
|
||
* # Rename
|
||
* Rename a file
|
||
* ## C
|
||
* `int rename ( const char * oldpath, const char * newpath );`
|
||
* ## ASM
|
||
* `>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 MLI.RENAME
|
||
|
||
.9 >RET 4
|
||
*/--------------------------------------
|
||
* # PrintF (BLOCKING)
|
||
* # FPrintF (BLOCKING)
|
||
* # SPrintF
|
||
* Prints C-Style String
|
||
* ## C
|
||
* `int printf ( const char *format, ... );`
|
||
* `int fprintf ( short int stream, const char *format, ... );`
|
||
* `int sprintf ( char *str, const char *format, ... );`
|
||
* ## ASM
|
||
* PrintF : (example is for printing Y,A as integer : format="%I", 2 bytes)
|
||
* `>PUSHW format`
|
||
* `>PUSHW i`
|
||
* `...`
|
||
* `>PUSHBI 2` #bytecount
|
||
* `>SYSCALL PrintF`
|
||
* FPrintF :
|
||
* `>PUSHB hFILE`
|
||
* `>PUSHW format`
|
||
* `>PUSHW i`
|
||
* `...`
|
||
* `>PUSHBI 2` #bytecount
|
||
* `>SYSCALL fprintf`
|
||
* SPrintF :
|
||
* `>PUSHW str`
|
||
* `>PUSHW format`
|
||
* `>PUSHW i`
|
||
* `...`
|
||
* `>PUSHBI 2` #bytecount
|
||
* `>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
|
||
* Modifiers for len and padding :
|
||
* + %d : '9' '12'
|
||
* + %2d : ' 9' '12'
|
||
* + %02d : '09' '12'
|
||
* + %11s : 'ABCDEFGH '
|
||
* + %011s : 'ABCDEFGH000'
|
||
* + %2f : '3.14'
|
||
*\--------------------------------------
|
||
.DUMMY ZPTMP+5,5 Used by : STDIO2
|
||
.OR ZPTMP+5 5 Bytes
|
||
PrintF.Cnt .BS 2
|
||
PrintF.hFILE .BS 1
|
||
STDIO.iStkB .BS 1
|
||
STDIO.PopCnt .BS 1
|
||
.ED
|
||
*--------------------------------------
|
||
K.PrintF.PadL .EQ FAC+5
|
||
K.PrintF.PadC .EQ ARG.SIGN
|
||
*--------------------------------------
|
||
K.PrintF ldy #S.PS.hStdOut
|
||
lda (pPS),y
|
||
sta PrintF.hFILE
|
||
|
||
ldx #1
|
||
.HS 2C BIT ABS
|
||
*--------------------------------------
|
||
K.FPrintf ldx #2
|
||
.HS 2C BIT ABS
|
||
*--------------------------------------
|
||
K.SPrintf ldx #3
|
||
*--------------------------------------
|
||
K.PrintF.1 sec format string->ptr2
|
||
jsr STDIO.GetParams
|
||
|
||
stx pIOBuf
|
||
sta pIOBuf+1 Output buffer->pIOBuf
|
||
|
||
sty STDIO.PopCnt Total bytes to POP
|
||
|
||
.1 jsr SHARED.GetCP2
|
||
beq .8 end of format..
|
||
|
||
.22 cmp #'%'
|
||
bne .20
|
||
|
||
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.NextCP2 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.AddY2P2 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.NextCP2
|
||
txa yes, jmp to it!
|
||
asl
|
||
tax
|
||
jsr PrintF.ESC
|
||
bcc .1
|
||
|
||
bra .99
|
||
|
||
.7 lda #'%'
|
||
|
||
.20 jsr PrintF.PutC
|
||
bcc .1
|
||
|
||
jmp STDIO.Exit
|
||
*--------------------------------------
|
||
.99 lda #E.BADARG
|
||
sec
|
||
jmp STDIO.Exit
|
||
*--------------------------------------
|
||
.8 lda PrintF.hFILE
|
||
beq .80 Writing to buffer, append \0
|
||
|
||
>PUSHA
|
||
>PUSHWI K.IOBuf
|
||
>PUSHW PrintF.Cnt Writing to File/dev...
|
||
|
||
jsr K.FWrite.PFT
|
||
bcc .81
|
||
|
||
tay
|
||
bne .9
|
||
|
||
>RET 5 0=BLOCKING
|
||
|
||
.80 ldy PrintF.Cnt A=0, Writing to buffer, append \0
|
||
sta (pIOBuf),y
|
||
clc
|
||
|
||
.81 >LDYA PrintF.Cnt
|
||
* clc
|
||
.9 jmp STDIO.Exit
|
||
*--------------------------------------
|
||
PrintFTBL1 .AS "bdDuefhHiILsS"
|
||
PrintFTBL1.Cnt .EQ *-PrintFTBL1
|
||
*--------------------------------------
|
||
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
|
||
*--------------------------------------
|
||
PrintF.B jsr STDIO.GetStkB
|
||
bcs PrintF.B.RTS
|
||
ldy #8
|
||
|
||
.1 asl
|
||
pha
|
||
lda #'0'/2
|
||
rol
|
||
jsr PrintF.PutC
|
||
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 sty .2+1
|
||
|
||
ror ACC32.Sign save signed/unsigned flag
|
||
jsr M32.ACC32Z
|
||
|
||
.1 jsr STDIO.GetStkB
|
||
bcs PrintF.B.RTS
|
||
|
||
sta ACC32-1,y PULL 4,2 or 1
|
||
dey
|
||
bne .1
|
||
|
||
bit ACC32.Sign
|
||
bpl .4
|
||
|
||
.2 ldy #$ff SELF MODIFIED
|
||
|
||
lda ACC32-1,y Get highest Byte
|
||
bpl .4 positive....
|
||
|
||
lda #$ff
|
||
|
||
.3 cpy #4
|
||
beq .4
|
||
|
||
iny
|
||
sta ACC32-1,y
|
||
bra .3
|
||
|
||
.4 ldx K.PrintF.PadL
|
||
ldy K.PrintF.PadC
|
||
|
||
rol ACC32.Sign get back signed/unsigned flag
|
||
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 (pStack) get current stack Ptr
|
||
sec at least 5 bytes remaining ?
|
||
sbc #5
|
||
bcc PrintF.StrNum.Err
|
||
|
||
sta (pStack)
|
||
|
||
* sec
|
||
adc pStack
|
||
ldy pStack+1 A,Y = float
|
||
ldx #FPU.SETFAC
|
||
jsr GP.ROMCALL
|
||
|
||
ldy #FOUTBuf+1 FOUT.1 will do a DEY
|
||
ldx #FPU.FOUT
|
||
jsr GP.ROMCALL
|
||
|
||
PrintF.StrNum ldy #0
|
||
.2 lda FOUTBuf,y
|
||
beq .8
|
||
|
||
iny
|
||
jsr PrintF.PutC
|
||
bcc .2
|
||
|
||
.9 rts
|
||
|
||
.8 clc
|
||
rts
|
||
PrintF.StrNum.Err
|
||
lda #E.STACK
|
||
sec
|
||
rts
|
||
*--------------------------------------
|
||
PrintF.S ldy #$ff CSTR
|
||
.HS 2C bit abs
|
||
PrintF.SS ldy #$00 PSTR
|
||
|
||
sty .1+1
|
||
|
||
jsr STDIO.GetStkB
|
||
bcs .9
|
||
|
||
sta ZPPtr1+1
|
||
jsr STDIO.GetStkB
|
||
bcs .9
|
||
|
||
sta ZPPtr1
|
||
|
||
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.PutC
|
||
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.PutC
|
||
bcs .9
|
||
|
||
iny
|
||
bne .3
|
||
|
||
* clc
|
||
.9 rts
|
||
*--------------------------------------
|
||
PrintF.HH jsr STDIO.GetStkB
|
||
bcs STDIO.RTS
|
||
|
||
pha LO byte
|
||
jsr STDIO.GetStkB
|
||
plx
|
||
bcs STDIO.RTS
|
||
|
||
pha
|
||
txa
|
||
jsr PrintF.H.1
|
||
plx
|
||
bcs STDIO.RTS
|
||
|
||
txa
|
||
bra PrintF.H.1
|
||
*--------------------------------------
|
||
PrintF.H jsr STDIO.GetStkB
|
||
bcs STDIO.RTS
|
||
|
||
PrintF.H.1 jsr STDIO.A2HexAX
|
||
jsr PrintF.PutC
|
||
bcs STDIO.RTS
|
||
|
||
txa
|
||
*--------------------------------------
|
||
PrintF.PutC 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
|
||
STDIO.RTS rts
|
||
*/--------------------------------------
|
||
* # ScanF (BLOCKING)
|
||
* # FScanF (BLOCKING)
|
||
* # SScanF
|
||
* Read formatted data from string
|
||
* ## C
|
||
* `int scanf( const char *format, ... );`
|
||
* `int fscanf( short int stream, const char *format, ... );`
|
||
* `int sscanf ( const char *s, const char *format, ... );`
|
||
* ## ASM
|
||
* ScanF :
|
||
* `>PUSHW format`
|
||
* `>PUSHW ptr`
|
||
* `...`
|
||
* `>PUSHB bytecount`
|
||
* `>SYSCALL scanf`
|
||
* FScanF :
|
||
* `>PUSHB stream`
|
||
* `>PUSHW format`
|
||
* `>PUSHW ptr`
|
||
* `...`
|
||
* `>PUSHB bytecount`
|
||
* `>SYSCALL fscanf`
|
||
* SScanF :
|
||
* `>PUSHW s`
|
||
* `>PUSHW format`
|
||
* `>PUSHW ptr`
|
||
* `...`
|
||
* `>PUSHB bytecount`
|
||
* `>SYSCALL sscanf`
|
||
* Specifiers :
|
||
* + %i : short int
|
||
* + %d : byte
|
||
* + %I : int
|
||
* + %D : word
|
||
* + %L : long int
|
||
* + %U : dword
|
||
* + %h : HEX byte
|
||
* + %H : HEX word
|
||
* + %s : string
|
||
* TODO : %10s
|
||
* ## RETURN VALUE
|
||
* A = Number of arguments filled.
|
||
*\--------------------------------------
|
||
K.ScanF ldy #S.PS.hStdIn
|
||
lda (pPS),y
|
||
sta PrintF.hFILE
|
||
|
||
ldx #1
|
||
.HS 2C BIT ABS
|
||
*--------------------------------------
|
||
K.FScanF ldx #2
|
||
.HS 2C BIT ABS
|
||
*--------------------------------------
|
||
K.SScanF ldx #3
|
||
*--------------------------------------
|
||
K.SScanF.1 clc format string->ptr1
|
||
jsr STDIO.GetParams stz PrintF.Cnt
|
||
|
||
stx ZPPtr2
|
||
sta ZPPtr2+1 Output buffer->ZPPtr2
|
||
|
||
sty STDIO.PopCnt Total bytes to POP
|
||
|
||
ldx PrintF.hFILE
|
||
beq .1
|
||
|
||
txa
|
||
>PUSHA
|
||
>PUSHW pIOBuf
|
||
>PUSHWI 256
|
||
jsr K.FGetS
|
||
bcc .1
|
||
|
||
tax
|
||
bne STDIO.RTS
|
||
>RET 4
|
||
|
||
.1 jsr SHARED.GetCP1 End Of format?
|
||
beq .8
|
||
|
||
cmp #'%' Escape ?
|
||
beq .2
|
||
|
||
cmp #C.SPACE Space ?
|
||
beq .12
|
||
|
||
sta .11+1
|
||
|
||
jsr SHARED.GetCP2
|
||
beq .9
|
||
|
||
.11 cmp #$ff Same char in string?
|
||
beq .1
|
||
|
||
bra .9
|
||
|
||
.12 jsr SHARED.GetCP2
|
||
beq .9
|
||
|
||
cmp #C.SPACE
|
||
bne .9
|
||
|
||
.13 jsr SHARED.GetCP2
|
||
cmp #C.SPACE another space ?
|
||
beq .13
|
||
|
||
bra .1
|
||
|
||
.2 jsr SHARED.GetCP1 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 STDIO.Exit
|
||
|
||
.4 jsr STDIO.GetStkB
|
||
bcs .9
|
||
|
||
sta ZPPtr3+1
|
||
jsr STDIO.GetStkB
|
||
bcs .9
|
||
|
||
sta ZPPtr3
|
||
|
||
jsr .5
|
||
bcs .9 out of Ptr on stack
|
||
|
||
inc PrintF.Cnt parsed one more arg!
|
||
bra .1 no chance more than 256 ptrs on stack
|
||
|
||
.8 ldy PrintF.Cnt Arg processed
|
||
lda #0
|
||
clc
|
||
jmp STDIO.Exit
|
||
*--------------------------------------
|
||
.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.AddY2P2 Y=char count parsed
|
||
|
||
ply get back VAL size
|
||
|
||
.1 lda ACC32-1,y
|
||
dey
|
||
sta (ZPPtr3),y
|
||
bne .1
|
||
|
||
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 #C.SPACE is it a space ?
|
||
bne .1
|
||
|
||
.2 lda #0 add \0 to param ptr
|
||
sta (ZPPtr3),y
|
||
|
||
K.SScanF.Fwd jmp SHARED.AddY2P2 Y=char count parsed
|
||
*--------------------------------------
|
||
* IN:
|
||
* CC : format in ZPPtr1
|
||
* CS : format in ZPPtr2
|
||
* X = 3 : get format & buffer
|
||
* X = 2 : get format & hFile
|
||
* X = 1 : get format only
|
||
* OUT:
|
||
* X = Buf LO
|
||
* A = Buf HI
|
||
* format on stack
|
||
* Y = BytePtr
|
||
*--------------------------------------
|
||
STDIO.GetParams stz PrintF.Cnt
|
||
stz PrintF.Cnt+1
|
||
|
||
lda (pStack) Bytecount
|
||
|
||
tay
|
||
sty STDIO.iStkB
|
||
|
||
iny
|
||
lda (pStack),y format LO
|
||
pha
|
||
|
||
iny
|
||
lda (pStack),y format HI
|
||
bcs .10
|
||
|
||
sta ZPPtr1+1
|
||
pla
|
||
sta ZPPtr1
|
||
bra .11
|
||
|
||
.10 sta ZPPtr2+1
|
||
pla
|
||
sta ZPPtr2
|
||
|
||
.11 dex
|
||
beq .1
|
||
|
||
dex
|
||
beq .2
|
||
|
||
.3 stz PrintF.hFILE
|
||
|
||
iny
|
||
lda (pStack),y str LO
|
||
tax
|
||
|
||
iny
|
||
lda (pStack),y str HI
|
||
|
||
rts
|
||
|
||
.2 iny
|
||
lda (pStack),y hFILE
|
||
sta PrintF.hFILE
|
||
|
||
.1 ldx #K.IOBuf
|
||
lda /K.IOBuf
|
||
|
||
rts
|
||
*--------------------------------------
|
||
STDIO.GetStkB phy
|
||
|
||
ldy STDIO.iStkB
|
||
beq .9
|
||
|
||
lda (pStack),y
|
||
dec STDIO.iStkB
|
||
|
||
ply
|
||
clc
|
||
rts
|
||
|
||
.9 lda #E.STACK
|
||
|
||
ply
|
||
sec
|
||
rts
|
||
*--------------------------------------
|
||
STDIO.Exit php
|
||
pha
|
||
|
||
lda pStack
|
||
sec
|
||
adc STDIO.PopCnt
|
||
sta pStack
|
||
|
||
pla
|
||
plp
|
||
rts
|
||
*--------------------------------------
|
||
* Convert A to 2 hex digits in AX
|
||
*--------------------------------------
|
||
STDIO.A2HexAX pha
|
||
|
||
and #$0F
|
||
jsr .8
|
||
|
||
tax
|
||
|
||
pla
|
||
lsr
|
||
lsr
|
||
lsr
|
||
lsr
|
||
|
||
.8 ora #$30
|
||
cmp #'9'+1
|
||
bcc .9
|
||
|
||
adc #6
|
||
|
||
.9 rts
|
||
*--------------------------------------
|
||
MAN
|
||
SAVE usr/src/sys/kernel.s.stdio
|
||
LOAD usr/src/sys/kernel.s
|
||
ASM
|