PAGE 60,132 TITLE SHOW ; Program SHOW.ASM ; Purpose Text file displayer ; Input File name from command line or prompt ; Output Display file to screen DOSSEG .MODEL small INCLUDE dos.inc INCLUDE bios.inc .STACK 100h .DATA ; Status line PUBLIC statline,linenum statline DB " Line: " statfile DB " File: " stathelp DB " Quit: ESC Move:   PGUP PGDN HOME END " linenum DW 1 ; Variables for screen handling PUBLIC cell,rows,columns,vidadr,statatr,scrnatr,cga cell LABEL WORD ; Cell (character and attribute) char DB " " ; Initialize to space attr DB ? ; Attribute columns EQU 80 ; Number of columns rows DW 24 ; Number of rows - status line takes one more mode DB ? ; Initial mode pag DB ? ; Initial display page newvid DB 0 ; Video change flag cga DB 1 ; CGA flag - default yes vidadr DW 0B800h ; Video buffer address - default CGA mono EQU 0B000h ; Monochrome address statatr DB 030h ; Color default - black on cyan bwstat EQU 070h ; B&W default - black on white scrnatr DB 017h ; Color default - white on blue bwscrn EQU 007h ; B&W default - white on black ; Variables for buffer and file handling PUBLIC buffer,pbuffer,sbuffer,fsize,namebuf buffer LABEL DWORD pbuffer DW 0 ; Position in buffer (offset) sbuffer DW ? ; Base of buffer (segment) lbuffer DW ? ; Length of buffer fhandle DW ? ; Holds file handle on open fsize DW ? ; File size after dosopen prompt DB 13,10,13,10,"Enter filename: $" prompt2 DB 13,10,"File problem. Try again? $" namebuf DB 66,? filename DB 66 DUP (0) ; Buffer for file name err1 DB 13,10,"Must have DOS 2.0 or higher",13,10,"$" err2 DB 13,10,"File too big",13,10,"$" ; Call table exkeys DB 71,72,73,79,80,81 ; Extended key codes lexkeys EQU $-exkeys ; Table of keys extable DW homek DW upk DW pgupk DW endk DW downk DW pgdnk DW nonek .CODE EXTRN pager:PROC,isEGA:PROC ; Routines in other module start: mov ax,@DATA ; Initialize data segment mov ds,ax cli ; Turn off interrupts mov ss,ax ; Make SS and mov sp,OFFSET STACK ; SP relative to DGROUP sti ; Adjust memory allocation mov bx,sp ; Convert stack pointer to paragraphs mov cl,4 ; to get stack size shr bx,cl add ax,bx ; Add SS to get end of program mov bx,es ; Get start of program sub ax,bx ; Subtract start from end @ModBlok ax ; Release memory after program ; Allocate dynamic memory for file buffer @GetBlok 0FFFh ; Try to allocate 64K mov sbuffer,ax ; Save buffer segment mov lbuffer,bx ; Save actual length allocated ; Check DOS @GetVer ; Get DOS version cmp al,2 ; Requires DOS 2.0 jge video @DispStr err1 ; else error and quit int 20h ; Adjust for current mode and and video adapter video: call isEGA ; EGA (or VGA)? or ax,ax ; If 0 must be CGA or MA je modechk ; Leave default mov rows,ax ; Load rows dec cga ; Not CGA modechk: @GetMode ; Get video mode mov mode,al ; Save initial mode and page mov pag,bh mov dl,al ; Work on copy cmp dl,7 ; Is it mono 7? je loadmono ; Yes? Set mono cmp dl,15 ; Is it mono 15? jne graphchk ; No? Check graphics loadmono: mov vidadr,mono ; Load mono address mov statatr,bwstat ; Set B&W defaults for status line mov scrnatr,bwscrn ; and screen background dec cga ; Not CGA cmp al,15 ; Is it mono 15? jne cmdchk ; No? Done mov dl,7 ; Yes? Set standard mono jmp SHORT chmode graphchk: cmp dl,7 ; 7 or higher? jg color ; 8 to 14 are color (7 and 15 done) cmp dl,4 ; 4 or higher? jg bnw ; 5 and 6 are probably black and white je color ; 4 is color test dl,1 ; Even? jz bnw ; 0 and 2 are black and white color: ; 1 and 3 are color cmp dl,3 ; 3? je cmdchk ; Yes? Done mov dl,3 ; Change mode to 3 jmp SHORT chmode bnw: mov statatr,bwstat ; Set B&W defaults for status line mov scrnatr,bwscrn ; and screen background cmp dl,2 ; 2? je cmdchk ; Yes? Done mov dl,2 ; Make it 2 chmode: @SetMode dl ; Set video mode @SetPage 0 ; Set video page mov newvid,1 ; Set flag ; Try to open command line file cmdchk: mov bl,es:[80h] ; Get length sub bh,bh mov WORD PTR es:[bx+81h],0; Convert to ASCIIZ push ds @OpenFil 82h,0,es ; Open argument pop ds jc getname ; If error, get from prompt mov fhandle,ax ; else save handle push ds @GetFirst 82h,,es ; Let DOS convert to file name pop ds jnc opened ; If OK file is open ; Prompt for file getname: @DispStr prompt ; Prompt for file @GetStr namebuf,0 ; Get response as ASCIIZ @OpenFil filename,0 ; Try to open response jc badfile ; If successful, continue mov fhandle,ax ; Save handle @GetFirst filename ; Let DOS convert to file name jnc opened ; If OK, file is opened badfile: @DispStr prompt2 ; else prompt to try again @GetKey 0,1,0 and al,11011111b ; Convert key to uppercase cmp al,"Y" ; If yes, je getname ; try again jmp quit ; else quit ; Copy file name to status line opened: mov si,9Eh ; Load FCB as as source mov di,OFFSET statfile[7] ; Load status line as destination mov al,es:[si] ; Load first byte inc si copy: mov [di],al ; Save and load bytes until 0 inc di mov al,es:[si] inc si or al,al ; Check for 0 loopne copy ; Check file size @GetFilSz fhandle ; Get file size or dx,dx ; Larger than 64K? jne big ; Yes? Too big mov fsize,ax ; Save file size mov cx,4 ; Convert to paragraphs shr ax,cl cmp ax,lbuffer ; Is it larger than buffer jle fileread ; No? Continue big: @DispStr err2 ; else error @Exit 2 fileread: push ds @Read buffer,fsize,fhandle ; Read file pop ds jnc readok ; If no read error continue jmp getname ; else try again ; Search back for EOF marker and adjust if necessary readok: mov di,ax ; Load file length push es ; Save ES and load buffer segment mov es,sbuffer std ; Look backward for 255 characters mov cx,0FFh mov al,1Ah ; Search for EOF marker repne scasb cld jcxz noeof ; If none, we're OK inc di ; else adjust and save file size mov fsize,di noeof: pop es @SetCurPos 0,43 ; Turn off cursor by moving off screen ; Display first page xor ax,ax ; Start at 0 push ax firstpg: call pager ; Handle keys nextkey: @GetKey 0,0,0 ; Get a key nextkey2: cmp al,0 ; Is it a null? je extended ; Yes? Must be extended code cmp al,27 ; Is it ESCAPE? jne nextkey ; No? Ignore unknown command quit: @ClosFil fhandle ; Yes? Close file @FreeBlok sbuffer ; Release buffer cmp newvid,1 ; Restore video? jne thatsall ; No? @SetMode mode ; Restore video mode, page, and cursor @SetPage pag thatsall: mov dx,rows ; Load last row and first column xchg dl,dh mov cx,dx ; Make row the same mov dl,79 @Scroll 0 ; Clear last line sub dl,dl @SetCurPos ; Set cursor @Exit 0 ; Quit extended: @GetKey 0,0,0 ; Get extended code push es push ds ; Load DS into ES pop es mov di,OFFSET exkeys ; Load address and length of key list mov cx,lexkeys+1 repne scasb ; Find position pop es sub di,(OFFSET exkeys)+1 ; Point to key shl di,1 ; Adjust pointer for word addresses call extable[di] ; Call procedure jmp nextkey homek: mov pbuffer,0 ; HOME - set position to 0 push pbuffer mov linenum,1 call pager retn upk: mov ax,-1 ; UP - scroll back 1 line push ax call pager retn pgupk: mov ax,rows ; PGUP - Page back neg ax push ax call pager retn endk: mov ax,fsize ; END - Get last byte of file mov pbuffer,ax ; Make it the file position mov linenum,-1 ; Set illegal line number as flag mov ax,rows ; Page back neg ax push ax call pager retn downk: mov ax,1 ; DOWN - scroll forward 1 line push ax call pager retn pgdnk: push rows ; PGDN - page forward call pager retn nonek: retn ; Ignore unknown key END start