📄 memory.asm
字号:
jnz @@f0 ;keep looking.
clc
jmp @@exit ;All physical so exit.
;
@@Virtual: ;Virtual memory will be needed so see if we can provide any.
;
cmp VMMHandle,0 ;Virtual memory active?
jz @@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 @@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 @@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 @@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 @@DoneTables
add ebx,ebx ;Page + Det
mov ecx,ebp
cmp ebx,edx
jc @@OK
jz @@OK
jmp @@error
;
@@OK: ;Allocate new page tables.
;
mov esi,PageDirLinear ;get page directory address.
mov edx,LinearLimit
shr edx,12
@@v2: mov eax,edx ;get new entry number.
shr eax,10 ;/1024 for page dir entry.
test es:d[esi+eax*4],1 ;this page present?
jnz @@v3
;
;get DET page.
;
pushm ecx,edx
call UnMapPhysical ;get a physical page for us to use.
mov eax,edx
mov ebx,ecx
popm ecx,edx
jc @@error ;not enough physical memory to support virtual memory.
pushm ecx,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.
popm ecx,edx
;
;And again for page table.
;
pushm ecx,edx
call UnMapPhysical ;get a physical page for us to use.
mov eax,edx
mov ebx,ecx
popm ecx,edx
jc @@error ;not enough physical memory to support virtual memory.
pushm ecx,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.
popm ecx,edx
@@v3: inc edx
dec ecx
jnz @@v2
;
@@DoneTables: ;Now mark all the new pages as un-locked/free
;
mov eax,LinearLimit
mov ecx,ebp
@@v4: call RawClearPageLock ;clear page locking for this entry.
push eax
shr eax,12
mov es:d[1024*4096*1022+eax*4],0
pop eax
add eax,4096
dec ecx
jnz @@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 @@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 Real_EAX[edi],eax
mov Real_EBX[edi],ebx
mov Real_ECX[edi],ecx
mov Real_EDX[edi],edx
mov Real_SS[edi],0
mov 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 Real_EAX[edi],eax
mov Real_EBX[edi],ebx
mov Real_ECX[edi],ecx
mov Real_EDX[edi],edx
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
push ds
pop es
call EMURawSimulateInt ;move to right place.
pop edi
pop ecx
test Real_Flags[edi],1
jnz @@disk_error
mov SwapFileLength,ecx
;
xor cx,cx
xor dx,dx
mov ax,4201h
mov bx,VMMHandle
push edi
mov edi,offset PageInt
mov Real_EAX[edi],eax
mov Real_EBX[edi],ebx
mov Real_ECX[edi],ecx
mov Real_EDX[edi],edx
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
push ds
pop es
call EMURawSimulateInt ;move to right place.
pop edi
test Real_Flags[edi],1
jnz @@disk_error
mov edx,Real_EDX[edi]
mov eax,Real_EAX[edi]
shl edx,16
mov dx,ax
cmp edx,SwapFileLength
jnz @@disk_error
;
@@Extended: ;Update the end of the memory map.
;
add FreePages,ebp
; sub medAllocPages,ebp
shl ebp,12
add LinearLimit,ebp
clc
jmp @@Exit
;
@@error: stc
@@Exit: ;
popm ds,es
popad
ret
;
@@Disk_Error: jmp @@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
pushm ds,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 es:d[esi+eax*4],1 ;this page present?
jnz @@AddPage
;
cmp PageDETLinear,0 ;DET in use yet?
jz @@AddTable
mov esi,PageDETLinear ;get page table address.
test es:d[esi+eax*4],1 ;DET page present?
jnz @@AddTable
;
@@AddDET: ;Need a new DET page.
;
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov es:d[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 @@Finished
;
@@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 es:d[esi+eax*4],edx ;store this tables address.
mov esi,PageAliasLinear ;get alias table address.
mov es:d[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 @@Finished
;
@@AddPage: ;Update recent page usage stack.
;
pushm ecx,es,ds
pop es
mov edi,offset RecentMapStack+(4*PageStackSize)-4
mov esi,offset RecentMapStack+(4*PageStackSize)-8
mov ecx,PageStackSize-1
std
rep movsd
popm ecx,es
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,es:d[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 es:d[esi+eax*4],edx ;set physical address.
;
cmp PageDETLinear,0
jz @@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
;
@@NoLocking: ;Check if this page needs fetching from swap space.
;
cmp VMMHandle,0
jz @@NoRead
;
test ebx,1 shl 11
jz @@NoRead
;
mov esi,BreakAddress
mov al,es:[esi]
mov es:b[esi],0
push eax
;
mov ecx,LinearEntry ;get page number.
shl ecx,12 ;get linear address.
sub ecx,LinearBase
mov dx,cx
shr ecx,16
mov bx,VMMHandle
mov ax,4200h
mov edi,offset PageInt
mov Real_EBX[edi],ebx
mov Real_EAX[edi],eax
mov Real_EDX[edi],edx
mov Real_ECX[edi],ecx
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
pushm es,ds
pop es
call EMURawSimulateInt ;move to right place.
mov edi,offset PageInt
mov ax,VMMHandle
mov Real_EBX[edi],eax
mov ax,PageBufferReal
mov Real_DS[edi],ax
mov Real_EAX[edi],3f00h
mov Real_EDX[edi],0
mov Real_ECX[edi],4096
mov Real_SS[edi],0
mov Real_SP[edi],0
mov bl,21h
call EMURawSimulateInt ;read it from disk.
pop es
test Real_Flags[edi],1
jz @@ok
mov esi,BreakAddress
pop eax
mov es:[esi],al
jmp @@Finished2
;
@@ok: mov esi,BreakAddress
pop eax
mov es:[esi],al
;
mov esi,PageBufferLinear
mov edi,LinearEntry
shl edi,12 ;get linear address again.
mov ecx,4096/4
pushm ds,es
pop ds
cld
rep movsd ;copy back into place.
pop ds
;
mov eax,LinearEntry ;get new entry number.
mov esi,1024*4096*1023 ;base of page alias's.
and es:d[esi+eax*4],0FFFFFFFFh-(3 shl 5) ;clear accesed & dirty bits.
call EMUCR3Flush
;
@@NoRead: inc LinearEntry ;update counter.
;
@@Finished: clc
;
@@Finished2: popm ds,es
popad
ret
assume ds:_cwDPMIEMU
MapPhysical endp
;-------------------------------------------------------------------------------
;
;Retrieve the address of the most un-needed physical memory and mark its current page table entry
;as not present after writing to disk if needed.
;
;On Entry:-
;
;On Exit:-
;
;EDX - Physical address of page.
;CL - User flags.
;
UnMapPhysical proc near
pushm eax,ebx,esi,edi,ebp,ds,es,fs
;
mov ax,KernalDS
mov ds,ax
mov es,ax
assume ds:_cwRaw
mov ax,KernalZero
mov fs,ax
;
mov ProposedPresentFlag,0
mov ProposedRecentFlag,0
mov CompareCount,0
;
mov esi,PageDirLinear
mov edi,1024*4096*1023 ;base of page alias's.
mov ebp,1024*4096*1022
mov ecx,PageingPointer ;get current position.
mov ebx,LinearLimit ;maximum size of scan we can do.
sub ebx,LinearBase
shr ebx,12
inc ebx
cld
;
@@ScanLoop: dec ebx
jnz @@80 ;shit, we've been all the way round.
;
cmp ProposedPresentFlag,0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -