home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Assembler / DVD!OMA2.DMS / in.adf / Examples / Library / MathFunctions / Convert.asm next >
Encoding:
Assembly Source File  |  1994-10-13  |  6.8 KB  |  376 lines

  1.  
  2. ; Routinen zum Konvertieren von FFP-Fließkommazahlen in ASCII und umgekehrt.  Compress-Tab 8.
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12. ; FFP =    afp (Stringzeiger)
  13. ; Wandelt einen    ASCII-String in    eine FFP-Fließkommazahl    um.  Rückgabe in D0.
  14.  
  15.     IFD    afp_c
  16.  
  17.     XDEF    _afp
  18.  
  19.     XREF    FFPAFP
  20.  
  21. _afp_REG    REG    d1-d7/a0-a6
  22. REGISTER    SET    14
  23.  
  24. _afp
  25.     movem.l    _afp_REG,-(SP)
  26.     move.l    REGISTER*4+4(SP),a0    ; Stringzeiger
  27.     jsr    FFPAFP
  28.     move.l    d7,d0            ; Rückgabewert
  29.     movem.l    (SP)+,_afp_REG
  30.     rts
  31.  
  32.     ENDC
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43. ; FFPAFP
  44. ; Assemblerversion von _afp.
  45. ; Eingabe:    A0 zeigt auf den umzuwandelnden    ASCII-String.
  46. ; Ausgabe:    D7 und D0 enthalten die    FFP-Fließkommazahl.
  47. ;        A0 zeigt direkt    hinter den gelesenen ASCII-String.
  48. ;        Falls ein Fehler auftrat, ist das Carry-Flag gesetzt, und A0
  49. ;        zeigt auf die Fehlerstelle.
  50.  
  51. ; Der String muß die Form haben:
  52. ;    [+|-]{x}.xxxx[(e|E)[+|-]x{x}]
  53. ;    [+|-]x{x}[(e|E)[+|-]x{x}]
  54.  
  55.     IFD    afp_a
  56.  
  57.     INCLUDE    "lvo/math.i"
  58.  
  59.     XDEF    FFPAFP
  60.  
  61.     XREF    _MathBase
  62.  
  63. FFPAFP
  64.     ; Initialisiere    ein paar Werte.
  65.     move.l    a0,a5            ; benutze A5 als Quellzeiger
  66.     moveq    #0,d7            ; Zahl
  67.     moveq    #0,d6            ; Zeichen
  68.     move.l    _MathBase,a6        ; Library-Basis
  69.  
  70.     ; Gibt es ein Vorzeichen ?
  71.     move.b    (a5)+,d6        ; hole Zeichen
  72.     cmp.b    #'-',d6            ; Minus    ?
  73.     seq    d5            ; ja, setze Vorzeichenflag
  74.     beq.s    1$            ; ja, neues Zeichen holen
  75.     cmp.b    #'+',d6            ; Plus ?
  76.     bne.s    2$            ; nein,    dann Vorzeichen    beendet
  77. 1$    move.b    (a5)+,d6        ; hole Zeichen
  78.     bra.s    2$
  79.  
  80.  
  81.  
  82.     ; Solange Dezimalziffern (vor dem Komma) kommen, multipliziere die
  83.     ; Zahl mit zehn    und addiere die    Ziffer.
  84. 4$    move.l    d7,d0            ; FFP-Zahl
  85.     move.l    #$A0000044,d1        ; mal 10
  86.     jsr    _LVOSPMul(a6)
  87.     bvs    AFPOverflow        ; wenn Überlauf
  88.     move.l    d0,d7
  89.     move.l    d6,d0
  90.     sub.b    #'0',d0            ; ergibt Integerzahl der Ziffer
  91.     jsr    _LVOSPFlt(a6)        ; wandele in FFP um
  92.     move.l    d7,d1
  93.     jsr    _LVOSPAdd(a6)        ; addiere die Ziffer zur Zahl
  94.     bvs    AFPOverflow        ; wenn Überlauf
  95.     move.l    d0,d7
  96.     move.b    (a5)+,d6        ; hole Zeichen
  97. 2$    cmp.b    #'0',d6
  98.     blo.s    3$
  99.     cmp.b    #'9',d6
  100.     bls.s    4$            ; wenn weitermachen
  101.  
  102.  
  103.  
  104.     ; Jetzt    folgt ein Punkt    mit Nachkommastellen oder der Exponent.
  105. 3$    cmp.b    #'.',d6            ; folgt    Punkt ?
  106.     bne.s    AFPNoDot        ; nein
  107.     move.l    #$CCCCCD3D,d4        ; beginne mit 0.1
  108.     bra.s    5$
  109.  
  110.     ; Addiere Nachkommastellen.
  111. 6$    move.l    d6,d0
  112.     sub.b    #'0',d0            ; ergibt Integerzahl der Ziffer
  113.     jsr    _LVOSPFlt(a6)        ; wandele in FFP um
  114.     move.l    d4,d1
  115.     jsr    _LVOSPMul(a6)
  116.     move.l    d7,d1
  117.     jsr    _LVOSPAdd(a6)        ; addiere die Ziffer zur Zahl
  118.     bvs    AFPOverflow        ; wenn Überlauf
  119.     move.l    d0,d7
  120.     move.l    d4,d0
  121.     move.l    #$CCCCCD3D,d1        ; mal 0.1
  122.     jsr    _LVOSPMul(a6)
  123.     beq.s    AFPNoDot        ; wenn Stellen nicht mehr signifikant
  124.     move.l    d0,d4
  125. 5$    move.b    (a5)+,d6        ; hole Zeichen
  126.     cmp.b    #'0',d6
  127.     blo.s    AFPNoDot
  128.     cmp.b    #'9',d6
  129.     bls.s    6$            ; wenn weitermachen
  130.  
  131.  
  132.  
  133. AFPNoDot
  134.     ; Jetzt    kann der Exponent folgen.
  135.     bclr    #5,d6            ; wandele in Großbuchstaben
  136.     cmp.b    #'E',d6            ; kommt    jetzt Exponent ?
  137.     bne.s    AFPEnd            ; nein,    Ende
  138.  
  139.     ; Gibt es ein Exponentenvorzeichen ?
  140.     swap    d5            ; rette    Vorzeichenflag
  141.     move.b    (a5)+,d6        ; hole Zeichen
  142.     cmp.b    #'-',d6            ; Minus    ?
  143.     seq    d5            ; ja, setze Flag
  144.     beq.s    1$            ; und hole neues Zeichen
  145.     cmp.b    #'+',d6            ; Plus ?
  146.     bne.s    2$            ; nein,    dann Vorzeichen    beendet
  147. 1$    move.b    (a5)+,d6        ; hole Zeichen
  148.  
  149.  
  150.     ; Lies den Exponenten maximal vierstellig.  Bei    zu vielen Stellen
  151.     ; gibt es automatisch einen Überlauf.
  152. 2$    moveq    #4-1,d0
  153.     moveq    #0,d3            ; Exponentenzahl
  154.     cmp.b    #'9',d6            ; Dezimalziffer    ?
  155.     bhi.s    AFPOverflow        ; nein,    Fehler
  156.     cmp.b    #'0',d6
  157.     blo.s    AFPOverflow        ; nein,    Fehler
  158.  
  159. 4$    mulu    #10,d3
  160.     sub.b    #'0',d6
  161.     add    d6,d3
  162.     move.b    (a5)+,d6
  163.     cmp.b    #'0',d6
  164.     blo.s    3$            ; wenn Ende
  165.     cmp.b    #'9',d6
  166.     bhi.s    3$            ; wenn Ende
  167.     dbra    d0,4$
  168.  
  169.  
  170.     ; Der Exponent ist zu Ende.  Ermittle den Exponentenfaktor.
  171. 3$    move.l    #$80000041,d0        ; beginne mit 1.0
  172.     move.l    #$A0000044,d4        ; vorerst Faktor 10.0
  173.     swap    d5
  174.     btst    #16,d5            ; negativer Exponent ?
  175.     beq.s    5$
  176.     move.l    #$CCCCCD3D,d4        ; ja, dann Faktor 0.1
  177.     bra.s    5$
  178.  
  179. 6$    move.l    d4,d1            ; Faktor
  180.     jsr    _LVOSPMul(a6)
  181.     bvs.s    AFPOverflow        ; wenn Überlauf
  182. 5$    dbra    d3,6$
  183.  
  184.  
  185.     ; Multipliziere    den Exponenten hinein.
  186.     move.l    d7,d1
  187.     jsr    _LVOSPMul(a6)
  188.     bvs.s    AFPOverflow        ; wenn Überlauf
  189.     move.l    d0,d7
  190.  
  191.  
  192. AFPEnd
  193.     ; Soll die FFP-Zahl negativ sein ?
  194.     move.l    d7,d0
  195.     tst.b    d5
  196.     beq.s    1$            ; nein
  197.     jsr    _LVOSPNeg(a6)        ; ja, negiere Zahl
  198.     move.l    d0,d7
  199. 1$    subq    #1,a5            ; stelle Zeiger    zurück
  200.     move.l    a5,a0
  201.     andi    #~1,CCR            ; lösche das Carry-Flag
  202.     rts
  203.  
  204.  
  205.  
  206. AFPOverflow
  207.     ; Es kam ein Überlauf vor.
  208.     subq    #1,a5            ; zeigt    jetzt auf Fehlerstelle
  209.     move.l    a5,a0
  210.     ori    #1,CCR            ; setze    das Carry-Flag
  211.     rts
  212.  
  213.     ENDC
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222.  
  223.  
  224. ; Exponent = fpa (FFP-Zahl, Stringzeiger)
  225. ; Wandelt eine FFP-Fließkommazahl in einen ASCII-String    um.
  226.  
  227.     IFD    fpa_c
  228.  
  229.     XDEF    _fpa
  230.  
  231.     XREF    FFPFPA
  232.  
  233. _fpa_REG    REG    d1-d7/a0-a6
  234. REGISTER    SET    14
  235.  
  236. _fpa
  237.     movem.l    _fpa_REG,-(SP)
  238.     movem.l    REGISTER*4+4(SP),d0/a0
  239.     jsr    FFPFPA            ; Exponent in D0 zurück
  240.     movem.l    (SP)+,_fpa_REG
  241.     rts
  242.  
  243.     ENDC
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254. ; FFPFPA
  255. ; Assemblerversion von _fpa.
  256. ; Eingabe:    D0 enthält die FFP-Fließkommazahl.
  257. ;        A0 zeigt auf den Zielstring.
  258. ; Ausgabe:    D0 enthält den Exponenten als vorzeichenbehafteten 32-Bit-Integer.
  259.  
  260.     IFD    fpa_a
  261.  
  262.     INCLUDE    "lvo/math.i"
  263.  
  264.     XDEF    FFPFPA
  265.  
  266.     XREF    _MathBase
  267.  
  268. FFPFPA
  269.     ; Initialisiere.
  270.     move.l    a0,a5            ; Zielzeiger
  271.     move.l    d0,d7            ; FFP-Zahl
  272.     move.l    _MathBase,a6        ; Library-Basis
  273.  
  274.     ; Ist die Zahl negativ ?
  275.     moveq    #0,d6            ; Exponent
  276.     bclr    #7,d7
  277.     beq.s    1$
  278.     move.b    #'-',(a5)+        ; ja, stelle Minus davor
  279.     bra.s    1$
  280.  
  281.     ; Ziehe    den negativen Exponenten.
  282. 3$    move.l    d7,d0
  283.     move.l    #$A0000044,d1
  284.     jsr    _LVOSPMul(a6)
  285.     move.l    d0,d7            ; Zahl mal 10.0
  286.     subq.l    #1,d6            ; dekrementiere    Exponent
  287. 1$    move.l    d7,d0
  288.     move.l    #$80000041,d1        ; vergleiche mit 1.0
  289.     jsr    _LVOSPCmp(a6)
  290.     bge.s    2$            ; wenn größer gleich 1.0
  291.     move.l    d7,d1
  292.     jsr    _LVOSPTst(a6)
  293.     bne.s    3$            ; wenn ungleich    Null
  294.     bra.s    2$
  295.  
  296.     ; Ziehe    den positiven Exponenten.
  297. 4$    move.l    d7,d0
  298.     move.l    #$CCCCCD3D,d1
  299.     jsr    _LVOSPMul(a6)
  300.     move.l    d0,d7            ; Zahl mal 0.1
  301.     addq.l    #1,d6            ; inkrementiere    Exponent
  302. 2$    move.l    d7,d0
  303.     move.l    #$A0000044,d1        ; vergleiche mit 10.0
  304.     jsr    _LVOSPCmp(a6)
  305.     bge.s    4$            ; solange größer gleich    10.0
  306.  
  307.     ; Was steht vor    dem Komma ?
  308.     move.l    d7,d0
  309.     jsr    _LVOSPFix(a6)
  310.     move    d0,d1
  311.     add.b    #'0',d1            ; ergibt ASCII-Ziffer
  312.     move.b    d1,(a5)+
  313.     jsr    _LVOSPFlt(a6)
  314.     move.l    d0,d1
  315.     move.l    d7,d0
  316.     jsr    _LVOSPSub(a6)
  317.     beq.s    FPAExp            ; wenn nichts mehr nach    dem Komma kommt
  318.     move.b    #'.',(a5)+
  319.     moveq    #6-1,d5            ; maximale Nachkommastellen
  320.  
  321.  
  322.     ; Gib die Nachkommastellen aus.
  323. 5$    move.l    d0,d7
  324.     move.l    #$A0000044,d1
  325.     jsr    _LVOSPMul(a6)        ; Zahl mal 10.0
  326.     move.l    d0,d7
  327.     jsr    _LVOSPFix(a6)
  328.     move    d0,d1
  329.     add.b    #'0',d1            ; ergibt ASCII-Ziffer
  330.     move.b    d1,(a5)+
  331.     jsr    _LVOSPFlt(a6)
  332.     move.l    d0,d1
  333.     move.l    d7,d0
  334.     jsr    _LVOSPSub(a6)
  335.     dbeq    d5,5$            ; wenn noch Nachkommastellen
  336.  
  337.  
  338. FPAExp
  339.     ; Ist der Exponent Null    ?
  340.     move.l    d6,d0            ; Rückgabewert
  341.     beq.s    0$            ; ja, dann nicht ausgeben und Ende
  342.  
  343.     ; Ist der Exponenten negativ ?
  344.     move.b    #'e',(a5)+
  345.     move.b    #'+',(a5)+
  346.     tst.l    d6
  347.     bpl.s    1$
  348.     neg.l    d6            ; ja
  349.     move.b    #'-',-1(a5)        ; gib Minus aus
  350.  
  351.     ; Der Exponent ist zweistellig.
  352. 1$    divu    #10,d6
  353.     add.b    #'0',d6
  354.     move.b    d6,(a5)+        ; 10er-Stelle
  355.     swap    d6
  356.     add.b    #'0',d6
  357.     move.b    d6,(a5)+        ; 1er-Stelle
  358.  
  359.     ; Fertig !
  360. 0$    clr.b    (a5)            ; Stringende
  361.     rts
  362.  
  363.     ENDC
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.     END
  375.  
  376.