home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
ZCPR33
/
A-R
/
RCPPEEP.LBR
/
RPEEP.LZB
/
RPEEP.LIB
Wrap
Text File
|
2000-06-30
|
19KB
|
934 lines
;=============================================================================
;
; P E E P C O M M A N D
;
;============================================================================
; +++++++ NOT an official RCP segment for Z33RCP.Z80
; This is a hacker's module intended to work with Z33RCP.
; Command: PEEP
; Function: Text File Browser and Lister
; Comments: The CRT protocol has to be hard coded into this module.
; If the TCAP were used, PEEP would not be practical.
; PEEPSECURE equate determines where the file is loaded.
; Author: Rob Friefeld, 4607 Colorado St., Long Beach, CA 213-434-7338
; Date: 23 Aug 1987 Version 1.0
;----------------------------------------------------------------------------
; Usage: Hands rest on the home row of keys. Left hand moves ahead,
; right hand moves back through file.
; ---
; Go To Marker | 0 |
; ---
; Read More Init Set Print
; (if memory full) Printer Marker (from mark)
; --- --- --- ---
; | R | | I | | O | | P |
; --- --- --- ---
; --- --- --- --- --- --- --- --- --- ---
; | A | | S | | D | | F | | G | | H | | J | | K | | L | | ; |
; --- --- --- --- --- --- --- --- --- ---
; End Scan Next Next Find Rpt Prev Prev R/Scan Top
; Screen Line Screen Find Screen Line Screen
;
;
; X - Exit <sp> - Hop 10 lines <cr> - Next Screen (F) </,?> - File Name
;----------------------------------------------------------------------------
;
; PEEP EQUATES
;
bell equ 07h
PEEPGO EQU NO ; Permit re-entering with a GO
IF PEEPGO
TEXTLOC EQU TPA+3 ; There will be a jump instruction at TPA
ELSE
TEXTLOC EQU TPA ; File will be read in to TPA
ENDIF
crtrows equ 24 ; 24 line screen
crtcols equ 80 ; 80 col screen
tabsize equ 8 ; Tab expansion size
scanspd equ 2000h ; Scroll rate - smaller number goes faster
scrlns equ crtrows-1 ; Don't change these
width equ crtcols-1
findsz equ 12 ; Maximum size of "find" string
;
; PRINITER INITIALIZATION STRING
; If you wish to send an initialization string with the I command, install
; it here. The last byte must have the MSB set.
init$str:
db cr+80h
;
; CRT PROTOCOL INSTALLATION SECTION
;
; The defaults are standard for Televideo, Wyse, et al.
;
; CODE TO CLEAR SCREEN, HOME CURSOR
clr_scr macro
db 1ah+80h ; Not used if CLSON is true.
endm
; CODE FOR CLEAR TO END OF LINE
cl_to_eol macro
db esc,'T'+80h
endm
; CODE FOR HOME CURSOR, DO NOT CLEAR SCREEN.
hom_crs macro
db 1eh+80h
endm
; CODE FOR INSERT LINE
ins_line macro
db esc,'E'+80h
endm
; CODE FOR RETURNING CURSOR TO START OF BOTTOM LINE OF CRT
ret_crs macro
db esc,'=',scrlns+32,0+32+80h
endm
; CODE FOR STANDOUT MODE. MUST NOT TAKE SCREEN SPACE. USE 0 IF NOT AVAILABLE.
dim_on macro
db esc,')'+80h
endm
; CODE FOR STANDEND.
dim_off macro
db esc,'('+80h
endm
;
; END OF CRT PROTOCOL INSTALLATION SECTION
;
;
; CRT ROUTINES USING ABOVE MACROS
;
; PRINT CR AND CLREOL
cr$clr: ld a,cr
call conout
clreol: call print
cl_to_eol
ret
; HOME CURSOR
homcrs: call print
hom_crs
ret
; INSERT BLANK LINE AT TOP OF SCREEN
inslin: call homcrs
call print
ins_line
jr clreol
; RETURN CURSOR TO LAST LINE OF SCREEN
retcrs: call print
ret_crs
ret
; CLEAR SCREEN
if [ not CLSON ]
cls: call print
clr_scr
ret
endif
;
; DISPLAY CONTROL CHARACTERS AS ^n
;
outchr:
cp 20h
jp nc,conout ; Not a control
; WE HAVE A CONTROL
push af ;save it
ld a,'^'
call conout
pop af ;restore it
add 40h ;make it printable
inc c ;bump tab expansion counter of "^" char
jp conout
; SWITCHING CONOUT
plcon: ld a,5 ; Switch to list output
plcon1: ld (conout+8),a ; Poke list byte at ld c,bdosf
ret
plcoff: ld a,2 ; Switch to con output
jr plcon1
; START STANDOUT MODE
stndout:
call print
dim_on
ret
; END STANDOUT MODE
stndend:
call print
dim_off
ret
;
; SLOW DOWN SCAN FUNCTIONS
;
wait: ld hl,scanspd
wait0: dec hl ; Down count to 0
ld a,h
or l
ret z
jr wait0
;
; WAIT FOR A CHAR THEN ERASE LINE
;
getchr:
call conin
push af
call cr$clr ; Erase it
pop af
ret
;
; UPCASE CHAR IN A
;
mkupper:
cp 'a'
ret c
cp 'z'+1
ret nc
and 5fh
ret
;
; MAIN PROGRAM
;
peep: call retsave ; Save zcpr return
; A jump instruction to peep is loaded at 100h. This permits using peep again
; with a GO, and prevents an object file read in at TPA from starting with a GO
if peepgo
ld a,0c3h ; Jump code
ld (tpa),a
ld hl,peep
ld (tpa+1),hl
endif
call getfil ; Read the file into memory
call cls ; Clear the screen
; RESTART ENTRY FOR READING IN MORE TEXT ON "MEMORY FULL" MESSAGE
resrt: ld hl,textloc ; Set Start Pointer to beginning of file
ld (srtptr),hl
ld (mrkptr),hl ; Set place marker to start of text
ld hl,(eofptr) ; Set End of Screen Pointer to beginning
ld b,scrlns ; of last screen
call pvline ; Back up one screen from end
djnz $-3
ld (eosptr),hl ; Now set pointer
;
; PRINT ONE SCREEN OF TEXT
;
prnscr: call homcrs
ld hl,(srtptr)
push hl ; If near end then print entire last screen
ld de,(eosptr) ; Compute position relative to last screen
xor a ; Reset carry flag
sbc hl,de
pop hl
jr z,prn1 ; We are at or before last screen so go ahead
jp nc,last ; We are past last screen so back up
prn1: ld b,scrlns ; Line count in B
prnlp1: call clreol
call prnline
djnz prnlp1 ; Print SCRLNS lines
ld (nxtptr),hl ; And set Next Pointer
call retcrs ; Cursor to prompt line
;
; COMMAND INPUT ROUTINE
;
command:
call getchr ; Get command
call case ; Scan list of commands
;
; COMMAND LIST: CHAR TO MATCH FOLLOWED BY ADDRESS
;
db 'A' ; Last screen of file
dw last
db 'D' ; Forward a line
dw down
db 'F' ; Next screen
dw next
db 'G' ; Find string
dw find
db 'H' ; Find string again
dw find0
db 'I' ; Init printer
dw init$prt
db 'J' ; Previous screen
dw prev
db 'K' ; Back a line
dw up
db 'L' ; Scan backward
dw back
db 'O' ; Set place marker
dw mark
db 'P' ; Print from marker
dw list
db 'R' ; Read in more text
dw read
db 'S' ; Scan forward
dw scan
db 'X' ; Exit to CPR
dw exit
db ';' ; Top of file
dw top
db '0' ; Go to marker
dw gomark0
db 20h ; <sp> jump ahead 10 lines
dw hop
db cr ; <cr> next screen
dw next
db '/'
dw what ; Show filename
db '?'
dw what
db 0 ; table delimiter
jr command ; Loop back on invalid input
;
; CASE - JUMP TABLE SCANNER
; FORMAT: CALL CASE ;CALL WITH VALUE TO MATCH IN A
; DB VAL1 ;FIRST VAL TO MATCH
; DW ADDR1 ;JUMP ADDRESS
; ...
; DB 0 ;END TABLE
; ELSE NEXT INSTUCTION EXECUTES IF NO MATCH
case:
ex (sp),hl ;hl -> next addr after call
ex af,af' ;save char
xor a
case1:
ex af,af' ;restore char
cp (hl) ;match?
inc hl ;set pointer to val's jump addr
jr z,case0 ;if match, jump
inc hl ;point to next val
inc hl
ex af,af' ;check for list terminator
cp (hl)
jr nz,case1 ;keep looking
inc hl ;no match, execute next instruction
casex: ex (sp),hl
ret
case0: ld e,(hl) ;load address
inc hl
ld d,(hl)
ex de,hl
jr casex ;go
;
; PRINT ONE LINE OF TEXT
; HL -> first char on entry, next char on exit
;
prnline:
push bc ; Preserve possible loop counter on entry
xor a
ld c,a ; Char counter for CRT width and tabs
prnl1:
ld a,(hl) ; Get char
cp eof ; At end?
jr z,prnl2 ; Can occur on text smaller than one screen
call prnl3 ; Print the character
cp lf ; Are we at end of line?
inc hl ; Bump pointer
jr nz,prnl1 ; No
prnl2: pop bc
ret ; Exit routine
; PRINT THE CHAR IF THE LINE IS NOT FULL
prnl3: cp cr ; Always print cr
jp z,conout
cp lf ; Always print lf
jp z,conout
cp tab
jr z,prnl5 ; Expand tab
prnl4: ld e,a ; Save char
inc c ; Bump char counter
ld a,width ; Exceeded line width?
cp c
ret c ; Yes, quit
ld a,e ; Restore char
jp outchr ; Send it out
; TAB EXPANSION
prnl5: ld a,c ; Compute char count MOD tabsize
sub tabsize
jr nc,$-2
neg ; Spaces to next tab in A
ld b,a ; Use as loop counter
ld a,' ' ; Print space
prnl51: call prnl4 ; Send it out if room and update char count
ret c ; Line overflow, quit
djnz prnl51
ret
;
; PRINT NEXT SCREEN
;
next: ld hl,(nxtptr)
ld a,eof ; Is there a next screen?
cp (hl)
jr z,hop0 ; No
ld (srtptr),hl ; Next screen is new start pointer
jr top0 ; Print the screen
;
; PRINT FIRST SCREEN
;
top: ld hl,textloc ; Start of text
ld (srtptr),hl ; To start pointer
top0: jp prnscr
;
; PRINT LAST SCREEN
;
last: ld hl,(eosptr) ; Top of last screen
ld (srtptr),hl ; Start there
jr top0 ; Print the screen
;
; PRINT NEXT LINE
;
down: ld b,1 ; Loop counter = 1 line
jr hop1 ; Print the line
;
; HOP FORWARD 10 LINES
;
hop: ld b,10 ; Loop counter = 10 lines
hop1: push bc ; Save it
call dnline ; Print next line
pop bc
djnz hop1
hop0: jp command
;
; SCROLL CONTINUOUSLY AHEAD UNTIL A KEY PRESSED
;
scan: call dnline ; Print next line
jr z,hop0 ; Routine returns 0 on EOF
call scstop ; Check for key press
call wait ; Pause a few msec
jr scan
;
; CHECK FOR BREAK
;
scstop: ld c,CONSTF
call bdos
or a
ret z ; No character, continue
pop af ; Dispose of return address
call getchr ; Erase screen echo and dispose of char
jr hop0 ; Back to command list
;
; PRINT NEXT LINE
;
dnline: ld hl,(nxtptr) ; Look at start of next line
ld a,eof ; Is it EOF?
cp (hl)
ret z ; There is no next line
call prnline ; Print the line
ld (nxtptr),hl ; Advance Next Pointer
ld hl,(srtptr) ; Advance Start Pointer
call nxline ; Find start of next line
ld (srtptr),hl
xor a ; A NZ flag on successful return
dec a
ret
;
; SEARCH FOR NEXT LINE OF TEXT
; HL -> starting point
;
nxline: ld a,(hl) ; Look at char
cp eof
ret z ; No more text
inc hl ; Bump pointer
cp lf
jr nz,nxline
ret ; Returns HL at character after LF
;
; PRINT PREVIOUS SCREEN
;
prev: ld hl,(srtptr) ; HL-> char at top of screen
ld b,scrlns ; Loop counter SCRLNS lines
prev0: call pvline ; Find start of previous line
djnz prev0
ld (srtptr),hl ; Set Start Pointer
jp prnscr ; Print the screen
;
; SEARCH FOR START OF PREVIOUS LINE OF TEXT
;
pvline: push bc ; Save possible loop counter on entry
ld b,2 ; We need the LF BEFORE the last one
prvlp: xor a ; Reset carry flag
ld de,textloc ; Are we already at beginning of file?
push hl
sbc hl,de
pop hl
jr c,prv0 ; Yes, so we are done
ld a,(hl) ; Look for last LF
cp lf
dec hl ; Decrement char pointer
jr nz,prvlp ; Haven't found LF yet
djnz prvlp ; Do it once more
inc hl ; Move HL pointer to character after LF
prv0: inc hl
pop bc
ret
;
; PRINT PREVIOUS LINE
;
up: call upline
up0: jp command
;
; SCAN BACKWARDS UNTIL KEY PRESS
;
back: call upline ; Move up a line
jr z,up0 ; Returns Z if no more lines
call scstop ; Check for break
call wait ; Give screen time to catch up
jr back
;
; MOVE DISPLAY UP A LINE
;
upline: ld de,textloc ; Are we already at start of text?
ld hl,(srtptr)
xor a
sbc hl,de
ret z ; Yes, quit and return Z
call inslin ; Home cursor and insert a blank line
ld hl,(srtptr) ; Back up a line
call pvline
ld (srtptr),hl ; Set pointer
call prnline ; Print the line
ld hl,(nxtptr) ; Set Next Pointer
call pvline
ld (nxtptr),hl
call retcrs ; Return cursor to bottom of screen
call cr$clr ; Erase dead line
xor a ; Return NZ
dec a
ret
;
; FIND A STRING
;
find:
call STNDOUT
call print ; Find string in following pages
db 'Find ->',' '+80h
ld de,finbuf ; Read string to find
ld c,RDBUFF
call bdos
call STNDEND
call cr$clr ; Erase it from screen
find0: ld ix,finbuf+1 ; IX points to string length
ld a,(ix) ; Move it to A
or a
jp z,command ; 0 length string ... abort
; UPCASE THE STRING FOR CASE INSENSITIVE SEARCH
ld b,a ; Length is loop counter
ld hl,findat ; First char of string
find01: ld a,(hl)
call mkupper
ld (hl),a
inc hl
djnz find01
; START SEARCH AT NEXT LINE
ld hl,(srtptr)
call nxline ; HL now -> next line
finlp0: ld iy,findat ; IY will be string pointer
finlp1: ld a,(hl) ; Get char from text
call mkupper ; Upcase it
cp eof
jr z,finot ; Hit end of file before match
cp (iy) ; First char to match
inc hl ; Bump text pointer
jr nz,finlp1 ; No match, keep moving through text
; AT THIS POINT, FIRST CHAR IS MATCHED
ld b,(ix) ; IX still has string length
dec b ; We have already found 1
jr z,findex ; Done if only 1 char to match
finlp2: inc iy ; Compare the next chars
ld a,(hl)
call mkupper
cp (iy)
jr nz,finlp0 ; No match ... start looking again
inc hl ; So far, so good
djnz finlp2 ; Match next chars
; THE STRING IS IN THE CURRENT LINE, MOVE IT TO TOP OF SCREEN
findex: call pvline ; Find previous line
call nxline ; Go to beginning of this line
ld (srtptr),hl
jp prnscr ; Show the screen
; NO LUCK ON FIND
finot: call cr$clr ; String not found - print message
call stndout
call print
db 'Not found',' '+80h
finot0: call stndend
jp command
; BUFFERS FOR FIND
finbuf: db FINDSZ ; String to match size
ds 1 ; Returned char count
findat: ds FINDSZ ; Buffer
;
; SHOW FILE NAME COMMAND
;
what: call stndout
ld hl,fcb1+1
call prfn ; ROUTINE ELSEWHERE IN RCP
jr finot0 ; Finish up display
;
; SET PLACE MARKER
;
mark:
ld hl,(srtptr) ; Top of screen pointer is marker pointer
ld (mrkptr),hl
call stndout
call print
db 'Marke','d'+80h
jr finot0 ; Finish up display
;
; GO TO MARKER
;
gomark0:
ld hl,(mrkptr)
ld (srtptr),hl
jp prnscr
;
; LIST MARKED PORTION OF FILE
;
list:
ld hl,lstmsg
call qprompt ; Are we serious? (And is printer on?)
jr z,list4 ; Abort
; Compute print block size
ld de,(mrkptr) ; Beginning of block
ld hl,(nxtptr) ; End of block
xor a
sbc hl,de ; Block size now in HL
jr c,lsterr ; If beginning at or after end then no go
jr z,lsterr
; Set up pointers
ex de,hl ; Block size in DE, start in HL
push de
pop bc ; Block size in HL
ld de,0 ; Count # lines in DE
ld a,lf
list1: cpir ; Count line feeds
jp po,list11 ; Loop expired
inc de
jr list1
list11:
call plcon ; Switch output to list
push de
pop bc ; Count to BC
inc bc ; Actually need 1 more
ld hl,(mrkptr) ; Print BC lines
list3: call prnline ; Output switched to list:
dec bc
ld a,b
or c
jr nz,list3
call plcoff ; Switch output to con:
lsterr: ld a,bell ; Beep on marker error or finish print
call conout
list4: call cr$clr
listx: jp command
lstmsg: db 'Print from MAR','K'+80h
;
; SEND INIT STRING TO PRINTER
;
init$prt:
ld hl,initmsg
call qprompt
jr z,list4
call plcon ; Switch conout to list
ld hl,init$str ; Send string
call printhl
call plcoff ; Switch conout to con
jr list4
initmsg:
db 'Init LST',':'+80h
;
; READ FILE INTO TPA UNTIL FULL OR EOF
;
getfil:
; SET UP TOP OF MEMORY POINTER
ld hl,(bdos+1) ; BDOS location
ld de,-905h ; CCP size + TPA + cr,lf,eof at end
add hl,de
ld (topmem),hl ; Store as top of memory
; REJECT BLANK FILE SPEC
getfil1:
call filcheck
CALL LOGUSR ; ROUTINE IS IN RCPSUBS.LIB
; OPEN THE FILE
call opensource
; RESET EOF FLAG (EOF NOT ENCOUNTERED)
xor a
ld (eoflag),a
; FILE READ LOOP
ld hl,textloc ; Start of text pointer
getlp1: ld (srtptr),hl ; Entry with hl -> input location
ex de,hl
ld hl,(topmem) ; Check memory full
xor a
sbc hl,de
jr c,toobig ; Yes
ld c,SETDMAF ; File read into current position
call bdos
ld de,fcb1
ld c,readf
call bdos
or a ; Check for end of file encountered
jr nz,geteof ; Yes
ld hl,(srtptr) ; Move pointer along one record worth
ld de,128
add hl,de
jr getlp1 ; Keep reading
geteof: ld (eoflag),a ; Set EOF flag
ld hl,(srtptr) ; Eof not returned until read after eof!
ld de,-128
add hl,de ; Back up a record
ld a,eof
ld bc,128
cpir ; Find the first eof
; SET UP EOF POINTER
getmrk:
dec hl
getmrk1:
ld (hl),cr ; Works better with CRLF at end of file
inc hl
ld (hl),lf
inc hl
ld (hl),eof
ld (eofptr),hl ; Store it for later
ret
; FILE HAS FILLED AVAILABLE MEMORY, PRINT WARNING
toobig: push de
call print
db bell,'Mem full',' '+80h
call getchr ; Wait for key press
pop hl
jr getmrk1
;
; READ MORE TEXT COMMAND
;
read: ld a,(eoflag) ; Has EOF been encountered?
or a
jr nz,rdprompt ; If so, send message
ld de,textloc ; Else, preserve some text and read more
ld hl,(eosptr)
ld a,eof
rdlp1: ldi ; Move last page to beginning of buffer
cp (hl) ; Check for end of file marker
jr nz,rdlp1 ; Loop until it is reached
dec de ; Back up over last CR,LF
dec de
ex de,hl ; HL now points to read data location
call getlp1 ; Fill memory with more of file
jr readx ; Re-initialize pointers and start
; PROMPT IF NO MORE TO READ
rdmsg: db 'Start ove','r'+80h
rdprompt:
ld hl,rdmsg
call qprompt
push af ; Save answer
call cr$clr
pop af
jp z,command ; No
; STARTING OVER, ZERO FCB POSITION POINTERS
read1:
CALL INITFCB1 ; IN RCPSUBS.LIB
call getfil1 ; Read the file
readx: jp resrt ; Restart PEEP
; EXAMINE COMMAND LINE FOR FILE SPEC
filcheck:
ld hl,fcb1+1
ld a,' '
cp (hl)
filcx: ret nz
call prfnf ; ROUNTINE IS ELSEWHERE IN RCP
jp exit ; NO FILE SPEC
; OPEN SOURCE FILE
opensource:
ld de,fcb1
ld c,openf
call bdos
inc a
jr filcx
; Enter with HL -> message. Return Z if answer = N.
qprompt:
call stndout
call printhl
call print
db ' ? (Y/n)',' '+80h
call stndend
call conin
cp 'N'
ret
;
; STORAGE
;
eoflag ds 1 ; EOF encountered flag
srtptr ds 2 ; Start Pointer -> top of screen
nxtptr ds 2 ; Next Pointer -> next screen
eosptr ds 2 ; End of Screen Pointer -> last screen
eofptr ds 2 ; End of File Pointer -> end of text
topmem ds 2 ; Top of memory pointer
mrkptr: dw textloc ; Place marker
; End RCP-PEEP.Z80
File Pointer -> end of text
topmem ds 2 ; Top of memory poin