home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-07 | 26.3 KB | 607 lines | [TEXT/MPS ] |
- ; Blat:
- ; To fool around with the MMU registers and tables.
- ;
- ; Copyright © 1991 by Apple Computer, Inc., all rights reserved.
- ;
- ; by Bo3b Johnson 8/28/91
- ; MS 37-DS
- ; for best viewing, use Palatino 12.
- ;
- ; Found out you can't do PMOVE to a data register on 030. Weak.
-
- ; Questions:
- ; If I don't go VBR based, then I must know something about Macsbug and where it is
- ; calling from. The problem is that I bust the Macsbug bus error stuffing, and then call
- ; DebugStr, which leads to wedge-city. If VBR based, then Macsbug stuff there, for most,
- ; but seems to have something else that causes it to freak out.
- ; -- turns out to have been Macsbug calling the video driver to switch modes, and
- ; that code installed a bus error handler.
- ; Do I need to flush the Data cache for the cpu though? ie, does the MMU skip the data
- ; cache and get something stale from memory when it might be unprotected?
- ; Maybe have a recover routine that turns off the mapping by putting it back to the
- ; system start way?
- ; Maybe only emulate the access for things that are being ignored? eg. if it is an error,
- ; I can show it and not let it happen.
- ; Totally rad bug: copy/paste error of having an extra page mapped to the same place in
- ; RAM, in the system heap. When that page got used, I died. Very hard to find.
- ; Worse, I did it twice. Had another several bugs in table over 8 Meg.
-
- ;*** make the data access into a function instead, have pascal routine fill it. Access method.
-
- INCLUDE 'ToolEqu.a'
- INCLUDE 'Traps.a'
- INCLUDE 'PackMacs.a'
- INCLUDE 'QuickEqu.a'
- INCLUDE 'SysEqu.a'
-
-
- MACHINE MC68030
-
- ;-------------------------------------------------------------------------------------------------------------------------
-
-
- ;--------------------------------------------------------------------------------------------------------------------
- ; These tables are exported so that the Pascal can get to the tables as just a chunk of data.
- ; Since I can't really just access them as pointers, I have these access methods to export the
- ; pointer to the Pascal. This makes the Pascal easier to read, with less coercion. These
- ; glue routines just return the address of each of the tables I use. Pascal and assembly
- ; don't talk to each other totally smoothly.
- ; Each routine is of the form:
- ; FUNCTION Getxxx: Ptr;
-
- AccessMethods PROC ; so it's in a proc for assembler.
-
- EXPORT GetStartSpace, GetEndOfTables
- EXPORT GetFirstLevel32, GetSecondLevel32, GetThirdLevel32, GetFourthLevel32
- EXPORT GetFirstLevel24, GetSecondLevel24
-
- GetStartSpace
- LEA StartSpace, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
- GetEndOfTables
- LEA EndOfTables, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
- GetFirstLevel32
- LEA FirstLevel32, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
- GetSecondLevel32
- LEA SecondLevel32, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
- GetThirdLevel32
- LEA ThirdLevel32, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
- GetFourthLevel32
- LEA FourthLevel32, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
-
- GetFirstLevel24
- LEA FirstLevel24, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
- GetSecondLevel24
- LEA SecondLevel24, A0 ; address of table.
- MOVE.L A0, 4(A7) ; replace function result.
- RTS ; and return it.
-
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; Now a routine to install the VBR vector passed in as the current VBR vector. This is
- ; just an access method for the Pascal code to set the VBR register. Could be INLINE, but
- ; since I have an assembly file anyway, I might as well make it clear.
- ; PROCEDURE SetVBR (vbrPointer: Ptr);
-
- EXPORT SetVBR
-
- SetVBR
- MOVE.L (SP)+, A0 ; return address
- MOVE.L (SP)+, A1 ; move pointer into register,
- MOVEC A1, VBR ; move pointer into VBR register.
- JMP (A0) ; and return to caller.
-
-
- ; A function to send back a value, the VBR register value currently in use.
- ; This is the counterpart of SetVBR naturally.
- ; FUNCTION GetVBR: LongInt;
-
- EXPORT GetVBR
-
- GetVBR
- MOVEC VBR, A0 ; can only move into register.
- MOVE.L A0, 4(SP) ; move it to function result.
- RTS ; and return.
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; When switching to my MMU tables, I need to do the switch without turning off the MMU.
- ; The trouble is that on an IIci, Ram Bank B physically starts at $400 0000, and is mapped
- ; to zero. If I turn off the MMU at any time, the banks flip flop out to physical space, and
- ; I get wedge city because the CPU is left stranded in some bogus place.
- ; This routine does what SwapMMUMode does on those machines, by making the switch
- ; without turning off the MMU.
- ; PROCEDURE SetMMURegisters (theRegisters: MMURegisters);
-
- MMURegisters RECORD 0
- theCRP DS.L 2 ; Int64Bit in Pascal. Double Long.
- theTC DS.L 1
- ENDR
-
- EXPORT SetMMURegisters
-
- SetMMURegisters
- BSR.S TurnInterruptsOff ; be sure nothing else is running.
-
- WITH MMURegisters
-
- MOVE.L 4(SP), A0 ; fetch 'theRegisters' pointer.
- PLOADR #5, theCRP(A0) ; #5 is User Data Space function code.
- PMOVEFD theCRP(A0), CRP ; don't flush ATC, load with new set.
- PMOVE theTC(A0), TC ; This flushes ATC, sets new TC.
-
- BSR.S TurnInterruptsOn
-
- MOVE.L (SP)+, (SP) ; crush input with return address
- RTS ; and exit.
-
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; This routine is to allow an interface to the PTEST instruction. The instruction allows me
- ; to take an address passed in, and find out what entry in my MMU tables correspond to it.
- ; This is handy, so I don't have to do a bunch of weird code to find an address. The Ptr
- ; passed back is the pointer returned from PTEST as the MMU entry that matches. The
- ; #5 is the address space, as the Supervisor Data Space, which is where the VBR is located,
- ; the #7 means to use the full tables, and skip the ATC, and the result is stored in A1.
- ; FUNCTION FindMMUEntry (address: Ptr): Ptr;
-
- EXPORT FindMMUEntry
-
- FindMMUEntry
- MOVE.L 4(SP), A0 ; address to find entry for,
- PTESTW #5, (A0), #7, A1 ; use the tables, not the ATC to test.
- MOVE.L (SP)+, A0 ; return address
- ADDQ #4, SP ; kill input parameter,
- MOVE.L A1, (SP) ; save result as function result.
- JMP (A0) ; and return.
-
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; An access method to allow for saving the A5 register as a PC-Relative variable.
- ; This is so that it is handy when called as part of a bus error.
- ; This can only be called during the time when A5 is expected to be valid.
-
- EXPORT SaveTheA5
-
- SaveTheA5
- LEA dcmdA5(PC), A0 ; the variable being saved,
- MOVE.L A5, (A0) ; set to the current A5.
- RTS
-
- dcmdA5 DC.L 0 ; PC Relative addressed storage.
-
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; A small method to flush the Address Translation Cache in the MMU. The ATC is
- ; invalid after I change the protection bits for the 0 page, since the WriteProtect bit is
- ; saved in the ATC line. This takes the input pointer as the place to be flushed. This
- ; is so I can just flush the individual line in the cache that needs it, rather than doing
- ; the brute force flush them all, that I was doing before. The PFLUSH on #0, #0 says
- ; to use the mask as 0, so that it will flush all address spaces as any function code. Since
- ; I only protect memory from 0..255, and that is a single line in the ATC, I just set the
- ; destination to 0, and flush that single page.
- ; PROCEDURE FlushATC (address: Ptr);
-
- EXPORT FlushATC
-
- FlushATC
- MOVE.L 4(SP), A0 ; set up the cache line from input.
- PFLUSH #0, #0, (A0) ; flush just that line in all function codes.
- MOVE.L (SP)+, (SP) ; crush input parameter.
- RTS
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; This will just turn them off in a reasonable fashion. It will save off the value in the SR
- ; in a A5-relative storage, for later use turning them on. This saves the mask from being
- ; set to something weird, since I'm not sure the state of the machine when this might
- ; get called. This naturally requires that A5 be set up before it is used.
- ; PROCEDURE TurnInterruptsOff;
-
- EXPORT TurnInterruptsOff
- IMPORT gSavedSR: DATA
-
- TurnInterruptsOff
- MOVE SR, gSavedSR(A5) ; save the current value
- ORI #$0700, SR ; turn off all interrupts.
- RTS ; and exit.
-
-
- ; This turns them back on, but does so by using the A5-relative pSavedSR. If that's not
- ; valid, then this will be bad.
- ; PROCEDURE TurnInterruptsOn;
-
- EXPORT TurnInterruptsOn
-
- TurnInterruptsOn
- MOVE gSavedSR(A5), SR ; stuff it back into the SR, restoring interrupts.
- RTS
-
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ; This bus error hander is the one that gets installed as part of turning it on. Rather than
- ; have some big assembly language goop here, this will just do the minimum it needs to
- ; glue in the Pascal handler, then jump to that handler instead.
- ; The first thing it needs to do is save the registers that Pascal will crush, since a bus error
- ; handler has to save all registers.
- ; It also turns off interrupts in here, since I will be moving MMU tables around, which
- ; could cause an interrupt routine to crash.
- ; It sets up A5 to be the dcmd's A5 world, so that the Pascal can use globals.
- ; It will pass the pointer to the stack frame, so that the Pascal can use that record to decide
- ; what to do.
- ; It will return by an RTE in order to restart the CPU where it left off, and will dispose of
- ; the exception stack frame. This is hard to do from Pascal too. The RTE will reload the
- ; SR with the right interrupt mask too, so I don't save it's contents.
- ; It isn't possible to set a breakpoint or debugger statement in this routine, since this will
- ; be called when a protection violation occurs. That happens when Macsbug tries to set it's
- ; vector, and when Macsbug switches video states, the video driver installs a bus error
- ; handler. If Macsbug is invoked while it is already running, you get an infinite loop.
- ; Added the PTEST to this glue area, since it had to be in assembly anyway. This tests to
- ; see if the bus error is MMU related or not, and if it isn't, it just jumps on to the standard
- ; bus error handler in 8; under the assumption that that would be what the system does
- ; in the standard (no blat) case.
- ; The PTEST is kind of complicated. I'm using DFC since that should always be right when
- ; I have a bus error, as the destination address space, either program or data, and in
- ; supervisor or user mode, where I don't want to have to check. The $10(A7) crap is
- ; to take the value at A7+$10, an address pointing to the fault address, and to then (A0)
- ; it to get the actual address that faulted. That address is the one I need to see if it is
- ; bogus, or merely an MMU fault. The #7 says to drive the MMU tables to full depth to
- ; see if it can find the fault address in the table. Further info found via experiments:
- ; The bus error bit in the MMUSR is not set when a bad address like -4 is referenced. The
- ; docs are vague, but seems to only be set if the table tree itself caused a bus error. In the
- ; ATC only case (#0) it was also not set, so I'm not sure how an address would get that
- ; set in the ATC. Turning the logic upside down, I'll look for a WP bit or an Invalid bit
- ; in the MMUSR and if both those are missing, then I'll assume it was a stock bus error
- ; and feed it on through. The Invalid bit is set if the DT=0, as I set when read protection
- ; is desired. I used to assume everything was an MMU fault, and try to find the ones
- ; that weren't. That didn't work, so now I assume everything is a regular bus error, and
- ; look for MMU faults. I thought you'd like to know some of the reasons why the
- ; logic is this way, not just see the logic.
-
- registerSize EQU 15*4 ; saved register set on stack.
-
- EXPORT BusErrorGlue
- IMPORT BusError
- IMPORT gStandardBusError : DATA
- IMPORT gStandardVBRBusError : DATA
-
- BusErrorGlue
- MOVEM.L A0-A6/D0-D7, -(SP) ; save all registers to be conservative.
-
- MOVE.L $10+registerSize(A7), A0 ; get the fault address.
- MOVE.W $A+registerSize(A7), D0 ; get SSW from frame.
- MOVEC D0, DFC ; stuff it into DFC for PTEST.
- PTESTW DFC, (A0), #7 ; use the tables, not the ATC to test.
-
- CLR.W -(A7) ; make space for lame MMU
- PMOVE MMUSR, (A7) ; get the result of the search.
- MOVE.W (A7)+, D0 ; get MMUSR, from only addressing mode.
- ANDI.W #$0C00, D0 ; test WP and Invalid bits.
- BEQ.S StandardBusError ; if neither bit set, it's a normal bus error.
-
- ; If the bit wasn't set, that means it was MMU related, and the Pascal handler gets it.
-
- ORI.W #$0700, SR ; Turn interrupts off.
-
- MOVE.L dcmdA5(PC), A5 ; set up A5.
-
- PEA registerSize(SP) ; push pointer to stack frame,
- JSR BusError ; go handle it.
-
- MOVEM.L (SP)+, A0-A6/D0-D7 ; restore registers.
- RTE ; restores the SR too.
-
-
- ; This is where I send the PC off to the previously installed bus error handler, since it
- ; wasn't MMU related. Restore the registers, then vector off to the old handler since it
- ; is presumably primed to handle this error. It will RTE out, so this is a JMP (as RTS).
- ; Decide which bus error handler to send it to, by checking the gStandardVBRBusError
- ; first, and if it is not equal to the BusErrorGlue, it is a valid handler, that takes precedence
- ; over the one in low memory. If not, use the one from low memory, saved in the
- ; gStandardBusError variable.
- ; *** skip use of global, if use 8 anyway.
-
- StandardBusError
- MOVE.L dcmdA5(PC), A5 ; set up A5.
- LEA oldBusError, A0 ; set var to it.
-
- MOVE.L gStandardVBRBusError(A5), (A0) ; assume it will work,
- LEA BusErrorGlue, A1 ; if me, can't use it.
- CMP.L gStandardVBRBusError(A5), A1 ; address of potential handler,
- BNE.S @0 ; if no match, use it.
-
- MOVE.L gStandardBusError(A5), (A0) ; address of prior handler,
-
- @0
- MOVEM.L (SP)+, A0-A6/D0-D7 ; restore registers.
- MOVE.L oldBusError (PC), -(A7) ; address of prior handler,
- RTS ; jump to it.
-
- oldBusError DC.L 0 ; pc relative.
-
-
- ;-------------------------------------------------------------------------------------------------------------------------
- ;--------------------------------------------------------------------------------------------------------------------
- ; The first level table is pointed to by the CRP register, and is used to map the entire
- ; 32-bit address space. The slot and I/O space are set with Cache Inhibit, so they get an
- ; immediate write instead of being cached. The invalid pages are DT=0.
- ; In the real system tables, the RAM above 08000000 is set as invalid, probably to force
- ; a bus error earlier. Unfortunately, I need to know if it is a real bus error or mmu
- ; induced, so I mark them as valid, then let the memory subsystem return a bus error
- ; for no ram installed. Thank you, microsoft word for an easy to find real bus error that
- ; pointed out this flaw when I had them marked DT=0.
- ; This is in use, and it is 5 bits worth of 32-bit address space. 5 bits of the space is thus
- ; 32 entries, dividing the 4 gig space into 32 hunks. 128 Meg per hunk.
- ; This is so that the superslot address spaces are all distinct.
- ; The DT=01 means early termination, so all pages are valid.
- ; The StartSpace here is so that I can move the tables around in the dcmd space, and just
- ; have the tables there, instead of in the system heap. The tables have to be quad-long word
- ; aligned though, so the starting 16 bytes of zeros is to allow me to move the tables from
- ; FirstLevel to EndTables further up in memory to make the starting address for FirstLevel
- ; quad-long word aligned. Hey, it's an MMU requirement, not my plan. During the Init,
- ; I BlockMove the table up to the right spot so that the low nibble will be zero.
-
- StartSpace DC.L 0, 0, 0, 0 ; to allow for quad-long aligned tables.
-
- ; *** could be a bit cleaner if I use a label here, like FirstTableData so that the init stuff
- ; doesn't have to presume FirstLevel32 is the actual first data.
- FirstLevel32 DC.L $00000001, $08000001 ; a 128 Meg chunk for each.
- DC.L $10000001, $18000001 ; all invalid space, DT=0 for invalid.
- DC.L $20000001, $28000001
- DC.L $30000001, $38000001
- DC.L $40000001, $48000001 ; rom space here, so valid.
- DC.L $50000041, $58000041 ; Cache Inhibit bit too, slot and I/O space.
- DC.L $60000041, $68000041
- DC.L $70000041, $78000041
- DC.L $80000041, $88000041
- DC.L $90000041, $98000041
- DC.L $A0000041, $A8000041
- DC.L $B0000041, $B8000041
- DC.L $C0000041, $C8000041
- DC.L $D0000041, $D8000041
- DC.L $E0000041, $E8000041
- DC.L $F0000041, $F8000041 ; Full 32-bit address space.
-
-
- ; This is the second level table, of the MMU tree, and it is pointed at by the first entry
- ; in the first level table. That is the first 128 Meg space, and this divides that space up
- ; using the 7 bits for TIB. 7 bits means 128 entries, so each piece is thus 1 Meg in size.
- ; Since this part of the address space is always in RAM, I don't have to worry about
- ; the cache inhibit bit, or invalid pages.
-
- SecondLevel32 DC.L $00000001, $00100001, $00200001, $00300001
- DC.L $00400001, $00500001, $00600001, $00700001
- DC.L $00800001, $00900001, $00A00001, $00B00001
- DC.L $00C00001, $00D00001, $00E00001, $00F00001
-
- DC.L $01000001, $01100001, $01200001, $01300001
- DC.L $01400001, $01500001, $01600001, $01700001
- DC.L $01800001, $01900001, $01A00001, $01B00001
- DC.L $01C00001, $01D00001, $01E00001, $01F00001
-
- DC.L $02000001, $02100001, $02200001, $02300001
- DC.L $02400001, $02500001, $02600001, $02700001
- DC.L $02800001, $02900001, $02A00001, $02B00001
- DC.L $02C00001, $02D00001, $02E00001, $02F00001
-
- DC.L $03000001, $03100001, $03200001, $03300001
- DC.L $03400001, $03500001, $03600001, $03700001
- DC.L $03800001, $03900001, $03A00001, $03B00001
- DC.L $03C00001, $03D00001, $03E00001, $03F00001
-
- DC.L $04000001, $04100001, $04200001, $04300001
- DC.L $04400001, $04500001, $04600001, $04700001
- DC.L $04800001, $04900001, $04A00001, $04B00001
- DC.L $04C00001, $04D00001, $04E00001, $04F00001
-
- DC.L $05000001, $05100001, $05200001, $05300001
- DC.L $05400001, $05500001, $05600001, $05700001
- DC.L $05800001, $05900001, $05A00001, $05B00001
- DC.L $05C00001, $05D00001, $05E00001, $05F00001
-
- DC.L $06000001, $06100001, $06200001, $06300001
- DC.L $06400001, $06500001, $06600001, $06700001
- DC.L $06800001, $06900001, $06A00001, $06B00001
- DC.L $06C00001, $06D00001, $06E00001, $06F00001
-
- DC.L $07000001, $07100001, $07200001, $07300001
- DC.L $07400001, $07500001, $07600001, $07700001
- DC.L $07800001, $07900001, $07A00001, $07B00001
- DC.L $07C00001, $07D00001, $07E00001, $07F00001
-
-
- ; This is when I replace that first entry with the pointer to this table, and change the
- ; DT=2 so that it indicates the next level will have short format descriptors.
- ; Like:
- ; DC.L $xxxx xx02
- ; Where I stuff the xxx bits with the address of the new table entry.
-
- ; Third level table, when installed for the first entry of the second4 level table.
- ; This table, breaks up the first 1 Meg of the system into 16, 64-K hunks. I map all of the
- ; pages as contiguous memory, and thus these are early termination descriptors too. The
- ; only exception is the first 64K hunk, which points to another table.
- ; The tables are set up this way, with the 5748 for no particular reason, except that the
- ; prototype I had built had a couple of tables already, and this made it so I didn't have to
- ; build all new ones. There doesn't seem to be an advantage to different ways of specifying
- ; it, since all bits of an address have to be mapped.
-
- ThirdLevel32 DC.L $00000001 ; 02 for real.
- DC.L $00010001 ; 64-K boundary, early termination.
- DC.L $00020001
- DC.L $00030001
- DC.L $00040001
- DC.L $00050001
- DC.L $00060001
- DC.L $00070001
- DC.L $00080001
- DC.L $00090001
- DC.L $000A0001
- DC.L $000B0001
- DC.L $000C0001
- DC.L $000D0001
- DC.L $000E0001 ; 15
- DC.L $000F0001 ; 16
-
- ; For the 256 byte page sizes. This table is big. 8 bits for this table, so 256 entries.
- ; At this fourth level, I am breaking up the first 64k hunk. Breaking it into 256
- ; entries, gives 256 byte pages.
- ; Write protect the very first page, the 256 bytes of vectors.
- ; Read protect the 256 bytes, by setting it to DT=0 as invalid page.
- ; Turn off protection by setting DT=1.
- ; This table is used as the 4th level table for the 32-bit mode tables, and is used as the
- ; 3rd level table for 24-bit mode. This is to save some work on maintaining the two
- ; sets of tables, since I can just use this lowest level in both cases. This is especially
- ; handy for setting and creating the VBR write protection.
-
- FourthLevel32 DC.L $00000001, $00000101, $00000201, $00000301
- DC.L $00000401, $00000501, $00000601, $00000701
- DC.L $00000801, $00000901, $00000A01, $00000B01
- DC.L $00000C01, $00000D01, $00000E01, $00000F01
-
- DC.L $00001001, $00001101, $00001201, $00001301
- DC.L $00001401, $00001501, $00001601, $00001701
- DC.L $00001801, $00001901, $00001A01, $00001B01
- DC.L $00001C01, $00001D01, $00001E01, $00001F01
-
- DC.L $00002001, $00002101, $00002201, $00002301
- DC.L $00002401, $00002501, $00002601, $00002701
- DC.L $00002801, $00002901, $00002A01, $00002B01
- DC.L $00002C01, $00002D01, $00002E01, $00002F01
-
- DC.L $00003001, $00003101, $00003201, $00003301
- DC.L $00003401, $00003501, $00003601, $00003701
- DC.L $00003801, $00003901, $00003A01, $00003B01
- DC.L $00003C01, $00003D01, $00003E01, $00003F01
-
- DC.L $00004001, $00004101, $00004201, $00004301
- DC.L $00004401, $00004501, $00004601, $00004701
- DC.L $00004801, $00004901, $00004A01, $00004B01
- DC.L $00004C01, $00004D01, $00004E01, $00004F01
-
- DC.L $00005001, $00005101, $00005201, $00005301
- DC.L $00005401, $00005501, $00005601, $00005701
- DC.L $00005801, $00005901, $00005A01, $00005B01
- DC.L $00005C01, $00005D01, $00005E01, $00005F01
-
- DC.L $00006001, $00006101, $00006201, $00006301
- DC.L $00006401, $00006501, $00006601, $00006701
- DC.L $00006801, $00006901, $00006A01, $00006B01
- DC.L $00006C01, $00006D01, $00006E01, $00006F01
-
- DC.L $00007001, $00007101, $00007201, $00007301
- DC.L $00007401, $00007501, $00007601, $00007701
- DC.L $00007801, $00007901, $00007A01, $00007B01
- DC.L $00007C01, $00007D01, $00007E01, $00007F01
-
- DC.L $00008001, $00008101, $00008201, $00008301
- DC.L $00008401, $00008501, $00008601, $00008701
- DC.L $00008801, $00008901, $00008A01, $00008B01
- DC.L $00008C01, $00008D01, $00008E01, $00008F01
-
- DC.L $00009001, $00009101, $00009201, $00009301
- DC.L $00009401, $00009501, $00009601, $00009701
- DC.L $00009801, $00009901, $00009A01, $00009B01
- DC.L $00009C01, $00009D01, $00009E01, $00009F01
-
- DC.L $0000A001, $0000A101, $0000A201, $0000A301
- DC.L $0000A401, $0000A501, $0000A601, $0000A701
- DC.L $0000A801, $0000A901, $0000AA01, $0000AB01
- DC.L $0000AC01, $0000AD01, $0000AE01, $0000AF01
-
- DC.L $0000B001, $0000B101, $0000B201, $0000B301
- DC.L $0000B401, $0000B501, $0000B601, $0000B701
- DC.L $0000B801, $0000B901, $0000BA01, $0000BB01
- DC.L $0000BC01, $0000BD01, $0000BE01, $0000BF01
-
- DC.L $0000C001, $0000C101, $0000C201, $0000C301
- DC.L $0000C401, $0000C501, $0000C601, $0000C701
- DC.L $0000C801, $0000C901, $0000CA01, $0000CB01
- DC.L $0000CC01, $0000CD01, $0000CE01, $0000CF01
-
- DC.L $0000D001, $0000D101, $0000D201, $0000D301
- DC.L $0000D401, $0000D501, $0000D601, $0000D701
- DC.L $0000D801, $0000D901, $0000DA01, $0000DB01
- DC.L $0000DC01, $0000DD01, $0000DE01, $0000DF01
-
- DC.L $0000E001, $0000E101, $0000E201, $0000E301
- DC.L $0000E401, $0000E501, $0000E601, $0000E701
- DC.L $0000E801, $0000E901, $0000EA01, $0000EB01
- DC.L $0000EC01, $0000ED01, $0000EE01, $0000EF01
-
- DC.L $0000F001, $0000F101, $0000F201, $0000F301
- DC.L $0000F401, $0000F501, $0000F601, $0000F701
- DC.L $0000F801, $0000F901, $0000FA01, $0000FB01
- DC.L $0000FC01, $0000FD01, $0000FE01, $0000FF01
-
-
- ; And in 24 bit mode, I need to have a different set of tables.
- ; This one starts out as the 16 megabyte actual space, since the top 8 bits are thrown out.
- ; With 4 bits for the first level, I have 16 entries, so each entry is for 1 meg.
- ; The levels are mapped to other spaces like it says in the Guide to Macintosh Hardware.
-
- FirstLevel24 DC.L $00000001 ; top=0
- DC.L $00100001 ; top=1, 1 meg boundary.
- DC.L $00200001 ; top=2
- DC.L $00300001 ; top=3
- DC.L $00400001 ; top=4
- DC.L $00500001 ; top=5
- DC.L $00600001 ; top=6
- DC.L $00700001 ; top=7
- DC.L $40800001 ; top=8, for ROM at 8 meg.
- DC.L $F9000041 ; slot 9 (mac)- CI bit on.
- DC.L $FA000041 ; slot A - CI bit on.
- DC.L $FB000041 ; top=B
- DC.L $FC000041 ; top=C
- DC.L $FD000041 ; top=D
- DC.L $FE000041 ; top=E
- DC.L $50000041 ; top=F, i/o space, -CI bit on.
-
- ; The next level is for the 4 bits of space next to be decoded by the MMU, so it is also a
- ; 16 entry table. This thus decodes the first 1 meg space into 64K hunks.
- ; The first entry in this table will point to the 4th level table used in 32-bit mode.
-
- SecondLevel24 DC.L $00000001
- DC.L $00010001 ; 64k higher.
- DC.L $00020001
- DC.L $00030001
- DC.L $00040001
- DC.L $00050001
- DC.L $00060001
- DC.L $00070001
- DC.L $00080001
- DC.L $00090001
- DC.L $000A0001
- DC.L $000B0001
- DC.L $000C0001
- DC.L $000D0001
- DC.L $000E0001
- DC.L $000F0001
-
- ; The third and final level for the 24-bit tables is the same as the 4th level for the 32-bit
- ; tables. The second level table here just points to the same table above.
-
- EndOfTables
-
- ENDPROC
-
- END
-
-