home *** CD-ROM | disk | FTP | other *** search
-
- ;
- ; Copyright (c) 1988 Commodore-Amiga, Inc.
- ;
- ; Executables based on this information may be used in software
- ; for Commodore Amiga computers. All other rights reserved.
- ;
- ; This information is provided "as is"; no warranties are made.
- ; All use is at your own risk, and no liability or responsibility is assumed.
- ;
-
- SECTION _printf,CODE
- XREF _AbsExecBase,_LVOOpenLibrary,_LVOCloseLibrary
- XREF _LVOOutput,_LVOWrite
-
- ;===========================================================================
- ; The actual code of the printf function. Generates a formatted string with
- ; a maximum length of 512 bytes and then calls the appropriate text output
- ; function. Text is output as a whole string to speed up the DOS write
- ; function which goes real slow on single character output. Args passed on
- ; the stack as: format,arg1,arg2, ... arg8 and it is up to the caller to
- ; clean up the stack space used, this is handled by the printf macro.
- ;===========================================================================
- XDEF _printf
- _printf movem.l d0-d2/a0-a4/a6,-(sp) save regs
- movea.l 40(sp),a3 a3 points to string
- lea.l 44(sp),a4 a4 points to args
- lea.l -256(sp),sp make room for output string
- movea.l sp,a2 a2 points to output string
-
- ; The main loop, copy characters to the output buffer until a % or \ is
- ; encountered in which case interpret the characters following in the same
- ; manner as C's printf function and put the results into the output stream
- ; instead. A null byte terminates the output.
- _printloop move.b (a3)+,d0 get a copy of the byte
- _possibleend move.b d0,(a2) move to output string
- beq _printdone terminating byte
- cmpi.b #'\',d0 special character byte ?
- beq.s _specialchar yes, go see what it is
- cmpi.b #'%',d0 number or string byte ?
- beq.s _introchar yes, go process that
- _bumpptr addq.l #1,a2 nothing special, bump ptr...
- bra.s _printloop ...and go back for the next
-
- ; Found a backslash, replace character after with tab or newline (\t or \n)
- _specialchar move.b (a3)+,d0 get the next character
- beq.s _possibleend that could have been nasty!!
- cmpi.b #'\',d0 did caller want a backslash
- beq.s _bumpptr yes, so leave the other
- cmpi.b #'t',d0 did user want a tab ?
- bne.s _checkcr nope, maybe a newline
- move.b #9,(a2)+ yes, store tab and bump
- bra.s _printloop and go for the next char
- _checkcr cmpi.b #'n',d0 did user want a newline ?
- bne.s _printloop nope, ignore all others
- move.b #13,(a2)+ yes, store cr and bump
- move.b #10,(a2)+
- bra.s _printloop and go for the next char
-
- ; Found a percent sign. Must be introducing a number, string or character
- _introchar move.b (a3)+,d0 get the next character
- beq.s _possibleend another possible oops!
- cmpi.b #'%',d0 did caller want a percent?
- beq.s _bumpptr yes, so leave the last one
- cmpi.b #'c',d0 print a character ?
- bne.s _checkstring nope!
- move.l (a4)+,d0 get char from arg stack
- move.b d0,(a2)+ store it and bump ptr
- bra.s _printloop and go for the next char
- _checkstring cmpi.b #'s',d0 print a string ?
- bne.s _checknumber nope!
- movea.l (a4)+,a0 get ptr from arg stack
- 10$ move.b (a0)+,(a2)+ and copy the string
- bne.s 10$
- subq.l #1,a2 went 1 byte too far
- bra.s _printloop go for the next char
-
- ; wasn't a string or character code so it has to be a number code here
- _checknumber moveq.l #0,d2 flag, short (word) number
- cmpi.b #'l',d0 long version of a number ?
- bne.s _whatnumber no, it was a short
- moveq.l #1,d2 flag, longword number
- move.b (a3)+,d0 and get the next letter
- beq.s _possibleend yet another nasty spot!
- _whatnumber cmpi.b #'x',d0 hex character ?
- bne.s _decnumber nope, must be a decimal
- move.l (a4)+,d0 get hex value to print
- movea.l a2,a0 buffer to store to
- tst.w d2 see what size
- bne.s _dolonghex it's a longword
- bsr bin2hex16 it's a word
- bra.s _findend find where number ends
- _dolonghex bsr bin2hex32
- bra.s _findend find where number ends
-
- _decnumber cmpi.b #'d',d0 really want a decimal ?
- bne _printloop nope, illegal character!
- move.l (a4)+,d0 get decimal value to print
- movea.l a2,a0 and buffer to store to
- tst.w d2 see what size
- bne.s _dolongdec it's a longword
- bsr bin2asc16 it's a word
- bra.s _findend see what size
- _dolongdec bsr bin2asc32
-
- ; A number has been stored into the buffer, find the end to update A2 ptr
- _findend tst.b (a2)+ search for null byte
- bne.s _findend not there yet
- subq.l #1,a2 went one byte too far
- bra _printloop go for the next char
-
- ; We got to the end of the format string and now have a formatted string on
- ; the stack that is terminated by a null byte. Open the dos library to find
- ; the current output stream and write the string out.
- _printdone movea.l _AbsExecBase,a6 need exec library node
- lea.l DosName(pc),a1
- moveq.l #0,d0 don't care what version
- jsr _LVOOpenLibrary(a6)
- tst.l d0
- beq.s _cleanup didn't get the library
- movea.l d0,a6
-
- jsr _LVOOutput(a6) find output handle
- move.l d0,d1 where we print to
- move.l sp,d2 where we print from
- suba.l sp,a2 find length of string
- move.l a2,d3
- jsr _LVOWrite(a6) and write it out
-
- movea.l a6,a1
- movea.l _AbsExecBase,a6 finished with dos lib now
- jsr _LVOCloseLibrary(a6)
-
- _cleanup lea.l 256(sp),sp fix up the stack pointer
- movem.l (sp)+,d0-d2/a0-a4/a6 restore regs
- rts all done
-
- INCLUDE "numbers.asm"
-
- DosName DC.B 'dos.library',0
- CNOP 0,2
-
- END
-
-