A2osX/SYS/KERNEL.S.STDIO.txt

1405 lines
27 KiB
Plaintext
Raw Normal View History

2017-12-22 21:24:30 +00:00
NEW
PREFIX /A2OSX.BUILD
2017-12-22 21:24:30 +00:00
AUTO 4,1
2018-08-22 15:23:27 +00:00
*--------------------------------------
*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
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # FPutC
* Print A (char) to hFILE
2018-06-18 06:22:50 +00:00
* ## C
2018-08-08 15:13:37 +00:00
* `int fputc ( hFILE stream , int character );`
2018-06-18 06:22:50 +00:00
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-06-19 15:08:22 +00:00
* A : character
* Y : stream
2018-06-14 15:31:36 +00:00
* **Out:**
2018-06-18 06:22:50 +00:00
* CC = success
*\--------------------------------------
2018-06-19 15:08:22 +00:00
K.FPutC sta K.IOBuf
tya
2018-06-18 06:22:50 +00:00
bra K.PutChar.1
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # PutChar
* ## C
* `int putchar ( int character );`
* ## ASM
* Print A (char) to StdOut
2018-06-14 15:31:36 +00:00
* **In:**
2018-06-18 06:22:50 +00:00
* A : char to print
2018-06-14 15:31:36 +00:00
* **Out:**
2018-06-18 06:22:50 +00:00
* CC = success
*\--------------------------------------
2018-06-18 06:22:50 +00:00
K.PutChar sta K.IOBuf
ldy #S.PS.hStdOut
lda (pPs),y
2018-08-08 15:13:37 +00:00
K.PutChar.1 jsr K.GetMemPtr
bcs K.PutS.9
>STYA pFD
2018-06-19 15:08:22 +00:00
ldx #1
K.PutChar.X >LDYAI K.IOBuf
>STYA K.S.IOCTL+S.IOCTL.BUFPTR
stx K.S.IOCTL+S.IOCTL.BYTECNT
2018-06-22 06:24:35 +00:00
stz K.S.IOCTL+S.IOCTL.BYTECNT+1
2018-07-19 15:33:55 +00:00
jmp IO.Write.I
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # PutS
* Write Str to StdOut, appends '\r\n'
2018-06-18 06:22:50 +00:00
* ## C
* `int puts ( const char * str );`
2018-06-14 15:31:36 +00:00
* **In:**
2018-07-27 13:34:34 +00:00
* ## ASM
* `>LDYAI str`
* `>SYSCALL puts`
2018-06-14 15:31:36 +00:00
* **Out:**
2018-06-18 06:22:50 +00:00
* CC = success
*\--------------------------------------
2018-06-19 15:08:22 +00:00
K.PutS >STYA K.S.IOCTL+S.IOCTL.BUFPTR
>STYA ZPPtr1
ldy #S.PS.hStdOut
lda (pPs),y
2018-06-19 15:08:22 +00:00
jsr K.FPutS.I
2018-08-08 15:13:37 +00:00
bcs K.PutS.9
lda #13
2018-06-19 15:08:22 +00:00
sta K.IOBuf
lda #10
2018-06-19 15:08:22 +00:00
sta K.IOBuf+1
ldx #2
bra K.PutChar.X
2018-08-08 15:13:37 +00:00
K.PutS.9 rts
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # FPutS
* Write Str to FILE
2018-06-18 06:22:50 +00:00
* ## C
2018-07-26 15:26:39 +00:00
* `int fputs (hFILE stream, const char * str );`
2018-07-27 13:34:34 +00:00
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-07-27 13:34:34 +00:00
* `>PUSHW str`
* `lda stream`
* `>SYSCALL fputs`
2018-06-14 15:31:36 +00:00
* **Out:**
2018-06-18 06:22:50 +00:00
* CC = success
*\--------------------------------------
2018-07-27 13:34:34 +00:00
K.FPutS pha
>PULLA
2018-07-27 13:34:34 +00:00
sta K.S.IOCTL+S.IOCTL.BUFPTR
sta ZPPtr1
>PULLA
sta K.S.IOCTL+S.IOCTL.BUFPTR+1
sta ZPPtr1+1
pla
2018-08-08 15:13:37 +00:00
K.FPutS.I jsr K.GetMemPtr
bcs K.PutS.9
>STYA pFD
2018-07-27 13:34:34 +00:00
2018-06-19 15:08:22 +00:00
ldy #0
ldx #0
2018-06-19 15:08:22 +00:00
.1 lda (ZPPtr1),y
beq .2
iny
bne .1
inx
2018-06-19 15:08:22 +00:00
inc ZPPtr1+1
bra .1
2018-06-19 15:08:22 +00:00
.2 sty K.S.IOCTL+S.IOCTL.BYTECNT
2018-06-22 06:24:35 +00:00
stx K.S.IOCTL+S.IOCTL.BYTECNT+1
2018-07-19 15:33:55 +00:00
jmp IO.Write.I
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # PrintF/SPrintF/FPrintF
* Prints C-Style String
2018-06-18 06:22:50 +00:00
* ## C
* `int printf ( const char * format, ... );`
* `int sprintf ( char * str, const char * format, ... );`
2018-06-18 08:44:02 +00:00
* `int fprintf ( hFILE stream, const char * format, ... );`
2018-06-18 06:22:50 +00:00
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-06-18 08:44:02 +00:00
* PrintF : (example is for printing Y,A as integer : format="Y,A= %I", 2 bytes)
* `>PUSHYA`
2018-07-24 06:24:23 +00:00
* `...`
* `>PUSHBI bytecount`
2018-06-18 08:44:02 +00:00
* `>LDYAI format`
* `>SYSCALL printf`
2018-06-18 06:22:50 +00:00
* SPrintF :
2018-06-18 08:44:02 +00:00
* `>PUSHYA`
2018-07-24 06:24:23 +00:00
* `...`
* `>PUSHBI bytecount`
2018-06-18 08:44:02 +00:00
* `>PUSHWI format`
* `>LDYAI str`
* `>SYSCALL sprintf`
2018-06-18 06:22:50 +00:00
* FPrintF :
2018-06-18 08:44:02 +00:00
* `>PUSHYA`
2018-07-24 06:24:23 +00:00
* `...`
* `>PUSHBI bytecount`
2018-06-18 08:44:02 +00:00
* `>PUSHWI format`
* `lda hFILE`
* `>SYSCALL fprintf`
2018-06-14 15:31:36 +00:00
* **Out:**
2018-06-18 08:44:02 +00:00
* CC : success, Y,A = bytes sent
* CS : error, A = code from Output
* Specifiers :
2018-06-18 06:22:50 +00:00
* + %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 :
2018-06-18 06:22:50 +00:00
* + %d : '9' '12'
* + %2d : ' 9' '12'
* + %02d : '09' '12'
* + %11s : 'ABCDEFGH '
* + %011s : 'ABCDEFGH000'
* + %2f : '3.14'
*\--------------------------------------
2018-06-18 06:22:50 +00:00
K.SPrintF >STYA pIOBuf Out Buffer
>PULLW ZPPtr1 format
bra K.PrintF.1
2018-08-08 15:13:37 +00:00
K.FPrintF jsr K.GetMemPtr A = hFILE
>STYA pFD
>PULLW ZPPtr1 format
bra K.PrintF.0
2018-06-18 06:22:50 +00:00
K.PrintF >STYA ZPPtr1 format
ldy #S.PS.hStdOut
lda (pPs),y
2018-08-08 15:13:37 +00:00
jsr K.GetMemPtr
>STYA pFD
K.PrintF.0 >LDYAI K.IOBuf
>STYA pIOBuf
2018-07-13 14:38:24 +00:00
>STYA K.S.IOCTL+S.IOCTL.BUFPTR
2018-07-13 14:38:24 +00:00
K.PrintF.1 stz K.S.IOCTL+S.IOCTL.BYTECNT
stz K.S.IOCTL+S.IOCTL.BYTECNT+1
2018-08-22 15:23:27 +00:00
stz PrintF.GetByte+1
2018-07-13 14:38:24 +00:00
ldy #0
.1 lda (ZPPtr1),y
2018-07-13 14:38:24 +00:00
beq .8 end of format..
iny
cmp #'%'
bne .10
stz K.PrintF.PadL
lda #' '
sta K.PrintF.PadC
.2 ldx #PrintFTBL2-PrintFTBL1-1
lda (ZPPtr1),y
beq .99
iny
.3 cmp PrintFTBL1,x do we have a %x command?
2018-07-13 14:38:24 +00:00
beq .6 yes, jmp to it!
dex
bpl .3 no valid letter...
cmp #'0' ...a 0...mmm... padding char?
bne .4
2018-06-18 08:44:02 +00:00
ldx K.PrintF.PadL K.PrintF.PadL is not nul, so this 0 is second digit
bne .5
* lda #'0'
2018-06-18 08:44:02 +00:00
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...
2018-07-13 14:38:24 +00:00
.6 phy
txa
asl
tax
jsr PrintF.ESC
ply
bcc .1
2018-08-22 15:23:27 +00:00
bcs .99
2018-07-13 14:38:24 +00:00
2018-08-22 15:23:27 +00:00
.8 jsr PrintF.Flush
bra .99
.10 cmp #'\'
bne .20
ldx #PrintFTBL2.OUT-PrintFTBL2-1
lda (ZPPtr1),y
beq .99
iny
.12 cmp PrintFTBL2,x
beq .13
dex
bpl .12
bra .1
.13 lda PrintFTBL2.OUT,x
.20 jsr PrintF.COut
bcc .1
2018-08-22 15:23:27 +00:00
.99 php
pha
lda pStack
sec ByteCnt byte
adc (pStack) ... ByteCnt
sta pStack CC
pla
plp
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 #'%' \%
*--------------------------------------
2018-08-22 15:23:27 +00:00
PrintF.BB jsr PrintF.GetByte
bcs PrintF.BB.RTS
pha
jsr PrintF.B
pla
bcc PrintF.B.1
PrintF.BB.RTS rts
*--------------------------------------
2018-08-22 15:23:27 +00:00
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)
ldx #0 one byte
2018-08-22 15:23:27 +00:00
jsr PrintF.GetByte
bcs PrintF.BB.RTS
sta HEXBUF
stz HEXBUF+1
bra PrintF.DD.1
PrintF.II sec signed int
.HS 90 BCC
PrintF.DD clc unsigned int (WORD)
ldx #1 two bytes
2018-08-22 15:23:27 +00:00
jsr PrintF.GetByte
bcs PrintF.BB.RTS
sta HEXBUF
jsr PrintF.GetByte
bcs PrintF.BB.RTS
sta HEXBUF+1
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)
2018-08-22 15:23:27 +00:00
ldx #$ff
2018-08-22 15:23:27 +00:00
.1 jsr PrintF.GetByte
bcs PrintF.BB.RTS
inx
sta HEXBUF,x
cpx #3
bne .1
* ldx #3 4 bytes
PrintF.U.1 bcc 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 .31+1
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
.31 bit #$ff SELF MODIFIED -sign to print before digits ?
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
*--------------------------------------
2018-06-18 06:22:50 +00:00
* 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
2018-08-22 15:23:27 +00:00
2018-08-23 15:16:20 +00:00
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
2018-08-22 15:23:27 +00:00
2018-06-13 15:18:08 +00:00
ldx #ROM.SETFAC
jsr GP.ROMCALL
2018-08-23 15:16:20 +00:00
lda PrintF.GetByte+1
clc
adc #5
sta PrintF.GetByte+1
ldy #3 In order not to trash A2osX.SaveSM,A2osX.SaveSX
2018-06-13 15:18:08 +00:00
ldx #ROM.FOUT
jsr GP.ROMCALL
ldy #0
.2 lda $102,y
beq .8
jsr PrintF.COut
iny
bne .2
.8 clc
2018-08-23 15:16:20 +00:00
rts
.9 sec
rts
*--------------------------------------
2018-08-22 15:23:27 +00:00
PrintF.HH jsr PrintF.GetByte
bcs PrintF.H.9
pha
jsr PrintF.H
pla
bra PrintF.H.1
*--------------------------------------
2018-08-22 15:23:27 +00:00
PrintF.H jsr PrintF.GetByte
bcs PrintF.H.9
PrintF.H.1 pha
jsr PrintF.NN.1
pla
bra PrintF.N.1
2018-08-22 15:23:27 +00:00
PrintF.H.9 rts
*--------------------------------------
2018-08-22 15:23:27 +00:00
PrintF.N jsr PrintF.GetByte
bcs PrintF.H.9
PrintF.N.1 and #$0F
bra PrintF.NN.2
2018-08-22 15:23:27 +00:00
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
2018-08-22 15:23:27 +00:00
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
*--------------------------------------
2018-08-22 15:23:27 +00:00
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
2018-07-13 14:38:24 +00:00
ldy K.S.IOCTL+S.IOCTL.BYTECNT
sta (pIOBuf),y
2018-07-13 14:38:24 +00:00
inc K.S.IOCTL+S.IOCTL.BYTECNT
bne .8
lda pIOBuf+1
eor /K.IOBuf
bne .7
* we are printing to IObuf, flush!
2018-07-13 14:38:24 +00:00
lda K.S.IOCTL+S.IOCTL.BYTECNT+1
pha
lda #1 Flush $100 bytes
2018-07-13 14:38:24 +00:00
sta K.S.IOCTL+S.IOCTL.BYTECNT+1
pla
inc
2018-07-13 14:38:24 +00:00
sta K.S.IOCTL+S.IOCTL.BYTECNT+1
.7 inc pIOBuf+1
2018-07-13 14:38:24 +00:00
inc K.S.IOCTL+S.IOCTL.BYTECNT+1
.8 ply
clc
rts
2018-07-13 14:38:24 +00:00
*--------------------------------------
2018-07-19 15:33:55 +00:00
PrintF.Flush jmp IO.Write.I
*/--------------------------------------
2018-07-27 13:34:34 +00:00
* # 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`
* **Out:**
* Y,A: s
* CC = success
*\--------------------------------------
2018-08-08 15:13:37 +00:00
K.FGetS pha save hFILE
>PULLW ZPPtr1 s
2018-07-27 13:34:34 +00:00
>PULLA
sec
sbc #2
eor #$ff
sta ZPPtr2 !n
>PULLA
sbc #0
eor #$ff
sta ZPPtr2+1 !n
pla
2018-08-08 15:13:37 +00:00
jsr K.GetMemPtr
bcs .99
>STYA pFD
2018-07-27 13:34:34 +00:00
jsr K.GetC.I
bcs .9
.1 lda K.IOBuf
cmp #C.CR
beq .8
sta (ZPPtr1)
inc ZPPtr1
bne .2
inc ZPPtr1+1
.2 inc ZPPtr2
bne .3
inc ZPPtr2+1
beq .8
.3 jsr IO.READ.I
bcc .1
.8 clc
.9 pha
lda #0
sta (ZPPtr1)
pla
2018-08-08 15:13:37 +00:00
.99 rts
2018-07-27 13:34:34 +00:00
*/--------------------------------------
* # GetChar
* Get char from StdIn
2018-06-14 15:31:36 +00:00
* **In:**
* none.
2018-06-14 15:31:36 +00:00
* **Out:**
* CC = success
* A = char
*\--------------------------------------
K.GetChar ldy #S.PS.hStdIn
lda (pPs),y
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # GetC
* Get char from Node
2018-06-18 06:22:50 +00:00
* ## C
* `int getc ( FILE * stream );`
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
* A = hNODE
2018-06-14 15:31:36 +00:00
* **Out:**
* CC = success
* A = char
2018-07-27 13:34:34 +00:00
*\-----------a---------------------------
2018-08-08 15:13:37 +00:00
K.GetC jsr K.GetMemPtr
2018-07-27 13:34:34 +00:00
bcs K.GetC.9
2018-08-08 15:13:37 +00:00
>STYA pFD
2018-07-27 13:34:34 +00:00
K.GetC.I >LDYAI K.IOBuf
2018-07-18 15:30:42 +00:00
>STYA K.S.IOCTL+S.IOCTL.BUFPTR
lda #1
sta K.S.IOCTL+S.IOCTL.BYTECNT
stz K.S.IOCTL+S.IOCTL.BYTECNT+1
2018-07-19 15:33:55 +00:00
jsr IO.READ.I
2018-07-27 13:34:34 +00:00
bcs K.GetC.9
2018-07-18 15:30:42 +00:00
lda K.IOBuf
2018-07-27 13:34:34 +00:00
K.GetC.9 rts
*/--------------------------------------
2018-06-18 06:22:50 +00:00
* # SScanF
* Read formatted data from string
* ## C
2018-07-23 06:28:47 +00:00
* `int sscanf ( const char * s, const char * format, ... );`
2018-06-18 06:22:50 +00:00
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-08-08 15:13:37 +00:00
* `>PUSHW ptr`
* `...`
* `>PUSHBI bytecount`
* `>PUSHWI format`
2018-06-18 06:22:50 +00:00
* + %i : short int
* + %d : byte
* + %I : int
* + %D : word
* + %L : long int
* + %U : dword
* + %h : HEX byte
* + %H : HEX word
2018-07-26 15:26:39 +00:00
* + %s : string
2018-08-08 15:13:37 +00:00
* TODO : %10s
2018-06-18 06:22:50 +00:00
* `>LDYA s`
2018-08-22 15:23:27 +00:00
* `>SYSCALL sscanf`
2018-06-14 15:31:36 +00:00
* **Out:**
2018-08-08 15:13:37 +00:00
* A = Number of arguments filled.
*\--------------------------------------
2018-06-18 06:22:50 +00:00
K.SScanF >STYA ZPPtr2 String to Scan
>PULLW ZPPtr1 format
2018-07-23 06:28:47 +00:00
2018-08-08 15:13:37 +00:00
stz .5+1 reset LStack Ptr
stz .80+1 rest Arg processed
2018-06-18 06:22:50 +00:00
.1 lda (ZPPtr1) End Of format?
beq .8
inc ZPPtr1
bne .11
inc ZPPtr1+1
2018-08-08 15:13:37 +00:00
.11 cmp #'%' Escape ?
beq .2
2018-08-08 15:13:37 +00:00
cmp #' ' Space ?
beq .12
cmp (ZPPtr2) Same char in string?
bne .9
inc ZPPtr2
bne .1
inc ZPPtr2+1
bra .1
2018-08-08 15:13:37 +00:00
.12 inc ZPPtr2 Space....
bne .14
inc ZPPtr2+1
.14 cmp (ZPPtr2) another one ?
beq .12
bne .1
.2 lda (ZPPtr1) Get specifier after %
2018-06-18 06:22:50 +00:00
beq .9 unexpected End of format after "%" ?
inc ZPPtr1
bne .21
inc ZPPtr1+1
2018-07-27 13:34:34 +00:00
.21 ldx #K.SScanFJMP-K.SScanFTBL-2
.3 cmp K.SScanFTBL,x
beq .4
dex
2018-07-27 13:34:34 +00:00
dex
bpl .3
2018-06-18 06:22:50 +00:00
.9 jsr .8
lda #MLI.E.EOF
sec
rts
.4 jsr .5
2018-07-27 13:34:34 +00:00
bcs .9 out of Ptr on stack
2018-06-18 06:22:50 +00:00
bra .1
2018-06-18 06:22:50 +00:00
.8 lda pStack
2018-07-27 13:34:34 +00:00
sec ByteCnt byte
adc (pStack) ... ByteCnt
2018-06-18 06:22:50 +00:00
sta pStack CC
2018-08-08 15:13:37 +00:00
.80 lda #$ff SELF MODIFIED Arg porcessed
2018-06-18 06:22:50 +00:00
.99 rts
*--------------------------------------
2018-08-08 15:13:37 +00:00
.5 lda #$FF SELF MODIFIED LStack Ptr
2018-07-27 13:34:34 +00:00
cmp (pStack)
2018-06-18 06:22:50 +00:00
beq .99 CS
2018-07-27 13:34:34 +00:00
tay
iny
2018-06-18 06:22:50 +00:00
lda (pStack),y
sta ZPPtr3
2018-07-27 13:34:34 +00:00
2018-06-18 06:22:50 +00:00
iny
lda (pStack),y
sta ZPPtr3+1 get VAR Ptr
2018-07-27 13:34:34 +00:00
sty .5+1
2018-08-08 15:13:37 +00:00
inc .80+1 parsed one more arg!
jmp (K.SScanFJMP,x)
*--------------------------------------
2018-07-27 13:34:34 +00:00
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
2018-07-26 15:26:39 +00:00
.DA K.SScanF.S
*--------------------------------------
K.SScanF.I
K.SScanF.D
K.SScanF.II
K.SScanF.DD
K.SScanF.L
2018-07-26 15:26:39 +00:00
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
2018-07-26 15:26:39 +00:00
K.SScanF.H lda K.SScanFTBL+1,x Get VAR size
pha
jsr STDLIB.GetHex
2018-07-26 15:26:39 +00:00
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
2018-07-26 15:26:39 +00:00
*--------------------------------------
K.SScanF.S ldy #$ff
.1 iny
2018-09-07 14:12:42 +00:00
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 ?
2018-07-26 15:26:39 +00:00
bne .1
2018-09-07 14:12:42 +00:00
.2 lda #0 add \0 to param ptr
2018-08-08 15:13:37 +00:00
sta (ZPPtr3),y
2018-07-26 15:26:39 +00:00
K.SScanF.Fwd tya Y=char count parsed
clc
adc ZPPtr2
sta ZPPtr2
bcc .8
2018-08-08 15:13:37 +00:00
clc
2018-07-26 15:26:39 +00:00
inc ZPPtr2+1
.8 rts
*/--------------------------------------
* # FOpen
* Open a file
2018-06-18 15:48:00 +00:00
* ## C
* `hFILE fopen ( const char * filename, short int mode, short int ftype, int auxtype );`
2018-06-18 08:44:02 +00:00
* **In:**
2018-06-18 15:48:00 +00:00
* ## ASM
* `>PUSHWI auxtype`
* `>PUSHBI ftype`
* `>PUSHBI mode`
* + SYS.FOpen.R : if R and !exists -> ERROR
* + SYS.FOpen.W : if W and !exists -> CREATE
* + SYS.FOpen.A : Append
* + SYS.FOpen.T : Open/Append in Text mode
* + SYS.FOpen.X : Create if not exists
2018-07-11 15:13:29 +00:00
* http://man7.org/linux/man-pages/man3/fopen.3.html
* r = O_RDONLY
* w = O_WRONLY | O_CREAT | O_TRUNC
* a = O_WRONLY | O_CREAT | O_APPEND
* r+ = O_RDWR
* w+ = O_RDWR | O_CREAT | O_TRUNC
* a+ = O_RDWR | O_CREAT | O_APPEND
*
* TODO: mode="w+t=TYP,x=AUXTYPE"
2018-06-18 15:48:00 +00:00
* `>LDYAI filename`
2018-06-18 08:44:02 +00:00
* **Out:**
* CC : A = hFILE
* CS : A = EC
*\--------------------------------------
2018-07-25 15:26:14 +00:00
K.FOpen jsr PFT.CheckPathYA
jsr STDIO.SetMLIPathYA
>PULLB K.FOpen.MODE
>PULLB K.FOpen.TYPE
>PULLW K.FOpen.AUXTYPE
2018-09-05 15:22:46 +00:00
K.FOpen.I >MLICALL MLIGETFILEINFO
bcc K.FOpen.10 Already Exists
bit K.FOpen.MODE Create if not exists ?
bpl K.FOpen.9 No, return MLI error
lda #S.FI.A.FULL Yes, Create...
sta K.MLI.PARAMS+3 Access
lda K.FOpen.TYPE
sta K.MLI.PARAMS+4 File type
>LDYA K.FOpen.AUXTYPE
>STYA K.MLI.PARAMS+5 Aux type
lda #S.FI.ST.STD
sta K.MLI.PARAMS+7
ldx #3
.1 lda DATELO,x
sta K.MLI.PARAMS+8,x
dex
bpl .1
>MLICALL MLICREATE
bcc K.FOpen.10
K.FOpen.9 rts
2018-08-08 15:13:37 +00:00
K.FOpen.10 lda #S.FD.REG
sec
adc K.MLI.PATH
tay
lda #0
2018-08-11 10:57:57 +00:00
ldx #S.MEM.F.INIT0+S.MEM.F.FD
jsr MEM.GetMem.YAX
bcs K.FOpen.9
2018-08-08 15:13:37 +00:00
>STYA pFD
stx .8+1
2018-08-08 15:13:37 +00:00
ldx #0
ldy #S.FD.REG
.1 inx
lda K.MLI.PATH,x
sta (pFD),y
iny
cpx K.MLI.PATH
bne .1
lda #0
sta (pFD),y
2018-07-10 15:33:13 +00:00
* ldy #S.FD.T Done by GetMem0
* lda #S.FD.T.REG
2018-08-08 15:13:37 +00:00
* sta (pFD),y
jsr STDIO.SetIOBUF
bcs .98
>MLICALL MLIOPEN
bcs .98
lda K.MLI.PARAMS+5 get ref_num
2018-07-10 15:33:13 +00:00
ldy #S.FD.REG.REF
2018-08-08 15:13:37 +00:00
sta (pFD),y
sta K.MLI.PARAMS+1 Next MLI Calls are REF_NUM based
2018-05-22 06:01:05 +00:00
lda K.FOpen.MODE
bit #SYS.FOpen.W
beq .20 Write mode ?
2018-05-22 06:01:05 +00:00
and #SYS.FOpen.A Append ?
bne .11 yes, go to end of file
2018-05-22 06:01:05 +00:00
stz K.MLI.PARAMS+2
stz K.MLI.PARAMS+3
stz K.MLI.PARAMS+4
>MLICALL MLISETEOF no, reset size to 0
bra .21
2018-05-22 06:01:05 +00:00
.11 >MLICALL MLIGETEOF
bcs .98
2018-05-22 06:01:05 +00:00
>MLICALL MLISETMARK
.21 bcs .98
.20 lda K.FOpen.MODE
and #SYS.FOpen.T Text Mode ?
beq .8
lda #$FF
sta K.MLI.PARAMS+2
2018-08-22 15:23:27 +00:00
lda #C.CR
sta K.MLI.PARAMS+3
>MLICALL MLINEWLINE
2018-08-22 15:23:27 +00:00
.8 lda #$ff Self Modified, hFD
clc
rts CC
2018-05-22 06:01:05 +00:00
.98 pha save MLI error
lda .8+1
2018-06-22 06:24:35 +00:00
jsr K.FClose
pla get back MLI error
sec
rts
*--------------------------------------
K.FOpen.MODE .BS 1
K.FOpen.TYPE .BS 1
K.FOpen.AUXTYPE .BS 2
*/--------------------------------------
2018-06-22 06:24:35 +00:00
* # FClose
* Close a file
2018-07-10 15:33:13 +00:00
* ## C
2018-09-05 15:22:46 +00:00
* int fclose ( hFILE stream );
2018-07-10 15:33:13 +00:00
* ## ASM
2018-06-18 08:44:02 +00:00
* **In:**
* A = hFILE
2018-06-18 08:44:02 +00:00
* **Out:**
*\--------------------------------------
2018-06-22 06:24:35 +00:00
K.FClose jsr PFT.CheckNodeA
2018-07-10 15:33:13 +00:00
sta .8+1
2018-06-21 15:12:10 +00:00
jsr K.GetMemPtr
2018-08-08 15:13:37 +00:00
>STYA pFD
2018-07-10 15:33:13 +00:00
ldy #S.FD.REG.REF
2018-08-08 15:13:37 +00:00
lda (pFD),y
beq .1
sta K.MLI.PARAMS+1
>MLICALL MLICLOSE
2018-05-22 06:01:05 +00:00
2018-08-08 15:13:37 +00:00
.1 ldy #S.FD.REG.IOBUF
lda (pFD),y
2018-07-10 15:33:13 +00:00
beq .8
2018-05-22 06:01:05 +00:00
2018-06-22 06:24:35 +00:00
jsr K.FreeMem
2018-05-22 06:01:05 +00:00
2018-07-10 15:33:13 +00:00
.8 lda #$ff Self Modified
2018-06-22 06:24:35 +00:00
jmp K.FreeMem
2018-07-10 15:33:13 +00:00
.9 rts
*/--------------------------------------
* # FRead
2018-07-24 16:00:24 +00:00
* int fread (hFILE stream, void * ptr, int count );
* Read bytes from file
2018-06-18 08:44:02 +00:00
* **In:**
2018-07-24 16:00:24 +00:00
* `>PUSHWI count`
* `>PUSHW ptr`
* `lda hFILE`
* `>SYSCALL fread`
2018-06-18 08:44:02 +00:00
* **Out:**
* Y,A = Bytes Read
*\--------------------------------------
2018-07-24 16:00:24 +00:00
K.FRead jsr PFT.CheckNodeA
ldx #MLIREAD
bra K.FReadWrite.1
*/--------------------------------------
* # FWrite
* Write bytes to file
2018-06-19 15:08:22 +00:00
* ## C
2018-07-24 16:00:24 +00:00
* `int fwrite (hFILE stream, const void * ptr, int count );`
2018-06-19 15:08:22 +00:00
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-07-24 16:00:24 +00:00
* `>PUSHWI count`
* `>PUSHW ptr`
* `lda hFILE`
* `>SYSCALL fwrite`
2018-08-08 15:13:37 +00:00
* **Out:**
* Y,A = Bytes Written
*\--------------------------------------
2018-07-24 16:00:24 +00:00
K.FWrite jsr PFT.CheckNodeA
ldx #MLIWRITE
2018-07-24 16:00:24 +00:00
K.FReadWrite.1 jsr STDIO.GetRefNum
>PULLW K.MLI.PARAMS+2
2018-07-25 15:26:14 +00:00
>PULLW K.MLI.PARAMS+4
lda #4 Param Count = 4 for MLIREAD & MLIWRITE
jsr GP.MLICall
bcs .9
>LDYA K.MLI.PARAMS+6
.9 rts
*/--------------------------------------
2018-06-22 06:24:35 +00:00
* # FFlush
2018-07-25 15:26:14 +00:00
* ## C
* int fflush(hFILE stream);
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
* A = hFILE
*\--------------------------------------
2018-06-22 06:24:35 +00:00
K.FFlush jsr PFT.CheckNodeA
jsr STDIO.GetRefNum
>MLICALL MLIFLUSH
rts
*/-------------------------------------
* # FSeek
* Set the file-position indicator for hFILE
2018-07-25 15:26:14 +00:00
* ## C
2018-08-08 15:13:37 +00:00
* `int fseek(hFILE stream, long offset, short int whence);`
2018-07-25 15:26:14 +00:00
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-08-08 15:13:37 +00:00
* `>PUSHBI whence`
* `>PUSHL offset`
* `lda stream`
* `>SYSCALL fseek`
*\-------------------------------------
2018-08-08 15:13:37 +00:00
K.FSeek jsr PFT.CheckNodeA
jsr STDIO.GetRefNum
>PULLA FROM
tax
2018-08-08 15:13:37 +00:00
>PULLW ZPPtr1 offset LW
>PULLW ZPPtr2 offset HW
cpx #SYS.FSeek.END+1
bcs .98
2018-05-22 06:01:05 +00:00
jmp (.1,x)
2018-05-22 06:01:05 +00:00
.1 .DA .10
.DA .20
.DA .30
* K.FSeek.SET
.10 stz K.MLI.PARAMS+2
stz K.MLI.PARAMS+3
stz K.MLI.PARAMS+4
2018-05-22 06:01:05 +00:00
bra .8
* K.FSeek.CUR
.20 >MLICALL MLIGETMARK
bcc .8
rts
* K.FSeek.END
.30 >MLICALL MLIGETEOF
bcs .9
.8 ldy #0
ldx #3 3 bytes, 24 bits!!!
clc
.81 lda K.MLI.PARAMS+2,y
2018-08-08 15:13:37 +00:00
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 #K.E.SYN
.HS 2C bit abs
.99 lda #K.E.FTB
sec
rts
*/--------------------------------------
2018-06-22 06:24:35 +00:00
* # FEOF
* Test the end-of-file indicator for hFILE
2018-06-14 15:31:36 +00:00
* **In:**
* A = hFILE
2018-06-14 15:31:36 +00:00
* **Out:**
* CC :
* A=0 EOF
* A !=0 NOT EOF
* CS :
*\--------------------------------------
2018-06-22 06:24:35 +00:00
K.FEOF jsr PFT.CheckNodeA
jsr STDIO.GetRefNum
>MLICALL MLIGETMARK
bcs .9
ldy #2
.1 lda K.MLI.PARAMS+2,y
2018-06-22 06:24:35 +00:00
sta K.FEOF.MARK,y
dey
bpl .1
>MLICALL MLIGETEOF
bcs .9
ldy #2
.2 lda K.MLI.PARAMS+2,y
2018-06-22 06:24:35 +00:00
eor K.FEOF.MARK,y
bne .8
dey
bpl .2
.8 clc
.9 rts
2018-06-22 06:24:35 +00:00
K.FEOF.MARK .BS 3
*/--------------------------------------
* # FTell
* Return the current value of the file-position indicator
2018-07-25 15:26:14 +00:00
* ## C
* `long ftell(hFILE stream);`
* ## ASM
2018-06-14 15:31:36 +00:00
* **In:**
2018-08-08 15:13:37 +00:00
* `lda stream`
* `>SYSCALL ftell`
2018-06-14 15:31:36 +00:00
* **Out:**
2018-08-08 15:13:37 +00:00
* On stack (long)
*\--------------------------------------
2018-08-08 15:13:37 +00:00
K.FTell jsr PFT.CheckNodeA
jsr STDIO.GetRefNum
>MLICALL MLIGETMARK
bcs .9
lda #0
2018-08-08 15:13:37 +00:00
>PUSHA
ldy #2
.1 lda K.MLI.PARAMS+2,y
2018-08-08 15:13:37 +00:00
>PUSHA
dey
bpl .1
.9 rts
*/--------------------------------------
2018-06-22 06:24:35 +00:00
* # Remove
*\--------------------------------------
2018-06-22 06:24:35 +00:00
K.Remove jsr PFT.CheckPathYA
jsr STDIO.SetMLIPathYA
>MLICALL MLIDESTROY
rts
*/--------------------------------------
* # Rename
* Rename a file
2018-08-08 15:13:37 +00:00
* ## C
* `int rename(const char *oldpath, const char *newpath);`
* ## ASM
2018-06-18 08:44:02 +00:00
* **In:**
2018-08-08 15:13:37 +00:00
* `>PUSHW newpath`
* `>LDYA oldpath`
* `>SYSCALL rename`
2018-06-18 08:44:02 +00:00
* **Out:**
*\--------------------------------------
2018-08-08 15:13:37 +00:00
K.Rename jsr PFT.CheckPathYA
jsr STDIO.SetMLIPathYA
>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
*--------------------------------------
STDIO.SetMLIPathYA
>STYA .1+1
2018-09-05 15:22:46 +00:00
ldx #0
2018-09-05 15:22:46 +00:00
.1 lda $ffff,x Self Modified
beq .8
2018-09-05 15:22:46 +00:00
inx
sta K.MLI.PATH,x
cpx #MLI.MAXPATH
bne .1
2018-09-05 15:22:46 +00:00
.8 stx K.MLI.PATH
inx
stz K.MLI.PATH,x Make ending 0 for /dev/xxx path
>LDYAI K.MLI.PATH
>STYA K.MLI.PARAMS+1
rts
*--------------------------------------
2018-05-22 06:01:05 +00:00
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
2018-07-10 15:33:13 +00:00
ldy #S.FD.REG.IOBUF
2018-08-08 15:13:37 +00:00
sta (pFD),y
.9 rts
*--------------------------------------
2018-06-21 15:12:10 +00:00
STDIO.GetRefNum jsr K.GetMemPtr
2018-08-08 15:13:37 +00:00
>STYA pFD
2018-07-10 15:33:13 +00:00
ldy #S.FD.REG.REF
2018-08-08 15:13:37 +00:00
lda (pFD),y
sta K.MLI.PARAMS+1
rts
*--------------------------------------
STDIO.IOERR lda #MLI.E.IO
sec
rts
*--------------------------------------
MAN
SAVE /A2OSX.SRC/SYS/KERNEL.S.STDIO
LOAD /A2OSX.SRC/SYS/KERNEL.S
ASM