📄 tsk.mac
字号:
@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
_P_&lab = 1
ELSE
extrn C lab: near
ENDIF
endm
;
CGlbext macro lab
extrn C lab: near
endm
;
PGlbext macro lab
extrn pascal lab: near
_P_&lab = 1
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
_P_&lab = 1
ELSE
extrn C lab: far
ENDIF
endm
;
CGlbext macro lab
extrn C lab: far
endm
;
PGlbext macro lab
extrn pascal lab: far
_P_&lab = 1
endm
;
ENDIF
;
IF LOCALS_FAR
;
Locext macro lab
IF CALL_PASCAL
extrn pascal lab: far
_P_&lab = 1
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
_P_&lab = 1
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
IF CHECKING
IFNDEF fatal_pmd
extrn C tsk_fatal_pmd: far
ENDIF
@fnstring catstr <">,@filename,<">
ENDIF
endm
;
Globalfunc macro name,pars
IF NEAR_CODE
IF CALL_PASCAL
IFDEF ??Version
name proc pascal near pars
ELSE
name proc near pascal pars
ENDIF
ELSE
IFDEF ??Version
name proc C near pars
ELSE
name proc near C pars
ENDIF
ENDIF
ELSE
IF CALL_PASCAL
IFDEF ??Version
name proc pascal far pars
ELSE
name proc pascal far pars
ENDIF
ELSE
IFDEF ??Version
name proc C far pars
ELSE
name proc far C pars
ENDIF
ENDIF
ENDIF
endm
;
CGlobalfunc macro name,pars
IF NEAR_CODE
name proc near pars
ELSE
IFDEF ??Version
name proc C far pars
ELSE
name proc far C pars
ENDIF
ENDIF
endm
;
Localfunc macro name,pars
IF LOCALS_FAR
IF CALL_PASCAL
IFDEF ??Version
name proc pascal far pars
ELSE
name proc far pascal pars
ENDIF
ELSE
IFDEF ??Version
name proc C far pars
ELSE
name proc far C pars
ENDIF
ENDIF
ELSE
IF CALL_PASCAL
IFDEF ??Version
name proc pascal near pars
ELSE
name proc near pascal pars
ENDIF
ELSE
IFDEF ??Version
name proc C near pars
ELSE
name proc near C pars
ENDIF
ENDIF
ENDIF
endm
;
CLocalfunc macro name,pars
IF LOCALS_FAR
IFDEF ??Version
name proc C far pars
ELSE
name proc far C pars
ENDIF
ELSE
IFDEF ??Version
name proc C near pars
ELSE
name proc near C pars
ENDIF
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 shortcuts '#' and '/'. Note that AX is destroyed
; when constants are pushed and the CPU is an 8086/88.
;
vpush macro val,val2
local vrest,hash,slash,strg,strgc,snext
cc_parcnt = cc_parcnt + 2
strg instr 1,<val>,<">
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 strg EQ 1
jmp short snext
strgc db val,0
snext:
push cs
IF @Cpu AND 2
push offset strgc
ELSE
mov ax,offset strgc
push ax
ax_is_zero = 0
ENDIF
cc_parcnt = cc_parcnt + 2
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
IFDEF _P_&name
IRP p,<pars>
vpush p
ENDM
ELSE
pushp pars
ENDIF
call name
IFNDEF _P_&name
IF cc_parcnt
add sp,cc_parcnt
ENDIF
ENDIF
ENDM
;
;--------------------------------------------------------------------------
;
xjz macro where
local nxt
IF CHECKING
jnz nxt
jmp where
nxt:
ELSE
jz where
ENDIF
ENDM
;
xjmp macro where
local nxt
IF CHECKING
jmp where
ELSE
jmp short where
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
;
FATAL macro txt,pars
local str,nok
IF CHECKING
jmp short nok
str db txt,0ah,0
nok:
callp tsk_fatal_pmd,<<cs,#str>,<pars>>
ENDIF
ENDM
;
ASSERT macro arg1,opn,arg2,txt,pars
local str,nok,isok,fns
IF CHECKING
cmp arg1,arg2
j&opn isok
jmp short nok
IFNB <txt>
str db txt,0ah,0
nok:
callp tsk_fatal_pmd,<<cs,#str>,<pars>>
ELSE
str db 0ah,"Assertion failed <&arg1 &opn &arg2> - "
db @fnstring," - AX=%04X",0ah,0
nok:
callp tsk_fatal_pmd,<<cs,#str>,ax>
ENDIF
isok:
ENDIF
ENDM
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -