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

📄 cstart.asm

📁 一个dos操作系统DRDOS的源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:

	cmp	exec_filetype,0		; was it a CMD
	 jne	exec30
	push	ax
	mov	ax,XIOS_PCKBD		; we are in must-be-24 line
	mov	cl,0			; mode, get back to default mode
	mov	dl,defconsole		; for console number
	call	xios
	pop	ax
exec30:
	pop	di
	pop	si
	pop	bp
	ret

_TEXT	ENDS


	Assume	CS:DGROUP, DS:DGROUP, SS:DGROUP
else
;
;	Novell 2.1 intercepts the DOSPLUS 4B00  return by updating the
;	PSP USER_SS/SP and  when it returns ALL registers except CS:IP
;	have been corrupted.
;
	extrn	stack_min:word		; Minimum Stack Address
	extrn	heap_top:word

readline	label	dword		; FAR pointer to READLINE routine
		dw	dataOFFSET msdos_readline
readline_seg	dw	?

critical	dd	?		; Critical Error Handler Address
exec_sp		dw	?
exec_ss		dw	?

exec_block	label	byte
exec_env	dw	?		; Environment Segment
exec_clineoff	dw	?		; ASCIIZ Command line Offset
exec_clineseg	dw	?		; ASCIIZ Command Line Segment
exec_fcb1off	dw	dataOFFSET fcb1	; FCB1 Contents Offset
exec_fcb1seg	dw	?		; FCB1 Contents Segment
exec_fcb2off	dw	dataOFFSET fcb2	; FCB2 Contents Offset
exec_fcb2seg	dw	?		; FCB2 Contents Segment

exec		label	dword		; FAR pointer to EXEC routine
		dw	dataOFFSET msdos_exec
exec_seg	dw	?

msdos_exec_ret	label	dword		; FAR pointer to exit EXEC routine
		dw	codeOFFSET _exec_ret
msdos_exec_ret_seg dw	?

fcb1		db	16 dup (?)	; FCB1 Buffer
fcb2		db	16 dup (?)	; FCB2 Buffer
crc		dw	?		; COMMAND.COM crc

; For Dual Language Support...
ifdef DLS
;;ED_TEXT		SEGMENT para public 'CDATA'

	Public	_rld_msgs,_rld_text
_rld_msgs	dw	120 ;RELOAD_LEN	; size of this message buffer
_reload_msgs	dw	0		; First part of Code reload prompt
_reload_msgf	dw	0		; Second part of Code reload prompt
_reload_msgm	dw	0		; Unlikely part of Code reload prompt
		dw	0		; end of list
_rld_text	db	120 dup (?)	; message text is placed here
RELOAD_LEN	equ	$-_reload_msgs
;;ED_TEXT		ENDS
else
	extrn	_reload_msgs:byte	; First part of Code reload prompt
	extrn	_reload_msgf:byte	; Second part of Code reload prompt
	extrn	_reload_msgm:byte	; No memory available message
endif


reload_flag	db	0		; Reloading Command Processor	
in_exec     db  0       
high_code	dw	TRUE		; Enable High Code
exe_file	dw	FALSE		; True if COMMAND.COM is really an EXE
return_code	dw	?		; Exec return code
net_error_mode  db	?

; int2E data

i2e_lock	dw	0		; mutex flag
i2e_user_ss	dw	0		; users ss, sp
i2e_user_sp	dw	0
i2e_stack	dw	0
i2e_cmd		dw	0		; offset of local copy of command line

i2e_c_entry	label	dword
i2e_c_offs	dw	codeOFFSET _int2e_handler
i2e_c_seg	dw	?

i2e_i23vec	label	dword
i2e_i23off	dw	?
i2e_i23seg	dw	?

i2e_i24vec	label	dword
i2e_i24off	dw	?
i2e_i24seg	dw	?

endif
_DATA	ENDS

_BSS	SEGMENT
Public	_edata
_edata	label	BYTE		; end of data (start of bss)
_BSS	ENDS

ETEXT	SEGMENT
;
;	The RLSTACK segment holds the stack used by the READLINE routine.
;	This must be in High memory for the PolyTron PolyWindows product.
;
;	"ETEXT" also forces the linker to pad the CGROUP to at least
;	real_code bytes. Otherwise the file length can be upto 15 bytes 
;	shorter then real_code + total_length. This obviously causes 
;	problems with CALC_CRC and the file reloading.
;
		db	RLSTACK_SIZE dup(0CCh)
rlstack		label	word

ETEXT	ENDS

ifdef CDOSTMP
STACK	SEGMENT

Public	_end
_end	label	BYTE		; end of bss (start of starup/stack)

 		db	(C_HEAP_SIZE - 6) dup (0DDh)	; C Heap Area
stack_top	label	word
stack_ip	dw	?		; Initial Offset	
stack_cs	dw	?		; Initial Code Segment (Unknown)
stack_flags	dw	?		; Initial Flags (Unknown)

temp_buffer	db	512 dup(0)	; temp far buffer for *gp_far_buff

STACK	ENDS
else

STACK	SEGMENT

stack_start:
;	HEAP_TOP is initialised to _end so the _RELOAD_FILE and CMDLINE
;	variables are allocated on the HEAP.
;

Public	_end
_end	label	BYTE		; end of bss (start of startup/stack)


	db	255,'3771146-XXXX-654321'

	page
;
;	The CS register is now adjusted so that this startup
;	can be used in the form of an .EXE or .COM. Whatever the 
;	execution format of this file DS still points at the PSP
;	but must be careful when resizing the RAM.
;
getIP	PROC	FAR
	cld				; be sure of DIR flag...
	pop	di			; Get the Program Counter
	sub	di,dataOFFSET retIP	; Correct for retIP
	mov	cl,4			; Convert Offset values to Segments
	mov	ax,cs			; Get the current CS
	shr	di,cl			; Convert Initial IP to Segment
	add	ax,di			; add to CS and save for CALLF to MAIN
	push	ax			; Save the New CS and the offset to
	mov	ax,dataOFFSET gotCS	; the next instruction and then execute
	push	ax
	ret				; a RETF instruction to correct CS.
getIP	ENDP

ifdef DOSPLUS

; Most of the PSP (FCB's and command buffer) is unused - we reclaim this space
; by relocating the resident part of COMMAND.COM

reloc_code:
;----------
; On Entry:
;	CS = DGROUP, DS = PSP, ES = nothing
; On Exit:
;	CS = relocated DGROUP
;
; We build a "REP MOVSB ! RETF 6" on the stack. We also fiddle the near return
; address into a FAR. We then setup our registers appropriately and execute
; this code.
;
if 1
	ret
else
	cmp	ds:byte ptr 0080h,7fh	; discard garbage cmdline lengths
	jb	reloc_code10
	ret

reloc_code10:	 
	pop	bx			; recover return offset

	mov	ax,0
	push	ax			; 0 (part of RETF 6)
	mov	ax,006cah
	push	ax			; RETF 6 on stack

	mov	ax,0a4f3h
	push	ax			; REP MOVSB on stack

	mov	al,ds:0080h		; Get the Command length
	xor	ah,ah
	mov	cl,4			; convert AX to cmdline length
	shr	ax,cl			; in rounded down para's
	add	ax,9			; keep at least this much
	mov	si,ds
	add	ax,si			; add in PSP
	mov	es,ax
	mov	cx,sp			; save address of code on stack
	push	ax
	push	bx			; new RETF address on stack

	push	ss
	push	cx			; address of CODE on stack

	push	cs
	pop	ds			; DS -> DGROUP
	xor	si,si			; setup DS:SI, ES:DI and CX
	xor	di,di			;  ready to do REP MOVSB
	mov	cx,total_length		; DGROUP length
	add	cx,real_code		;+CGROUP length
	
	db	0cbh			; RETF to code on stack
endif	
endif

gotCS:
	;out	0fdh,al			; for debug purposes
	
	mov	[__psp],ds		; Save our PSP in the local variable
ifdef DOSPLUS
	mov	ax,cs			; put our stack somewhere safe
	mov	ss,ax
	mov	sp,dataOFFSET rlstack
	push	ds
	push	di
	call	reloc_code		; relocate code over unused bit of PSP
	pop	di
	pop	ds
endif
ifdef DLS
	call	_my_dls_init
endif

	mov	[code_seg],cs		; Initialise the DATA segment address
	mov	[data_seg],cs		; and calculate the current address
	mov	[exec_seg],cs		; of the Code Segment
	mov	[readline_seg],cs	; use it to fixup some JMPFs
	mov	[_batch_seg_ptr+2],cs
	mov	[low_seg],cs	    ; we may be relocated to upper or high
				    ; memory so remember the current segment

	mov	bx,cs			; Path up the JMPF instructions
	sub	bx,[__psp]		; around the MSDOS EXEC code to
	mov	cl,4
	shl	bx,cl
	add	cs:[exec_psp-2],bx
	mov	cs:[func4b_seg],cs
	mov	cs:[int2E_seg],cs
	mov	cs:[exec_psp],ds

	cmp	di,0000h		; Disable Code Relocation if we have
	jnz	gotCS_10		; been loaded as an .EXE file
	;;mov	high_code,FALSE
	
	mov	exe_file,TRUE		; Remember we are an EXE

gotCS_10:
	mov	di,total_length
	shr	di,cl
	add	[code_seg],di

	push	ds			; Initialise the Checksum so we can
	mov	ds,[code_seg]		; check the integrity of the high
	mov	si,2			 ; high copy of the command processor
	call	calc_crc		; code
	pop	ds
	mov	[crc],ax

	mov	ah,0ddh			; set Novell error mode
	mov	dl,0			; to 00 - BAP
	int	21h
	mov	net_error_mode,al	; save original error mode

	call	get_ds			; Get DGROUP value in AX
	cli				; turn off interrupts
	mov	ss,ax			; SS = DGROUP
	mov	sp,dynamic_length	; Initialise SP
	;mov	sp,total_length
	sti				; turn interrupts back on

	assume	ss:DGROUP

	push	ax
	call	handler_init		; Initialise the Control Break and
	pop	ax			; Critical Error Interrupt Vectors

	mov	si,total_length		; Get the DGROUP length in bytes
	add	si,code_length		; Add in the Code Length
	mov	cl,4			; and convert to a paragraphs
	shr	si,cl
	mov	bx,ax			; Get the Current DS
	sub	bx,__psp		; and calculate DS - PSP Seg
	add	bx,si			; DS + Data length in Para's
	mov	es,__psp
	mov	ah,MS_M_SETBLOCK
	int	DOS_INT

	call	exec_name		; Get our Load Path from the environment

	cmp	high_code,FALSE		; Skip Memory check if HIGH_CODE
	jz	cstart_10		; support has been disabled

	mov	high_code,FALSE		; Assume Failure.
	
	call	alloc_com_memory	; Allocate high memory for command.com
	jnc	carry_on
	
	mov	ax,cs			; if no memory and CS is nearing
	cmp	ax,8000h		; transient part abort and go home.
	jb	cstart_10
	
	mov	ah,4ch
	int	21h	

carry_on:
	mov	high_code,TRUE		; Set HIGH_CODE flag TRUE	
	push	es			; Relocate the command processor code
	push	ds			; into high memory
	mov	es,ax			; es-> destination segment
	mov	di,0
	mov	si,0
	mov	ds,code_seg		; ds-> code to be moved
	mov	cx,real_code		; convert bytes to words
	shr	cx,1
	rep	movsw			; Move code up to high memory
	mov	code_seg,es		; update code_seg

	pop	ds
	pop	es
		
; Shrink memory containing low memory version of step aside code
	mov	si,total_length		; Get the DGROUP length in bytes
	mov	cl,4			; and convert to a paragraphs
	shr	si,cl
	call	get_ds
	mov	bx,ax			; Get the Current DS
	sub	bx,__psp		; and calculate DS - PSP Seg
	add	bx,si			; DS + Data length in Para's
	mov	ah,MS_M_SETBLOCK
	int	DOS_INT
	
cstart_10:
ifdef	DOSPLUS
	mov	ax,4457h		; terminate HILOAD operation
	mov	dx,200h
	int	DOS_INT
	call	dbcs_init		; initialise the DBCS support
endif
	call	get_cs
	push	ax
	mov	ax,codeOFFSET memory_init
	push	ax
	db	0CBh			; a RETF instruction to correct CS.

page
;
;	Build the full path and filename of this process using the
;	loadpath attached to the environment. If no filename exists
;	then prevent the Command Processor code from being located
;	in high memory.
;
exec_name:
	push	es
	mov	es,__psp		; Get the PSP Segment Address
	mov	dx,PSP_ENVIRON		; Get the environment segment
	cmp	dx,0000			; Have we got an environment ?
	jz	exec_n11		; No prevent High Code Support

	mov	es,dx			; Scan through the environment and
	mov	di,0			; determine the Environment size and
	mov	al,0			; the Load file name
	mov	cx,7FFFh
exec_n05:				; Scan through the Environment
	repne	scasb			; searching for the 00 00 terminator
	jcxz	exec_n10		; Terminate On CX == 0000
	cmp	es:byte ptr [di],al	; If the next byte is zero then this is
	jnz	exec_n05		; then end of the environment
	cmp	es:word ptr 1[di],1	; Are we pointing at the Control Word
	jnz	exec_n10		; No then no Load Path exists

	push	ds
	mov	ds,dx			 ; DS -> Environment Segment
	;call	get_ds
	;mov	es,ax			 ; ES -> Command Processor Data Seg
	mov	es,[low_seg]
	lea	si,03[di]		 ; Fully expand the filename so the
	mov	di,dataOFFSET reload_file ; user can SUBST drives
	mov	ah,60h
	int	DOS_INT
exec_n15:
if 0
	mov	di,dataOFFSET reload_file ; this ASCIIZ string is on the heap
	xor	ax,ax			;  so now we need to find out how
	mov	cx,-1			;  much space it takes up and reserve
	repne	scasb			;  that amount of the heap
	mov	heap_top,di		; byte after the NUL is available
endif
	pop	ds
	pop	es
	ret

exec_n10:
	mov	high_code,FALSE
exec_n11:
	mov	ah,MS_DRV_GET
	int	DOS_INT			; get default drive
	mov	es,[low_seg]
	add	es:reload_file,al	;  and use that for the comspec
	push	ds
	;call	get_ds
	;mov	es,ax			 ; ES -> Command Processor Data Seg
	jmp	exec_n15

ifdef	DOSPLUS
DI_BUF_PTR	equ	dword ptr -4	; pointer to DBCS lead byte table
DI_BUF_ID	equ	byte ptr -5	; buffer id
DI_BUF		equ	byte ptr -5	; buffer

DI_LOCALS	equ	5		; No. bytes storage local to init_dbcs

_DATA		SEGMENT byte public 'DATA'

	Public	dbcs_table_ptr

dbcs_table_ptr	label	dword
dbcs_table_off	dw	dataOFFSET dummy_dbcs_table
dbcs_table_seg	dw	0

dummy_dbcs_table dw	0

_DATA		ENDS

dbcs_init	proc	near
;--------
; To initialise the double byte character set (DBCS) lead byte table.
; MUST be called before the first call to dbcs_lead() or dbcs_expected().

⌨️ 快捷键说明

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