📄 tskprf.asm
字号:
;
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 + -