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

📄 tsk.mac

📁 用TC2实现的DOS多任务功能
💻 MAC
📖 第 1 页 / 共 2 页
字号:
;
		dd	?	; special return addr
entry_flags	dw	?	; flags on entry to switch_stack
caller_ip	dw	?	; IP from INT stack
caller_cs	dw	?	; CS from INT stack
caller_flags	dw	?	; flags from INT stack
save_es		dw	?
save_ds		dw	?
save_bp		dw	?
save_di		dw	?
save_si		dw	?
save_dx		dw	?
save_ax		dw	?
slot_sp		dw	?	; stack slot sp
slot_idx	dw	?	; stack slot index
save_cx		dw	?
save_bx		dw	?
;
saved_regs	ends
;
;
stc_saved	macro
		or	byte ptr caller_flags[bp],1
		endm
;
clc_saved	macro
		and	byte ptr caller_flags[bp],0feh
		endm
;
;	Flags for the T_INDOS field in the TCB
;
OWN_LOWER       =       1
OWN_UPPER       =       2
DOS_ENTERED	=	4
;
;---------------------------------------------------------------------
;
global_ext	macro
		IF	SINGLE_DATA
		extrn	tsk_glob_rec: byte
		ELSE
		extrn	tsk_global: dword
		ENDIF
		endm
;
		IFDEF	TC_HUGE
;
.tsk_data	macro
CTASK_DATA	segment byte public 'DATA'
		assume	ds:CTASK_DATA,es:CTASK_DATA
@CTASK_DATA	equ	<CTASK_DATA>
@data		equ	<CTASK_DATA>
		endm
;
		ELSE
;
.tsk_data	macro
		.data
@CTASK_DATA	equ	<DGROUP>
		assume	ds:@data,es:@data
		endm
;
		ENDIF
;
		IF	NEAR_CODE
;
.tsk_code	macro
		.code
		endm
;
Globext		macro	lab
		IF	CALL_PASCAL
		extrn	pascal lab: near
		ELSE
		extrn	C lab: near
		ENDIF
		endm
;
CGlbext		macro	lab
		extrn	C lab: near
		endm
;
		ELSE
;
.tsk_code	macro
CTASK_TEXT	segment word public 'CODE'
@code		equ	<CTASK_TEXT>
		assume	cs:CTASK_TEXT
		endm
;
Globext		macro	lab
		IF	CALL_PASCAL
		extrn	pascal lab: far
		ELSE
		extrn	C lab: far
		ENDIF
		endm
;
CGlbext		macro	lab
		extrn	C lab: far
		endm
;
		ENDIF
;
		IF	LOCALS_FAR
;
Locext		macro	lab
		IF	CALL_PASCAL
		extrn	pascal lab: far
		ELSE
		extrn	C lab: far
		ENDIF
		endm
;
CLocext		macro	lab
		extrn	C lab: far
		endm
;
		ELSE
;
Locext		macro	lab
		IF	CALL_PASCAL
		extrn	pascal lab: near
		ELSE
		extrn	C lab: near
		ENDIF
		endm
;
CLocext		macro	lab
		extrn	C lab: near
		endm
;
		ENDIF
;
.tsk_ecode	macro
	IFDEF	@CurSeg
@CurSeg		ends
	ELSE
@curseg		ends
	ENDIF
		endm
;
.tsk_edata	macro
	IFDEF	@CurSeg
@CurSeg		ends
	ELSE
@curseg		ends
	ENDIF
		endm
;
.tsk_model	macro
		.model	small,c
		endm
;
Globalfunc	macro	name,pars
		IF	NEAR_CODE
		IF	CALL_PASCAL
name		proc	near pascal pars
		ELSE
name		proc	near C pars
		ENDIF
		ELSE
		IF	CALL_PASCAL
name		proc	far pascal pars
		ELSE
name		proc	far C pars
		ENDIF
		ENDIF
		endm
;	
CGlobalfunc	macro	name,pars
		IF	NEAR_CODE
name		proc	near C pars
		ELSE
name		proc	far C pars
		ENDIF
		endm
;
Localfunc	macro	name,pars
		IF	LOCALS_FAR
		IF	CALL_PASCAL
name		proc	far pascal pars
		ELSE
name		proc	far C pars
		ENDIF
		ELSE
		IF	CALL_PASCAL
name		proc	near pascal pars
		ELSE
name		proc	near C pars
		ENDIF
		ENDIF
		endm
;	
CLocalfunc	macro	name,pars
		IF	LOCALS_FAR
name		proc	far C pars
		ELSE
name		proc	near C pars
		ENDIF
		endm
;
Pubfunc		macro	name
		IF	CALL_PASCAL
		public	pascal name
		ELSE
		public	C name
		ENDIF
		endm
;
CPubfnc		macro	name
		public	C name
		endm
;
;-------------------------------------------------------------------
;
;	The following is a set of macros that allow calling an
;	external routine without caring about the calling sequence
;	(C or Pascal) in use. Usage is
;
;		callp	procname,<parameter list>
;	as in
;		callp	request_resource,<<ds,offset dosupper>,0,0>
;
;	Doubleword and Segment/Offset pairs must be grouped with an
;	additional level of brackets.
;
;	The parameter list may contain the special character '#'
;	as a prefix to a label to identify an offset, so the above
;	example could be abbreviated to
;
;		callp	request_resource,<<ds,#dosupper>,0,0>
;
;	Also, the prefix '/' denotes an effective address, i.e. the
;	LEA instruction is used to load the parameter value.
;
;
;	The 'vpush' macro pushes a single value or a doubleword pair.
;	It checks the type of parameter (constant or variable), and
;	handles the offset shortcut '#'. Note that AX is destroyed
;	when constants are pushed and the CPU is an 8086/88.
;
vpush	macro	val,val2
	local	vrest,hash,slash
cc_parcnt	=	cc_parcnt + 2
hash	instr	1,<val>,<#>
slash	instr	1,<val>,</>
	IF	hash EQ 1		;; If hashmark prefix
vrest	substr	<val>,2			;; Get real parameter
	IF	@Cpu AND 2
	push	offset vrest
	ELSE
	mov	ax,offset vrest
	push	ax
ax_is_zero	=	0
	ENDIF
	ELSEIF	slash EQ 1
vrest	substr	<val>,2			;; Get real parameter
	lea	ax,vrest
	push	ax
ax_is_zero	=	0
	ELSEIF	(.TYPE val) AND 4	;; If it's a constant
	IF	@Cpu AND 2
	push	val
	ELSE
	IF	val
	mov	ax,val
ax_is_zero	=	0
	ELSEIFE	ax_is_zero		;; Push 0 is handled special
	xor	ax,ax
ax_is_zero	=	TRUE
	ENDIF
	push	ax
	ENDIF
	ELSEIF	(.TYPE val) AND 10h	;; If it's a register
	push	val			;; Push normal if register
	ELSE
	push	word ptr (val)		;; Push word if variable
	ENDIF
	IFNB	<val2>
	vpush	val2			;; Do it again if second parameter
	ENDIF
	endm
;
;	The 'pushp' macro reverses the parameter list for the C calling
;	sequence by calling itself recursively.
;
pushp	macro	p1,p2,p3,p4,p5,p6,p7,p8,p9,p10
	IFNB	<p2>
	pushp	<p2>,<p3>,<p4>,<p5>,<p6>,<p7>,<p8>,<p9>,<p10>
	ENDIF
	IFNB	<p1>
	vpush	p1
	ENDIF
	endm
;
;	The 'callp' macro calls pushp or vpush depending on the 
;	calling sequence, and re-adjusts the stack after the call
;	for C.
;
callp	macro	name,pars
cc_parcnt	=	0
ax_is_zero	=	FALSE
	IF	CALL_PASCAL
	IRP	p,<pars>
	vpush	p
	ENDM
	ELSE
	pushp	pars
	ENDIF
	call	name
	IF	NOT CALL_PASCAL AND cc_parcnt
	add	sp,cc_parcnt
	ENDIF
	ENDM
;
;--------------------------------------------------------------------------
;
;	Checking mode support macros
;
CHECK_PTR_R	macro	sreg,reg,txt
	local	ok,nok,str
	IF	CHECKING
	push	ax
	mov	ax,sreg
	or	ax,reg
	jnz	ok
	jmp	short nok
str	db	txt,' - Invalid pointer: %FP',0ah,0
nok:
	callp	tsk_fatal_pmd,<<cs,#str>,<sreg,reg>>
ok:
	pop	ax
	ENDIF
	ENDM
;
;
CHECK_PTR	macro	pntr,txt
	local	ok,nok,str
	IF	CHECKING
	push	ax
	mov	ax,word ptr (pntr)
	or	ax,word ptr (pntr+2)
	jnz	ok
	jmp	short nok
str	db	txt,' - Invalid pointer: %FP',0ah,0
nok:
	callp	tsk_fatal_pmd,<<cs,#str>,<pntr+2,pntr>>
ok:
	pop	ax
	ENDIF
	ENDM
;
;
CHECK_TCBPTR_R	macro	sreg,reg,txt
	local	ok,nok,str
	IF	CHECKING
	push	ax
	mov	ax,sreg
	or	ax,reg
	jz	nok
	cmp	sreg:cqueue.q_kind[reg],TYP_TCB
	jne	nok
	IF	TSK_NAMED
	cmp	sreg:tname.nlist.q_kind[reg],TYP_TCB
	je	ok
	ENDIF
	jmp	short nok
str	db	txt,' - Invalid pointer: %FP',0ah,0
nok:
	callp	tsk_fatal_pmd,<<cs,#str>,<sreg,reg>>
ok:
	pop	ax
	ENDIF
	ENDM
;
;
CHECK_TCBPTR	macro	pntr,txt
	IF	CHECKING
	push	ds
	push	si
	lds	si,pntr
	CHECK_TCBPTR_R	ds,si,txt
	pop	si
	pop	ds
	ENDIF
	ENDM
;
;
CHECK_EVTPTR_R	macro	sreg,reg,kind,txt
	local	ok,nok,str
	IF	CHECKING
	push	ax
	mov	ax,sreg
	or	ax,reg
	jz	nok
	mov	al,kind
	or	al,Q_HEAD
	cmp	al,sreg:cqueue.q_kind[reg]
	je	ok
	jmp	short nok
str	db	txt,' - Invalid pointer: %FP',0ah,0
nok:
	callp	tsk_fatal_pmd,<<cs,#str>,<sreg,reg>>
ok:
	pop	ax
	ENDIF
	ENDM
;
;
CHECK_EVTPTR	macro	pntr,kind,txt
	IF	CHECKING
	push	ds
	push	si
	lds	si,pntr
	CHECK_EVTPTR_R	ds,si,kind,txt
	pop	si
	pop	ds
	ENDIF
	ENDM
;
;
CHECK_QHEAD_R	macro	sreg,reg,txt
	local	ok,nok,str
	IF	CHECKING
	push	ax
	mov	ax,sreg
	or	ax,reg
	jz	nok
	test	sreg:cqueue.q_kind[reg],Q_HEAD
	jnz	ok
	jmp	short nok
str	db	txt,' - Invalid pointer: %FP',0ah,0
nok:
	callp	tsk_fatal_pmd,<<cs,#str>,<sreg,reg>>
ok:
	pop	ax
	ENDIF
	ENDM
;
;
CHECK_QHEAD	macro	pntr,txt
	IF	CHECKING
	push	ds
	push	si
	lds	si,pntr
	CHECK_QHEAD_R	ds,si,txt
	pop	si
	pop	ds
	ENDIF
	ENDM
;

⌨️ 快捷键说明

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