memory.asm
字号:
pop es
pop ds
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop eax
ret
assume ds:_cwDPMIEMU
RAWGetMemoryMax endp
;-------------------------------------------------------------------------------
;
;Extend the linear memory map by allocateing physical memory if available or
;virtual memory if not, or even a combination of the two.
;
;On Entry:
;
;ECX - Pages to extend by.
;
;On Exit:
;
;Carry set on error else memory map extended.
;
ExtendLinearMemory proc near
pushad
push ds
push es
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
mov ax,KernalZero
mov es,ax
mov ebp,ecx
mov eax,ecx
shl eax,12
dec eax
add eax,LinearLimit
dec eax
sub eax,LinearBase
cmp eax,MaxMemLin
jnc mem10_error
;
;Try extending useing physical memory first.
;
mem10_f0: mov eax,LinearLimit ;get new entry number.
shr eax,12 ;page number.
mov LinearEntry,eax
shr eax,10 ;/1024 for page dir entry.
mov edi,PageDirLinear ;get page table address.
mov eax,DWORD PTR es:[edi+eax*4] ;this page present?
test eax,1 ;do we have a page table?
jnz mem10_f1 ;keep going till we do.
;
;No page table so make sure we can get 2 pages (page and det)
;
call PhysicalGetPages
cmp edx,2
jc mem10_virtual
;
;both pages available so go to it.
;
mem10_f2: call PhysicalGetPage ;get a page.
jc mem10_error ;it lied.
mov eax,LinearLimit ;get new entry number.
shr eax,12 ;page number.
mov LinearEntry,eax
push LinearEntry
call MapPhysical ;use this page for page table.
call PhysicalGetPage ;get a page.
pop LinearEntry
jc mem10_error ;it lied.
call MapPhysical ;use this page for page table.
;
mem10_f1: call PhysicalGetPage ;get a page.
jc mem10_Virtual ;use virtual memory.
mov eax,LinearLimit ;get new entry number.
shr eax,12 ;page number.
mov LinearEntry,eax
call MapPhysical ;use this page for page table.
;
;Update details.
;
mov eax,LinearLimit
shr eax,12
mov DWORD PTR es:[(1024*4096*1022)+eax*4],0
inc FreePages
; dec medAllocPages
inc TotalPages
add LinearLimit,4096 ;bump up the end of the memory map.
dec ebp ;update the counter.
jnz mem10_f0 ;keep looking.
clc
jmp mem10_exit ;All physical so exit.
;
mem10_Virtual: ;Virtual memory will be needed so see if we can provide any.
;
cmp VMMHandle,0 ;Virtual memory active?
jz mem10_error
;
;Find out how much disk space is left for swap file to grow into.
;
mov dl,VMMName ;get drive letter for this media.
sub dl,'A' ;make it real.
inc dl ;adjust for current type select.
mov ah,36h ;get free space.
push ebp
int 21h ;/
pop ebp
cmp ax,-1 ;invalid drive?
jz mem10_error
mul cx ;Get bytes per cluster.
mul bx ;Get bytes available.
shl edx,16
mov dx,ax ;make 32 bit.
and edx,not 65535
add edx,SwapFileLength ;add existing size.
mov eax,LinearLimit
sub eax,LinearBase ;get current real memory.
sub edx,eax
shr edx,12 ;get it as pages.
cmp edx,ebp ;Enough pages?
jc mem10_error
;
;Find out how many un-locked pages we currently have.
;
mov edx,NoneLockedPages
;
;Enough page's for minimum requirement?
;
cmp edx,16 ;un-locked pages < 16?
jc mem10_error ;force minimum of 16.
sub edx,16
;
;Work out how many new page/det tables are required.
;
mov eax,LinearLimit
shr eax,12
mov ebx,eax
dec eax ;Last definatly valid page table.
add ebx,ebp ;New end page.
shr eax,10
shr ebx,10 ;Get page table units (4Meg)
sub ebx,eax ;get the differance.
jz mem10_DoneTables
add ebx,ebx ;Page + Det
mov ecx,ebp
cmp ebx,edx
jc mem10_OK
jz mem10_OK
jmp mem10_error
;
mem10_OK: ;Allocate new page tables.
;
mov esi,PageDirLinear ;get page directory address.
mov edx,LinearLimit
shr edx,12
mem10_v2: mov eax,edx ;get new entry number.
shr eax,10 ;/1024 for page dir entry.
test DWORD PTR es:[esi+eax*4],1 ;this page present?
jnz mem10_v3
;
;get DET page.
;
push ecx
push edx
call UnMapPhysical ;get a physical page for us to use.
mov eax,edx
mov ebx,ecx
pop edx
pop ecx
jc mem10_error ;not enough physical memory to support virtual memory.
push ecx
push edx
mov LinearEntry,edx ;set logical page address.
mov edx,eax ;get physical address again.
mov ecx,ebx
call MapPhysical ;use this to add a new page table.
pop edx
pop ecx
;
;And again for page table.
;
push ecx
push edx
call UnMapPhysical ;get a physical page for us to use.
mov eax,edx
mov ebx,ecx
pop edx
pop ecx
jc mem10_error ;not enough physical memory to support virtual memory.
push ecx
push edx
mov LinearEntry,edx ;set logical page address.
mov edx,eax ;get physical address again.
mov ecx,ebx
call MapPhysical ;use this to add a new page table.
pop edx
pop ecx
mem10_v3: inc edx
dec ecx
jnz mem10_v2
;
mem10_DoneTables: ;Now mark all the new pages as un-locked/free
;
mov eax,LinearLimit
mov ecx,ebp
mem10_v4: call RawClearPageLock ;clear page locking for this entry.
push eax
shr eax,12
mov DWORD PTR es:[1024*4096*1022+eax*4],0
pop eax
add eax,4096
dec ecx
jnz mem10_v4
;
;Extend the swap file.
;
mov ecx,LinearLimit ;current end position.
sub ecx,LinearBase ;length.
mov eax,ebp ;extension needed in pages.
shl eax,12
add ecx,eax ;New extremity desired.
cmp ecx,SwapFileLength
jc mem10_Extended
add ecx,65535
and ecx,not 65535
push ecx
mov dx,cx
shr ecx,16
mov bx,VMMHandle ;get swap file handle.
mov ax,4200h
mov edi,offset PageInt
push edi
mov RealRegsStruc.Real_EAX[edi],eax
mov RealRegsStruc.Real_EBX[edi],ebx
mov RealRegsStruc.Real_ECX[edi],ecx
mov RealRegsStruc.Real_EDX[edi],edx
mov RealRegsStruc.Real_SS[edi],0
mov RealRegsStruc.Real_SP[edi],0
mov bl,21h
push ds
pop es
call EMURawSimulateInt ;move to right place.
pop edi
mov ah,40h
mov bx,VMMHandle ;get swap file handle.
mov cx,0
push edi
mov edi,offset PageInt
mov RealRegsStruc.Real_EAX[edi],eax
mov RealRegsStruc.Real_EBX[edi],ebx
mov RealRegsStruc.Real_ECX[edi],ecx
mov RealRegsStruc.Real_EDX[edi],edx
mov RealRegsStruc.Real_SS[edi],0
mov RealRegsStruc.Real_SP[edi],0
mov bl,21h
push ds
pop es
call EMURawSimulateInt ;move to right place.
pop edi
pop ecx
test RealRegsStruc.Real_Flags[edi],1
jnz mem10_disk_error
mov SwapFileLength,ecx
;
xor cx,cx
xor dx,dx
mov ax,4201h
mov bx,VMMHandle
push edi
mov edi,offset PageInt
mov RealRegsStruc.Real_EAX[edi],eax
mov RealRegsStruc.Real_EBX[edi],ebx
mov RealRegsStruc.Real_ECX[edi],ecx
mov RealRegsStruc.Real_EDX[edi],edx
mov RealRegsStruc.Real_SS[edi],0
mov RealRegsStruc.Real_SP[edi],0
mov bl,21h
push ds
pop es
call EMURawSimulateInt ;move to right place.
pop edi
test RealRegsStruc.Real_Flags[edi],1
jnz mem10_disk_error
mov edx,RealRegsStruc.Real_EDX[edi]
mov eax,RealRegsStruc.Real_EAX[edi]
shl edx,16
mov dx,ax
cmp edx,SwapFileLength
jnz mem10_disk_error
;
mem10_Extended: ;Update the end of the memory map.
;
add FreePages,ebp
; sub medAllocPages,ebp
shl ebp,12
add LinearLimit,ebp
clc
jmp mem10_Exit
;
mem10_error: stc
mem10_Exit: ;
pop es
pop ds
popad
ret
;
mem10_Disk_Error: jmp mem10_error
assume ds:_cwDPMIEMU
ExtendLinearMemory endp
;-------------------------------------------------------------------------------
;
;Map physical page supplied into logical address space. If a new page table is needed, the page
;supplied will become a page table.
;
;On Entry:-
;
;CL - Use flags 0-3. 1 being used for VCPI memory to allow release later.
;EDX - Physical address to map.
;
MapPhysical proc near
pushad
push ds
push es
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
mov ax,KernalZero ;make everything addresable.
mov es,ax
;
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,0FFFFFFFFh-4095 ;lose user bits.
mov eax,LinearEntry ;get new entry number.
shr eax,10 ;/1024 for page dir entry.
;
mov esi,PageDirLinear ;get page table address.
test DWORD PTR es:[esi+eax*4],1 ;this page present?
jnz mem11_AddPage
;
cmp PageDETLinear,0 ;DET in use yet?
jz mem11_AddTable
mov esi,PageDETLinear ;get page table address.
test DWORD PTR es:[esi+eax*4],1 ;DET page present?
jnz mem11_AddTable
;
mem11_AddDET: ;Need a new DET page.
;
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov DWORD PTR es:[esi+eax*4],edx ;store this tables address.
;
;Clear this page to locked.
;
mov edi,1024*4096*1022 ;base of page DET's.
mov eax,LinearEntry ;get the entry number again.
shl eax,2 ;4 bytes per entry.
add edi,eax
mov ecx,4096/4
mov eax,MEM_FILL
cld
rep stosd
;
jmp mem11_Finished
;
mem11_AddTable: ;Need a new page table.
;
mov eax,LinearEntry ;get new entry number.
shr eax,10 ;/1024 for page dir entry.
mov esi,PageDirLinear ;get page table address.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov DWORD PTR es:[esi+eax*4],edx ;store this tables address.
mov esi,PageAliasLinear ;get alias table address.
mov DWORD PTR es:[esi+eax*4],edx ;setup in alias table as well.
;
;Clear this page to 0.
;
mov edi,1024*4096*1023 ;base of page alias's.
mov eax,LinearEntry ;get the entry number again.
shl eax,2 ;4 bytes per entry.
add edi,eax
mov ecx,4096/4
xor eax,eax
cld
rep stosd
;
jmp mem11_Finished
;
mem11_AddPage: ;Update recent page usage stack.
;
push ecx
push es
push ds
pop es
mov edi,offset RecentMapStack+(4*PageStackSize)-4
mov esi,offset RecentMapStack+(4*PageStackSize)-8
mov ecx,PageStackSize-1
std
rep movsd
pop es
pop ecx
cld
mov eax,LinearEntry
shl eax,12
mov RecentMapStack,eax
;
;Add this to the relavent page table.
;
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov ebx,DWORD PTR es:[esi+eax*4] ;get current details.
and ebx,1 shl 11
or edx,ebx
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov DWORD PTR es:[esi+eax*4],edx ;set physical address.
;
cmp PageDETLinear,0
jz mem11_NoLocking
mov eax,LinearEntry
shl eax,12
call RawClearPageLock ;clear page locking for this entry.
;
;Update number of un-locked physical pages present.
;
inc NoneLockedPages
;
mem11_NoLocking: ;Check if this page needs fetching from swap space.
;
cmp VMMHandle,0
jz mem11_NoRead
;
test ebx,1 shl 11
jz mem11_NoRead
;
mov esi,BreakAddress
mov al,es:[esi]
mov BYTE PTR es:[esi],0
push eax
;
mov ecx,LinearEntry ;get page number.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -