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