File: MM24SPEC.ENG

Date: 19 september 1992

By  : Ries Vriend / Ramon van der Winkel - (c) MST



Unauthorised translation by Arnold Metselaar, 1 April 1996

Updated 6 January 1998 to fix some typos and misspellings.

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



  This text contains the information necessary to  write  application

programs for MemMan 2.4. For the specifications regarding programming

TSR's we point to the technical documentation that can  be  found  on

the   `TSR-Development   disk'.   This   disk   contains   the   full

specifications on TSR's and some development tools. It can be ordered

from the MST, see the `LezersService' of `MSX Computer Magazine'  for

more information.



Contents

--------



Changes in MemMan 2.3 with respect to version 2.2

Updates from MemMan 2.30 to MemMan 2.31

Changes in MemMan 2.4 with respect to version 2.3



Used terminology

Why MemMan 2.4?



The basics



Appendix 1: BIOS-calls under Turbo Pascal

Appendix 2: Hints and directions for programmers



MEMMAN version 2.4 - specifications

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



Changes in MemMan 2.3 with respect to version 2.2

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



-      The function XTsrCall has been added. This function  works  in

       the same way as TsrCall (63), the only difference  being  that

       the Tsr-ID is expected in register  IX  instead  of  BC.  This

       makes BC available for passing an argument.



-      The function Info (50) can be used to obtain  the  address  at

       which XTsrCall can be called directly.



-      The function Status is improved. The total  amount  of  usable

       memory is reported correctly, even under MSX-DOS2.



-      The function Alloc (10) now also  recognises  the  memory  that

       becomes available when the DOS2 RAM-disk is removed or  shrunk!

       It does not matter whether the RAM-disk was installed before or

       after MemMan wss installed. 



-      The internal stack of MemMan that is used to process  function

       calls is enlarged from 160 to 240 bytes. The stack  of  MemMan

       proved to be too small to process nested "TsrCalls".



Updates from MemMan 2.30 to MemMan 2.31

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



-      A bug turned up in TL.COM, that caused problems  when  loading

       TSR's under DOS1. The error was in the parsing of the  command

       line and was known and solved the day after the fair.



-      The second bug was more complicated, en  was  revealed  during

       experiments with new TSR's. It was not reported before. It was

       about CMD TL. That command did not perform an IniChk,  due  to

       which the CurSeg function of MemMan did not work well  either.

       TSR's that used CurSeg and  switched  memory  in  page  2  got

       stuck. The printer-buffer was (is?) the only TSR to do so. The

       problem did not occur when loading a TSR with  TL.COM  because

       TL.COM does perform an IniChk. This bug is also solved.



Changes in MemMan 2.4 with respect to version 2.3

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



-      The function GetTPA (33) is added, making it possible  to  use

       the 32 kB RAM behind the BIOS and the  BASIC  ROM  under  disk

       BASIC. Many people asked for this!



-      CMD HELP is now supported by the standard TSR `MST  TsrUtils'.

       This command puts a small overview of the extra BASIC commands

       on  the  screen.  Look  at  the  hints  and   directions   for

       programmers for more information on CMD HELP. 



-      TL.COM uses the environment item  TL,  to  locate  the  TSR's.

       Owners of a hard disk only need to  put  `SET  TL=A:\TSRS'  in

       their  AUTOEXEC.BAT  and  to  place  all  the  TSR's  in   the

       subdirectory A:\TSRS can always be found  by  TL.  Giving  the

       path is than no longer necessary.



-      TV.COM also shows in which  segment  the  TSR's  reside.  This

       makes it easy to free a segment by removing all the  TSR's  in

       them. TSR segment 0 is the MemMan  segment,  the  memory  left

       over in that segment can only be used by TSR's, not  by  other

       programs.



-      Two functions have been added read and set the  stack  pointer

       of MemMan's internal stack. That is  necessary  if  a  program

       calls the expression evaluator in the BASIC ROM and  wants  to

       handle errors itself. This is because ExpEval may  call a  TSR

       that calls ExpEval and an error may than occur. In  that  case

       junk will be left on the stack. If the  error-handler  of  MSX

       BASIC is used after such errors, there  is  no  problem:  then

       MemMan itself clears its stack.



-      In  all  MemMan  TSR-segments  the  MemMan  function  handling

       routine starts at &h4002. Therefore MemMan can be called  from

       a TSR with a quick and simple `call &H4002'.



-      A new version (1.04) of the file-copier BK is  delivered  that

       makes no errors if more than 4 MB  is  available.  In  version

       1.02 a counter would overflow causing a  wrong  indication  on

       screen of the amount of memory.



-      IniChk gives the address of the MemMan function handler in  HL.

       This saves a call to the Info function.





Why MemMan 2.4?

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



  In fact there was little reason for a releasing new  version  after

the updates. The differences between 2.3 and 2.4 are small. All known

bugs had been solved and there are no  big  extensions,  just  a  few

small extras. 

  Apart from what is new now, we have and had more and bigger  plans.

We still work on them but we did not want to wait with releasing  2.4

until the other things  had  been  finished  and  tested.  Especially

because more and more programmers  encountered  an  design  error  in

MemMan: It was impossible to switch the 32  kB  RAM  behind  the  ROM

under disk BASIC using MemMan. That has been solved: From now on  All

switching can be done neatly using MemMan, even  if  a  program  runs

under disk BASIC and really wants to use all the memory.

  All other extensions are nice but could have waited. On  the  other

hand there are some wishes amongst the further plans that are in fact

quite important. But they all require a considerable  change  in  the

internal structure of MemMan and that takes time. 

 

Used terminology

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



Page     Part of the addressing space. The addressing  space  of  the

         Z80 is divided into 4 pages of 16  k,  starting  at  &h0000,

         &h4000, &h8000 and &hC000 respectively.



Segment  Memory block 16 kB in size. There are two types of segments;

         page-bound and flexible segments. The flexible segments  can

         can be switched on page 0, 1 and 2. There are three sorts of

         page-bound segments: PSEG0000, PSEG4000  and  PSEG8000. They

         can be switched on page 0, 1 and 2 respectively.



Heap     Memory area in page 3 (somewhere between &hC000 and &hFFFF).

         MemMan application programs can allocate a piece and use  it

         freely. The size can be set with the  configuration  program

         CFGMMAN.



FastUse  Equal to Use, called directly in  page  3.  There  are  also

         other routines that can be called directly,  which  benefits

         the speed.



Uncrash  To prevent allocated  segments  from  never  being  released

         because a program crashed, the IniChk  routine  performs  an

         UnCrash. This releases all segments.  One  can  prevent  the

         UnCrashing of a segment by giving it  the  Reserved  status.

         This can be done with the  function  SetRes.  In  general  a

         segment does not need be given the Reserved status.



TPA      `Transient Program Area'. Originally this meant the piece of

         memory from &h0100 until the first  byte  of  the  operating

         system under CP/M or MSX DOS. That was the area  where  user

         programs could be loaded. In this text the term TPA is  used

         for the four segments (64 kB) that are switched on under MSX

         DOS. The upper two of them are also switched  on  under  MSX

         BASIC.



The basics

----------



  MemMan divides the memory into segments of 16 kB. Before a  segment

may be used it must be allocated. After use  it  should  be  released

again. There are two types of segments: the  page-bound  segments  or

PSEG's end the flexible FSEG's.

  PSEG's are segments that are requested for use in a specific  page,

e.g. &h4000-&h7FFF or &h8000-&hBFFF. When a PSEG is requested, MemMan

will allocate a segment that is not in a memory mapper, if  possible.

FSEG's are segments that can be used on any page. These  always  come

from memory-mappers.



  Whatever type of segment is requested MemMan will return a  16-bits

`segment-code'.  This  segment-code  is  needed  for   switching   or 

releasing the segment. Those who only need memory in  the  area  from

&h8000 to &hBFFF, can best request PSEG's.  MemMan  than  first  uses

memory from `old' 16 and 64 kB modules before  it  starts  using  the

mapper.



  Using MemMan eliminates the need to search for memory. Just request

a page, use it and release it in the end. It's as simple as that.

  However there is a page that MemMan can not switch. Page 3 contains

a part of the MemMan code, the stack (in most  cases) and  a  lot  of

system variables. Switching all that is quite tricky business.



Description of MemMan 2.4 functions

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



  One can execute MemMan functions by calling the `Extended BIOS'  or

EXTBIO hook, on address &hFFCA. The device ID of MemMan -`M' or &h4D-

should be placed in register D. Register E should contain the  MemMan

function code. After calling a MemMan function all registers  can  be

altered unless the description states otherwise.

  MemMan can also be called directly, the address  where  it  can  be

called, can be asked for using the info function  (50)  and  is  also

returned by IniChk (30). This way the disadvantages of calling MemMan

via a hook  are  avoided.  Look  at  the  hints  and  directions  for

programmers for more information.

  The state of interrupts remains unchanged after a  MemMan  function 

in most cases. Some  functions,  like  the FastUse functions, disable

interrupts. When MemMan was called with interrupts disabled, it  will

never return with interrupts enabled. 

  This feature is important for e.g. TSR programs that  only  have  a

very small stack. As long as  interrupts  are  disabled,  all  MemMan

functions can be processed without problems. However with  interrupts

enabled a big stack is required, as the interrupt handler  puts  tens 

of bytes on the stack.



Name:        Use0

Number:      0

Purpose:     Switch a segment on page 0 (addresses &h0000-&h3FFF) 

In:          HL           = Segment-code

Out:         A            = Exit status (-1 = Failure, 0 = Success)



             Switching a segment in page 0 is only  possible  if  the

             segment  contains  the  standard  MSX  slot-switch entry

             points.



Remark:      This function may not be called  via  the  EXTBIO  hook.

             This function may only be executed after a  direct  call

             to the MemMan function handler or the FastUse0 function.

             One can ask for the addresses where these functions  can

             be called directly, using the function Info (50).





Name:        Use1

Number:      1

Purpose:     Switch a segment on page 0 (addresses &h4000-&h7FFF) 

In:          HL           = Segment-code

Out:         A            = Exit status (-1 = Failure, 0 = Success)



Remark:      This function may not be called  via  the  EXTBIO  hook.

             This function may only be executed after a  direct  call

             to the MemMan function handler or the FastUse1 function.

             One can ask for the addresses where these functions  can

             be called directly, using the function Info (50).





Name:        Use2

Number:      2

Purpose:     Switch a segment on page 0 (addresses &h0000-&h3FFF)

In:          HL           = Segment-code

Out:         A            = Exit status (-1 = Failure, 0 = Success)



Remark:      This function may not be called  via  the  EXTBIO  hook.

             This function may only be executed after a  direct  call

             to the MemMan function handler or the FastUse1 function.

             One can ask for the addresses where these functions  can

             be called directly, using the function Info (50).





Name:        Alloc

Number:      10

Purpose:     Request a segment

In:          B            = Segment preference code

             Bit 0 and 1: 00 = PSEG0000

                          01 = PSEG4000

                          10 = PSEG8000

                          11 = FSEG

             Bit 2 til 5: Unused. Must be 0.

             Bit 6:       1 = Prefer TPA or the standard  MSXDOS  RAM

                          slot. This results in faster switching  but

                          probably  also  in  not  cooperating   with

                          non-MemMan TSR's that put themselves in the

                          TPA slot.

             Bit 7:       1 = Prefer unexpanded (thus fast) slot. The

                          same things as for bit six hold  for  this.

                          Unexpanded slots era switched  faster,  but

                          have a bigger change of  being  in  use  by

                          non-MemMan applications.

Out:         HL           = Segment-code. (&h0000 = No free segment 

                            left)

             B            = Type of segment (-1 = FSeg, 0 = PSeg)



             If a PSEG is requested, but not available, an FSEG, that

             can replace the PSEG,  is allocated instead.





Name:        SetRes

Number:      11

Purpose:     Give a segment the Reserved status

In:          HL           = Segment-code



             Gives a segment the `Reserved-status' preventing it from

             being released automatically after a call to the  IniChk

             function. In general programs do not  need  to  set  the

             reserved status, unless a  program  -e.g.  a  RAM  disk-

             wants to secure a segment for its own use.





Name:        DeAlloc

Number:      20

Purpose:     Releasing a segment

In:          HL           = Segment-code



             On exiting a program this function  should  be  used  to

             release all allocated  segments.  DeAlloc  automatically

             unsets  the  reserved  status  of  the   segment   being

             released.

             DeAlloc will make segments that are also administered by

             DOS2, available for DOS2 again.





Name:        ClrRes

Number:      21

Purpose:     Clear the reserved status of a segment

In:          HL           = Segment-code



             It is not necessary to call this  function  just  before

             calling DeAlloc. DeAlloc clears the reserved status of a

             segment itself.





Name:        IniChk

Number:      30

Purpose:     Initialises MemMan for a program

In:          A            = Check code

Out:         A            = Check code + "M"

             DE           = Version number (format: Version #D.E)

             HL           = Starting from version 2.4: address of the

                            MemMan function  handler  (Look  at  Info

                            (50) for more information.)



             This routine adds the ASCII-value of the letter  "M"  to

             the contents of register A. This makes  it  possible  to

             check the presence of  MemMan.  Further  an  UnCrash  is

             performed en the segment-codes of the currently switched

             segments are computed and stored for use by CurSeg.

             The function IniChk may only  be  called  once  by  each

             MemMan application program. This should be  done  before

             any other MemMan function is called.  TSR  programs  may

             never call the IniChk function.



Name:        Status

Number:      31

Purpose:     Get status data of MemMan

Out:         HL           = Number of present segments

             BC           = Number of free segments

             DE           = Number of segments administered by both 

                            DOS2 and MemMan

             A            = Connected Status of the connected

                            hardware.

                            Bit 0: 1 if the DOS2 Mapper Support

                            Routines are present, 0 otherwise

                            Bit 1-7: Reserved, always 0.



       If bit 0 of the Connected  status  is  set,  the  Mapper

             Support functions of DOS 2.20 are present. The number of

             free segments can be lower than stated in  register  bc,

             because  some  segments  are  used  by  DOS2  after  the

             installation of MemMan -e.g. to install a RAM-disk.  





Name:        CurSeg

Number:      32

Purpose:     Ask for the segment-code of a switched segment 

In:          B            = Page-number (0,1,2,3)

Out:         HL           = Segment-code

             A            = Type of segment (255 = FSeg, 0 = PSeg)



             This routine returns the segment-code of one of the four

             pages. 

             TSR's may not use this function to determine the current

             segment in page 0. To save some time this setting is not

             automatically computed and stored when a TSR is  called.

             The current segments in the pages 1 and  2  however  are

             computed at each call to  a  hook,  and  can  always  be

             asked for using this function. The segment  in  page  3,

             always being the same, can also  be  asked  for  at  all

             times. 

             There is also a FastCurSeg  that  does  the  same  thing

             faster. One can ask for the  address  where  it  can  be

             called directly, using the function Info (50).





Name:        GetTPA

Number:      33

Purpose:     Ask for the@segment-code of a TPA segment

In:          B            = Page number (0,1,2,3)

Out:         HL           = Segment-code

             A            = Type of segment (255 = FSeg, 0 = PSeg)



             The purpose of this function is to make it  possible  to

             use the lower 32 kB of the TPA from a program under Disk

             BASIC. MemMan normally does not use these as they  might

             contain RAM-cartridges, or BASIC's RAM-disk. Use at your

             own risk. Do check whether the segments are  FSEG's,  if

             necessary. Note that the  TPA  segments  should  not  be

             passed to DeAlloc.





Name:        StoSeg

Number:      40

Purpose:     Store the current setting of segments

In:          HL           = Address of a buffer (9 bytes)



             The segment-codes known to  MemMan  are  stored  in  the

             buffer. These codes are normally computed by IniChk  and

             subsequently updated by the Use  functions.  The  stored

             settings are not the current setting but the settings as

             known to  MemMan.  Therefore  TSR's  can  not  use  this

             function to store the current settings.



Remark:      This function may not be called  via  the  EXTBIO  hook.

             This function may only be executed after a  direct  call

             to the MemMan function handler.  One  can  ask  for  the

             addresses where these functions can be called  directly,

             using the function Info (50). Of  course  the  functions

             (Fast)CurSeg can also be used to  ask  for  the  current

             segment settings.





Name:        RstSeg

Number:      41

Purpose:     Make stored segment settings active

In:          HL           = Address of buffer



             The settings stored in the buffer are made active  again

             and are stored for future use by CurSeg.



Remark:      This function may not be called  via  the  EXTBIO  hook.

             This function may only be executed after a  direct  call

             to the MemMan function handler.  One  can  ask  for  the

             addresses where these functions can be called  directly,

             using the function Info (50). Of  course  the  functions

             (Fast)Use can also be used to restore segment settings.





Name:        Info

Number:      50

Purpose:     Give information about amongst others call addresses  of

             MemMan functions

In:          B            = Information number (0..8)

Out:         HL           = Information



             Information number overview. Between parentheses are the

             equivalent MemMan function codes:

             0 - Call address of FastUse0 (function 0)

             1 - Call address of FastUse1 (function 1)

             2 - Call address of FastUse2 (function 2)

             3 - Call address of TsrCall (function 63)

             4 - Call address of BasicCall

             5 - Call address of FastCurSeg (function 32)

             6 - Call address of MemMan, the function handler

             7 - Version-number of MemMan, format: Version #H.L

             8 - Call address of XTsrCall (function 61)

             9 - Call address of GetMMSP

             10 - Call address of SetMMSP



             The  call  addresses  mentioned  above  may  be   called

             directly by an application program or a  TSR.  All  call

             addresses are guaranteed to be in page 3.

             The functions are performed quickly because  the  MemMan

             call to the EXTBIO hook is omitted and function codes in

             D and E need not be parsed. Another  advantage  is  that

             arguments can also be passed using register DE, this  is

             especially  important  for  the  functions  TsrCall  and

             BasicCall.

             E.g. the initialising routine of a TSR can ask  for  the

             call-addresses  of  the  needed  functions   using   the 

             function Info and store them in the TSR program code for

             later use, which can greatly benefit the  speed  of  the 

             TSR.

             An exact description of the functions above can be found

             at the MemMan function of  which  the  number  is  given

             between parentheses. One should  however  bear  in  mind 

             that the  `fast'  functions  differ  from  the  ordinary 

             MemMan functions in the following ways: 



FastUse?:    Switches a segment in a specific memory  page.  Look  at

             the description at the MemMan `Use' functions.



TsrCall:     Register DE is passed to the TSR unchanged. In  contrast

             with  function  (TsrCall),  in  that  case  DE   already

             contains the MemMan function code.



XTsrCall:    All main registers are passed to the TSR unchanged.  The

             TSR-Id code  should be placed in register IX.



BasicCall:   Does not have a MemMan function code.

Purpose:     Call a routine in the BASIC ROM.

In:          IX           = Call address in page 0 or 1

             AF,HL,BC,DE  = data registers for the BASIC-ROM

Out:         AF,HL,BC,E   = data registers from the BASIC-ROM

             Interrupts disabled



             Via this function TSR's can call a  routine  in  page  0

             and/or 1 of the BASIC-ROM.  The  BIOS  must  already  be

             switched in page 0. The BASIC ROM is switched by  MemMan

             in page 1

             This is necessary  for instance to  call  the  math-pack

             routine that are in page 0 of the  BASIC  ROM  but  call

             some routines in page 1 in the mean time.

             The H.STKE (stack error) hook is changed, to  clear  the

             internal stacks of MemMan if a BASIC error occurs.



fastCurSeg:  The returned value  in  register  A  is  undefined.  The

             function CurSeg (32) indicates whether a  segment  is  a

             PSEG or an FSEG 



MemMan:      Does not have MemMan function code

Purpose:     Call a MemMan function directly

In:          E            = MemMan function code

             AF,HL,BC     = Data registers depending on the  function

                            to be called.

Out:         AF,HL,BC,DE  = Data registers depending  on  the  called

                            function.



             A call to this routine has the same effect as calling  a

             MemMan function via the EXTBIO hook. Because the calling

             of the EXTBIO is omitted  other  extensions  using  this

             hook are not called. Due to this,  the  usage  of  stack

             stays limited en the processing speed is increased.



GetMMSP:     Does not have MemMan function code

Purpose:     Ask for the internal MemMan Stack Pointer

In:          Nothing

Out:         HL           = Internal stack pointer of the

                            TSR-Manager.



SetMMSP:     Does not have MemMan function code

Purpose:     Set the internal MemMan Stack Pointer

In:          HL           = New value for the Internal stack pointer

                            of the TSR-Manager.

Out:         Nothing



             TSR's can  use  these  two  functions  to  ask  for  the

             internal stack pointer of MemMan and restore it  when  a

             TSR has not returned neatly to the return address of the

             TSR-Manager.

             That is necessary if  a  program  calls  the  Expression

             Evaluator in the BASIC ROM and wants  to  handle  errors

             itself. The situation may occur  that  ExpEval  calls  a

             TSR, that itself calls ExpEval resulting  in  an  error.

             That would leave junk on  the  MemMan  stack.  If  after

             such errors the error handler  of  MSX  BASIC  is  used,

             there is no problem: then MemMan itself will  clear  its

             own stack.  



             Example:

             ; This is an example of a good invocation of the

             ; expression evaluator in the BASIC ROM, like it

             ; can occur in a program.

             ...

             ld (saveSP),sp          ;Store SP of TSR-program

             call getMMSP

             ld (saveMMSP),hl        ;Store SP of MemMan

             invocation frmEval      ;Evaluate expression (BIOS)

             ...

             jp main



             ; This routine is connected to H.ERRO

             ; it is called if there was an error

             ; in the expression

             ld sp,(saveSP)          ;Restore the TSR-stack

             ld hl,(saveMMSP)

             call setMMSP            ;Restore the MemMan stack

             jp main                 ;Act as if nothing  happened





Name:        XTsrCall

Number:      61

Purpose:     Call the driver-entry of a TSR

In:          IX           = ID code of the TSR to be called

             AF,HL,BC,DE  = passed unchanged to the TSR

Out:         AF,HL,BC,DE  = returned unchanged from the TSR



             This function is an improved  version  of  the  function

             TsrCall  (63).  Because  with  the  function  all   main

             registers can  be  used  for  passing  arguments  it  is

             recommendable to use this function instead  of  function

             63.



Remark:      This function may not be called  vie  the  EXTBIO  hook,

             because the IX register is altered when a call to EXTBIO

             is made. Call this function directly or use  the  MemMan

             function handler. One can ask for  the  addresses  where

             these  functions  can  be  called  directly,  using  the

             function Info (50). 





Name:        GetTsrID

Number:      62

Purpose:     Determine TSR ID code

In:          HL           = Pointer to the TsrName (12 characters).

                            Fill unused positions with spaces.

Out:         Carry        = Clear (NC) if the TSR is found,  Set  (C)

                            if the TSR is not found,

             BC           = TSR ID code





Name:        TsrCall

Number:      63

Purpose:     Call the driver-entry of a TSR

In:          BC           = ID code of the TSR to be called

             AF,HL,DE     = passed unchanged to the TSR.

Out:         AF,HL,BC,DE  = returned unchanged from the TSR.



             Note that though DE is passed unchanged to the  TSR,  it

             can not be used  to  pass  arguments  to  the  TSR.  The

             Extended BIOS function code of MemMan (D='M' E=63)  must

             be placed in this register. This is not the case for the

             Fast-TsrCall routine; one can ask  for  the  address  of

             this routine using the function Info (50)





Name:        HeapAlloc

Number:      70

Purpose:     Request space in the heap

In:          HL           = requested size of the space (in bytes)

Out:         HL           = &h0000 if there was insufficient space,

                            else the starting address of the space.



             One can allocate a piece of memory using this  function.

             The memory block is guaranteed to be in page 3.

             The heap is primarily of use to  TSR-programs  That  can

             use it as  temporary  or  permanent  disk-buffer.  Other

             buffers - that really must be in page 3 - can be  placed

             in the heap as well. Allocated blocks in the heap remain

             unusable  to  other  programs  until  a  HeapDeAlloc  is

             executed (function 71).

             One can set the size of the heap using the configuration

             program CFGMMAN.





Name:        HeapDeAlloc

Number:      71

Purpose:     Release allocated space in the heap

In:          HL           = Start-address of the space





Name:        HeapMax

Number:      72

Purpose:     Return the length of the largest free block in the heap.

Out:         HL           = Length of the largest free block





Appendix 1: BIOS-calls under Turbo Pascal

  If inter-slot-calls to the BIOS are used in a  program  written  in

Turbo Pascal it is important that the stack is in page  2  or  3.  In

that case MemMan can safely activate a TSR  when  the  BIOS  calls  a

hook. The position of the stack is dependent of the  maximum  program

address to which Turbo Pascal is  configured.  In  Turbo  Pascal  the

stack is directly below the memory used for variables. Therefore  the

memory for variables should be placed well above address &h8000.

  If no source is available, one can still change the  stack  address

of  programs  written  in  Turbo  Pascal  using   a   debugger.   The

initialising code of a TP program looks as follows:



  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 contains the stack address, this

         ld bc,nn       ; only needs to be changed if it is 

         call zz        ; lower than &h80A0

         ...



The stack address in register DE can be set to e.g. &hC100. 





Appendix 2: Hints and directions for programmers

  Because the EXTBIO hook is used for various system extensions  like

KANJI and RS232 interfaces, it is possible that MemMan function calls

are processed very slowly. One can  increase  the  performance  of  a

MemMan application significantly by calling the function  handler  of

MemMan directly instead of the EXTBIO  hook.  One  can  ask  for  the

address where the function handler can be called, using the  function

Info (50). Starting from version 2.4 the function IniChk also returns

the  address  of  the  function  handler  in  HL,  this  address  can

immediately be stored in the program.

  Most MemMan functions reside in a special memory segment in page 1.

These functions switch to an internal  stack,  due  to  which  MemMan

applications can have a relatively small  stack.  A  MemMan  function

places at most twenty bytes on the stack of an application.  This  is

only valid if the function is called directly or by a direct call  to

the MemMan function handler. A function call via the EXTBIO hook  can

require a very big stack. This is because all  extensions  linked  to

the EXTBIO hook call each other until  one  of  them  recognises  the

call. When interrupts have to be handled in the same time, the  Stack

use can rise a lot. This is another reason to use the MemMan function

handler instead of the EXTBIO hook.



  MemMan version 1.1 contains some bugs that are solved in version 2.

The advantage of MemMan 1.1 is that it does not use an extra segment,

and therefore works on computers  with  only  64  kB  memory.  It  is

however not worth the trouble to keep MemMan 1.1 up to date for  this

limited group. To make a program work on a 64 kB computer  we  advise

to switch and use 64 kB in  the  program  itself  if  MemMan  is  not

present. One could even use the whole mapper. Under DOS MemMan is not

needed to use 64 kB and under MSX Basic it can  not  be  done  neatly

with MemMan 1.1.  MemMan  version  1.1  will  not  be  developed  any

further.



  When programming TSR's one can use, starting from version 2.4,  the

MemMan function handler on address &h4002  that  is  present  in  all

TSR-segments. This makes the code for TSR's faster and much easier to

read.



  Always use the BIOS-routines when writing  to  the  VDP  registers.

This keeps the system variables in page 3 up to date and  some  TSR's

(CurBlink, screen-savers, debuggers, memory  viewers) use  these.  To

determine e.g. the the active screen  mode  or  the  address  of  the

sprite-tables. Writing to the palette registers should also  be  done

using the BIOS to keep the information in the VRAM up to  date.  Only

when the VRAM is really needed for other things (e.g. in  case  of  a

VDP(24)-scroll) one has to do otherwise.



  Disable interrupts when sending of block of data to the VRAM. It is

possible that a TSR that activated in the  mean  time,  accesses  the

VRAM, changing the read/write pointer in the VDP. Be aware that  some

BIOS routines enable interrupts themselves. In these  cases  one  can 

use the interrupt enable bit in the VDP in the main program (or in  a

TSR but than this  bit  should  be  read  and  restored  afterwards).

Resetting this bit stops interrupts from being generated by the  VDP. 

A DI should still be used as there are also cartridges that  generate

interrupts, but it is somewhat safer.



  Requesting a segment (ALLOC) from an  interrupt routine  can  cause

hanging the machine. This is because DOS2 is not reentrant.  If  DOS2

is active at the time of an interrupt and DOS2 is called  again  from

the interrupt routine, the internal  stack  of  DOS2,  amongst  other

things, is overwritten. And  ALLOC  calls  the  DOS2  Mapper  support

routines (if DOS2 is present). This problem  presumably  occurs  with

DEALLOC in the same way. Experience with the printer-buffer has shown

that USE causes no problem at all.



  Limit the number of  segments  a  program  requests  to  a  certain

maximum. There are 4MB Memory Mappers, and it is not too  complicated

to connect eight of them to one MSX using  two  slot-expanders.  This

gives a total memory of over 32 MB (2048 segments).  Requesting  more

segments than necessary only wastes time and space. By  the  way,  BK

for instance has a limit as well,  it  requests  at  most  4  MB.  In

version 1.02 however things still go wrong if these 4 MB are actually

available... The solution is to install a  RAM-disk or printer-buffer

that is big enough to make the available memory less  than  4MB.  The

word-processor TED does it right  it  requests  at  most  2  MB  from 

MemMan.

   

  It is practical to let TSR's  that  extend  BASIC  in  one  way  or

another, recognise `CMD HELP' and  print  a  small  overview  of  the

possibilities. Do not set the `QuitHook'-flag  and  leave  the  stack

unchanged to have the CMD HELP's of other TSR's (and finally the  one

of `MST TsrUtils', that  suppresses  the  error  messages  of  BASIC)

executed as well.



  Never forget to test for the  presence  and  (also  in  TSR's)  the

version number of MemMan. Require at least 2.3(1),  or  even  better:

2.4. This version can be spread together with the program so it  need

not be a limitation.



  It is often convenient to put the current segment  in  page  2  and

(for programs under Disk Basic) the TPA-segments 0 and  1,  that  can

now be determined with the function GetTPA, in the table of segments.

Note that DeAlloc should not be called  for  these  segments.  MemMan

does not check the segment-codes passed to DeAlloc and starts  making

errors.



** End **

