NEW
  AUTO 3,1
*--------------------------------------
HEXBUF			.EQ FAC
K.PrintF.PadL	.EQ FAC+4
K.PrintF.PadC	.EQ FAC+5
BCDBUF			.EQ ARG					5, enough to handle 10 digits (32bits)
HEXBUF.Signed	.EQ ARG.SIGN
*/--------------------------------------
* # 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 IO.Write.I
				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 .99
				tay
				bne .99					0 = BLOCKING

				inc pStack				pop K.IOBuf
				inc pStack
*				sec
.99				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 .9

				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 IO.Write.I
				bcc .9
				tay
				bpl .9					IO Erorr
				
				inc						0 = BLOCKING
				
				rts			
				
.9				>RET 2					pop str	
*/--------------------------------------
* # PrintF (BLOCKING)
* # FPrintF (BLOCKING)
* # SPrintF
* Prints C-Style String
* ## C
* `int printf ( const char * format, ... );`
* `int fprintf ( hFILE stream, const char * format, ... );`
* `int sprintf ( char * str, const char * format, ... );`
* ## ASM
* **In:**
* PrintF : (example is for printing Y,A as integer : format="%I", 2 bytes)  
* `>PUSHYA`		#I
* `>PUSHBI 2`	#bytecount
* `...`
* `>LDYAI format`
* `>SYSCALL printf`
* FPrintF : 
* `>PUSHYA`		#I
* `>PUSHBI 2`	#bytecount
* `...`
* `>PUSHWI format`
* `lda hFILE`
* `>SYSCALL fprintf`
* SPrintF : 
* `>PUSHYA`		#I
* `>PUSHBI 2`	#bytecount
* `...`
* `>PUSHWI format`
* `>LDYAI str`
* `>SYSCALL sprintf`
* ## RETURN VALUE
* CC : success, Y,A = bytes sent
* CS : error, A = code from Output
* Specifiers :
* + %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
* + %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)
* + \t : Print 'TAB' ($09,09)
* + \v : Print 'VT' ($0B,11)
* + \xHH : Print byte with hexadecimal value HH (1 to 2 digits)
* + \\\\ : Print \
* + \\% : Print %
* Modifiers for len and padding : 
* + %d	  : '9'  '12'
* + %2d	  : ' 9' '12'   				
* + %02d  : '09' '12'
* + %11s  : 'ABCDEFGH   '	
* + %011s : 'ABCDEFGH000'
* + %2f	  :	'3.14'
*\--------------------------------------
*				.DUMMY
*				.OR ZPTMP
PrintF.Cnt		.BS 2
PrintF.hFILE	.BS 1
*				.ED
*--------------------------------------
K.PrintF.GetFormat
				lda (pStack)
				sta ZPPtr1
				ldy #1
				lda (pStack),y
				sta ZPPtr1+1
				
				lda pStack
				inc
				inc
				sta pLocal
				
				rts
*--------------------------------------
K.SPrintF		stz PrintF.hFILE
				>STYA pIOBuf			str
				jsr K.PrintF.GetFormat
				bra K.PrintF.1
				
K.FPrintF		sta PrintF.hFILE
				jsr K.PrintF.GetFormat
				bra K.PrintF.0

K.PrintF		>STYA ZPPtr1			format

				lda pStack
				sta pLocal

				ldy #S.PS.hStdOut
				lda	(pPs),y
				sta PrintF.hFILE
	
K.PrintF.0		>LDYAI K.IOBuf
				>STYA pIOBuf
				
K.PrintF.1		stz PrintF.Cnt
				stz PrintF.Cnt+1

				stz PrintF.GetByte+1
	
.1				jsr MEM.GetCharPtr1
				bne .22
				jmp .8					end of format..

.22				cmp #'%'
				bne .10
						
				stz K.PrintF.PadL
				lda #' '
				sta K.PrintF.PadC
				
				ldy #0
				
.2				lda (ZPPtr1),y
				beq .7					end of line... print % and exit
				iny
				
				jsr K.PrintF.CheckTBL1	do we have a %x command?
				bcc .6					yes, jmp to it!
				
				cmp #'0'				...a 0...mmm... padding char?
				bne .4
				
				ldx K.PrintF.PadL		K.PrintF.PadL is not nul, so this 0 is second digit
				bne .5
				
*				lda #'0'
				sta K.PrintF.PadC		no, this is the first 0, so make it K.PrintF.PadC
				bra .2

.4				jsr MEM.IsDigit
				bcs .7					no TBL1, no digit....abort		
				
.5				and #$0F				we have a digit
				ldx K.PrintF.PadL
				bne .51					second digit...
				
				sta K.PrintF.PadL		first digit, store.
				bra .2
				
.51				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
				
				lda (ZPPtr1),y			we have 2 digits, must get a letter, now
				beq .7
				iny
				jsr K.PrintF.CheckTBL1
				bcs .7					abort and print %

.6				jsr MEM.AddYToPtr1		skip all processed chars

				txa
				asl
				tax
				jsr PrintF.ESC
				bcc .1
				bcs .99
				
.7				lda #'%'
				bra .20
*--------------------------------------	
.10				cmp #'\'
				bne .20
				
				jsr MEM.GetCharPtr1
				beq .99
				
				ldx	#PrintFTBL2.Cnt-1
				
.12				cmp PrintFTBL2,x
				beq .19
				dex
				bpl	.12

				cmp #'x'
				bne .1
				
				>LDYA ZPPtr1
				>STYA ZPPtr2

				jsr STDLIB.GetHex
				bcs .99
				
				jsr MEM.AddYToPtr1
				
.14				lda HEXBUF
				bra .20
				
.19				lda	PrintFTBL2.OUT,x

.20				jsr	PrintF.COut
				bcs	.99
				jmp .1
*--------------------------------------				
.99				pha
				lda pLocal
				sec						ByteCnt byte
				adc (pLocal)			... ByteCnt
				sta pStack				CC
				pla

				sec
				rts
*--------------------------------------				
.8				lda PrintF.hFILE
				beq .80					Writing to buffer, append \0
				
				>PUSHW PrintF.Cnt		Writing to File/dev...
				>PUSHWI K.IOBuf

				lda PrintF.hFILE
				jsr K.FWrite
				bcc .81

				tay
				bne .99

				>RET 4					0=BLOCKING
				
.80				ldy PrintF.Cnt			A=0, Writing to buffer, append \0
				sta (pIOBuf),y

.81				lda pLocal
				sec						ByteCnt byte
				adc (pLocal)			... ByteCnt
				sta pStack				CC
				>LDYA PrintF.Cnt
				clc
				rts
*--------------------------------------
K.PrintF.CheckTBL1
				ldx	#PrintFTBL1.Cnt-1
				
.1				cmp PrintFTBL1,x
				beq .8
				dex
				bpl	.1
				sec						no valid letter...
				rts
				
.8				clc
				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.S,PrintF.SS
*--------------------------------------
PrintFTBL1		.AS	"bBdDuefhHiILsS"
PrintFTBL1.Cnt	.EQ *-PrintFTBL1
PrintFTBL2		.AS	"befnrtv\%"
PrintFTBL2.Cnt	.EQ *-PrintFTBL2
PrintFTBL2.OUT	.HS 08.1B.0C.0A.0D.09.0B		\b\e\f\n\r\t\v
				.DA #'\'				\\
				.DA #'%'				\%
*--------------------------------------
PrintF.BB		jsr PrintF.GetByte
				bcs PrintF.BB.RTS
				pha
				jsr PrintF.B
				pla
				bcc PrintF.B.1
PrintF.BB.RTS	rts
*--------------------------------------
PrintF.B		jsr PrintF.GetByte
				bcs PrintF.BB.RTS
				
PrintF.B.1		ldx #8

.1				asl
				tay
				lda #'0'/2
				rol
				jsr PrintF.COut
				bcs .9
				
				tya
				dex
				bne .1
				
.9				rts
*--------------------------------------
PrintF.I		sec						signed short
				.HS 90					BCC
PrintF.D		clc						unsigned short (BYTE)

				ror HEXBUF.Signed
				
				jsr PrintF.GetByte
				bcs PrintF.BB.RTS
				sta HEXBUF
				
				stz HEXBUF+1

				ldx #0					one byte
				
				bra PrintF.DD.1
				
PrintF.II		sec						signed int
				.HS 90					BCC
PrintF.DD		clc						unsigned int (WORD)

				ror HEXBUF.Signed

				jsr PrintF.GetByte
				bcs PrintF.BB.RTS
				sta HEXBUF

				jsr PrintF.GetByte
				bcs PrintF.BB.RTS
				sta HEXBUF+1

				ldx #1					two bytes
								
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)

				ror HEXBUF.Signed

				ldx #$ff
				
.1				jsr PrintF.GetByte
				bcs PrintF.BB.RTS
				inx
				sta HEXBUF,x

				cpx #3
				bne .1
				
*				ldx #3					4 bytes
				
PrintF.U.1		clc
				bit HEXBUF.Signed
				bpl 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 HEXBUF.Signed

				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

				bit HEXBUF.Signed
				bpl .9

				lda #'-'
				jsr PrintF.COut
				bcs .99
				
.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
*--------------------------------------	
* 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 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
								
				ldx #ROM.SETFAC
				jsr GP.ROMCALL
				
				lda PrintF.GetByte+1
				clc
				adc #5
				sta PrintF.GetByte+1

				ldy #3					In order not to trash A2osX.SaveSM,A2osX.SaveSX
				ldx #ROM.FOUT
				jsr GP.ROMCALL
				
				ldy #0
				
.2				lda $102,y
				beq .8
				
				jsr PrintF.COut
				bcs .99
				
				iny
				bne .2
				
.8				clc
				rts
				
.9				sec
.99				rts
*--------------------------------------
PrintF.S		ldy #$ff				CSTR
				.HS 2C					bit abs
PrintF.SS		ldy #$00				PSTR

				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
*--------------------------------------
PrintF.HH		jsr PrintF.GetByte
				bcs PrintF.COut.RTS
				tax						LO byte
				jsr PrintF.H
				bcs PrintF.COut.RTS
				txa
				bra PrintF.H.1
*--------------------------------------
PrintF.H		jsr PrintF.GetByte
				bcs PrintF.COut.RTS
PrintF.H.1		tay
				lsr
				lsr
				lsr
				lsr
				jsr PrintF.COutHex
				bcs PrintF.COut.RTS
				tya
				and #$0F
*--------------------------------------
PrintF.COutHex	ora #$30
				cmp #$3A
				bcc PrintF.COut
				adc #6
*--------------------------------------
PrintF.COut		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
PrintF.COut.RTS	rts		
*--------------------------------------
PrintF.GetByte	lda #$FF				SELF MODIFIED LStack Ptr
				cmp (pLocal)
				beq PrintF.GetByte.9	CS

				phy

				tay
				iny
				lda (pLocal),y
				sty PrintF.GetByte+1

				ply
				
*				clc

PrintF.GetByte.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
* **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 PrintF.GetByte.9

				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				>PUSHWI 1
				>PUSHWI K.IOBuf
				jsr IO.READ.I
				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 MEM.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				>PUSHWI 1
				>PUSHWI K.IOBuf
				jsr IO.READ.I
				bcs .5

				lda K.IOBuf
				cmp #C.CR
				beq .8
				
				jsr MEM.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

				>PUSHWI 1
				>PUSHWI K.IOBuf
				jsr IO.READ.I
				bcc .8
				tay
				bpl K.GetC.RTS			I/O error

				inc						0 = BLOCKING
				rts

.8				lda K.IOBuf

K.GetC.RTS		rts				
*/--------------------------------------
* # SScanF
* Read formatted data from string
* ## C
* `int sscanf ( const char * s, const char * format, ... );`
* ## ASM
* **In:**
* `>PUSHW ptr`
* `...`
* `>PUSHBI bytecount`
* `>PUSHWI format`
* + %i : short int
* + %d : byte
* + %I : int
* + %D : word
* + %L : long int
* + %U : dword
* + %h : HEX byte
* + %H : HEX word
* + %s : string
* TODO : %10s
* `>LDYA s`
* `>SYSCALL sscanf`
* ## RETURN VALUE
* A = Number of arguments filled.
*\--------------------------------------
K.SScanF		jsr MEM.SPtr2PPtr1		ptr2=String to Scan,Ptr1=format

				stz .5+1				reset LStack Ptr
				stz .80+1				rest Arg processed

.1				jsr MEM.GetCharPtr1		End Of format?
				beq .8

				cmp #'%' 				Escape ?
				beq .2

				cmp #' '				Space ?
				beq .12

				cmp (ZPPtr2)			Same char in string?
				bne .9

				inc ZPPtr2
				bne .1
				inc ZPPtr2+1
				bra .1

.12				inc ZPPtr2				Space....
				bne .14
				inc ZPPtr2+1

.14				cmp (ZPPtr2)			another one ?
				beq .12
				bne .1

.2				jsr MEM.GetCharPtr1		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				jsr .8
				lda #MLI.E.EOF
				sec
				rts

.4				jsr .5
				bcs .9					out of Ptr on stack

				bra .1

.8				lda pStack
				sec						ByteCnt byte
				adc (pStack)			... ByteCnt
				sta pStack				CC

.80				lda #$ff				SELF MODIFIED Arg processed
.99				rts
*--------------------------------------
.5				lda #$FF				SELF MODIFIED LStack Ptr
				cmp (pStack)
				beq .99					CS

				tay
				iny
				lda (pStack),y
				sta ZPPtr3

				iny
				lda (pStack),y
				sta ZPPtr3+1			get VAR Ptr
				sty .5+1

				inc .80+1				parsed one more arg!
				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 STDLIB.GetDec
				bra K.SScanF.GetVAL
*--------------------------------------
K.SScanF.HH
K.SScanF.H		lda K.SScanFTBL+1,x		Get VAR size
				pha

				jsr STDLIB.GetHex

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
*--------------------------------------
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 #' '				is it a space ?
				bne .1
.2				lda #0					add \0 to param ptr
				sta (ZPPtr3),y

K.SScanF.Fwd	tya						Y=char count parsed
				clc
				adc ZPPtr2
				sta ZPPtr2
				bcc .8
				clc
				inc ZPPtr2+1
.8				rts
*/--------------------------------------
* # FOpen
* Open a file
* ## C
* `hFILE fopen ( const char * filename, short int flags, short int ftype, int auxtype );`
* **In:**
* ## ASM
* `>PUSHWI auxtype`
* `>PUSHBI ftype`
* `>PUSHBI 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
* 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
* `>LDYAI filename`
* ## RETURN VALUE 
*  CC : A = hFILE
*  CS : A = EC
*\--------------------------------------
K.FOpen			jsr PFT.CheckPathYA
				bcs K.FOpen.RET4

				>PULLB K.Open.FLAGS
				>PULLB K.Open.TYPE
				>PULLW K.Open.AUXTYPE

				jsr IO.Open.I
				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 IO.Close.I
				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

K.FClose.RTS	rts
*/--------------------------------------
* # 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 IO.Read.I
				bcs K.FWrite.9

				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 IO.Write.I
				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				>PULLA					whence
				tax
				>PULLW ZPPtr1			offset LW
				>PULLW ZPPtr2			offset HW
				cpx #SEEK.END+1
				bcs .98

				jmp (.1,x)

.1				.DA .10
				.DA .20
				.DA .30			
* SEEK.SET
.10				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
				ldx #3					3 bytes, 24 bits!!!

				clc

.81				lda K.MLI.PARAMS+2,y
				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 #E.BADARG
				.HS 2C					bit abs
.99				lda #E.FTB
				sec
				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 .9

				jmp IO.EOF

.9				rts
*/--------------------------------------
* # 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 newpath`
* `>LDYA oldpath`
* `>SYSCALL rename`
* ## RETURN VALUE
*\--------------------------------------
K.Rename		jsr PFT.CheckPathYA
				bcs .9

				>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
				
.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.BANK
				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
