home *** CD-ROM | disk | FTP | other *** search
- * QuickROM - uses 68060 or 68040 MMU to remap Kickstart in FAST RAM
- * First written by Simon N Goodwin October 10th 1996, PUBLIC DOMAIN
- * Updated January 1997: automatically senses the Kickstart ROM size
- * and can be re-assembled for page sizes other than the default 4K.
- * First upload to Aminet, version 36.07, May 1998.
- *
- * This program works like KSREMAP and ROM2FAST, but it's compatible
- * with more systems, smaller than the former, and more capable than
- * the latter. Written and tested on a Mark 2 Cyberstorm 68060, more
- * than doubling the speed of access to Kickstart code. Also tested
- * on GVP G-FORCE 68060, Commodore's 3640 (helps a bit, but hampered
- * by its very slow 'fast' RAM interface) Warp Engine 68040/33 and a
- * Mark 1 Cyberstorm, which was even faster than the Mark 2 - though
- * it's a shame that Phase Five's Mark 1 SCSI add-on never worked as
- * it should have done. Nic Wilson's KickSpeed tester (from Set040)
- * reads ROM 2.4 times faster on my Mark 1 Cyberstorm hardware after
- * running QuickROM.
- *
- * The advantages of QuickROM over the proprietary versions are:
- *
- * Allocates RAM from the top of memory to minimise fragmentation.
- *
- * Allows de-allocation as well as allocation, freeing 516K memory.
- *
- * More diagnostics for cases when it won't work (Exec result codes).
- *
- * Freely distributable including the Devpac Source code (this is it)
- * with copious comments explaining its strengths and weaknesses.
- *
- * Does not use undocumented 68060.library hooks, so it should work
- * fine on any other 68060 or 68040 system with an MMU, unlike some.
- *
- * Works with 1 Mb ROMs as well as Commodore 512K ones, and uses the
- * documented method to find the ROM size, so it should suit other
- * sizes too, as long as they're in the first 32 Mb of address space
- * (likely as the MAGIC_ROM_SIZE needs to be at address 16 Mb - 20).
- *
- * Limitations are:
- *
- * No messages. Check the return code to find out EXACTLY what happened.
- *
- * Requires an MMU, and won't work with old 68030, 68451 or 68851 ones.
- * There are already plenty of Kickstart re-mappers for those systems.
- *
- * May get confused in the MMU table setup or ROM location is radically
- * changed in some future Amiga. This program is inevitably architecture-
- * and processor-specific, although I've tried to make it fairly flexible.
- *
- * History and Predictions:
- *
- * Code was originally designed to shadow the 512K ROM at $00F80000; this
- * suited all Commodore Amiga ROMs from Kickstart 1.4 to 3.1, but new 1Mb
- * versions are expected one day, so the updated code includes changes to
- * look for them, from address $00F00000 up. It still expects ROM sizes to
- * be a multiple of 256K, where that's the size of a pointer-level table
- * entry, as it works in units of one complete 256K mapping table.
- *
- * The Third Edition of the Amiga Hardware Reference Manual documents
- * on page 224 a technique for finding the size and hence the start
- * address of the ROM, making reference to these 'magic' constants:
- *
- MAGIC_ROMEND equ $01000000 End of C= Kickstarts
- MAGIC_SIZEOFFSET equ -20 Offset to ROM size.L
- *
- * When testing modifications, check the MMU start pointer offset and
- * number of pointer-level entries modified in TableFix, as well as the
- * ROM address and size. If it's past $01FFFFFF you'll need to use a
- * later root pointer to find the required first pointer level entry.
- *
- * The re-mapping area includes one extra MMU page of RAM to ensure page
- * alignment. It uses eight bytes after the ROM image (guaranteed to be
- * available by heap alignment rules) to point back to the start of the
- * allocation and watermark the area "MMU!". All current systems use 4K
- * pages but some effort has been made to make the code adjust to other
- * page sizes, if re-assembled with the following constant adjusted:
- *
- PAGE_SIZE equ 4096
- *
- * PLEASE NOTE: the code has not been tested with 8K pages, as they're not
- * used in any known Amiga; similarly it assumes 256K areas for each pointer
- * level table entry, as these are standard on current 68040 and 68060s. It
- * will probably require radical change for new or non-68040/68060 MMUs
- *
- ******************************************************************************
- *
- * This is the program itself. It uses 68020+ opcodes as well as the MMU,
- * so it starts by checking ExecBase to ensure that the processor is suitable.
- *
- QuickROM move.l 4.w,a6 Find EXEC
- btst #3,$129(a6) Test for a 68060 or 68040
- beq.s Too_Old
-
- lea.l FindMMU,a5
- jsr -30(a6) EXEC Supervisor function
- tst.w d0 Is MMU enabled in TC? If so,
- bpl.s MMU_off bit 15=1 (on 68040/060 only)
-
- if PAGE_SIZE=4096
-
- add.w d0,d0 Check we're using 4K pages: if
- bpl.s Pages_OK so, TC bit 14 should be zero
-
- Pages_8K moveq #24,d0 FAIL! MMU using 8K pages
- rts
-
- endc
-
- Pages_OK move.l a0,d0 Copy and test Root Pointer
- bne.s got_MMU Zero is definitely not enough
-
- no_MMU moveq #28,d0 FAIL! MMU not initialised
- rts
-
- MMU_off moveq #26,d0 FAIL! MMU not enabled
- rts
-
- Too_Old moveq #30,d0 FAIL! 68060 or 68040 required
- rts
-
- dc.b '$VER: QuickROM v36.07 (3-May-1998) by Simon N Goodwin',0
- even
-
- Bad_Copy moveq #20,d0 FAIL! Remapped by someone else
- rts
-
- * EXEC Supervisor routine to extract MMU configuration register details
-
- FindMMU movec urp,a0
- movec tc,d0
- rte
-
- No_Room moveq #22,d0 FAIL! More FAST RAM needed
- rts
-
- ******************************************************************************
- *
- * If we get thus far we're basically onto a winner. We've got an 060 or 040,
- * 4K memory mapping is enabled. Code has been extended to allow undoing, and
- * the memory to be reclaimed, if it is re-invoked when already in use.
- *
- * Register usage:
- *
- * D0, D1, A0, A1 scratch and system
- * D4 Size of physical ROM
- * D7 MMU table address mask
- *
- * A4 Start of physical ROM
- * A5 End of physical ROM
- *
- got_MMU move.l (a0),d0 MMU pointer table for 1st 32 Mb
- move.l #$FFFFFE00,d7 Mask to clear lower 9 bits
- and.l d7,d0 Mask allows safe .W in offset
- lea.l MAGIC_ROMEND,a5 End of ROM
- move.l a5,a4
- move.l MAGIC_SIZEOFFSET(a5),d4 Size of ROM
- moveq #16,d1 Shift to divide start*4 by 256K
- sub.l d4,a4 Start of ROM
- move.l a4,d5
-
- * The pointers handle 256K each, so if the ROM is at $00F80000 as usual the
- * first associated long word pointer will be entry 62, counting from 0, in the
- * pointer-level table, since 62*256K = 15.5 Mb = $00F80000 (as any fule kno).
-
- lsr.l d1,d5 Expect 62*4 for ROM at $F80000
- add.w d5,d0 Offset to first page pointer
- move.l d0,a2 Save first pointer table entry
- move.l (a2),d1 Find first page table entry
- and.l d7,d1 Mask out page usage flags
- move.l (d1.l),d1 Get page table entry
- and.l d7,d1 Physical address for this page
- cmp.l a4,d1 Is it pointing at ROM already?
- beq.s Create If so, we can soon change that!
-
- * It's already re-mapped, so try to un-map it
-
- add.l d4,d1 Point past end of ROM
- move.l d1,a1
- move.l (a1)+,d6 Pick up past pointer
- beq.s Bad_Copy Check it's non zero!
-
- moveq #7,d1 Mask for lower three bits
- and.l d6,d1 which should all be zero
- bne.s Bad_Copy Check alignment is plausible
-
- cmp.l #'MMU!',(a1) Check for our odd signature
- bne.s Bad_Copy
-
- move.l a4,d2
- bsr.s TableFix Point MMU tables back to ROM
-
- move.l d6,a1 Where to deallocate
- move.l #PAGE_SIZE,d0
- add.l d4,d0 ROM size and a bit
-
- jsr -210(a6) FreeMem
-
- moveq #0,d0 No error
- rts
-
- * Allocate memory
-
- Create move.l #$00040004,d1 MEMF_REVERSE and MEMF_FAST
- move.l d4,d0 Deduced ROM size
- add.l #PAGE_SIZE,d0 ...and a bit for overlap
-
- jsr -198(a6) AllocMem
-
- move.l a4,a0 Computed ROM address
- move.l d0,d2 Copy returned address
- beq.s No_Room
-
- move.l d0,a3 Save base of allocated RAM
-
- * Ensure correct alignment on a page boundary
-
- move.l d4,d0 ROM size
- add.l #PAGE_SIZE-1,d2
- and.l #$FFFFFFFF-PAGE_SIZE+1,d2
- move.l d2,a1 Where to copy TO
- move.l a3,(a1,d0.l) Store real base at end of copy
- move.l #'MMU!',4(a1,d0.l) Put watermark in last 4 bytes
-
- * Copy ROM there
-
- jsr -624(a6) CopyMemQuick, A0 to A1 for D0
-
- * This subroutine updates the MMU page table, whether mapping or unmapping
-
- TableFix jsr -120(a6) Disable, implies Forbid
-
- * Fix the MMU tables by pointing them at the new copy
- * D2 points at the 'new' ROM image to be used, and D4 is its size.
- * A2 points to the MMU pointer table entry for the first 256K of ROM space
-
- move.l d4,d1 Work out size in pointer pages
- moveq #18,d0 Shift factor to divide by 256K
- lsr.l d0,d1 Number of pointers to be tweaked
- addq.l #1,d2 Set Resident flag for pages
- subq.l #1,d1 Adjust for DBRA
-
- Pointers move.l d7,d0
- and.l (a2)+,d0 Pointer to MMU block to remap
- move.l d0,a0 Masked to 512 boundary
- moveq #63,d0 Count 4K blocks
-
- Pages move.l d2,(a0)+ Masked page pointer
- add.l #PAGE_SIZE,d2
- dbra d0,Pages
-
- dbra d1,Pointers
-
- jsr -126(a6) Enable, implies Permit
-
- moveq #0,d0 Admit nothing
- rts
-
- end
-