欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

memory.asm

开放源码的编译器open watcom 1.6.0版的源代码
ASM
第 1 页 / 共 5 页
字号:
        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 + -