; title 'BISHOW v1.06 - buffered bidirectional file scroll utility' ; ; Ver 1.06 2 Jul 83, Chuck Forsberg ; - added commands for more, mince, vi familiarity. Bad cmd gives help ; ; Ver 1.051, 26 June 83, Dick Mead ; - added "?" for help on commands. ; ; Ver 1.05, 31 May 83, Bruce Ratoff ; - added 'N' (next line) and 'P' (previous line) cmds ; - decreased buffer from 8k to 4k (8k takes too long) ; ; Ver 1.04, 15 May 83, Keith Petersen, W8SDZ ; - fixed bug which caused display past end-of-file ; and added bugus eof in case none at file end ; - added strip of high-order bit in line count routine ; - added exit clear of any left-over keyboard character ; ; Ver 1.03, 11 May 83, Keith Petersen, W8SDZ ; - fixed to allow assembly with ASM.COM ; - fixed screen clear bug when crossing read boundries ; - added strip for high-order bit in character before ; printing (needed for WordStar files) ; - improved stack routines ; - fixed bug in console input routine ; - removed Z80 dependant code (now works on 8080 too) ; ; Ver 1.02, 06 May 83, Lucien Pan, Toronto, Canada ; - fixed some minor bugs ; - returns to ccp w/o warm boot ; - filters form-feeds (useful in .PRN files) ; - scrolls foward/backwards by same number of lines ; - disable/enable cursor during scroll for H-19 ; ; Ver 1.01, 30 Mar 83 - added BDOS function 6. W.F.Mcgee ; ; Ver 1.00, 23 Aug 82 Phil Cary, 748 Kenilworth Parkway, Baton ; Rouge, LA 70808 ; ; BISHOW is a buffered, bidirectional version of SHOW.ASM ; which first appeared in Interface Age, November, 1981. That ; program could only scroll forward in a file, and read ; sectors from disk one at a time as they were sent to the ; console. I used SHOW frequently to take a quick look at a ; file without loading a big text editor, and to examine ; another file with the RUN command while in Wordstar. TYPE ; does not work since it is not a file that Wordstar can load ; and run. ; ; It was annoying when I went past the point I was looking for ; in a file with SHOW, and could not go backwards. Thus, this ; bidirectional version which uses random access reads. In ; addition, buffering was added so that the number of disk ; reads would be reduced, and moving back and forth in a ; moderate sized file would be speeded up. There is a trade ; off between the size of the buffer and the length of time it ; takes to refill the buffer which should be set to the user's ; preference. ; ; There are two customizing items in this program. One is ; the equate "maxsec" which sets the buffer size. The other ; is the string in the subroutine "clrscr" just after the org ; statement. This should be changed to the erase screen and ; home cursor sequence for the user's terminal. The program is ; presently set up for an ADM-3A. The program, as written, ; does require a 24 X 80 screen with an erase screen and home ; cursor function. Finally, direct I/O to the console is used ; to avoid echoing the commands to the console as the CP/M ; write console function does. ; ; Just a small contribution to the public domain software as ; partial payment for the many fine and educational programs ; the system has given me. Phil Cary. ; ;Define version number for help message vers equ 1 revs equ 60 ; false equ 0 true equ not false ; ; Operational equates ; maxsec equ 32 ;number of sectors in buffer scroln equ 24 ;number of lines per scroll fulbuf set dskbuf+(maxsec*128) ;need to know end of buffer ; heath equ true ;assemble for H-19 terminal base equ 0 ;standard zero base CP/M ; ; BDOS functions ; conout equ 2 ;console write open equ 15 ;open file readr equ 33 ;read file random access stdma equ 26 ;set dma address ; ; Page zero equates ; wboot equ base ;warm boot entry point bdos equ wboot+5 ;BDOS entry point fcb equ wboot+5ch ;default fcb drive number fcbfn equ fcb+1 ;start of filename fcbft equ fcb+9 ;start of filetype fcbex equ fcb+12 ;current extent number fcbcrr equ fcb+33 ;current record number, random access tpa equ wboot+100h ;transient program area ; ; ASCII equates ; endmsg equ 0 ;null bell equ 7 ;bell lf equ 0ah ;line feed cr equ 0dh ;carriage return eof equ 1ah ;end of file esc equ 1bh ;escape ; org tpa ; jmp start ;skip over next subroutine ; clrscr: if not heath call cdisp db 7eh,1ch,endmsg ;put your screen clear string here endif ; if heath call cdisp ;command to erase screen and home cursor db esc,'E',endmsg ;__for H/Z-19 terminal. change as required wait: mvi b,0 ;waste time (may or may not be necessary) ; wait1: xthl ;good time gobbeler! xthl dcr b jnz wait1 endif ; ret ;return from clrscr ; start: lxi h,0 ;get ccp's stack dad sp shld stack ;save old stack for later lxi sp,stack ;set new stack call opnfil ;open file in default fcb ; wrtfwd: xra a ;get a 0 sta lincnt ;store in line count sta fcbex ;zero current extent sta fcbcrr ;zero current record sta fcbcrr+1 ;__both bytes sta fcbcrr+2 ;__and the overflow call clrscr ;erase the screen ; wrtfw0: call filbuf ;fill the disk buffer lxi h,dskbuf ;point to beginning of buffer ; wrtfw1: mov a,m ;get a character cpi eof ;see if eof jz getcmd ;yes, wait for command inx h ;bump pointer ani 7fh ;strip high bit cpi 'L'-40h ;filter form-feeds jz filter ;__commonly found in .PRN files call co ;put it on console cpi cr ;see if end of line jz fwdcnt ;yes, adjust line count ; wrtfw2: lxi d,fulbuf ;get end of buffer address mov a,d ;compare high cmp h ;__order bytes jnz wrtfw1 ;if not equal, continuee Hc htt Prufwrtd ptuuuuut, uuuuuuuuuuuuuuuuuuuuuuuu l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l Hleet call co ;__of control character pop psw ;restore status adi 40h ;mask into displayable char call co ;display filtered control char ; fwdcnt: lda lincnt ;get number of lines displayed inr a ;bump it sta lincnt ;__and store it xchg ;save the buffer pointer lxi h,linmax ;point to max number of line for this pass cmp m ;compare with line count xchg ;restore pointer jnz wrtfw2 ;if not there, continue, else get command xra a ;zero the sta lincnt ;__line count ; getcmd: push h push d push b ; if heath call cdisp db esc,'x5',endmsg ;disable cursor endif ; getcm1: mvi c,6 ;direct console I/O mvi e,0ffh ;__set up for input call bdos ora a ;loop till char avail jz getcm1 pop b pop d pop h cpi '1' ; 1 means goto 1st line jz wrtfwd cpi '?' ;help request jz help2 cpi ' ' ; more uses space jz wrtfw1 cpi 'F' ;scroll forward? jz wrtfw1 ;br if yes cpi 'f' jz wrtfw1 ;br if yes cpi 06 ;vi uses ^F jz wrtfw1 cpi 026Q ; mince uses ^V jz wrtfw1 cpi 'B' ;scroll backward? jz wrtbak cpi 'b' jz wrtbak cpi 02 ;vi uses ^B jz wrtbak cpi 'N' ;scroll next line? jz wrtnxt cpi 'n' jz wrtnxt cpi '+' jz wrtnxt cpi cr ;scroll next line? jz wrtnxt cpi lf jz wrtnxt cpi 'P' ;scroll prev line? jz wrtprv cpi 'p' jz wrtprv cpi '-' jz wrtprv cpi 'C'-40h ;must be exit jz exit ;return control to CCP if yes or cpi 'q' jz exit ;more uses q for quit cpi 'Q' jz exit jmp help2 ;else give a hint ; wrtnxt: lda linmax dcr a ;fool wrtfw1 to only write one line sta lincnt jmp wrtfw1 ; wrtprv: lda linmax ;back up one screen + 1 line inr a jmp wrtbk0 ; wrtbak: lda linmax ;get screen line count add a ;__multiply by 2 wrtbk0: inr a ;__and add 1 sta lincnt ;__to backup to previous page call clrscr ;clear the screen ; wrtbk1: lxi d,dskbuf ;get address of buffer start mov a,d ;compare high cmp h ;__order bytes jnz wrtbk2 ;continue if not equal mov a,e ;else, compare low cmp l ;__order bytes jnz wrtbk2 ;continue if not equal jmp filbak ;__and go write it ; wrtbk2: mov a,m ;get a character ani 7fh ;strip high bit dcx h ;decrement buffer cpi cr ;see if end of line jz bakcnt ;__or form-feed cpi 'L'-40h ;__and adjust line count if so jnz wrtbk1 ;else, loop if not ; bakcnt: lda lincnt ;else, get number of lines to move back dcr a ;__and decrement it sta lincnt ;__store it jnz wrtbk1 ;__and loop if not there inx h ;else bump pointer inx h ;__to account for dcx jmp wrtfw1 ;and go write a screen ; filbak: lxi d,maxsec ;get the buffer size lhld seccnt ;__and number of sectors last read dad d ;add them xchg ;__and put them in DE lda fcbcrr ;subtract low order byte sub e ;__from current record count sta fcbcrr ;__and store in current record count lda fcbcrr+1 ;same with high order byte sbb d ;__but with borrow jm wrtfwd ;if beyond beginning of file, start over sta fcbcrr+1 ;else, store high order byte call filbuf ;fill the buffer lxi h,fulbuf ;__and point to end of buffer call clrscr ;clear the screen jmp wrtbk2 ;continue moving back in file ; filbuf: lxi d,dskbuf ;load start of disk buffer mvi b,maxsec ;number of sectors to resd lxi h,0 ;zero out the shld seccnt ;__number of sectors in buffer ; filbu1: push h ;save all push d ;__registers from push b ;__BDOS clobber mvi c,stdma ;set dma to call bdos ;__disk buffer lxi d,fcb ;set up to read mvi c,readr ;__a record call bdos ;do it ora a ;read OK? lhld fcbcrr ;get current record number inx h ;__bump it shld fcbcrr ;__and save it lhld seccnt ;get sectors in buffer inx h ;bump it shld seccnt ;store it pop b pop d pop h jnz rderr ;no, last sector read dcr b ;decrement it rz ;if done return lxi h,128 ;else, add 128 to dad d ;__dma address xchg ;put it in de jmp filbu1 ;read another sector ; ;We only get here if end of file ; rderr: mvi a,eof ;get bogus eof stax d ;save at buffer end in case no eof in file xra a ;get a zero to direct to start of buffer ret ;__on ret ; opnfil: lda fcbfn ;point to first letter of filename cpi ' ' ;anything there? jz help ;no, give help message lxi d,fcb ;file name in default fcb mvi c,open ;set up to open call bdos ;do it cpi 0ffh ;open OK? rnz ;yes call cdisp ;else, give error msg and quit db 'file not found ',endmsg jmp exit1 ;leave msg on screen on exit ; help: call cdisp db 'BISHOW version ' db (vers mod 10)+'0','.' db revs/10+'0',(revs mod 10)+'0',cr,lf db 'Usage: d:bishow d:fn.ft ',cr,lf db endmsg jmp exit1 help2: call cdisp db cr,lf,'Commands:',cr,lf db '^F,F,^V,sp=forward page, ^B,B=back page',cr,lf db 'CR,+,N=next line, ' db '-,P=back line, 1=1st line, ^C,Q=exit',cr,lf,endmsg jmp getcmd ; cdisp: xthl ;exchange top of stack and HL ; cdis1: mov a,m ;HL now pointing to db message ora a ;see if 0 at end of message inx h jz cdis2 ;yes, restore stack and return call co ;no, print the character jmp cdis1 ;__and loop ; cdis2: xthl ;get return address on top of stack ret ;__and return ; co: push b ;Save the registers push d ;__from bdos push h ;__clobber push psw mov e,a ;set up character mvi c,conout ;__to send to console call bdos ;do it pop psw pop h ;restore pop d ;__the registers pop b ret ; exit: mvi c,11 ;console status call bdos ;--check for any waiting characters ora a ;character waiting? mvi c,1 ;console input cnz bdos ;if so, gobble it up call clrscr ;clear the screen ; if heath call cdisp ;re-enable cursor db esc,'y5',endmsg endif ; lxi d,fcb ;close file mvi c,16 ;--in case this is MP/M call bdos ; exit1: lhld stack ;get old stack sphl ret ;return to CCP ; ; Memory allocation ; seccnt: dw 0 ;number of sectors read into buffer linmax: db scroln ;number of to write lines on console lincnt: db 0 ;line number on write or move back in buffer ds 60 ;stack area stack: ds 2 ;old stack saved here dskbuf: equ $ ;disk buffer area above the program ; end tpa f stack ret ;__and return ; co: pusht dcx h ;decrement buffer cpi cr ;see if end of line jz bakcnt ;__or form-feed cpi