.SP2. @OVERLAY^PROGRAMS. . The AEMS provides you with a large memory. The 9900 microprocessor in the TI 99/4A, however, is limited to a 16 bit address or a 64K "address space". Further, half of this 64K address space is dedicated to special purpose code -- DSR ROM, OS ROM, Cartridge ROM/RAM, etc.. . To provide access to the large memory, AEMS "maps" 4K "pages" into the microprocessor's address space at addresses >2000, >3000, >A000, >B000, >C000, >D000, >E000 and >F000. This gives access to 8 different 4K pages of RAM at any one time in addition to the 8K of unmapped RAM that may be in a cartridge at address >6000 or any DSR RAM at address >4000.. . While programming in a mapped memory environment is not as easy as programming in a large linear address space, it is very nice to have large quantities of RAM available directly to the microprocessor. In programs there are two almost independent uses of memory. The first use is for the executable code of a program and the second is for the data on which a program works.. . The AEMS LINKER with its "overlay" processing solves some of the large code problem. The library routines provided with the AEMS solve some of the large data problem. Both the LINKER and the library routines provide the programmer access to the large memory without having to know the details of how the memory mapping works and without having to write extra code. (Section 'SYSTEM INFORMATION' gives the details for those who want them).. . Writing any large program requires some discipline on the programmer's part. This discipline is even more important if the program is to execute in a small address space via a mapping mechanism. It is &always good practice to subdivide a large program into relatively small subroutines. It is also &always good practice to make these subroutines "independent". An independent subroutine is one that depends only on clearly defined data: data passed as parameters, data in a defined "COMMON" area, or data defined and contained within itself.. . If the code in a large program consists of a main program and several independent subroutines with a "calling pattern" that can be diagrammed as a "tree" then that program can be segmented into an "overlay structure" by the LINKER. All code to perform the overlay (or mapping in and out of pages) can be added automatically by the LINKER without the programmer having to explicitly write code to perform the function. The programmer's task is simply to write his program as a series of "small" independent subroutines, which is good programming practice in any event.. . In order to demonstrate what we are talking about here we will use an example. Suppose we have a well designed and written "large" program. The source for the program is shown below, written in a "pseudo" language.. .SP;IN+5. * Main Program. ^^^^CALL INIT. ^^^^CALL PASS1. ^^^^CALL PASS2. ^^^^CALL ENDUP. ^^^^END. . . * Initialization Subroutine. ^^^^ENTRY INIT. ^^^^SETUP VDP. ^^^^SETUP TABLES. ^^^^GET USER INPUTS. ^^^^OPEN FILES. ^^^^RETURN. ^^^^END. . * Pass 1 Processing. ^^^^ENTRY PASS1. ^^^^CALL GETREC. ^^^^CALL BLDTBL. ^^^^LOOP TILL EOF. ^^^^RETURN. ^^^^END. . * Pass 2 Processing. ^^^^ENTRY PASS2. ^^^^CALL GETTBL. ^^^^CALL PUTREC. ^^^^LOOP TILL END OF TABLE. ^^^^RETURN. ^^^^END. . * End of Program Processing. ^^^^ENTRY ENDUP. ^^^^CLOSE FILES. ^^^^ISSUE MESSAGES. ^^^^RETURN. ^^^^END. . * Get Input Records. ^^^^ENTRY GETREC. ^^^^GET RECORD. ^^^^CHECK RECORD. ^^^^RETURN. ^^^^END. . * Output Record. ^^^^ENTRY PUTREC. ^^^^BUILD OUTPUT RECORD. ^^^^PUT RECORD. ^^^^RETURN. ^^^^END. . * Build Data Tables. ^^^^ENTRY BLDTBL. ^^^^ENTER DATA FROM RECORD. ^^^^RETURN. ^^^^END. . * Lookup Table Entry. ^^^^ENTRY GETTBL. ^^^^CALCULATE TABLE POSITION. ^^^^PICK OUT VALUES. ^^^^RETURN. ^^^^END. .SP;IN+0. In this program we have a main program and 8 subroutines. This is a "large" program, so let's assume each of these routines is just under 8K bytes. Then our large program is 9 x 8K = 72K bytes, which is indeed a large program for the TI 99/4A with 32K RAM.. .BP. Now, let's view the "calling tree" of this program. It is shown below.. .SP;AI;LM+5. --- | | +--------+ | | | 8K | MAIN | | | | | +--------+ | / . . \ | / \ --- / . . \ | / \ | / . . \ | +------+ +------+ +------+ +------+ 8K | | | | | | | | | |INIT | |PASS1 | |PASS2 | |ENDUP | | | | | | | | | | | +------+ +------+ +------+ +------+ | / | | \ --- / | | \ | / | | \ | / | | \ | / | | \ | +------+ +------+ +------+ +------+ 8K | | | | | | | | | |GETREC| |BLDTBL| |GETTBL| |PUTREC| | | | | | | | | | | +------+ +------+ +------+ +------+ | --- .SP;FI;AD;LM-5 You can see from the diagram that, while the total program size is 72K, the depth of the calling tree is only 24K. The depth of the tree (or addressing space required) is the important measurement in a mapped memory environment.. .BP. Now, let's look at the addressing space and RAM availability of the TI 99/4A with AEMS.. .SP;AI;LM+5. +-------+. >0000 | | ROM OS. +-------+. >1000 | | ROM OS. +-------+-------+-------+--. >2000 |(1)2000|(2)2000|(3)2000| ...^Mapped RAM. +-------+-------+-------+--. >3000 |(1)3000|(2)3000|(3)3000| ...^Mapped RAM. +-------+-------+-------+--. >4000 | | DSR ROM. +-------+. >5000 | | DSR ROM. +-------+. >6000 | | Cartridge ROM/RAM. +-------+. >7000 | | Cartridge ROM/RAM. +-------+. >8000 | | Special (VDP, PAD) +-------+. >9000 | | Special (GROM, SPEECH) +-------+-------+-------+--. >A000 |(1)A000|(2)A000|(3)A000| ... Mapped RAM +-------+-------+-------+--. >B000 |(1)B000|(2)B000|(3)B000| ... Mapped RAM +-------+-------+-------+--. >C000 |(1)C000|(2)C000|(3)C000| ... Mapped RAM +-------+-------+-------+--. >D000 |(1)D000|(2)D000|(3)D000| ... Mapped RAM +-------+-------+-------+--. >E000 |(1)E000|(2)E000|(3)E000| ... Mapped RAM +-------+-------+-------+--. >F000 |(1)F000|(2)F000|(3)F000| ... Mapped RAM +-------+-------+-------+--. .SP;FI;AD;LM-5. This diagram shows the fixed area of the TI 99/4A addressing space and shows the mapped area with each 4K having the possibility of being mapped to several different pages of extended RAM.. .BP. Now we can see that it is possible to map our "large" program into the AEMS as shown below.. .SP;AI;LM+5. +------+. ROOT >2000 | |. >3000 |MAIN |. +------+. . +------+ +------+ +------+ +------+. LEVEL1 >A000 | | | | | | | |. >B000 |INIT | |PASS1 | |PASS2 | |ENDUP |. +------+ +------+ +------+ +------+. +------+ +------+ +------+ +------+. LEVEL2 >C000 | | | | | | | |. >D000 |GETREC| |BLDTBL| |GETTBL| |PUTREC|. +------+ +------+ +------+ +------+. . +------+. Free >E000 | |. >F000 | |. +------+. .SP;FI;AD;LM-5. This mapping, of course, assumes that the CALLs somehow map in the correct pages at the correct addresses. The primary function of the overlay processing in the LINKER is to supply the code necessary to do the mapping at each CALL. It does this by building a small stub for each called routine in the caller's section plus a small overlay manager routine in the root section.. . This overlay technique can be a powerful tool. In our example we have a 72K program and yet still have 8K of address space free (>E000 to >FFFF). The LINKER control statements necessary to produce the overlay program for the above example are shown in Examples 9 and 10 later in this manual.. . To summarize overlaying:. .LM+5;IN-4. ^1.^The program must be written as small independent relocatable subroutines.. ^2.^All CALLs must be made up and down the tree branches not across the branches.. ^3.^All CALLS must be via the BLWP instruction.. ^4.^No code is written in the program for overlaying. The overlay structure is specified in the LINKER control file and the LINKER inserts the code necessary to perform the overlay mapping.. ^5.^The CALL stub for each overlayed subroutine is 16 bytes. CALLs within an overlay or towards the root of the tree have no overhead.. ^6.^The overlay manager code inserted into the root segment is 60 bytes in size.. ^7.^The mapping hardware works on 4K blocks in the >2000 to >3FFF and >A000 to >FFFF addressing ranges giving a maximum of a root section and 7 levels of overlay. Minimum size of an overlay is 4K.. ^8.^The overlays must occur at 4K boundaries. The LINKER automatically adjusts section sizes rounding them up to the next 4K boundary.. ^9.^The lengths of the various sections at a single overlay level do not have to be the same. The total depth of the CALL tree is 24K plus 8K.. 10.^Each overlay section consists of one or more object code files plus possible routines from libraries. That is, an overlay section can contain more than one subroutine.. 11.^The same subroutine code can be placed in different overlays on different branches. REFs are resolved up and down branches of the tree not across the call tree.. 12.^The LIBRARY statement must be used in each overlay section if resolution of REFs from the library is desired.. .LM-5;IN+0;SP2. @SUBROUTINE^LIBRARIES. . On the LINKER distribution disk is a library of object routines, RAGLIB. This is the same library distributed with the TI 99/4A versions of LINKER. It is for use with "standard" E/A Option 5 programs.. . With the AEMS card is shipped a Library disk with a linker library, AEMSLIB, which contains routines specifically written for the AEMS.. . &RAGLIB^Routines. . The RAGLIB library contains the following routines:. .IN+5;SP. DSRLNK^Device Service Routine Link. GPLLNK^GPL Subroutine Link. KSCAN^^Keyboard Scan. XMLLNK^Link to ROM routines. VMBR^^^VDP Multi Byte Read. VMBW^^^VDP Multi Byte Write. VSBR^^^VDP Single Byte Read. VSBW^^^VDP Single Byte Write. VWTR^^^VDP Write To Register. .IN+0;SP. Which perform the same functions as the routines described in the Editor/Assembler or Mini Memory manuals. The routines are all separate so that when the library is searched by LINKER only those routines that are actually used will be loaded. These routines (in particular GPLLNK) will work no matter which cartridge is used to load the memory image program. They are all relocatable object modules, and are not necessarily loaded into low memory as they are by E/A.. . Note also, that the information about the DSR routine left in memory by the E/A and MM DSRLNK routines is ¬ left by the library DSRLNK.. ...................... EXIT - Exit from program. . Exits from a program and returns to the AEMS Loader. This is the recommended way to end an AEMS program rather than using BLWP @@0 or some other method.. . FREE - Free AEMS pages. . Frees a previously allocated block of pages for reuse.. Parameters:. ^^^^^pageno^^-^^number of the first page of the block. ^^^^^npages^^-^^number of pages to free. . MOVE - Move data in RAM. . Moves data from one page to another. The pages need not be mapped into the 4A's address space.. Parameters:. ^^^^^Fpageno -^^from extended page number. ^^^^^Foffset -^^offset in the from page. ^^^^^Tpageno -^^to extended page number. ^^^^^Toffset -^^offset in the to page. ^^^^^length^^-^^length in bytes of data. . VREAD - Read from VDP. . Reads data from the VDP into a page of extended memory. The page need not be mapped into the 4A's address space.. Parameters:. ^^^^^Vaddr^^-^^VDP address. ^^^^^pageno -^^extended page number. ^^^^^offset -^^offset within the page. ^^^^^length -^^length in bytes of data. . VSET - Setup VDP. . Loads VDP registers and tables for "standard" modes.. Parameters:. ^^^^^Mode^^^-^^0 - graphics mode. ^^^^^^^^^^^^^^^1 - text mode. ^^^^^^^^^^^^^^^2 - XB graphics mode. ^^^^^Chars^^-^^0 - standard character set. ^^^^^^^^^^^^^^^1 - true lower case letters. . VWRITE - Write to VDP. . Writes data to the VDP from a page of extended memory. The page need not be mapped into the 4A's address space.. Parameters:. ^^^^^Vaddr^^-^^VDP address. ^^^^^pageno -^^extended page number. ^^^^^offset -^^offset within the page. ^^^^^length -^^length in bytes of data. ...................... ^^^^^^^^^>05^Load into GRAM 4 at >8000.. ^^^^^^^^^>06^Load into GRAM 5 at >A000.. ^^^^^^^^^>07^Load into GRAM 6 at >C000.. ^^^^^^^^^>08^Load into GRAM 7 at >E000.. ^^^^^^^^^>09^Load into ROM BANK 1 at >6000.. ^^^^^^^^^>0A^Load into ROM BANK 2 at >6000.. ^^^^^^^^^>A0^AEMS non-overlay program or overlay root.. ^^^^^^^^^>A1^AEMS overlay segment.. .LM-13;IN+0;SP. &Standard^program^files consist of the exact contents of memory written to a disk. A memory image program may be split into two or more segments depending upon the length of the program. Each of the segments is written to a separate disk file. Option 3 of TI WRITER will load a segment with a maximum size of >2000 while Option 5 of Editor/Assembler will load a segment with maximum size of >2400 bytes. LINKER produces segments with a maximum length of >1FFA. The name of the first segment is specified and the names for all following segments is derived by adding 1 to the last byte of the name of the previous segment. Each memory image file has a 3 word (or 6 bytes) header that indicates to a loader where in memory to load the program. The header is:. .SP;LM+7;IN-7. WORD^1^Flag word as described above.. WORD^2^Length of code in this segment in bytes. Note that the length of the segment on disk is 6 bytes more to include the 6 bytes of header information.. WORD^3^Address at which this segment is to be loaded.. .LM-7;IN+0;SP. NOTE that the length of the memory image program may not be the same as the length of the tagged object program. This can be caused by a work area that has no code or data loaded into it occurring at the end of the program. LINKER will not waste disk space writing out an area that you have not filled with code or data. In fact, if your program contains areas inside the program that are unused and which exceed 518 bytes in size LINKER will break the program at that point and create two separate segments. The 518 bytes is the overhead for creating another file -- 1 sector for the disk catalog, 1 sector minimum for a file and 6 bytes of header information per file.. . The &AEMS^Program^File format is a bit more complicated than the standard in order to accomadate the much larger memory size and features of the AEMS system.. . The header for an AEMS program or root segment of an overlay program is as follows.. .SP;LM+7;IN-7. WORD^1^Flag >FFA0 or >00A0.. WORD^2^Length of code in this segment in bytes.. WORD^3^Address at which this segment is to be loaded.. WORD^4^Total number of pages of memory required for the overlay program. This number does not include the two pages at >2000 and >3000. If this number is zero then the program is not an overlay program.. WORD^5^Number of bytes in the "page relocation table" which begins at WORD 6. This may be zero.. WORD^6^If there are page relocation entries (WORD 5 is non-zero) then each word in the table is the address of a word containing a "relative page number" which is to be relocated.. .SP;LM-7;IN+0. Note that there may be more than one root segment in a program and that the root segment may be loaded in the high memory area >A000 to >FFFF. If there is more than one root segment WORD 4 (number of pages required) will be identical in all segments. It is redundant in all but the first segment.. . The header for an AEMS overlay segment is as follows. .SP;LM+7;IN-7. WORD^1^Flag >FFA1 or >00A1.. WORD^2^Length of code in this segment in bytes.. WORD^3^Address of this segment when it is mapped in for execution. The last 12 bits of this address is the offset within the relative page at which this segment is loaded.. WORD^4^Relative page number of this segment.. WORD^5^Number of bytes in the "page relocation table" which begins at WORD 6. This may be zero.. WORD^6^If there are page relocation entries (WORD 5 is non-zero) then each word in the table is the address of a word containing a "relative page number" which is to be relocated.. .SP;LM-7;IN+0. Note that an overlay segment may be more than one page in length.. . . &Overlay^Code. . The "Overlay Manager" code shown below is added to the root segment of a program by the LINKER.. .SP;AI. * Map in N sequential pages and. * simulate BLWP call to subroutine.. *. OVMGR SBO 0 enable mapper regs. MOV *R11+,R10 Get N, # pages. MOV *R11+,R9 Get 1st mapper reg. MOV *R11+,R7 Get 1st page #. OVMGR2 MOV R7,*R9+ Set mapper reg INC R7 Incr page #. DEC R10 Loop for N pages. JGT OVMGR2. SBZ 0 Disable mapper regs. MOV *R11,*R11 Get real BLWP vector. MOV *R11+,R7 Get WSP. MOV *R11,R9 Get branch addr. MOV R13,@@26(R7) Simulate BLWP. MOV R14,@@28(R7). MOV R15,@@30(R7). OVMGRW EQU $-12 OVMGR workspace. * CALL user subroutine. LWPI 0 R6,R7 Load user WSP. B @@0 R8,R9 Go to user sub. BSS 2 R10. BSS 2 R11. DATA >1E00 R12 Mapper CRU addr. BSS 6 R13-R15. .SP;FI;AD. Shown below is the "stub" inserted by the LINKER for each subroutine call that causes an overlay.. .SP;AI. OSUB DATA OVMGRW Overlay Manager. DATA $+2. BL @@OVMGR Call manager. DATA N # pages in overlay. DATA >400X 1st mapper reg addr. DATA n 1st page number. DATA sub real BLWP vector. .FI;AD;SP2. &AEMS^Mapper. . AEMS uses the Texas Instruments SN74LS612 memory mapper chip along with additional logic to map the high memory addresses from a 16 bit address to a 23 bit address. A 23 bit address accomadates a 4 Megabyte memory. . This mapping is done by splitting the TI 99/4A 16 bit address into two parts: a 4 bit page number and a 12 bit page offset. The 12 bit page offset gives a 4K page. The 4 bit page number is used to select a "mapper register" containing an 11 bit page number. The 11 bit expanded page number is combined with the original 12 bit page offset to give a 23 bit expanded memory address.. . The mapper can be inactive or active. When the mapper is inactive the TI99/4A will operate as though it had an ordinary 32K memory card. At power on, the mapper is inactive.. . The mapper is activated by setting a CRU bit (>1E02) to one. When active only addresses >A000 to >FFFF are mapped. Mapping can be turned off by setting the CRU bit to zero.. . The mapper has 6 active "registers" that specify which pages are mapped into the TI99/4A's address space. In order to access these registers (for write or read) the access must be enabled by setting CRU bit >1E00 to one. Access is disabled by setting the CRU bit to zero. The mapper registers are accessed by normal 9900 instructions at the following addresses:. .SP;LM+5. Register^^^Access^at^^^Maps Page. ^Number^^^^^Address^^^^^^in at. ^^^A^^^^^^^^^>40A0^^^^^^>A000. ^^^B^^^^^^^^^>40B0^^^^^^>B000. ^^^C^^^^^^^^^>40C0^^^^^^>C000. ^^^D^^^^^^^^^>40D0^^^^^^>D000. ^^^E^^^^^^^^^>40E0^^^^^^>E000. ^^^F^^^^^^^^^>40F0^^^^^^>F000. .LM-5;SP. The access addresses will respond to instructions just like a normal word of RAM.. . Typical code for operation of the mapper is shown below.. .SP;LM+5. * Load Mapper Registers. ^^^^^^^LI^^^^R12,>1E00^^^^^CRU base address. ^^^^^^^SBO^^^0^^^^^^^^^^^^^Enable register access. ^^^^^^^LI^^^^R0,20^^^^^^^^^Page # 20. ^^^^^^^MOV^^^R0,@@>40A0^^^^^Map page in at >A000. ^^^^^^^LI^^^^R0,50^^^^^^^^^Page # 50. ^^^^^^^MOV^^^R0,@@>40B0^^^^^Map page in at >B000. ^^^^^^^SBZ^^^0^^^^^^^^^^^^^Disable register access. ^^^^^^^SBO^^^1^^^^^^^^^^^^^Turn mapper on. ^^^^^^^MOV^^^@@>A000,R0^^^^^Get 1st word page 20. ^^^^^^^MOV^^^@@>B002,R1^^^^^Get 2nd word page 50. ^^^^^^^SBZ^^^1^^^^^^^^^^^^^Turn mapper off. .LM-5;SP. Only in special cases should the programmer have to manipulate the mapper or its registers directly. Assembler macros and library routines are provided for most routine tasks.. .SP2. @AEMS^LIBRARY^MANAGER. . The AEMS Library Manager is a program to assist you to build and maintain libraries of routines for use by the LINKER.. ......................