;BLISTER.ASM 1.0 Generates page-pauses during BASIC LISTings to the console. ;Roy Lipscomb Compatible with CP/M 2.2 and 8080/8085/Z80 CPUs ;9/16/87 Assemble with ASM.COM ; ; (C) Copyright 1987, Logic Associates ; Permission is hereby granted only for ; non-fee copying and distribution. ; ; ; NOTE: No separate .DOC file is provided. All documentation is in this file. ; ;**************************************************************************** ;"WHAT'S IT FOR?" ; ; BLISTER is an add-on for interpreted BASIC (any version). ; ; During long LISTings to the console, BLISTER suspends the LISTing after ; each "page-full" of lines. ; ; BLISTER permits the LISTing to resume as soon as any key is pressed (except ; that the LISTing is terminated if control-C is pressed). ; ;**************************************************************************** ;INSTALLATION ; ; BLISTER relocates itself to very low memory not used by most programs. ; ; Do not run BLISTER if your system is using any of the CPU restart locations, ; (apart from the DDT vector). See "CAUTION" below. Otherwise, -- ; ; Type "BLISTER." ; ;**************************************************************************** ;REMOVAL ; ; Type "BLISTER OFF", or press reset. ; ;**************************************************************************** ;CUSTOMIZING ; ; The distribution version of this program generates page pauses every 22 ; lines. You can change this page length by either of two methods: ; ; [] Change the variable "pagelen" in this source code, ; and then reassemble this source code, ; ; or [] (after running BLISTER) POKE the desired page-length value ; (1-255) into location 37H (55 decimal). ; ;**************************************************************************** ;THEORY OF OPERATION ; ; By patching the BIOS jumptable, BLISTER is able to review all output to the ; console, and to monitor all console input. ; ; When it finds a line that does not begin with a digit, it resets its counter. ; When it finds a line that does begin with a digit, it decrements its counter. ; When its counter reaches zero, BLISTER pauses and waits for any keystroke. ; At the keystroke, BLISTER passes control back to BASIC. ; ; The above strategy allows BLISTER to work not only with BASIC but also ; with other programs that display lines prefixed with digits. ; ;**************************************************************************** ; ===>>>> *****>>>>>CAUTION<<<<<***** <<<<=== ; ; BLISTER relocates itself to low memory locations 8H through 50H. If your ; system uses any of this space (except the DDT vector at 38H), BLISTER will ; cause your system to crash. It's ok to use DDT or other debugger, however. ; ; BLISTER works fine in all systems at our location, and should also work ; fine in most other systems. But Logic Associates cannot be responsible ; for any damage resulting from use of this software. Use it at your own risk. ; ;**************************************************************************** org 100h jmp begin ;---------------------------------------------------------------------------- ; User-Customizable Constant. ; ;---------------------------------------------------------------------------- pagelen equ 22 ;recommended values: 11 or 22. ;---------------------------------------------------------------------------- ; Other constants ; ;---------------------------------------------------------------------------- bell equ 7 lf equ 10 cr equ 13 bdos equ 5 loadpt equ 8 fcb equ 05ch display equ 9 mlogon db cr,lf,'BLISTER 1.0 (C) Copyright 1987, Logic Associates.' db cr,lf db cr,lf,'Inserts page pauses into BASIC LISTings to the console.' db cr,lf,'(To remove, press reset or type "BLISTER OFF".)' db cr,lf crlf: db cr,lf,'$' miok: db cr,lf,'Installed.$' mdok: db cr,lf,'De-installed.$' miabort db cr,lf,bell,'Installation ABORTED: BLISTER already installed.$' mdabort db cr,lf,bell,'De-installation ABORTED: BLISTER not installed.$' ;---------------------------------------------------------------------------- ; MAINLINE ; ;---------------------------------------------------------------------------- begin: lxi d,mlogon ;display welcome message. mvi c,display call bdos call tstoff ;is request to turn BLISTER off? jz deinst ; yes, go do it. ;install BLISTER. call tstact ;is BLISTER already active? lxi d,miabort ;(prepare error message) jz exit ; yes, abort call install ;install BLISTER relocatable module. lxi d,miok ;notify of successful installation. jmp exit ;De-install BLISTER. deinst: call tstact ;is BLISTER active? lxi d,mdabort ;(prepare error message) jnz exit ; no, abort call unpatch ;unpatch the BIOS jumptable. lxi d,mdok ;notify of successful de-installation. ;end of processing. exit: mvi c,display ;inform user of results. call bdos lxi d,crlf mvi c,display call bdos ret ;---------------------------------------------------------------------------- ;is request for de-installation? ;if yes, return z = yes. tstoff: lxi h,fcb+1 mov a,m cpi 'O' jnz tstoffx inx h mov a,m cpi 'F' jnz tstoffx inx h mov a,m cpi 'F' tstoffx: ret ;---------------------------------------------------------------------------- ;is BLISTER active? ;if yes, return z = yes. tstact: lhld 1 ;test for conin patch. mvi l,9+1 mov e,m inx h mov d,m lxi h,-trconin dad d mov a,h ;is appropriate patch present? ora l jnz tstactx ; no, exit. lhld 1 ;test for conout patch. mvi l,12+1 mov e,m inx h mov d,m lxi h,-trconout dad d mov a,h ;is appropriate patch present? ora l tstactx: ret ;---------------------------------------------------------------------------- ;install the BLISTER relocatable module. install: call fillmod ;fill run-time addresses into module ;(must be done BEFORE patching, below.) call movemod ;move module into place. call patch ;patch the BIOS jumptable. ret ;---------------------------------------------------------------------------- ;copy run-time addresses into BLISTER relocatable module. fillmod: lhld 38h ;copy DDT vector contents into module. shld ddtvect+adjust lda 38h+2 sta ddtvect+adjust+2 lhld 1 ;get conin-routine addr... mvi l,9+1 mov e,m inx h mov d,m xchg shld getkey+adjust+1 ; ...then copy into module. lhld 1 ;get conout-routine addr... mvi l,12+1 mov e,m inx h mov d,m xchg shld todisp+adjust+1 ; ...then copy into module. ret ;---------------------------------------------------------------------------- ;move module into place. movemod: mvi b,modlen lxi d,loadpt lxi h,module movem1: mov a,m stax d inx d inx h dcr b jnz movem1 ret ;---------------------------------------------------------------------------- ;patch BIOS jumptable. patch: lhld 1 ;patch conin vector in BIOS table. mvi l,9+1 lxi d,trconin mov m,e inx h mov m,d lhld 1 ;patch conout vector in BIOS table. mvi l,12+1 lxi d,trconout mov m,e inx h mov m,d ret ;---------------------------------------------------------------------------- ;unpatch BIOS jumptable. unpatch: lhld getkey+1 ;unpatch conin vector in BIOS table. xchg lhld 1 mvi l,9+1 mov m,e inx h mov m,d lhld todisp+1 ;unpatch conout vector in BIOS table. xchg lhld 1 mvi l,12+1 mov m,e inx h mov m,d ret ***************************************************************************** ;---------------------------------------------------------------------------- ; RELOCATABLE MODULE ; ;---------------------------------------------------------------------------- module: adjust equ $-loadpt ;correction for addresses below. ;............................................................................ trconout equ $-adjust oldout equ $-adjust+1 mvi a,$-$ ;old char = lf? cpi lf mov a,c sta oldout ;(save new char.) cz traplf ; yes: see if pause needed. oldin equ $-adjust+1 mvi a,$-$ ;last keystroke = ^C? cpi 3 rz ;yes, throw away display char. todisp equ $-adjust jmp $-$ ;no, display character. ;------------------------------------------------------ ;trap routine for conin. trconin equ $-adjust call reinit ;reinitialize count. lxi h,oldin mov a,m ;get buffered character, mvi m,0 ; clear the buffer. ora a ;buffer empty? rnz ; no, return the buffered char. getkey equ $-adjust jmp $-$ ;go get keystroke. ;------------------------------------------------------ ;new line: reset line count if full page now displayed. traplf equ $-adjust sui '0' ;1st char on line is digit? cpi 10 jnc reinit ; no, reset counter. lxi h,counter ;end of screen page? jmp continue ;...................................................... counter equ $-adjust db pagelen ;lines left until pause. initcnt equ $-adjust db pagelen ;initial value of counter ;...................................................... ddtvect equ $-adjust ;DDT vector location. ds 3 ;(copied to here at run time.) ;...................................................... continue equ $-adjust dcr m rnz ; no, exit. lda oldin ;^-C already in effect? cpi 3 push b cnz getkey ; no, wait for keypress, and... pop b sta oldin ; ...save it for conin request. reinit equ $-adjust lda initcnt ;reset counter for next list-page. sta counter ret ;---------------------------------------------------------------------------- modlen equ $-module