⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genercfg.a86

📁 一个dos操作系统DRDOS的源码
💻 A86
📖 第 1 页 / 共 5 页
字号:
	mov	byte ptr [si],al	; command line string and update 
					; the count	

	mov	ax,offset envstart	; env buffer is para aligned
	mov	cl,4
	shr	ax,cl			; convert offset to paras
	mov	cx,ds
	add	ax,cx			; segment of env variables
	mov	exec_envseg,ax
	mov	exec_lineoff,si
	mov	exec_lineseg,ds
	mov	exec_fcb1off,0FFFEh	  ; Force PCMODE to generate
	mov	exec_fcb2off,0FFFEh	  ; correct FCB References

	mov	system_ss,ss
	mov	system_sp,sp

	mov	dx,offset dev_name	; Get ASCIIZ Command
	mov	bx,offset exec_envseg	; and Parameter Block Offset
	mov	ax,4B00h		; Load and Execute Program with Handle
	int	DOS_INT			; EXEC the application

	cli				; Swap back to the original stack
	mov	ss,cs:system_ss		; again with interrupts disabled
    mov sp,cs:system_sp
	sti

	mov	ah,MS_X_WAIT		; if all went well return the
	 jnc	func_i20		;  termination code
	mov	ah,MS_F_ERROR		; if we had an error from EXEC
	xor	bx,bx			;  get extended error
func_i20:
	int	DOS_INT			; retrieve error value
	mov	cs:error_level,ax	;  and save for testing

	pop	es			; recover the seg we protected
	mov	ah, MS_M_FREE		; so we can free that memory up
	int	21h
	
	mov	ah,MS_M_ALLOC		; try and allocate as much as possible
	mov	bx, 0FFFFh		; ASSUME this will cover CONFIG
	int	21h			; bx = No. of paras available
	mov	ah, MS_M_ALLOC		;  give me bx paras please
	int	21h			;  ax:0 -> my memory

	pop es ! pop ds
	mov	mem_current_base,ax	; save memory base
	mov	mem_current,ax		; for future allocations
	ret



func_hidos:		; HIDOS ON/OFF
	call	check_onoff		; Check for ON or OFF
	 jc	f_hidos10		; Return on error
	mov	hidos,al		; update hidos flag
f_hidos10:
	ret


func_dos:		; DOS=HIGH - relocate BIOS/BDOS/Buffer etc to FFFF
	call	separator		; Deblank Command
	mov	di,offset high_opt	; es:di -> "HIGH"
	call	compare			; do we have an "HIGH"?
	 jc	func_dos10
	push	si
	call	func_dos_high		; execute HIGH
	pop	si
	jmps	func_dos
func_dos10:
	mov	di,offset low_opt	; es:di -> "LOW"
	call	compare
	 jc	func_dos20
	push	si
	call	func_dos_low		; execute LOW
	pop	si
	jmps	func_dos
func_dos20:
	mov	di,offset umb_opt	; es:di -> "UMB"
	call	compare
	 jc	func_dos30
	push	si
	call	func_dos_umb		; execute UMB
	pop	si
	jmps	func_dos
func_dos30:
	mov	di,offset noumb_opt	; es:di -> "NOUMB"
	call	compare
	 jc	func_dos40
	push	si
	call	func_dos_noumb		; execute NOUMB
	pop	si
	jmps	func_dos
func_dos40:
	ret

func_dos_high:
;-------------
; Move DOS into the HMA and allocate buffers etc. high too.
;
	mov	dos_target_seg,0FFFFh
	mov	bios_target_seg,0FFFFh
	mov	hidos,TRUE		; update hidos flag to be ON
	or	buffersIn,BUFFERS_IN_HMA; buffers at seg FFFF too
	ret

func_dos_low:
;------------
; force all allocation to be low
;
	mov	dos_target_seg,0
	mov	bios_target_seg,0
	mov	hidos,FALSE		; system allocation from low memory
	mov	buffersIn,0		; buffers from low memory
	ret

func_dos_umb:
;------------
; allocate Upper Memory Blocks and link them to the DMD chain
;
	mov	hidos,TRUE		; update hidos flag to be ON
	call	initialise_dmd_upper	; build initial upper memory DMD
	 jc	func_dos_umb30
func_dos_umb10:
	call	alloc_xms_umb		; allocate XMS upper memory
	 jc	func_dos_umb20
	call	add_dmd_upper		; add to upper memory DMD's
	jmps	func_dos_umb10		;  go around again
func_dos_umb20:
	call	remove_last_dmd		; get rid of useless last DMD
func_dos_umb30:
	mov	ax,(MS_M_STRATEGY*256)+3
	mov	bx,1			; link in upper memory region
	int	21h
	ret

func_dos_noumb:
;--------------
; Unlink Upper Memory blocks from the DMD chain
;
	mov	ax,(MS_M_STRATEGY*256)+3
	xor	bx,bx			; unlink upper memory region
	int	21h
	ret

alloc_xms_umb:
; On Entry:
;	None
; On Exit:
;	CY set is no upper memory available
; else
;	BX = para base address
;	DX = para size
;
; Try to allocate the largest possible block of XMS memory
; so we can link it to the upper memory chain
;
	push	es
	mov	ax,4300h		; check for XMS installation
	int	2fh
	cmp	al,80h
	 jne	alloc_xms10
	mov	ax,4310h		; get address of XMS driver
	int	2fh
	mov	word ptr xms_driver,bx
	mov	word ptr xms_driver+2,es
	mov	ah,10h			; allocate upper memory block
	mov	dx,0FFFFh		; DX set to find largest block
	callf	xms_driver
	cmp	dx,3			; we need at least 3 para's
	 jb	alloc_xms10		;  before we contruct a DMD
	mov	ah,10h			; now allocate largest block
	callf	xms_driver
	cmp	ax,1			; did we succeed ?
	 je	alloc_xms20
alloc_xms10:
	stc				; return CY set indicating failure
alloc_xms20:
	pop	es
	ret

xms_driver	rd	0
	dw	0,0

initialise_dmd_upper:
; On Entry:
;	None
; On Exit:
;	CY set if chain already exists
;	(BX/DX preserved)
;
; build initial upper memory DMD
; we rely on the fact the last para in memory is unused
; (but BIOSINIT makes sure that is true)
;
	push	es
	push	bx
	push	dx
if DOS5
	les	bx,func52_ptr		; ES:BX -> list of lists
	cmp	es:F52_DMD_UPPER[bx],0FFFFh
else
	les	bx,drdos_ptr
	cmp	es:DRDOS_DMD_UPPER[bx],0
	les	bx,funv52_ptr		; ES:BX -> list of lists
endif
	stc				; assume error return required
	 jne	initialise_dmd_upper30	; bail out if chain already established
	mov	es,es:F52_DMDROOT	; ES -> 1st DMD
initialise_dmd_upper10:
	cmp	es:DMD_ID,IDZ		; end of DMD chain ?
	 je	initialise_dmd_upper20
	cmp	es:DMD_ID,IDM		; do we have any more DMD's ?
	stc
	 jne	initialise_dmd_upper30 	; woops, chain must be bad
	mov	ax,es			; better point to it
	inc	ax
	add	ax,es:DMD_LEN		; AX:0 -> next DMD
	mov	es,ax
	jmps	initialise_dmd_upper10

initialise_dmd_upper20:
	mov	ax,es
	add	ax,es:DMD_LEN		; AX:0 -> will be upper memory chain
	cmp	ax,0A000h		; if the DMD chain is already into
	cmc				;  upper memory, lets make sure we
	 jb	initialise_dmd_upper30	;  stop before we fall apart
	mov	es:DMD_ID,IDM		; no longer the last entry
	dec	es:DMD_LEN		; shorten last DMD to make room
	mov	es,ax			; point to new DMD
	mov	es:DMD_ID,IDZ		; there is only one entry in the chain
	mov	es:DMD_PSP,8		; its' owned by "system"
	xchg	ax,cx			; CX = DMD
	mov	ax,0FFFFh
	sub	ax,cx			; it's this big
	mov	es:DMD_LEN,ax
if DOS5
	les	bx,func52_ptr
	mov	es:F52_DMD_UPPER[bx],cx
else
	les	bx,drdos_ptr
	mov	es:DRDOS_DMD_UPPER[bx],cx
endif
	clc
initialise_dmd_upper30:
	pop	dx
	pop	bx
	pop	es
	ret


remove_last_dmd:
; On Entry:
;	None
; On Exit:
;	None
;
; We have build an upper memory DMD chain, but we have left an extra
; DMD around covering the ROMs at the top of memory. Remove it if
; it's not required.
;
	push	es
	les	bx,func52_ptr		; ES:BX -> list of lists
	mov	es,es:F52_DMDROOT[bx]	; ES -> 1st DMD
remove_last_dmd10:
	cmp	es:DMD_ID,IDM		; do we have any more DMD's ?
	 jne	remove_last_dmd20	; bail out if we don't
	mov	ax,es			; remember previous DMD
	mov	dx,es
	inc	dx
	add	dx,es:DMD_LEN		; DX:0 -> next DMD
	mov	es,dx
	cmp	es:DMD_ID,IDZ		; end of DMD chain ?
	 jne	remove_last_dmd10
	cmp	es:DMD_PSP,8		; is it owned by "system" ?
	 jne	remove_last_dmd20	;  if so we can ditch this entry
	mov	es,ax			; ES = next to last DMD
	mov	es:DMD_ID,IDZ		; new end of chain
	inc	es:DMD_LEN		; include last para
if DOS5
	les	bx,func52_ptr		; ES:BX -> list of lists
	cmp	dx,es:F52_DMD_UPPER[bx]
	 jne	remove_last_dmd20	; remove upper memory link if none left
	mov	es:F52_DMD_UPPER[bx],0FFFFh
else
	les	bx,drdos_ptr
	cmp	dx,es:DRDOS_DMD_UPPER[bx]
	 jne	remove_last_dmd20	; remove upper memory link if none left
	mov	es:DRDOS_DMD_UPPER[bx],0
endif
remove_last_dmd20:	
	pop	es
	ret


add_dmd_upper:
; On Entry:
;	BX = base address of DMD
;	DX = size of DMD
; On Exit:
;	None
;
; Add this block into the upper memory chain.
; To do this we find the DMD containing the block and link it into place
;
	push	es
	push	bx			; save base address
	les	bx,func52_ptr		; ES:BX -> list of lists
	mov	ax,es:F52_DMDROOT[bx]	; AX -> 1st DMD
	pop	bx			; 1st DMD is always below XMS
	cmp	ax,bx			;  memory, so bomb out if not
	 jae	add_dmd_upper40		;  as our DMD's must be corrupt
add_dmd_upper10:
	mov	es,ax
	add	ax,es:DMD_LEN		; AX:0 -> end of this block
	cmp	ax,bx			; is the next block above us ?
	 ja	add_dmd_upper20		; if not try the next block
	inc	ax			; AX:0 -> next DMD
	cmp	es:DMD_ID,IDM		; do we have any more DMD's ?
	 je	add_dmd_upper10		;  we should have......
	jmps	add_dmd_upper40		; stop, DMD's are screwed up

add_dmd_upper20:
; We have found the block we wish to insert a new free block into
	cmp	es:DMD_PSP,8		; it must be owned by "system"
	 jne	add_dmd_upper40
; Shorten existing DMD to point to new block
	mov	ax,bx			; work out how far to new DMD
	mov	cx,es
	sub	ax,cx			; it's this many para's
	dec	ax			; forget the header
	xchg	ax,es:DMD_LEN		; set new length
; now we need to work out how much is left above the new DMD
	sub	ax,dx			; subtract length of new block
	sub	ax,es:DMD_LEN		; subtract the portion below
; Create DMD covering new block
	mov	cl,IDM			; create a new entry
	xchg	cl,es:DMD_ID		; CL = existing ID (M/Z)
	mov	es,bx			; ES -> base of new DMD
	mov	es:DMD_ID,IDM		; it's a link field
	mov	es:DMD_PSP,0		; it's free
	dec	dx			; forget the header
	add	bx,dx			; last para is here
	dec	dx			; forget the next link
	mov	es:DMD_LEN,dx		; it's this long
; Build a new DMD at the top if the new block for anything above it
	mov	es,bx
	mov	es:DMD_ID,cl		; inherit the ID field
	mov	es:DMD_LEN,ax		; and it's this long
	test	ax,ax			; if zero length then
	 jz	add_dmd_upper30		;  it's free
	mov	ax,8			; else it's system
add_dmd_upper30:
	mov	es:DMD_PSP,ax		; set owner
add_dmd_upper40:
	pop	es
	ret




func_set:		; SET envar=string
	call	whitespace		; deblank the command
	mov	di,offset envstart-1	; point to our environment area
func_set5:
	inc	di
	cmp	es:word ptr [di],0	; are we at the end yet
	 jne	func_set5
	cmp	di,offset envstart	; if nothing is there yet start
	 je	func_set10		;  at the NUL, else skip the NUL
	inc	di			;  to leave a seperator
func_set10:
	lodsb				; get a character
	cmp	al,CR			; end of the line yet ?
	 je	func_set20
	cmp	di,offset envend	; have we room ?
	 jae	func_set30		; bail out if not
	stosb				; save the character
	jmps	func_set10
func_set20:
	xor	ax,ax			; terminate with NULL
	stosb
func_set30:
	ret
endif					;not ADDDRV


func_echo:		; ECHO "string"	
	call	whitespace		; Scan off all white space
	lodsb				; before the optional
	cmp	al,'='			; '=' character.
	 je	func_echo10
	dec	si			; point at char
func_echo10:
	mov	dx,offset msg_dollar	; NUL error message
	mov	al,CR			; SI -> config line anyway
	jmp	config_error		; use error reporting routine

func_yeschar:		; yeschar "string"	
	call	whitespace		; Scan off all white space
	lodsb				; before the optional
	cmp	al,'='			; '=' character.
	 je	func_yeschar10
	dec	si			; point at char
func_yeschar10:
	call	whitespace
	lodsb
	mov	yes_char,al		; update YES character
	ret

func_chain:		; CHAIN="filename" - use as new CONFIG.SYS
	mov	di,offset dev_name	; Copy the Device Filename into a 
	mov	byte ptr [di],0		; local buffer and zero terminate
	call	copy_file
	 jc	func_chain10		; ignore if any problems
	mov	ax,(MS_X_OPEN*256)+80h	; Try to open the file
	mov	dx,offset dev_name	; as a new config file
	int	DOS_INT			; if we can't ignore it
	 jc	func_chain10
	mov	bx,ax
	mov	ah,MS_X_CLOSE
	int	DOS_INT			; close the new file
	mov	si,offset dev_name
	mov	di,offset cfg_file
	call	copy_asciiz		; copy the new name
	mov	cfg_seeklo,0		; start at begining of it
	mov	cfg_seekhi,0
	mov	cfg_tail,0		; force a read
func_chain10:
	ret

func_switch:				; SWITCH=option0, option1
; GOSUB to appropriate label
	call	wait_for_key		; wait until a key is pressed
	 jc	func_switch01		; ignore if timeout
	mov	ah,MS_C_RAWIN
	int	DOS_INT			; read a char
	cmp	al,CR
	 jne	func_switch02
func_switch01:
	mov	al,default_switch_char	; use default character
func_switch02:
	cmp	al,'0'			; ignore if < '0'
	 jb	func_switch
	cmp	al,'9'			;  or > '9'
	 ja	func_switch
	sub	al,'1'			; convert from ASCII
	 jns	func_switch05
	mov	al,10			; make '0' into 10
func_switch05:
	cbw				; AX = lines to skip
	xchg	ax,cx			; make CX the loop count
	 jcxz	func_switch30
	mov	bx,si			; BX -> saved command line start
func_switch10:
	push	bx
	push	cx
	mov	di,offset dev_name	; copy and discard a label
	call	copy_file
	pop	cx
	pop	bx
	 jc	func_switch40		; ignore if any problems
	push	bx
	push	cx
	call	separator		; look for ','
	pop	cx
	pop	bx
	 jc	func_switch40		; stop at end of line
	loop	func_switch10
func_switch30:
	jmp	func_gosub		; execute a GOSUB

func_switch40:
	mov	si,bx			; retract to start of line
	jmps	func_switch		;  then back to sleep again

func_gosub:		; GOSUB="label"
;----------
	pop	ax			; get return address
	mov	bx,cfg_seeklo		; get existing offset
	mov	cx,cfg_seekhi		;  in CONFIG file
	sub	bx,cfg_tail		; work out begining of buffer
	sbb	cx,0
	add	bx,cfg_head		; add in current offset in buffer
	adc	cx,0
	push	bx			; save as position to RETURN to
	push	cx
	push	ax			; save return address again
	call	func_goto		; try to GOTO label
	 jc	func_return
	ret				; RET, with old offset on stack

func_return:		; RETURN [n]
;-----------
	pop	bx			; get return address
	cmp	sp,save_sp		; is anything on stack ?

⌨️ 快捷键说明

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