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
/
CNTLH11.LBR
/
CNTLH11.ZZ0
/
CNTLH11.Z80
Wrap
Text File
|
2000-06-30
|
12KB
|
475 lines
;
; File: CNTLH.Z80
; Author: D. McCord
; Last Revised: 10 Sept 89
; Version: 1.1
;
; 1.1 Revision - added proper handling for an existing .BAK file and
; processing of orphan cr's (adds lf's)
;
; Purpose: Text filtering for captured telecomm conversation files. This
; program cleans up such "chat" files in several different ways:
; 1. resets the high-order bit of all characters in the input
; file, making it also usable to change a WS document-format
; file to plain ASCII (non-document).
; 2. Filters out any control-h (backspace) characters and
; processes these implied edits (deleting the immediately-
; previous character also).
; 3. adds linefeed characters as needed to "orphan" carriage
; returns.
;
; This software is not copyrighted.
;
; assembly command lines:
;
; a0:command>zas cntlh
; a0:command>zlink cntlh,z3lib/,syslib/
;
; Equates
;
CR EQU 13 ; carriage return
LF EQU 10 ; linefeed
Z3ENV EQU 0FE00h ; address of your ENV
VERSION EQU 11 ; 11 = 1.1
FCB1 EQU 5Ch ; 1st default fcb
BUFFER$SIZE EQU 16 ; 16k each input and output file buffers
PIPE$SIZE EQU 64 ; maximum active control h's in process
CONTROLH EQU 'H'-40h ; control h character
;
; SYSLIB declarations
;
extrn print,phlfdc,phl4hc,subhd,comphd
extrn getud,putud,logud,codend,fxi$open,fxo$open
extrn fxi$close,fxo$close,fx$get,fx$put,f$rename,f$delete
extrn pfn2,retud
;
; Z3LIB declarations
;
extrn z3init
;
; Z3 Utility header
;
beglow:
jp start
db 'Z3ENV'
db 1 ; external ENV
envadr:
dw z3env
start:
ld hl,(envadr)
call z3init ; init Z3 stuff
ld (oldstk),sp ; save old stack
ld sp,stack ; set internal stack
call banner ; print name of program and version
ld a,(fcb1+1) ; look at first char on command line
cp '/' ; help request?
jp z,help
cp ' ' ; no parameters?
jp z,help
;
; determine DU: of input file
;
call putud ; save current DU:
call retud ; get current DU: in BC
ld a,(fcb1+13) ; get parsed user area
ld c,a
ld a,(fcb1) ; and parsed disk
or a
jr z,start1 ; if no parsed disk, use what RETUD gave us
dec a ; adjust
ld b,a
start1:
call logud ; set it
;
; init fcb of input file
;
ld bc,12
ld de,iniocbfcb
ld hl,fcb1
ldir ; move default fcb to iniocb
call codend ; get end of code address
ld (inbuff$add),hl ; init buffer pointer in iniocb
;
; init fcb of output file
;
ld de,buffer$size*1024
add hl,de ; set output to start one
; buffer$size after input
ld (outbuff$add),hl ; init buffer pointer in outiocb
push hl ; save start of outbuf for use below
ld bc,12
ld de,outiocbfcb
ld hl,fcb1
ldir ; move default fcb to outiocb
ld bc,3
ld de,outiocbfcb+9
ld hl,tempext
ldir ; setup output file to have $$$ extension
;
; setup character processing pipe
;
pop hl ; get back start of outbuf
ld de,buffer$size*1024
add hl,de ; set pipe to start one
; buffer$size after output
ld (lowpipe$add),hl ; init pointer to lower boundary
ld (pipepointer),hl ; init pipe pointer
ld de,pipe$size ; size of pipe
add hl,de ; determine upper boundary of pipe
ld (highpipe$add),hl ; init pointer to high boundary
;
; Inform operator of memory usage
;
push hl
call print
db ' Highest memory address used is ',0
pop hl
call phl4hc
call print
db cr,lf,0
;
; setup of unitialized data complete. Now open files for use.
;
open$input:
ld de,iniocb ; prep for open
call fxi$open ; open input file
jp z,inopen$error ; did an error occur?
call print
db ' Opened input file: ',0
ld de,iniocbfcb+1
call pfn2
call print
db cr,lf,0
open$output:
ld de,outiocb ; prep for open
call fxo$open ; open output file
jp z,outopen$error ; any errors?
call print
db ' Output file opened successfully'
db cr,lf,0
;
; All files opened successfully... enter main loop
;
loop01:
call abort ; check for operator termination
call getinput ; get an input character, maybe set endflag
ld c,a ; save input character
ld a,(endflag) ; end of input?
or a
jr nz,loop10 ; if end, jump to closing stuff
ld a,c ; get input character back
res 7,a ; reset high bit
cp controlh ; is it a control-h?
jp nz,loop02 ; if not, go to loop02
ld hl,(ctlh$count) ; increment statistics
inc hl
ld (ctlh$count),hl
call takefrompipe ; yes it was a ^H, back up the pipe
jr loop01 ; go get next character
loop02:
call putinpipe ; put it in the pipe
jr loop01
loop10:
call flush ; flush whatever's in the pipe
call close ; close output file
call print
db ' Processing completed - ',0
ld hl,(ctlh$count)
call phlfdc
call print
db ' control-h''s processed',cr,lf,0
call rename ; rename original to .bak, .$$$ to original
jp exit1
;
; getinput reads the next character from the input file, sets endflag if
; the end is reached.
;
getinput:
ld de,iniocb ; point to input file
call fx$get ; read it into A
ret nz ; return, no error
ld a,0ffh
ld (endflag),a ; set end of file
ret
;
; push character in A into character pipe. If overflow, write an output
; character.
;
putinpipe:
push hl ; save registers
push de
push bc
ld c,a ; save character in C
ld hl,(pipepointer) ; get current top
ld de,(highpipe$add) ; get upper boundary
call comphd ; compare 'em
jr nz,nowrite ; if they are equal, write a character
;
; get a character out of the far end of the pipe and write it
;
writeone:
dec hl ; bump pipepointer down 1
ld (pipepointer),hl ; store new pipepointer
call write$hl ; go write character at (HL) to output
;
; if we needed to write, we did. now, shift pipe if needed.
;
nowrite:
ld hl,(pipepointer)
ld de,(lowpipe$add)
call subhd ; get length to shift pipe
ld a,h ; test if HL is zero...
or l
jr z,noshift ; might be first character in pipe
;
; we need to, so shift pipe one inward
;
push bc ; save character in C
push hl
pop bc ; length to shift in BC
ld de,(pipepointer); destination
ld hl,(pipepointer)
dec hl ; one less than destination
lddr ; block load with decrement [ (DE) <- (HL),
; decrement HL & DE, repeat (BC) times ]
pop bc ; get character back
noshift:
ld a,c
ld hl,(lowpipe$add)
ld (hl),a ; put character at front of pipe
ld hl,(pipepointer)
inc hl
ld (pipepointer),hl; increment pipepointer appropriately
pop bc ; restore registers
pop de
pop hl
ret
;
; takefrompipe empties the nearest character from the pipe
;
takefrompipe:
push hl ; save registers
push de
push bc
ld hl,(pipepointer)
ld de,(lowpipe$add)
call subhd
ld a,h ; test if HL is zero...
or l
jr z,notake ; must be empty pipe if Z, don't do anything
push hl ; get size of pipe
pop bc ; ...into BC
ld hl,(lowpipe$add)
inc hl ; DE already has (lowpipe$add) in it
ldir ; (DE) <- (HL), autoincrement (BC) times
ld hl,(pipepointer)
dec hl
ld (pipepointer),hl
notake:
pop bc
pop de
pop hl
ret
;
; some error when opening input file brings us here
;
inopen$error:
call print
db ' Error opening input file - probably no file with '
db 'that name - aborting',cr,lf,0
exit:
call getud
jp exit1
;
; some error when opening output file brings us here
;
outopen$error:
call print
db ' Error opening output file - aborting',cr,lf,0
jr exit
;
; write$hl writes the character at (HL) to the output file after control-h
; processing. here we fix orphan cr's.
;
write$hl:
ld a,(was$a$cr) ; was the previous character a cr?
or a
jr z,write$hl10 ; if not, skip
ld a,(hl)
cp lf ; is a linefeed following prev. cr?
jr z,write$hl05 ; if yes, reset things to normal
ld a,lf ; load A with linefeed
call write$hl20 ; go write it and come back
write$hl05:
ld a,0h ; make A zero
ld (was$a$cr),a ; reset flag
write$hl10:
ld a,(hl) ; get character to write
cp cr ; is a cr?
jr nz,write$hl20 ; if not, go finish
ld (was$a$cr),a ; set flag to cr (0dh), non-zero
write$hl20:
ld de,outiocb ; point to output
call fx$put ; write character in A to it
ret nz ; if no error, return, else fall to...
;
; an error writing to output brings us here
;
outwrite$error:
call print
db ' Error writing output file - aborting',cr,lf,0
jp exit
;
; print program name and version info
;
banner:
call print
db 'CNTLH, Version '
db version/10+'0','.',(version mod 10)+'0',cr,lf,0
ret
;
; Built-in help
;
help:
call print
db ' Text filtering and processing for captured "chat" files.'
db cr,lf
db 'Syntax:',cr,lf
db ' CNTLH <filespec>',cr,lf
db ' <filespec> may use DU:, DIR: as needed. Original <filespec>'
db cr,lf
db ' is renamed to .BAK, filtered file is named <filespec>.'
db cr,lf,0
exit1:
ld sp,(oldstk)
ret
;
; flush takes whatever is in the pipe and writes it to the output file
;
flush:
ld hl,(pipepointer)
ld de,(lowpipe$add)
call subhd
ld a,h
or l
ret z ; nothing in pipe if Z
push hl
pop bc ; BC now has # of items in pipe
ld hl,(pipepointer)
dec hl
floop:
call write$hl ; write (HL) to output file
dec bc
ld a,b
or c ; if NZ, more to do
ret z ; return if done
dec hl
jr floop ; go do more
;
; close all files
;
close:
ld de,iniocb
call fxi$close ; close input
ld de,outiocb
call fxo$close ; close output
ret nz ; return if no errors
call print
db ' Error closing output file',cr,lf,0
jp exit
;
; rename deletes any existing filename.BAK, then renames the original
; file to .BAK, new file to original's name
;
rename:
ld de,renamefcb ; set up to move input filename to renamefcb
ld hl,iniocbfcb
ld bc,12
ldir ; zap!
ld bc,3 ; setup renamed input file to have BAK
ld de,renamefcb+9 ; extension
ld hl,bakext
ldir ; zap!
ld de,renamefcb
call f$delete ; delete an existing .BAK file, if any
ld de,iniocbfcb ; point to old name
ld hl,renamefcb ; point at new name
call f$rename ; go rename input file to .BAK
ld de,renamefcb ; move original filename to renamefcb
ld hl,iniocbfcb
ld bc,12
ldir ; zap!
ld de,outiocbfcb ; point to old name
ld hl,renamefcb ; point to new name
call f$rename ; go rename output file to what original was
ret
;
; abort checks for operator abort
;
abort:
ld hl,abort1
push hl ; we return to abort1 after the jp (hl) below
ld hl,(1)
inc hl
inc hl
inc hl ; HL points to BIOS CONST
jp (hl)
abort1:
or a
ret z ; return if nothing waiting
call print
db cr,lf,'[User Abort]',cr,lf,0
;
; gobble the pending character which caused the abort
;
ld hl,exit
push hl ; we return to exit after the jp (hl) below
ld hl,(1)
ld de,6
add hl,de ; HL points to BIOS CONIN
jp (hl)
;
; initialized data area
;
tempext: db '$$$'
bakext: db 'BAK'
;
iniocb:
db buffer$size*8
db 0
dw 0
dw 0
inbuff$add:
dw 0
iniocbfcb:
ds 36
outiocb:
db buffer$size*8
db 0
dw 0
dw 0
outbuff$add:
dw 0
outiocbfcb:
ds 36
lowpipe$add:
dw 0
highpipe$add:
dw 0
pipepointer:
dw 0 ; where the NEXT character would go in the pipe
endflag:
db 0
ctlh$count:
dw 0
was$a$cr:
db 0 ; 0 = previous character was not a cr
;
; uninitialized data area
;
renamefcb:
ds 36
ds 64
stack:
oldstk: ds 2