📄 memory.asm
字号:
call GetPageStatus
pop eax
jc @@15 ;ignore not present tables.
test edx,1
jz @@005 ;already present.
call RawPageLocked ;locked page?
jnz @@05
dec d[_LM_Got] ;reduce available pages.
jmp @@05
@@005: inc d[_LM_Needed]
@@05: add eax,4096
cmp eax,d[_LM_BlockEnd] ;done them all yet?
jc @@04
;
;Check if we actually need any more pages to lock this region.
;
cmp d[_LM_Needed],0
jz @@OK
;
;If VMM isn't active then pages can always be locked assumeing they exist.
;
cmp VMMHandle,0
jnz @@VMM
mov eax,d[_LM_Needed]
cmp eax,d[_LM_Got]
jc @@OK
jz @@OK
jmp @@15
;
;VMM is active and pages are required so we need to make sure enough pages are
;left for swapping.
;
@@VMM: mov eax,d[_LM_Needed]
add eax,16 ;arbitrary safety buffer.
cmp eax,d[_LM_Got]
jc @@OK
jz @@OK
jmp @@15
;
;Enough free pages so lock the region.
;
@@OK: mov eax,d[_LM_BlockBase]
@@4: cmp eax,LinearBase ;must be in our memory pool.
jc @@5
cmp eax,LinearLimit
jnc @@5
push eax
call GetPageStatus
pop eax
jc @@15 ;ignore not present tables.
test edx,1 ;is it present?
jnz @@6
;
@@11: ;Need to allocate a physical page first.
;
push eax
call UnMapPhysical
pop eax
jc @@15 ;this shouldn't happen.
mov LinearEntry,eax
shr LinearEntry,12 ;store page number to allocate at.
push eax
call MapPhysical ;map this page in.
pop eax
;
@@6: ;Now mark this page as locked.
;
call RawLockPage
;
@@5: add eax,4096
cmp eax,d[_LM_BlockEnd] ;done them all yet?
jc @@4
;
@@10: clc
jmp @@1
;
@@15: stc
;
@@1:
lss esp,f[esp]
pushf
add d[RawStackPos],RawStackDif
popf
popm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
ret
assume ds:_cwDPMIEMU
RAWLockMemory endp
;-------------------------------------------------------------------------------
RAWUnLockMemory proc near
call RAWCopyCheck
;
pushm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
mov ax,KernalDS
mov ds,ax
assume ds:_cwRaw
;
push ebx
push ecx
push edx
xor ebx,ebx
mov bx,ss
mov ecx,esp
pushf
cli
mov edx,d[RawStackPos]
sub d[RawStackPos],RawStackDif
popf
mov ax,KernalSS
mov ss,ax
mov esp,edx
add ecx,4+4+4
pushm ebx,ecx
sub ecx,4+4+4
push es
mov es,bx
mov edx,es:[ecx]
mov ebx,es:[ecx+4+4]
mov ecx,es:[ecx+4]
pop es
shl ebx,16
mov bx,cx
shl esi,16
mov si,di
add esi,ebx
and ebx,0FFFFFFFFh-4095 ;round down to nearest page.
mov d[_LM_BlockBase],ebx
add esi,4095
and esi,0FFFFFFFFh-4095 ;round up to next page.
dec esi
mov d[_LM_BlockEnd],esi ;store address of last page.
;
;Now run through all pages in this range un-locking them.
;
mov eax,d[_LM_BlockBase]
@@4: cmp eax,LinearBase ;must be in our memory pool.
jc @@5
cmp eax,LinearLimit
jnc @@5
push eax
call GetPageStatus
pop eax
jc @@5 ;ignore not present tables.
test edx,1 ;is it present?
jz @@5
call RawUnLockPage ;unlock the page.
@@5: add eax,4096
cmp eax,d[_LM_BlockEnd] ;done them all yet?
jc @@4
clc
@@1:
lss esp,f[esp]
pushf
add d[RawStackPos],RawStackDif
popf
popm eax,ebx,ecx,edx,esi,edi,ebp,ds,es,fs,gs
ret
assume ds:_cwDPMIEMU
RAWUnLockMemory endp
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
RAWGetMemoryMax proc near
;
;Work out biggest memory block remaining.
;
call RAWCopyCheck
;
pushm eax,ecx,edx,esi,edi,ebp,ds,es
mov ax,KernalDS ;make data addresable.
mov ds,ax
assume ds:_cwRaw
push ebx
push ecx
push edx
xor ebx,ebx
mov bx,ss
mov ecx,esp
pushf
cli
mov edx,d[RawStackPos]
sub d[RawStackPos],RawStackDif
popf
mov ax,KernalSS
mov ss,ax
mov esp,edx
add ecx,4+4+4
pushm ebx,ecx
sub ecx,4+4+4
push es
mov es,bx
mov edx,es:[ecx]
mov ebx,es:[ecx+4+4]
mov ecx,es:[ecx+4]
pop es
mov ax,KernalZero
mov es,ax
;
;Look in existing memory first.
;
mov edx,LinearBase ;Get starting point.
mov ecx,LinearLimit
sub ecx,edx ;Get memory present.
shr ecx,12 ;Get pages.
shr edx,12 ;Get page number.
xor edi,edi ;Clear flag.
xor ebp,ebp ;Clear biggest so far.
;
@@l0: ;Look for a bigest block of free memory.
;
mov eax,es:d[(1024*4096*1022)+edx*4] ;Get page details.
and eax,MEM_MASK
cmp eax,MEM_FREE ;Free block?
jnz @@l2
or edi,edi ;Got any yet?
jnz @@l1
mov esi,edx ;Get base page number.
@@l1: inc edi
cmp edi,ebp ;Biggest yet?
jc @@l3
mov ebx,esi ;Get base.
mov ebp,edi ;Get size.
jmp @@l3
@@l2: xor edi,edi
@@l3: inc edx ;Next page.
dec ecx
jnz @@l0
;
;See if biggest block found is the last block in the map.
;
xor edx,edx ;reset end of chain value.
or edi,edi ;last block free?
jz @@l4
cmp ebx,esi ;same base?
jnz @@l4
mov edx,ebp ;setup extra block size.
mov ebp,0 ;reset normal block size.
jmp @@l5
;
@@l4: ;Get size of the last block in the memory map.
;
mov eax,LinearBase
mov esi,LinearLimit
shr esi,12
dec esi
shr eax,12
mov ecx,esi
sub ecx,eax
@@l6: jecxz @@l5
mov eax,es:d[(1024*4096*1022)+esi*4] ;Get page details.
and eax,MEM_MASK
cmp eax,MEM_FREE ;Free block?
jnz @@l5
dec esi
inc edx
dec ecx
jmp @@l6
;
@@l5: ;See what extra memory we can get hold of.
;
mov ebx,edx
call PhysicalGetPages ;Get extra memory available.
mov ecx,ebx ;Save origional value.
add ebx,edx ;update extra memory value.
;
;See how many pages of real memory would be lost to page tables.
;
mov eax,LinearLimit
shr eax,12
add eax,edx
shr eax,10
mov edx,LinearLimit
shr edx,12
dec edx
shr edx,10
sub eax,edx
add eax,eax ;Page + Det
sub ebx,eax
;
;See what extra memory the VMM can get hold of.
;
cmp VMMHandle,0
jz @@l8
mov ebx,ecx
pushm ebx,ebp
;
;Get free disk space remaining.
;
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.
int 21h ;/
xor edx,edx
cmp ax,-1 ;invalid drive?
jz @@l7
mul cx ;Get bytes per cluster.
mul bx ;Get bytes available.
shl edx,16
mov dx,ax
@@l7: ;
;Get current swap file size.
;
push edx
mov bx,VMMHandle
mov ax,4202h
xor cx,cx
mov dx,cx
int 21h
shl edx,16
mov dx,ax
pop eax
add edx,eax
and edx,not 65535
shr edx,12
popm ebx,ebp
;
;Work out how much of the VMM space is extra.
;
mov eax,LinearLimit
sub eax,LinearBase
shr eax,12
sub edx,eax
add ebx,edx
;
@@l8: ;Check which block is bigger and exit.
;
push ecx
mov eax,ebx
shl eax,12
mov ecx,LinearLimit
sub ecx,LinearBase
sub eax,ecx
js @@l89
cmp eax,MaxMemLin
jc @@l89
mov ebx,MaxMemLin
sub ebx,ecx
shr ebx,12
@@l89: pop ecx
cmp ebx,ebp
jnc @@l9
mov ebx,ebp
@@l9: shl ebx,12
clc
lss esp,f[esp]
pushf
add d[RawStackPos],RawStackDif
popf
popm eax,ecx,edx,esi,edi,ebp,ds,es
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
pushm ds,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 @@error
;
;Try extending useing physical memory first.
;
@@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,es:d[edi+eax*4] ;this page present?
test eax,1 ;do we have a page table?
jnz @@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 @@virtual
;
;both pages available so go to it.
;
@@f2: call PhysicalGetPage ;get a page.
jc @@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 @@error ;it lied.
call MapPhysical ;use this page for page table.
;
@@f1: call PhysicalGetPage ;get a page.
jc @@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 es:d[(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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -