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 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 ldy #1 lda (pStack),y sta ZPPtr2+1 s iny lda (pStack),y n * clc sbc #1 eor #$ff sta ZPPtr1 !(n-2) iny lda (pStack),y n sbc #0 eor #$ff sta ZPPtr1+1 !(n-2) >PUSHWI 1 >PUSHWI K.IOBuf jsr IO.READ.I bcs .7 lda K.IOBuf cmp #C.LF Discard any leading LF beq .3 .2 lda K.IOBuf cmp #C.CR beq .8 jsr MEM.PutCharPtr2 inc ZPPtr1 bne .3 inc ZPPtr1+1 beq .8 Buffer full .3 >PUSHWI 1 >PUSHWI K.IOBuf jsr IO.READ.I bcc .2 another char... cmp #MLI.E.EOF beq .8 tay bpl .9 I/O error lda ZPPtr2 sta (pStack) s lda ZPPtr2+1 ldy #1 sta (pStack),y s lda ZPPtr1 eor #$ff * sec adc #1 iny sta (pStack),y !(n+2) lda ZPPtr1+1 eor #$ff adc #0 iny sta (pStack),y !(n+2) lda #0 BLOCKING sec rts .7 tay bpl .9 inc FF rts BLOCKING .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