File : MM2SPECS.TXT
Datum: 21 Maart 1991
Door : Ries Vriend / Ramon van der Winkel - (c) MST
---------------------------------------------------

Deze tekst bevat de informatie die nodig is voor het schrijven 
van  MemMan 2 toepassingsprogramma's. Voor specifieke specifi 
caties omtrend	het programmeren van TSR's wordt echter verwe 
zen  naar  de  technische documentie  die te  vinden is  op de 
`TSR-Development disk'. Hierop staan de volledige TSR specifi 
caties en enkele TSR ontwikkel tools. Deze disk kan binnenkort 
besteld  worden bij  het MST, zie voor meer nieuws hierover de 
aanstaande nummers van MSX Computer Magazine.


MEMMAN versie 2.0 - specificaties
=================================


Gebruikte terminologie
----------------------

Segment - Geheugenblok van 16kB. Segmenten komen voor in Pagi 
	  na specifieke  segmenten (PSEG) en Flexibele segmen 
	  ten  (FSEG).	De  Flexibele segmenten  kunnen op  de 
	  pagina's  0,1 en  2 worden  aangeschakeld. De Pagina 
	  specifieke segmenten	alleen op hun eigen pagina. Er 
	  zijn	 drie  soorten	 pagina  specifieke   segment: 
	  PSEG0000, PSEG4000  en PSEG8000.  Ze zijn op respec 
	  tievelijk pagina 0,1 en 2 aanschakelbaar.

	  Indien  DOS2 aktief  is tijdens  de installatie  van 
	  MemMan, zal  MemMan de  segmenten die niet meer vrij 
	  zijn	bij DOS2  niet in  de segmenten tabel opnemen. 
	  Het geheugen dat door een voor MemMan genstalleerde 
	  RAMdisk in gebruik is, zal dus niet meer door MemMan 
	  beheerd kunnen worden.
	  Wanneer een  (Dos2-) RAMdisk na MemMan genstalleerd 
	  wordt,  kunnen  de  segmenten  die  door de  RAMdisk 
	  gebruikt  werden wel	weer door MemMan gebruikt wor 
	  den, nadat de RAMdisk verwijderd is.

Heap	- Blok geheugen  in pagina  3 (ergens tussen &HC000 en 
	  &HFFFF)  waarvan  MemMan  toepassingsprogramma's een 
	  stuk	aan kunnen vragen en daarna vrij mogen gebrui 
	  ken.

FastUse - Zelfde als Use, maar dan het adres waarop de routine 
	  direct aan te roepen is in pagina 3.

unCrash - Om te  voorkomen dat	segmenten aangevraagd  zijn en 
	  door	een crash  van een  programma nooit  meer vrij 
	  zouden worden  gegeven, voert  de IniChk routine een 
	  unCrash  uit.  Hierbij  worden  alle	segmenten weer 
	  vrijgegeven.	Het unCrashen  van een	segment is  te 
	  voorkomen  door  een segment	de Reserved  status te 
	  geven. Dit  kan met  de funktie SetRes (11). Normaal 
	  gesproken  hoeft een segment niet de Reserved status 
	  gegeven te worden.


De principes

MemMan verdeelt het aanwezige geheugen in segmenten van 16 kB. 
Voordat een segment gebruikt mag worden moet het worden aange 
vraagd. Na  gebruik dient  het weer  te worden vrijgegeven. Er 
zijn  twee soorten  segmenten: de zogenaamde pagina-specifieke 
ofwel PSEG's en de flexibele FSEG's.

PSEG's zijn  segmenten die aangevraagd worden voor het gebruik 
op  een bepaalde pagina, bijvoorbeeld van &h4000-&h7FFF of van 
&h8000-&hBFFF. Wanneer	er een PSEG aangevraagd wordt zal Mem 
Man  zo mogelijk  geheugensegmenten toewijzen  die niet in een 
memory-mapper zitten.

FSEG's zijn  segmenten die  op elke willekeurige pagina kunnen 
worden	ingeschakeld. Deze  segmenten komen  altijd uit memory 
mappers. Welk  soort segment  er ook aangevraagd wordt, MemMan 
zal  een 16-bits 'segmentcode' teruggeven. Deze segmentcode is 
weer nodig  bij het  inschakelen of het weer vrijgeven van het 
segment.  Wie alleen  maar geheugen  nodig heeft in het gebied 
van  &h8000  tot &hBFFF  kan dus  het beste  PSEG's aanvragen. 
MemMan	gebruikt  dan eerst  zoveel mogelijk  geheugen uit  de 
'oude' 16- en 64 Kb modules en gaat dan de mapper gebruiken.

Met behulp  van MemMan	hoeft er  dus nooit meer naar geheugen 
gezocht  te worden.  Simpelweg een pagina aanvragen, gebruiken 
en uiteindelijk weer vrijgeven. Zo eenvoudig is dat.
Overigens is er een pagina die zich met MemMan niet laat scha 
kelen. Pagina 3 bevat behalve de MemMan code zelf ook de stack 
(meestal) en  een grote hoeveelheid systeemvariabelen. Er zit 
ten  nogal wat	haken en ogen aan het wegschakelen van dat al 
les.


Funktie omschrijving
--------------------

Naam   : Use0
Nummer : 0
Funktie: Aanschakelen van  een segment	op pagina 0 (adres ge 
	 bied 0000..3FFF)
In     : HL = Segmentcode
Uit    : A  = Resultaatcode (-1 = Mislukt, 0 = Gelukt)

Het inschakelen van een segment in pagina 0 is alleen mogelijk 
indien	het segment de MSX-standaard slot-schakel entry points 
bevat.


Naam   : Use1
Nummer : 1
Funktie: Aanschakelen van  een segment	op pagina 1 (adres ge 
	 bied 4000..7FFF)
In     : HL = Segmentcode
Uit    : A  = Resultaatcode (-1 = Mislukt, 0 = Gelukt)


Naam   : Use2
Nummer : 2
Funktie: Aanschakelen  van een	segment op pagina 2 (adres ge 
	 bied 8000..BFFF)
In     : HL = Segmentcode
Uit    : A  = Resultaatcode (-1 = Mislukt, 0 = Gelukt)


Naam   : Alloc
Nummer : 10
Funktie: Aanvragen van een segment
In     : B  = Segment voorkeuze code
Uit    : HL = Segmentcode. (0000 = Geen segment meer vrij)
         B  = Segmentsoort code (-1 = FSeg, 0 = PSeg)

Segment voorkeuze code overzicht (Register B):

  Bit 7 6 5 4 3 2 1 0
      ^ ^ ^ ^ ^ ^ ^ ^
      | | | | | | | |
      | | | | | | +-+--> Segment Type. 00 = PSEG0000
      | | 0 0 0 0		       01 = PSEG4000
      | |			       10 = PSEG8000
      | |			       11 = FSEG
      | +--------------> 1 = Prefereer TPA oftewel het
      | 		     standaard MSXDOS RAM slot
      +----------------> 1 = Prefereer ongexpandeerd (dus
			     snel) slot

De bits 5 tot en met 2 zijn niet gebruikt en moeten 0 zijn.

Mocht een  PSEG type  aangevraagd, maar  niet beschikbaar zijn 
wordt - indien mogelijk - een FSEG ter beschikking gesteld die 
dan het PSEG kan vervangen.


Naam   : SetRes
Nummer : 11
Funktie: Segment de Reserved status geven
In     : HL = Segmentcode

Geeft een segment de `Reserved-status'; zodat het segment niet 
automatisch wordt vrij gegeven na aanroep van de IniChk routi 
ne.  Normaal gesproken	hoeven programma's  de reserved status 
niet te  zetten, behalve  als een programma - bijvoorbeeld een 
Ramdisk - een segment voor eigen gebruik zeker wil stellen.


Naam   : DeAlloc
Nummer : 20
Funktie: Teruggeven van een segment
In     : HL = Segmentcode

Bij het verlaten van een programma dient deze funktie gebruikt 
te  worden om  alle aangevraagde segmenten weer terug te geven 
aan  MemMan.  De eventuele  reserved status  van het  terug te 
geven segment wordt door DeAlloc automatisch opgeheven.
Segmenten die  ook door  DOS2 beheerd  worden, worden  door de 
DeAlloc funktie weer ter beschikking gesteld van DOS2.


Naam   : ClrRes
Nummer : 21
Funktie: Reserved status van het segment opheffen
In     : HL = Segmentcode

Het  is niet  nodig deze funktie vlak voor DeAlloc aan te roe 
pen. DeAlloc heft zelf de Reserved status van het segment op.


Naam   : IniChk
Nummer : 30
Funktie: Initialisatie MemMan voor een programma
In     : A  = Controle code
Uit    : A  = Controle code + "M"
         DE = Versie nummer (format: Versie #D.E)

Deze routine  telt de ascii-waarde van de letter "M" op bij de 
inhoud	van register  A. Hierdoor  kan er een MemMan aanwezig 
heids controle	uitgevoerd worden. Verder wordt er een unCrash 
uitgevoerd  en worden de segmentcodes van de actief aangescha 
kelde sloten berekend en opgeslagen voor CurSeg.


Naam   : Status
Nummer : 31
Funktie: Status gegevens van MemMan ophalen
Uit    : HL = Aantal aanwezige segmenten
         BC = Aantal nog vrije segmenten
	 DE = Aantal segmenten	in dubbel  beheer bij  DOS2 en 
	      MemMan
	 A  = Connected Status van de aangesloten hardware.
	      Bit   Funktie
	       0    Dos2 Mapper Support Routines aanwezig
	      1-7   Gereserveerd, altijd 0

Als  bit 0 van de Connected status gezet is, zijn de geheugen 
beheer funkties van dos2.20 aanwezig.
Het aantal  nog vrije segmenten kan lager zijn dan is aangege 
ven  in register BC, omdat sommige segmenten na de installatie 
van MemMan  door DOS2 gebruikt zijn - om bijvoorbeeld een ram 
disk te installeren.


Naam   : CurSeg
Nummer : 32
Funktie: Segmentcode van een aangeschakeld segment opvragen.
In     : B  = Paginanummer (0,1,2,3)
Uit    : HL = Segmentcode
         A  = Segmentsoort code (-1 = FSeg, 0 = Pseg)

Deze  routine geeft de huidige segentcode terug van een van de 
vier pagina's.

TSR programma's mogen deze funktie niet gebruiken om de aktie 
ve segmenten  stand van  pagina 0 te bepalen. Wegens snelheids 
redenen  en  laag  gebruik wordt  deze stand  niet automatisch 
bepaald  en opgeslagen bij de aanroep van een TSR. Voor pagina 
1 en 2 gebeurt dit wel, pagina 3 veranderd niet.

Om  de	uitvoer  te  versnellen kan  ook de  FastCurSeg worden 
gebruikt. Het  aanroep adres  hiervan is  via de  Info funktie 
(50) op te vragen.


Naam   : StoSeg
Nummer : 40
Funktie: Huidige segmenten stand opslaan
In     : HL = Buffer adres (9 bytes groot)

De voor  MemMan bekende  segmentcodes van de actief aangescha 
kelde  sloten worden opgeslagen in het buffer. Deze segmentco 
des zijn in beginsel door IniChk berekend en later door de Use 
funkties  geupdate.  De opgeslagen  stand is  niet de  huidige 
stand, maar  de voor  MemMan bekende stand. TSR kunnen hiermee 
dus niet de actieve stand opslaan.


Naam   : RstSeg
Nummer : 41
Funktie: Opgeslagen segmenten stand actief maken
In     : HL = Buffer adres

De  in het buffer opgeslagen segmenten stand wordt weer actief 
gemaakt en wordt opgeslagen voor CurSeg.


Naam   : Info
Nummer : 50
Funktie: Geeft aanroep-adressen van snelle memman funkties
In     : B  = Informatie nummer (0..5)
Uit    : HL = Start adres van de funktie

Informatie nummer  overzicht. Tussen  haakjes staan de equiva 
lente MemMan funktie codes:

0 - FastUse0 adres (funktie 0)
1 - FastUse1 adres (funktie 1)
2 - FastUse2 adres (funktie 2)
3 - TsrCall adres (funktie 61)
4 - BasicCall adres
5 - FastCurSeg adres (funktie 32)


De  bovengenoemde funktie-adressen mogen door een toepassings 
programma of  TSR rechtstreeks	aangeroepen worden. Alle entry 
adressen liggen gegarandeerd in pagina 3.

De  funkties worden  snel uitgevoerd omdat de MemMan CALL naar 
de EXTBIO hook vervalt en de funktie-codes in registers D en E 
niet  uitgeplozen  hoeven worden.  Een ander  voordeel is  dat 
parameters ook	via het register DE doorgegeven kunnen worden, 
dit is vooral van belang bij de TsrCall en BasicCall funkties.

Bijvoorbeeld,  de  initialisatie  routine van  een TSR	kan de 
benodigde funktieadressen via de INFO funktie opvragen en deze 
vervolgens  ergens in  de TSR  programmacode invullen,	wat de 
snelheid van de TSR zeer ten goede kan komen.

Een  exacte  beschrijving  van	de  bovenstaande  funkties kan 
gevonden worden  bij de MemMan funktie waarvan het nummer tus 
sen haakjes is aangegeven.
Houd  echter onder  de aandacht dat de `snelle' funkties op de 
volgende punten van de gewone MemMan funkties verschillen:

fastUse0-2: Exact  dezelfde  werking  als  als een  memMan Use 
	    aanroep.

tsrCall   : Register [DE] wordt ongewijzigd aan de TSR doorge 
	    geven. Dit	in tegenstelling  tot funktie 61 (Tsr 
	    Call),  register DE  is dan al bezet om het MemMan 
	    funktienummer in op te slaan.

fastCurSeg: In register [A] komt geen zinnige waarde terug. De 
	    MemMan CurSeg  funktie (32)  geeft aan  of het een 
	    FSEG/PSEG betreft.

basicCall : Heeft geen MemMan funktie nummer.
	    Funktie: Aanroepen	van  een  routine in  de BASIC 
		     ROM.
	    In:      IX=Call address in pagina 0 of 1
		     AF,  HL, BC,  DE =  dataregisters voor de 
		     BASIC-ROM
	    Uit:     AF,  HL,  BC, DE  = dataregisters	van de 
		     BASIC-ROM
		     Interrupts disabled

	    Via deze  funktie kunnen TSR's een routine aanroe 
	    pen  die zich  in pagina  0 en/of pagina 1 van het 
	    BASIC-ROM bevindt.	De bios  moet al  in pagina  0 
	    aangeschakeld zijn. In pagina 1 wordt de BASIC ROM 
	    door MemMan aangeschakeld.
	    Dit  is bijvoorbeeld  noodzakelijk om de math-pack 
	    routines aan  te kunnen roepen die in pagina 0 van 
	    de	BASIC ROM zitten, maar tussendoor ook een aan 
	    tal routines in pagina 1 aanroepen.
	    De	H.STKE	(stack	error)	hook wordt  afgebogen, 
	    zodat na  een eventueel op getreden BASIC error de 
	    interne stacks van MemMan gereset kunnen worden.


Naam   : GetTsrID
Nummer : 60
Funktie: Bepaal TSR ID code
In     : HL = Pointer naar de TsrNaam (12 tekens). Ongebruikte 
	      posities opvullen met spaties.
Uit    : Gevonden: Carry clear (NC)
		   IX = TSR ID code
	 Anders  : Carry set (C)


Naam   : TsrCall
Nummer : 61
Funktie: Roep het driver-entry van een TSR aan
In     : IX = ID code van de aan te roepen TSR
	 AF,  HL, BC,  DE worden  ongewijzigd doorgeven aan de 
	 TSR.
Uit    : AF, HL, BC, DE komen ongewijzigd terug van de TSR.

Merk  op dat  alhoewel het  DE register ongewijzigd aan de TSR 
wordt doorgegeven,  het niet  voor parameter-invoer  benut kan 
worden.  De Extended  BIOS funktiecode van MemMan (D='M' E=61) 
moet namelijk in dat register geplaatst worden.
Bij de	Fast-TsrCall routine  treedt deze complicatie niet op; 
het  adres van	deze routine kan middels de info funktie opge 
vraagd worden.


Naam   : HeapAlloc
Nummer : 70
Funktie: Alloceer ruimte in de heap
In     : HL = Gewenste grootte van de ruimte (in bytes)
Uit    : Genoeg ruimte: HL = Startadres van de ruimte
	 Anders       : HL = 0000

Door middel van deze funktie kan een stuk geheugen gealloceerd 
worden.  Het geheugenblok  zal zich  gegarandeerd in  pagina 3 
bevinden.
De heap  is vooral  nuttig voor  TSR programma's, die hem bij 
voorbeeld  als	tijdelijke  of	permanente  diskbuffer	kunnen 
gebruiken. Ook andere buffers - waarvan het absoluut noodzake 
lijk  is dat  ze zich in pagina 3 bevinden - kunnen op de heap 
worden geplaatst.
Aangevraagde blokken  geheugen uit de heap blijven onbruikbaar 
voor andere programma's totdat een `HeapDeAlloc' is uitgevoerd 
(funktie 71).


Naam   : HeapDeAlloc
Nummer : 71
Funktie: Geef geAlloceerde ruimte van de heap weer vrij
In     : HL = Startadres van de ruimte


Naam   : HeapMax
Nummer : 72
Funktie: Geef  de lengte  van het grootste vrije blok geheugen 
	 in de heap terug
Uit    : HL = Lengte van het grootste vrije blok


Gebruik van de stack onder MemMan
---------------------------------

MemMan toepassingsprogramma's dienen de stack pointer (SP) bij 
voorkeur in  pagina 2 of 3 (tussen &h8000 en &HFFFF) te plaat 
sen.  Indien MemMan  door een  hook-aanroep geactiveerd wordt, 
wordt  het  huidige segment  in pagina	1 (&h4000  tot &h8000) 
namelijk weggeschakeld	om plaats te maken voor de TSR-Manager 
en  de eventuele  TSR's. Indien de stack zich op dat moment in 
pagina 1 bevindt zal de computer vastlopen.

Indien	TSR's na  een BDOS call of interrupt via een BIOS-hook 
worden	aangeroepen  treden geen  stackproblemen op;  ook niet 
indien	de  stack  van	het toepassingsprogramma  in pagina  1 
staat. De  BDOS en  interrupt funkties	gebruiken namelijk hun 
eigen  stack in  pagina 3. De stack bevindt zich dan alsnog in 
pagina 3 op het moment dat de hook aangeroepen wordt.

Bestaande CP/M	en MSX-DOS programmatuur is dus zonder proble 
men  in combinatie  met MemMan	2 te  gebruiken -  maar alleen 
indien de standaard BDOS calls gebruikt worden. Wanneer echter 
via een interslot call een BIOS routine rechtstreeks aangeroe 
pen wordt, dient de stack in pagina 2 of 3 te staan. Reserveer 
minimaal 150 bytes voor de stack.


Appendix 1: BIOS aanroepen onder Turbo Pascal

Indien in  een Turbo  Pascal programma interslot-calls naar de 
BIOS gebruikt worden, is het belangrijk dat de stack in pagina 
2  of 3 staat. Op het moment dat de BIOS dan een hook aanroept 
kan MemMan  veilig de TSR's aktiveren. De positie van de stack 
is  afhankelijk van het maximum programma adres dat tijdens de 
compilatie in Turbo Pascal is ingesteld. De stack bevindt zich 
in  Turbo  Pascal direkt  onder het  variabelen geheugen.  Het 
variabelen geheugen  dient bij programma's die de BIOS aanroe 
pen dus ruim boven adres &h8000 geplaatst te worden.

Is  geen source  voorhanden, dan  is het  mogelijk om  met een 
debugger het  stack adres  van Turbo Pascal programma's aan te 
passen. De initialisatie code van een TP programma ziet er als 
volgt uit:

  start: jp init
	 ...
	 ...
  init:  ld sp,100h
	 ld hl,nn
	 ld de,nn
	 ld bc,nn
	 call yy
	 ld hl,nn
	 ld de,stack	;DE bevat het stack adres, hoeft
	 ld bc,nn	; alleen aangepast te worden als het
	 call zz	; lager is dan &h80A0
	 ...

Het stackadres in register DE kan bijvoorbeeld op &hC100 gezet 
worden.

** Einde **
