                         TURBO Pascal 3.0 Projekte

    --------------------------------------------------------------------

    TURBO PASCAL Run Time Error

    Nach dem Motto "Keine Software ist fehlerfrei" besitzt auch CP/M-80
    TURBO Pascal 3.0 einige Bugs, die leider nicht als Features
    durchgehen knnen. Neben einigen Publikationen zu diesem Thema habe
    ich einen bisher nirgends beschriebenen Fehler gefunden, der schon
    recht kurios ist.
    Aufgetreten ist dieser Fehler bei mir, als ich versuchte, den freien
    Speicher nicht als negative Zahl, wie von der Funktion memavail
    geliefert, wenn viel Speicher frei ist, sondern als positive Zahl zu
    erhalten. Der Trick ist die folgende Anweisung:

                if memavail<0 then mfree:=65536.0+memavail
                              else mfree:=memavail;

    Hierbei ist die Variable mfree vom Typ real. Die Korrektur mit der
    Konstanten 65536.0 erfolgt bei negativer integer Zahl, also im
    Breich $8000..$FFFF. Hierbei ist $FFFF -1, also steht in mfree
    65535, was ja richtig ist.
    Nun zum Fehler: Bei einem einzigen Wert von memavail hngt sich der
    Rechner auf! Dieser Wert ist $8000. Ich habe mir mal den Code
    angeschaut und im Compiler bei Adresse $1008 die Funktion gefunden,
    die eine integer in eine real Zahl wandelt und fr den Hnger
    verantwortlich ist.
    Diese Funktion sieht wie folgt aus:

    ;
    ; Adresse $1008
    ;
    int2real:
            ld      a,h             ; Test ob integer=0
            or      l
            jp      z,int.0         ; Wenn ja, real Resultat Null setzen
            bit     7,h             ; Test ob integer<0
            ex      af,af'          ; Vorzeichen merken
            call    absNEG          ; Integer absolut (nur positiv)
            ld      a,90h           ; Startexponent laden
    i2r.loop:
            add     hl,hl           ; Integer solange links schieben
            dec     a
            bit     7,h             ; Bis das hoechste Bit gesetzt ist
            jr      z,i2r.loop
            ld      b,h             ; Resultat holen
            ld      c,l
            ld      de,0
            ld      h,d
            ld      l,a
            ex      af,af'          ; Altes Vorzeichen holen
            ret     nZ              ; War negativ
            res     7,b             ; Real positiv machen
            ret

    Die Routine, die ich "int.0" genannt habe, findet sich in Adresse
    $07b2 des Compilers:

    ;
    ; Adresse $0b72
    ;
    int.0:
            xor     a
            ld      l,a             ; Real Resultat auf Null setzen
            ld      b,a
            ld      c,a
            ld      d,a
            ld      e,a
            ld      h,a
            ret

    Diese Routine sieht problemlos aus. Was ist nun mit der von mir
    genannten Routine "absNEG" ?

    ;
    ; Adresse $0780
    ;
    absNEG:
            bit     7,h             ; Test Vorzeichen
            ret     z               ; Ende bei $0000..$7FFF
            ld      a,h             ; Negative Zahl bilden
            cpl                     ; als $8000..$FFFF -> $8000..$0001
            ld      h,a
            ld      a,l
            cpl
            ld      l,a
            inc     hl
            ret

    Hier fllt auf, da ausgerechnet die Zahl, bei der der Rechner
    hngt, sowohl negativ als auch positiv identisch ist. Und hier liegt
    das Problem. In der Routine "int2real" wird HL links geschoben und
    dann getestet, ob das Bit 7 vom Register H gesetzt ist. Falls nicht,
    wird weitergeschoben.
    Schiebt man den Wert $8000 links, dann erhlt man $0000 ! Jetzt kann
    man lange schieben, bis man das Bit 7 findet, es ist kein Bit mehr
    da !
    Klar, da der Rechner hngt.

    Will man dieses Problem beseitigen, so bleibt nur ein Patch, der
    erst das Bit prft und dann schiebt. Leider reicht der vorhandene
    Platz der Routine nicht aus, so da ein freien Platz gesucht werden
    mu. Die gepatchte Routine knnte wie folgt aussehen:

    ;
    ; Adresse $1008
    ;
    int2real:
            ld      a,h
            or      l
            jp      z,int.0
            bit     7,h
            ex      af,af'
    ;
    ; #### PATCH ####
    ;
            call    i2r.patch
    i2r.loop:
            bit     7,h             ; Bit testen
            jr      nz,i2r.ex       ; Ende wenn gesetzt
            add     hl,hl           ; Nun schieben
            dec     a
            jr      i2r.loop
    i2r.ex:
    ;
    ; #### PATCH ENDE ####
    ;
            ld      b,h
            ld      c,l
            ld      de,0
            ld      h,d
            ld      l,a
            ex      af,af'
            ret     nz
            res     7,b
            ret

    Es fehlt genau ein Byte !! den Patch habe ich bei mir in Aresse
    $0106 des Compilers gepackt, dort steht nur ein Copyright Hinweis:

    ;
    ; Adresse $0106
    ;
    i2r.patch:
            call    absNEG
            ld      a,90h
            ret

    Fr alle, die diesen Patch einfahren wollen, hier die Anweisungen
    fr SID:

    x>SID TURBO.COM                 # SID aufrufen, TURBO.COM laden
    CP/M 3 SID - Version 3.0
    NEXT MSZE  PC  END
    7980 7980 0100 D1FF
    #S106                           # Angabe fr nderung
    0106 6F CD                      # Werte ndern
    0107 70 80
    0108 79 07
    0109 72 3E
    010A 69 90
    010B 67 C9
    0108 68 .                       # nderung fertig
    #S1011                          # Zweiter Teil
    1011 80 06
    1012 07 01
    1013 3E CB
    1014 90 7C
    1015 29 20
    1016 3D 04
    1017 CB 29
    1018 7C 3D
    1019 28 18
    101A FA F8
    101B 44 .                       # Ende
    #WTURBOP.COM                    # Neue Datei TURBOP.COM schreiben
    00F1h record(s) written.
    #^C                             # Ende
    x>

    --------------------------------------------------------------------
    Um das Tipseln im SID berflssig zu machen, hier eine SUBMIT Datei,
    die das automatisch macht.
    --------------------------------------------------------------------

    Abgedruckt in Klubzeitung Nr. 55 - Mrz 1999.    Autor: Werner
    Cirsovius
                                                                    [Image]
