init.asm
来自「Dos6.0」· 汇编 代码 · 共 2,531 行 · 第 1/5 页
ASM
2,531 行
cmp al,MODE_AUTO ;Q: exit in Auto mode ?
jne short IE_ModeChkOFF ; N: check for mode = OFF
cmp gs:[Auto_State],0 ; Y: Q: go active ?
je short IE_ModeSet ; N: ok, mode is set
jmp short IE_ModeActive ; Y: go active now ...
IE_ModeChkOFF:
cmp al,MODE_OFF ;Q: exit mode is OFF ?
jne short IE_ModeActive ; N: mode is ON, turn CEMM on
mov [Devname],'$'
jmp short IE_ModeSet ; Y: ok, mode is set
IE_ModeActive:
call FarGoVirtual ; go to virtual mode
jc ICnon386
or gs:[Current_State],fState_Active; set active flag
IE_ModeSet:
;
; exit - display status messages and set exit status
;
IE_exit:
;
; display signon message first
;
mov ax,R_CODE
mov ds,ax
assume ds:R_CODE
cmp [msg_flag], 0 ; Q: any msgs to display?
jnz short disp_signon ; Y: disp signon msg even if !verbose
cmp [Verbose], TRUE ; N: skip signon unless verbose mode
jnz short skip_signon
disp_signon:
mov [Verbose], TRUE
call I_Message_Display
skip_signon:
;
; check for messages to display
;
mov ecx,MAX_MSG ; number of potential msgs
mov si,offset msg_tbl ; table of messages
mov ebx,1 ;
m_loop:
test [msg_flag],ebx ; q:is this one set?
jz short m_inc_ptr ; n: increment table pointer
mov dx,cs:[si] ; y: display message
PRINT_MSG
m_inc_ptr:
ADD SI, 2 ; Increment msg table ptr
shl ebx,1 ; Look for next flag
loop m_loop
TEST [msg_flag],KILLER_MSG ;Q: Is there a killer?
jnz IE_not_installed ; Y: Don't install
CMP [msg_flag], 0 ; Q: Is there a warning?
JE SHORT no_KLLR_MSG ; N: Continue
CALL wait_key ; Wait for 10 seconds
no_KLLR_MSG:
ifdef DEBUG
bt [GenFlags],fDebugActiveBit
jnc IE_NoDebug
or [TrapFlags],fpModeDebInit ; protected mode debugger
int ProtTrap ; initialization
IE_NoDebug:
endif
pushf
cli
;
; Initialize Virtual HMA
;
call VirHMAinit
;
; Add real mode interrupt handlers
;
call PICVecInit
ifdef ROMcomp
;
; Fixup IVT for ROM compression
;
call FixIVTptrs
endif
xor ax,ax
mov es,ax
ASSUME es:ABS0
; Add an INT 15h handler
mov ax,seg R_CODE
shl eax,16
mov ax,offset R_CODE:rINT15hHandler
xchg es:[int15],eax
mov [PrevInt15],eax
; Add CEMM to INT 19h chain.
mov ax,seg R_CODE
shl eax,16
mov ax,offset R_CODE:rINT19hHandler
xchg es:[int19],eax
mov [PrevInt19],eax
; Add CEMM to INT 2Fh chain.
mov ax,seg R1_CODE
mov fs, ax
shl eax,16
mov ax,offset R1_CODE:rINT2FhHandler
xchg es:[int2f],eax
mov dword ptr fs:[PrevInt2f],eax
; Add CEMM to INT 4Bh chain.
mov ax,seg R1_CODE
shl eax,16
mov ax,offset R1_CODE:rINT4BhHandler
xchg es:[int4B],eax
mov fs:[PrevInt4B],eax
; The int 67h vector is now patched out with CEMM's routine.
mov es:[int67],offset R_CODE:EMM_rEntry
mov es:[int67+2],seg R_CODE
; Add an INT 13h handler
call Install_I13handler
;
; Chain possible UMB links
;
call UMBlink
call MovUmbSeg
popf ; restore interrupt flag state
call MoveExtBIOS ; move extended BIOS data area
xor eax,eax ; clear high order word
int 12h ; get base memory size
push ax ; save it
; The end of the driver's resident part is rounded up to
; a 1k boundary.
mov ax,cs:[EndDriver]
add ax,40h - 1
shr eax,6
add ax,DOS3X_ADJ + 64 ; add in dos 3.xx adjustment and 64k
pop dx ; get base memory back
cmp dx,ax ; q: do we have enough?
jae short IE_setbrk ; y: continue
or gs:[msg_flag],MEM_ERR_MSG ; n: set memory error
jmp IE_exit ; and exit
;
; set driver break addr in Init Request Header
;
IE_setbrk:
mov bx,[bp+2] ; get entry DS from stack
mov es,bx
assume es:ABS0
mov bx,[bp+10] ; ES:BX pts to req hdr
mov ES:[bx.BRK_OFF],10h ; set it
mov ax,cs:[EndDriver] ; get brk addr segment
mov ES:[bx.BRK_SEG],ax ; set it
cmp [Verbose], TRUE ; Exit vocally?
jnz IE_Success ; N: keep quiet
mov ax,seg LAST
mov es,ax
assume es:LAST ; destination of message
mov dx,offset LAST:InstallMess
PRINT_MSG
mov ax,R_CODE
mov ds,ax
assume ds:R_CODE
call E_XStatus_Display
;
; output messages displaying state of Weitek support
;
test [Weitek_State],fWeitek_Inst ;Q: Weitek installed ?
jz short prnw_done ; N: no messages then
mov dx,offset LAST:WeitekONMess ; Y: assume Weitek ON
test [Weitek_State],fWeitek_Map ;Q: Weitek enabled ?
jnz short print_weitek ; Y: display message
mov dx,offset LAST:WeitekOFFMess ; N: assume OFF
print_weitek:
PRINT_MSG
; chk for Weitek not accessible
cmp [Initial_Mode],MODE_OFF ;Q: CEMM OFF specified ?
jne short prnw_done ; N: no more messages
mov dx,offset LAST:WeitekNAMess ; Y: W not accessible
PRINT_MSG
prnw_done:
;
; output messages displaying current mode
;
mov dx,offset LAST:OFFMess
cmp [Current_Mode],MODE_OFF ;Q: OFF mode ?
je short print_mode ; Y: print it's message
cmp [Current_Mode],MODE_AUTO ;Q: auto mode ?
jne short print_ONOFF ; N: check for ON/OFF
mov dx,offset LAST:AutoMess ; Y: display AUTO mode message
PRINT_MSG ;
print_ONOFF:
mov dx,offset LAST:InactiveMess ; assume inactive
test [Current_State],fState_Active ;Q: Active ?
jz short print_mode ; N: display OFF message
mov dx,offset LAST:ActiveMess ; Y: display ON message
print_mode:
PRINT_MSG
;
; all done with no errors
;
IE_Success:
xor ax,ax ; NO errors
;
.8086 ; Must be in 8086 instructions
IE_leave:
pop es
pop ds
pop di
pop bp
pop dx
pop bx
mov ss,cs:[SYSSS] ; restore DOS stack
mov sp,cs:[SYSSP]
ret
;
.386p
IE_not_installed:
mov eax,-1 ; abort in progress
call MemExit ; put back memory we took
.8086 ; Must be in 8086 instructions
ICerror:
call ErrorExit ; Clean up on error condition
ICerror1:
call wait_key ; pause to let user read error
mov ax,ERROR ; error return
jmp short IE_leave
ICnon386:
mov dx,offset LAST:Incorrect_PRT
jmp short ICmessPrint
ICinvdos:
mov dx, offset LAST:Inv_DOS_msg
jmp short ICmessPrint
ICbadstate:
mov dx, offset LAST:bad_mc_state
ICmessPrint:
PRINT_MSG
jmp short ICerror1
;
Init_CEMM386 endp
.386p ; Here can be 386P?
page
;******************************************************************************
;
; parser - parse out CEMM parameters and set appropriate values.
;
; entry: es:di == config.sys command line parameters
; ds = _DATA
; 386 systems only
; exit: [min/max_pool_size] = expanded memory sizes
; [Initial_Mode] = mode for driver exit
; [msg_flag] = appropriate messages to display
; ... many others ...
;
; used: none
;
;******************************************************************************
;
ASSUME CS: LAST, DS: _DATA, GS: R_CODE
Parser PROC
PUSHA
PUSH DS
PUSH ES
PUSH FS
MOV SI, _DATA
MOV FS, SI
ASSUME FS: _DATA
MOV SI, DI
MOV DI, ES ; Move ES:DI to DS:SI
MOV DS, DI
MOV DI, LAST ; ES:DI points to token buffer
MOV ES, DI
ASSUME ES: LAST
MOV DI, OFFSET tknBuf
CLD ; Direction set to increment
CALL Get_Token ; Skip the first token
JCXZ no_token
nexToken:
;
; CX = Get_Token(DS:SI, ES:DI);
;
CALL Get_Token
JCXZ no_token
CALL Parse_Token
JMP nexToken
no_token:
MOV AX, _DATA
MOV DS, AX
ASSUME DS: _DATA
cmp gs:[Initial_Weitek],0FFh; Q: did they specifiy Weitek mode ?
je short def_mode ; N: ok, leave it off
test gs:[Weitek_State],fWeitek_Inst ;Q: Weitek installed ?
jz short setwm_notpres ; N: set msg flag
cmp gs:[Initial_Weitek],0 ; Y:Q: Weitek OFF ?
je short setwm_done ; Y: leave flag off
or gs:[Weitek_State],fWeitek_Map ; N: set flag -> ON
jmp SHORT setwm_done
setwm_notpres:
or gs:[msg_flag],W_NI_MSG ; warning flag set
setwm_done:
def_mode:
cmp gs:[Initial_Mode],0FFh ;Q: did they specify mode ?
jne short def_mode2 ; Y: ok ...
ifdef MSFLAG
mov gs:[Initial_Mode],MODE_ON ; N: default is ON MODE (MS)
else
mov gs:[Initial_Mode],MODE_AUTO ; N: default is AUTO MODE (CPQ)
endif
def_mode2:
cmp byte ptr cs:[RAMset],2 ;Q: RAM specified?
jne short def_ON ; Y: turn CEMM ON
ifdef 901022
cmp byte ptr cs:[ROMset],2 ;Q: ROM specified?
jne short def_ON ; Y: turn CEMM ON
endif
cmp cs:[UMBset],TRUE ;Q: RAM specified?
je short def_ON ; Y: turn CEMM ON
cmp cs:[HMAonSet],TRUE ;Q: Virtual HMA requested?
je short def_ON ; Y: turn CEMM ON
cmp gs:[NoPFset],TRUE ;Q: FRAME=NONE specified?
je short def_ON ; Y: turn CEMM ON
cmp gs:[NoEMSset],TRUE ;Q: NoEMS specified?
jne short def_size ; Y: turn CEMM ON
def_ON:
mov gs:[UMBHMA],TRUE ; CEMM is providing UMBs or an HMA
mov gs:[Initial_Mode],MODE_ON; turn CEMM ON
def_size:
ifdef 910611
cmp cs:[pool_size],0 ;Q: Did user specify size?
jnz short P_locate_windows ; Y: OK
mov cs:[pool_size],256 ; N: default to 256K
P_locate_windows:
endif
call NoEMScheck
; Make sure that the MIN and MAX EMS pool sizes make sense. The
; min_pool_size must be <= max_pool_size which must be <= total free memory.
; If the max or min need to be adjusted from a value explictly set by the
; user, flag the SIZE_ADJ_MSG. Either or both parameters can be defaulted,
; and if the user selects a min > max, raise the max. We don't know how
; much free memory is available at this time so that needs to be checked
; later.
mov ax, [min_pool_size] ; make sure min_pool_size <= max_pool
cmp ax, [max_pool_size]
jbe short sizes_ok
cmp [min_pool_set], TRUE ; if MIN=size explictly given, adjust
je short adj_max ; the max value up
mov ax, [max_pool_size] ; otherwise adjust the defaulted min
mov [min_pool_size], ax ; value down
jmp short sizes_ok
adj_max:
mov [max_pool_size], ax
cmp [max_pool_set], TRUE ; if max was explictly set, tell user
jne short sizes_ok ; we changed it
or gs:[msg_flag], SIZE_ADJ_MSG
sizes_ok:
;
; The EMS windows are located and the page frame is selected.
;
call FindWindowLocations
cmp gs:[PF_Base], FREE
jne SHORT P_check_for_warning
cmp gs:[NoEMSset],TRUE ;Q: NoEMS set?
je short parse_xit ; Y: continue
cmp gs:[NoPFset],TRUE ;Q: FRAME=NONE set?
je short parse_xit ; Y: continue
; If this is reached then there are no valid page frames
CMP [xma2ems], TRUE ; Q: Is it in XMA2EMS mode?
JNE SHORT no_PF_no_XMA ; N: Bad!
OR GS:[msg_flag], NO_LIM_PF_MSG ; Set error flag
JMP SHORT P_check_for_warning
no_PF_no_XMA:
; Set the message flag and load with NOEMS
OR GS:[msg_flag], NO_PF_MSG
mov gs:[NoEMSset], TRUE ; set NOEMS mode
JMP def_mode ; and try again
; If the user supplied page frame has ROM in it then print
; out a warning to him.
P_check_for_warning:
cmp cs:[PFB_warning],FALSE
je short parse_xit
or gs:[msg_flag],PF_WARN_MSG
parse_xit: ; restore registers and exit
POP FS
POP ES
POP DS
POPA
RET
Parser ENDP
;******************************************************************************
; Get_Token - Retrieves a token from DS:SI and stores it at ES:DI
;
; ENTRY: DS:SI points to string where a token is to be retrieved
; ES:DI points to a buffer where a token is to be stored
; EXIT: DS:SI points to string where tokens remain to be retrieved
; CX is the number of characters in ES:DI
; USED: CX, SI
; STACK: <amount of stack used by routine>
;------------------------------------------------------------------------------
public Get_Token
Get_Token PROC
PUSH AX
PUSH DI
;
; while (DS[SI] == ' ' || DS[SI] == '\t') SI++;
;
SPorTB: ; Skip all white characters
LODSB ; Get a character
CMP AL, ' ' ; Q: Is it a space?
JE SPorTB ; Y: Skip it
CMP AL, TB ; Q: Is it a tab?
JE SPorTB ; Y: Skip it
;
; CX = 0;
; do {
; if (DS[SI] == CR || DS[SI] == LF || DS[SI] == ' ' || DS[SI] == '\t')
; break;
; CX++;
; ES[DI++] = toupper(DS[SI++]);
; } while (1);
; ES[DI++] = '\0';
;
XOR CX, CX ; Initialize counter
checkCH:
CMP AL, CR ; Q: Is this character a CR?
JE SHORT EOToken ; Y: it's the end of the token
CMP AL, LF ; Q: Is this character a LF?
JE SHORT EOToken ; Y: it's the end of the token
CMP AL, ' ' ; Q: Is this character a space?
JE SHORT EOToken ; Y: it's the end of the token
CMP AL, TB ; Q: Is this character a tab?
JE SHORT EOToken ; Y: it's the end of the token
INC CX ; N: it's a valid character in token
CMP AL, 'a' ; Q: Is it less than 'a'?
JB SHORT storeAL ; Y: not 'a'..'z'
CMP AL, 'z' ; Q: Is it greater than 'z'?
JA SHORT storeAL ; Y: not 'a'..'z'
AND AL, NOT 20h ; Convert to 'A'..'Z'
storeAL:
STOSB ; Store the character
LODSB ; Retrieve another character
JMP checkCH
EOToken:
XOR AL, AL ; End of string
STOSB
POP DI
POP AX
RET
Get_Token ENDP
;******************************************************************************
; Parse_Token - Checks the validity of a token, and keeps it when valid
;
; ENTRY: ES:DI points to a buffer where a token is stored
; EXIT:
; USED:
; STACK: <amount of stack used by routine>
;------------------------------------------------------------------------------
public Parse_Token
Parse_Token PROC
PUSHAD
PUSH DS
MOV AX, LAST
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?