home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_01 / libcf / format.asm < prev    next >
Encoding:
Assembly Source File  |  1994-03-27  |  5.3 KB  |  211 lines

  1. *
  2. * Format to "printf" output: A=Output Function, I = Argument List
  3. *
  4. format    PUSHA            Save output function pointer
  5.     PUSHI            Save argument pointer
  6.     ALLOC    10        Save  flag variable
  7. * Local variable & argument offsets
  8. ?1    EQU    12        Pointer to output function
  9. ?2    EQU    10        Pointer to argument list
  10. ?3    EQU    4        Buffer for number conversions (6 bytes)
  11. ?4    EQU    2        Temporary locations
  12. ?5    EQU    1        Character count
  13. ?6    EQU    0        Formatting controls
  14. *
  15.     LDI    ?2,S        Get arg pointer
  16.     LDI    I        Get format string
  17. ?7    LDB    I        Get character from string
  18.     SJZ    ?8        Exit if end
  19.     CMPB    #'%'        Format character
  20.     SJNZ    ?10        Yes, handle it
  21.     LDB    I        Get char back
  22.     LEAI    1,I        Advance pointer
  23.     PUSHI            Save Index
  24.     PUSHA            Pass character
  25.     LD    4+?1,S        Get output function
  26.     CALL    ?9        Output the character
  27.     LD    S+        Clean stack
  28.     LDI    S+        Get Index back
  29.     SJMP    ?7        And proceed
  30. ?8    FREE    14        Release stack
  31.     RET
  32. * Call output function in A
  33. ?9    IJMP            Call function
  34. * Format character located
  35. ?10    LEAI    1,I        Skip to next
  36.     CLR            Begin with zero
  37.     ST    ?4,S        Save for later
  38. * Check for leading '-' = Left justify
  39.     STB    ?6,S        Init. flag
  40.     STB    ?5,S        Init. count
  41.     LDB    I        Get char
  42.     CMPB    #'-'        Minus?
  43.     SJZ    ?11        No, try next
  44.     LEAI    1,I        Advance pointer
  45.     LDB    #%10000000    Set justify flag
  46.     STB    ?6,S        Resave
  47. * Check for leading '0' = Zero fill
  48. ?11    LDB    I        Get char back
  49.     CMPB    #'0'        Zero fill?
  50.     SJZ    ?12        No, try next
  51.     LEAI    1,I        Advance
  52.     LDB    ?6,S        Get value
  53.     ORB    #%01000000    Set zero fill flag
  54.     STB    ?6,S        Resave
  55. * Get field width
  56. ?12    LDB    I        Get character
  57.     SUBB    #'0'        Convert to binary
  58.     PUSHA            Save
  59.     CMPB    #10        In range?
  60.     ULT            Must be less than
  61.     SJZ    ?13        Nope
  62.     LEAI    1,I        Skip digit
  63.     LD    2+?4,S        Get old value
  64.     MULB    #10        x10
  65.     ADD    S+        Include new
  66.     ST    ?4,S        Resave
  67.     SJMP    ?12        Do them all
  68. ?13    LD    S+        Clear stack
  69.     LD    ?4,S        Get value
  70.     ORB    ?6,S        Include previous flags
  71.     STB    ?6,S        Resave
  72. * Lookup character & dispatch handler
  73.     PUSHI            Save format pointer
  74.     LD    2+?2,S        Get argptr
  75.     DEC            Backup
  76.     DEC            Backup
  77.     ST    2+?2,S        Resave
  78.     TAI            Address
  79.     LD    I        Get value
  80.     ST    2+?4,S        Resave
  81.     LDB    [S]        Get next character
  82.     LEAI    ?14        Point to table
  83.     SWITCH            Lookup & execute
  84. ?14    FDB    ?15,'o'        Octal number
  85.     FDB    ?16,'d'        Decimal number
  86.     FDB    ?17,'u'        Unsigned number
  87.     FDB    ?18,'x'        Hexidecimal number
  88.     FDB    ?26,'c'        Character output
  89.     FDB    ?28,'s'        String output
  90.     FDB    0,?27        Ignore it
  91. * '%o' - Octal number
  92. ?15    LDB    #8        Base 8
  93.     SJMP    ?19        Do number
  94. * '%d' - signed Decimal number
  95. ?16    LD    2+?4,S        Get value
  96.     AND    #$8000        Negatve?
  97.     SJZ    ?17        Nothing special
  98.     LDB    #'-'        Minus size
  99.     PUSHA            Pass to function
  100.     LD    4+?1,S        Get output function
  101.     CALL    ?9        Call function
  102.     LD    S+        Clean stack
  103.     LD    2+?4,S        Get value
  104.     NEG            Negate
  105.     ST    2+?4,S        And prcoeed
  106.     LDB    2+?6,S        Get length
  107.     ANDB    #%001111111    Free format?
  108.     SJZ    ?17        Yes, ignore
  109.     LDB    2+?6,S        Get value back
  110.     DEC            Adjust for '-'
  111.     STB    2+?6,S        Resave
  112. * '%u' - Unsigned decimal number
  113. ?17    LDB    #10        Base 10 output
  114.     SJMP    ?19        Do number
  115. * '%x' - heXidecimal number
  116. ?18    LDB    #16        Base 16 output
  117. * Output a number in the specified number base
  118. ?19    STB    2+?3,S        Save number base
  119.     LEAI    6+2+?3,S    Point to END of buffer
  120. ?20    TIA            Get index
  121.     DEC            Backup
  122.     TAI            Set index
  123.     LDB    2+?5,S        Get count
  124.     INC            Advance
  125.     STB    2+?5,S        Resave
  126.     LD    2+?4,S        Get value
  127.     DIVB    2+?3,S        Divide by 10
  128.     PUSHA            Save quotient
  129.     ALT            Get remainder
  130.     ADDB    #'0'        Convert to ASCII
  131.     STB    I        Write to stack
  132.     CMPB    #'9'        Is it HEX?
  133.     UGT            Complete test
  134.     SJZ    ?21        Yes it is
  135.     LDB    I        Get char back
  136.     ADDB    #7        Adjust
  137.     STB    I        Resave char
  138. ?21    LD    S+        Get quotient
  139.     ST    2+?4,S        Save new value
  140.     SJNZ    ?20        Do them all
  141. * At this point, I = pointer, ?5=Length
  142. ?22    LDB    2+?5,S        Get count
  143.     STB    3+?4,S        Set extra count
  144.     LDB    2+?6,S        Get flag
  145.     ANDB    #%10000000    Left justify?
  146.     SJNZ    ?23        Yes, don't fill
  147.     CALL    ?31        Do any pre-output
  148. ?23    LDB    3+?4,S        Get count
  149.     SJZ    ?24        All done, exit
  150.     DEC            Reduce count
  151.     STB    3+?4,S        Resave
  152.     LDB    I        Get character from string
  153.     LEAI    1,I        Advance
  154.     PUSHI            Save it
  155.     PUSHA            Pass character
  156.     LD    6+?1,S        Get output function
  157.     CALL    ?9        Output character
  158.     LD    S+        Clean stack
  159.     LDI    S+        Restore I
  160.     SJMP    ?23        Go again
  161. ?24    LDB    2+?6,S        Get flag
  162.     ANDB    #%10000000    Left justify
  163.     SJZ    ?25        No, skip it
  164.     CALL    ?31        Post justify
  165. ?25    LDI    S+        Restore format string
  166.     LEAI    1,I        Advance pointer
  167.     JMP    ?7        And proceed
  168. * '%c' - output character
  169. ?26    LDB    2+?4,S        Get character
  170. ?27    LEAI    2+?3,S        Point to buffer
  171.     STB    I        Save it
  172.     LDB    #1        Get 1
  173.     STB    2+?5,S
  174.     SJMP    ?22
  175. * '%s' - output string
  176. ?28    LDI    2+?4,S        Get string pointer
  177. ?29    LDB    I        Get character
  178.     SJZ    ?30        End of string
  179.     LEAI    1,I        Skip to next
  180.     LDB    2+?5,S        Get count
  181.     INC            Advance
  182.     STB    2+?5,S        Resave count
  183.     SJMP    ?29        And proceed
  184. ?30    LDI    2+?4,S        Get pointer back
  185.     SJMP    ?22        And output
  186. * Perform pre-output justify
  187. ?31    LDB    4+?6,S        Get flag
  188.     ANDB    #%00111111    Save length only
  189.     SJZ    ?35        No justify
  190.     STB    4+?4,S        Save for later
  191.     PUSHI            Save index
  192. ?32    LDB    6+?5,S        Get count
  193.     CMPB    6+?4,S        Are we over
  194.     UGE            Complete test
  195.     SJNZ    ?34        Yes, exit
  196.     LDB    6+?6,S        Get flag
  197.     ANDB    #%01000000    Zero fill?
  198.     SJZ    ?33        No, use ' '
  199.     LDB    #'0'-' '    Get value
  200. ?33    ADDB    #' '        Convert to char
  201.     PUSHA            Pass character
  202.     LD    8+?1,S        Get output function
  203.     CALL    ?9        Output character
  204.     LD    S+        Clean stack
  205.     LDB    6+?4,S        Get remaining width
  206.     DEC            Reduce
  207.     STB    6+?4,S        Resave
  208.     SJMP    ?32        Do next
  209. ?34    LDI    S+        Restore index
  210. ?35    RET
  211.