home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.wwiv.com
/
ftp.wwiv.com.zip
/
ftp.wwiv.com
/
pub
/
BBS
/
DLMST251.ZIP
/
DOSWDW.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-12-29
|
8KB
|
294 lines
;=====================================================================
;DOSWDW.ASM written by E. Dong to be used in Turbo C programming, and
;is based on EXECWIN.ASM originally written by Kim Kokkonen, TurboPower
;Software (first in 10/88, then updated to 1.01 on 11/14/88) and
;released to the public domain by K.K. K.K.'s 1.01 version added saving
;BP register since some int 10 BIOS handlers trash it.
;
;Version 2.0 12/29/89 Edward V. Dong
;This version (DOSWDW.ASM) ports EXECWIN.ASM from Turbo Pascal to Turbo
;C and adds optional pausing when the window fills up. If pausing is
;enabled, then any keystroke starts it again.
name doswdw
DOSWDW_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:DOSWDW_TEXT,ds:DGROUP
DOSWDW_TEXT ends
_DATA segment word public 'DATA'
_d@ label byte
_DATA ends
_BSS segment word public 'BSS'
_b@ label byte
_BSS ends
_DATA segment word public 'DATA'
extrn _oldint21 : dword ;Previous $21 vector
extrn _wdwpause : byte ;MORE filter: pause after each page
extrn _wdwpos : word ;Cursor position in window
extrn _wdwupr : word ;Top left corner of window
extrn _wdwlwr : word ; and bottom right corner.
extrn _wdwattr : byte ;Attribute with which to
; display all characters.
_DATA ends
DOSWDW_TEXT segment byte public 'CODE'
col equ (byte ptr 0)
row equ (byte ptr 1)
ofst equ (word ptr 0)
segm equ (word ptr 2)
ToDos macro ;Transfer control to DOS
jmp dword ptr Int21CS
endm
ToApp macro ;Transfer control back to caller
clc ;Clear error flag
ret 2 ;Return with flags intact
endm
public _setup21
public _doswdw
Int21CS dd ? ;Old interrupt 21 in code segment
rowcnt db ? ;Count of rows displayed so far
rowlmt db ? ;Max rows to show for pausing
;Set up dos window & check for pausing between pages
;Checks for single parameter (int) which is zero for no page
;pausing or is the number of rows to pause at.
_setup21 proc far
push bp
mov bp,sp
mov al,0 ;Initialize row counting
mov rowcnt,al
mov ax,word ptr [bp+6] ;Limit specified?
mov rowlmt,al ;Save limit
les ax,_oldint21 ;Save ints in code segment
mov Int21CS.ofst,ax
mov Int21CS.segm,es
mov sp,bp
pop bp
ret
_setup21 endp
; Handle interrupt 21 to trap output calls
_doswdw proc far
cmp ah,2 ;Just get functions that go to StdOut
jz DispOut
cmp ah,6
jz DirectOut
cmp ah,9
jz StringOut
cmp ah,40h ;Or maybe to StdErr
jz BlockOut
ToDos
;-----------
DispOut: ;DOS function 2
push ax
mov al,dl ;Character to write in AL
call WriteChar ;Write via video BIOS
pop ax
ToApp ;Return successfully
;-----------
DirectOut: ;DOS function 6
cmp dl,0FFh ;Console input?
jnz DispOut ;Jump if not
ToDos ;Else transfer to DOS
;------------
StringOut: ;DOS function 9
push ax ;Save AX
push bx ;Save string index
mov bx,dx ;DS:BX -> string
StringOut1:
mov al,[bx] ;AL = next character to write
cmp al,'$' ;Terminator?
jz StringOut2 ;Exit if so
call WriteChar ;Write it
inc bx ;Next character
jmp StringOut1 ;Loop
StringOut2:
pop bx
pop ax
ToApp ;Back to application
;------------
BlockOut: ;DOS function 40h
cmp bx,1 ;To StdOut?
jz BlockOut1 ;Jump if so
cmp bx,2 ;To StdErr?
jz BlockOut1 ;Jump if so
ToDos ;Else let DOS handle it
BlockOut1:
jcxz BlockOut3 ;Get out if none to write
push ax
push bx
push cx ;Save loop counter
mov bx,dx ;DS:BX -> stuff to write
BlockOut2:
mov al,[bx] ;Next character to write
call WriteChar ;Write it
inc bx ;Next index
loop BlockOut2 ;Loop for all the characters
pop cx
pop bx
pop ax
mov ax,cx ;Wrote all the characters
BlockOut3:
ToApp ;Back to application
_doswdw endp
;------------
; Write a character to current position via BIOS
; Entry: AL is character to write
; Must preserve all but AX
WriteChar proc near
push bp ;some versions of int 10 BIOS trash BP
push bx
push cx
push dx
push ds
mov bx,DGROUP ;set up ds
mov ds,bx
cmp al,7 ;Bell character?
jz BiosWriteDone ;Don't write
mov dx,_wdwpos ;Current cursor pos in DX
cmp al,8 ;Backspace?
jz BackSpace
cmp al,9 ;Tab?
jz Tab
cmp al,10 ;Line feed?
jz LineFeed
cmp al,13 ;Carriage return?
jz Carriage
call WriteOne ;Write one normal character
BiosSetCursor: ;Position cursor
xor bh,bh
mov ah,2
int 10h
mov _wdwpos,dx ;Save new cursor position
BiosWriteDone:
pop ds
pop dx
pop cx
pop bx
pop bp
ret
Carriage:
mov dl,_wdwupr.col ;Move to left edge
jmp BiosSetCursor
LineFeed:
cmp dh,_wdwlwr.row ;Room to increment row?
jb LineFeed1
mov al,rowlmt ;Test if pausing on pages
cmp al,0
jz GoSrll ;No, then skip pausing
jmp Pause ;Test if rowcnt forces pausing
GoSrll: mov ax,0601h ;Scroll up one line
mov cx,_wdwupr
mov dx,_wdwlwr
mov bh,_wdwattr
int 10h
jmp BiosWriteDone
LineFeed1:
inc dh ;Increment row
inc cs:rowcnt ;Keep track of rows
jmp BiosSetCursor ;No, go set cursor position
Tab: mov cl,dl
sub cl,_wdwupr.Col ;Characters beyond left edge
add cl,8
and cl,0F8h ;To next tab stop
add cl,_wdwupr.Col ;Window coords
sub cl,dl ;Spaces to write
xor ch,ch ;CX = spaces to write
Tab1: mov al,20h ;Write spaces
push cx
call WriteOne ;One at a time
xor bh,bh
mov ah,2
int 10h
mov _wdwpos,dx ;Save new cursor position
pop cx
loop Tab1 ;Do all of them
jmp BiosWriteDone
BackSpace:
cmp dl,_wdwupr.col ;Beyond left edge?
jbe BiosWriteDone ;Exit if not
dec dl ;One left
xor bh,bh
mov ah,2 ;Position cursor
int 10h
mov _wdwpos,dx
mov cx,1 ;Write character
mov bl,_wdwattr
mov ax,0920h ;Write a space
int 10h
jmp BiosWriteDone ;Done now
Pause: mov al,rowcnt ;Calculate # of rows processed
inc al
mov rowcnt,al
cmp al,rowlmt ;Compare against limit
jae GetKey ;Yes, then wait for keystroke
jmp GoSrll ;No, then go scroll page
GetKey: mov ax,0 ;Zero count
mov rowcnt,al ;Save it
int 16h ;Wait for keystroke
jmp GoSrll ;Scroll page
WriteChar endp
;---------------
; Write one character and update cursor variable
WriteOne proc near
mov cx,1 ;Write character
mov bl,_wdwattr
xor bh,bh
mov ah,9
int 10h
cmp dl,_wdwlwr.col ;Below right border?
jb IncCol ;If so, just increment column
cmp dh,_wdwlwr.row ;Room for CR/LF?
jb IncRow ;Jump if so
mov ax,0601h ;Scroll up one line
mov cx,_wdwupr
mov dx,_wdwlwr
mov bh,_wdwattr
int 10h
dec dh ;Compensate for inc to follow
IncRow: inc dh ;Next row
mov dl,_wdwupr.col ;First col
dec dl ;Compensate for inc to follow
IncCol: inc dl ;Increment column
ret
WriteOne endp
DOSWDW_TEXT ends
end