home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Programmer's Journal Buyer's Guide / Visual_Basic_Programmers_Journal_Buyers_Guide_CD-ROM_1994.iso / vbpjiss / shell.rpl (.txt) < prev    next >
Farallon Replica Document  |  1994-03-13  |  41KB  |  1 lines

  1. D   O   S       S   H   E   L    LSee Next Page36     FEBRUARY/MARCH 1994   Visual Basic ProgrammerÆs JournalD   O   S       S   H   E   L    LSHELL Shinesin DOS WindowAn assembly-language routine lets you SHELL to a predefined window formaximum control of your DOS user interface.B  Y     T  O  N  Y     E  L  L  I  O  T; DOSWIN.ASM - Listing 1; DOS windowing routine for use during a SHELL; Copyright (C) 1993 EllTech Development, Inc.; Written by Tony Elliott - August 1993f youÆre like most programmers, you; Requires MASM 6.0x or later to reassemble. This routine; is compatible with QB/PDS/VBDOS, and PowerBasic 3.0x.create polished user interfaces. YouI.Model Medium, Basicmake sure that the colors are well bal-.Codeanced and pleasing to the eye, and that;                 Variable Declaration Areaanything the user needs to do is only a key press;; We're going to store our local variables in the code; segment in order to avoid any impact on DGroup.or mouse click away. ItÆs frustrating to losecontrol of your meticulously handcrafted screenOrigInt10       LABEL DWord     ;A "far" label pointing todisplays when you SHELL out to a DOS (orOrigInt10Ofs    dw 0            ; interrupt 10h's originalother) command-line utility. During the SHELL,OrigInt10Seg    dw 0            ; vector.OrigInt29       LABEL DWord     ;A "far" label pointing tothese utilities can cause your display to wrapOrigInt29Ofs    dw 0            ; interrupt 29h's originalaround and scroll, temporarily destroying all ofOrigInt29Seg    dw 0            ; vector.your hard work. WouldnÆt it be great if youTopRow          db 0            ;When the programmercould confine the output of such utilities to aLeftCol         db 0            ; defines the windowBottomRow       db 0            ; coordinates and colorpredefined window on the screen during aRightCol        db 0            ; attribute, they areSHELL? After hearing several programmersColorAttr       db 0            ; stored here.complain about this problem, I created a solu-LineWrap        db 0tion. The DosWindow routine described hereScrnRows        db 25           ;The current displayScrnCols        db 0            ; parameters will belets you control the screen display during aScrnPage        db 0            ; stored here.SHELL and add a first-class professional touch;                       Define Macrosto your applications.VideoInt Macro                  ;Some BIOS can destroyBefore I discuss how this routine works,    Push    bp                  ; the BP register. Using    Int     10h                 ; this macro, we make sureconsider the organization of operating system    Pop     bp                  ; that BP is alwayssoftware and ROM BIOS services. There areEndm                            ; preserved.at least three software layers in every PC:;                     Procedure AreaBIOS, DOS, and application programs.DosWindow proc uses DS, TopR:Word, LeftC:Word,         BottomR:Word, RightC:Word, Colr:Word, LWrap:WordAt the lowest level, thereÆs the system hard-; On entry to this routine, let's get some informationware. This includes all the IC chips and circuit; about the current video adapter.boards that make up your computer. Generally    Cmp     cs:OrigInt10Seg,0   ;Are we already installed?speaking, there can be literally hundreds of    Jz      @f                  ;If not, continue    Call    RemoveDosWindow     ;If so, deinstall first@@: Push    csTony Elliott is Vice President and General    Pop     ds                  ;Point ds to code segmentManager of EllTech Development Inc. and    Assume  ds:@Codeauthor of several add-ons for Basic, including    Mov     ah,0fh              ;Get video modeCONTINUED ON NEXT PAGE.E-Tree Plus, Printer Plus, Compression Plus,and Fax Plus. He can be contacted at 4374LISTING 1Hooking an Interrupt. This complete assembly-language routine allows you to createShallowford Industrial Parkway, Marietta,a predefined window while SHELLing from QB, PDS, VBDOS, or PB. Making thisGeorgia, 30066, or on CompuServe atroutine work requires intercepting all calls made to interrupt &H29 and &H10 during the SHELL.76220,2575.Visual Basic ProgrammerÆs Journal   FEBRUARY/MARCH 1994     37D   O   S       S   H   E   L    Lmachine-language instructions required just toput a single character on your video display.LISTING 1. CONTINUED FROM PREVIOUS PAGE.And to make matters more complicated, these    VideoInt                    ;Call the video BIOSsteps can vary from one hardware configura-    Dec     ah                  ;Make screen cols base 0tion to another. Realizing this early on, IBM    Mov     ScrnCols,ah         ;Screen colums    Mov     ScrnPage,bh         ;Active display pagecreated the specifications for a group of soft-    Xor     ax,axware subroutines called Basic Input Output    Mov     es,ax               ;Point es to BIOS dataSystem, or BIOS.    Mov     al,byte ptr es:[484h] ;Rows, if EGA/VGAThe BIOS specification defines the inter-    Cmp     al,42               ;43 line mode? (base 0)    Jz      RowsOk              ;If so, continuerupt numbers and parameters used to control    Cmp     al,49               ;50 line mode?everything from disk I/O and printer services to    Jz      RowsOk              ;If so, continuekeyboard handling and screen display. Manu-    Mov     al,24               ;Assume 25 line modefacturers that want to produce PC-compatibleRowsOk:    Mov     ScrnRows,al         ;Store rows in our varmotherboards, video cards, and other types of;   Now, load and evaluate the window coordinates providedhardware must also include a set of BIOS;   by the Basic program.functions, usually stored in ROM or a device    Mov     ax,TopR             ;TopRow% into axdriver, that conform to the IBM specifications.    Dec     al                  ;Make it base 0    Cmp     al,ScrnRows         ;Greater than ScrnRows?These functions act as the software layer be-    Ja      BadParam            ;Exit if sotween the operating system and the hardware.    Mov     bx,LeftC            ;LeftCol% into bxFor example, if I want to switch the current    Dec     bl                  ;Make it base 0video adapter into the 80-by-25 color mode    Cmp     bl,ScrnCols         ;Greater than ScrnCols?    Ja      BadParamfrom assembly language, I donÆt need to know    Mov     cx,BottomR          ;BottomRow% into cxall the low-level steps required by the specific    Dec     cl                  ;Make it base 0video card IÆm using; I simply use BIOS inter-    Cmp     cl,al               ;Less than TopRow%?rupt &H10 service. The video card manufac-    Jb      BadParam            ;If so, exit    Cmp     cl,ScrnRows         ;Greater than ScrnRows?turer has provided a group of interrupt &H10    Ja      BadParam            ;If so, exitfunctions designed specifically for his card.    Mov     dx,RightC           ;RightCol% into dxThis approach makes life much easier.    Dec     dl                  ;Make it base 0The software layer above the BIOS is the    Cmp     dl,bl               ;Less than LeftCol%?    Jb      BadParam            ;If so, exitoperating system: DOS. DOS provides memory    Cmp     dl,ScrnCols         ;Greater than ScrnCols?management, file and directory organization,    Ja      BadParam            ;If so, exitprogram loading and termination services, and;   All of the coordinates seem to be ok. Load them intomuch more. For example, the BIOS provides;   our internal variables along with the remaining;   two parameters.services for reading and writing individual    Mov     TopRow,alsectors on a hard disk, and DOS provides the    Mov     LeftCol,blhigher-level organization that keeps track of    Mov     BottomRow,clwhere on disk the files are stored, and so forth.    Mov     RightCol,dl    Mov     ax,Colr             ;Color attribute into axIn other words, when manipulation of hard-    Mov     ColorAttr,al        ;Store itware devices is necessary, DOS functions will    Mov     ax,LWrap            ;LineWrap% into axusually call BIOS routines instead of manipu-    Mov     LineWrap,al         ;Store itlating the hardware directly. This approach;   All of the parameters are now stored in our internal;   variables. Let's now clear the window area using theprevents DOS from becoming dependent on;   specified color and position the cursor to the upper-one specific brand of hardware. The software;   left corner of the window.layer above DOS is an application program.    Mov     ax,600h             ;Scroll up 0 lines (clear)Application programs can use DOS and even    Mov     bh,ColorAttr        ;Color attribute into bh    Mov     ch,TopRow           ;Window coordinates intoBIOS services to handle keyboard input, screen    Mov     cl,LeftCol          ;CX and DX.I/O, file I/O, and other operations.    Mov     dh,BottomRowKnowing the sequence of events that tran-    Mov     dl,RightColspire when an application prints a string allows    VideoInt                    ;Call the video BIOS    Mov     ah,2                ;Set cursor position tous to write a routine like DosWindow. For    Mov     bh,ScrnPage         ; the upper-left cornerexample, when most DOS command-line utili-    Mov     dh,TopRow           ; of our window.ties want to print a character, they use the DOS    Mov     dl,LeftColôfast put characterö function (interrupt &H29).    VideoInt;   The window is clear and the cursor is positioned. NowThis function simply writes a character to the;   get interrupt 10h's current vector and store it. Thenscreen at the current cursor location and moves;   point int 10h to our handler so we can take control.the cursor to the next character position. It also    Mov     ax,3510h            ;Get the current vectorprocesses the carriage return (ASCII 10) and    Int     21h                 ; for interrupt 10h.    Mov     OrigInt10Seg,es     ;Store it for laterline feed (ASCII 13) characters, and manipu-    Mov     OrigInt10Ofs,bxlates the cursor accordingly when these charac-    Mov     ax,3529h            ;Get current vector forters are encountered. Interrupt &H29 doesnÆt    Int     21h                 ; interrupt 29h.access the video hardware directly. It makes    Mov     OrigInt29Seg,es     ;Store it for later    Mov     OrigInt29Ofs,bxcalls to the video BIOS interrupt &H10 ser-    Mov     ax,2510h            ;Point the int 10h vectorvices to get the current cursor location, print the    Mov     dx,offset OurInt10  ; to our codecharacter, move the cursor to the next position,    Int     21hand to scroll the screen when necessary.    Mov     ax,2529h            ;Point Int 29h to our code    Mov     dx,offset OurInt29In order to make the DosWindow routineCONTINUED ON NEXT PAGE.work, you must intercept all calls made to38     FEBRUARY/MARCH 1994   Visual Basic ProgrammerÆs JournalD   O   S       S   H   E   L    LLISTING 1. CONTINUED FROM PREVIOUS PAGE.    Int     21h    cmp     al,0ah              ;Is it a line feed?    Xor     ax,ax               ;Return 0 (successful)    jnz     CheckBounds         ;If not, continueDosWindowExit:    mov     bx,-1               ;If so, set both flags    Ret                         ;Back to Basic    Inc     dh                  ;Point to the next lineBadParam:                       ;If we detected a badCheckBounds:                    ;Check cursor bounds    Mov     ax,-1               ; parameter, return -1.    Cmp     dl,LeftCol          ;Position < LeftCol?    jmp     short DosWindowExit    Jae     CheckRightCol       ;If not, continueDosWindow endp    Mov     bl,-1               ;Set "reset cursor" flag;               Our Interrupt 10h Handler    Mov     dl,LeftCol          ;New column for cursor; When an interrupt 10h hits, we check to see if it is    Jmp     short CheckRow      ;No need to checktheRightCol; "scroll zero" function. This is used to clear aCheckRightCol:; rectangular area of the screen (or the entire screen).    Cmp     dl,RightCol         ;Position > RightCol?; DOS and command line utilities use this service to    Jbe     CheckRow            ;If not, continue; perform a CLS operation. If a scroll zero request is    Cmp     LineWrap,0; detected, we redefine the coordinates to include only    jnz     @f; our window. Anything else, we pass right through to    Mov     bh,-1; the original int 10h handler.    jmp     short CheckRowOurInt10 proc far@@: Mov     bl,-1               ;Set cursor pos flag    Assume  ds:Nothing, cs:@code    Mov     dl,LeftCol          ;Cursor back to LeftCol    Sti                         ;Enable interrupts    Inc     dh                  ;And move to next row    Push    ds                  ;Preserve dsCheckRow:    Cmp     ax,600h             ;A scroll up 0? (CLS)    Cmp     dh,TopRow           ;Above TopRow?    jz      ScrollZero          ;If so, process it    Jae     CheckBottomRow      ;If not, continue    cmp     ah,9                ;Multiple char TTY?    Mov     bl,-1               ;Set cursor repos flag    jz      CharPrint    Mov     dh,TopRow           ;New row to set cursor to    cmp     ah,0eh              ;Or single char TTY    Jmp     short FixUp         ;Don't check BottomRow    jz      CharPrint           ;Process themCheckBottomRow:    Jmp     ChainToOrigInt10    ;If no of above, chain    Cmp     dh,BottomRow        ;Below BottomRow?CharPrint:                      ;If function 9 or E    Jbe     Fixup               ;If not, continue    mov     bl,cs:ColorAttr     ; use this attribute.    Mov     bl,-1               ;Reset cursor flag    Jmp     ChainToOrigInt10    ;Chain to orig int 10h    Mov     dh,BottomRow;   If we get here, we need to scroll the window up aScrollZero:                     ;If a scroll zeroline    Push    cs                  ;    Push    bx                  ;Save our control flags    Pop     ds                  ;Point ds to code    Push    dx                  ;And new cursor position    Assume  ds:@code    Mov     ax,601h             ;Scroll up one line    Mov     ch,TopRow           ;Override the requested    Mov     bh,ColorAttr        ;Load registers with    Mov     cl,LeftCol          ; CLS area (whole screen)    Mov     ch,TopRow           ; coordinates of    Mov     dh,BottomRow        ; with the coordinates    Mov     cl,LeftCol          ; window and color    Mov     dl,RightCol         ; and color defined for    Mov     dh,BottomRow        ; attribute.    Mov     bh,ColorAttr        ; our window.    Mov     dl,RightColChainToOrigInt10:    VideoInt    Pop     ds                     ;Restore ds    Pop     dx                  ;Restore the registers    Jmp     Dword Ptr cs:OrigInt10 ;Chain orig int 10h    Pop     bxOurInt10 endpFixUp:                          ;Adjust cursor pos, if;               Our Interrupt 29h Handler    Push    bx                  ; needed.; When an interrupt 29h (DOS "Fast PutChar") function    Or      bl,bl               ;Reset the cursor pos?; hits, we check the cursor position and make sure it is    Jz      @f                  ;If not, continue; within our window. If it is outside the window, we    Mov     ah,2; either wrap to the next line, or scroll the window up.    Mov     bh,ScrnPageOurInt29 proc far    VideoInt    Sti                         ;Turn interrupts back on@@: Pop     bx                  ;Restore flags again    Push    ds                  ;Save these registers    Or      bh,bh               ;Skip printing this char?    Push    ax    Pop     dx    Push    bx    Pop     cx    Push    cx    Pop     bx                  ;Restore these registers    Push    dx    Pop     ax    Push    cs    Pop     ds    Pop     ds                  ;Point ds to code segment    jnz     @f                     ;If skip print, return    Assume  ds:@Code    Jmp     DWord Ptr cs:OrigInt29 ;Otherwise, chain    Mov     ah,3                ;Get current cursor pos@@: Iret    Mov     bh,ScrnPage         ;Returned in DH/DLOurInt29 endp    VideoInt;ùùùùùùùùùùùùùùùùùùùùùùùùùùùù;   As we qualify the output, BH and BL are used asRemoveDosWindow proc uses ds;   control flags. If BH is set, then the current;   From Basic:;   character is not printed (CR, BL, or if past right;       DECLARE SUB RemoveDosWindow ();   border of window when the LineWrap flag is clear).;   Unhooks the DosWindow routine from int 10h and resets;   BL is set when the cursor position needs to be;   our internal variables.;   updated (line wrap or carriage return).    Push    cs    Xor     bx,bx               ;Clear our control flag    Pop     ds                 ;Point ds to codeCheckCR:    Assume  ds:@Code    cmp     al,0dh              ;A carriage return?    Cmp     OrigInt10Seg,0     ;Are we installed?    jnz     CheckLF             ;If not, continue    Jz      RemoveExit         ;If not, exit    Mov     dl,LeftCol          ;If so, set left col to    Mov     ax,2510h           ;Set vector for int 10h    Mov     bx,-1               ; left side of window and    Mov     dx,OrigInt10Ofs    ;Offset of orig handler    jmp     short CheckBounds   ; set "update cursor    Mov     bx,OrigInt10Seg    ;Seg of handler in bxflag"    Mov     OrigInt10Seg,0     ;Reset our "flag"CheckLF:CONTINUED ON NEXT PAGE.Visual Basic ProgrammerÆs Journal   FEBRUARY/MARCH 1994     39D   O   S       S   H   E   L    LBack% and Fore% represent a set of BasicLISTING 1. CONTINUED FROM PREVIOUS PAGE.background and foreground color values (as    Mov     ds,bx              ;Seg of orig handler in dsused with the COLOR statement), Colr% can    Assume  ds:nothingbe calculated as follows:    Int     21h                 ;Call DOS    Mov     ax,2529h            ;Restore original int 29h    Mov     dx,cs:OrigInt29OfsColr% = (Back% OR (Fore% AND 16) \ 2 )_    Mov     bx,cs:OrigInt29Seg* 16 + (Fore% AND 15)    Mov     ds,bx    Int     21hRemoveExit:The LineWrap% parameter is used to deter-    Ret                         ;We're finishedmine if the DosWindow routine wraps or trun-RemoveDosWindow endpcates a line thatÆs wider than the defined win-enddow. Truncating generally provides a moren'TESTWIN.BAS - LISTING 2readable display within a DosWindow. Pass aDEFINT A-Zvalue of -1 to wrap text or 0 to truncate text.DECLARE SUB RemoveDosWindow()Once the routines are declared, all you haveDECLARE FUNCTION DosWindow% (BYVAL TopRow%, _to do is invoke the DosWindow% function                    BYVAL LeftCol%, BYVAL BottomRow%, _immediately before your SHELL statement and                    BYVAL RightCol%, BYVAL Colr%, _                    BYVAL LWrap%)call RemoveDosWindow immediately upon'PB3 users, unrem the following line:returning from the SHELL. Listing 2 contains'$link "dosbox2.obj"a small example program called'Clear the screen to black on whiteDWTEST.BAS.COLOR 0,7CLSRemember, the DosWindow routine can'Dress up the screen a little with an instruction barcontrol the output of programs only when they'above and below our Dos window area.use DOS or BIOS services to display data.COLOR 7,1Because BasicÆs PRINT statement uses directLOCATE 2,10: PRINT SPC(61)LOCATE 2,28: PRINT "** Dos Shell In Progess **"video writes instead of BIOS and DOS servicesLOCATE 24,10: PRINT SPC(61);(direct writes are faster), DosWindow will notLOCATE 24,25: PRINT "Type 'Exit' to return to Basic";be able to control its output. There is a way'Set up and call the DosWindow routinearound this: instead of using a regular PRINTTopRow% = 4:     LeftCol% = 8:          'Upper left cornerBottomRow% = 22: RightCol% = 72         'Lower rightstatement in a program you want to SHELL,Colr% = 3:       LineWrap% = 0          'Color and wrapOPEN the CON (console) device and printStatus% = DosWindow%(TopRow%, LeftCol%, BottomRow%,_through it. For example:                     RightCol%, Colr%, LineWrap%)IF Status% THENOPEN "CON" FOR OUTPUT AS #1    PRINT "Bad coordinates were passed to DosWindow!"    ENDPRINT #1, "This text is routine _END IFthrough the BIOS and"SHELL                   'Now, we're ready to shell!PRINT #1, "is trapable by the _'Don't forget this! Failure to call this routine beforeDosWindow routine!"'ending your program can result in a crash.Call RemoveDosWindowCLOSE #1'Clear the screen to white on black and end.COLOR 7,0There you have it. Once youÆve integratedCLSENDthe DosWindow routine with your application,you can SHELL to the predefined window andmaintain control of your user interface. ToLISTING 2Polish Your Shell. This sample program generates screen output to test yourdownload the this code, call my BBS at 404-image when SHELLing to a pre-defined window.928-7111 and download a file calledDOSWIN.EXE. It is a self-extracting archiveinterrupt &H29 and interrupt &H10 during theDeclare Function DosWindow% ( BYVAL_that contains everything you need. nSHELL. The interception of an interrupt ser-TopRow%, BYVAL LeftCol%, _vice is referred to as ôhooking an interrupt.öBYVAL BottomRow%, BYVAL _While these interrupts are hooked, theRightCol%, BYVAL Colr%, _DosWindow routine makes sure that all cursorBYVAL LineWrap% )positioning requests are kept within the boundsDeclare Function RemoveDosWindow ()of a predefined window, that the desired colorattribute is used to display data within theIf you are using PowerBasic 3.0, youÆll needwindow, and that attempts to clear (CLS) orone additional line:scroll the screen affect only the contents of thewindow (Listing 1). If an application requests$Link ôDOSWIN.OBJöan interrupt &H10 service that  my routine isnÆtprepared to handle, the original interrupt &H10When declaring the routines, donÆt forgetservice routine will handle it.the BYVALs! If you leave them out, unpredict-ItÆs easy to use the DosWindow routineable results will occur!from Quick Basic, Basic PDS, VBDOS, orThe parameters TopRow%, LeftCol%,PowerBasic 3.0. Just add the following declara-BottomRow%, and RightCol% define the up-tions to the top of the Basic program moduleper-left and bottom-right corners of the win-that will be calling the DosWindow routines:dow. Colr% defines the color attribute usedwhen displaying data within the window. When40     FEBRUARY/MARCH 1994   Visual Basic ProgrammerÆs Journal