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