NEW AUTO 3,1 */-------------------------------------- * # fputc (BLOCKING) * Print A (char) to hFILE * ## C * `int fputc ( hFILE stream , short int character );` * ## ASM * **In:** * `>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 * **In:** * `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 );` * **In:** * ## 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 * **In:** * `>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 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:** * `>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 * **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 * `short int getc ( short int stream );` * ## ASM * **In:** * `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 #SYS.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 );` * **In:** * ## ASM * `>PUSHW filename` * `>PUSHB flags` * + O.RDONLY : if R and !exists -> ERROR * + O.WRONLY : if W and !exists -> CREATE * + O.TRUNC : Reset Size To 0 * + O.APPEND : Append * + O.TEXT : Open/Append in Text mode * + O.CREATE : Create if not exists * `>PUSHB ftype` * `>PUSHW auxtype` * TODO: replace flags/ftype/auxtype with mode="w+,t=TYP,x=AUXTYPE" * + r = O_RDONLY * + r+ = O_RDWR * + w = O_WRONLY | O_CREAT | O_TRUNC * + w+ = O_RDWR | O_CREAT | O_TRUNC * + a = O_WRONLY | O_CREAT | O_APPEND * + a+ = O_RDWR | O_CREAT | O_APPEND * + ,t=123 or t=$ff or t=TXT * + ,x=12345 or x=$ffff * ## RETURN VALUE * CC : A = hFILE * CS : A = EC *\-------------------------------------- K.FOpen jsr PFT.CheckPath4 bcs 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 ldx IO.hFILE lda (pFD) bne K.FOpen.8 K.FOpen.REGDIR >LDYAI K.Buf256 >SYSCALL2 StrDup bcs K.FOpen.90 txa ldx IO.hFILE sta hFDs.hName-1,x K.FOpen.8 inc hFDs.oCnt-1,x txa * 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 * **In:** * `lda stream` * `>SYSCALL FClose` * ## RETURN VALUE *\-------------------------------------- K.FClose jsr PFT.CheckNodeA bcs K.FRead.RTS jsr UNISTD.Close ldx IO.hFILE dec hFDs.oCnt-1,x bne .8 lda hFDs.hName-1,x its a DEV, don't clear FD beq .8 stz hFDs.hName-1,x jsr K.FreeMem lda (pFD) tay ldx IO.hFILE lda hFDs-1,x beq .8 stz hFDs-1,x cpy #S.FD.T.DSOCK SOCKS will free FDs beq .8 cpy #S.FD.T.SSOCK beq .8 jmp K.FreeMem .8 clc rts */-------------------------------------- * # FRead (BLOCKING) * Read bytes from file * ## C * `int fread (short int stream, void * ptr, int count );` * ## ASM * **In:** * `>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 * **In:** * `>PUSHB stream` * `>PUSHW ptr` * `>PUSHW count` * `>SYSCALL fwrite` * ## RETURN VALUE * Y,A = Bytes Written *\-------------------------------------- K.FWrite.PFT ldx #SYS.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 * **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( short int stream, long offset, short int whence );` * ## ASM * **In:** * `>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 MLIGETMARK bcc .8 rts * SEEK.END .30 >MLICALL MLIGETEOF bcs .9 .8 ldy #0 clc .81 lda K.MLI.PARAMS+2,y adc ACC32,y sta K.MLI.PARAMS+2,y iny tya 3 bytes, 24 bits!!! eor #3 bne .81 bcs .99 Offset out of range! .82 >MLICALL MLISETMARK bcc .9 cmp #MLI.E.BEYEOF bne .9 >MLICALL MLISETEOF bcc .82 .9 rts .98 lda #E.BADARG .HS 2C bit abs .99 lda #E.FTB * sec K.FSeek.RTS rts */-------------------------------------- * # FEOF * Test the end-of-file indicator for hFILE * ## C * `short int feof( short int stream );` * ## ASM * **In:** * `lda stream` * `>SYSCALL feof` * ## RETURN VALUE * CC : * A = $ff EOF * A = 0 NOT EOF * CS : *\-------------------------------------- K.FEOF jsr PFT.CheckNodeA bcs K.FSeek.RTS 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 * **In:** * `lda stream` * `>SYSCALL ftell` * ## RETURN VALUE * On stack (long) *\-------------------------------------- K.FTell jsr PFT.CheckNodeA bcs .9 >MLICALL MLIGETMARK bcs .9 lda #0 >PUSHA ldy #2 .1 lda K.MLI.PARAMS+2,y >PUSHA dey bpl .1 .9 rts */-------------------------------------- * # Remove * Remove a file or directory * ## C * `int remove ( const char *pathname );` * ## ASM * **In:** * `>LDYA pathname` * `>SYSCALL remove` * ## RETURN VALUE *\-------------------------------------- K.Remove jsr PFT.CheckPathYA bcs .9 >MLICALL MLIDESTROY .9 rts */-------------------------------------- * # Rename * Rename a file * ## C * `int rename ( const char * oldpath, const char * newpath );` * ## ASM * **In:** * `>PUSHW oldpath` * `>PUSHW newpath` * `>SYSCALL rename` * ## RETURN VALUE *\-------------------------------------- K.Rename jsr PFT.CheckPath2 bcs .9 lda (pStack) sta ZPPtr1 ldy #1 lda (pStack),y sta ZPPtr1+1 dey ldy #0 .1 lda (ZPPtr1),y beq .8 iny sta K.Buf256,y cpy #MLI.MAXPATH bne .1 .8 sty K.Buf256 >LDYAI K.Buf256 >STYA K.MLI.PARAMS+3 >MLICALL MLIRENAME .9 >RET 4 */-------------------------------------- * # 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 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 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.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 .11 bcc .1 bra .99 .7 lda #'%' bra .20 *-------------------------------------- .10 cmp #'\' bne .20 jsr SHARED.GetCP2 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.AddY2P2 .14 lda ACC32 bra .20 .19 lda PrintFTBL2.OUT,x .20 jsr PrintF.PutC bcc .11 *-------------------------------------- .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 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.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 * **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 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