home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 303.lha / AssemTools / Include / ffplib.i < prev    next >
Text File  |  1980-12-03  |  10KB  |  455 lines

  1.  
  2. * Include file for Amiga A68k macro assembler *
  3. * created 19.07.89 JM - Supervisor Software *
  4. * for handling Motorola FFP numbers *
  5.  
  6. *T
  7. *T    FFPLIB.I * A68k Include File
  8. *T        Version 1.00
  9. *T          Date 20.07.1989
  10. *T
  11.  
  12. ;  "atof, ftoa" created -> v0.10 19.07.89
  13. ;  "adjust" created -> v1.00 20.07.89
  14.  
  15.  
  16.  
  17. *B
  18.  
  19. ;  atof        (convert ASCII to FFP)
  20. ;  in:        a0=*string;
  21. ;  call:    ffplib    atof;
  22. ;  out:        d0=FFP_number;
  23. ;        a0=*last_digit+1;
  24. ;        p.c=error;
  25. ;        p.v=overflow;
  26. ;  notes:    /uses a huge table; still needs some/
  27. ;        /cleanup/
  28.  
  29. ;  ftoa        (convert FFP to ASCII)
  30. ;  in:        a0=*buffer;
  31. ;  call:    ffplib    ftoa;
  32. ;  out:        a0=*NULL;
  33. ;        d0=???;
  34. ;  notes:    /uses a huge table; still needs some/
  35. ;        /cleanup/
  36. ;        /output format: "S.abcdefghESij"/
  37. ;        /where S is "+" or "-" and a...j/
  38. ;        /are decimal digits 0...9/
  39. ;        /example: "-.12340000E+12"
  40.  
  41. ;  adjust    (adjust an ASCII FFP number)
  42. ;  in:        a0=*string;
  43. ;  call:    ffplib    adjust;
  44. ;  out:        a0=*NULL;
  45. ;  notes:    /converts a FFP ASCII number into more/
  46. ;        /readable form/
  47. ;        /accepts input from ffplib ftoa/
  48. ;        /Output format:/
  49. ;        /number            format/
  50. ;        / |X| < 1E-6        Sa.bcdefghE-ij/
  51. ;        /-1E8 < X <  1E8    Sa[b[c]d]]][.e[f[g[h]]]]/
  52. ;        / 1E8 < X         a.bcdefghE+ij/
  53. ;        /       X < -1E8    -a.bcdefghE+ij/
  54.  
  55. *E
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63. _FFPFftoa    set    0
  64. _FFPFatof    set    0
  65.  
  66.  
  67. ffplib        macro    name
  68.         ifnc    '\1',''
  69. _FFPF\1    set    1
  70.         bsr    _FFP\1
  71.         mexit
  72.         endc
  73.  
  74.         ifne    _FFPFftoa!_FFPFatof
  75.     dc.b    $00,$40,$8a,$c7,$23,$05,$00,$3c,$de,$0b,$6b,$3a
  76.     dc.b    $00,$39,$b1,$a2,$bc,$2f,$00,$36,$8e,$1b,$c9,$bf
  77.     dc.b    $00,$32,$e3,$5f,$a9,$32,$00,$2f,$b5,$e6,$20,$f5
  78.     dc.b    $00,$2c,$91,$84,$e7,$2a,$00,$28,$e8,$d4,$a5,$10
  79.     dc.b    $00,$25,$ba,$43,$b7,$40,$00,$22,$95,$02,$f9,$00
  80.     dc.b    $00,$1e,$ee,$6b,$28,$00,$00,$1b,$be,$bc,$20,$00
  81.     dc.b    $00,$18,$98,$96,$80,$00,$00,$14,$f4,$24,$00,$00
  82.     dc.b    $00,$11,$c3,$50,$00,$00,$00,$0e,$9c,$40,$00,$00
  83.     dc.b    $00,$0a,$fa,$00,$00,$00,$00,$07,$c8,$00,$00,$00
  84.     dc.b    $00,$04,$a0,$00,$00,$00
  85. FFP10TBL
  86.     dc.b    $00,$01,$80,$00,$00,$00,$ff,$fd,$cc,$cc,$cc,$cd
  87.     dc.b    $ff,$fa,$a3,$d7,$0a,$3d,$ff,$f7,$83,$12,$6e,$98
  88.     dc.b    $ff,$f3,$d1,$b7,$17,$59,$ff,$f0,$a7,$c5,$ac,$47
  89.     dc.b    $ff,$ed,$86,$37,$bd,$06,$ff,$e9,$d6,$bf,$94,$d6
  90.     dc.b    $ff,$e6,$ab,$cc,$77,$12,$ff,$e3,$89,$70,$5f,$41
  91.     dc.b    $ff,$df,$db,$e6,$fe,$cf,$ff,$dc,$af,$eb,$ff,$0c
  92.     dc.b    $ff,$d9,$8c,$bc,$cc,$09,$ff,$d5,$e1,$2e,$13,$42
  93.     dc.b    $ff,$d2,$b4,$24,$dc,$35,$ff,$cf,$90,$1d,$7c,$f7
  94.     dc.b    $ff,$cb,$e6,$95,$94,$bf,$ff,$c8,$b8,$77,$aa,$32
  95.     dc.b    $ff,$c5,$93,$92,$ee,$8f,$ff,$c1,$ec,$1e,$4a,$7e
  96.     dc.b    $ff,$be,$bc,$e5,$08,$65,$ff,$bb,$97,$1d,$a0,$50
  97.     dc.b    $ff,$b7,$f1,$c9,$00,$81,$ff,$b4,$c1,$6d,$9a,$01
  98.     dc.b    $ff,$b1,$9a,$be,$14,$cd,$ff,$ad,$f7,$96,$87,$ae
  99.     dc.b    $ff,$aa,$c6,$12,$06,$25,$ff,$a7,$9e,$74,$d1,$b8
  100.     dc.b    $ff,$a3,$fd,$87,$b5,$f3
  101.  
  102.     endc
  103.  
  104.  
  105.  
  106.     ifne    _FFPFatof
  107.  
  108. _FFPatof    push    d1-d5
  109.         bsr.s    FPAATOF
  110.         pull    d1-d5
  111.         rts
  112.  
  113. FPAATOF    moveq    #0,d0        clear result
  114.     moveq    #0,d1        clear exponent
  115.     bsr    FPANXT        .eq if num, .c if error, .ne if sign; d5=num
  116.     beq.s    FPANMB        -> jump if a decimal digit
  117.     bcs.s    FPANOS        handle error somehow
  118.     cmpi.b    #'-',d5        (comes here if char was plus or minus)
  119.     seq    d1
  120.     swap    d1
  121.     bsr    FPANXT
  122.     beq.s    FPANMB
  123. FPANOS    cmpi.b    #'.',d5        decimal point?
  124.     bne.s    FPABAD
  125.     bsr    FPANXT
  126.     beq.s    FPADOF
  127. FPABAD    subq.l    #1,a0        error, return .C=1
  128.     setc
  129.     rts     
  130.  
  131. FPANXD    bsr    FPANXT        get next byte of string
  132.     bne.s    FPANOD        -> jump if not a digit
  133. FPANMB    bsr.s    FPAX10        *10, add curr. dig. in d5, result in d0
  134.     bcc.s    FPANXD        -> loop if no error (gets next byte)
  135.  
  136. FPAMOV    addq.w    #1,d1        skip here the least significant digits
  137.     bsr.s    FPANXT        and do not store them.
  138.     beq.s    FPAMOV        end of loop if not a digit
  139.     cmpi.b    #'.',d5        is it a decimal point?
  140.     bne.s    FPATSE        no -> check if it's an exponent
  141. FPASRD    bsr.s    FPANXT        get next digit (skips digits after dp)
  142.     beq.s    FPASRD        and loop until not a digit
  143. FPATSE    cmpi.b    #'E',d5        is it "E"?
  144.     beq.s    1$
  145.     cmpi.b    #'e',d5
  146.     bne.s    FPACNV        no -> exit to FFPDBF
  147. 1$    bsr.s    FPANXT        get digit of exponent
  148.     beq.s    FPANTE        -> jump if a digit
  149.     bcs.s    FPABAD        exit immediately with C=1 if error
  150.     rol.l    #8,d1
  151.     cmpi.b    #'-',d5        "-" negative exponent?
  152.     seq    d1        if yes, set a flag
  153.     ror.l    #8,d1
  154.     bsr.s    FPANXT        get first digit of exponent
  155.     bne.s    FPABAD        if not a digit, exit immediately
  156. FPANTE    move.w    d5,d4        save current digit
  157. FPANXE    bsr.s    FPANXT        get next
  158.     bne.s    FPAFNE        jump if not a digit
  159.     mulu.w    #10,d4        multiply old digit by 10
  160.     cmpi.w    #$07d0,d4    check for overflow
  161.     bhi.s    FPABAD        over/underflow -> exit immediately
  162.     add.w    d5,d4        add new digit
  163.     bra.s    FPANXE        continue loop until exponent taken
  164.  
  165. FPAFNE    tst.l    d1        end of exponent, test negative flag
  166.     bpl.s    FPAADP
  167.     neg.w    d4        negate exponent if necessary
  168. FPAADP    add.w    d4,d1        ... well, sets the bias, I think...
  169. FPACNV    subq.l    #1,a0
  170.     bra.s    FFPDBF        exit
  171.  
  172. FPANOD    cmpi.b    #'.',d5        comes here when the first numeric ends, "."?
  173.     bne.s    FPATSE        -> no, check for exponent
  174. FPADPN    bsr.s    FPANXT
  175.     bne.s    FPATSE        -> exit if all digits eaten
  176. FPADOF    bsr.s    FPAX10        get next digit (after dp)
  177.     bcs.s    FPASRD
  178.     subq.w    #1,d1        subtract one from exponent
  179.     bra.s    FPADPN
  180.  
  181. FPAX10    move.l    d0,d3        put result into temporary register
  182.     lsl.l    #1,d3        d3 temp. working register
  183.     bcs.s    FPAXRT
  184.     lsl.l    #1,d3
  185.     bcs.s    FPAXRT
  186.     lsl.l    #1,d3
  187.     bcs.s    FPAXRT
  188.     add.l    d0,d3
  189.     bcs.s    FPAXRT
  190.     add.l    d0,d3
  191.     bcs.s    FPAXRT
  192.     add.l    d5,d3        add current digit
  193.     bcs.s    FPAXRT
  194.     move.l    d3,d0        give result in d0
  195. FPAXRT    rts     
  196.  
  197. FPANXT    moveq    #0,d5        Ascii to FP NeXT char
  198.     move.b    (a0)+,d5
  199.     cmpi.b    #'+',d5        plus?
  200.     beq.s    FPASGN        yes -> handle sign
  201.     cmpi.b    #'-',d5        minus?
  202.     beq.s    FPASGN        yes -> handle sign
  203.     cmpi.b    #'0',d5
  204.     bcs.s    FPAOTR        <0 -> out of range
  205.     cmpi.b    #'9',d5
  206.     bhi.s    FPAOTR        >9 -> out of range
  207.     andi.b    #$0f,d5        make it a number
  208.     move    #$0004,ccr    Z=1
  209.     rts     
  210.  
  211. FPASGN    move    #0,ccr        it was a sign        Z=C=0
  212.     rts     
  213.  
  214. FPAOTR    move    #1,ccr        error: out of range    C=1
  215.     rts     
  216.  
  217.  
  218. FFPDBF    moveq    #$20,d5        I don't comprehend this...
  219.     tst.l    d0
  220.     beq    FPDRTN        if result=0, exit
  221.     bmi.s    FPDINM
  222.     moveq    #$1f,d5        get $1f if result is positive
  223. FPDNMI    add.l    d0,d0        aha, it adjusts the number to the correct
  224.     dbmi    d5,FPDNMI    bit position in d0 here!
  225. FPDINM    cmpi.w    #$0012,d1
  226.     bgt.s    FPDOVF        -> overflow, exit with V=1
  227.     cmpi.w    #-$001c,d1
  228.     blt.s    FPDRT0        -> underflow, returns a zero
  229.     move.w    d1,d4        copy exponent
  230.     neg.w    d4        negate it
  231.     muls    #6,d4        and multiply by 6
  232.     move.l    a0,-(sp)    save sourceptr
  233.     lea    FFP10TBL(pc),a0    get table address
  234.     add.w    0(a0,d4.w),d5    ummm...
  235.     move.w    d5,d1        - " -
  236.     move.l    2(a0,d4.w),d3    hmm...
  237.     movea.l    (sp),a0        restore sourceptr
  238.     move.l    d3,(sp)        save d3
  239.     move.w    d0,d5
  240.     mulu    d3,d5
  241.     clr.w    d5
  242.     swap    d5
  243.     moveq    #0,d4
  244.     swap    d3
  245.     mulu    d0,d3
  246.     add.l    d3,d5
  247.     addx.b    d4,d4
  248.     swap    d0
  249.     move.w    d0,d3
  250.     mulu    2(sp),d3
  251.     add.l    d3,d5
  252.     bcc.s    FPDNOC
  253.     addq.b    #1,d4
  254. FPDNOC    move.w    d4,d5
  255.     swap    d5
  256.     mulu    (sp),d0
  257.     lea    4(sp),sp
  258.     add.l    d5,d0
  259.     bmi.s    FPDNON
  260.     add.l    d0,d0
  261.     subq.w    #1,d1
  262. FPDNON    addi.l    #$00000080,d0
  263.     bcc.s    FPDROK
  264.     roxr.l    #1,d0
  265.     addq.w    #1,d1
  266. FPDROK    moveq    #9,d3
  267.     move.w    d1,d4
  268.     asl.w    d3,d1
  269.     bvs.s    FPDXOV
  270.     eori.w    #-$8000,d1
  271.     lsr.l    d3,d1
  272.     move.b    d1,d0            set exponent to d0
  273.     beq.s    FPDRT0
  274. FPDRTN    rts     
  275.  
  276. FPDRT0    moveq    #0,d0            return a zero
  277.     rts     
  278.  
  279. FPDXOV    tst.w    d4
  280.     bmi.s    FPDRT0
  281. FPDOVF    moveq    #-1,d0            overflow: return V=1
  282.     swap    d1
  283.     roxr.b    #1,d1
  284.     roxr.b    #1,d0
  285.     tst.b    d0
  286.     setv
  287.     rts     
  288.     endc
  289.  
  290.  
  291.  
  292.     ifne    _FFPFftoa
  293.  
  294. _FFPftoa
  295.     push    d1-d5/a1/a2        save registers
  296.     move.l    a0,a2
  297.     tst.b    d0            check if value is zero
  298.     bne.s    FPFNOT0            jump if not zero
  299.     moveq    #$41,d0            $41 represents zero
  300. FPFNOT0    move.b    #'+',(a0)+
  301.     move.b    #'.',(a0)+        store "+."
  302.     move.b    d0,d1
  303.     bpl.s    FPFPLS            jump if positive
  304.     addq.b    #2,(a2)            make "+" a "-"
  305. FPFPLS    add.b    d1,d1
  306.     move.b    #-$80,d0
  307.     eor.b    d0,d1
  308.     ext.w    d1
  309.     asr.w    #1,d1
  310.     moveq    #1,d3
  311.     lea.l    FFP10TBL(pc),a1        get table address
  312.     cmp.w    (a1),d1
  313.     blt.s    FPFMIN
  314.     bgt.s    FPFPLU
  315. FPFEQE    cmp.l    2(a1),d0
  316.     bcc.s    FPFFND
  317. FPFBCK    addq.w    #6,a1
  318.     subq.w    #1,d3
  319.     bra.s    FPFFND
  320.  
  321. FPFPLU    lea.l    -6(a1),a1
  322.     addq.w    #1,d3
  323.     cmp.w    (a1),d1
  324.     bgt.s    FPFPLU
  325.     beq.s    FPFEQE
  326.     bra.s    FPFBCK
  327.  
  328. FPFMIN    lea.l    6(a1),a1
  329.     subq.w    #1,d3
  330.     cmp.w    (a1),d1
  331.     blt.s    FPFMIN
  332.     beq.s    FPFEQE
  333. FPFFND    move.b    #'E',10(a2)    put seed of exponent
  334.     move.b    #'+',11(a2)
  335.     move.b    #'0',12(a2)
  336.     move.b    #'0',13(a2)
  337.     move.w    d3,d2
  338.     bpl.s    FPFPEX
  339.     neg.w    d2
  340.     addq.b    #2,11(a2)    change "+" to "-"
  341. FPFPEX    cmpi.w    #10,d2
  342.     bcs.s    FPFGEN
  343.     addq.b    #1,12(a2)    increment MSD of exponent
  344.     subi.w    #10,d2
  345. FPFGEN    or.b    d2,13(a2)    set LSD of exponent
  346.     moveq    #7,d2
  347.     tst.l    d0
  348.     bpl.s    FPFZRO
  349.     tst.b    5(a1)
  350.     bne.s    FPFNXI
  351. FPFZRO    clr.b    d0
  352. FPFNXI    move.w    d1,d4
  353.     sub.w    (a1)+,d4
  354.     move.l    (a1)+,d5
  355.     lsr.l    d4,d5
  356.     moveq    #9,d4
  357. FPFINC    sub.l    d5,d0
  358.     dbcs    d4,FPFINC
  359.     bcs.s    FPFNIM
  360.     clr.b    d4
  361. FPFNIM    add.l    d5,d0
  362.     subi.b    #9,d4
  363.     neg.b    d4
  364.     ori.b    #'0',d4
  365.     move.b    d4,(a0)+        stores an ASCII byte here! :-)
  366.     dbf    d2,FPFNXI
  367.     move.w    d3,d0
  368.     ext.l    d0
  369.     lea.l    14(a2),a0
  370.     clr.b    (a0)
  371.     pull    d1-d5/a1/a2
  372.     rts     
  373.  
  374.     endc
  375.  
  376.  
  377.  
  378.         ifd    _FFPFadjust
  379.  
  380. _FFPadjust    push    a1/d0-d2
  381.         cmpi.b    #'-',(a0)        value negative?
  382.         beq.s    01$            yes -> jump
  383.         move.b    #' ',(a0)        replc plus with a space
  384. 01$        moveq    #0,d1            clear exponent
  385.         moveq    #0,d0
  386.         move.b    12(a0),d1        MSD
  387.         mulu.w    #10,d1
  388.          move.b    13(a0),d0
  389.         add.w    d0,d1            LSD
  390.         sub.w    #('0'*10+'0'),d1    compensate for ASCII
  391.         move.w    d1,d0
  392.         cmpi.b    #'-',11(a0)        negative exponent?
  393.         bne.s    1$            -> no
  394.         neg.w    d1
  395. 1$        cmp.w    #9,d1            how big is the exponent?
  396.         bge.s    _FFPadj_big        -> go handle big numbers
  397.         tst.w    d1
  398.         bgt.s    _FFPadj_spe        small positive exponent
  399.         cmp.w    #-6,d1
  400.         ble.s    _FFPadj_big        -> go handle small numbers
  401.  
  402.  
  403. _FFPadj_sne    lea.l    10(a0),a1        addr of E
  404.         moveq    #7,d2            # of digits to shift -1
  405.         lea.l    1(a1,d0.w),a0
  406. 1$        move.b    -(a1),1(a1,d0.w)    shift mantissa to the right
  407.         dbf    d2,1$
  408. 4$        move.b    #'0',-1(a1)        put integers (0)
  409.         move.b    #'.',(a1)+        put dp
  410.         subq.w    #1,d0
  411.         bmi.s    _FFPadj_eze
  412. 2$        move.b    #'0',(a1)+        fill with zeros after dp
  413.         dbf    d0,2$
  414. _FFPadj_eze    cmp.b    #'0',-(a0)        blank unnecessary zeros
  415.         beq.s    _FFPadj_eze
  416.         cmp.b    #'.',(a0)        if no decimals, remove dp
  417.         beq.s    1$
  418.         addq.l    #1,a0
  419. 1$        clr.b    (a0)            add null
  420.         pull    a1/d0-d2
  421.         rts
  422.  
  423. _FFPadj_spe    subq.w    #1,d0            small positive exponent
  424.         lea.l    2(a0),a1
  425. 1$        move.b    (a1)+,-2(a1)
  426.         dbf    d0,1$
  427.         move.b    #'.',-1(a1)
  428.         lea    9(a0),a0
  429.         bra.s    _FFPadj_eze        eat zeros
  430.  
  431. _FFPadj_big    move.b    1(a0),d0        swap first digit and dp
  432.         move.b    2(a0),1(a0)
  433.         move.b    d0,2(a0)
  434.         subq.w    #1,d1            decrement exponent by one
  435. _FFPadj_pet    tst.w    d1            test sign of exponent
  436.         bmi.s    1$            jump if negative
  437.         move.b    #'+',11(a0)        write plus sign
  438.         bra.s    2$
  439. 1$        move.b    #'-',11(a0)        write minus sign
  440.         neg.w    d1            make exponent positive again
  441. 2$        divu.w    #10,d1            separate digits
  442.         or.b    #'0',d1
  443.         lea    12(a0),a0
  444.         move.b    d1,(a0)+        write MSD
  445.         swap    d1
  446.         or.b    #'0',d1
  447.         move.b    d1,(a0)+        write LSD
  448.         clr.b    (a0)            add NULL
  449.         pull    a1/d0-d2
  450.         rts
  451.         endc        
  452.  
  453.         endm
  454.  
  455.