home *** CD-ROM | disk | FTP | other *** search
- ;=====================================================================
- ;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
-