home *** CD-ROM | disk | FTP | other *** search
- .prot
- .xlisti
- include dosx.ah
- include hw386.ah
-
- comment ~**********************************************
-
- repl_hndlr(low_lin, high_lin, expf)
- ULONG low_lin;
- ULONG high_lin;
- ULONG expf;
-
- tick_hndlr(low_lin, high_lin)
- ULONG low_lin;
- ULONG high_lin;
-
- pgin_hndlr(linadr)
- ULONG linadr;
-
- Description:
- Handlers for page replacement. As simple as
- possible -- we simply do a circular scan
- always selecting the first page we find
- as the page to be swapped.
- Since we don't take any program activity into
- account when selecting a page to swap,
- neither the page aging handler called
- periodically, nor the handler called each
- time a virtual page is read into memory,
- need to do anything.
-
- Calling arguments:
- low_lin bottom of virtual region
- high_lin top of virtual region
- expf T ==> EXP page only
- F ==> any swappable page
- linadr lin addr of page just
- swapped in
-
- Returned values:
- 0 if no pages to swap
- otherwise linear addr of page to swap
- ~******************************************************
- ;
- ; Since the linker creates a single program segment
- ; for a protected mode program, and both CS and DS
- ; point to it, we can put any global data
- ; needed in our code segment and still get to it
- ; from DS -- all we have to do is tell the assembler
- ; we can get to it by ASSUMEing that DS points to the
- ; code segment. (Note, of course, that when the
- ; handler gets control DS is undefined and we have
- ; to set it to our data segment).
- ;
- ; The advantage of putting the data in the same segment
- ; as the handler code is that we know they will end
- ; up next to each other when the program is linked,
- ; which makes it simpler to lock our handler code and
- ; data in memory (if the code and data are in two
- ; different segments, they may not be adjacent so
- ; we would have to do two separate locks, one for the
- ; code and one for the data).
- ;
- assume cs:text,ds:text
- text segment byte public use32 'code'
-
- public hndlr_startp,hndlr_endp
- public tick_hndlr,pgin_hndlr,repl_hndlr
-
- ;
- ; Start of handler code & data to be locked in
- ; memory
- ;
- hndlr_startp label byte
-
- ;
- ; Global data needed by handlers.
- ;
- swap_lin dd 0 ; linear addr of last page
- ; swapped
-
- tick_hndlr proc far ; page aging handler
- ret
- tick_hndlr endp
-
- pgin_hndlr proc far ; page read in handler
- ret
- pgin_hndlr endp
-
- repl_hndlr proc far ; select page for replacement
- ;
- ; Stack frame
- ;
- #EXPF equ (dword ptr 20[ebp])
- #HIGH_LIN equ (dword ptr 16[ebp])
- #LOW_LIN equ (dword ptr 12[ebp])
-
- push ebp ; Set up stack frame
- mov ebp,esp ;
- push es ; Save modified regs
- push fs ;
- push ds ;
- push esi ;
- push edi ;
- mov ax,14h ; set up DS to our data
- mov ds,ax ; segment
- mov ax,SS_PGTAB ; set up ES to point to
- mov es,ax ; page table seg
- mov ax,SS_PTINF ; set up FS to page table
- mov fs,ax ; info segment
-
- mov eax,swap_lin ; adjust last page
- cmp eax,#LOW_LIN ; swapped if out
- jb short #fix ; of range
- cmp eax,#HIGH_LIN ;
- jb short #ok ;
- #fix: ;
- mov eax,#LOW_LIN ;
- mov swap_lin,eax ;
- #ok:
-
- ;
- ; Perform a circular scan of all page table entries
- ; in the virtual linear region, starting with 1 past the
- ; last page swapped, to find the first page we can swap.
- ; EDI = page number of end of virtual region
- ; ESI = page number of start of virtual region
- ; EDX = current page number
- ;
- mov eax,#LOW_LIN ; branch if virtual linear
- cmp eax,#HIGH_LIN ; region null
- jae #err ;
- mov esi,#LOW_LIN ; set ESI to start of range,
- shr esi,PAGE_SHIFT ; EDI to end
- mov edi,#HIGH_LIN ;
- shr edi,PAGE_SHIFT ;
- mov edx,swap_lin ; start with 1 past last
- shr edx,PAGE_SHIFT ; page swapped
- inc edx ;
- cmp edx,edi ;
- jb short #loop ;
- mov edx,esi ;
- #loop:
- mov eax,es:[edx*4] ; get pg tbl entry
- test eax,PE_PRESENT ; branch if not present
- jz short #next ;
- test eax,PE_LOCKED ; branch if locked
- jnz short #next ;
- test eax,PE_ALLOC ; branch if not allocated
- jz short #next ; (mapped)
- cmp #EXPF,FALSE ; if any page OK,
- je short #done ; we're done
- mov eax,fs:[edx*4] ; get pg tbl info entry
- test eax,PTI_ONDISK ; branch if not on disk
- jz short #next ;
- test eax,PTI_INEXP ; branch if in EXP file
- jnz short #done ;
- #next:
- inc edx ; step to next page
- cmp edx,edi ; & continue
- jb #loop ;
- mov edx,esi ;
- jmp #loop ;
- #done:
-
- ;
- ; OK, done with loop - return linear addr of page
- ; we found
- ;
- mov eax,edx ; return linear addr of
- shl eax,PAGE_SHIFT ; page to swap
- mov swap_lin,eax ; update last pg swapped
-
- #exit:
- pop edi ; Restore modified regs
- pop esi ;
- pop ds ;
- pop fs ;
- pop es ;
- mov esp,ebp ; restore stack frame
- pop ebp ; & exit
- ret ;
-
- #err:
- ;
- ; Couldn't find any pages eligible for swapping
- ;
- xor eax,eax ; return no available
- jmp #exit ; pages to swap
- repl_hndlr endp
-
- ;
- ; End of handler code and data
- ;
- hndlr_endp label byte
-
- text ends
-
- end
-