diff options
| author | fishsoupisgood <github@madingley.org> | 2019-05-27 02:41:51 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 02:41:51 +0100 | 
| commit | 333b605b2afd472b823aeda0adf0e8b1ea9843c0 (patch) | |
| tree | bc8f581317897e2e53f278f1716b4471fcdccd4f /tests/t_fl90 | |
| download | asl-master.tar.gz asl-master.tar.bz2 asl-master.zip | |
Diffstat (limited to 'tests/t_fl90')
| -rw-r--r-- | tests/t_fl90/asflags | 0 | ||||
| -rw-r--r-- | tests/t_fl90/cpu_time.inc | 170 | ||||
| -rw-r--r-- | tests/t_fl90/float.inc | 1601 | ||||
| -rw-r--r-- | tests/t_fl90/macros.inc | 57 | ||||
| -rw-r--r-- | tests/t_fl90/mon.inc | 11 | ||||
| -rw-r--r-- | tests/t_fl90/t_fl90.asm | 179 | ||||
| -rw-r--r-- | tests/t_fl90/t_fl90.doc | 6 | ||||
| -rw-r--r-- | tests/t_fl90/t_fl90.ori | bin | 0 -> 5466 bytes | 
8 files changed, 2024 insertions, 0 deletions
| diff --git a/tests/t_fl90/asflags b/tests/t_fl90/asflags new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/t_fl90/asflags diff --git a/tests/t_fl90/cpu_time.inc b/tests/t_fl90/cpu_time.inc new file mode 100644 index 0000000..bb23594 --- /dev/null +++ b/tests/t_fl90/cpu_time.inc @@ -0,0 +1,170 @@ +; CPU_TIME.INC +;****************************************************************************** +;* Zeitmessmodul fr TLCS 90                                                  * +;*                                                                            * +;* Originale fr den TLCS 900 von Oli(ver Sellke)                             * +;* Implementierung TLCS 90 von Alfred Arnold, Dezember 1993                   * +;*                                                                            * +;*  Routine     Funktion                Eingabe Ausgabe  Stack    L„nge       * +;*                                                                            * +;* InitTimer    Timer initialisieren     ----    ----    0 Byte   6 Byte      * +;* StartTimer   Timer starten            ----    ----    0 Byte   7 Byte      * +;* StopTime     Timer stoppen & Ausgabe  ----    ----    6 Byte 117 Byte *)   * +;*                                                                            * +;*      *) bei hoher Aufl”sung                                                * +;*                                                                            * +;* - Die Routinen benutzen Timer 4, dieser darf nicht von der Anwendung       * +;*   benutzt werden!!                                                         * +;* - Die Aufl”sung kann ber das Symbol BigTime umgeschaltet werden:          * +;*                                                                            * +;*       BigTime       Aufl”sung    Maximalzeit                               * +;*       definiert      0,8 us       52,428 ms                                * +;*       undefiniert   12,8 us      838,848 ms                                * +;*                                                                            * +;* - Die Datei MON.INC wird fr die Einsprnge des TDBTMP90-Monitors ben”tigt.* +;* - MACROS.INC muá vorher eingebunden werden                                 * +;*                                                                            * +;****************************************************************************** + +                section CPU_Time + +;------------------------------------------------------------------------------ +; Monitoreinsprungadressen laden + +                include "mon.inc" + +;------------------------------------------------------------------------------ +; Timer vorinitialisieren + +                proc    InitTimer +                ifdef   BigTime +                 ld      (T4MOD),00100010b ; nur Software-Capture, Phi16 +                elseif +                 ld      (T4MOD),00100001b ; nur Software-Capture, Phi1 +                endif +                set     5,(TRUN)        ; Vorteiler starten +                res     4,(TRUN)        ; Timer steht noch +                ret +                endp + +;------------------------------------------------------------------------------ +; Timer starten + +                proc    StartTimer +                set     2,(T4MOD)       ; Timer l”schen +                res     2,(T4MOD) +                set     4,(TRUN)        ; Timer starten +                ret +                endp + +;------------------------------------------------------------------------------ +; Timer stoppen & Wert auf Konsole ausgeben + +                subproc Div24 + +                ld      b,16            ; A-HL : B = HL und A +DivLoop:        sll     l               ; Divident hochschieben +                rl      h +                rla +                srl     h               ; fr nachher +                rr      l +                sub     a,c             ; paát Divisor hinein ? +                jr      nc,DivOK +                add     a,c             ; nein, zurcknehmen +                scf                     ; ins Ergebnis 0 einschieben +DivOK:          ccf                     ; neues Ergebnisbit +                rl      l               ; Ergebnis in HL einschieben +                rl      h +                djnz    DivLoop +                ret + +                endp + + +                proc    StopTimer + +                push    af              ; Register retten +                push    hl +                push    de +                push    bc + +                res     5,(T4MOD)       ; Wert im CAP1 latchen +                res     4,(TRUN)        ; Timer wieder anhalten +                ld      hl,(CAP1L)      ; Wert auslesen + +                ifdef   BigTime +                 ld     a,h             ; groáe Periode: x128... +                 ld     h,l +                 ld     l,0 +                 srla +                 rr     h +                 rr     l +                 ld     c,100           ; ...Teilen durch 100 +                elseif +                 ld     a,0             ; kleine Periode: x8... +                 rept   3 +                  sll   l +                  rl    h +                  rla +                 endm +                 ld     c,10            ; ...Teilen durch 10 +                endif +                call    Div24           ; Division durchfhren +                ifdef   BigTime         ; Kommatrennung fr groáe Periode +                 ld     a,0 +                 call   Div24 +                 ld     d,a             ; Rest merken +                endif +                ld      e,0             ; Zeichenz„hler nullen +                ld      c,10            ; Teilerfaktor konstant +InLoop:         ld      a,0             ; Erweiterung auf 24 Bit +                call    Div24           ; einmal teilen +                push    af              ; Zeichen auf LIFO merken +                inc     e               ; ein Zeichen mehr +                or      hl,hl           ; noch etwas brig ? +                jr      nz,InLoop +                ld      a,5             ; Leerzeichen fr Ausrichtung +                sub     a,e             ; Zahl berechnen +                jr      z,OutErg        ; Nullschleife abfangen +                ld      b,a             ; ansonsten passende Zahl Leerzeichen +BlankLoop:      call    BLAUS           ; voranstellen +                djnz    BlankLoop +OutErg:         ld      b,e             ; jetzt die Zeichen ausgeben +OutLoop:        pop     af +                add     a,'0' +                call    CONOUT +                djnz    OutLoop +                ifdef   BigTime         ; bei groáer Aufl”sung Nachkommastellen +                 ld     a,'.' +                 call   CONOUT +                 ld     l,d             ; Zehner/Einerzerlegung +                 ld     h,0 +                 div    hl,c +                 add    hl,'00' +                 ld     a,l +                 call   CONOUT +                 ld     a,h +                 call   CONOUT +                 call   BLAUS +                 ld     a,'m' +                elseif +                 ld     a,' ' +                 call   CONOUT +                 ld     a,'u' +                endif +                call    CONOUT          ; Ausgabe Einheit +                ld      a,'s' +                call    CONOUT + +                pop     bc              ; Register zurck +                pop     de +                pop     hl +                pop     af + +                ret +                endp + +;------------------------------------------------------------------------------ +; gemeinsames Ende + +                endsection diff --git a/tests/t_fl90/float.inc b/tests/t_fl90/float.inc new file mode 100644 index 0000000..7355130 --- /dev/null +++ b/tests/t_fl90/float.inc @@ -0,0 +1,1601 @@ +; FLOAT.INC +;****************************************************************************** +;* Gleitkommabibliothek fr TLCS 90                                           * +;*                                                                            * +;* Originale fr den Z80 aus mc 12/88,1/89                                    * +;* Portierung auf TLCS 90 von Alfred Arnold, Dezember 1993                    * +;*                                                                            * +;*  Routine  Funktion             Eingabe Ausgabe  Stack    L„nge  Zeit/10MHz * +;*                                                                            * +;*  fadd     Addition             2*Stack  BC-DE  14 Byte 347 Byte   248 us   * +;*  fsub     Subtraktion          2*Stack  BC-DE  14 Byte  12 Byte   255 us   * +;*  fmul     Multiplikation       2*Stack  BC-DE  20 Byte 356 Byte   936 us   * +;*  fdiv     Division             2*Stack  BC-DE  22 Byte 303 Byte  1081 us   * +;*  fmul2    Mult. mit 2er-Potenz Stack,A  BC-DE  10 Byte 162 Byte    28 us   * +;*  fsqrt    Quadratwurzel        Stack    BC-DE  22 Byte 621 Byte  1900 us   * +;*  fitof    Int-->Float          Stack    BC-DE  10 Byte  84 Byte  160 us *) * +;*  fftoi    Float-->Int          Stack    BC-DE  10 Byte 104 Byte  170 us *) * +;*  fftoa    Float-->ASCII        3*Stack  -----  40 Byte 451 Byte     *)     * +;*  fatof    ASCII-->Float        Stack  C,BC-DE  42 Byte 396 Byte     *)     * +;*                                                                            * +;*  *) Die Ausfhrungszeiten streuen je nach Operand sehr stark und k”nnen    * +;*     bei den ASCII-Funktionen bei vielen Millisekunden liegen.              * +;*                                                                            * +;*  - Parametereingabe ber den Stack bedeutet, daá die Parameter mittels     * +;*    PUSH vor dem Aufruf auf den Stack gelegt werden mssen.  Diese Werte    * +;*    werden von den Unterroutinen am Ende automatisch vom Stack entfernt.    * +;*    Der zur šbergabe ben”tigte Platz ist bei den Angaben zur Stackbelastung * +;*    eingerechnet!                                                           * +;*  - Wollen Sie einzelne Routinen entfernen, so beachten Sie, daá fsub Teile * +;*    aus fadd, fdiv Teile aus fmul sowie fftoi Teile aus fitof verwendet !   * +;*  - Gleitkommaformat ist IEEE Single (32 Bit)                               * +;*  - Integerwerte bei fmul2, fitof und fftoi sind vorzeichenbehaftet         * +;*  - Da die Routinen lokale Labels verwenden, ist mindestens AS 1.39 erfor-  * +;*    derlich                                                                 * +;*  - MACROS.INC muá vorher eingebunden werden                                * +;****************************************************************************** + +                section float + +;------------------------------------------------------------------------------ +; modulglobale Konstanten + +MaxExpo         equ     255 +Bias            equ     127 + +OpSize          equ     4               ; Gr”áe eines Operanden + +fIX_alt         equ     0               ; Top of Stack liegt IX +FAdr            equ     2               ; Rcksprungadresse +Op2             equ     4               ; Adresse Operand 2 +Op1             equ     Op2+OpSize      ; Adresse Operand 1 + +Ld10:           dd      ld(10) +One:            dd      1.0 +Ten:            dd      10.0 +Tenth:          dd      3dcccccdh       ; =0.1, aber die Rundung auf manchen +					; Systemen variiert (damit Test nicht +					; scheitert) +Half:           dd      0.5 + +cpsh            macro   reg,op,{NoExpand} +                ld      reg,(op+2) +                push    reg +                ld      reg,(op) +                push    reg +                endm + +;------------------------------------------------------------------------------ +; Addition + +                proc    fadd +                link    ix,0            ; Eintritt + +                push    af              ; Register retten +                push    hl + +                public  AddSub:Parent   ; Einsprung fr fsub + +AddSub:         ld      a,(ix+Op1+3)    ; Vorzeichen Operand 1 laden +                ld      e,a             ; Ergebnisvorzeichen in E, Bit 7 +                xor     a,(ix+Op2+3)    ; mit Vorzeichen von Op2 verknpfen +                ld      d,a             ; Subtraktionsflag in D, Bit 7 +                res     7,(ix+Op1+3)    ; Vorzeichen in Mantisse 1 l”schen +                res     7,(ix+Op2+3)    ; Vorzeichen in Mantisse 2 l”schen + +; Die Operanden sind jetzt in der Form 0eee eeee efff ... ffff + +                ld      hl,(ix+Op1)     ; Differenz Op1-Op2 bilden +                sub     hl,(ix+Op2) +                ld      hl,(ix+Op1+2) +                sbc     hl,(ix+Op2+2) +                jr      nc,Ad_1         ; Sprung falls Op1>Op2 +                ld      bc,(ix+Op1)     ; ansonsten Operanden vertauschen +                ex      bc,(ix+Op2) +                ld      (ix+Op1),bc +                ld      bc,(ix+Op1+2) +                ex      bc,(ix+Op2+2) +                ld      (ix+Op1+2),bc +                ld      a,e             ; Ergebnisvorzeichen neu berechnen +                xor     a,d +                ld      e,a + +Ad_1:           ld      a,(ix+Op1+2)    ; Exponent der gr”áeren Zahl laden +                ld      c,(ix+Op1+3) +                slaa +                rl      c +                jr      z,Den1 +                set     7,(ix+Op1+2)    ; implizite Eins erzeugen +Den1:           ld      a,(ix+Op2+2)    ; dito Zahl 2 +                ld      b,(ix+Op2+3) +                slaa +                rl      b +                jr      z,Den2 +                set     7,(ix+Op2+2) + +Den2:           push    bc              ; jetzt die Register fr den +                push    de              ; Blocktransferbefehl retten +                ld      bc,2*OpSize-1   ; beide Operanden verschieben +                ld      hl,ix           ; HL zeigt auf letztes Byte +                add     hl,Op2+2*OpSize-1 +                ld      de,hl           ; HL nach DE kopieren +                dec     hl              ; HL zeigt auf vorletztes Byte +                lddr                    ; Verschiebung beider Mantissen +                pop     de              ; um 8 Bit nach links +                pop     bc + +                xor     a,a +                ld      (ix+Op1),a      ; Form: ffff ... ffff 0000 0000 +                ld      (ix+Op2),a +                ld      a,c             ; Differenz der Exponenten berechnen +                sub     a,b +                ld      b,a             ; Differenz nach B fr LOOP-Befehl +                jr      z,N_Anp         ; falls Null, keine Anpassung +                cp      a,25            ; mehr als 24? (Abfrage mit Carry +                jp      c,Anp           ; erfordert Vergleich mit 25) +                ld      b,0             ; !!!! +                jp      Round + +Anp:            srl     (ix+Op2+3)      ; Anpassung der zweiten Mantisse +                rr      (ix+Op2+2)      ; durch Verschiebung nach rechts +                rr      (ix+Op2+1) +                rr      (ix+Op2) +                djnz    Anp             ; bis B=0 + +N_Anp:          bit     7,d             ; Addition oder Subtraktion ? +                jr      nz,Subtract     ; ggfs. zur Subtraktion springen +                ld      hl,(ix+Op1)     ; jetzt werden die beiden Mantissen +                add     hl,(ix+Op2)     ; zueinander addiert +                ld      (ix+Op1),hl +                ld      hl,(ix+Op1+2) +                adc     hl,(ix+Op2+2) +                ld      (ix+Op1+2),hl +                jr      nc,Round        ; kein šberlauf-->zum Runden +                rr      (ix+Op1+3)      ; šberlauf einschieben +                rr      (ix+Op1+2) +                rr      (ix+Op1+1) +                rr      (ix+Op1) +                inc     bc              ; Exponent erh”hen (B ist 0 durch +                jr      Round           ; Schleife), zum Runden + +Subtract:       ld      hl,(ix+Op1)     ; beide Mantissen werden voneinander +                sub     hl,(ix+Op2)     ; subtrahiert +                ld      (ix+Op1),hl +                ld      hl,(ix+Op1+2) +                sbc     hl,(ix+Op2+2) +                ld      (ix+Op1+2),hl +                jr      m,Round         ; bei fhrender Eins zum Runden +                jr      nz,Norm         ; ungleich 0 ?  Dann zum Normalisieren +                cp      hl,(ix+Op1)     ; Rest der Mantisse auch Null ? +                jr      eq,Zero         ; alles Null --> Ergebnis ist Null + +Norm:           ld      a,b             ; Exponent noch nicht Null ? +                or      a,c +                jr      z,Round +                dec     bc              ; Exponent erniedrigen +                sla     (ix+Op1)        ; Mantisse normalisieren, bis +                rl      (ix+Op1+1)      ; fhrende Eins auftaucht +                rl      (ix+Op1+2) +                rl      (ix+Op1+3) +                jr      p,Norm          ; noch keine Eins-->weitermachen + +Round:          add     (ix+Op1),80h    ; jetzt Runden auf Bit hinter Mantisse +                jr      nc,NoOver       ; kein šbertrag ? +                inc     (ix+Op1+1)      ; doch, n„chstes Mantissenbyte +                jr      nz,NoOver       ; behandeln, jetzt auf Null prfen, +                inc     (ix+Op1+2)      ; da der INC-Befehl kein Carry liefert +                jr      nz,NoOver +                inc     (ix+Op1+3) +                jr      nz,NoOver +                scf                     ; fhrende Eins erzeugen +                rr      (ix+Op1+3)      ; bei šberlauf Mantisse durch +                rr      (ix+Op1+2)      ; Rechtsschieben wieder normalisieren +                rr      (ix+Op1+1)      ; (nur fr 24 Bit notwendig) +                inc     bc              ; und Exponent korrigieren + +NoOver:         xor     a,a             ; A = 0 +                cp      a,(ix+Op1+3)    ; Mantisse auf Null prfen +                jr      nz,NoZero +                cp      a,(ix+Op1+2) +                jr      nz,NoZero +                cp      a,(ix+Op1+1)    ; alle Mantissenbytes Null ? +                jr      nz,NoZero       ; dann ist auch das Ergebnis Null + +Zero:           ld      b,a             ; Null-Ergebnis aufbauen +                ld      c,a +                ld      de,bc +                jr      Exit            ; dann Routine verlassen + +NoZero:         cp      a,b             ; A ist Null +                ld      a,MaxExpo       ; Exponent oberes Byte ungleich Null ? +                jr      nz,Over         ; dann ist šberlauf eingetreten +                cp      a,c             ; oder genau MaxExpo erreicht ? +                jr      nz,NoUe +Over:           ld      c,a             ; Exponent auf MaxExpo setzen +                xor     a,a             ; und Mantisse auf Null +                ld      (ix+Op1+3),a +                ld      (ix+Op1+2),a +                ld      (ix+Op1+1),a +                jr      DeNorm + +NoUe:           xor     a,a             ; A = 0 +                cp      a,c             ; Exponent Null (Zahl denormalisiert ? +                jr      z,DeNorm        ; ja --> +                sla     (ix+Op1+1)      ; fhrendes Bit wird nicht gespeichert +                rl      (ix+Op1+2)      ; daher Mantisse um 1 Bit nach links +                rl      (ix+Op1+3) + +DeNorm:         ld      b,c             ; Ergebnis aufbauen: Exponent in B +                ld      c,(ix+Op1+3)    ; Mantisse oberstes Byte +                ld      d,(ix+Op1+2) +                sla     e               ; Vorzeichen aus E in Carry schieben +                ld      e,(ix+Op1+1) +                rr      b               ; Vorzeichen in Ergebnis einschieben +                rr      c +                rr      d +                rr      e + +Exit:           pop     hl              ; Register restaurieren +                pop     af + +                unlk    ix              ; Austritt +                retd    2*OpSize        ; Parameter abr„umen +                endp + +;------------------------------------------------------------------------------ +; Subtraktion + +                proc    fsub + +                link    ix,0            ; Eintritt + +                push    af              ; Register retten +                push    hl + +                xor     (ix+Op2+3),80h  ; Vorzeichen Operand 2 kippen + +                jrl     AddSub          ; weiter wie Addition + +                endp + +;------------------------------------------------------------------------------ +; Multiplikation + +                proc    fmul + +                DefLocal temp,6         ; Platz Tempor„rvariable + +                link    ix,LocalSize    ; Platz auf Stack reservieren + +                push    af              ; Register retten +                push    hl + +                ld      a,(ix+Op1+3)    ; Ergebnisvorzeichen bestimmen +                xor     a,(ix+Op2+3) +                ld      c,a             ; in C merken + +                ld      d,0             ; Exponent 1 laden +                ld      e,(ix+Op1+3) +                ld      a,(ix+Op1+2) +                slaa                    ; Exponent unterstes Bit in Carry +                rl      e               ; und in E einschieben +                srla                    ; ergibt Bit 7=0 +                ld      (ix+Op1+3),a    ; impl. Null vorbesetzen+um 8 Bit schieben +                cp      e,0 +                jr      z,Den1          ; falls Null, dann denormalisiert +                set     7,(ix+Op1+3)    ; ansonsten impl. Eins erzeugen +                dec     de              ; Bias kompensieren +Den1:           ld      hl,(ix+Op1)     ; jetzt restliche Bytes verschieben +                ld      (ix+Op1+1),hl +                xor     hl,hl           ; unterste Mantissenbits l”schen +                ld      (ix+Op1),h      ; Form: ffff ... ffff 0000 0000 + +                ld      (ix+temp+4),hl  ; lokale Variable mit Null vorbesetzen +                ld      (ix+temp+2),hl +                ld      (ix+temp),hl + +                ld      l,(ix+Op2+3)    ; Exponent 2 in HL aufbauen +                ld      a,(ix+Op2+2) +                res     7,(ix+Op2+2)    ; gleiches Verfahren wie Op1 +                slaa +                rl      l +                jr      z,Den2 +                set     7,(ix+Op2+2) +                dec     hl +Den2: +                add     hl,de           ; Exponenten aufaddieren +                sub     hl,Bias-3       ; Bias-3 subtrahieren +                jp      p,NoZero        ; positiv-->kein Unterlauf +                ld      a,l             ; Exponent <-24 ? +                cp      a,-24 +                jr      nc,NoZero +                jp      MulZero         ; ja, dann ist Ergebnis Null + +NoZero:         ld      b,24            ; Schleifenz„hler Multiplikation +                ld      de,0            ; Hilfsregister Multiplikand +                push    hl              ; HL zum Addieren benutzen +Multiply:       srl     (ix+Op1+3)      ; Multiplikand nach rechts schieben +                rr      (ix+Op1+2) +                rr      (ix+Op1+1) +                rr      (ix+Op1) +                rr      d               ; DE als Verl„ngerung von Operand 1 +                rr      e +                sla     (ix+Op2)        ; Multiplikator nach links schieben +                rl      (ix+Op2+1) +                rl      (ix+Op2+2)      ; falls fhrendes Bit 0, nicht addieren +                jr      nc,NoAdd +                ld      hl,(ix+temp)    ; sonst aufaddieren +                add     hl,de +                ld      (ix+temp),hl +                ld      hl,(ix+temp+2) +                adc     hl,(ix+Op1) +                ld      (ix+temp+2),hl +                ld      hl,(ix+temp+4) +                adc     hl,(ix+Op1+2) +                ld      (ix+temp+4),hl +NoAdd:          djnz    Multiply        ; Schleife durchlaufen +                pop     hl +                ld      a,(ix+temp+5) +                or      a,a             ; Flags setzen +                jp      m,MulRound      ; bei fhrender Eins zum Runden +                jr      nz,Normalize    ; ansonsten normalisieren +                cp      a,(ix+temp+4) +                jr      nz,Normalize +                cp      a,(ix+temp+3) +                jr      nz,Normalize +                cp      a,(ix+temp+2) +                jr      Normalize +                jp      MulZero         ; komplett Null-->Ergebnis Null + +Normalize:      bit     7,h             ; Exponent negativ ? +                jp      nz,Underrun     ; ggf. Unterlauf behandlen + +Norm1:          cp      hl,0            ; Exponent=0 ? +                jr      z,MulRound +                dec     hl              ; Exponent erniedrigen, +                sla     (ix+temp)       ; Mantisse verschieben... +                rl      (ix+temp+1) +                rl      (ix+temp+2) +                rl      (ix+temp+3) +                rl      (ix+temp+4) +                rl      (ix+temp+5) +                jp      p,Norm1         ; ...bis fhrende Eins auftaucht + +                public  MulRound:Parent ; Einsprung fr Division +MulRound:       ld      a,(ix+temp+2)   ; jetzt Runden auf Bit hinter Mantisse +                add     a,80h +                jr      nc,NoOver       ; kein šbertrag +                inc     (ix+temp+3)     ; doch, n„chstes Mantissenbyte +                jr      nz,NoOver       ; behandeln, jetzt auf Null prfen +                inc     (ix+temp+4)     ; da INC kein Carry liefert +                jr      nz,NoOver +                inc     (ix+temp+5) +                jr      nz,NoOver +                scf                     ; Eins erzeugen +                rr      (ix+temp+5)     ; bei šberlauf Mantisse durch +                rr      (ix+temp+4)     ; Rechtsschieben wieder normalisieren +                rr      (ix+temp+3) +                inc     hl              ; und Exponent korrigieren + +NoOver:         cp      hl,MaxExpo      ; Exponent prfen +                jr      ult,NoUeber     ; kein šberlauf + +                public  MulOver:Parent  ; Einsprung fr fdiv +MulOver:        ld      hl,MaxExpo      ; šberlauf: Exponent=MaxExpo +                ld      (ix+temp+5),h +                ld      (ix+temp+4),h +                ld      (ix+temp+3),h +                jr      DeNorm + +NoUeber:        xor     a,a             ; A=0 +                cp      a,l             ; Exponent ist Null ? +                jr      z,DeNorm        ; ja, Ergebnis ist denormalisiert +                sla     (ix+temp+3)     ; nein, fhrende=implizite Eins +                rl      (ix+temp+4)     ; rausschieben +                rl      (ix+temp+5) + +DeNorm:         sla     c               ; Vorzeichen in Carry schieben +                ld      b,l             ; Exponent einsetzen +                ld      c,(ix+temp+5) +                ld      d,(ix+temp+4) +                ld      e,(ix+temp+3) +                rr      b               ; und Vorzeichen einschieben +                rr      c +                rr      d +                rr      e               ; Form: seee eeee efff ffff ... ffff + +Result:         pop     hl              ; Register zurck +                pop     af + +                unlk    ix              ; Stackrahmen abbauen +                retd    2*OpSize        ; Operanden abr„umen + +                public  MulZero:Parent  ; Einsprung fr fdiv +MulZero:        xor     a,a             ; Ergebnis ist Null +                ld      b,a +                ld      c,a +                ld      d,a +                ld      e,a +                jr      Result + +Underrun:       ld      a,l             ; Exponent in A +                neg     a               ; negieren fr Schleifenz„hler +                cp      a,24            ; totaler Unterlauf ? +                jr      nc,MulZero      ; ja, dann ist Ergebnis Null +                ld      b,a             ; Mantisse denormalisieren +Shr:            srl     (ix+temp+5)     ; bis Exponent Null ist +                rr      (ix+temp+4) +                rr      (ix+temp+3) +                djnz    Shr +                ld      l,b             ; Exponent in Register L=B=0 +                jp      Denorm          ; denormalisiertes Ergebnis erzeugen + +                endp + +;------------------------------------------------------------------------------ +; Division + +                proc    fdiv + +                DefLocal temp,6         ; Platz Tempor„rvariable + +                link    ix,LocalSize    ; 6 Byte Platz auf Stack reservieren + +                push    af              ; Register retten +                push    hl + +                ld      a,(ix+Op1+3)    ; Ergebnisvorzeichen bestimmen +                xor     a,(ix+Op2+3) +                ld      c,a             ; Vorzeichen in C Bit 7 merken +                push    bc              ; Vorzeichen retten + +                ld      h,0             ; Exponent 1 laden +                ld      l,(ix+Op1+3) +                ld      a,(ix+Op1+2) +                res     7,(ix+Op1+2)    ; impl. Null vorbesetzen +                slaa                    ; Exponent unterstes Bit in Carry +                rl      l               ; und in L einschieben +                jr      z,Den1          ; falls Null, dann Op1 denormalisiert +                set     7,(ix+Op1+2)    ; implizite Eins erzeugen +                dec     hl              ; Bias kompensieren +Den1: +                ld      d,0             ; Exponent 2 in DE aufbauen +                ld      e,(ix+Op2+3) +                ld      a,(ix+Op2+2) +                ld      (ix+Op2+3),a    ; Verfahren wie oben +                res     7,(ix+Op2+3) +                slaa +                rl      e +                jr      z,Den2 +                set     7,(ix+Op2+3) +                dec     de +Den2: +                ld      bc,(ix+Op2)     ; jetzt restliche Bytes kopieren +                ld      (ix+Op2+1),bc +                xor     a,a             ; A=0 +                ld      (ix+Op2),a      ; Form: ffff ... ffff 0000 0000 +                srl     (ix+Op2+3) +                rr      (ix+Op2+2) +                rr      (ix+Op2+1) +                rr      (ix+Op2)        ; Form: 0fff ... ffff f000 0000 +                jr      nz,NoZero1      ; Mantisse 2 auf Null prfen +                cp      a,(ix+Op2+1) +                jr      nz,NoZero1 +                cp      a,(ix+Op2+2) +                jr      nz,NoZero1 +                cp      a,(ix+Op2+3) +                jr      nz,NoZero1 +                jp      MulOver + +NoZero1:        xor     a,a             ; Carry-Flag l”schen +                sbc     hl,de           ; Exponenten subtrahieren +                add     hl,Bias         ; Bias addieren +                jr      p,NoZero        ; Exponent negativ ? +                cp      l,-24           ; Exponent kleiner als -24 ? +                jr      nc,NoZero +                jp      MulZero         ; ja, dann ist das Ergebnis Null +NoZero: +                add     hl,25           ; Exponent um 25 erh”hen; jetzt ist er sicher gr”áer als Null +                xor     a,a             ; A=0 +                ld      bc,(ix+Op1+1)   ; Divident in Register kopieren +                ld      d,(ix+Op1) +                ld      e,a             ; die untersten Bits sind Null +                cp      a,d             ; ist Divident Null ? +                jr      nz,NoZero2 +                cp      a,c +                jr      nz,NoZero2 +                cp      a,b +                jr      nz,NoZero2 +                pop     bc              ; Stack bereinigen (Vorzeichen laden) +                jp      MulZero         ; und Null als Ergebnis ausgeben +NoZero2: +                ld      (ix+temp+5),a   ; Ergebnis vorbesetzen +                ld      (ix+temp+4),a +                ld      (ix+temp+3),a +                ld      (ix+temp+2),a + +NormLoop:       bit     6,(ix+Op2+3)    ; ist der Divisor normalisiert ? +                jr      nz,Norm         ; ja--> +                inc     hl              ; nein, Exponent erh”hen +                sla     (ix+Op2)        ; Divisor verschieben bis in +                rl      (ix+Op2+1)      ; Form 01ff ... +                rl      (ix+Op2+2) +                rl      (ix+Op2+3) +                jr      NormLoop +Norm:           srl     b +                rr      c +                rr      d +                rr      e               ; Form: 0fff ... ffff f000 0000 + +                push    iy              ; Exponent nach IY +                ld      iy,hl +Loop:           ld      (ix+Op1+2),bc   ; Divident zwischenspeichern +                                        ; die Speicherpl„tze von Op1 +                ld      (ix+Op1),de     ; stehen zur Verfgung, da wir Op1 +                                        ; in die Register BC-DE kopiert haben +                ld      hl,de           ; jetzt Divisor abziehen +                sub     hl,(ix+Op2) +                ld      de,hl +                ld      hl,bc +                sbc     hl,(ix+Op2+2) +                ld      bc,hl +                jr      nc,IsOne        ; kein Carry: Divisor paát +                ld      de,(ix+Op1)     ; ansonsten zurckkopieren +                ld      bc,(ix+Op1+2)   ; Carry bleibt erhalten! +IsOne:          ccf                     ; Carry-Flag umdrehen +                rl      (ix+temp+2)     ; Ergebnis aufbauen +                rl      (ix+temp+3) +                rl      (ix+temp+4) +                rl      (ix+temp+5) +                sla     e               ; Divident verschieben +                rl      d +                rl      c +                rl      b + +                add     iy,-1           ; Exponent erniedrigen +                jr      z,DeNorm        ; falls Null, dann denormalisiert +                bit     0,(ix+temp+5)   ; fhrende Eins in Ergebnis-Mantisse ? +                jr      z,Loop          ; nein, weiter rechnen + +DeNorm:         ld      hl,iy           ; Exponent zurck +                ld      b,(ix+temp+5)   ; h”chstes Bit merken +                ld      a,(ix+temp+4) +                ld      (ix+temp+5),a   ; Mantisse in Form +                ld      iy,(ix+temp+2)  ; ffff ... ffff 0000 0000 +                ld      (ix+temp+3),iy +                pop     iy              ; IY erst jetzt freigeben +                rr      b               ; h”chstes Bit einschieben +                rr      (ix+temp+5) +                rr      (ix+temp+4) +                rr      (ix+temp+3) +                rr      (ix+temp+2) + +                pop     bc              ; Vorzeichen wieder laden +                xor     a,a             ; A=0 +                cp      a,(ix+temp+5)   ; Mantisse ist Null ? +                jr      nz,NoZero3 +                cp      a,(ix+temp+4) +                jr      nz,NoZero3 +                cp      a,(ix+temp+3) +                jr      nz,NoZero3 +                cp      a,(ix+temp+2) +                jp      z,MulZero +NoZero3: +                jp      MulRound + +                endp + +;------------------------------------------------------------------------------ +; Wandlung Integer-->Gleitkomma + +                proc    fitof + +                link    ix,0            ; Stackrahmen aufbauen +                push    af              ; Register retten +                push    hl + +                ld      bc,(ix+Op2+2)   ; Operanden hereinholen +                ld      de,(ix+Op2)     ; Reihenfolge: BCDE + +                ld      hl,bc           ; Operand = 0 ? +                or      hl,de +                jr      z,ItofResult    ; dann Ergebnis Null + +                bit     7,b             ; Zahl positiv ? +                jr      z,Positive +                ld      hl,bc           ; dann Zahl negieren +                xor     hl,-1 +                ld      bc,hl +                ld      hl,de +                xor     hl,-1 +                inc     hl +                or      hl,hl +                ld      de,hl +                jr      nz,Positive +                inc     bc + +Positive:       ld      l,Bias+32       ; Exponent vorbesetzen +Shift:          dec     l +                sla     e               ; Mantisse verschieben, bis fhrende +                rl      d               ; Eins auftaucht +                rl      c +                rl      b +                jr      nc,Shift +                ld      e,d             ; Exponent einsetzen +                ld      d,c +                ld      c,b +                ld      b,l +                sla     (ix+Op2+3)      ; Vorzeichen in Carry +                rr      b               ; ins Ergebnis einschieben +                rr      c +                rr      d +                rr      e + +                public  ItofResult:Parent +ItofResult:     pop     hl              ; Register zurck +                pop     af +                unlk    ix              ; abbauen +                retd    4               ; Ende + +                endp + +;------------------------------------------------------------------------------ +; Wandlung Gleitkomma-->Integer + +                proc    fftoi + +                link    ix,0            ; Stackrahmen aufbauen + +                push    af              ; Register retten +                push    hl + +                ld      d,(ix+Op2)      ; Operand in Register laden +                ld      bc,(ix+Op2+1)   ; Reihenfolge: EBCD +                ld      e,(ix+Op2+3)    ; erspart sp„ter Vertauschungen + +                ld      h,e             ; Vorzeichen in H, Bit 7 +                ld      a,e             ; Exponent in A aufbauen +                sla     b               ; LSB aus B holen +                rla +                scf                     ; impl. Eins einschieben +                rr      b +                sub     a,Bias +                ld      l,a             ; Exponent nach L kopieren +                jp      m,Zero          ; falls keiner Null, Ergebnis Null +                ld      a,30 +                cp      a,l             ; gr”áer 30 ? +                jr      c,Over          ; dann šberlauf +                ld      e,0             ; Zahl jetzt in BCDE in der Form +                inc     a               ; 1fff ... ffff 0000 0000 + +Shift:          srl     b               ; jetzt Mantisse verschieben +                rr      c +                rr      d +                rr      e +                inc     l +                cp      a,l             ; bis Exponent stimmt +                jr      nz,Shift +                bit     7,h             ; Zahl negativ ? +                jr      z,ItofResult    ; nein, fertig + +                ld      hl,de           ; Zahl negieren +                xor     hl,-1 +                ld      de,hl +                ld      hl,bc +                xor     hl,-1 +                ld      bc,hl +                inc     de +                jr      nz,ItofResult +                inc     bc +                jr      nz,ItofResult + +Zero:           ld      bc,0 +                ld      de,bc +                jp      ItofResult      ; Ergebnis Null + +Over:           bit     7,h             ; Ergebnis positiv ? +                jr      z,OpPos +                ld      b,80h           ; MININT laden +                xor     a,a             ; A=0 +                ld      c,a +                ld      d,a +                ld      e,a +                jp      ItofResult +OpPos:          ld      b,7fh           ; MAXINT laden +                ld      a,0ffh +                ld      c,a +                ld      d,a +                ld      e,a +                jp      ItofResult + +                endp + +;------------------------------------------------------------------------------ +; Multiplikation mit Zweierpotenz (in A) + +                proc    fmul2 + +                link    ix,0            ; Stackrahmen aufbauen + +                push    af              ; Register retten +                push    hl + +                ld      de,(ix+Op2)     ; Operand 1 in Register laden +                ld      bc,(ix+Op2+2) + +                ld      h,a             ; Operand 2 nach H kopieren +                ld      l,b             ; Vorzeichen nach L, Bit 7 +                xor     a,a             ; A=0 +                cp      a,b             ; Operand 1 = Null ? +                jr      nz,NoZero +                cp      a,c +                jr      nz,NoZero +                cp      a,d +                jr      nz,NoZero +                cp      a,e +                jr      z,Zero + +NoZero:         sla     e               ; Operand 1 verschieben +                rl      d +                rl      c +                rl      b               ; Form: eeee eeee ffff ... fff0 +                jr      z,Den           ; Falls Exponent Null -->denormal + +                add     a,h             ; A=0+H +                jr      m,Div           ; Falls Op2<0-->Division +                add     a,b             ; A=Summe der Exponenten +                ld      b,a             ; zurck nach B +                jr      c,Over          ; bei šberlauf--> +                cp      a,MaxExpo       ; oder genau MaxExpo +                jr      z,Over + +Result:         sla     l               ; Vorzeichen in Carry schieben +                rr      b +                rr      c +                rr      d +                rr      e               ; Ergebnis zusammensetzen + +Zero:           pop     hl              ; Register zurck +                pop     af + +                unlk    ix              ; Stackrahmen abbauen +                retd    4               ; Ende + +Over:           ld      b,MaxExpo       ; šberlauf: Exponent=MaxExpo +                xor     a,a             ;           Mantisse=0 +                ld      c,a +                ld      d,a +                ld      e,a +                jr      Result + +Div:            add     a,b             ; A = Summe der Exponenten +                ld      b,a             ; zurck nach B +                jr      z,Div2 +                jr      p,Result        ; falls >0, Ergebnis abliefern +Div2:           scf                     ; implizite Eins real machen +                rr      c +                rr      d +                rr      e               ; Form: eeee eeee 1fff ... ffff + +Denorm:         xor     a,a             ; A = 0 +                cp      a,b             ; Exponent Null ? +                jr      z,Result        ; ja, ergebnis abliefern +                srl     c +                rr      d +                rr      e               ; Mantisse denormalisieren +                jr      nz,NoZero2 +                cp      a,d +                jr      nz,NoZero2 +                cp      a,c +                jr      nz,NoZero2 +                ld      b,a             ; totaler Unterlauf, Ergebnis = Null +                jr      Zero + +NoZero2:        inc     b               ; Exponent erh”hen +                jr      Denorm          ; weiter denormalisieren + +DDD:            add     a,b             ; Summe der Exponenten bilden +                ld      b,a             ; zurck nach B +                jr      Denorm + +Den:            add     a,h             ; A=0+H +                jr      m,DDD           ; bei Division verzweigen +NoOver:         sla     e               ; Multiplikation: Eine +                rl      d               ; denormalisierte Mantisse +                rl      c               ; wird wieder normalisiert +                jr      c,Stop          ; bis fhrende Eins rausfliegt +                dec     h               ; oder Operand 2 = Null +                jr      nz,NoOver +                jr      Result + +Stop:           ld      a,h             ; Summe der Exponenten bilden +                add     a,b +                ld      b,a             ; zurck nach B +                jr      Result + +                endp + +;------------------------------------------------------------------------------ +; Quadratwurzel ziehen + +                proc    fsqrt + +Op              equ     4               ; Lage Parameter +                DefLocal XRoot,4        ; Iterationsvariablen +                DefLocal m2,4 +                DefLocal xx2,4 + +                link    ix,LocalSize    ; Stackrahmen aufbauen + +                push    af              ; Register retten +                push    hl +                push    iy + +                bit     7,(ix+Op+3)     ; negatives Argument ? +                jp      nz,DomainError  ; dann Fehler + +                ld      hl,(ix+Op+2)    ; Exponent isolieren +                and     hl,07f80h +                jp      z,Zero          ; keine Behandlung denormaler Zahlen + +                ld      (ix+Op+3),0     ; Mantisse isolieren +                and     (ix+Op+2),7fh +                sub     hl,7fh*80h      ; Bias vom Exponenten entfernen +                ld      bc,hl +                bit     7,c             ; Exponent ungerade ? +                res     7,c +                jr      z,EvenExp +                ld      hl,(ix+Op)      ; ja: Mantisse verdoppeln +                add     hl,hl +                ld      (ix+Op),hl +                ld      hl,(ix+Op+2) +                adc     hl,hl +                add     hl,100h-80h     ; impl. Eins dazu +                ld      (ix+Op+2),hl +EvenExp: +                sra     b               ; Exponent/2 mit Vorzeichen +                rr      c +                ld      hl,7fh*80h      ; Bias wieder dazu +                add     hl,bc +                ld      iy,hl           ; Exponent in IY aufheben +                ld      de,(ix+Op+1)    ; x ausrichten (um 7 nach links) +                ld      a,(ix+Op+3)     ; oberstes Byte merken +                ld      (ix+Op+2),de    ; da wir hier eins zuviel schieben +                ld      d,(ix+Op) +                ld      e,0 +                ld      (ix+Op),de +                srla                    ; dieses Bit einschieben +                rr      (ix+Op+3) +                rr      (ix+Op+2) +                rr      (ix+Op+1) +                rr      (ix+Op) +                ld      de,0            ; vorbelegen +                ld      (ix+XRoot),de +                ld      (ix+m2),de +                ld      d,40h +                ld      (ix+XRoot+2),de +                ld      d,10h +                ld      (ix+m2+2),de +Loop10:         ld      de,(ix+Op)      ; xx2 = x +                ld      (ix+xx2),de +                ld      de,(ix+Op+2) +                ld      (ix+xx2+2),de +Loop11:         ld      hl,(ix+xx2)     ; xx2 -= xroot +                sub     hl,(ix+XRoot) +                ld      (ix+xx2),hl +                ld      hl,(ix+xx2+2) +                sbc     hl,(ix+XRoot+2) +                ld      (ix+xx2+2),hl +                srl     (ix+XRoot+3)    ; xroot /= 2 +                rr      (ix+XRoot+2) +                rr      (ix+XRoot+1) +                rr      (ix+XRoot) +                ld      hl,(ix+xx2)     ; xx2 -= m2 +                sub     hl,(ix+m2) +                ld      (ix+xx2),hl +                ld      hl,(ix+xx2+2) +                sbc     hl,(ix+m2+2) +                ld      (ix+xx2+2),hl +                jr      m,DontSet1 +                ld      hl,(ix+xx2)     ; x = xx2 +                ld      (ix+Op),hl +                ld      hl,(ix+xx2+2) +                ld      (ix+Op+2),hl +                ld      hl,(ix+XRoot)   ; xroot += m2 +                or      hl,(ix+m2) +                ld      (ix+XRoot),hl +                ld      hl,(ix+XRoot+2) +                or      hl,(ix+m2+2) +                ld      (ix+XRoot+2),hl +                ld      hl,(ix+m2)      ; m2 /= 4 +                ld      de,(ix+m2+2) +                rept    2 +                 srl    d +                 rr     e +                 rr     h +                 rr     l +                endm +                ld      (ix+m2),hl +                ld      (ix+m2+2),de +                or      hl,de +                jr      nz,Loop11 +                jr      IsSame +DontSet1:       ld      hl,(ix+m2)      ; m2 /= 4 +                ld      de,(ix+m2+2) +                rept    2 +                 srl    d +                 rr     e +                 rr     h +                 rr     l +                endm +                ld      (ix+m2),hl +                ld      (ix+m2+2),de +                or      hl,de +                jp      nz,Loop10       ; 15* abarbeiten +                                        ; Bit 22..8 +                ld      hl,(ix+Op)      ; 17. Iteration separat +                ld      (ix+xx2),hl +                ld      hl,(ix+Op+2) +                ld      (ix+xx2+2),hl +IsSame:         ld      hl,(ix+xx2) +                sub     hl,(ix+XRoot) +                ld      (ix+xx2),hl +                ld      hl,(ix+xx2+2) +                sbc     hl,(ix+XRoot+2) +                ld      (ix+xx2+2),hl +                ld      de,(ix+XRoot+2) ; mitsamt Carry... +                ld      hl,(ix+XRoot) +                srl     d +                rr      e +                rr      h +                rr      l +                jr      nc,NoC1 +                set     7,d +NoC1:           ld      (ix+XRoot+2),hl ; auf neues Alignment umstellen +                ld      (ix+XRoot),de +                decw    (ix+xx2)        ; Carry von 0-$4000: xx2 -= m2 +                jr      nz,NoC2 +                decw    (ix+xx2+2) +NoC2:           bit     7,(ix+xx2+3) +                jr      nz,DontSet7 +                or      (ix+xx2+3),0c0h ; 0-$4000: x2 -= m2, Teil 2 +                ld      hl,(ix+xx2) +                ld      (ix+Op),hl +                ld      hl,(ix+xx2+2) +                ld      (ix+Op+2),hl +                or      (ix+XRoot+1),40h; xroot += m2 +DontSet7:       ld      hl,(ix+Op)      ; x auf neues Alignment umstellen +                ld      de,(ix+Op+2) +                ld      (ix+Op),de +                ld      (ix+Op+2),hl +                ld      hl,1000h        ; m2 - obere H„lfte schon 0 +                ld      (ix+m2),hl +Loop20:         ld      hl,(ix+Op)      ; xx2 = x +                ld      (ix+xx2),hl +                ld      hl,(ix+Op+2) +                ld      (ix+xx2+2),hl +Loop21:         ld      hl,(ix+xx2)     ; xx2 -= xroot +                sub     hl,(ix+XRoot) +                ld      (ix+xx2),hl +                ld      hl,(ix+xx2+2) +                sbc     hl,(ix+XRoot+2) +                ld      (ix+xx2+2),hl +                srl     (ix+XRoot+3)    ; XRoot = XRoot/2 +                rr      (ix+XRoot+2) +                rr      (ix+XRoot+1) +                rr      (ix+XRoot) +                ld      hl,(ix+xx2)     ; x2 -= m2 +                sub     hl,(ix+m2) +                ld      (ix+xx2),hl +                ld      hl,(ix+xx2+2) +                sbc     hl,(ix+m2+2) +                ld      (ix+xx2+2),hl +                jr      m,DontSet2 +                ld      hl,(ix+xx2)     ; x = xx2 +                ld      (ix+Op),hl +                ld      hl,(ix+xx2+2) +                ld      (ix+Op+2),hl +                ld      hl,(ix+XRoot)   ; xroot += m2 +                or      hl,(ix+m2) +                ld      (ix+XRoot),hl +                ld      hl,(ix+XRoot+2) +                or      hl,(ix+m2+2) +                ld      (ix+XRoot+2),hl +                ld      hl,(ix+m2)      ; m2 /= 4 +                ld      de,(ix+m2+2) +                rept    2 +                 srl    d +                 rr     e +                 rr     h +                 rr     l +                endm +                ld      (ix+m2),hl +                ld      (ix+m2+2),de +                or      hl,de +                jr      nz,Loop21 +                jr      Finish +DontSet2:       ld      hl,(ix+m2)      ; m2 /= 4 +                ld      de,(ix+m2+2) +                rept    2 +                 srl    d +                 rr     e +                 rr     h +                 rr     l +                endm +                ld      (ix+m2),hl +                ld      (ix+m2+2),de +                or      hl,de +                jp      nz,Loop20       ; 7* abarbeiten + +Finish:         ld      hl,(ix+Op)      ; Aufrunden notwendig ? +                sub     hl,(ix+XRoot) +                ld      (ix+Op),hl +                ld      hl,(ix+Op+2) +                sub     hl,(ix+XRoot+2) +                ld      (ix+Op+2),hl +                jr      ule,NoInc +                incw    (ix+XRoot)      ; wenn ja, durchfhren +                jr      nz,NoInc +                incw    (ix+XRoot) +NoInc:          res     7,(ix+XRoot+2)  ; impl. Eins l”schen +                ld      hl,(ix+XRoot+2) ; Exponent einbauen +                or      hl,iy +                ld      bc,hl           ; Ergebnis in BC-DE +                ld      de,(ix+XRoot) +                jr      End + +DomainError:    ld      bc,0ffc0h       ; - NAN zuckgeben +                ld      de,0 +                jr      End + +Zero:           ld      bc,0            ; Ergebnis 0 +                ld      de,bc + +End:            pop     iy              ; Register zurck +                pop     hl +                pop     af + +                unlk    ix              ; Stackrahmen abbauen +                retd    4               ; Ende + +                endp + +;------------------------------------------------------------------------------ +; Zehnerpotenz bilden + +                subproc fPot10 + +                push    ix              ; Register retten +                push    iy +                push    hl + +                ld      bc,(One+2)      ; Ausgangspunkt frs Multiplizieren +                ld      de,(One) +                ld      ix,(Ten+2)      ; zu benutzende Potenz +                ld      iy,(Ten) +                or      hl,hl           ; negative Potenz? +                jr      p,IsPos +                ld      ix,(Tenth+2)    ; dann eben mit Zehntel +                ld      iy,(Tenth) +                xor     hl,-1           ; Zweierkomplement +                inc     hl +IsPos: +                or      hl,hl           ; weiter multiplizieren ? +                jr      z,End           ; nein, Ende +                bit     0,l             ; Restpotenz ungerade ? +                jr      z,IsEven +                push    bc              ; ja: einzeln multiplizieren +                push    de +                push    ix +                push    iy +                call    fmul +IsEven:         srl     h +                rr      l +                push    bc              ; n„chste Potenz berechnen +                push    de +                push    ix              ; durch quadrieren +                push    iy +                push    ix +                push    iy +                call    fmul +                ld      ix,bc +                ld      iy,de +                pop     de +                pop     bc +                jr      IsPos           ; weitersuchen +End: +                pop     hl              ; Register zurck +                pop     iy +                pop     ix + +                ret                     ; Ende + +                endp + +;------------------------------------------------------------------------------ + +                subproc fOutDec + +Op              equ     6               ; Adresse Operand +Format          equ     4               ; Formatdeskriptor +                DefLocal Temp,4         ; 64-Bit-Erweiterung Divident + +                link    ix,LocalSize + +                push    af              ; Register retten +                push    bc +                push    de +                push    hl + +                bit     7,(ix+Op+3)     ; negativ ? +                jr      z,IsPos +                ld      (iy),'-'        ; ja: vermerken... +                inc     iy +                ld      hl,(ix+Op)      ; ...und Zweierkomplement +                xor     hl,-1 +                ld      (ix+Op),hl +                ld      hl,(ix+Op+2) +                xor     hl,-1 +                ld      (ix+Op+2),hl +                incw    (ix+Op) +                jr      nz,GoOn +                incw    (ix+Op+2) +                jr      GoOn +IsPos:          bit     7,(ix+Format+1) ; Pluszeichen ausgeben ? +                jr      nz,GoOn +                ld      (iy),'+' +                inc     iy +GoOn:           res     7,(ix+Format+1) ; Plusflag l”schen +                ld      de,0            ; Nullflag & Z„hler l”schen + +InLoop:         ld      hl,0            ; Division vorbereiten +                ld      (ix+Temp),hl    ; dazu auf 64 Bit erweitern +                ld      (ix+Temp+2),hl +                ld      b,32            ; 32-Bit-Division +DivLoop:        sll     (ix+Op)         ; eins weiterschieben +                rl      (ix+Op+1) +                rl      (ix+Op+2) +                rl      (ix+Op+3) +                rl      (ix+Temp) +                rl      (ix+Temp+1) +                rl      (ix+Temp+2) +                rl      (ix+Temp+3) +                srl     (ix+Op)         ; fr nachher +                ld      hl,(ix+Temp)    ; probeweise abziehen +                sub     hl,10 +                ld      (ix+Temp),hl +                ld      hl,(ix+Temp+2) +                sbc     hl,0 +                ld      (ix+Temp+2),hl +                jr      nc,DivOK        ; paát es ? +                ld      hl,(ix+Temp)    ; nein, zurcknehmen +                add     hl,10 +                ld      (ix+Temp),hl +                ld      hl,(ix+Temp+2) +                adc     hl,0 +                ld      (ix+Temp+2),hl +                scf                     ; ins Ergebnis 0 einschieben +DivOK:          ccf                     ; neues Ergebnisbit +                rl      (ix+Op)         ; von unten einschieben +                djnz    DivLoop + +                ld      a,(ix+Temp)     ; ASCII-Offset addieren +                add     a,'0' +                bit     0,d             ; schon im Nullbereich ? +                jr      z,NormVal +                ld      a,(ix+Format)   ; ja, dann gewnschtes Leerzeichen +NormVal:        push    af              ; auf LIFO legen +                inc     e               ; ein Zeichen mehr +                ld      a,(ix+Op)       ; Quotient Null ? +                or      a,(ix+Op+1) +                or      a,(ix+Op+2) +                or      a,(ix+Op+3) +                ld      d,0             ; Annahme: nicht Null +                jr      nz,InLoop       ; falls <>0, auf jeden Fall weiter +                ld      d,0ffh          ; Flag auf True setzen +                ld      a,e             ; ansonsten nur weiter, falls minimale +                cp      a,(ix+Format+1) ; Zahl noch nicht erreicht +                jr      ult,InLoop + +                ld      b,e             ; jetzt Zeichen ausgeben +OutLoop:        pop     af +                ld      (iy),a +                inc     iy +                djnz    OutLoop + +                pop     hl              ; Register zurck +                pop     de +                pop     bc +                pop     af + +                unlk    ix +                retd    6 + +                endp + +;------------------------------------------------------------------------------ +; Wandlung Float-->ASCII + +                proc    fftoa + +Op              equ     8               ; Lage Eingabe auf Stack +Format          equ     6               ; Lage Formatdeskriptor auf Stack +Buffer          equ     4               ; Pufferadresse +                DefLocal Copy,4         ; Tempor„rkopie der Zahl +                DefLocal ExpSave,2      ; berechneter Exponent + +                link    ix,LocalSize    ; Platz fr Exponenten/Kopie der Zahl + +                push    af              ; Register retten +                push    de +                push    iy +                push    hl + +                ld      iy,(ix+Buffer)  ; Pufferadresse holen + +                ld      hl,(ix+Op)      ; Zahl kopieren +                ld      (ix+Copy),hl +                ld      hl,(ix+Op+2) +                res     7,h             ; dabei Vorzeichen l”schen +                ld      (ix+Copy+2),hl + +                ld      a,'+'           ; Annahme positiv +                sll     (ix+Op)         ; Vorzeichen herausschieben +                rl      (ix+Op+1)       ; und in Carry bringen +                rl      (ix+Op+2) +                rl      (ix+Op+3) +                jr      c,IsNeg         ; Minuszeichen immer erforderlich +                bit     0,(ix+Format+1) ; Pluszeichen dagegen optional +                jr      nz,NoMantSgn +                jr      WrMantSgn +IsNeg:          ld      a,'-'           ; negative Zahl +WrMantSgn:      ld      (iy),a          ; Vorzeichen ablegen +                inc     iy +NoMantSgn: +                ld      l,(ix+Op+3)     ; Exponent herausholen... +                ld      h,0             ; ...auf 16 Bit erweitern... +                ld      bc,(ix+Op+1)    ; ...und in Quelle l”schen +                ld      (ix+Op+2),bc +                ld      b,(ix+Op) +                ld      c,0 +                ld      (ix+Op),bc + +                cp      hl,MaxExpo      ; Sonderwerte ? +                jp      z,SpecialVals   ; ja--> + +                or      hl,hl           ; Zahl denormal ? +                jr      nz,IsNormal     ; nein, normal weiter +                ld      a,(ix+Op+3)     ; falls Mantisse Null, +                or      a,(ix+Op+2)     ; nicht normalisieren +                or      a,(ix+Op+1) +                jr      z,IsNull +Normalize:      sll     (ix+Op+1)       ; ansonsten schieben, bis fhrende +                rl      (ix+Op+2)       ; Eins da +                rl      (ix+Op+3) +                jr      c,IsNormal +                dec     hl +                jr      Normalize +IsNormal:       sub     hl,Bias         ; Bias abziehen +IsNull: +                ld      b,h             ; Zweierexponenten in Float wandeln +                ld      c,h +                push    bc +                push    hl +                call    fitof +                push    bc              ; in Dezimalexponenten wandeln +                push    de +                cpsh    bc,Ld10 +                call    fdiv +                bit     7,b             ; Zahl negativ ? +                jr      z,NoCorr +                push    bc              ; dann noch eins abziehen wegen +                push    de              ; unterer Gauáklammer +                cpsh    bc,One +                call    fsub +NoCorr:         push    bc              ; den Ausflug in Float beenden +                push    de +                call    fftoi +                ld      (ix+ExpSave),de ; Exponenten retten + +                ld      bc,(ix+Copy+2)  ; Originalzahl +                push    bc +                ld      bc,(ix+Copy) +                push    bc +                ld      hl,de           ; durch die Zehnerpotenz +                call    fPot10          ; des Exponenten +                push    bc +                push    de +                call    fdiv            ; teilen +Again:          ld      (ix+Copy),de    ; Ergebnis zwischen 1...9,999 retten +                ld      (ix+Copy+2),bc +                push    bc              ; Vorkommastelle berechnen +                push    de +                call    fftoi +                cp      e,10            ; doch etwas drber ? +                jr      ult,NoRoundErr +                ld      bc,(ix+Copy+2)  ; dann nocheinmal zehnteln +                push    bc +                ld      bc,(ix+Copy) +                push    bc +                cpsh    bc,Tenth +                call    fmul +                incw    (ix+ExpSave) +                jr      Again +NoRoundErr:     add     e,'0'           ; Vorkommastelle nach ASCII +                ld      (iy),e          ; ablegen +                inc     iy +                sub     e,'0'           ; wieder rckg„ngig machen +                cp      (ix+Format),0   ; gar keine Nachkommastellen ? +                jr      eq,NoComma +                ld      (iy),'.'        ; Dezimalpunkt ausgeben +                inc     iy +                push    bc              ; Vorkomma nach Float wandeln +                push    de +                call    fitof +                push    bc +                push    de +                cpsh    bc,ix+Copy      ; von alter Zahl abziehen +                call    fsub +                xor     b,80h           ; war verkehrtherum +                push    bc              ; zum Skalieren auf Stack +                push    de +                ld      l,(ix+Format)   ; passende Skalierungskonstante ausrechnen +                ld      h,0 +                call    fPot10 +                push    bc +                push    de +                call    fmul            ; hochskalieren +                push    bc              ; Rundung +                push    de +                cpsh    bc,Half +                call    fadd +                push    bc              ; Stellen nach Integer +                push    de +                call    fftoi +                push    bc              ; entspr. ausgeben +                push    de +                ld      b,(ix+Format)   ; Format fr fOutDec aufbauen +                set     7,b             ; kein Pluszeichen +                ld      c,'0'           ; Fllzeichen Nullen +                push    bc +                call    fOutDec +                bit     5,(ix+Format+1) ; Nullen am Ende abr„umen ? +                jr      nz,CleanZeros +NoComma: +                ld      a,(ix+Format+1) ; falls Minimalstellenzahl Exponent=0 +                and     a,00011100b     ; und Exponent=0, vergessen +                or      a,(ix+ExpSave) +                or      a,(ix+ExpSave+1) +                jr      z,End + +                ld      (iy),'E'        ; Exponenten ausgeben +                inc     iy +                ld      hl,(ix+ExpSave) +                ld      b,h +                ld      c,h +                push    bc +                push    hl +                ld      c,'0'           ; evtl. vornullen +                ld      b,(ix+Format+1) +                rrc     b               ; Bit 1-->Bit 7 +                rrc     b +                and     b,87h +                push    bc +                call    fOutDec + +End:            ld      (iy),0          ; NUL-Zeichen als Terminierer +                ld      de,iy           ; Endezeiger nach DE +                pop     hl              ; Register zurck +                pop     iy +                ex      de,hl           ; zur Subtraktion tauschen +                sub     hl,de           ; = Zahl geschriebener Zeichen +                ex      de,hl           ; HL wieder original +                ld      bc,de           ; Ergebnis nach BC +                pop     de +                pop     af + +                unlk    ix              ; Stackrahmen abbauen +                retd    8               ; Ende + +SpecialVals:    ld      a,(ix+Op+3)     ; Mantisse Null ? +                or      a,(ix+Op+2) +                or      a,(ix+Op+1) +                jr      nz,IsNAN +                ld      (iy),'I'        ; ja: Unendlichkeit +                ld      (iy+1),'N' +                ld      (iy+2),'F' +                add     iy,3 +                jr      End +IsNAN:          ld      (iy),'N'        ; nein: NAN +                ld      (iy+1),'A' +                ld      (iy+2),'N' +                add     iy,3 +                jr      End + +CleanZeros:     cp      (iy-1),'0'      ; Null am Ende ? +                jr      nz,CleanNoZero  ; nein, Ende +                dec     iy              ; ja: Z„hler runter, so daá ber- +                jr      CleanZeros      ; schrieben wird und neuer Versuch +CleanNoZero:    cp      (iy-1),'.'      ; evtl. Komma entfernbar ? +                jr      nz,Ready        ; nein--> +                dec     iy              ; ja: noch ein Zeichen weniger +Ready:          jrl     NoComma + +                endp + +;------------------------------------------------------------------------------ +; Wandlung ASCII-->Float + +                proc    fatof + +SrcAddr         equ     4               ; Lage Parameter auf Stack +                DefLocal Flags,2        ; Steuerflags +                DefLocal Exp,2          ; Speicher Exponent +                DefLocal Mant,4         ; Speicher fr Mantissenzwischenwert +                DefLocal Factor,4       ; Speicher fr Zehnerpotenz + +                link    ix,LocalSize    ; Stackrahmen aufbauen + +                push    af              ; Register retten +                push    hl +                push    iy + +                ld      iy,(ix+SrcAddr) ; Zeigeradresse laden +                ld      (ix+Flags),01h  ; Phase 1 (Mantisse), noch kein Vorzeichen +                ld      (ix+Flags+1),0 +                ld      bc,(Ten)        ; in der Mantisse mit 10 hochmultiplizieren +                ld      (ix+Factor),bc +                ld      bc,(Ten+2) +                ld      (ix+Factor+2),bc +                ld      bc,0            ; Exponent mit 0 vorbelegen +                ld      (ix+Exp),bc +                ld      (ix+Mant),bc    ; Mantisse auch +                ld      (ix+Mant+2),bc + +ReadLoop:       ld      a,(iy)          ; ein neues Zeichen holen +                inc     iy + +                cp      a,0             ; Endezeichen ? +                jp      eq,Combine      ; ja, zusammenbauen + +                cp      a,' '           ; Leerzeichen ignorieren +                jr      eq,ReadLoop + +                cp      a,'+'           ; Pluszeichen gnadenhalber zulassen +                jr      ne,NoPlus       ; ist aber nur ein Dummy +                bit     0,(ix+Flags+1)  ; schon ein Vorzeichen dagewesen ? +                jp      nz,Error        ; dann Fehler +                set     0,(ix+Flags+1)  ; ansonsten einfach setzen +                jr      ReadLoop +NoPlus: +                cp      a,'-'           ; Minuszeichen bewirkt schon eher etwas +                jr      ne,NoMinus +                bit     0,(ix+Flags+1)  ; darf auch nur einmal auftreten +                jp      nz,Error +                set     0,(ix+Flags+1) +                cp      (ix+Flags),1    ; je nach Phase anderes Flag setzen +                jr      ne,MinPhase3 +                set     1,(ix+Flags+1)  ; bei Mantisse Bit 1... +                jr      ReadLoop +MinPhase3:      set     2,(ix+Flags+1)  ; ...bei Exponent Bit 2 +                jr      ReadLoop +NoMinus: +                cp      a,'.'           ; Umschaltung Phase 2 (Nachkomma) ? +                jr      ne,NoPoint +                cp      (ix+Flags),1    ; bish. Phase muá Eins sein +                jp      ne,Error +                ld      (ix+Flags),2    ; neue Phase eintragen +                set     0,(ix+Flags+1)  ; Nachkomma darf kein Vorzeichen haben +                ld      bc,(Tenth)      ; im Nachkomma durch 10 teilen +                ld      (ix+Factor),bc +                ld      bc,(Tenth+2) +                ld      (ix+Factor+2),bc +                jr      ReadLoop +NoPoint: +                cp      a,'e'           ; kleines & groáes E zulassen +                jr      eq,IsE +                cp      a,'E' +                jr      ne,NoE +IsE:            cp      (ix+Flags),3    ; vorh. Phase muá 1 oder 2 sein +                jp      eq,Error +                ld      (ix+Flags),3    ; vermerken +                res     0,(ix+Flags+1)  ; Vorzeichen wieder zulassen +                jr      ReadLoop +NoE: +                sub     a,'0'           ; jetzt nur noch 0..9 zugelassen +                jp      c,Error +                cp      a,9 +                jp      ugt,Error +                set     0,(ix+Flags+1)  ; nach Ziffern keine Vorzeichen mehr zulassen + +                cp      (ix+Flags),1    ; Phase 1 (Mantisse) : +                jr      ne,NoPhase1 +                cpsh    bc,ix+Mant      ; bish. Mantisse * 10 +                cpsh    bc,ix+Factor +                call    fmul +                push    bc              ; Ziffer dazuaddieren +                push    de +                ld      e,a +                ld      d,0 +                ld      bc,0 +                push    bc +                push    de +                call    fitof +                push    bc +                push    de +                call    fadd +                ld      (ix+Mant),de    ; Mantisse zurcklegen +                ld      (ix+Mant+2),bc +                jrl     ReadLoop +NoPhase1: +                cp      (ix+Flags),2    ; Phase 2 (Nachkomma) : +                jr      nz,NoPhase2 +                ld      e,a             ; Stelle nach Float +                ld      d,0 +                ld      bc,0 +                push    bc +                push    de +                call    fitof +                push    bc              ; mit Zehnerpotenz skalieren +                push    de +                cpsh    bc,ix+Factor +                call    fmul +                push    bc              ; zur Mantisse addieren +                push    de +                cpsh    bc,ix+Mant +                call    fadd +                ld      (ix+Mant),de    ; Mantisse zurcklegen +                ld      (ix+Mant+2),bc +                cpsh    bc,ix+Factor    ; Faktor * 1/10 +                cpsh    bc,Tenth +                call    fmul +                ld      (ix+Factor),de +                ld      (ix+Factor+2),bc +                jrl     ReadLoop +NoPhase2: +                ld      hl,(ix+Exp) +                mul     hl,10           ; Exponent heraufmultiplizieren +                add     a,l +                ld      l,a +                ld      a,0 +                adc     h,0 +                cp      hl,45           ; Minimum ist 1E-45 +                jr      ugt,Error +                ld      (ix+Exp),hl +                jrl     ReadLoop + +Combine:        ld      hl,(ix+Exp) +                bit     2,(ix+Flags+1)  ; Exponent negativ ? +                jr      z,ExpPos +                xor     hl,-1 +                inc     hl +ExpPos:         call    fPot10          ; Zehnerpotenz des Exponenten bilden +                push    bc +                push    de +                cpsh    bc,ix+Mant      ; mit Mantisse kombinieren +                call    fmul +                bit     1,(ix+Flags+1)  ; Mantisse negativ ? +                jr      z,ManPos +                set     7,b +ManPos:         rcf                     ; Ende ohne Fehler + +End:            pop     iy              ; Register zurck +                pop     hl +                pop     af + +                unlk    ix              ; Rahmen abbauen +                retd    2               ; Ende + +Error:          ld      hl,iy           ; rel. Zeichenposition ermitteln +                sub     hl,(ix+SrcAddr) +                ld      bc,hl +                scf                     ; Ende mit Fehler +                jr      End + +                endp + +;------------------------------------------------------------------------------ +; gemeinsames Ende + +                endsection + diff --git a/tests/t_fl90/macros.inc b/tests/t_fl90/macros.inc new file mode 100644 index 0000000..d949ddc --- /dev/null +++ b/tests/t_fl90/macros.inc @@ -0,0 +1,57 @@ +; MACROS.INC +;****************************************************************************** +;* überall gebrauchte Makros                                                  * +;*                                                                            * +;* Alfred Arnold, Oktober 1993                                                * +;****************************************************************************** + +proc            macro   name,{NoExpand} ; Prozedureintritt +                section name +                forward LocalSize       ; lokal reservierter Speicher auf Stack +LocalSize       eval    0 +                public  name +name            label   $ +                endm + +subproc         macro   name,{NoExpand} ; Prozedureintritt für private Routine +                section name +                forward LocalSize       ; lokal reservierter Speicher auf Stack +LocalSize       eval    0 +                public  name:Parent +name            label   $ +                endm + +endp            macro   name,{NoExpand} ; Prozeduraustritt +LocalSize       eval    0-LocalSize     ; damit man's im Listing lesen kann +                endsection name +                endm + +link            macro   reg,count,{NoExpand} ; Stack-Rahmen einrichten +                push    reg             ; alten Basepointer retten +                ld      reg,sp          ; neuen aufbauen +                if      count<>0 +                 add    sp,count        ; Platz auf Stack reservieren +                endif +                endm + +unlk            macro   reg,{NoExpand}  ; Stack-Rahmen abbauen +                ld      sp,reg          ; Speicherreservierung zurücknehmen +                pop     reg             ; alten Basepointer zurück +                endm + +retd            macro   dist,{NoExpand} ; Return and Deallocate +                if      dist<>0 +                 push   hl              ; Arbeitsregister retten +                 ld     hl,(sp+2)       ; Rücksprungadresse umkopieren +                 ld     (sp+2+dist),hl +                 ld     hl,(sp)         ; Arbeitsregister zurück +                 add    sp,2+dist       ; Stack aufräumen +                endif +                ret +                endm + +DefLocal        macro   Name,Size,{NoExpand} ; eine lokale Variable definieren +LocalSize       eval    LocalSize-Size  ; zählt lok. reservierten Speicher +Name            equ     LocalSize       ; liegt an neuem unteren Ende des Stackrahmens +                endm + diff --git a/tests/t_fl90/mon.inc b/tests/t_fl90/mon.inc new file mode 100644 index 0000000..46e08d3 --- /dev/null +++ b/tests/t_fl90/mon.inc @@ -0,0 +1,11 @@ +MRET    EQU     0080H           ;  RETURN TO MONITOR +CONIN	EQU	0083H		;  CONSOLE INPUT +COSTAT	EQU	0086H		;  CONSOLE STATUS +CONOUT	EQU	0089H		;  CONSOLE OUTPUT +TXTAUS	EQU	008CH		;  TEXT-OUTPUT +PSTR	EQU	008FH		;  STRING OUTPUT +A_ASC	EQU	0092H		;  CONVERT CONTENT OF A TO ASCII  +HL_ASC	EQU	0095H		;  CONVERT CONTENT OF HL TO ASCII +BLAUS	EQU	0098H		;  BLANK OUTPUT +GETZEIL	EQU	009BH		;  READ LINE	 + diff --git a/tests/t_fl90/t_fl90.asm b/tests/t_fl90/t_fl90.asm new file mode 100644 index 0000000..3e53195 --- /dev/null +++ b/tests/t_fl90/t_fl90.asm @@ -0,0 +1,179 @@ +; FTEST.ASM +;****************************************************************************** +;* Testet Gleitkommabibliothek für TLCS90                                     * +;*                                                                            * +;* Hardware: TDB-TMP90                                                        * +;* Software: AS 1.39p5 oder höher                                             * +;*           Includes MACROS.INC, FLOAT.INC, CPU_TIME.INC                     * +;*                                                                            * +;* Übersetzen mit AS ftest oder beiliegendem Makefile                         * +;*                                                                            * +;****************************************************************************** + +                cpu     90c141 + +                org     8500h           ; Startadresse User-RAM + +;------------------------------------------------------------------------------ + +CR              equ     13 +LF              equ     10 +Format_Tab      equ     0000100000000110b ; fftoa-Format für tab. Ausgabe +Format_Min      equ     0010001100000101b ; fftoa-Format für minimale Länge +;                         ^<+>^^<--+---> +;                         | | ||   | +;                         | | ||   +------ Maximalzahl Nachkommastellen +;                         | | |+---------- Mantissenpluszeichen unterdrücken +;                         | | +----------- Exponentenpluszeichen unterdrücken +;                         | +------------- Minimalstellenzahl Exponent +;                         +--------------- anhängende Nullen in Mantisse löschen +Format          equ     Format_Tab      ; gewähltes fftoa-Format + +;------------------------------------------------------------------------------ +; Vorgaben + +                include stddef90.inc    ; Registeradressen +                include macros.inc      ; für Unterroutinen benötigte Makros +                include mon.inc         ; Einsprungadressen TDBTMP90-Monitor + +                section MainProg + +;------------------------------------------------------------------------------ +; Makros zur Schreiberleichterung + +pushop          macro   adr,{NoExpand}  ; einen Operanden auf den Stack legen +                ld      hl,(adr+2) +                push    hl +                ld      hl,(adr) +                push    hl +                endm + +storeop         macro   {NoExpand}      ; Ergebnis in Array ablegen +                ld      (iy),de +                ld      (iy+2),bc +                add     iy,4 +                endm + +OneOp           macro   Msg,Operation,Op1,Op2,{Expand}  ; Aufruf, Ausgabe und +                call    PSTR                              ; Zeitmessung +                db      Msg,0 +                call    StartTimer +                if      "OP1"<>"" +                 pushop Op1 +                endif +                if      "OP2"<>"" +                 pushop Op2 +                endif +                call    Operation +                storeop +                call    StopTimer +                if      (("OPERATION"<>"FNOP") && ("OPERATION"<>"FFTOI")) +                 call    PSTR +                 db      ", Ergebnis ",0 +                 push    bc +                 push    de +                 ld      hl,Format +                 push    hl +                 ld      hl,CharBuffer +                 push    hl +                 call    fftoa +                 call    TXTAUS +                endif +                call    PSTR +                db      CR,LF,0 +                endm + +;------------------------------------------------------------------------------ +; Hauptroutine + +                proc    Main + +                ld      sp,Stack        ; Stack reservieren +                ld      iy,Erg          ; Zeiger auf Ergebnisfeld +                call    InitTimer       ; Zeitmessung vorinitialisieren + +                OneOp   "Ladeoverhead         : ",fnop,Eins,Eins +                OneOp   "Addition 2+Pi        : ",fadd,Zwei,Pi +                OneOp   "Addition 100000+2    : ",fadd,Thou,Zwei +                OneOp   "Addition 0+1         : ",fadd,Null,Eins +                OneOp   "Subtraktion Pi-2     : ",fsub,Pi,Zwei +                OneOp   "Subtraktion 100000-1 : ",fsub,Thou,Eins +                OneOp   "Multiplikation 2*Pi  : ",fmul,Zwei,Pi +                OneOp   "Division 1/Pi        : ",fdiv,Eins,Pi +                OneOp   "Wurzel aus 2         : ",fsqrt,Zwei, +                OneOp   "Wurzel aus 10000     : ",fsqrt,Thou, +                OneOp   "Wurzel aus -1        : ",fsqrt,MinEins, +                OneOp   "Wandlung 1-->Float   : ",fitof,IntEins, +                OneOp   "Wandlung 1E5-->Float : ",fitof,IntThou, +                OneOp   "Wandlung 1-->Int     : ",fftoi,Eins, +                OneOp   "Wandlung 1E5-->Int   : ",fftoi,Thou, +                ld      a,10 +                OneOp   "Pi*2^10              : ",fmul2,Pi, +                ld      a,-10 +                OneOp   "Pi*2^(-10)           : ",fmul2,Pi, + +                call    PSTR +                db      "Eingabe: ",0 +                ld      hl,InpBuffer +                call    TXTAUS +                ld      hl,InpBuffer +                push    hl +                call    fatof +                storeop +                call    PSTR +                db      ", Ergebnis: ",0 +                push    bc +                push    de +                ld      hl,Format +                push    hl +                ld      hl,CharBuffer +                push    hl +                call    fftoa +                call    TXTAUS +                call    PSTR +                db      13,10,0 + +                jp      MRET + +                endp + +                proc    fnop            ; Dummyroutine fr Overheadmessung + +                link    ix,0 +                unlk    ix + +                retd    8 + +                endp + +CharBuffer:     db      30 dup (?)      ; Puffer fr fftoa +InpBuffer:      db      "-123.456E-7",0 ; Puffer fr fatof + +                align   4 +Eins:           dd      1.0             ; ben”tigte Konstanten +MinEins:        dd      -1.0 +Zwei:           dd      2.0 +Pi:             dd      40490fdbh	; um Vergleichsfehler durch Rundung zu +                                        ; vermeiden +Zehn:           dd      10.0 +Null:           dd      0.0 +Thou:           dd      100000.0 +IntEins:        dd      1 +IntThou:        dd      100000 +Erg:            dd      40 dup (?)      ; Ergebnisfeld + +                align   2               ; Platz fr Stack +                db      300 dup (?) +Stack: +                endsection + +;------------------------------------------------------------------------------ +; ben”tigte Module + +                include cpu_time.inc     ; Zeitmessung +                include float.inc        ; Gleitkommabibliothek + +;------------------------------------------------------------------------------ + +                end     Main + diff --git a/tests/t_fl90/t_fl90.doc b/tests/t_fl90/t_fl90.doc new file mode 100644 index 0000000..668986f --- /dev/null +++ b/tests/t_fl90/t_fl90.doc @@ -0,0 +1,6 @@ ++------------------------  Test Application FL90 -----------------------------+ +|                                                                             | +|  This is an IEEE single precision floating point library for the Toshiba    | +|  TLCS-90 microcontroller, embedded into a small test program.               | +|                                                                             | ++-----------------------------------------------------------------------------+ diff --git a/tests/t_fl90/t_fl90.ori b/tests/t_fl90/t_fl90.oriBinary files differ new file mode 100644 index 0000000..4aff532 --- /dev/null +++ b/tests/t_fl90/t_fl90.ori | 
