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 + -
显示快捷键?