home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Washington_1988 / DevCon88.1 / Assembler / debug / printf.asm < prev    next >
Encoding:
Assembly Source File  |  1992-08-27  |  5.4 KB  |  145 lines

  1.  
  2. ;
  3. ; Copyright (c) 1988 Commodore-Amiga, Inc.
  4. ;
  5. ; Executables based on this information may be used in software
  6. ; for Commodore Amiga computers.  All other rights reserved.
  7. ;
  8. ; This information is provided "as is"; no warranties are made.
  9. ; All use is at your own risk, and no liability or responsibility is assumed.
  10. ;
  11.  
  12.         SECTION    _printf,CODE
  13.         XREF    _AbsExecBase,_LVOOpenLibrary,_LVOCloseLibrary
  14.         XREF    _LVOOutput,_LVOWrite
  15.  
  16. ;===========================================================================
  17. ; The actual code of the printf function.  Generates a formatted string with
  18. ; a maximum length of 512 bytes and then calls the appropriate text output
  19. ; function.  Text is output as a whole string to speed up the DOS write
  20. ; function which goes real slow on single character output.  Args passed on
  21. ; the stack as: format,arg1,arg2, ... arg8 and it is up to the caller to
  22. ; clean up the stack space used, this is handled by the printf macro.
  23. ;===========================================================================
  24.         XDEF    _printf
  25. _printf        movem.l    d0-d2/a0-a4/a6,-(sp)    save regs
  26.         movea.l    40(sp),a3        a3 points to string
  27.         lea.l    44(sp),a4        a4 points to args
  28.         lea.l    -256(sp),sp        make room for output string
  29.         movea.l    sp,a2            a2 points to output string
  30.  
  31. ; The main loop, copy characters to the output buffer until a % or \ is
  32. ; encountered in which case interpret the characters following in the same
  33. ; manner as C's printf function and put the results into the output stream
  34. ; instead.  A null byte terminates the output.
  35. _printloop    move.b    (a3)+,d0        get a copy of the byte
  36. _possibleend    move.b    d0,(a2)            move to output string
  37.         beq    _printdone        terminating byte
  38.         cmpi.b    #'\',d0            special character byte ?
  39.         beq.s    _specialchar        yes, go see what it is
  40.         cmpi.b    #'%',d0            number or string byte ?
  41.         beq.s    _introchar        yes, go process that
  42. _bumpptr    addq.l    #1,a2            nothing special, bump ptr...
  43.         bra.s    _printloop        ...and go back for the next
  44.  
  45. ; Found a backslash, replace character after with tab or newline (\t or \n)
  46. _specialchar    move.b    (a3)+,d0        get the next character
  47.         beq.s    _possibleend        that could have been nasty!!
  48.         cmpi.b    #'\',d0            did caller want a backslash
  49.         beq.s    _bumpptr        yes, so leave the other
  50.         cmpi.b    #'t',d0            did user want a tab ?
  51.         bne.s    _checkcr        nope, maybe a newline
  52.         move.b    #9,(a2)+        yes, store tab and bump
  53.         bra.s    _printloop        and go for the next char
  54. _checkcr    cmpi.b    #'n',d0            did user want a newline ?
  55.         bne.s    _printloop        nope, ignore all others
  56.         move.b    #13,(a2)+        yes, store cr and bump
  57.         move.b    #10,(a2)+
  58.         bra.s    _printloop        and go for the next char
  59.  
  60. ; Found a percent sign.  Must be introducing a number, string or character
  61. _introchar    move.b    (a3)+,d0        get the next character
  62.         beq.s    _possibleend        another possible oops!
  63.         cmpi.b    #'%',d0            did caller want a percent?
  64.         beq.s    _bumpptr        yes, so leave the last one
  65.         cmpi.b    #'c',d0            print a character ?
  66.         bne.s    _checkstring        nope!
  67.         move.l    (a4)+,d0        get char from arg stack
  68.         move.b    d0,(a2)+        store it and bump ptr
  69.         bra.s    _printloop        and go for the next char
  70. _checkstring    cmpi.b    #'s',d0            print a string ?
  71.         bne.s    _checknumber        nope!
  72.         movea.l    (a4)+,a0        get ptr from arg stack
  73. 10$        move.b    (a0)+,(a2)+        and copy the string
  74.         bne.s    10$
  75.         subq.l    #1,a2            went 1 byte too far
  76.         bra.s    _printloop        go for the next char
  77.  
  78. ; wasn't a string or character code so it has to be a number code here
  79. _checknumber    moveq.l    #0,d2            flag, short (word) number
  80.         cmpi.b    #'l',d0            long version of a number ?
  81.         bne.s    _whatnumber        no, it was a short
  82.         moveq.l    #1,d2            flag, longword number
  83.         move.b    (a3)+,d0        and get the next letter
  84.         beq.s    _possibleend        yet another nasty spot!
  85. _whatnumber    cmpi.b    #'x',d0            hex character ?
  86.         bne.s    _decnumber        nope, must be a decimal
  87.         move.l    (a4)+,d0        get hex value to print
  88.         movea.l    a2,a0            buffer to store to
  89.         tst.w    d2            see what size
  90.         bne.s    _dolonghex        it's a longword
  91.         bsr    bin2hex16        it's a word
  92.         bra.s    _findend        find where number ends
  93. _dolonghex    bsr    bin2hex32
  94.         bra.s    _findend        find where number ends
  95.  
  96. _decnumber    cmpi.b    #'d',d0            really want a decimal ?
  97.         bne    _printloop        nope, illegal character!
  98.         move.l    (a4)+,d0        get decimal value to print
  99.         movea.l    a2,a0            and buffer to store to
  100.         tst.w    d2            see what size
  101.         bne.s    _dolongdec        it's a longword
  102.         bsr    bin2asc16        it's a word
  103.         bra.s    _findend        see what size
  104. _dolongdec    bsr    bin2asc32
  105.  
  106. ; A number has been stored into the buffer, find the end to update A2 ptr
  107. _findend    tst.b    (a2)+            search for null byte
  108.         bne.s    _findend        not there yet
  109.         subq.l    #1,a2            went one byte too far
  110.         bra    _printloop        go for the next char
  111.  
  112. ; We got to the end of the format string and now have a formatted string on
  113. ; the stack that is terminated by a null byte.  Open the dos library to find
  114. ; the current output stream and write the string out.
  115. _printdone    movea.l    _AbsExecBase,a6        need exec library node
  116.         lea.l    DosName(pc),a1
  117.         moveq.l    #0,d0            don't care what version
  118.         jsr    _LVOOpenLibrary(a6)
  119.         tst.l    d0
  120.         beq.s    _cleanup        didn't get the library
  121.         movea.l    d0,a6
  122.  
  123.         jsr    _LVOOutput(a6)        find output handle
  124.         move.l    d0,d1            where we print to
  125.         move.l    sp,d2            where we print from
  126.         suba.l    sp,a2            find length of string
  127.         move.l    a2,d3
  128.         jsr    _LVOWrite(a6)        and write it out
  129.  
  130.         movea.l    a6,a1
  131.         movea.l    _AbsExecBase,a6        finished with dos lib now
  132.         jsr    _LVOCloseLibrary(a6)
  133.  
  134. _cleanup    lea.l    256(sp),sp        fix up the stack pointer
  135.         movem.l    (sp)+,d0-d2/a0-a4/a6    restore regs
  136.         rts                all done
  137.  
  138.         INCLUDE    "numbers.asm"
  139.  
  140. DosName        DC.B    'dos.library',0
  141.         CNOP    0,2
  142.  
  143.         END
  144.  
  145.