home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 9
/
FreshFishVol9-CD2.bin
/
bbs
/
util
/
appvm-0.9.lha
/
AppVM
/
appvm.s
< prev
next >
Wrap
Text File
|
1994-01-28
|
54KB
|
1,668 lines
*************************************************************************************
*
* AppVM ® (Application VIRTUAL MEMORY) © Copyright LVA March 1992
* ------- --------------------------
*
* Written by Laurence Vanhelsuwé.
*
*
* AppVM ® is a stop-gap solution for application writers who need UNIX-style
* Demand Paged Virtual Memory.
* This program extends the functionality of Exec's AllocMem() and FreeMem() and
* AmigaDOS's Read() and Write().
* Only Processes can use VM, not Tasks !
*
* This implementation behaves like an exclusive resource like PAR: or SER: as
* opposed to a shared resource. A single Process at a time can allocate (and use)
* areas of memory that are larger than physical RAM memory as if that memory was
* physically present.
* As soon as this unique Process (referred to in the source as the "client") frees
* all its VM, another client can immediately start using the resource again.
*
* This program is called Application VM because the system (Exec, Intuition)
* is never allowed to handle VM pointers.
* Only applications are able to get VM and use it "internally", i.e. they are not
* allowed to pass a VM ptr to the system (via a call to DoIO() for example).
* (More precisely, bus error exceptions due to the dereferencing of VM ptrs are
* only handled correctly if the code trapping is in the scope of the client Process.)
*
* There's one important exception to this rule:
* Exec's AllocMem() is the source of VM ptrs and FreeMem(), Read() and Write() can
* all handle VM ptrs.
* This should be enough for any application (who gets the status of "client") to
* process huge amounts of data and load and/or save into/from VM.
*
* History
* -------
* 24/MAR/92: started code (goal: getting the Amiga to use my new MMU tree)
* 25/MAR/92: (goal: getting instructions which use VM to restart)
* 26/MAR/92: (goal: getting a client Process to use service)
* 27/MAR/92: (goal: full service incl. Read()/Write() )
* 29/APR/92: fixed double Close() bug in case disk full
*
*************************************************************************************
include std
include hardware/custom.i
include exec/vmemory.i ;include our new VM include!
;-----------------------------------------------
; Program Global Constants
;-----------------------------------------------
; This version allows a maximum VM request of 256Mb (if you've got that much spare
; on your hard disk). The code can handle more though. **!! (How much, 2 Gb ?)
; The absolute maximum in any case is 2 Gigabytes since VM addresses start at
; $80000000.
MAX_VM_MEGS equ 256 ;256Mb max LA range
; Since we're only using a single B-level table for the VM logical addresses (which
; have bit31=1), I can only map a maximum VM range of 256Mb.
; That should be enough since you also need that much space on your hard disk!
KILOBYTE equ 1024
MEGABYTE equ KILOBYTE*KILOBYTE
PAGE_SHIFT equ 15 ;2^15 = 32K
PAGE_SIZE equ 1<<PAGE_SHIFT ;one PAGE is 32K big
; Pages are this large because:
;
; 1) AmigaDOS is very efficient at transfering large chuncks from/to disk.
; 2) Bus exception errors become less frequent.
; 4) The D-level table shrinks significantly.
; 3) The free pages bitmap shrinks too.
VM_START equ $80000000 ;all VM addresses have b31=1
; What this program does is to create a new MMU table which CONTAINS the standard
; 2-level (A,B) Exec MMU table and a new branch for VM addresses.
; The standard table uses TIA=8 and TIB=6 with a table A index LIMIT of 16.
; This means that the standard table provides translation for the very first 256Mb
; of address space in the Amiga. Everything above it is off-limit (BUS ERROR).
; What AppVM does is to "shift down" this tree and turn it into a branch of a bigger
; tree using the following LA field subdivisions:
; TABLE ENTRIES PER ENTRY
; ----- ------- ---------
TIA equ 4 ; 4Gb 16 = 256 Mb
TIB equ 4 ;256Mb 16 = 16 Mb
TIC equ 6 ; 16Mb 64 = 256 K
TID equ 3 ;256K 8 = 32 K PAGES
; Check whether chosen logical address breakdown fields are legal.
TC_CHECK equ 32-(TIA+TIB+TIC+TID+PAGE_SHIFT)
IFNE TC_CHECK
blabla ; ** WARNING ** SELECTED LA INDEX BREAK-DOWN IS INVALID
END
ENDC
; The new TIB,TIC values have to be derived from the TIA,TIB values of the original
; translation tree. TIC has to be the old TIB. TIB Can be 4 instead the original
; TIA's 8 because the original A-table is LIMITED to the first 16 indices.
; This is necessary so that I can retain the existing MMU translation tree as a
; branch of my bigger tree (which is now a 4-level tree).
*####################################################################################
*
* RESULTING MMU TRANSLATION TREE STRUCTURE:
* =========================================
*
* A-table (one for ENTIRE SYSTEM)
*
* ____________
* 0 |_1st 256Mb|------> STANDARD Exec MMU table (becomes levels B and C)
* 1 | |
* 2 | |
* 3 | |
* 4 | |
* 5 | |
* 6 | |
* 7 | |
* 8 |_8th 256Mb|------> VM B-table
* 9 | | ____________
* A | | | 1st 16Mb |------> 1st VM C-table
* B | | | 2nd 16Mb | ______________
* C | | | 3rd 16Mb | | 1st 256K |-----> 1st VM D-table
* D | | | 4th 16Mb | | 2nd 256K | _______________
* E | | | 5th 16Mb | | | | 1st 32K PAGE |
* F | | | 6th 16Mb | : : | 2nd 32K PAGE |
* ------------ | 7th 16Mb | | 3rd 32K PAGE |
* All other ranges | 8th 16Mb | 64 entries | 4th 32K PAGE |
* are INVALID. | 9th 16Mb | | 5th 32K PAGE |
* |10th 16Mb | : : | 6th 32K PAGE |
* |11th 16Mb | | | | 7th 32K PAGE |
* |12th 16Mb | | 63rd 256K | | 8th 32K PAGE |
* |13th 16Mb | | 64th 256K | ----------------
* |14th 16Mb | --------------
* |15th 16Mb |
* |16th 16Mb |
* ------------
*####################################################################################
A_TSIZE equ (1<<TIA)*4 ;64 ;size of one table at each level
B_TSIZE equ (1<<TIB)*4 ;64 ;(using short descriptors)
C_TSIZE equ (1<<TIC)*4 ;256
D_TSIZE equ (1<<TID)*4 ;32
C_TABLES equ 1<<TIB ;number of C tables depends on B level
D_TABLES equ 1<<(TIB+TIC) ;1024 of them ! (8192 descriptors)
TREE_SIZE equ A_TSIZE+B_TSIZE+(C_TABLES*C_TSIZE)+(D_TABLES*D_TSIZE)
; 64 + 64 + 4096 + 32768
SHORT_INVALID equ $BAD00000 ;DT bits = 00 = INVALID
;this descriptor HAS to have b31=1 (quick test)
PTR_MASK equ $FFFFFF00 ;low descriptor byte is not part of ptr
MODIFIED_PAGE equ 4 ;bit set if page has been written to
ACCESSED_PAGE equ 3 ;bit set if page has been accessed (R/W)
DT_INVALID equ $0
DT_PAGE equ $1
DT_VALID_4BYTE equ $2 ;table pointer points to short table
DT_VALID_8BYTE equ $3 ;table pointer points to short table
TC_ENABLE equ 1<<31
TC_PSIZE equ (%1111)<<20 ;select 32K pages
TC_TIA equ TIA<<12
TC_TIB equ TIB<<8
TC_TIC equ TIC<<4
TC_TID equ TID
NEW_TC equ TC_ENABLE+TC_PSIZE+TC_TIA+TC_TIB+TC_TIC+TC_TID
_intena equ $dff000+intena ;for DISABLE/ENABLE
;##########################################################################
START_APPVM: move.l sp,stack_level ;store original sp
move.l a0,arg_line ;store raw arguments ptr
bsr init_all ;init vars, open DOS, stdout
beq bail_out ;if couldn't open something: exit now
move.l 4.w,a6 ;check to see that this machine is
move.w AttnFlags(a6),d0 ;at least 030 based coz I need MMU
btst #AFB_68030,d0 ;(**!! SIMPLISTIC TEST: tst mmu config!)
beq need_MMU
bsr parse_args ;get arguments (VM size, swapfile name)
cmp.l #$00FFFFFF,$8 ;has other copy of APPVM already been
bhi already_resident ;started ? (**!! SIMPLISTIC TEST)
bsr create_swapfile ;create swapfile on disk
bsr init_VM_p