MILC logo

IndexVorigeVolgendeLeeg

Mathpack info v2
MCCM/WR/JvdM, 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.)
       -----------------------------------------------------------------------

==============================================================================
===============    MATH-PACK ROUTINES EN HUN ENTRY-ADRESSEN    ===============
==============================================================================


   PRIMAIRE REKENFUNKTIES:
  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie                                               |
  |--------|--------|-------------------------------------------------------|
  | DECSUB | &H268C | DAC <--- DAC - ARG                                    |
  | DECADD | &H269A | DAC <--- DAC + ARG                                    |
  | DECNRM | &H26FA | normaliseert DAC: eventuele voorloopnullen worden     |
  |        |        |  uit de mantisse verwijderd. Exponent wordt aangepast |
  |        |        |  op dec. punt voor 1e cijfer. Bijvoorbeeld: 0.001234  |
  |        |        |  wordt: .12340000000000E-2 (i.n.) ---> 1.234E-3 (w.n.)|
  | DECROU | &H273C | rondt DAC af tot mantisse van 14 relevante cijfers.   |
  | DECMUL | &H27E6 | DAC <--- DAC * ARG                                    |
  | DECDIV | &H289F | DAC <--- DAC / ARG                                    |
  ---------------------------------------------------------------------------
Noot: Deze routines behandelen de getallen in DAC en ARG als dubbele
      precisie. De registers worden niet bewaard !!!



   GONIOMETRISCHE FUNCTIES, WORTELTREKKEN, KWADRATEREN & AFRONDEN:
  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie                       | Wijzigt registers     |
  |--------|--------|-------------------------------|-----------------------|
  | COS    | &H2993 | DAC <--- COS(DAC)             |  A,B,C,D,E,H en L     |
  | SIN    | &H29AC | DAC <--- SIN(DAC)             |  A,B,C,D,E,H en L     |
  | TAN    | &H29FB | DAC <--- TAN(DAC)             |  A,B,C,D,E,H en L     |
  | ATN    | &H2A14 | DAC <--- ATN(DAC)             |  A,B,C,D,E,H en L     |
  | LOG    | &H2A72 | DAC <--- LOG(DAC)             |  A,B,C,D,E,H en L     |
  | SQR    | &H2AFF | DAC <--- SQR(DAC)             |  A,B,C,D,E,H en L     |
  | EXP    | &H2B4A | DAC <--- EXP(DAC)             |  A,B,C,D,E,H en L     |
  | RND    | &H2BDF | DAC <--- RND(DAC)             |  A,B,C,D,E,H en L     |
  ---------------------------------------------------------------------------
  Noot: Deze functies hebben dezelfde naam en functie als in BASIC.



 TEKEN-MANIPULATIES:
-----------------------------------------------------------------------------
| Label  | Adres  | Funktie                           | Wijzigt register(s) |
|--------|--------|-----------------------------------|---------------------|
| SIGN   | &H2E71 | AF <--- teken van DAC             |     A               |
|        |        |   NC, Z    (A = &H00) <--- DAC = 0|                     |
|        |        |   NC, NZ   (A = &H01) <--- DAC > 0|                     |
|        |        |   C,S-vlag (A = &HFF) <--- DAC < 0|                     |
| ABSFN  | &H2E82 | DAC <--- ABS(DAC)                 |     A,B,C,D,E,H,L   |
|        |        |   Resultaat: Mantisse positief    |                     |
| NEG    | &H2E8D | DAC <--- NEG(DAC)                 |     A,H,L           |
|        |        |   Teken mantisse + <----  -       |                     |
|        |        |               of - <----  +       |                     |
| SGN    | &H2E97 | DAC <--- SGN(DAC)                 |     A,H,L           |
|        |        |   Resultaat is 2 bytes integer    |                     |
|        |        |   DAC+2 = &H00 <----- DAC = 0     |                     |
|        |        |   DAC+3 = &H00 <-----             |                     |
|        |        |                                   |                     |
|        |        |   DAC+2 = &H01 <----- DAC > 0     |                     |
|        |        |   DAC+3 = &H00 <-----             |                     |
|        |        |                                   |                     |
|        |        |   DAC+2 = &HFF <----- DAC < 0     |                     |
|        |        |   DAC+3 = &HFF <-----             |                     |
|        |        |       (&HF663) <----- &H02        |                     |
-----------------------------------------------------------------------------
   Noot: De funktie SGN is identiek aan de BASIC-funktie SNG( < N > )
         De funktie ABSFN is identiek aan de BASIC-funktie ABS( < N > )
         (Overige funkties hebben geen equivalent in BASIC.)
         De funktie SIGN is soortgelijk als SGN. SIGN geeft echter het
         resultaat in het 'A' register en de vlaggen in het 'F' register zijn
         reeds gezet (voor gebruik in machinetaal). DAC en VALTYP (&HF663)
         blijven ongewijzigd bij SIGN !!




   DATA VERPLAATSINGEN:

  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie          | Type variabele | wijzigt registers |
  |--------|--------|------------------|----------------|-------------------|
  | MAF    | &H2C4D | ARG <--- DAC     | dubb. precisie | A,B,D,E,H,L       |
  | MAM    | &H2C50 | ARG <--- (HL)    | dubb. precisie | A,B,D,E,H,L       |
  | MOV8DH | &H2C53 | (DE) <--- (HL)   | dubb. precisie | A,B,D,E,H,L       |
  | MFA    | &H2C59 | DAC <--- ARG     | dubb. precisie | A,B,D,E,H,L       |
  | MFM    | &H2C5C | DAC <--- (HL)    | dubb. precisie | A,B,D,E,H,L       |
  | MMF    | &H2C67 | (HL) <--- DAC    | dubb. precisie | A,B,D,E,H,L       |
  | MOV8HD | &H2C6A | (HL) <--- (DE)   | dubb. precisie | A,B,D,E,H,L       |
  | XTF    | &H2C6F | (SP) <--> DAC    | dubb. precisie | A,B,D,E,H,L       |
  | PHA    | &H2CC7 | ARG <--- (SP)    | dubb. precisie | A,B,D,E,H,L       |
  | PHF    | &H2CCC | DAC <--- (SP)    | dubb. precisie | A,B,D,E,H,L       |
  | PPA    | &H2CDC | (SP) <--- ARG    | dubb. precisie | A,B,D,E,H,L       |
  | PPF    | &H2CE1 | (SP) <--- DAC    | dubb. precisie | A,B,D,E,H,L       |
  | PUSHF  | &H2EB1 | DAC <--- (SP)    | enk.  precisie |     D,E           |
  | MOVFM  | &H2EBE | DAC <--- (HL)    | enk.  precisie | B,C,D,E,H,L       |
  | MOVFR  | &H2EC1 | DAC <--- (CBED)  | enk.  precisie |     D,E           |
  | MOVRF  | &H2ECC | (CBED) <--- DAC  | enk.  precisie | B,C,D,E,H,L       |
  | MOVRMI | &H2ED6 | (CBED) <--- (HL) | enk.  precisie | B,C,D,E,H,L       |
  | MOVRM  | &H2EDF | (BCDE) <--- (HL) | enk.  precisie | B,C,D,E,H,L       |
  | MOVMF  | &H2EE8 | (HL) <--- DAC    | enk.  precisie | A,B,D,E,H,L       |
  | MOVE   | &H2EEB | (HL) <--- (DE)   | enk.  precisie | B,C,D,E,H,L       |
  | VMOVAM | &H2EEF | ARG <--- (HL)    | VALTYP         | B,C,D,E,H,L       |
  | MOVVFM | &H2EF2 | (DE) <--- (HL)   | VALTYP         | B,C,D,E,H,L       |
  | VMOVE  | &H2EF3 | (HL) <--- (DE)   | VALTYP         | B,C,D,E,H,L       |
  | VMOVFA | &H2F05 | DAC <--- ARG     | VALTYP         | B,C,D,E,H,L       |
  | VMOVFM | &H2F08 | DAC <--- (HL)    | VALTYP         | B,C,D,E,H,L       |
  | VMOVAF | &H2F0D | ARG <--- DAC     | VALTYP         | B,C,D,E,H,L       |
  | VMOVMF | &H2F10 | (HL) <--- DAC    | VALTYP         | B,C,D,E,H,L       |
  ---------------------------------------------------------------------------

Noot: Een registernaam tussen haakjes (DE), (HL), (SP) betekent, dat het
      betreffende register de pointer bevat naar het geheugenadres waar de
      1e byte van de te verplaatsen 2, 4 of 8 databytes is (of moet worden-)
      opgeslagen.

      4 Registernamen tussen haakjes zoals (CBED) bevatten een getal in enkele
      precisie: Van links naar rechts bevatten de 4 registers het exponentbyte
      (in C), mantissa 1e & 2e cijfer (in B), idem 3e & 4e cijfer (in E) en
      idem 5e & 6e cijfer (in D).

      "VALTYP" betekent dat het aantal te verplaatsen bytes (2, 4 of 8)
      en de juiste plaatsing in DAC of ARG bepaald wordt door de code voor het
      type variabele in geheugenplaats 'VALTYP' (&HF663).



   VERGELIJKINGEN:
  ---------------------------------------------------------------------------
  | Label  | Adres  | Type variabele  | Links  | Rechts | Wijzigt registers |
  |--------|--------|-----------------|--------|--------|-------------------|
  | FCOMP  | &H2F21 | enk.  precisie  | CBED *)| DAC    |    H,L            |
  | ICOMP  | &H2F4D | 2-byte integer  | DE     | HL     |    H,L            |
  | XDCOMP | &H2F5C | dubb. precisie  | ARG    | DAC    |  A,B,C,D,E,H,en L |
  ---------------------------------------------------------------------------
   *) In C: Teken & exponentcodering        in B: 1e & 2e cijfer mantissa
      in E: 3e & 4e cijfer mantissa,        in D: 5e & 6e cijfer mantissa

   Noot: Het resultaat komt in het A-register, de betekenis is:
             A=1   ---------->  links < rechts
             A=0   ---------->  links = rechts
             A=-1 (&HFF) ---->  links > rechts



  INVOER ascii string, UITVOER (naar DAC) integer of getal met drijvende punt
  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie                                               |
  |--------|--------|-------------------------------------------------------|
  | FIN    | &H3299 | AsciiZ-string, welke een pos./neg. getal (met/zonder  |
  |        |        | dec. punt) voorstelt wordt geconverteerd naar of een  |
  |        |        | integer of een getal met drijvende punt (volgens in-  |
  |        |        | terne notatie) en opgeslagen in DAC.  &  VALTYP       |
  |-------------------------------------------------------------------------|
  | Invoer:     HL <---- Pointer naar in geheugen opgeslagen ascii string.  |
  |              A <---- Eerste teken van de opgeslagen string.         *)  |
  | Uitvoer:   DAC <---- Integer of getal van enkele- of dubbele-precisie.  |
  |              C <---- &HFF: Ascii string bevatte geen decimale punt. **) |
  |                   of &H00: Ascii string bevatte wel decimale punt.      |
  |              B <---- aantal bytes mantissa                         ***) |
  |              D <---- Aantal numerieke karakters in de ascii string      |
  |       (&HF663) <---- VALTYP (&H02, &H04 of &H08)                  ****) |
  | Alle registers worden gewijzigd !!                                      |
  ---------------------------------------------------------------------------
  Noot: De basic-rom moet reeds in page 1 aangeschakeld zijn.

*)     Data-invoer in het 'A' register is niet nodig bij Turbo-R. (genegeerd)
**)    Bij een integere waarde betekent "&HFF" dat het getal negatief is.
***)   Alleen geldig bij getal in dubbele precisie.
****)  De variabele codering die in VALTYP wordt gezet hangt af van de
       getalswaarde, welke de ascii-string blijkt voor te stellen.

   Als niet zeker is, dat de string een getal met dubbele precisie
   voorstelt, dan dienen v¢¢r het gebruik van deze routine de 8 geheugen-
   plaatsen DAC+0 t/m DAC+7 gewist te worden door ze te vullen met &H00.

   Een ascii-string, welke een getal voorstelt met decimale punt erin, wordt
   altijd geconverteerd naar een getal met drijvende decimale punt. (enkele
   of dubbele precisie)

   Voor een integere waarde mag de ascii-string bestaan uit:
            Alleen cijfers met teken erv¢¢r. (+ teken niet verplicht)
        of: &H....   1 - 4 hex  karakters
        of: &O....   1 - 6 octal karakters (binnen range &O0 - &O177777)
        of: &B....   1 - 16 binaire karakters "0" of "1"

   Voor een waarde in enkele- of dubbele precisie mag de string bestaan uit:
            Alleen cijfers met teken erv¢¢r (+teken niet verplicht) met- of
            zonder decimale punt.
        of: Een wetenschappelijke notatie.
            Notatie als macht (...^..) is niet toegestaan.


   CONVERSIE WAARDE IN DAC naar afdrukbare ascii-string
  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie                                               |
  |--------|--------|-------------------------------------------------------|
  | FOUT   | &H3425 | Conversie van (DAC) naar dubbele precisie en daarna   |
  |        |        | conversie naar ascii-string.   (&HF663) <---- &H08    |
  |-------------------------------------------------------------------------|
  | Waarde in DAC positief: 1e karakter van de string is een spatie.        |
  | Waarde in DAC negatief: 1e karakter is minteken. DAC neg. ----> DAC pos.|
  |                                                                         |
  | Indien de waarde van de exponent (i.n.) buiten het bereik -1 t/m +14    |
  | ligt, dan wordt de wetenschappelijke notatie gebruikt. (Decimale punt   |
  | na 1e cijfer van de mantissa)                                           |
  | uitvoer: HL <---- pointer naar startadres van de string.                |
  ---------------------------------------------------------------------------
  Noot: De basic-rom moet reeds in page 1 aangeschakeld zijn.


   CONVERSIE WAARDE IN DAC naar afdrukbare geformatteerde ascii-string
   (Vergelijkbaar met basicfunktie "PRINT USING")
  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie                                               |
  |--------|--------|-------------------------------------------------------|
  | PUFOUT | &H3426 | Als funktie FOUT (zie boven) doch geformateerd        |
  |-------------------------------------------------------------------------|
  | invoer:   A <---- formaat codering                                      |
  |                bit 7:  0 = ongeformateerd      1 = geformateerd         |
  |                bit 6:  0 = zonder komma's      1 = met komma's om de    |
  |                                                    drie cijfers.        |
  |                bit 5:  0 = geen betekenis      1 = voorafgaande spaties |
  |                                                    worden opgevuld met  |
  |                                                    punten.              |
  |                bit 4:  0 = geen betekenis      1 = een "$" wordt voor de|
  |                                                    waarde geplakt.      |
  |                bit 3:  0 = geen betekenis      1 = een "+" wordt voor   |
  |                                                    een positieve waarde |
  |                                                    gezet.               |
  |                bit 2:  0 = geen betekenis      1 = het +/-teken komt na |
  |                                                    de waarde.           |
  |                bit 1:  niet gebruikt                                    |
  |                bit 0:  0 = fixed point         1 = floating point       |
  |           B <---- aantal cijfers voor (excl.) de decimale punt.         |
  |           C <---- aantal cijfers na   (incl.) de decimale punt.         |
  |                                                                         |
  | uitvoer: HL <---- pointer naar startadres van de string.                |
  ---------------------------------------------------------------------------
  Noot: Indien het A register = &H00 dan wordt de inhoud van de overige
        registers genegeerd en de funktie FOUT (Label &H3425) uitgevoerd.
        De basic-rom moet reeds in page 1 aangeschakeld zijn !!!


  CONVERSIE INTEGER (in DAC) naar binaire/octal/hexadecimale ascii-string.
  ---------------------------------------------------------------------------
  | Label  | Adres  | Funktie                                               |
  |--------|--------|-------------------------------------------------------|
  | FOUTB  | &H371A | Maakt van de 2-byte integer in DAC+2, +3 een binair   |
  |        |        | uitgedrukte ascii-string.                             |
  | FOUTO  | &H371E | Maakt van de 2-byte integer in DAC+2, +3 een octaal   |
  |        |        | uitgedrukte ascii-string.                             |
  | FOUTH  | &H3722 | Maakt van de 2-byte integer in DAC+2, +3 een hexade-  |
  |        |        | cimaal uitgedrukte ascii-string.                      |
  |-------------------------------------------------------------------------|
  | invoer: DAC+2 (lowbyte), DAC+3 (highbyte) <----- 2-byte integer         |
  |         VALTYP <--- 2                                                   |
  | uitvoer:    HL <--- Pointer naar beginadres van de string.              |
  ---------------------------------------------------------------------------

Noot: Er zijn geen strings gereserveerd. Het startadres van de string van 
      de uitvoerroutine is normaal FBUFFR (vanaf &HF7C5). In sommige gevallen
      kan het enigzins verschillen. Dit geldt ook voor de routines "FOUT" en
      "PUFOUT" voor conversie naar een string.



   TYPE CONVERSIE:
  --------------------------------------------------------------------------
  | label  | adres  | functie                                              |
  |------------------------------------------------------------------------|
  | FRCINT | &H2F8A | Converteert (DAC) naar een 2-byte integer (DAC+2, 3).|
  | FRCSNG | &H2FB2 | Converteert (DAC) naar een enkele precisie waarde.   |
  | FRCDBL | &H303A | Converteert (DAC) naar een dubbele precisie waarde.  |
  | FIXER  | &H30BE | (DAC) <--- SGN(DAC) * INT(ABS(DAC))                  |
  |             Alle registers kunnen gewijzigd worden                     |
  --------------------------------------------------------------------------

Noot: Na het aanroepen van een van deze routines, bevat VALTYP (&HF663) de
      code (2, 4 of 8) van het gewijzigde getalstype in DAC.
      De basic-rom moet reeds in page 1 aangeschakeld zijn !!
      Alle registers worden veranderd.



   REKENFUNKTIES MET 2 INTEGERE GETALLEN:
   (Positief +1 t/m +32767 of negatief -1 t/m -32768)
  --------------------------------------------------------------------------
  | Label  | Adres  | Funktie           | Wijzigt registers                |
  |--------|--------|-------------------|----------------------------------|
  | UMULT  | &H314A | DE <--- BC * DE   | A,B,C,D,E                        |
  | ISUB   | &H3167 | HL <--- DE - HL   | Alle                             |
  | IADD   | &H3172 | HL <--- DE + HL   | Alle                             |
  | IMULT  | &H3193 | HL <--- DE * HL   | Alle                             |
  | IDIV   | &H31E6 | HL <--- DE \ HL   | Alle                             |
  | IMOD   | &H323A | HL <--- DE mod HL | Alle                             |
  |        |        | DE <--- (2 * resultaat indien getallen positief)     |
  --------------------------------------------------------------------------
Noot: De routine IDIV geeft, indien DE en HL beiden met een POSITIEF integer
      getal geladen waren, de rest * 2 terug in register DE. De rest verkrijgt
      men door (DE)/2. De routine IMOD heeft men dan niet nodig.

      Bij de routines IDIV en IMOD moeten BEIDE getallen positief of negatief
      zijn om een geldige uitkomst te verkrijgen.

      Negatieve getallen als twee complement! en #02 in VALTYP zetten.




   MACHTSVERHEFFEN:
 -----------------------------------------------------------------------------
 | Label  | Adres  | Funktie                  | Grondtal | Macht | Resultaat |
 |--------|--------|--------------------------|----------|-------|-----------|
 | SGNEXP | &H37C8 | macht van enk. precisie  |    DAC   |  ARG  |    DAC    |
 | DBLEXP | &H37D7 | macht van dubb. precisie |    DAC   |  ARG  |    DAC    |
 | INTEXP | &H383F | macht van 2-byte integer |    DE    |  HL   |    DAC    |
 -----------------------------------------------------------------------------

 Noot: Alle registers worden gewijzigd.





  @@@  EXTRA: @@@

  --------------------------------------------------------------------------
  | Label  | Adres  | Funktie                                              |
  |--------|--------|------------------------------------------------------|
  | PRTHL  | &H3412 | Zet HL decimaal op het scherm.                       |
  --------------------------------------------------------------------------

Noot: Deze, wellicht meest gebruikte, MP-routine is niet officieel! Page 1 
      hoeft hierbij niet op de ROM te staan.

Op en aanmerkingen over deze file graag sturen naar:

Jan van der Meer
Rensumaheerd 16
9736 AA Groningen
^/*\^ 050-417266

;------------------------------------------------------------------
;ML-PROGRAMMA VOOR UITVOERING VAN EEN MATHPACK ROUTINE WELKE OOK DE
;BASIC-ROM (in page 1) GEBRUIKT. B.v. mathpack-routine "FIN"
;Onderstaand programma werkt op elke MSX computer (in COM-files, geen basic)
;-------------------------------------------------------------------
;Opmerking: De inputbuffer (#F55E t/m #F65F = 258 bytes) wordt alleen gebruikt
;           voor input via het toetsenbord en is dus vrij voor gebruik als
;           geheugen in pagina 3. Omdat pagina 3 nooit weggeschakeld wordt kan
;           dit geheugengebied gebruikt worden voor 'lastige' klussen, welke
;           anders in conflict komen met benodigde slotomschakelingen.
;           Gebruik van dit geheugengebied heeft als bijkomend voordeel, dat
;           er geen geheugen behoeft te worden gereserveerd elders in pag. 3


        LD   HL,COPY_ML ;Beginadres te kopie‰ren ML-code
        LD   DE,#F55E   ;Input-buffer, te gebruiken als tijdelijke
                        ; opslagplaats voor ML-routine
        LD   BC,#004D   ;Aantal bytes van ML-routine
        LDIR            ;Kopi‰er ML-code naar input-buffer
        LD   HL,GETAL   ;Ascii-Z string (getalswaarde in ascii)
        LD   DE,#F600   ;Opslagadres (in input-buffer)
        LD   BC,#0016   ;Maximum mogelijke aantal bytes (21 + eindnul = 22)
        LDIR            ;Ascii-Z string kopi‰ren naar input-buffer
        CALL #F55E      ;ML-routine (in buffer) uitvoeren
        JR   VERVOLG
;=======================

;--> Instellingen betreffende RAM in pag.1 opvragen en opslaan

COPY_ML IN   A,(#A8)    ;Lees slotregister
        LD   (#F65E),A  ;Opslaan in input-buffer
        LD   A,(#FFFF)  ;Lees komplement van subslotregister
        CPL             ;Converteer naar werkelijke inhoud van subslotregister
        LD   (#F65F),A  ;Opslaan in input-buffer

;--> Basic-ROM aanschakelen

        LD   A,(#FCC1)  ;Slotadres basic-ROM
        LD   HL,#4000   ;Pagina identificatie
        CALL #0024      ;Schakel basic-ROM in pagina 1

;--> Mathpack routine uitvoeren

        LD   HL,#F600   ;Input benodigd voor MATHPACK routine "FIN"
        LD   A,(HL)     ;Idem
        PUSH IX         ;Save
        PUSH IY         ;Save
ENTRY_M LD   IX,#3299   ;Entry adres MATHPACK routine "FIN"
                        ;Conversie ascii-Z naar notatie in 'DAC' & 'VALTYP'
                        ;Het adres komt na kopi‰ren in #F57D te staan. Als
                        ;er een andere routine nodig is kan het adres van die
                        ;routine in #F5D7 worden ingevuld voordat de routine
                        ;met "CALL #F55E" wirdt aangeroepen.
        LD   IY,(#FCC0) ;Slot ID basic-ROM
        CALL #001C      ;Call mathpack-routine

;--> RAM terugschakelen in pagina 1

        LD   A,(#F65E)  ;Haal oude instelling slotregister
        OUT  (#A8),A    ;Herstel instelling slotregister
        LD   A,(#F65F)  ;Haal oude instelling subslotregister
        LD   (#FFFF),A  ;Herstel instelling subslotregister
        POP  IY         ;Herstel IY
        POP  IX         ;Herstel IX
        RET             ;Terug naar normale ML-routine
;---------------
GETAL   DEFB "12345.6789" ;(11 BYTES) voorbeeld van mogelijke ascii-Z string
        DEFS 11           ;+ 11 NUL-bytes = totaal 22 bytes
;========================

VERVOLG NOP             ;Hier komt het vervolg van het ML-programma


    

Index

Vorige

Volgende