Sitenotice:
2020: NameSpaces are going to be implemented this year to better separate content. OS-9 Al (talk) 11:18, 15 April 2020 (CDT)
2020-05-17: If a page gives you an error about some revision not being found, just EDIT the page and the old page should appear in the editor. If it does, just SAVE that and the page should be restored. OS-9 Al (talk) 12:22, 17 May 2020 (CDT)

Understanding and Using the MMU

From CoCopedia - The Tandy/Radio Shack Color Computer Wiki
Jump to navigation Jump to search
WELCOME
Looking for CoCo help? If you are trying to do something with your old Color Computer, read this quick reference. Want to contribute to this wiki? Be sure to read this first. This CoCo wiki project was started on October 29, 2004. --OS-9 Al

See Recent Changes. | About this site. | Join the E-Mail List or Facebook Group. | Contact me with updates/questions.

This page was last updated on 04/22/2020. Total Pages: 680. Total Files: 943.


Home / Articles - Understanding and Using the MMU


Understanding and Using the MMU

A “Hopefully Helpful” Text file by
Allen C. Huffman

The 6809 CPU can only access 64K at a time. In order for an 8-bit CPU to access memory beyond that range, some sort of Memory Management Unit must be used. The CoCo 3’s MMU does the job nicely by breaking all of the memory into 8K chunks. The CoCo 3 is set up to handle up to 512K of memory which is addressed from &H0000 to &H7FFFF (0 – 524287). The 6809 will recognize the last 64K in this map (&H70000 to &H7FFFF) as “normal” memory for it. (In Basic, when you do a POKE 1024,42 it is actually putting a 42 in physical memory &H70000 + 1024. (If you do an LPOKE 1024,42 you will actually be putting the 42 in physical memory location 1024.) This may seem strange at this time, but hopefully it will soon be clear.

In a 128K Color Computer, the RAM is located from &H60000 to &H7FFFF. (All memory from &H00000 to &H5FFFF is unusable unless you have 512K in which case your extra memory resides there.) The 128K is broken into two parts. One is the normal 64K workspace that the CoCo uses. The other 64K is used for Hi-Res graphics, screens, etc. (For more detail on where everything is, refer to your CoCo 3 owners manual Memory Map on Page 311.)

Meanwhile, back to the MMU, all of the CoCo’s memory is handled internally as 8K blocks. Thus, a 64K workspace is actually 8 MMU blocks. (8 x 8K is 64K, right?) The MMU can access any of these 8K blocks by using the corresponding block number. The blocks are numbered as follows:

##    Memory Range      ##   Memory Range      ##   Memory Range
00    00000 - 01FFF     10   20000 - 21FFF     20   40000 - 41FFF
01    02000 - 03FFF     11   22000 - 23FFF     21   42000 - 43FFF
02    04000 - 05FFF     12   24000 - 25FFF     22   44000 - 45FFF
03    06000 - 07FFF     13   26000 - 27FFF     23   46000 - 47FFF
04    08000 - 09FFF     14   28000 - 29FFF     24   48000 - 49FFF
05    0A000 - 0BFFF     15   2A000 - 2BFFF     25   4A000 - 4BFFF
06    0C000 - 0DFFF     16   2C000 - 2DFFF     26   4C000 - 4DFFF
07    0E000 - 0FFFF     17   2E000 - 2FFFF     27   4E000 - 4FFFF
08    10000 - 11FFF     18   30000 - 31FFF     28   50000 - 51FFF
09    12000 - 13FFF     19   32000 - 33FFF     29   52000 - 53FFF
0A    14000 - 15FFF     1A   34000 - 35FFF     2A   54000 - 55FFF
0B    16000 - 17FFF     1B   36000 - 37FFF     2B   56000 - 57FFF
0C    18000 - 19FFF     1C   38000 - 39FFF     2C   58000 - 59FFF
0D    1A000 - 1BFFF     1D   3A000 - 3BFFF     2D   5A000 - 5BFFF
0E    1C000 - 1DFFF     1E   3C000 - 3DFFF     2E   5C000 - 5DFFF
0F    1E000 - 1FFFF     1F   3E000 - 3FFFF     2F   5E000 - 5FFFF

That covers the 512K area. On a 128K CoCo, you can’t even use blocks 00 to 2F, so let’s look at what you can use:

30    60000 - 61FFF
31    62000 - 63FFF     The first 4 blocks (32K) is where Basic puts the
32    64000 - 65FFF     HSCREEN graphics.
33    66000 - 67FFF

34    68000 - 69FFF     This is where the HGET/HPUT buffer is. (8K)

35    6A000 - 6BFFF     This is the secondary stack area. (8K)

36    6C000 - 6DFFF     This is where the 40/80 column screen goes. (8K)
37    6E000 - 6FFFF     And this one is unused by Basic. (8K)

That takes care of the 64K you don’t have direct access to on startup. Here is the 64K you do have access to:

38    70000 - 71FFF     The first 32K is normal system RAM.  (System use,
39    72000 - 73FFF     32 column text screen. PMODE graphics, Basic program
3A    74000 - 75FFF     and variable storage)
3B    76000 - 77FFF

3C    78000 - 79FFF     The last 32K is where system ROM goes.   (Note that
3D    7A000 - 7BFFF     on the CoCo 3, all ROM is copied into RAM so these
3E    7C000 - 7DFFF     locations are indeed RAM.)
3F    7E000 - 7FFFF

(Notice that all you have to do to convert physical locations to normal 8 bit locations on the older CoCo’s is to remove the 7.)

So now you should have some idea of how memory is looked at, but how do you actually use it? Eight memory locations control what physical block of memory goes where. Let’s have another chart…

FFA0    0000 - 1FFF      Remember those block numbers given earlier?
FFA1    2000 - 3FFF      On startup, FFA0 - FFA7 contain:
FFA2    4000 - 5FFF
FFA3    6000 - 7FFF      78, 79, 7A, 7B, 7C, 7D, 7E, & 7F.
FFA4    8000 - 9FFF
FFA5    A000 - BFFF      WHY?  Shouldn't they be 38, 39, 3A, etc, as the
FFA6    C000 - DFFF      block numbers would indicate?  Read on...
FFA7    E000 - FFFF

The MMU locations have bit 6 set high which adds &H20 (64) to their actual value. Therefore, to the MMU 38 is the same as 78, 3E is the same as 7E, etc. The CoCo 3 Service Manual indicates that programmers may use any blocks in the range of 00-3F so we will go by that. Please try not to let this confuse you! Just accept it.

In order to use the MMU from Basic, you simply use the POKE command to tell the MMU what “block” goes where. For instance, location &HFFA2 contains 7A on startup. Anytime you peek memory between 4000-5FFF it is actually PEEKing from block 3A which is physical locations 74000-75FFF. You can change this by POKEing to it. If you POKE &HFFA2,&H30 then anytime you PEEK or use memory in the range of 4000-5FFF it will actually be coming from physical memory 60000-61FFF. Whatever was in block 3A is still there, but when you try to use that memory, the MMU points the CPU to somewhere else. The CPU never knows the difference! To get it back as before, POKE &HFFA2,&H3A.

You may now have a slight understanding of how those Basic HSCREEN save/load routines work. Take a look:

10 INPUT "Save picture as";N$
20 FOR A = &H30 TO &H33
30 POKE &HFFA2,A
40 SAVEM N$+"/HR"+CHR$(A-&H2F),&H4000,&H5FFF,0
50 NEXT A
60 POKE &HFFA2,&H3A

Line 10 simply asks for what to save the picture as. Line 20 does a loop. If you notice 30-33 is the physical location of the hi-res HSCREENs. The poke in line 30 switches the physical location pointed to by “A” into CPU location 4000-5FFF. (The first time through, block 30 is there, then 31, then 32, etc.) After this, line 30 does a SAVEM of whatever is now at that location. (It tags the extension of HR at the end followed by a number 1-4). Line 50 continues the loop and line 60 restores the memory like it was before this routine.

Programmers out there might think this is strange seeing a program save the same contents of memory (4000-5FFF) four times, but that is where the magic of the MMU comes in. Thanks to the POKE, each time the program gets to that line the MMU points to a different area. To load a file back in, a similar routine must be used that flips the MMU to that area then, after loading, flips it back where it goes. It might look something like this:

10 INPUT "Load picture";N$
20 INPUT "HSCREEN #";H
30 HSCREEN H
40 FOR A = &H30 TO &H33
50 POKE &HFFA2,A
60 LOADM N$+"/HR"+CHR$(A-&H2F)
70 NEXT A
80 POKE &HFFA2,&H3A

If you can understand why this program works, you are in good shape. By theory, someone could save the entire memory of the Color Computer to disk in 8K chunks using the above method. (Why? I don’t know, but they could…)

Now if you still don’t see how this works, try this experiment. Enter the following line which will fill up physical block &H37 (6E000-6FFFF) with the value of 42.

FOR A=&H6E000 TO &H6FFFF:LPOKE A,42:NEXT A

Okay. So all the memory from 6E000 to 6FFFF should have 42s in it, right? Right. (To verify, you could do FOR A=&H6E000 TO &H6FFFF:PRINT LPEEK(A):NEXT A and you would get 42s back.)

Somewhere in memory we have a block of 42s. We can make that block appear to be somewhere else. Try a POKE &HFF2A,&H30. You have just set it so whenever the CPU looks at locations 4000-5FFF it will really be looking at 60000-61FFF. Confirm this and try:

FOR A=&H4000 TO &H5FFF:PRINT PEEK(A);:NEXT A

You will see a bunch of 42s. Magic, right? No, just amazing. Still not convinced? Type POKE&HFF2A,&H3A and try that previous line again. What happened to the 42s? They are still where they were originally but, the CPU is being directed back to where it was supposed to be.

This is just the start of what the MMU can do. There is another bank of MMU registers from FFA8 to FFAF. These are being used by the CoCo itself while in basic, but any machine language programmer could define each set of MMU registers and then by toggling a single bit (bit 0 of FF91) he could select between which MMU map would be used.

If you still haven’t got it, leave a message for me and I will do my best to answer questions or to create another file that further explains the MMU.