init.asm
来自「Dos6.0」· 汇编 代码 · 共 2,531 行 · 第 1/5 页
ASM
2,531 行
mov cs:[UMBset],TRUE
add si,3
jmp PT_exit
RAMrange: ; RAM=FROM-TO
add si,2 ; get to "=" sign
lea bx,[RAMSet]
jmp GetRange
ROMrange: ; ROM=FROM-TO
add si,2 ; get to "=" sign
lea bx,[ROMSet]
jmp GetRange
ROMparam: ; ROM(COMPRESS)
dec si ; start at "R" again
mov cs:[ROMparm],TRUE ; assume it compares
push es ; save current ES
push cs ; make ES:DI point to "ROMCOMPRESS"
pop es
lea di,ROMCompParm
mov cx,ROMCompLen ; length of string
cld
rep cmpsb ;Q: Does it match
pop es
jz PT_exit ; Y: OK
dec si ; N: check why not
cmp byte ptr ds:[si],' ' ;Q: Was it due to a space?
je PT_exit ; Y: OK
cmp byte ptr ds:[si],'0' ;Q: Was it another character
jb PT_exit ; N: OK
cmp byte ptr ds:[si],'Z'
ja PT_exit
mov cs:[ROMparm],FALSE ; bad parameter
jmp inv_parm
Get_Wetek_Mode: ; W
cmp byte ptr ds:[si], '='
jne WinParm
CMP GS:[Initial_Weitek], FREE; Q: Has the weitek been set?
JNE inv_parm ; Y: Bad!
inc si
MOV BX, SI
MOV DI, OFFSET op_on
MOV CX, ONLEN
REPE CMPSB
JNE SHORT check_woff
MOV GS:[Initial_Weitek], 1
JMP PT_exit
check_woff:
MOV SI, BX
MOV DI, OFFSET op_off
MOV CX, OFFLEN
REPE CMPSB
JNZ inv_parm
MOV GS:[Initial_Weitek], 0
JMP PT_exit
WinParm:
cmp dword ptr ds:[si-1], '=NIW' ;Q: WIN=?
jne inv_parm
add si,2 ; get to "=" sign
lea bx,[WINset]
jmp GetRange
GetFullPath: ; M010 - Start
lodsb
cmp al, '='
jne inv_parm
call StorePath ; save user specified path in CEMMPath
jmp PT_exit ; M010 - End
Vir8042Parm:
cmp dword ptr ds:[si],'08RI' ;Q: correct switch?
jne VerboseParm ; N:
cmp word ptr ds:[si+4],'24' ;Q: correct switch?
jne VerboseParm ; N:
or gs:[GenFlags],fVir8042 ; Y: virtualize 8042 (keyboard)
add si,6
jmp PT_exit
VerboseParm:
dec si ; backup to 'V'
mov di, OFFSET verbose$ ; 'VERBOSE'
mov cx, verboseLen
repe cmpsb
jz got_verbose
cmp byte ptr ds:[si-1], 0 ; allow V, VE, VER, ... VERBOSE
jnz inv_parm
got_verbose:
mov cs:[Verbose], TRUE
jmp PT_exit
GetExcludeRange: ; X=FROM-TO
lea bx,[eXcSet]
jmp short GetRange
GetIncludeRange: ; I=FROM-TO
lea bx,[IncSet]
jmp short GetRange
;==============================================================================
;==
;== GetRange: Routine which extracts the range from a parameter of the form:
;==
;== [variable]=xxxx-yyyy (xxxx/yyyy: hexadecimal segment values)
;==
;== Enter:
;== DS:SI pointer to parameter at "=" sign.
;== DS:[BX] pointer to a word array which will store the range information.
;==
;== Exit:
;== DS:SI points to blank after the parameter
;== DS:[BX] array is updated to include the range.
;==
;==============================================================================
public GetRange
GetRange:
lodsb
cmp al,'=' ;Q: Possible range?
jne short inv_parm ; N: invalid parameter
int 12h ; Get conventional memory size
shl ax,6 ; In paragraph
mov cx,ax
call Get_Hexadecimal ; Get FROM
or dx,dx
jnz short inv_parm
cmp ax,cx ; Valid range: INT 12h-FFFF
jb short inv_parm
movzx di,byte ptr [bx]
mov [bx][di],ax ; save from value
cmp byte ptr ds:[si-1], '-' ;Q: Is there a TO?
jne short GFskipTO ; N: TO = FROM
mov cx,ax ; Save FROM
call Get_Hexadecimal ; Y: Get TO
jc short GFuseFROM
or dx,dx
jnz short GFuseFROM
cmp ax,cx ;Q: TO > FROM?
jb short GFuseFROM ; N: TO cannot be less tham FROM
GFskipTO:
add di,2
add byte ptr [bx],4
mov [bx][di],ax
jmp short PT_exit
GFuseFROM:
mov ax,cx
or gs:[msg_flag],INV_PARM_MSG ; set invalid parameter flag
jmp short GFskipTO
Invalid_Parameter:
inv_parm:
OR GS:[msg_flag], INV_PARM_MSG ; set invalid parameter flag
PT_exit:
POP DS
POPAD
RET
Parse_Token ENDP
;
; DX:AX = Get_Decimal
;
;******************************************************************************
; Get_Decimal - Translates ASCII decimal numbers
;
; ENTRY: DS:SI points to a buffer where a string is to be translated
; EXIT: DX:AX stores the number
; CY is set if error detected
; USED:
; STACK: <amount of stack used by routine>
;------------------------------------------------------------------------------
public Get_Decimal
Get_Decimal PROC
push ebx
push eax
xor eax,eax ; clear sum and current digit
xor ebx,ebx
LODSB
OR AL, AL ;Q: Anything there?
JZ SHORT invalid_ddd ; N: error
JMP SHORT check_AL ; Y: check if it's a digit
next_ddd:
LODSB ; get next digit
OR AL, AL ;Q: Anything there?
jnz short check_AL ; Y: check if it's a digit
pop eax ; N: return total in DX:AX
mov ax,bx ; low order word in AX
shr ebx,16 ; high order word in DX
mov dx,bx
clc
jmp short GDexit
check_AL:
CMP AL, '0' ;Q: Is it an ASCII digit?
JB SHORT invalid_ddd ; N: error
CMP AL, '9' ;Q: Is it an ASCII digit?
JA SHORT invalid_ddd ; N: error
SUB AL, '0' ; make it an integer
add ebx,ebx ; multiply current total by two
test ebx,0E0000000h ;Q: Reaching overflow of 32-bits?
jnz short invalid_ddd ; Y: must be an error! (number too large)
lea ebx,[ebx*4+ebx] ; N: multiply total by ten
add ebx,eax ; add new digit to total
JMP next_ddd
invalid_ddd:
pop eax
mov ax,bx
shr ebx,16
mov dx,bx
STC
GDexit:
pop ebx
ret
Get_Decimal ENDP
;
; DX:AX = Get_Hexadecimal
;
;******************************************************************************
; Get_Hexadecimal - Translates ASCII hexadecimal numbers
;
; ENTRY: DS:SI points to a buffer where a string is to be translated
; EXIT: DX:AX stores the number
; CY is set if error detected
; USED:
; STACK: <amount of stack used by routine>
;------------------------------------------------------------------------------
public Get_Hexadecimal
Get_Hexadecimal PROC
PUSH BX
PUSH CX
XOR AX, AX ; bottom part of result
LODSB
OR AL, AL
JZ SHORT invalid_hhh
XOR BX, BX ; Sum
XOR DX, DX ; top part of result
MOV CX, 16 ; Hexadecimal
JMP SHORT check_hh
next_hhh:
LODSB
OR AL, AL ; also clears carry
JZ SHORT no_hhh
check_hh:
CMP AL, 'A'
JB SHORT check_dd
CMP AL, 'F'
JA SHORT invalid_hhh
SUB AL, 'A'
ADD AL, 10
JMP SHORT calculator
check_dd:
CMP AL, '0'
JB SHORT invalid_hhh
CMP AL, '9'
JA SHORT invalid_hhh
SUB AL, '0'
calculator:
XCHG AX, BX
MUL CX
ADD AX, BX
ADC DX, 0
XCHG AX, BX
JMP next_hhh
invalid_hhh:
STC
no_hhh:
XCHG AX, BX
POP CX
POP BX
RET
Get_Hexadecimal ENDP
;
; ZF = Frame_Check(AX);
;
;******************************************************************************
; Frame_Check - Checks if the page frame is valid
;
; ENTRY: ED:DI points to a buffer where valid frames are stored
; AX stores the number to be checked
; EXIT: ZR is frame is invalid
; USED:
; STACK: <amount of stack used by routine>
;------------------------------------------------------------------------------
public Frame_Check
Frame_Check PROC
PUSH ES
PUSH DI
LES DI, framadr
CLD
REPNE SCASW
POP DI
POP ES
RET
Frame_Check ENDP
;==============================================================================
;==
;== NoEMScheck: If the [NoEMS] parameter is chosen. Changes all the defaults
;== to a minimum configuration.
;==
;==
;==============================================================================
public NoEMScheck
assume cs:LAST,ds:_DATA,gs:R_CODE
NoEMScheck proc near
cmp gs:[NoEMSset],TRUE ; Q: Was [NoEMS] set?
je NEcCont ; Y: continue
cmp cs:[max_pool_size],0 ; Q: Did user specify size?
jnz short NEcDone ; Y: OK
mov cs:[max_pool_size], MAX_SIZE ; default to large EMS size
NEcDone:
ret
NEcCont:
; Since noems has been specifed we need to setup with frame=none
; parms and also provide a 0 pool size if the user has not specifed
; any.
mov gs:[NoEMSset], FALSE
mov gs:[NoPFset], TRUE
;
; set up VCPIset to imply the foll.
;
; VCPIset = -1 => NOEMS has not been specifed (default)
; VCPIset = TRUE => NOEMS has been specifed
; VCPIset = FALSE => NOEMS+NOVCPI has been specifed
;
mov gs:[VCPIset], FALSE ; assume NOEMS + NOVCPI
cmp cs:[NoVCPI], TRUE ; Q: did user disable VCPI too?
je short NEcSetNoems ; Y:
mov gs:[VCPIset], TRUE ; N: VCPI = TRUE
cmp cs:[min_pool_set], TRUE ; default min pool size with NOEMS
je short NEcMinSet ; is 0
mov cs:[min_pool_size], 0
NEcMinSet:
cmp cs:[max_pool_set], TRUE ; default to large EMS/VCPI size
je short NEcMaxSet ; if VCPI support enabled
mov cs:[max_pool_size], MAX_SIZE
NEcMaxSet:
; Note: we'll set up the device name to EMMQXXX. This will enable
; Lotus 123 to work with noems option.
mov gs:[DevName+3],'Q'
; Some programs can't detect EMM386 when it's installed with the
; 'EMMQXXX0' name, so when this name is used add a second device
; driver header with the name '$MMXXXX0' that these programs do
; know to detect.
mov gs:[DEVHEAD], offset R_CODE:DEVHEAD2 ;link in second header
ret
; User doesn't want EMS or VCPI, must be a UMB only type of guy.
NEcSetNoems:
ifdef QLEO
or ax,ax
jz short NEcAltRegSets
or gs:[msg_flag],NoEMS_MSG
NEcAltRegSets:
endif
mov ds:[total_register_sets],2
ifdef QLEO
cmp cs:[altRset],0
je short NEcHandle
or gs:[msg_flag],NoEMS_MSG
NEcHandle:
endif
mov [total_handles],2
mov gs:[ttl_hndls],2
ifdef QLEO
cmp cs:[$Hset],0
je short NEcBase
or gs:[msg_flag],NoEMS_MSG
NEcBase:
cmp cs:[baseset],0
je short NEcPn
or gs:[msg_flag],NoEMS_MSG
NEcPn:
cmp cs:[PnSet],0
je short NEcFrame
or gs:[msg_flag],NoEMS_MSG
NEcFrame:
cmp gs:[PF_Base],FREE
je short NEcExit
or gs:[msg_flag],NoEMS_MSG
endif
mov gs:[DevName],'$'
NEcExit:
ret
NoEMScheck endp
;==============================================================================
;==
;== GetEMSPool: This subroutine preallocates the EMS pool for CEMM.
;==
;== Entry: (Real Mode)
;== CS:[min_pool_size] = minimum EMS pool size requested
;==
;== Exit:
;== CS:[min_pool_size] = preallocated EMS pool size
;== CS:[ext_size] = extended memory pool size (size of pool 1)
;== CS:[hi_size] = BIM pool size (size of pool 2)
;== CS:[ext_memory_address] = extended pool address (address of pool 1)
;== CS:[high_memory_address]= BIM pool address (address of pool 2)
;==
;==============================================================================
public GetEMSPool
assume ds:_DATA,es:ABS0,gs:R_CODE
GetEMSPool proc near
;
; Initialize variables
;
xor eax,eax
mov cs:[ext_memory_address],eax
mov cs:[high_memory_address],eax
mov cs:[ext_size],ax
mov cs:[hi_size],ax
;
; Leave atleast L=nnn extended memory after CEMM installs (default: L=0)
;
;+++
CMP CS:[ext_mem], FREE ; Q: Is L=ddd set?
JE SHORT skip_left_alone ; N: Skip these steps
CALL TotalFreeMem ; EAX = TotalFreeMem();
JC GEPerror
SHR EAX, 10 ; In K bytes
MOV EBX, CS:[ext_mem]
SUB EAX, EBX
JBE GEPerror
MOVZX EBX, cs:[max_pool_size]
CMP EAX, EBX
JAE SHORT skip_left_alone
CMP AX, MIN_SIZE
JB GEPerror
AND AX, NOT 0Fh ; Round it down to multiple 16K ;@PIW
OR GS:[msg_flag], SIZE_ADJ_MSG; Memory size adjusted message;@PIW
MOV cs:[max_pool_size], AX
cmp ax, cs:[min_pool_size] ; Max EMS pool size adjusted, don't
jae skip_left_alone ; let Min size be larger than Max
mov cs:[min_pool_size], ax
skip_left_alone:
;+++
;
; Try get all of preallocated EMS pool from BIM
;
xor ebx,ebx
movzx eax,cs:[min_pool_size] ; size of preallocated pool requested
or ax,ax ;Q: Any EMS pool needed?
jz short GEPcont ; N: no memory used
shl eax,10 ; in bytes
mov bx,fBIMMem
shl ebx,16
mov bx,EMS_BOUNDARY ; EMS bound and BIM
call MemGet ;Q: Enough BIM for EMS pool?
jc short GEPnotEnoughBIM ; N: not enough
GEPcont: ; Y: save starting address
mov [high_memory_address],ebx
shr eax,10 ; size in Kbytes
mov [hi_size],ax
jmp GEPexit
;
; Try get what is available from BIM
;
GEPnotEnoughBIM:
and eax,not (4000h-1) ; round down to 16 Kbytes
or eax,eax ;Q: Any BIM available?
jnz short GEPhi ; Y: allocate all of it?
movzx eax,cs:[min_pool_size] ; N: allocate any type of memory
shl eax,10 ; size in bytes
mov ebx,EMS_BOUNDARY ; must be 4K aligned
GEPhi:
and eax,not (4000h-1) ; round down to 16 Kbytes
or eax,eax ;Q: Any memory to allocate?
jz short GEPerror ; N: no memory available
call MemGet ;Q: Allocate hi memory?
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?