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

📄 tskdos.asm

📁 这是一个关于C++编程开发的算法!
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	push	ax
	push	ax
        mov     ax,offset _critical
	push	ds
	push	ax
        call    _asm_wait_flag_clear
	add	sp,8
;
no_crit:
	mov	cs:ctask_active,1	; mark that we are active
	sti				; Interrupts allowed now
;
        cmp     ah,4ch                  ; terminate?
        jne     dosent_x
        mov     ah,0                    ; translate to fn 0
dosent_x:
	cmp	ah,0ch
	jbe	lower_funcs
	jmp	upper_funcs
;
;	Functions 00-0C
;
lower_funcs:
;
;	first, request the "lower_dos" resource
;
        mov     bx,offset _lower_dos
	xor	cx,cx
	push	cx		; no timeout
	push	cx
	push	ds		; resource address
	push	bx
        call    _asm_request_resource
	add	sp,8
;
;	we have it, now let's get the upper_dos resource, too
;
        mov     bx,offset _upper_dos
	xor	cx,cx
	push	cx		; no timeout
	push	cx
	push	ds		; resource address
	push	bx
        call    _asm_request_resource
	add	sp,8
;
;	both resources gained, now we may execute the function if dos is free
;
	pop	di
	pop	si
	pop	ax
	pop	bx
	pop	cx
	pop	dx
;
	call	wait_dos_free
;
	or	ah,ah			; terminate ?
	je	fg_terminate		; special treatment required
	cmp	ah,4ch
	je	fg_terminate		; special treatment required
	pop     ds
	pop	es
	popf
	pop	bp
;
	dos				; execute function
;
;	Now we have to release the resources.
;
	pushf				; save registers again
	sti
	push	es
	push    ds
	push	dx
	push	cx
	push	bx
	push    ax
	push	si
	push	di
;
	mov	bx,SEG dgroup
	mov	ds,bx
	mov	es,bx
;
        mov     bx,offset _upper_dos
	push	ds		; resource address
	push	bx
        call    _asm_release_resource
	add	sp,4
;
        mov     bx,offset _lower_dos
	push	ds		; resource address
	push	bx
        call    _asm_release_resource
	add	sp,4
;
;	If both resources are free now, clear the ctask_active flag to
;	allow other background processes to gain access to DOS.
;
	cli
        mov     ax,_upper_dos.rstate
        or	ax,ax
        jz	no_relc
        cmp     ax,_lower_dos.rstate
	jne	no_relc
	mov	cs:ctask_active,0
no_relc:
;
;	All done, restore registers and return.
;
	pop	di
	pop	si
	pop	ax
	pop	bx
	pop	cx
	pop	dx
	pop     ds
	pop	es
	popf
;
	ret	2			; don't restore flags
;
;
;	The terminate request requires special treatment.
;	Since terminating the program without first un-installing
;	would crash the system, we do this here, not without telling
;	the user something went very wrong.
;
fg_terminate:
	cli
	call	_asm_remove_tasker
	mov	dx,offset term_err_msg
	mov	ah,9
	int	21h
	mov	ax,4cffh
	int	21h
;
;--------------------------------------------------------------------------
;
;	Functions 0D and above
;
upper_funcs:
        mov     bx,offset _upper_dos
	xor	cx,cx
	push	cx		; no timeout
	push	cx
	push	ds		; resource address
	push	bx
        call    _asm_request_resource
	add	sp,8
;
;	resource gained, now we may execute the function if dos is free
;
	pop	di
	pop	si
	pop	ax
	pop	bx
	pop	cx
	pop	dx
;
	call	wait_dos_free
;
	pop     ds
	pop	es
;
;
;	Filter pseudo-functions C0/C1 (Absolute Read/Write)
;
	cmp	ah,0c0h
	jne	uf_exec1
	popf
	pop	bp
	call	exec_absread
	jmp	short uf_complete
uf_exec1:
	cmp	ah,0c1h
	jne	uf_exec2
	popf
	pop	bp
	call	exec_abswrite
	jmp	short uf_complete
;
uf_exec2:
	popf
	pop	bp
	dos				; execute function
;
;	Now we have to release the resources.
;
uf_complete:
	pushf				; save registers again
	sti
	push	es
	push    ds
	push	dx
	push	cx
	push	bx
	push    ax
	push	si
	push	di
;
	mov	bx,SEG dgroup
	mov	ds,bx
	mov	es,bx
;
        mov     bx,offset _upper_dos
	push	ds		; resource address
	push	bx
        call    _asm_release_resource
	add	sp,4
;
;	If both resources are free now, clear the ctask_active flag to
;	allow other background processes to gain access to DOS.
;
	cli
        mov     ax,_upper_dos.rstate
        or	ax,ax
        jz	no_relc1
        cmp     ax,_lower_dos.rstate
	jne	no_relc1
	mov	cs:ctask_active,0
no_relc1:
;
;	All done, restore registers and return.
;
	pop	di
	pop	si
	pop	ax
	pop	bx
	pop	cx
	pop	dx
	pop     ds
	pop	es
	popf
;
	ret	2			; don't restore flags
;
;
dosentry	endp
;
;--------------------------------------------------------------------------
;
;	Absolute Read/Absolute Write.
;
exec_absread	proc	near

	pushf
	call	cs:savabsread
	inc	sp			; Remove flags (not using ADD,
	inc	sp			; this would clobber Carry)
	ret

exec_absread	endp
;
exec_abswrite	proc	near

	pushf
	call	cs:savabswrite
	inc	sp			; Remove flags (not using ADD,
	inc	sp			; this would clobber Carry)
	ret

exec_abswrite	endp
;
;----------------------------------------------------------------------------
;
wait_dos_free	proc	near
;
	push	es
	push	bx
in_use_loop:
	cmp	idle_active,0		; idle interrupt active?
	jne	dos_free		; then don't check for flag
;
	les	bx,in_use
	cmp	byte ptr es:[bx],0
	jne	is_in_use
	cmp	dos310,0
	je	dos_free
	les	bx,in_error
	cmp	byte ptr es:[bx],0
	je	dos_free
is_in_use:
	pushf
	call	scheduler
	jmp	in_use_loop
;
dos_free:
	pop	bx
	pop	es
	ret
;
wait_dos_free	endp
;
;----------------------------------------------------------------------------
;
;	INT 28: DOS Idle Interrupt
;
idleentry	proc	far
;
	push	ds
	push	es
	push	ax
;
	mov	ax,SEG dgroup
	mov	ds,ax
	mov	es,ax
;
;	Check if someone is waiting for upper_dos. If not, we can return
;	immediately.
;
        mov     ax,word ptr _upper_dos.rwaiting
        or      ax,word ptr _upper_dos.rwaiting+2
	jz	idle_exit
;
;	Also make sure this is not a second invocation of INT 28.
;	Normally, this should never happen, but better safe than sorry.
;
	cmp	idle_active,0
	jne	idle_exit
	inc	idle_active
;
;	someone is waiting, let's please him by releasing the resource
;
	mov	idle_ss,ss		; Switch to local stack
	mov	idle_sp,sp
	mov	ax,ds
	mov	ss,ax
	mov	sp,offset local_stack
;
	sti				; Interrupts allowed now
;
        push	bx			; save remaining regs
	push	cx
	push	dx
;
;	temporarily increase priority
;
	les	bx,_tsk_current
	push	es:prior[bx]
	mov	es:prior[bx],0ffffh
	push	bx
	push	es
;
;	release resource & request it again
;
	mov	ax,ds
	mov	es,ax
        mov     bx,offset _upper_dos
	push	ds
	push	bx
        call    _asm_release_resource
	add	sp,4
;
        mov     bx,offset _upper_dos
	xor	cx,cx
	push	cx
	push	cx
	push	ds
	push	bx
        call    _asm_request_resource
	add	sp,8
;
;	ready, restore priority, stack & regs
;
	cli
	pop	es
	pop	bx
	pop	es:prior[bx]
;
	pop	dx
	pop	cx
	pop	bx
;
	mov	ss,idle_ss		; restore stack
	mov	sp,idle_sp
;
	mov	idle_active,0
;
idle_exit:
	pop	ax
        pop     es
	pop	ds
;
	jmp	cs:savidle		; chain to original interrupt
;
idleentry	endp
;
;---------------------------------------------------------------------------
;
;	INT 2A: DOS Critical Section Interrupt.
;
;	Not documented.
;	Is used by DOS PRINT to mark Critical Regions.
;	Usage by PRINT:
;		AX = 8700 - Begin Critical Region
;				Returns:
;				Carry set if already active.
;		AX = 8701 - End Critical Region
;
;	Both these functions are handled here.
;
;	Other usage in DOS, function unknown:
;		AH = 82 (AL undefined)
;			seems to be called on DOS-Functions > 0C
;		AH = 84 (AL undefined)
;			seems to be called when DOS is idle
;
;	These functions are currently ignored.
;
critsectint	proc	far

	cmp	ax,8700h	; Enter critical region
	jne	csi1
	cmp	cs:critsect_active,0
	stc
	jnz	critsect_end
	cmp	cs:ctask_active,0
	stc
	jnz	critsect_end
;
	inc	cs:critsect_active
	push	ax
	push	bx
	push	cx
	push	dx
	push	ds
	push	es
	mov	ax,seg dgroup
	mov	ds,ax
	mov	es,ax
	mov	ax,word ptr _tsk_current
	mov	word ptr cs:crit_task,ax
	mov	ax,word ptr _tsk_current+2
	mov	word ptr cs:crit_task+2,ax
        mov     ax,offset _critical
	push	ds
	push	ax
	call	_asm_set_flag
	add	sp,4
	pop	es
	pop	ds
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	clc
critsect_end:
	ret	2
;
csi1:
	cmp	ax,8701h	; Leave critical region
	jne	csi2
	mov	cs:critsect_active,0
	push	ax
	push	bx
	push	cx
	push	dx
	push	ds
	push	es
	mov	ax,seg dgroup
	mov	ds,ax
	mov	es,ax
        mov     ax,offset _critical
	push	ds
	push	ax
        call    _asm_clear_flag
	add	sp,4
	pop	es
	pop	ds
	pop	dx
	pop	cx
	pop	bx
	pop	ax
csi2:
	iret
;
critsectint	endp
;
;
;---------------------------------------------------------------------------
;
        end

⌨️ 快捷键说明

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