{ This is the doc file of mapper.inc } {Kari Lammassaari /Finland } MAPPER.INC requires MSXDOS2, beacuse it uses EXTBIO hook at #ffca . MAPPER.INC makes possible to allocate, free ,read , write and call any of the pages in memory mappers available . So Your Turbo Pascal can use and utilize all the memory of Your MSX computer. MAPPER.INC allows your program to load a machine code on any page and call it from there (Input/return values in a,bc,de,hl,ix and iy ). REM ! USE MapperSupport function to check availability of mapper support and initialize mapper.inc variables ! REM ! All procedures and functions use temporary stack at #fbaf (at the end of VCBC) MAPPER.INC contains following contants, types, variables, procedures and fuctions: Const UserPage = 0 ; {This pagetype is automaticly free'ed upon the end of the user program.} SystemPage = 1;{This pagetype remains allocated until free'ed by FreeMapperPage. LoadChnFile and LoadMCFile use this type.} Type MapperTableType = Record {Every memory mapper has this table entry.} SlotId :Byte; PagesTotal :Byte; PagesFree :Byte; PagesSystem:Byte; PagesUser :Byte; Dummy1,Dummy2,Dummy3 :Byte; End; MapperTablePtrType = ^MapperTableType; {Used internally} Var MapperCount :Byte; MapperTablePtr :MapperTablePtrType; MapperTableAddr :Integer Absolute MapperTablePtr; PrimaryMapper :Byte; {Updated by function MapperSupport} SecondaryMapper :Byte; {If there is only one mapper SecondM = PrimM } WantedMapper :Byte; {You can set this to Primary/SecondaryMapper.} {Defaults PrimaryMapper, which is faster.} JumpTablePtr :Integer; {Addr of mapper support routine jump table} bc,de,hl,ix,iy :Integer; {These return values from CallMapperPage. } Function MapperSupport(Var MapperCount:Byte):Boolean; { Checks the existence of mapper support and initializes Turbo Pascal mapper variables MapperCount,MapperTablePtr,MapperTableAddr,PrimaryMapper SecondaryMapper,WantedMapper and JumpTablePtr. The WantedMapper defaults faster PrimaryMapper, but You can set it to SecondaryMapper, if You prefer it in some cases. MapperCount returns, ofcourse, the number of memory mappers available. If You have more than 2 mappers, Secondary mapper Refers actually the last mapper, but don't worry: System will use all memory available ! First the WantedMapper then the others. REM PrimaryMapper (slot_id) contains some extra bits (bit 5 is set) to force search annother mapper if primary mapper is already exhausted.) } Function AllocateMapperPage( SlotType,PageType :Byte; Var PageId :Integer ):Boolean; { Allocates one Mapper page. PageType can be UserPage (0) or SystemPage (1). SlotType can be PrimaryMapper, SecondaryMapper, WantedMapper or any legal (and reasonable ) slot id. Returns an true,if there was a free mapperpage to allocate. The returned integer value, PageId, will be used with WriteMapperPage, RadMapperpage, FreeMapperPage and CallMapperPage-procedures. Low byte of integer contains slot id of allocated page. High byte contains the page number. } Function FreeMapperPage(PageId:Integer):Boolean; { Frees allocated mapperpage back to system. The pages allocated as SystemPage will remain allocated after the program end. So free them, if they are no more needed. UserPages will be free'ed automaticly. Returns true if freeing succeeded. If not, the PageId was invalid. } Procedure CallMapperPage( SlotId,PageNumber :Byte; CallAddress :Integer; Var A :Byte; Var BC,DE,HL,IX,IY :Integer ); { Calls an routine in any mapper page in any slot. Ofcourse there must be an allocated page containig reasonable code before using this procedure. If You , for some reason, want to use this procedure, use syntax: 'CallMapperPage( Lo(PageId),Hi(PageId),CallAddress,a,bc,de,hl,ix,iy);'. The called routine can set return values in registers A,BC,DE,HL,IX and IY. } Function GetPage(MemoryAddress:Integer):Byte ; { Gets the current page number of the mapper page. Used Internally. } Procedure PutPage(MemoryAddress:Integer;Page:Byte); { Sets the mapper page. Used Internally. REM. You are not allowed to change the page on MemorySegmet at address range #c000 - #ffff. REM. This procedure changes the page, but NOT the slot configuration. } Procedure WriteMapperPage(PageId, SourceAddress,DestinationAddress, ByteCount :Integer); { Writes bytes on any page in any slot. The written page must first allocated by function AllocateMapperPage, which returns the legal page id. Otherwise owerwriting can occur to ramdisk or pages used by MSX operating system . } Procedure ReadMapperPage( PageId, SourceAddress,DestinationAddress, ByteCount :Integer); { Reads bytes from any page in any slot. You can read even MSXDOS2 and ramdisk internal pages, if You find them. PageId := SlotId + 256 * PageNumber; } Function LoadMcFile(FileName:StringType):Integer; { Allocates a mapper page from the mapper pointed by WantedMapper-variable; If there is no free page, tries annother mapper. After allocation loads a machine code program file on allocated page and returns an integer value. Lo(value) = Mapper slotId, Hi(value) = Page number. If NO free pages available or file NOT found value 0000 returned. The mc-code must fit in page , ie. must be smaller than 16Kb. REM. Disk i/o and some BIOS ROM codes cause problems if chn-code is loaded on secondary mapper. To avid this, use primary mapper. The Mc - code must return stackpointer in good condition ! When the code is no more needed, the allocated page must be free'ed by FreeMapperPage procedure. The loading starts from the first byte of the page. If You want to use other loading address, You must write a new loader using msxdos2.inc and WriteMapperPage. } Procedure CallMcPage( PageId,Address:Integer;Var a:Byte;Var bc,de,hl,ix,iy:Integer ); { Calls a Machine code on any mapper page in any slot. Remember that MC must have been compiled to operate at Address given to CallMcPage. Input/Output values can be transferred with predefined variables a,bc,de,hl, ix,iy ,which correspond the Z80 registers or via absolute variables in high memory . }