📄 tsk.mac
字号:
;
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 + -