home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Patches / QuickROM.lha / QuickROM / QuickROM.asm < prev    next >
Assembly Source File  |  1998-05-04  |  9KB  |  258 lines

  1. * QuickROM - uses 68060 or 68040 MMU to remap Kickstart in FAST RAM
  2. * First written by Simon N Goodwin October 10th 1996, PUBLIC DOMAIN
  3. * Updated January 1997: automatically senses the Kickstart ROM size
  4. * and can be re-assembled for page sizes other than the default 4K.
  5. * First upload to Aminet, version 36.07, May 1998.
  6. *
  7. * This program works like KSREMAP and ROM2FAST, but it's compatible
  8. * with more systems, smaller than the former, and more capable than
  9. * the latter. Written and tested on a Mark 2 Cyberstorm 68060, more
  10. * than doubling the speed of access to Kickstart code. Also tested
  11. * on GVP G-FORCE 68060, Commodore's 3640 (helps a bit, but hampered
  12. * by its very slow 'fast' RAM interface) Warp Engine 68040/33 and a
  13. * Mark 1 Cyberstorm, which was even faster than the Mark 2 - though
  14. * it's a shame that Phase Five's Mark 1 SCSI add-on never worked as
  15. * it should have done. Nic Wilson's KickSpeed tester (from Set040)
  16. * reads ROM 2.4 times faster on my Mark 1 Cyberstorm hardware after
  17. * running QuickROM. 
  18. *
  19. * The advantages of QuickROM over the proprietary versions are:
  20. *
  21. * Allocates RAM from the top of memory to minimise fragmentation.
  22. *
  23. * Allows de-allocation as well as allocation, freeing 516K memory.
  24. *
  25. * More diagnostics for cases when it won't work (Exec result codes).
  26. *
  27. * Freely distributable including the Devpac Source code (this is it)
  28. * with copious comments explaining its strengths and weaknesses.
  29. *
  30. * Does not use undocumented 68060.library hooks, so it should work
  31. * fine on any other 68060 or 68040 system with an MMU, unlike some.
  32. *
  33. * Works with 1 Mb ROMs as well as Commodore 512K ones, and uses the
  34. * documented method to find the ROM size, so it should suit other
  35. * sizes too, as long as they're in the first 32 Mb of address space
  36. * (likely as the MAGIC_ROM_SIZE needs to be at address 16 Mb - 20).
  37. *
  38. * Limitations are:
  39. *
  40. * No messages. Check the return code to find out EXACTLY what happened.
  41. *
  42. * Requires an MMU, and won't work with old 68030, 68451 or 68851 ones.
  43. * There are already plenty of Kickstart re-mappers for those systems.
  44. *
  45. * May get confused in the MMU table setup or ROM location is radically
  46. * changed in some future Amiga. This program is inevitably architecture-
  47. * and processor-specific, although I've tried to make it fairly flexible.
  48. *
  49. * History and Predictions:
  50. *
  51. * Code was originally designed to shadow the 512K ROM at $00F80000; this
  52. * suited all Commodore Amiga ROMs from Kickstart 1.4 to 3.1, but new 1Mb
  53. * versions are expected one day, so the updated code includes changes to
  54. * look for them, from address $00F00000 up. It still expects ROM sizes to
  55. * be a multiple of 256K, where that's the size of a pointer-level table
  56. * entry, as it works in units of one complete 256K mapping table.
  57. *
  58. *   The Third Edition of the Amiga Hardware Reference Manual documents
  59. *   on page 224 a technique for finding the size and hence the start
  60. *   address of the ROM, making reference to these 'magic' constants:
  61. *
  62. MAGIC_ROMEND equ    $01000000        End of C= Kickstarts
  63. MAGIC_SIZEOFFSET equ    -20        Offset to ROM size.L
  64. *
  65. * When testing modifications, check the MMU start pointer offset and
  66. * number of pointer-level entries modified in TableFix, as well as the
  67. * ROM address and size. If it's past $01FFFFFF you'll need to use a
  68. * later root pointer to find the required first pointer level entry.
  69. *
  70. * The re-mapping area includes one extra MMU page of RAM to ensure page
  71. * alignment. It uses eight bytes after the ROM image (guaranteed to be
  72. * available by heap alignment rules) to point back to the start of the
  73. * allocation and watermark the area "MMU!". All current systems use 4K
  74. * pages but some effort has been made to make the code adjust to other
  75. * page sizes, if re-assembled with the following constant adjusted:
  76. *
  77. PAGE_SIZE    equ    4096
  78. *
  79. * PLEASE NOTE: the code has not been tested with 8K pages, as they're not
  80. * used in any known Amiga; similarly it assumes 256K areas for each pointer
  81. * level table entry, as these are standard on current 68040 and 68060s. It
  82. * will probably require radical change for new or non-68040/68060 MMUs
  83. *
  84. ******************************************************************************
  85. *
  86. * This is the program itself. It uses 68020+ opcodes as well as the MMU,
  87. * so it starts by checking ExecBase to ensure that the processor is suitable.
  88. QuickROM    move.l      4.w,a6                    Find EXEC
  89.     btst      #3,$129(a6)         Test for a 68060 or 68040
  90.             beq.s    Too_Old
  91.  
  92.             lea.l    FindMMU,a5            
  93.            jsr        -30(a6)            EXEC Supervisor function
  94.             tst.w    d0        Is MMU enabled in TC? If so,
  95.             bpl.s    MMU_off        bit 15=1 (on 68040/060 only)
  96.  
  97.     if    PAGE_SIZE=4096
  98.     
  99.             add.w    d0,d0        Check we're using 4K pages: if
  100.             bpl.s    Pages_OK        so, TC bit 14 should be zero
  101.  
  102. Pages_8K    moveq    #24,d0        FAIL! MMU using 8K pages
  103.     rts
  104.  
  105.     endc
  106.     
  107. Pages_OK    move.l    a0,d0        Copy and test Root Pointer
  108.             bne.s    got_MMU        Zero is definitely not enough
  109.             
  110. no_MMU    moveq    #28,d0        FAIL! MMU not initialised
  111.     rts
  112.     
  113. MMU_off    moveq    #26,d0        FAIL! MMU not enabled
  114.     rts    
  115.     
  116. Too_Old    moveq    #30,d0        FAIL! 68060 or 68040 required
  117.     rts
  118.  
  119.     dc.b    '$VER: QuickROM v36.07 (3-May-1998) by Simon N Goodwin',0
  120.     even
  121.  
  122. Bad_Copy    moveq    #20,d0        FAIL! Remapped by someone else
  123.     rts        
  124.  
  125. * EXEC Supervisor routine to extract MMU configuration register details 
  126.  
  127. FindMMU    movec    urp,a0
  128.     movec    tc,d0
  129.     rte        
  130.  
  131. No_Room    moveq    #22,d0        FAIL! More FAST RAM needed
  132.      rts
  133.  
  134. ******************************************************************************
  135. *
  136. * If we get thus far we're basically onto a winner. We've got an 060 or 040,
  137. * 4K memory mapping is enabled. Code has been extended to allow undoing, and
  138. * the memory to be reclaimed, if it is re-invoked when already in use.
  139. *
  140. * Register usage:
  141. *
  142. * D0, D1, A0, A1 scratch and system
  143. * D4 Size of physical ROM
  144. * D7 MMU table address mask
  145. *
  146. * A4 Start of physical ROM
  147. * A5 End of physical ROM
  148. *
  149. got_MMU    move.l    (a0),d0        MMU pointer table for 1st 32 Mb
  150.     move.l    #$FFFFFE00,d7    Mask to clear lower 9 bits
  151.     and.l    d7,d0        Mask allows safe .W in offset
  152.     lea.l    MAGIC_ROMEND,a5    End of ROM
  153.     move.l    a5,a4        
  154.     move.l    MAGIC_SIZEOFFSET(a5),d4 Size of ROM
  155.     moveq    #16,d1        Shift to divide start*4 by 256K
  156.     sub.l    d4,a4        Start of ROM
  157.     move.l    a4,d5
  158.     
  159. * The pointers handle 256K each, so if the ROM is at $00F80000 as usual the
  160. * first associated long word pointer will be entry 62, counting from 0, in the
  161. * pointer-level table, since 62*256K = 15.5 Mb = $00F80000 (as any fule kno).
  162.  
  163.     lsr.l    d1,d5        Expect 62*4 for ROM at $F80000
  164.     add.w    d5,d0        Offset to first page pointer
  165.     move.l    d0,a2        Save first pointer table entry
  166.     move.l    (a2),d1        Find first page table entry
  167.     and.l    d7,d1        Mask out page usage flags
  168.     move.l    (d1.l),d1        Get page table entry
  169.     and.l    d7,d1        Physical address for this page
  170.     cmp.l    a4,d1        Is it pointing at ROM already?
  171.     beq.s    Create        If so, we can soon change that!
  172.  
  173. * It's already re-mapped, so try to un-map it
  174.  
  175.     add.l    d4,d1        Point past end of ROM
  176.     move.l    d1,a1
  177.     move.l    (a1)+,d6        Pick up past pointer
  178.     beq.s    Bad_Copy        Check it's non zero!
  179.     
  180.     moveq    #7,d1        Mask for lower three bits
  181.     and.l    d6,d1          which should all be zero
  182.     bne.s    Bad_Copy        Check alignment is plausible
  183.  
  184.     cmp.l    #'MMU!',(a1)    Check for our odd signature
  185.     bne.s    Bad_Copy
  186.  
  187.     move.l    a4,d2    
  188.     bsr.s    TableFix        Point MMU tables back to ROM
  189.  
  190.     move.l    d6,a1        Where to deallocate
  191.     move.l    #PAGE_SIZE,d0
  192.     add.l    d4,d0        ROM size and a bit
  193.  
  194.     jsr    -210(a6)        FreeMem
  195.  
  196.     moveq    #0,d0        No error
  197.     rts
  198.     
  199. * Allocate memory
  200.  
  201. Create    move.l    #$00040004,d1    MEMF_REVERSE and MEMF_FAST
  202.     move.l    d4,d0        Deduced ROM size
  203.     add.l    #PAGE_SIZE,d0    ...and a bit for overlap
  204.  
  205.     jsr    -198(a6)        AllocMem
  206.  
  207.     move.l    a4,a0        Computed ROM address
  208.     move.l    d0,d2        Copy returned address
  209.     beq.s    No_Room
  210.  
  211.     move.l    d0,a3        Save base of allocated RAM
  212.     
  213. * Ensure correct alignment on a page boundary
  214.  
  215.     move.l    d4,d0        ROM size
  216.     add.l    #PAGE_SIZE-1,d2
  217.     and.l    #$FFFFFFFF-PAGE_SIZE+1,d2
  218.     move.l    d2,a1        Where to copy TO
  219.     move.l    a3,(a1,d0.l)    Store real base at end of copy
  220.     move.l    #'MMU!',4(a1,d0.l)    Put watermark in last 4 bytes
  221.     
  222. * Copy ROM there
  223.  
  224.     jsr    -624(a6)        CopyMemQuick, A0 to A1 for D0
  225.  
  226. * This subroutine updates the MMU page table, whether mapping or unmapping
  227.         
  228. TableFix    jsr        -120(a6)            Disable, implies Forbid
  229.  
  230. * Fix the MMU tables by pointing them at the new copy
  231. * D2 points at the 'new' ROM image to be used, and D4 is its size.
  232. * A2 points to the MMU pointer table entry for the first 256K of ROM space
  233.  
  234.     move.l    d4,d1        Work out size in pointer pages
  235.     moveq    #18,d0        Shift factor to divide by 256K
  236.     lsr.l    d0,d1        Number of pointers to be tweaked
  237.     addq.l    #1,d2        Set Resident flag for pages
  238.     subq.l    #1,d1        Adjust for DBRA
  239.  
  240. Pointers    move.l    d7,d0
  241.     and.l    (a2)+,d0        Pointer to MMU block to remap
  242.     move.l    d0,a0        Masked to 512 boundary
  243.     moveq    #63,d0        Count 4K blocks
  244.  
  245. Pages    move.l    d2,(a0)+        Masked page pointer
  246.     add.l    #PAGE_SIZE,d2
  247.     dbra    d0,Pages
  248.  
  249.     dbra    d1,Pointers
  250.  
  251.     jsr        -126(a6)            Enable, implies Permit
  252.     
  253.     moveq    #0,d0        Admit nothing
  254.     rts
  255.     
  256.     end
  257.