cw32.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,222 行 · 第 1/5 页

ASM
2,222
字号
ELSE
        mov     ax,3
        int     10h
ENDIF


;
;Stow real mode PSP and environment values, we'll need them later.
;
        mov     RealPSPSegment,es
        mov     ax,WORD PTR es:[02ch]
        mov     RealEnvSegment,ax       ;Stow ENV for later.
;
;Re-size memory so we can allocate what we want high.
;
        mov     cs:IErrorNumber,1
        mov     ax,es
        mov     bx,_cwEnd               ;Get program end segment.
        sub     bx,ax           ;Size program.
        inc     bx
        mov     ah,4ah
        int     21h             ;Re-size memory block.

; MED 06/16/97
;       jc      InitError
        jnc     chk386

toiniterr:
        jmp     InitError

;
;Check we're on at least a 386 system.
;
chk386:
        mov     cs:IErrorNumber,2
        call    CheckProcessor

;       jc      InitError
        jc      toiniterr

;
;Check DOS version is high enough.
;
        mov     cs:IErrorNumber,4
        call    CheckDOSVersion
        jc      InitError
;
;Get execution name from environment.
;
        call    GetEXECName
;
;Retrieve setup info from 3P header.
;
        call    GetSystemFlags
;
;Check if a suitable method for switching to protected mode exists.
;
        call    GetProtectedType
        mov     cs:IErrorNumber,3
        cmp     ProtectedFlags,0        ;Any types available?
        jz      InitError
;
;Get CAUSEWAY environment variable settings.
;
        call    GetENVStuff
;
;Decide which environment to use.
;
        call    SetProtectedType
;
;Move the DTA to where we can get at it in the future.
;
        mov     dx,offset DTABuffer
        mov     ah,1ah
        int     21h
;
;now see about type specific initialisations.
;
        cmp     ProtectedType,2 ;DPMI initialiseation?
        jz      cw5_InitDPMI
;
;Useing either RAW or VCPI so do the stuff that's common to both for now.
;
        mov     ax,_cwRaw
        mov     ds,ax
        assume ds:_cwRaw
;
;Get SDA address so VMM can change BREAK state.
;
        .386
        push    ds
        mov     ax,5d06h
        int     21h
        mov     ax,ds
        pop     ds
        add     si,17h
        movzx   eax,ax
        shl     eax,4
        movzx   esi,si
        add     eax,esi
        mov     BreakAddress,eax
;
;Find out if XMS is present.
;
        mov     ax,4300h                ;XMS install check.
        int     2fh
        cmp     al,80h          ;XMS present?
        jnz     cw5_NoXMS
;
;XMS detected so work out max block size and entry point.
;
        mov     ax,4310h                ;Get XMS API.
        int     2fh
        mov     w[XMSControl],bx
        mov     w[XMSControl+2],es
        mov     XMSPresent,1            ;flag XMS is available.

; MED, 09/10/99, support extended XMS API to calculate XMS available to CauseWay
;  (maximum of 2G-32K, i.e. 32 handles/entries of 64K-1)
        mov     ah,0
        call    d[XMSControl]   ; get info
        cmp     ah,3
        jb      xms2
        cmp     bh,3
        jb      xms2
        cmp     bl,8
        jb      xms2                    ; treat early 3.x drivers < 3.08 as 2.x

; use extended XMS API
        mov     XMSVer3Present,1        ; flag XMS 3.x driver present
        mov     ah,88h
        call    d[XMSControl]   ;get size of biggest block free.
        mov     edx,eax
        test    eax,eax
        jz      cw5_YesXMS              ;no memory available.
        mov     DWORD PTR cs:[cw5_XMSSize],edx
        mov     ah,89h
        call    d[XMSControl]   ;claim biggest block to force XMS
        cmp     ax,1                    ;to stake a claim on int 15h.
        jnz     cw5_YesXMS
        mov     BYTE PTR cs:[cw5_NumXMSHandles],1
        push    dx
        mov     ah,8eh
        call    d[XMSControl]   ; get handle information
        cmp     ax,1
        jnz     cw5_NoHandles3
        cmp     cx,4
        jc      cw5_NoHandles3
        sub     cx,2
        mov     BYTE PTR cs:[cw5_NumXMSHandles],32
        cmp     cx,32
        jnc     cw5_NoHandles3
        mov     BYTE PTR cs:[cw5_NumXMSHandles],cl      ; cx known 8-bit value

cw5_NoHandles3:
        pop     dx
        mov     ah,0ah
        call    d[XMSControl]   ;now free it.

        movzx   eax, BYTE PTR cs:[cw5_NumXMSHandles]
        mov     edx,eax
        shl     eax,16
        sub     eax,edx         ; eax == handles (up to 32) * 65535
        cmp     eax,DWORD PTR cs:[cw5_XMSSize]
        jae     cw5_ComputeSize
        mov     DWORD PTR cs:[cw5_XMSSize],eax  ; throttle maximum size

cw5_ComputeSize:
        push    eax
        xor     edx,edx
        movzx   ebx,BYTE PTR cs:[cw5_NumXMSHandles]
        div     ebx
        pop     ebx
        cmp     ax,4            ; eax known 16-bit value
        jnc     cw5_SizeOK3
        mov     ax,bx           ; ebx == maximum size, known 16-bit value here

cw5_SizeOK3:
        mov     XMSBlockSize,ax
        jmp     cw5_YesXMS

xms2:
        mov     ah,8
        call    d[XMSControl]   ;get size of biggest block free.
        mov     dx,ax
        or      ax,ax
        jz      cw5_YesXMS              ;no memory available.
        mov     WORD PTR cs:[cw5_XMSSize],dx
        mov     ah,9
        call    d[XMSControl]   ;claim biggest block to force XMS
        cmp     ax,1            ;to stake a claim on int 15h.
        jnz     cw5_YesXMS
        mov     BYTE PTR cs:[cw5_NumXMSHandles],1
        push    dx
        mov     ah,0eh
        call    d[XMSControl]   ;now free it.
        cmp     ax,1
        jnz     cw5_NoHandles
        cmp     bl,4
        jc      cw5_NoHandles
        sub     bl,2
        mov     BYTE PTR cs:[cw5_NumXMSHandles],32
        cmp     bl,32
        jnc     cw5_NoHandles
        mov     BYTE PTR cs:[cw5_NumXMSHandles],bl
cw5_NoHandles:  pop     dx
        mov     ah,0ah
        call    d[XMSControl]   ;now free it.
        mov     ax,WORD PTR cs:[cw5_XMSSize]
        push    ax
        xor     dx,dx
        xor     bh,bh
        mov     bl,BYTE PTR cs:[cw5_NumXMSHandles]
        div     bx
        pop     bx
        cmp     ax,4
        jnc     cw5_SizeOK
        mov     ax,bx
cw5_SizeOK:     mov     XMSBlockSize,ax
        jmp     cw5_YesXMS
;
;Install raw A20 handler.
;
cw5_NoXMS:      call    InstallA20
;
;Get A20 state.
;
cw5_YesXMS:     push    ds
        les     di,HighMemory   ;   with the four at FFFF:0090
        lds     si,LowMemory            ; Compare the four words at 0000:0080
        mov     cx,4
        cld
        repe  cmpsw
        pop     ds
        xor     ax,ax
        jcxz    cw5_A20OFF               ; Are the two areas the same?
        inc     ax                  ; No, return A20 Enabled
cw5_A20OFF:     mov     A20Flag,al
;
;Change DOS allocation stratergy to highest so we'll get UMB's if available.
;
        mov     ax,5800h
        int     21h
        mov     WORD PTR cs:[cw5_OldStrat],ax
        mov     ax,5802h
        int     21h
        mov     WORD PTR cs:[cw5_OldStrat+2],ax
        mov     bx,1
        mov     ax,5803h
        int     21h
        mov     bx,81h
        mov     ax,5801h
        int     21h
;
;Grab memory for page dir, page alias & first page table entry.
;
        mov     bx,(4096*3)/16  ;smallest allocation possible.
        mov     ah,48h
        int     21h
        jc      cw5_OldWay
        push    ax
        movzx   eax,ax
        shl     eax,4           ;linear address.
        mov     ebx,eax
        add     eax,4095
        and     eax,0ffffffffh-4095     ;round up to next page.
        sub     eax,ebx
        shr     eax,4
        mov     bx,ax
        mov     cx,ax
        add     bx,(4096*3)/16
        mov     ah,4ah
        pop     es
        push    bx
        push    cx
        push    es
        int     21h             ;re-size the block.
        pop     es
        pop     cx
        pop     bx
        jnc     cw5_NewWay
        mov     ah,49h
        int     21h             ;release this block.
        ;
cw5_OldWay:     mov     cs:IErrorNumber,5
        mov     bx,(4096*4)/16  ;need space for 3 page tables on
        mov     ah,48h          ;4k boundary.
        int     21h
        jc      InitError
        mov     dx,ax
        movzx   eax,ax          ;get segment address.
        shl     eax,4           ;make linear.
        mov     ebx,eax
        add     eax,4095
        and     eax,0FFFFFFFFh-4095     ;round up to nearest page.
        mov     ecx,eax
        sub     ecx,ebx
        shr     ecx,4
        shr     eax,4           ;Get segment value again.
        jmp     cw5_GotSeg
        ;
cw5_NewWay:     mov     ax,es
        mov     dx,ax
        add     ax,cx           ;move to real start.
        ;
cw5_GotSeg:
        push    cx
        push    dx
        mov     es,ax

; MED 09/19/96
;       mov     PageDirReal,ax  ;setup page directory address.
;       add     ax,4096/16
;       mov     Page1stReal,ax  ;setup 1st page table address.
        mov     Page1stReal,ax  ;setup 1st page table address.
        add     ax,4096/16
        mov     PageDirReal,ax  ;setup page directory address.

        add     ax,4096/16
        mov     PageAliasReal,ax        ;setup alias table address.
        xor     di,di
        mov     cx,4096*3
        xor     al,al
        cld
        rep     stosb           ;clear it.
        movzx   eax,PageDIRReal
        shl     eax,4
        mov     PageDIRLinear,eax
        mov     VCPI_CR3,eax
        movzx   eax,PageALIASReal
        shl     eax,4
        mov     PageAliasLinear,eax
        movzx   eax,Page1stReal
        shl     eax,4
        mov     Page1stLinear,eax
        pop     dx
        pop     cx
;
;See if enough wasted space to squeeze TSS into.
;
        cmp     cx,(((size TSSFields)+2+16)/16)
        jc      cw5_TSSOld
        mov     ax,dx                   ;get segment.
        add     dx,(((size TSSFields)+2+16)/16) ;move segment base.
        sub     cx,(((size TSSFields)+2+16)/16) ;update space left size.
        jmp     cw5_TSSGot
;
;Allocate memory for Kernal TSS.
;
cw5_TSSOld:     mov     cs:IErrorNumber,5
        mov     bx,(((size TSSFields)+2+16)/16) ;(4096/2)+2+16)/16
        mov     ah,48h
        int     21h
        jc      InitError
cw5_TSSGot:     mov     KernalTSSReal,ax
;
;See if enough wasted space to squeeze GDT into.
;
        cmp     cx,((8*GDT_Entries)/16)+1
        jc      cw5_GDTOld
        mov     ax,dx                   ;get segment.
        add     dx,((8*GDT_Entries)/16)+1       ;move segment base.
        sub     cx,((8*GDT_Entries)/16)+1       ;update space left size.
        jmp     cw5_GDTGot
;
;Allocate some memory for the GDT.
;
cw5_GDTOld:     mov     cs:IErrorNumber,5
        mov     bx,((8*GDT_Entries)/16)+1
        mov     ah,48h
        int     21h
        jc      InitError
cw5_GDTGot:     mov     GDTReal,ax
        mov     es,ax
        movzx   eax,ax
        shl     eax,4
        mov     GDTLinear,eax
        xor     di,di
        mov     cx,(8*GDT_Entries)
        xor     al,al
        cld
        rep     stosb
;
;Allocate some memory for the stack.
;
        mov     cs:IErrorNumber,5
        mov     ebx,RawStackPos
        shr     ebx,4
        mov     ah,48h
        int     21h
        jc      InitError
        mov     RawStackReal,ax
        mov     es,ax
        mov     cx,w[RawStackPos]
        xor     di,di
        xor     al,al
        cld
        rep     stosb

; MED 09/19/96
; Set address for VMM page to disk buffer.
        mov     cs:IErrorNumber,5
        mov     bx,4096/16
        mov     ah,48h
        int     21h
        jc      InitError
        mov     PageBufferReal,ax
        movzx   eax,ax
        shl     eax,4
        mov     PageBufferLinear,eax

;
;Restore DOS memory allocation stratergy.
;
        mov     bx,WORD PTR cs:[cw5_OldStrat+2]
        xor     bh,bh
        mov     ax,5803h
        int     21h
        mov     bx,WORD PTR cs:[cw5_OldStrat]
        xor     bh,bh
        mov     ax,5801h
        int     21h
;
;Need to initialise 1st page table to map <1meg+64k 1:1.
;
        mov     es,Page1stReal
        xor     di,di
        mov     cx,256+16               ;1st 1 meg + 64k.
        mov     esi,111b                ;user+write+present
cw5_0:  mov     es:[di],esi
        add     di,4            ;next page table entry.
        add     esi,4096                ;next physical page address.
        dec     cx
        jnz     cw5_0

; MED 09/19/96
COMMENT !
;
;Set address for VMM page to disk buffer.
;
        mov     ax,PageDIRReal
        mov     PageBufferReal,ax
        movzx   eax,ax
        shl     eax,4
        mov     PageBufferLinear,eax

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?