MILC logo

IndexVorigeVolgendeLeeg

Math-pack info v2.00 [1/2]
Jan vd Meer, 00-00-94


    
 #############################################################################
 ##                                                                         ##
 ##                     MATH-PACK info - versie #2.00                       ##
 ##                                                                         ##
 #############################################################################

MPNED20.TXT (c) 1994 MCCM/WR/JvdM


Met deze tekst be”gen wij een zo compleet mogelijk overzicht te geven van
de officiele routines van de MATH-PACK (MP) en, in een later stadium, 
andere bruikbare aan de MP gerelateerde BASIC-routines.

De auteurs stellen op- en aanmerkingen zeer op prijs, welke kunnen dienen
om deze versie 2.00 verder te vervolmaken.

Dat deze file nu bestaat is voornamelijk aan Waldo Ruiterman (WR) te danken
die hiervoor het nodige 'koeliewerk' heeft verricht. Ik, Jan van der Meer 
(JvdM), teken voorlopig voor de tekst.

Deze file is overigens PD en mag dus vrij verspreid worden via BBS'en of op
wat voor andere, niet winstgevende, manier dan ook. Wat niet mag is dat je
er wijzigingen in aanbrengt - hoe logisch die ook mogen lijken. Zie je een
fout neem dan kontact met ons op via de aan het eind van deze file vermelde
adressen/telefoonnummers.

Allereerst wil ik kwijt dat je voor een goed gebruik van de MP over een
behoorlijke dosis machinetaal-kennis en -ervaring dient te beschikken. Ook 
een meer dan basale kennis van het MSX-geheugenbeheer kan geen kwaad. Aan 
de andere kant acht ik het niet onmogelijk dat een studie MP je deze 
vaardigheden vanzelf afdwingt...

Verwacht geen wonderen nu je deze file eenmaal hebt. De MATH-PACK laat zich
nu eenmaal moeilijk temmen en dus zul je zelf ook het nodige spitwerk moeten
verrichten. De navolgende informatie moet echter voldoende zijn om zonder al
te veel problemen thuis te raken in MATH-PACK. Mijn (JvdM) ervaring is dat
een pakket als WBASS2 alsook MSXDEBUG zich hier bij uitstek voor leent.

Deze file is gebaseerd op de over de MP bestaande originele engelstalige
literatuur. Deze literatuur werd niet alleen vertaald, doch aangezien hierin
vele onduidelijkheden en zelfs fouten voorkomen, werd e.e.a. bewerkt en aange-
vuld met wetenswaardige details, welke inmiddels zijn verzameld.

Een bron van onduidelijkheden is het verschil tussen de door een MSX-computer
gebruikte wetenschappelijke notatie voor uitvoer naar het beeldscherm en de
wijze waarop getalswaarden van enkele- en dubbele-precisie intern opgeslagen
worden in het geheugen. De engelse documentatie gebruikt deze interne notatie,
welke  E R U I T  Z I E T  als de bekende wetenschappelijke notatie (bekend
van de uitvoer naar het scherm)  D O C H  D I T  I N  F E I T E  N I E T  I S.
Aldus ontstaat er een spraakverwarring die we allereerst uit de wereld zullen
helpen door het verschil tussen de interne- en de wetenschappelijke notatie
duidelijk te maken. Het wegwijs worden in de documentatie wordt dan (hopen we)
een stuk minder lastig.


ALGEMENE DEFINITIES:
--------------------

Elk getal, dat buiten de grenzen voor een integere waarde valt, wordt intern
opgeslagen als een getal met drijvende decimale punt. Daarbij onderscheiden we
enkele- en dubbele-precisie, waarbij respektievelijk 6 of 14 relevante cijfers
worden gebruikt. Als voor het neerschrijven van een getal meer dan de genoemde
6 of 14 cijfers nodig zouden zijn (excl. decimale punt) dan wordt door een
MSX-computer in basic c.q. directmode voor de uitvoer naar het beeldscherm de
wetenschappelijke notatie gebruikt. (letter "E" gevolgd door exponentwaarde)

De 6 of 14 relevante cijfers worden zonder decimale punt intern opgeslagen in
BCD (binairy coded decimal). Daarbij wordt voor elk cijfer van een getal
slechts de binaire code gebruikt voor de cijfers 0 t/m 9. Voor 1 cijfer zijn
dan maar 4 bits (1 nibble) nodig. Er passen dus 2 cijfers in 1 byte. De 2
cijfers '39' b.v. worden binair 0011 en 1001. Samengevoegd tot 1 byte wordt dat
00111001. In hex uitgedrukt is de waarde van deze byte &H39. De 6 cijfers bij
een getal van enkele precisie passen dus in 3 bytes. Deze serie van 6 cijfers
heet "mantisse".

Bij een getal van dubbele precisie bestaat de mantisse uit 14 relevante
cijfers, passend in 7 bytes. De volgorde van de BCD gecodeerde bytes van de
mantisse is hetzelfde als wanneer we die zouden opschrijven. B.v. de mantisse
12345678901234  bestaat achtereenvolgend uit de 7 bytes &H12, &H34, &H56, &H78,
&H90, &H12 en &H34.

De mantisse kan zowel op een positief- als een negatief getal betrekking
hebben. Deze z.g. polariteit wordt gecodeerd in 1 byte tezamen met de waarde
van de exponent en de polariteit daarvan. Deze z.g. exponentbyte is altijd de
1e byte. Daarna komen de 3 of 7 bytes voor de mantisse. Hoe de codering van de
exponentbyte in elkaar steekt volgt later.

De exponent wordt uitgedrukt met de term 'E+n' of 'E-n', waarbij n staat voor
de getalswaarde van de exponent. De letter 'E' staat in feite voor de formule
(in basic notatie) " * 10^ ". Dit betekent, dat we om de werkelijke waarde van
het getal te krijgen, hetwelk door de mantisse en de exponent wordt voorge-
steld,  we de decimale punt bij een positieve exponent evenveel plaatsen naar
rechts zouden moeten verschuiven als het getal van de exponent. Bij een nega-
tieve exponent zou de decimale punt naar links i.p.v. naar rechts geschoven
moeten worden. We moeten dus weten waar in de mantisse de decimale punt wordt
geacht te staan om de werkelijke waarde van de kombinatie mantisse + exponent
te kunnen achterhalen. De plaats waar de decimale punt geacht wordt te staan
bij de interne notatie (opslag in het geheugen), is anders dan de plaats waar
de decimale punt werkelijk staat als een MSX-computer een wetenschappelijke
notatie op het scherm zet. Dit verschil moeten we kennen om vlot met de
Mathpack-routines om te kunnen gaan.



WETENSCHAPPELIJKE NOTATIE (uitvoer naar scherm)
-------------------------

De decimale punt wordt geplaatst tussen het 1e en 2e cijfer van de mantisse.
De exponent geeft het aantal plaatsen aan, dat de decimale punt verplaatst
moet worden om de werkelijke waarde van het getal te verkrijgen. Positieve
exponent: naar rechts.  Negatieve exponent: naar links.



INTERNE NOTATIE (opslag in het geheugen)
---------------

De decimale punt wordt geacht te staan v¢¢r het 1e cijfer van de mantisse
i.p.v. erachter zoals bij de wetenschappelijke notatie (zie boven). Omdat
de decimale punt nu 1 plaats verder naar links staat dan bij de wetenschappe-
lijke notatie, moet de exponent ook veranderd worden om dezelfde re‰ele waarde
van het getal te behouden. Het gevolg van e.e.a. is, dat bij de wetenschappe-
lijke notatie, die voor schermuitvoer wordt gebruikt, de waarde van de exponent
altijd 1 lager (-1) is dan bij de interne notatie, welke in het geheugen staat.
Voortaan zal de wetenschappelijke notatie worden aangeduid als " w.n. " en de
interne notatie als " i.n. "

Het verschil tussen i.n. en w.n. wordt duidelijk als we in directmode (basic)
zouden typen:

        A=.12345678901234E+15: B=.12345678901234E-15: PRINT A,B   <return>

De MSX-computer zet dan op het scherm:

        1.2345678901234E+14     1.234568901234E-16

De ingetypte waarden voor A & B waren overeenkomstig de i.n. Zo staan de
mantisse en de exponent in het geheugen. Bij de uitvoer naar het scherm werd
de w.n. gebruikt met als gevolg, dat waarde van de exponent bij w.n. 1 lager
(-1) is dan de waarde van de exponent, welke in het geheugen staat (i.n.).

Bij bovenstaand voorbeeld zou voor "A" ook 12345.678091234E+10 ingetypt kunnen
worden. Onze komputer zet de mantisse volgens de i.n. in het geheugen, dus de
decimale punt is 5 plaatsen naar links verhuisd (v¢¢r het 1e cijfer van de
mantisse). Voor het verkrijgen van de re‰ele waarde zou de punt weer 5 plaatsen
naar rechts verplaatst moeten worden en nog eens 10 plaatsen naar rechts
vanwege "E+10".  Als exponent-waarde wordt derhalve +5 +10 = +15 opgeslagen
zodat de re‰ele waarde van het getal gelijkwaardig blijft.

Alles wat we in direct-mode intypen is in feite een ascii-string, waarmee de
getalswaarde wordt voorgesteld. Onze computer gebruikt ‚‚n van de MP-routines
om die string om te zetten naar een re‰ele getalswaarde. Die MP-routine kun je
o.a. vinden in de tabellen verderop.

Het verschil tussen de w.n. en de i.n. moeten we kennen om een w.n. te kunnen
vertalen naar de juiste waarden voor de mantisse en de exponent. De engelse
documentatie gebruikt de i.n. daarbij worden de mantisse en de exponent steeds
gegeven zoals die intern opgeslagen staan. Een mantisse bestaat altijd uit 6
of 14 cijfers. De getalswaarde van b.v. 123.4E-15 heeft maar 4 relevante
cijfers. Bij de opslag hiervan wordt de mantisse aangevuld met nullen erachter
tot 6 of 14 cijfers. De engelse documentatie geeft in zo'n geval ook alle
erachter geplaatste nullen weer, welke in het geheugen zijn opgeslagen. Bij de
w.n. op het scherm worden deze afsluitende nullen altijd weggelaten.

De engelse notatie gebruikt gemakshalve de i.n. omdat daarbij de waarde van de
exponent identiek is aan waarde van de exponent, die in de exponentbyte
gecodeerd zit. Helaas werd verzuimd om te vermelden, dat dit niet de w.n. is,
hoewel die daar wel erg op lijkt. Dit kan bij het gebruik van de MP-routines
zeer verwarrend werken. In de diverse nog volgende voorbeelden, overzichten en
tabellen zal naast de i.n. uit de engelse documentatie tevens de w.n. worden
vermeld, zodat het verschil steeds duidelijk is. Onjuiste interpretatie hopen
we daardoor te voorkomen.



CODERING VAN EXPONENTBYTE
-------------------------

In de exponentbyte staan 3 gegevens gecodeerd, te weten: Polariteit (teken) van
het getal, polariteit van de exponent en waarde van de exponent.

    Alle bits = '0': De waarde van het getal (mantisse) is exakt nul.

    Bit 7 = '0':     Mantisse positief (positief getal)
    Bit 7 = '1':     Mantisse negatief (negatief getal)

    Bit 6 = '0':     Exponent negatief (in bereik -1 t/m -63)
                     Bits 0-5 vormen het 2-komplement van de
                              absolute binaire waarde van de exponent

    Bit 6 = '1':     Exponent positief (in bereik +0 t/m +63)
                     Bits 0-5 vormen de binaire waarde van de exponent

Opmerking: Voor het bepalen van de waarde van de exponent wordt de decimale
           punt geacht te staan v¢¢r het 1e cijfer van de mantisse.
           Het exponentbyte wordt als 1e byte in het geheugen opgeslagen. De
           3 of 7 bytes van de mantisse volgen direkt daarna. Opslagplaats
           is: 'DAC' of 'ARG', zie verderop voor details & adressen.

Aanwijzing voor minder gevorderden: 2-Komplement = Komplement +1

Voorbeeld vertaling naar 2 komplement: te vertalen waarde: -63
        Absolute waarde = 63, binair:   111111
                          komplement:   000000
                                  +1:        1
                                      + ------
                        2-komplement:   000001 = -63

Voorbeeld terugvertalen van 2-komplement naar absolute waarde:
             negatieve waarde uitgedrukt als 2-komplement:   000001 (-63)
                                               komplement:   111110
                                                       +1:        1
                                                           + ------
                 (nieuw 2-komplement) absolute waarde was:   111111 = 63

=============================================================================


De MATH-PACK (MP) is de kern voor de rekenkundige routines van MSX-BASIC.
De MP bestaat uit een breed scala aan reken- en wiskundige routines welke, 
mits aan bepaalde voorwaarden is voldaan, ook vanuit een 'gewoon' 
ml-programma zijn aan te roepen c.q. te gebruiken. In wezen is de MP dan 
ook niet meer dan een verzameling van niet officiele BIOS-routines.
Wel is het zo dat niet zelden zowel page 0 (#0000-#3FFF) alswel page 1
(#4000-#7FFF) gelijktijdig op de ROM geschakeld dienen te staan tijdens het
gebruik van MP-routines.

Bij de overgang van MSX1 naar MSX2 stonden de programmeurs van dit systeem 
voor het probleem dat, ook al waren de MP-routines niet officieel, er toch in
zowel hun eigen code alswel in zeer veel MSX1 programma's er al een dusdanig
veelvuldig en rechtstreeks gebruik van de MP-routines was gemaakt, dat ze
eigenlijk geen keus meer hadden. Het feit dat ze het voor elkaar hebben gekre-
gen deze routines op hetzelfde adres te houden verdient bewondering. Zo zijn
er ook nog diverse BASIC-routines die hun plaats hebben behouden. Een programma
dat hier listig gebruik van maakt is MSXCALC.TSR welke bij Jos de Boer
(MS-actie) is te bestellen.

In de MATH-PACK zijn een drietal adressen van groot belang. Dit zijn
VALTYP (#F663), DAC (#F7F6...) en ARG (#F847...).

VALTYP is een acroniem voor 'VALue TYPe' (waardetype). DAC en ARG staan
respectievelijk voor 'Decimal ACumulator (decimale opslagplaats) en
ARGument' (berekeningswaarde). Neem de voornoemde uitleg van DAC en ARG
niet al te letterlijk op; want er is op allerlei manieren mee te goochelen.



Het MATH-PACK werkgebied.
-------------------------

  ---------------------------------------------------------------------------
  | Label  | Adres  | Lengte |                Betekenis                     |
  |--------|--------|--------|----------------------------------------------|
  | DAC    | &HF7F6 |   16   | Decimal accumulator voor invoer en uitvoer *)|
  | ARG    | &HF847 |   16   | Argument (2e getal voor berekeningen)        |
  | VALTYP | &HF663 |    1   | Getalstypering of stringtypering             |
  ---------------------------------------------------------------------------
*) Getallen met drijvende decimale punt (floating point):
        Exponentbyte + mantisse in BCD notatie
        Enkele precisie in DAC+0 t/m DAC+3.
        Dubbele precisie in DAC+0 t/m DAC+7
   Integer getal:
        Binair in DAC+2 (lowbyte) en DAC+3 (highbyte).
        (Negatieve waarde als 2-komplement)

Voor zowel DAC als ARG zijn alleen de 1e 8 bytes van belang voor de program-
meur. De 2e 8 bytes worden gebruikt door diverse basic en MP-routines.

De 1-byte-waarde in (VALTYP) is 2, 3, 4 of 8 volgens onderstaand lijstje:

2 voor een 2-byte-integer         Opslag in DAC+2 (lowbyte) en DAC+3 (highbyte)
3 voor een stringdescriptor
4 voor een enkel precisie getal   Opslag in DAC+0 t/m DAC+3
8 voor een dubbel precisie getal  Opslag in DAC+0 t/m DAC+7

    De waarde 3 is thans onbelangrijk. We willen immers rekenen !

    De waarde in VALTYP geeft niet alleen de getalstypering aan, doch geeft
    tevens het aantal van belang zijnde (significante) bytes in (DAC...)
    en/of (ARG...)


Omdat de MATH-PACK eigenlijk een verzameling van BASIC-routines is zal er
bij het optreden/konstateren van een fout (bijv. delen door nul of een
"overflow") gepoogd worden naar BASIC terug te keren. Om dit te voorkomen zou
de hook H.ERRO (&HFFB1) omgebogen moeten worden. Hier hopen we een andere keer
op terug te komen. In feite dient elk machinetaalprogramma "eigen foutaf-
handelingsroutines" te hebben als er kans is, dat er een foutmelding via de
biosrom of de diskrom wordt geaktiveerd.



TABEL 1:  Formaat van getallen met drijvende decimale punt. (floating point)
-----------------------------------------------------------

    -----------------------------------------
     Bitnummer  | 7 |  6  5  4  3  2  1  0  |
    ------------|---|-----------------------| 1e byte      ^       ^
                |+/-|   exponentcodering    |              |       |
         -------|---------------------------|              |       |
          ^     |   1e cijfer |   2e cijfer | 2e byte    enkele    |
          |     |-------------|-------------|           precisie   |
          |     |   3e cijfer |   4e cijfer | 3e byte      |       |
          |     |-------------|-------------|              |       |
      mantisse  |   5e cijfer |   6e cijfer | 4e byte      v       |
         in     |-------------|-------------|----------------      |
    BCD-formaat |   7e cijfer |   8e cijfer | 5e byte           dubbele
          |     |-------------|-------------|                   precisie
          |     |   9e cijfer |  10e cijfer | 6e byte              |
          |     |-------------|-------------|                      |
          |     |  11e cijfer |  12e cijfer | 7e byte              |
          |     |-------------|-------------|                      |
          v     |  13e cijfer |  14e cijfer | 8e byte              v
         ------------------------------------------------------------
Noot: De exponentcodering werd reeds eerder besproken, zie aldaar.


Tabel 2: Voorbeelden van getalsuitdrukkingen.
---------------------------------------------

         Voorbeeld van een enkele precisie getal:

         123456 ---> .123456E+6 (i.n.) ---> 1.23456E+5 (w.n.)

                            DAC+0   +1   +2   +3
                              ---------------------
Interne opslag (hex) in DAC:  | 46 | 12 | 34 | 56 |
                              ---------------------


         Voorbeeld van een dubbele precisie getal:

 123456.78901234 ---> .12345678901234E+6 (i.n.) ---> 1.2345678901234E+5 (w.n.)

                            DAC+0   +1   +2   +3   +4   +5   +6   +7
                              -----------------------------------------
Interne opslag (hex) in DAC:  | 46 | 12 | 34 | 56 | 78 | 90 | 12 | 34 |
                              -----------------------------------------

Noot: Bij MSX geldt, dat de wetenschappelijke notatie niet wordt gebruikt als
      de exponent ( bij i.n.) in het bereik -1 t/m +14 ligt. De schermuitvoer
      bij dit voorbeeld zal daarom identiek zijn aan de 1e notatie met de
      decimale punt achter het 6e cijfer. Een getalswaarde, door MSX op het
      scherm gezet, zal dus nooit eindigen op E-2 t/m E+13. MSX zet dan de
      decimale punt op de juiste plaats i.p.v. de w.n. te gebruiken.



Tabel 3: Exponent formaat en grenzen.
-------------------------------------

  |+/- teken|<--exponent-codering-->|  Betekenis:
  |---------|-----------------------|---------------------------------------
  |    0    |  0  0  0  0  0  0  0  |  Het getal c.q. de mantisse is exact nul
  |---------|-----------------------|
  |    1    |  0  0  0  0  0  0  0  |  Niet toegestaan (* 10^-0 ???)
  |---------|-----------------------|
  |    x    |  0  0  0  0  0  0  1  |  * 10^-63      (E-63) kleinste exponent
  |---------|-----------------------|
  |    x    |  1  0  0  0  0  0  0  |  * 10^0 = * 1  (E+0)
  |---------|-----------------------|
  |    x    |  1  1  1  1  1  1  1  |  * 10^63       (E+63) grootste exponent
  -----------------------------------
  Noot: x = '0'  Getal (mantisse) is positief
        x = '1'  Getal (mantisse) is negatief
        De exponent-codering werd reeds eerder besproken, zie aldaar.



Tabel 4: Geldige reeks dubbele precisie getallen.
-------------------------------------------------

   Byte|  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |   Waarde van getal
   ----|----|----|----|----|----|----|----|----|------------------------------
   DAC:| FF | 99 | 99 | 99 | 99 | 99 | 99 | 99 |  -0.99999999999999E+63 (i.n.)
       |    |    |    |    |    |    |    |    |  -9.9999999999999E+62  (w.n.)
       |----|----|----|----|----|----|----|----|------------------------------
   DAC:| 81 | 10 | 00 | 00 | 00 | 00 | 00 | 00 |  -0.10000000000000E-63 (i.n.)
       |    |    |    |    |    |    |    |    |  -1E-64 (w.n.)
       |----|----|----|----|----|----|----|----|------------------------------
   DAC:| 00 | x  | x  | x  | x  | x  | x  | x  |   0
       |----|----|----|----|----|----|----|----|------------------------------
   DAC:| 01 | 10 | 00 | 00 | 00 | 00 | 00 | 00 |  +0.10000000000000E-63 (i.n.)
       |    |    |    |    |    |    |    |    |  +1E-64 (w.n.)
       |----|----|----|----|----|----|----|----|------------------------------
   DAC:| 7F | 99 | 99 | 99 | 99 | 99 | 99 | 99 |  +0.99999999999999E+63 (i.n.)
       |    |    |    |    |    |    |    |    |  +9.9999999999999E+62  (w.n.)
       -----------------------------------------------------------------------


    

Index

Vorige

Volgende