NEW
  AUTO 3,1
*/--------------------------------------
* # 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
* **In:**
* 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
* + \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+5				3 Bytes
PrintF.Cnt		.BS 2
PrintF.hFILE	.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

				clc
				jsr STDIO.GetFormat

				bra K.PrintF.1
*--------------------------------------
K.FPrintf		clc
				jsr STDIO.GetFormat

				iny
				lda (pStack),y			hFILE
				sta PrintF.hFILE

				bra K.PrintF.1
*--------------------------------------
K.SPrintf		stz PrintF.hFILE
				
				sec						Format & buffer
				jsr STDIO.GetFormat
*--------------------------------------
K.PrintF.1		sty STDIO.Exit.Cnt+1	Total bytes to POP

				stz PrintF.Cnt
				stz PrintF.Cnt+1

.1				jsr SHARED.GetCharPtr2
				bne .22

				jmp .8					end of format..

.22				cmp #'%'
				bne .10
				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.NextCharPtr2	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.AddYToPtr2		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.NextCharPtr2
				txa						yes, jmp to it!
				asl
				tax
				jsr PrintF.ESC
.11				bcc .1
				bra .99
.7				lda #'%'
				bra .20
*--------------------------------------	
.10				cmp #'\'
				bne .20

				jsr SHARED.GetCharPtr2
				beq .99
				ldx	#PrintFTBL2.Cnt-1
.12				cmp PrintFTBL2,x
				beq .19
				dex
				bpl	.12

				cmp #'x'				\xHH
				bne .1

				jsr MATH.Hex2ACC32
				bcs .99
				jsr SHARED.AddYToPtr2
.14				lda ACC32
				bra .20
.19				lda	PrintFTBL2.OUT,x

.20				jsr	PrintF.COut
				bcc .11
*--------------------------------------
.99				jmp STDIO.Exit
*--------------------------------------
.8				ldx PrintF.hFILE
				beq .80					Writing to buffer, append \0
				>PUSHW PrintF.Cnt		Writing to File/dev...
				>PUSHWI K.IOBuf

				txa
				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				>LDYA PrintF.Cnt
*				clc
				jmp STDIO.Exit
*--------------------------------------
PrintFTBL1		.AS	"bdDuefhHiILsS"
PrintFTBL1.Cnt	.EQ *-PrintFTBL1
PrintFTBL2		.AS	"abefnrtv\%"
PrintFTBL2.Cnt	.EQ *-PrintFTBL2
PrintFTBL2.OUT	.HS 07.08.1B.0C.0A.0D.09.0B		\a\b\e\f\n\r\t\v
				.DA #'\'				\\
				.DA #'%'				\%
*--------------------------------------
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.GetStackByte
				bcs PrintF.B.RTS
				ldy #8

.1				asl
				pha
				lda #'0'/2
				rol
				jsr PrintF.COut
				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		ror ACC32.Sign
				jsr MATH.ACC32ZERO
.1				jsr STDIO.GetStackByte
				bcs PrintF.B.RTS

				sta ACC32-1,y
				dey
				bne .1

				ldx K.PrintF.PadL
				ldy K.PrintF.PadC
				rol ACC32.Sign
				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 #A2osX.NumStrBuf+1	FOUT.1 will do a DEY
				ldx #FPU.FOUT
				jsr GP.ROMCALL
	
PrintF.StrNum	ldy #0
.2				lda A2osX.NumStrBuf,y
				beq .8
				iny
				jsr PrintF.COut
				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.GetStackByte
				bcs .9
				sta ZPPtr1+1
				jsr STDIO.GetStackByte
				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.COut
				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.COut
				bcs .9
				iny
				bne .3

*				clc
.9				rts
*--------------------------------------
PrintF.HH		jsr STDIO.GetStackByte
				bcs PrintF.COut.RTS
				pha						LO byte
				jsr STDIO.GetStackByte
				plx
				bcs PrintF.COut.RTS
				pha
				txa
				jsr PrintF.H.1
				plx
				bcs PrintF.COut.RTS
				txa
				bra PrintF.H.1
*--------------------------------------
PrintF.H		jsr STDIO.GetStackByte
				bcs PrintF.COut.RTS
PrintF.H.1		jsr MATH.AToHexAX
				jsr PrintF.COut
				bcs PrintF.COut.RTS
				txa
				jmp PrintF.COut
*--------------------------------------
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		
*/--------------------------------------
* # 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
* **In:**
* 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
				
				clc
				jsr STDIO.GetFormat

				bra K.SScanF.1
*--------------------------------------
K.FScanF		clc
				jsr STDIO.GetFormat

				iny
				lda (pStack),y			hFILE
				sta PrintF.hFILE

				bra K.SScanF.1
*--------------------------------------
K.SScanF		stz PrintF.hFILE

				sec						Format & buffer
				jsr STDIO.GetFormat
*--------------------------------------
K.SScanF.1		sty STDIO.Exit.Cnt+1	Total bytes to POP
				
.1				jsr SHARED.GetCharPtr2		End Of format?
				beq .8

				cmp #'%' 				Escape ?
				beq .2

				cmp #C.SPACE			Space ?
				beq .12

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

				inc ZPPtr1
				bne .1
				inc ZPPtr1+1
				bra .1

.12				inc ZPPtr1
				bne .13
				inc ZPPtr1+1
				
.13				cmp (ZPPtr1)			another one ?
				beq .12
				
				bne .1

.2				jsr SHARED.GetCharPtr2	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.GetStackByte
				bcs .9
				sta ZPPtr3
				jsr STDIO.GetStackByte
				bcs .9
				sta ZPPtr3+1
				
				jsr .5
				bcs .9					out of Ptr on stack

				inc .8+1				parsed one more arg!
				bra .1

.8				lda #$ff				SELF MODIFIED Arg processed
				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.AddYToPtr1	Y=char count parsed

.1				ply						get back VAL size 

.2				lda ACC32-1,y
				dey
				sta (ZPPtr3),y
				bne .2

.9				rts
*--------------------------------------
K.SScanF.S		ldy #$ff

.1				iny
				lda (ZPPtr1),y			Get char in string to scan
				sta (ZPPtr3),y			store in param ptr
				beq K.SScanF.Fwd		end of string to scan ?
				
				cmp (ZPPtr2)			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.AddYToPtr1		Y=char count parsed
*--------------------------------------
STDIO.GetFormat	lda (pStack)			Bytecount
				inc
				tay

				lda (pStack),y			format LO
				sta ZPPtr2
				iny
				lda (pStack),y			format HI
				sta ZPPtr2+1

				bcc .1
				
				iny
				lda (pStack),y			str LO
				sta pIOBuf
				iny
				lda (pStack),y			str HI
				sta pIOBuf+1
				rts
				
.1				lda #K.IOBuf
				sta pIOBuf
				lda /K.IOBuf
				sta pIOBuf+1

				rts
*--------------------------------------
STDIO.GetStackByte	
				lda (pStack)
				beq .9

				phy

				tay
				dec
				sta (pStack)
				lda (pStack),y
				
				ply
				
				clc
				rts

.9				lda #E.STACK
				sec
STDIO.GetStackByte.RTS				
				rts
*--------------------------------------
STDIO.Exit		php
				pha
				lda pStack
				sec						+Bytecount byte
STDIO.Exit.Cnt	adc #$ff				SELF MODIFIED
				sta pStack
				pla
				plp
				rts
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.STDIO2
LOAD USR/SRC/SYS/KERNEL.S
ASM
