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

📄 tskprf.asm

📁 用TC2实现的DOS多任务功能
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
loadwidth:
	mov	ax,word ptr es:[di]
	add	di,2
	add	arglen[bp],2
;
haswidth:
	or	prflags[bp],F_WIDTH
	mov	prwidth[bp],ax
	lodsb
;
no_width:
	cmp	al,'.'
	jne	no_prec
	lodsb
	cmp	al,'*'
	je	loadprec
	cmp	al,'9'
	ja	no_prec
	cmp	al,'0'
	jb	no_prec
	call	@getint
	jmp	short hasprec
;
loadprec:
	mov	ax,word ptr es:[di]
	add	di,2
	add	arglen[bp],2
;
hasprec:
	or	prflags[bp],F_PREC
	mov	prec[bp],ax
	lodsb
;
;	Process indirection.
;
no_prec:
	mov	dx,ds
	cmp	al,'^'
	je	indir_near
	cmp	al,'@'
	jne	no_indir
	add	arglen[bp],2
;
indir_near:
	or	prflags[bp],F_INDIR
;
indir_loop:
	cmp	al,'^'
	je	is_indir
	cmp	al,'@'
	jne	no_indir
	mov	dx,word ptr es:2[di]
is_indir:
	mov	di,word ptr es:[di]
	mov	es,dx
	lodsb			; next conversion char
	jmp	indir_loop
;
;	Indirection finished, check for size modification
;
no_indir:
	IF	DFLT_FAR
	cmp	al,'s'
	je	dfltsize0
	cmp	al,'n'
	je	dfltsize0
	cmp	al,'p'
	je	dfltsize0
	cmp	al,'P'
	jne	dfltsize1
;
dfltsize0:
	or	prflags[bp],F_LONGARG
	jmp	short no_sizemod
;
dfltsize1:
	ENDIF
	cmp	al,'F'
	je	sizemodl
	cmp	al,'N'
	jne	sizemod2
	lodsb
	jmp	short no_sizemod
;
sizemod2:
	cmp	al,'h'
	jne	sizemod3
	or	prflags[bp],F_SHORTARG
	lodsb
	jmp	short no_sizemod
;
sizemod3:
	cmp	al,'l'
	jne	no_sizemod
;
sizemodl:
	or	prflags[bp],F_LONGARG
	lodsb
;
no_sizemod:
	xor	dx,dx
	test	prflags[bp],F_LONGARG
	jz	loadsingle
	mov	dx,word ptr es:2[di]
	test	prflags[bp],F_INDIR
	jnz	loadsingle
	add	arglen[bp],2
;
loadsingle:
	mov	bl,al
	mov	ax,word ptr es:[di]
	test	prflags[bp],F_SHORTARG
	jz	noshort
	xor	ah,ah
;
noshort:
	cmp	bl,'n'
	jne	convc0
	test	prflags[bp],F_LONGARG
	jz	gostorelen
	mov	ds,dx
gostorelen:
	mov	bx,ax
	mov	ax,procnt[bp]
	mov	[bx],ax
	jmp	disploop1
;
convc0:
	lea	di,convbuf[bp]
;
	cmp	bl,'c'
	jne	convc1
	mov	byte ptr ss:[di],al
	inc	di
	mov	bx,1
	and	prflags[bp],NOT (F_PREC OR F_PADZERO)
	jmp	out_conv
;
convc1:
	cmp	bl,'s'
	jne	convc2
	test	prflags[bp],F_LONGARG
	jnz	gofmtstring
	mov	dx,ds
gofmtstring:
	and	prflags[bp],NOT F_PADZERO
	jmp	fmtstring
;
convc2:
	cmp	bl,'x'
	je	fmthex
	cmp	bl,'X'
	je	fmthex
	cmp	bl,'p'
	je	fmtptr
	cmp	bl,'P'
	je	fmtptr
	cmp	bl,'u'
	je	fmtdec
	cmp	bl,'d'
	jne	badconv
	test	prflags[bp],F_LONGARG
	jnz	signedlong
	test	prflags[bp],F_SHORTARG
	jz	signedint
	cbw
;
signedint:
	test	ah,80h
	jz	fmtdec
	or	prflags[bp],F_SIGNED
	neg	ax
	jmp	short fmtdec
;
signedlong:
	test	dh,80h
	jz	fmtdec
	or	prflags[bp],F_SIGNED
	mov	cx,dx
	xor	dx,dx
	neg	ax
	sbb	dx,cx
	jmp	short fmtdec
;
;	Invalid conversion. Reset parameter pointer and output the
;	char.
;
badconv:
	pop	di
	pop	es
	mov	al,bl
	jmp	dispchar
;
;
fmtdec:
	call	@decconv
	test	prflags[bp],F_SIGNED
	jz	fmtdnosign
	mov	byte ptr ss:[di],'-'
	inc	di
	inc	bx
fmtdnosign:
	jmp	short out_conv
;
fmthex:
	mov	prhexch[bp],'a'-10-'0'
	cmp	bl,'x'
	je	fmthex1
	mov	prhexch[bp],'A'-10-'0'
fmthex1:
	call	@hexconv
	jmp	short out_conv
;
fmtptr:
	mov	prhexch[bp],'a'-10-'0'
	cmp	bl,'p'
	je	fmtptr1
	mov	prhexch[bp],'A'-10-'0'
fmtptr1:
	and	prflags[bp],NOT (F_PREC OR F_PADZERO)
	mov	cl,4
	mov	bh,cl
	xor	bl,bl
;
fmtplo:
	call	@hexdigbp
	shr	ax,cl
	dec	bh
	jnz	fmtplo
	test	prflags[bp],F_LONGARG
	jz	out_conv
;
	mov	byte ptr ss:[di],':'
	inc	di
	inc	bl
	mov	bh,cl
	mov	ax,dx
;
fmtphilp:
	call	@hexdigbp
	shr	ax,cl
	dec	bh
	jnz	fmtphilp
;
;
out_conv:
	mov	cx,bx
	call	@padleft
	add	procnt[bp],cx
outc_out:
	dec	di
	mov	al,byte ptr ss:[di]
	call	prproc[bp]
	loop	outc_out
	call	@padright
	jmp	disploop1
;
;
fmtstring:
	push	si
	push	ds
	mov	ds,dx
	mov	si,ax
;
	mov	es,dx
	mov	di,ax
	xor	ax,ax
	mov	cx,-1
	repne scasb
	not	cx
	dec	cx
	test	prflags[bp],F_PREC
	jz	fmtstr_np
	cmp	cx,prec[bp]
	jbe	fmtstr_np
	mov	cx,prec[bp]
;
fmtstr_np:
	and	prflags[bp],NOT F_PREC
	mov	bx,cx
	call	@padleft
	jcxz	fmtstr_end
	add	procnt[bp],cx
fmtstr_out:
	lodsb
	call	prproc[bp]
	loop	fmtstr_out
fmtstr_end:
	call	@padright
	pop	ds
	pop	si
	jmp	disploop1
;
;
@disprintf	endp
;
;
; void tsk_printf (char far *format, ...)
;
;	Formatted output to console.
;
CGlobalfunc tsk_printf,<uses ds si di, fmt: far ptr, varg: word>
;
	mov	ax,ss
	mov	es,ax
	lds	si,fmt
	lea	di,varg
	mov	cx,offset @dischar
	call	@disprintf
	ret
tsk_printf	endp
;
;
; void tsk_vprintf (char far *format, void far *arg)
;
;	Formatted output to console.
;
Globalfunc tsk_vprintf,<uses ds si di, fmt: far ptr, varg: far ptr>
;
	lds	si,fmt
	les	di,varg
	mov	cx,offset @dischar
	call	@disprintf
	ret
tsk_vprintf	endp
;
;
; void tsk_fprintf (int handle, char far *format, ...)
;
;	Formatted output to file.
;
CGlobalfunc tsk_fprintf	<uses ds si di, handle: word, fmt: far ptr, varg: word>
;
	mov	ax,ss
	mov	es,ax
	lds	si,fmt
	lea	di,varg
	sub	sp,FILE_BUFSIZE
	mov	dx,sp
	mov	bx,sp
	mov	byte ptr ss:[bx],0
	mov	cx,offset @filechar
	mov	bx,handle
	call	@disprintf
	mov	si,sp
	mov	cl,ss:[si]
	xor	ch,ch
	jcxz	fprintfend
	mov	dx,si
	inc	dx
	mov	bx,handle
	mov	ax,ss
	mov	ds,ax
	mov	ah,40h
	int	21h
fprintfend:
	add	sp,FILE_BUFSIZE
	ret
tsk_fprintf	endp
;
;
; void tsk_vfprintf (int handle, char far *format, void far *arg)
;
;	Formatted output to file.
;
Globalfunc tsk_vfprintf,<uses ds si di, handle: word, fmt: far ptr, varg: far ptr>
;
	lds	si,fmt
	les	di,varg
	sub	sp,FILE_BUFSIZE
	mov	dx,sp
	mov	bx,sp
	mov	byte ptr ss:[bx],0
	mov	cx,offset @filechar
	mov	bx,handle
	call	@disprintf
	mov	si,sp
	mov	cl,ss:[si]
	xor	ch,ch
	jcxz	vfprintfend
	mov	dx,si
	inc	dx
	mov	bx,handle
	mov	ax,ss
	mov	ds,ax
	mov	ah,40h
	int	21h
vfprintfend:
	add	sp,FILE_BUFSIZE
	ret
tsk_vfprintf	endp
;
;
; void tsk_sprintf (char far *dest, char far *format, ...)
;
;	Formatted output to string.
;
CGlobalfunc tsk_sprintf,<uses ds si di, dest: far ptr, fmt: far ptr, varg: word>
;
	mov	ax,ss
	mov	es,ax
	lds	bx,dest
	mov	dx,ds
	lds	si,fmt
	lea	di,varg
	mov	cx,offset @stringchar
	call	@disprintf
	sub	bx,word ptr(dest)
	mov	ax,bx
	ret
tsk_sprintf	endp
;
;
; void tsk_vsprintf (char far *dest, char far *format, void far *arglist)
;
;	Formatted output to string.
;
Globalfunc tsk_vsprintf,<uses ds si di, dest: far ptr, fmt: far ptr, varg: far ptr>
;
	lds	bx,dest
	mov	dx,ds
	lds	si,fmt
	les	di,varg
	mov	cx,offset @stringchar
	call	@disprintf
	sub	bx,word ptr(dest)
	mov	ax,bx
	ret
tsk_vsprintf	endp
;
;
; void tsk_rprintf (char far *format, ...)
;
;	Formatted output to regen buffer (second display).
;
CGlobalfunc tsk_rprintf,<uses ds si di, fmt: far ptr, varg: word>
;
	IFDEF	LOAD_DS
	mov	ds,cs:ctdataseg
	ENDIF
	mov	cx,sc_proc
	mov	ax,ss
	mov	es,ax
	lds	si,fmt
	lea	di,varg
	call	@disprintf
	ret
tsk_rprintf	endp
;
;
; void tsk_vrprintf (char far *format, void far *arglist)
;
;	Formatted output to regen buffer (second display).
;
Globalfunc tsk_vrprintf,<uses ds si di, fmt: far ptr, varg: far ptr>
;
	IFDEF	LOAD_DS
	mov	ds,cs:ctdataseg
	ENDIF
	mov	cx,sc_proc
	lds	si,fmt
	les	di,varg
	call	@disprintf
	ret
tsk_vrprintf	endp
;
;
; void tsk_putc (char c)
;
;	Output character to console.
;    
Globalfunc tsk_putc,<chr: word>
	mov	ax,chr
	call	@dischar
	ret
tsk_putc	endp
;
;
; void tsk_puts (char far *s)
;
;	Output string to console.
;    
Globalfunc tsk_puts,<uses ds si, dstr: far ptr>
;
	lds	si,dstr
putslp:
	lodsb
	or	al,al
	jz	putsend
	call	@dischar
	jmp	putslp
;
putsend:
	mov	al,0dh
	call	@dischar
	mov	al,0ah
	call	@dischar
	ret
tsk_puts	endp
;
;
; void tsk_rputc (char c)
;
;	Output character to regen buffer (second display).
;    
Globalfunc tsk_rputc,<chr: word>
;
	mov	ax,chr
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	call	sc_proc
	pop	ds
	ELSE
	call	sc_proc
	ENDIF
	ret
tsk_rputc	endp
;
;
; void tsk_rputs (char far *s)
;
;	Output string to regen buffer.
;    
Globalfunc tsk_rputs,<uses si, dstr: far ptr>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	les	si,dstr
rputslp:
	lods	es:prflags
	or	al,al
	jz	rputsend
	call	sc_proc
	jmp	rputslp
;
rputsend:
	mov	al,0dh
	call	sc_proc
	mov	al,0ah
	call	sc_proc
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
tsk_rputs	endp
;
;
; void tsk_setpos (int row, int col)
;
;	Set cursor position for regen output.
;	First position on screen is (0, 0).
;
Globalfunc tsk_setpos,<row: word, col: word>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	ax,row
	mul	sc_cols
	add	ax,col
	add	ax,col
	mov	tsk_regen_o,ax
	call	@setcsr
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
tsk_setpos	endp
;
;
; void tsk_set_regen (int segment, int port, int rows, int cols)
;
;	Set regen buffer address and size, and display controller port.
;	This routine can be used to force regen output to the
;	primary screen for single-screen systems, and to modify
;	the output parameters (number of rows and columns).
;
Globalfunc tsk_set_regen,<reg: word, port: word, rows: word, cols: word>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	ax,reg
	mov	tsk_regen_s,ax
	mov	ax,port
	mov	tsk_disport,ax
	mov	tsk_regen_o,0
	mov	ax,cols
	add	ax,ax
	mov	sc_cols,ax
	mul	rows
	mov	sc_end,ax
	mov	sc_proc,offset @disregen
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
tsk_set_regen	endp
;
;
; int tsk_set_dualdis (void)
;
;	Determine regen buffer address on second monitor.
;	This routine first checks the current video mode. If it's
;	mode 7, the regen buffer is set to B800 (the colour screen).
;	For all other modes, the regen buffer is B000 (mono).
;	Then a check is done to make sure that the secondary card
;	exists. If it does, the regen output is initialized. Otherwise,
;	any output through the regen routines will be discarded.
;
;	Returns 0 if there is no secondary monitor, else the
;	regen buffer address.
;
;	No attempt is made to initialize the secondary monitor,
;	the monitor must be in alpha mode.
;
Globalfunc tsk_set_dualdis
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	ah,0fh
	push	bp
	int	10h		; get video mode
	pop	bp
	mov	bx,0b800h	; colour regen buffer
	mov	dx,3d4h		; CGA 6845 I/O addr
	cmp	al,7		; only mode 7 has regen at B000
	je	ddis_checks
	mov	bx,0b000h	; mono regen buffer
	mov	dx,3b4h		; mono 6845 I/O addr
;
ddis_checks:
	mov	tsk_regen_s,bx
	mov	tsk_regen_o,0
	mov	tsk_disport,dx
	mov	sc_cols,80 * 2
	mov	sc_end,25 * 80 * 2
	mov	al,0fh
	out	dx,al
	inc	dx
	in	al,dx
	mov	ah,al
	mov	al,56h
	out	dx,al
	mov	cx,100h
ddis_wait:
	loop	ddis_wait
	in	al,dx
	xchg	ah,al
	out	dx,al
	cmp	ah,56h
	je	ddis_ok
	mov	sc_proc,offset @nodis
	xor	ax,ax
	mov	tsk_regen_s,ax
	jmp	short ddis_end
;
ddis_ok:
	mov	sc_proc,offset @disregen
	mov	ax,bx
;
ddis_end:
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
;
tsk_set_dualdis	endp
;
;
; int tsk_set_currdis (void)
;
;	Determine regen buffer address on current monitor.
;	This routine checks the current video mode. If it's
;	mode 7, the regen buffer is set to B000 (the mono screen).
;	For all other modes, the regen buffer is B800 (colour).
;
;	Returns the regen buffer address.
;
;	No attempt is made to initialize the monitor, or to check for
;	special modes with different regen address. The monitor must 
;	be in alpha mode.
;
Globalfunc tsk_set_currdis
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	ah,0fh
	push	bp
	int	10h		; get video mode
	pop	bp
	mov	bx,0b800h	; colour regen buffer
	cmp	al,7		; only mode 7 has regen at B000
	jne	curdis_ready
	mov	bx,0b000h	; mono regen buffer
;
curdis_ready:
	mov	tsk_regen_s,bx
	mov	tsk_regen_o,0
	mov	ax,SEG biosdata
	mov	es,ax
	assume	es:biosdata
	mov	ax,bios_chipad
	mov	tsk_disport,ax
	mov	ax,bios_cols
	add	ax,ax
	mov	sc_cols,ax
	mov	dl,bios_rows
	xor	dh,dh
	mul	dx
	mov	sc_end,ax
	mov	sc_proc,offset @disregen
	mov	ax,bx
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
;
tsk_set_currdis	endp
;
;
; void tsk_set_colour (int rows, int cols)
;
;	Set regen buffer address to colour monitor.
;
Globalfunc tsk_set_colour,<rows: word, cols: word>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	tsk_regen_s,0b800h	; colour regen buffer
	mov	tsk_regen_o,0
	mov	tsk_disport,3d4h	; CGA 6845 I/O addr
	mov	ax,cols
	add	ax,ax
	mov	sc_cols,ax
	mul	rows
	mov	sc_end,ax
	mov	sc_proc,offset @disregen
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
;
tsk_set_colour	endp
;
;
; void tsk_set_mono (int rows, int cols)
;
;	Set regen buffer address to monochrome monitor.
;
Globalfunc tsk_set_mono,<rows: word, cols: word>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	tsk_regen_s,0b000h	; mono regen buffer
	mov	tsk_regen_o,0
	mov	tsk_disport,3b4h	; mono 6845 I/O addr
	mov	ax,cols
	add	ax,ax
	mov	sc_cols,ax
	mul	rows
	mov	sc_end,ax
	mov	sc_proc,offset @disregen
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
;
tsk_set_mono	endp
;
;
; void tsk_set_attr (int attr)
;
;	Set regen display attributes
;
Globalfunc tsk_set_attr,<attr: word>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	ax,attr
	mov	tsk_attrib,al
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
;
tsk_set_attr	endp
;
;
; void tsk_set_clreol (int clr)
;
;	Set special handling of CR. If "clr" is nonzero, CR will clear
;	to end of line before returning to the home position.
;
Globalfunc tsk_set_clreol,<clr: word>
;
	IFDEF	LOAD_DS
	push	ds
	mov	ds,cs:ctdataseg
	ENDIF
	mov	ax,clr
	mov	sc_clreol,al
	IFDEF	LOAD_DS
	pop	ds
	ENDIF
	ret
;
tsk_set_clreol	endp
;
	.tsk_ecode
	end

⌨️ 快捷键说明

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