1
0
Fork 0

Moved to new repository

This commit is contained in:
acn 2020-09-08 09:46:40 +02:00
commit 3809be0d36
25 changed files with 2878 additions and 0 deletions

102
README.md Normal file
View File

@ -0,0 +1,102 @@
# QTERM
QTERM is a terminal program which provides the following:
* Capture of text files
* Send text files to remote
* Xmodem / Modem7 / Ymodem protocol transfer
* Kermit protocol transfer
* VT100 emulation
* Split screen mode to separate typed and received text
* Script mechanism for automatic dialing and automation of other operations
* Transfer of text to printer
* Full user area support
(c) David Goodenough
It also has a huge advantage (at least for me, Anna) over KERMIT: It does not strip the 8th bit from received characters, so using a VT100 ANSI compatible terminal, you can just log into Telnet BBSes and see the full glory of ANSI/ASCII BBS graphics :)
QTERM uses patch files to adapt to the various CP/M implementations and hardware variations.
On this page, I provide several patches that can be used on "modern" CP/M systems like the RC2014 or SC126.
Unless otherwise noted, the patches were created by Anna Christina Naß and are based the IMSAI8080 patch by Udo Munk, the SIO initialization code by Steve Cousins and the XMODEM patch for RomWBW by Wayne Warthen.
## Common setting
The escape key is `^Y`, so to get help, just press `^Y` and `?` in sequence.
# The patches and binaries
## SIO/2 patch
This patch allows the use of QTERM on a RC2014 using a SIO/2 serial port.
At the moment, the patches provided here are tested on a RC2014 running RomWBW and using 2x SC104 serial ports (SIO/2).
The patch ```QT-RC82.Z``` uses the second serial port of the first SIO/2 port (base address 0x82) while ```QT-RC84.Z``` uses the first serial port of a second SIO/2 (0x84).
Direct download of binary:
* [QTERM82.COM](QTERM82.COM)
* [QTERM84.COM](QTERM84.COM)
The patch calls a RomWBW HBIOS routine to reset the SIO/2 after exiting, so I don't know what happens when using it without RomWBW.
## CP/M 3 patch
This patch uses CP/M 3 BDOS calls to send and receive data from the serial port, so it is independant of the hardware as long as the BIOS provides an interface for CP/M.
To use it, make sure the desired serial port is mapped to ```AUX:``` by using ```DEVICE.COM```.
In a standard RomWBW system, the second serial port is mapped automatically to ```AUX```, so no remapping is neccessary.
This makes using QTERM on an SC126 (Z180 ASCI serial port) possible, but also works on an RC2014 with a SIO/2 port.
Direct download:
* [QTERMC3.COM](QTERMC3.COM)
The patch file is ```QT-CPM3.Z```.
# Technical details
## Files
The file [QTERM43F.LBR](QTERM43F.LBR) is the original QTerm distribution file.
The directory [files/](files/) contains all files from the .LBR file. There, the documentation for QTerm, [QTERM.DOC](files/QTERM.DOC) can be found.
## Applying a patch
The patches are applied using ```ZSM``` and ```ZPATCH```, which are included in the QTerm distribution (```QTERM43F.LBR```).
To assemble the patch, use:
ZSM QT-xxxx.Z
This creates QT-xxxx.O, which then has to be applied to the .COM file:
ZPATCH QTERM43F QT-xxxx
Now QTERM43F.COM has the patch applied and should be ready to use.
## Details for the SIO/2 patch
When started, the patch initializes the serial port and it should "just work".
When exiting QTERM, the "uninitialization" routine is running, which calls the RomWBW function for "Reset with current settings".
I don't know (yet) what will happen on a RC2014 with the default ROM or with SCM.
If you have problems, you can change the patch file:
In the part:
.org 0x0273 ;exit subroutine
exit: jp uninit
change the `exit:` line into:
exit: ret
so the un-initialization routine won't be called.
You can then also remove the `uninit:` routine at the bottom of the code.
But then, other programs that will use the same serial port (e.g. KERMIT) won't run correctly until you reboot your system.

120
files/!README.1ST Normal file
View File

@ -0,0 +1,120 @@
QTERM v4.3f - Recompile of 43e including 2 files from QT43EFIX.LBR
QTERM V4.3e is dedicated to the memory of Irv Hoff - a programmer who was
a constant insipration while I was developing QTERM. Let us never forget
the work he did for the CP/M community.
Files included in QTERM43F.LBR: (QTERM43E.LBR)
!README.1YT You are
QTCHAT.DYC QTERM chat scripts documentation
*QTERM.CYM QTERM, unpatched
QTERM.DYC QTERM documentation
QTERM.FOR Quick description of what QTERM can do for you
QTERM.PYT Patch information for QTERM
*QT-PATCH.ZY Patch area source, to provide a basis to work with
WHATS.NYW Upgrade list of what's changed since V4.2g
(* files not included in this LBR)
Additional files here:
***************************************************************************
Adam files:
-QT-ADAM.4YF Notes on the Adam files here and using DDTZ
QTERM43F.CYM Qterm patched for the ADAM with an 80 col display
(use for replacement of the unpatched version)
QT42G-AD.PYT Adam specific patch for Qterm 4.2g (usable on 4.3f)
QT-ADAM.ZY Adam 80 Col patch for Televideo for ZSM/ZPATCH
QT-ADM40.ZY Adam 40 Col patch for ZSM/ZPATCH
-README.FYX Fix for 43E to 43F
QTZP.DYC Documentation on using ZSM and ZPATCH
ZSM.CYM Z80 assembler for .Z files
ZPATCH.CYM Hot Patcher for .Z/.O files
DDTZDDT.CYM DDTZ patched for DDT compatible commands
I apologise to David Goodenough for changing his -README and LBR listing
and hope he approves of the changes.. since this is for the ADAM CP/M LIB
on CompuServe and ADAM users. Rob Friedman
6/9/91
Sysop ADAM CP/M
CompuServe Computer Club
Note: files listed in the normal 43E not here are *'d. Also, This
set of files includes notes from the 43E-FIX Library as well as
some info. This file is set up as 43F.
**************************************************************************
Patch info for making QTERM work on your system is included in QTERM.PAT.
As provided, QTERM will work on a Televideo 803 (or a TPC-1), because
that's what I developed it on. Note that not all the patches are
necessary, but the more optional ones you get going, the more features
QTERM will have. QTERM.PAT also includes a reference to a "1K patch
overlay". I'm trying to collect as many of these as possible, so if you
can, try to get yours back to me, with a memo telling which computer it
works on, and which of the optional patches you have included.
The .?Y? files are made with the new LZH compression method, this typically
produces files 10 to 15 to 20 % smaller than CRUNCH. EXL.COM (in EXL.LBR)
is one tool that will decompress these, or CRLZH11.LBR is the original
.LBR for LZH compression.
For those that are interested, the name actually arose because in mid 1985
I needed a terminal program for my CP/M machine (A Televideo 803) and
put a quick 1/2K program together in under an hour. This program has been
growing ever since, but the name Q(uick) TERM(inal) program remains.
I give thanks to Dave Goodman, Tom Bopp, Larry Moore, Dave Presberg, Andy
Meyer, David Douthitt, Mitch Mitchell and Jim Bianchi for all their help
in debugging and beta testing QTERM, and to all the other people who have
sent in patches and suggestions. I'd never have got it anything like
working and as full featured without all your help.
Credit is also due the unknown author of the UNIX Kermit implementation
that I used for the basis of the Kermit code here, and to Steve Grandi
who wrote the Xmodem program in C that provided the basis for the Xmodem
code in QTERM.
If you need to get hold of me for any reason (need help with patches, or
a patch file to send my way), I can be reaced at:
UUCP: .....!wet!pallio!dg
Internet: dg%pallio.uucp@cs.sfsu.edu
GEnie: D.GOODENOUGH
Q-Link: Delta G
BBS's: DAVID GOODENOUGH on all of them
(617) 965-7046
(707) 539-1283
(415) 654-3798
(415) 755-2030
Or log into wet.UUCP at (415) 864-0954, and send me E-mail as dg once
you get set up.
David Goodenough (5-3-91)
A few notes:
Take a look in WHATS.NEW to see what has changed since V4.2g
QTERM V4.2 style patches will still work with QTERM V4.3e
VT100.TC got dropped since it's no longer needed - see WHATS.NEW for details
Since I've had several requests over the years to release the source, it
has been released. Modify it if you want, but please check back
with me before you release a version, and let me know what changes
you made, if they're useful I may put them into the next version.
As a side note to this, if you come across a version, and you are
not sure if it's been modified, check with me and I can give you
the correct CRCK values for the original V4.3e.


4
files/--READ.1ST Normal file
View File

@ -0,0 +1,4 @@
The files with the extension .?Y? are LZH Encoded. The program
UNCRLZH v2.0 or LT30 (or later version of these programs) are
required to decode them.


73
files/-QT-ADAM.43F Normal file
View File

@ -0,0 +1,73 @@
NOTES ON ADAM VERSION
Included here is the Qterm 4.3f for the Adam with an
80 col. display and an external modem. I have used
the codes for my TeleVideo 925 terminal, as they are
similar to the ADM3A that a lot of you use. To change
the screen codes is a simple matter. Use SPZ <SuperZap>
on a COPY of the program, and go to the 3rd page <hit
N twice>. You will see a grouping of ESCape codes <1B
28, 1B 29, etc>. Using the Qterm.Pat as a guide, plug
in your screen codes in those 8 positions <though you
should try what I have here.. as it does work on a LOT
of terminals. Exit with the ^Z and the Z command, and
it should work. This version will also use the
/QTERM.LBR for reading the script files, so that should
save a lot of space.
See the file QT43F-AD.COM as the replacement for the
unpatched QTERM.COM here. <If you are using this for a
non-adam computer, just use your own patch instead>
Also included is the QT42-AD.PAT for using DDT or DDTZ
to install your own Qterm. See the QTERM.PAT for
installing with DDT. For DDTZDDT <which is needed for
TDOS> use the I command, and the R command. DDTZDDT
is DDTZ patched to use DDT commands. It is included here.
Also, I've included the QT-ADAM.Z and the QT-ADM40.Z
ZSM/ZPATCH files. Be aware that the patches for 42G work
on 43F. Both are by QTERM author Dave Goodenough. The
QT-ADAM.Z is set up for a Televideo screen, so you will
have to edit it for the proper escape codes for your
own screen. QT-ADM40.Z is set up for a standard 40-col
under TDOS. See the QTZP.DOC for usage of ZSM and ZPATCH
Rob Friedman
Sysop ADAM CP/M
CompuServe Computer Club Forum
3-25-90
I can be reached nightly on Compuserve's Computer Club forum
with the User I.D. 76702,417
Additional files here:
***************************************************************************
Adam files:
-QT-ADAM.4YF Notes on the Adam files here and using DDTZ
QTERM43F.CYM Qterm patched for the ADAM with an 80 col display
(use for replacement of the unpatched version)
QT42G-AD.PYT Adam specific patch for Qterm 4.2g (usable on 4.3f)
QT-ADAM.ZY Adam 80 Col patch for Televideo for ZSM/ZPATCH
QT-ADM40.ZY Adam 40 Col patch for ZSM/ZPATCH
-README.FYX Fix for 43E to 43F
QTZP.DYC Documentation on using ZSM and ZPATCH
ZSM.CYM Z80 assembler for .Z files
ZPATCH.CYM Hot Patcher for .Z/.O files
DDTZDDT.CYM DDTZ patched for DDT compatible commands
I apologise to David Goodenough for changing his -README and LBR listing
and hope he approves of the changes.. since this is for the ADAM CP/M LIB
on CompuServe and ADAM users. Rob Friedman
6/9/91
Sysop ADAM CP/M
CompuServe Computer Club
Note: files listed in the normal 43E not here are *'d. Also, This
set of files includes notes from the 43E-FIX Library as well as
some info. This file is set up as 43F.
**************************************************************************


33
files/-README.FIX Normal file
View File

@ -0,0 +1,33 @@
[-READ.ME Mike Freeman 12-May-1991]
This file contains two patches, QT43EFX1.Z and QT43EFX2.Z, each of which
fixes a bug in QTERM.COM Version 43E (from QTERM43E.LBR) which caused sends
using True Ymodem protocol to fail. QT43EFX1.Z was suggested by QTERM's
author, David Goodenough and will, when patched over v43E of QTERM.COM,
correct the bug. MODEM7 batch transfers will no longer work. QT43EFX2.Z,
when patched over v43E of QTERM.COM will correct the same bug and allow
MODEM7 batch transfers to work. It uses a small fraction of QTERM's patch
area (from 0x04e0 to 0x04e7, inclusive). Thus, those who have QTERM patches
which extend into this region should use QT43EFX1.Z instead. Also included
in this archive is a corrected version of the appropriate QTERM source
module, SEND.Z. This is being done with the permission of QTERM's author,
David Goodenough. QTERM's version parameter "include-file", VERSION.I, is
also included with the revision level bumped to "F". This is in line with
Mr. Goodenough's wishes. Happy patching!
-- Mike Freeman K7UIJ --
[End of -READ.ME]
Addition by D. Goodenough, 5/22/91
QT43EFX2.Z as provided by Mike Freeman needed a little work: ZPATCH gets
confused if .org's in a ZSM source file go backwards. This means that I
had to put the low code (0x04e0) first. It'll work now.
Addition by R. Friedman, 6/9/91
I've renamed this little file -README.FIX and included it in a
new LBR called QTERM43F. I used the newer source modules from
Mike Freeman's FIX.LBR and the Qterm 43E source code from Dave
Goodenough's source LBR, and recompiled it to make 43F. Hence, no
need for the Fix.Z. So.. it is all better and running like a top!


BIN
files/DDTZDDT.COM Normal file

Binary file not shown.

253
files/QT-ADAM.Z Normal file
View File

@ -0,0 +1,253 @@
; QT-ADAM.Z - QTERM patch area for the Coleco ADAM
;
; Version 1.0
.var no 0 ; false value
.var yes 0xff ; true value
.var datap 0x44
.var statp 0x45
.var baudp 0x46
.var ctrlp 0x47
.var rxrdy 2
.var txrdy 1
.var break 0x3f
.var dtr 0x3d
.var norm 0x37
.org 0x0110 ; modem input status
modist: in a,(statp)
and rxrdy
ret
.org 0x0120 ; modem input
modin: in a,(datap)
ret
.org 0x0130 ; modem output status
modost: in a,(statp)
and txrdy
ret
.org 0x0140 ; modem output
modout: out (datap),a
ret
.org 0x0150
sbreak: ld a,break
out (ctrlp),a
ret
.org 0x0160
ebreak: ld a,norm
out (ctrlp),a
ret
.org 0x0170
dtroff: ld a,dtr
out (ctrlp),a
ret
.org 0x0180
dtron: ld a,norm
out (ctrlp),a
ret
.org 0x0190
setbd: jp finbd
; The Baud Rate Table has entries from 38400 baud down to 300 baud.
; There are 2 bytes per entry. The second byte determines if the entry is
; enabled or disabled (ffh=enabled; 00=disabled). The first byte is passed
; as the A value to the setbd subroutine.
.org 0x01a0
baudtb:
b38400: db 0,no ; 38400
b19200: db 0x3f,yes ; 19200
b9600: db 0x3e,yes ; 9600
b4800: db 0x3c,yes ; 4800
b2400: db 0x3a,yes ; 2400
b1200: db 0x37,yes ; 1200
b600: db 0x36,yes ; 600
b300: db 0x35,yes ; 300
.org 0x01b0
setmod: jp finmod
; Communication Mode Table.
.org 0x01c0 ; communication mode table
modetb:
n17: db 0x4a
n18: db 0x4e
n27: db 0xca
n28: db 0xce
e17: db 0x7a
e18: db 0x7e
e27: db 0xfa
e28: db 0xfe
o17: db 0x5a
o18: db 0x5e
o27: db 0xda
o28: db 0xde
.org 0x01cc
resrvd: db 0 ; reserved for later use
.org 0x01cd ; protocol transfer size
xfersz: db 8 ; number of K to read/write during file xfers
; Must be 1 / 2 / 4 / 8. Best left as 8 unless
; disk is verrrrry slow. Drop to smaller value
; if too many timeouts occur during "protocol"
; file transfers (xmodem or kermit).
.org 0x01ce ; processor speed
speed: db 4 ; cpu speed in Mhz;
.org 0x01cf ; escape character
escape: db '\e'
.org 0x01d0 ; signon message
signon: db 'Adam w/80col & RS232\0'
.org 0x01f0 ; clear screen
clrs: db 'z' & 0x1f, 0 ; clear screen string is Control-Z
.var scrout 0x0109 ; (a routine to print to CON: the
; character in C)
.var decout 0x010c ; (a routine to print to CON: a decimal value
; in HL. Is available for VT100 and the like.)
.org 0x0200 ; moveto routine
moveto: push hl ; save row,col
ld c,'\e' ; send escape
call scrout
ld c,'=' ; send =
call scrout
pop hl ; get row,col
ld de,0x2020 ; add offset
add hl,de
push hl ; and save
ld c,h ; send row+offset
call scrout
pop bc ; get col+offset
jp scrout ; send
; Terminal Capability Bits. The eight bits stand for each of the following
; strings. They count from 01h=bright to 80h=clear-to-end-of-screen.
.var b_brit 0b00000001 ; 0: bright -- NOT mandatory
.var b_dim 0b00000010 ; 1: dim -- NOT mandatory
.var b_ldel 0b00000100 ; 2: delete line -- important
.var b_lins 0b00001000 ; 3: insert line -- important
.var b_cdel 0b00010000 ; 4: delete character -- unused by QTERM
.var b_cins 0b00100000 ; 5: insert character -- unused by QTERM
.var b_ceol 0b01000000 ; 6: clear to end-of-line -- important
.var b_ceos 0b10000000 ; 7: clear to end-of-screen-- important
.org 0x022f ; terminal capability bit map
tcbits: db 0xff ; ff = support all bits
.org 0x0230
brites: db '\e(\0' ;bright
.org 0x0238
dims: db '\e)\0' ;dim
.org 0x0240
dlstr: db '\eR\0' ;delete line
.org 0x0248
ilstr: db '\eE\0' ;insert line
.org 0x0250
dcstr: db '\eW\0' ;Delete character
.org 0x0258
icstr: db '\eQ\0' ;Insert character
.org 0x0260
ceol: db '\eT\0' ;Clear to end of line
.org 0x0268
ceos: db '\eY\0' ;Clear to end of screen
; Entry and Exit hooks. These are provided to perform custom initialisation
; on startup and on exit from QTERM. They are invoked before any use is made
; of the screen or the port hardware.
.org 0x0270
entry: jp do_ent ; entry hook (270h .. 272h)
.org 0x0273
exit: jp do_exit ; exit hook (273h .. 275h)
.org 0x0276
user: ret ; user subroutine (276h .. 278h)
.org 0x0279
kbmap: ret ; keyboard map (279h .. 27bh)
.var ilprmt 0x027c ; entry to in line prompt subroutine.
; Extra patch area if needed. 280h .. 4ffh
.org 0x0280
finbd:
ld b,a
in a,(baudp)
ld c,a
in a,(baudp)
ld a,0x22
out (ctrlp),a
ld a,c
out (baudp),a
ld a,b
out (baudp),a
ld a,0x27
out (ctrlp),a
ret
finmod:
ld b,a
in a,(baudp)
in a,(baudp)
ld c,a
ld a,0x22
out (ctrlp),a
ld a,b
out (baudp),a
ld a,c
out (baudp),a
ld a,0x27
out (ctrlp),a
ret
do_ent:
ld e,0x19
ld c,2
call 5
in a,(baudp)
ld b,a
in a,(baudp)
ld a,b
or a
ret nz
ld a,(n18)
call setmod
ld a,(b2400)
call setbd
ret
do_exit:
ld e,0x19
ld c,2
call 5
ret


251
files/QT-ADM40.Z Normal file
View File

@ -0,0 +1,251 @@
; QT-ADM40.Z - QTERM patch for the Coleco ADAM, w/ 40 columns
.var no 0
.var yes ! no
.var datap 0x44 ; data port (in/out)
.var statp 0x45 ; status port (in)
.var contlp 0x47 ; control port (out)
.var baudrp 0x46 ; baud rate port (out)
.var inmsk 2 ; 8251 RxRDY
.var outmsk 1 ; 8251 TxRDY
.var chipset 0x37 ; 8251 RTS,ER,RxE,DTR,TxEN
.var chipoff 0x35 ; 8251 RTS,ER,RxE,TxEN (no dtr)
.var break chipset | 8 ; chipset OR send break
.var freeze 0x22
.var reset 0x27
; Misc variables
.var scrout 0x0109 ; output char in <C> (QTERM)
.var decout 0x010c ; output decimal value in <HL> (QTERM)
; Modem input status. 110h-11fh.
.org 0x0110
istat: in a,(statp)
and inmsk
ret
; Read modem character. 120h-12fh.
.org 0x0120
idata: in a,(datap)
ret
; Modem output status. 130h-13fh.
.org 0x0130
ostat: in a,(statp)
and outmsk
ret
; Write modem character. 140h-14fh.
.org 0x0140
odata: out (datap),a
ret
; Break. Start break 150h-15fh; end break 160-16fh.
.org 0x0150
brkon: ld a,break
out (contlp),a
ret
.org 0x0160
brkoff: ld a,chipset
out (contlp),a
ret
; Dtr. Drop dtr 170h-17fh; restore dtr 180h-18fh.
.org 0x0170
dtroff: ld a,chipoff
out (contlp),a
ret
.org 0x0180
dtron: ld a,chipset
out (contlp),a
ret
; Baud rate. Routine 190h-19fh; table 1a0h-1afh.
.org 0x0190
brset:
jp finbd
.org 0x01a0
brtbl:
b38400: db 0,no ; 38400
b19200: db 0x3f,yes ; 19200
b9600: db 0x3e,yes ; 9600
b4800: db 0x3c,yes ; 4800
b2400: db 0x3a,yes ; 2400
b1200: db 0x37,yes ; 1200
b600: db 0x36,yes ; 600
b300: db 0x35,yes ; 300
; Mode. Routine 1b0h-1bfh.
.org 0x01b0
modset: jp finmod
; Mode. Table 1c0h-1cbh. 8251 mode byte, sets stop bits, parity,
.org 0x01c0
modtbl:
n71: db 0b01001010 ; 7n1 ; this table must be
n81: db 0b01001110 ; 8n1 ; exactly 12 bytes long
n72: db 0b11001010 ; 7n2
n82: db 0b11001110 ; 8n2
e71: db 0b01111010 ; 7e1
e81: db 0b01111110 ; 8e1
e72: db 0b11111010 ; 7e2
e82: db 0b11111110 ; 8e2
o71: db 0b01011010 ; 7o1
o81: db 0b01011110 ; 8o1
o72: db 0b11011010 ; 7o2
o82: db 0b11011110 ; 8o2
; Miscellaneous one byte values.
.org 0x01cc
db 0 ; reserved for future use
.org 0x01cd
db 8 ; 1cdh - size of xfer buffer
.org 0x01ce
db 4 ; 1ceh - cpu clock speed
.org 0x01cf
db '\e' ; 1cfh - escape character
; Signon message. 1d0h-1efh
.org 0x01d0
db '\ex9\nColeco ADAM 40 Col W/-RS232\0'
; Clear screen string
.org 0x01f0
db 'z' & 0x1f, 0
; Moveto - move the cursor
.org 0x0200
moveto: push hl ; save row,col
ld c,'\e' ; send escape
call scrout
ld c,'=' ; send =
call scrout
pop hl ; get row,col
ld de,0x2020 ; add offset
add hl,de
push hl ; and save
ld c,h ; send row+offset
call scrout
pop bc ; get col+offset
jp scrout ; send
; tcbits - what terminal capabilities are present
.org 0x022f
db 0xff
.org 0x0230
db '\eq\0'
.org 0x0238
db '\ep\0'
.org 0x0240
db '\eM\0'
.org 0x0248
db '\eL\0'
.org 0x0250
db 0x97,0
.org 0x0258
db 0x94,0
.org 0x0260
db '\eK\0'
.org 0x0268
db '\eJ\0'
.org 0x0270
jp entry
.org 0x0273
jp exit
.org 0x0276
ret
.org 0x0279
ret
.org 0x0280
finbd:
ld b,a
in a,(baudrp)
ld c,a
in a,(baudrp)
ld a,freeze
out (contlp),a
ld a,c
out (baudrp),a
ld a,b
out (baudrp),a
ld a,reset
out (contlp),a
ret
finmod:
ld b,a
in a,(baudrp)
in a,(baudrp)
ld c,a
ld a,freeze
out (contlp),a
ld a,b
out (baudrp),a
ld a,c
out (baudrp),a
ld a,reset
out (contlp),a
ret
entry:
ld e,0x1a
ld c,2
call 5
in a,(baudrp)
ld b,a
in a,(baudrp)
ld a,b
or a
ret nz
ld a,0x4e
call 0x01b0
ld a,0x37
call 0x0190
ret
exit:
ld e,0x19
ld c,2
call 5
ld c,9
ld de,exitstr
jp 5
exitstr:
db 'z' & 0x1f, '\ey9$'


BIN
files/QT42G-AD.PAT Normal file

Binary file not shown.

650
files/QTCHAT.DOC Normal file
View File

@ -0,0 +1,650 @@
QTERM chat scripts
==================
A chat script is a means for getting QTERM to automatically send and
receive text, this can be used to auto-dial, connect to remote systems,
log in to them, and do whatever else is wanted. In addition, chat scripts
have a number of commands available, to do such things as protocol sends
and receives, transfer of text files, and many other things.
There are two ways of invoking a chat script. Firstly when QTERM is
executed from CP/M, a chat script and parameters can be provided there:
A>QTERM SCRIPT 1200
would be an example, alternatively the ^\ X command will prompt for a
filename, the response can be exactly the same:
Filename: SCRIPT 1200
will have the same effect.
QTERM will look in several places to try to find the script. The first
thing it will do is to take the filename as given (subject to the
current default drive/user, which may have been changed by the !n or
^\ N commands). If this is not successful, QTERM then searches the
drive/user area that was active when it first started. It should be
noted that if the entry subroutine includes BDOS calls to change either
the drive or user, then the values rememberd by QTERM will be those on
return from the entry subroutine. This provides a mechanism for setting
up a default script area, a place where QTERM will always try to find
scripts. In addition, if it can't find the script as a file in the
default script area, QTERM will look for a .LBR file /QTERM.LBR and
see if this library contains the script. The reason behind this is that
scripts tend be fairly small, and it is far more efficient to keep them
all together in one .LBR, since this saves disk space. It goes without
saying that QTERM cannot deal with squeezed or crunched scripts, they
must be saved in the .LBR as uncompressed ASCII text files.
When a chat script is running it can be terminated prematurely by typing
^X on the keyboard: this will return to normal terminal mode.
There are two types of lines in a chat script: send/expect lines, and
command lines. Command lines are always started with a '!' character,
any other character starts a send/expect line.
Looking first at send/expect lines, they can contain up to six fields,
and the first two must be provided, even if they are empty. An example
of such a line is:
-AT\r-OK\r\n-3-2-3-0-
In this example the '-' (first character) is the delimiter used to
separate fields. Any character can be used except for '!', but whatever
character is chosen cannot appear in the strings. Also note that
chosing a delimiter from the characters above 'z' in the ASCII character
set (i.e. '{', '|', '}', and '~') has a special effect, which is explained
below. Taking the fields in order they are SEND, EXPECT, TIME, TRIES,
SUCCESS, and FAIL. SEND is a string that is transmitted by QTERM, so in
the example above QTERM would transmit 'AT<carriage return>'. As was noted
above, delimiters above 'z' have a special effect: they cause the SEND
string to be written out slowly: there is a tenth of a second delay
after each character. EXPECT is a string that QTERM is looking for in
response to it's SEND string: so in the above example, QTERM would be
looking for the 'OK<carriage return><linefeed>' that a Hayes compatible
modem would respond with, when presented with 'AT<return>'.
The remining four fields are all decimal numbers, and can be omitted
as QTERM will provide default values. TIME is the number of seconds
to wait before assuming failure, if not given it defaults to 15. TRIES
is the number of times to retry on failure, so taking our first example,
TRIES is 2. If QTERM matched the EXPECT string on the first sending of
SEND, all is well, but on the first failure it would resend the SEND string
and look for the EXPECT string a second time. If it failed on this second
attempt, only then would it consider this line to have failed. SUCCESS
specifies the line number to transfer to in the chat script if it matched
the EXPECT string. The default for this is the line following the current
line. FAIL is the line to transfer to if the EXPECT string is not
matched. This can be a line in the chat script, or as shown above 0 is
allowed, which terminates the script immediately.
In the example above, the success and fail values are given as simple
line numbers, it is also possible to use labels in chat scripts, see !:
below for an explanation of how to define a label. If a label is being
used, the line might look like this:
-ATDT5551234\r-CONNECT-30--`connect-`fail-
In this case, the `connect and `fail are label usages, and cause transfer
to wherever the corresponding label is. Label useage is introduced with the
backquote character `, which must be followed by the label itself, with no
intervening white space: -` connect- will not work. Using an undefined label
does not directly cause an error, but the substitution of the non-existant
label will usually create a line that cannot be parsed, thus flagging the
error.
In another example, if the first line were:
-AT\r-OK\r\n--5-
since TIME is empty, it defaults to 15, but as TRIES is 5, this line
would try five times before giving up. Note also from this example
that there are two ways of causing QTERM to default a value: an empty
field (TIME) or end of the string (SUCCESS and FAIL). Note that the
closing '-' after the 5 for TRIES is necessary. On the basis of this,
the absulute minimum line is:
-send-expect-
This uses all four defaults: 15 seconds timeout, 1 try, success goes to
the next line, failure terminates the script. The idea behind these
defaults is that a collection of simple send/expect lines like the above
allow a "conversation" to be held with the remote system.
It is possible that either of SEND or EXPECT can be empty: an empty SEND
causes nothing to be sent, but the EXPECT must be matched to continue;
an empty EXPECT automatically matches. Note that if both are empty then
the chat script will terminate when it reaches that line, so a line like:
---
will serve as a means to terminate a chat script, returning to terminal
mode.
Command lines in chat scripts start with '!', and following the '!' is
a command letter. If input is needed (e.g. for a '!b' or '!s' line)
it should be placed after the command letter:
!b 1200 8n1 -5 30 500 +\x13\x11
As is shown in the above example, spaces are permitted after the command
letter, but not before.
Several of the ! commands correspond to ^\ commands available from terminal
mode: the !b above would set the baud rate etc., just like the corresponding
^\ B command would.
Commands available in this group are:
!, hangup
!. break
!B set baud rate
!E set local echo
!H set half duplex
!J toggle junking of control characters
!L set linefeed send for 'P'
!M set bit 7 mask
!N select new drive/user
!O toggle output to the printer
!V toggle VT100 emulation
!W toggle split window mode
!K program function key
!P print file to remote
!U invoke user function
!R protocol receive
!S protocol send
!C open catch file
!Y put catch file on hold
!Z close catch file
!X activate chat script
!Q exit QTERM
Note also that the toggles ('!E', '!H', '!J', '!L', '!M', '!O', '!V' and '!W')
behave a little differently. Since the state of these toggles is not defined
when a chat script starts, with one exception (!W) there are three ways of
invoking these. Using '!H' as an example:
!h
behaves as would an <escape> 'H' in normal operation, i.e. it toggles
the half duplex switch. However, if the following is given:
!h 1
the trailing '1' forces half duplex to be enabled, irrespective of
it's original state, and:
!h 0
guarantees to turn half duplex off. The other toggles work in the same
manner: a trailing '0' always disables, and a trailing '1' always
enables. !W is a little different, in that there are three possibilities:
window mode off, window mode on with big receive, and on with small. Also
allowing a pure toggle could have undefined results, since if window mode
were toggled on, there would be no indication what size was wanted. As
a result of this, there are three forms for the !W command in a script:
!w 0
forces window mode off,
!w b
forces it on with a big receive window, and:
!w s
forces it on, but with a small window. With all these toggles (!h etc. and
!w) the options above are guaranteed, using any other option letters will
have undefined results.
The 'X' command to activate a chat script can be used to chain scripts
together: when an 'X' is encountered the specified chat script is
invoked, however the current script is lost: it is overwritten by the
new one.
There are other commands that are not normally available are as follows:
!: - Define a label. Label usage was described above: the '`' character
introduces a label usage. NOTE that this is the BACKQUOTE character, not
the usual single quote character. To define a label, simply include a
line of the form:
!: connect
in the script. A few comments may make labels easier to use, firstly
they cannot be longer than seven characters, and where they are defined
there should be no trailing blanks. When a label is used, it is done by
means of a simple text substitution: after seeing a '`' character, QTERM
tries to match the following text with a label in the script, and it
stops at the first match. So if you have two labels one of which is a
prefix of the other, the results can be unpredictable. As a byproduct
of this, undefined labels do not generate an error (they just become
line zero), but the text substitution doesn't remove the label, so the
resulting line usually generates an error. In the event that a '`'
character is needed as part of a send or expect string, it can be
escaped by preceeding it with a $, so the line:
.send.exp$`ect.
will look for exp`ect, whereas:
.send.exp`ect.
will not work, it would try to look for and substitute the label 'ect'.
Since '$' is used to escape '`', it must also be used to escape itself,
so to match the string XXX$YYY, the script line would need to be:
.send.XXX$$YYY.
Labels should always be used to transfer control in a script: when a
script is being read in, comments and blank lines are stripped very
early in the process. This means that a given line in the script file
may have a different line number as far as QTERM is concerned. Labels
bypass this problem, so their usage is highly recommended.
The commands !@ and !# can be used for variable manipulation. Their
main purpose is to prevent infinite loops in chat scripts. In the
following example:
!: reset
.AT\r.OK\r\n.5.5.
.ATDT5551212\r.CONNECT.30..`connect.`reset.
!: connect
. ........
if the system being called is off line and not answering, QTERM will
loop here for ever. The !@ and !# provide the ability to keep count and
terminate the loop after some specified number of tries.
!@ var term +/- term
is the form of an @ line. var is a single letter variable (there are 26
available: a through z), and term is either a number or a variable. This
is very simplistic, in that two terms must be present: to set a variable
simply say something like:
!@ a 5 + 0
the operator can be either + or - and they act as you would expect. so:
!@ a a - 1
will subtract 1 from a, or:
!@ a a + b
will add b to a, etc. etc. Note that variables are recognised in either
upper or lower case:
!@ A a + B
would have exactly the same effect as the line above. Note that these are
single bytes, so there is some risk of working with values above 255.
!# tests variables: the general syntax is:
!# var operator term line
where var is a variable letter, term is a variable or a number, and the
operator can be '=' to test for equality, '#' to test for inequality, '<'
to check for less than and '>' to test for greater than. line is simply
the line number in the script to go to is the test succedes. Note that this
also provides a goto capability:
!# a = a `doit
will always go to doit, since a is always equal to itself.
All variables are initialized to zero when the first script in a series is
invoked, but values are retained when a !x command chains from one script
to another.
In addition to !@ and !# which set and test numeric variables, there are two
corresponding commands which set and test string variables. !$ and !% will
set and test strings. A line like:
!$ a This is a string
will put 'This is a string' into string variable a. Note that when a script
is started, or chained to with a !x command, the first nine parameters
become strings $1 through $9. These can be assigned to only if they are not
set when the script is invoked. The reason behind this is that if the
command line parameters are set with default values at the top of the script,
then missing parameters can be dealt with. An example might be a script
where the first parameter provides the baud rate, if it's invoked as:
SCRIPT 1200
then $1 will contain '1200', however if the following line appears in the
script:
!$ 1 2400
this will not disturb the 1200 in the case above, however if the script
is invoked with no parameters, then $1 will be empty initially, and the
assignment will put 2400 into it. String variables are used simply by
naming them, so to use $1 in this case, a line like:
!b $1 8n1
would set the baud rate as needed. In a similar manner, numeric variables
can be used simply by naming them:
-Send @a\r-expect-
would have the @a expanded to whatever the current value in variable a is.
As is done with labels, $a string use and @a variable use is handled by
simple text substitution, so a little care will make their use easier.
As was described above, '$' is used to escape '`' characters in strings,
it is also used to escape itself, and it can also be used to escape an
'@' character in a string. So, to actually place a '$' character in a
string say '$$', so that:
.send.exp$$ect.
would look for the string 'exp$ect'. There are only three things that
can follow a '$' sign: either '$' or '`' for escaping purposes,
and '1' through '9' and 'a' through 'z' for string substitution.
Placing any other character after a '$' will have an undefined result.
To test a string variable the !% line can be used: there are three forms
this line takes:
!% = .string1.string2. `label
!% _ .string1.string2. `label
!% # .string1.string2. `label
The first one will jump to label if the two strings are equal, so to test
a string, a line like:
!% = .$a.exit. `doexit
would jump to label doexit if string variable a contained 'exit'. The second
case is identical, except that the test is done ignoring case, so if _ were
used instead of = in the example above, 'exit', 'Exit', 'EXIT', and 'eXiT'
would all test as equal. The last case jumps to the label if the two strings
are different.
Two commands exist to manipulate the appearance of chat scripts:
!> This is a line of text\r\n
!> simply prints the text, after processing '\' escapes. Note that
leading and trailing spaces are ignored, so the above case would start
with the 'T' of 'This'. In order to start or end with a with a space,
\x20 can be used.
!&
This command is actually three different commands rolled into one:
!& o manipulates the echoing of characters received from the modem
while the script is running:
!& o 1
forces modem echo on,
!& o 0
forces it off, and:
!& o
simply switches state. In the same manner, !& m controls printout of
the 'Match: OK' messages that are printed when QTERM matches the expect
string in a send/expect line, and the 'Fail' and 'Retry' messages as
well. These two are initially on when a script starts, the third case
is !% l which controls printout of 'Looking for: ' messages. When this
option is turned on, these messages are printed when QTERM starts
looking for the expect string.
As a complement to !>, the !< command can be used to take keyboard input,
and make decisions based on what happens. This includes two subcommands
altogether:
!< - variable
The '-' causes QTERM to prompt for a line of input using CP/M's BDOS
buffered command. The line is then in the named variable, and can later
be tested with !% lines.
This allows for such things as multiple choice:
!> \r\nSelect system to call\r\n
!> 1. System 1 ..... \r\n
!> 2. System 2 ..... \r\n
!> 3. System 3 ..... \r\n
!: prompt
!> Enter 1, 2 or 3:\x20
!< - a
!% = .$a.1. `sys1
!% = .$a.2. `sys2
!% = .$s.3. `sys3
!> Error, invalid input\r\n
!# a = a `prompt
Where the first 4 lines print a menu, the next line defines a label. Then
comes a prompt, followed by an input command. After this, the line is
checked against 1, 2 and 3, and a jump is made to the appropriate label.
If there is no match an error message is printed, and the !# a = a line
is used as a goto, since a is always equal to a.
In a similar manner, '!< . a' will provide a "hot key" input - this reads
a single keystroke from the keyboard, and saves the numeric value of the
key pressed in the named variable, where it can be tested with a !# line.
The ![ command provides a similar function to the !< command, but it
works on text coming from the modem. There are several different
sub-commands available:
![ -
reads text from the modem. In this instance there are two ways that
reading can end:
![ - 15
would simply read text for 15 seconds. This numeric timeout must be
provided, but in addition up to four extra strings can be provided:
![ - 5 .string1.string2.string3.string4.
in which case input will terminate when 5 seconds have elapsed, or one
of the four strings is read. In this line, the '.' following the 5 is a
delimiter, this serves to separate the strings exactly like the delimiter
in a send / expect line. Not all four strings need to be there:
![ - 5 .OK.ERROR.
is acceptable, but the trailing delimiter must be there after the last
string. In addition to scanning for the four lines, QTERM keeps the last
sixty-four characters seen in a buffer, these can then be inspected with
![ =, ![ +, and ![ _ lines.
![ : 20
watches the data arriving from the modem, and only stops when 20 seconds
of silence are detected. This can prove useful when !C has opened a file,
and you want to capture the incoming text until a period of silence.
In addition, the last 64 characters are saved, just like with ![ - and
they can be tested with the same three commands.
The three commands that test are:
![ = string `label
![ + string `label
![ _ string `label
These are all very similar in that they all jump to label if the string is
found in the "last 64 character buffer", however the exact nature of the
test varies. Also note that during the search for the expect string in a
normal send/expect line, the last 64 characters seen are also saved in
this buffer, and can be tested using these commands.
![ = string `label
searches the saved text for the string, which in this case can include
\ escapes. If string occured anwhere in the last 64 characters, control
goes to label. ![ + looks exactly the same, but the difference is whether
the test is done on seven or eight bit data: ![ = just compares the least
significant seven bits, ignoring the parity bit, whereas ![ + compares
all eight. Note also that the strings provided in the ![ - line are only
checked in seven bit mode. ![ _ also does a seven bit test, but in addition
it ignores case.
Since spaces are used as the delimiter on a ![ = line, it is necessary to
escape a space: to match the 'CONNECT 1200' string that might be received
from a modem, it would be necessary to do something like this:
![ = CONNECT\x201200 `con1200
where the \x20 is an encoded space. Consult QTERM.DOC for a discourse on
\ escapes in strings.
Finally:
![ ^ a XY
allows a string to be extracted from the 64 character buffer and copied
into a variable. a is the variable name in this case (only letter variables
are allowed), and XY are two characters that delimit the string. If they
are left off, they both default to zero (NUL character, not '0' which is
ascii 0x30), which matches any white space. X and Y can be \ escapes, and
note that \0 (i.e. a NUL) has the special effect mentioned. The exact
algorithm used to determine the text to be saved is:
1. Scan backwards from the end of the buffer (last characters received), till
a 'Y' is seen, then skip over any adjacent duplicates. Then scan back to the
next 'X', and take all characters between, not including the X or Y. So if
the tail of the buffer holds:
..... YYY XXThis is a stringYY hello X world X
the string that would be extracted is 'This is a string'. As always, a little
care and attention will help in chosing the correct way of getting a buffer
of 64 characters, and then some care in chosing the delimiters will ensure
the correct string is extracted into the variable.
The !~ command has been added for rudimentary file manipulation
during chat script operation. Four options exist:
!~ - file
will erase a file. Note that QTERM will silently ignore this command
if the file doesn't exist, or if it is write protected. As with all
filenames, a drive/user can be given:
!~ - d15:foo.bar
does like you'd expect.
!~ = newname = oldname
renames a file: note that if a drive/user is given on oldname, it will
be ignored: newname completely defines where the action will happen.
This will fail silently if newname already exists, or if old name doesn't,
or if oldname does exist but is write protected.
!~ + newname = oldname
copies a file. In this case a file can be copied to a different
drive / user, so if needed a drive / user spec should be attached to
oldname. This will fail silently if newname exists or if oldname doesn't.
These can be used to good effect when QTERM is sending text files as
messages to a BBS, after sending the file with a !P command, a !~ - will
erase it, or files can be erased after uploading, or a file might be
renamed after a batch download.
The last options don't change any files, but allow QTERM to conditionally
alter script execution depending on whether a file exists or not:
!~ Y filename line
!~ N filename line
This simply transfers control to line if filename exists. As always line can
be a label. If needed, filename can be a wildcard:
!~ Y A17:*.TXT `sendtxt
will go to label sendtxt only if there are any files on A17: matching the
*.TXT wildcard.
Two commands exist to allow strings to be saved during a script run, for
possible reloading during a later script run. The commands are:
!( r a 7
to read, and:
!( w b 3
to write. The r or w specifies read or write, following this is a single
letter that tells which string variable to read or write, and finally a
file position to use. QTERM uses the file /QTERM.STR in the default chat
drive/user area as the file that holds thee saved strings, the last parameter
specifies which record will be used. '0' uses the first record, and up to a
certain point, the file can be made as large as is needed: ten records
would provide '0' through '9', however the file can be made larger to hold
records 'A' through 'Z', or even 'a' through 'z' if needed. To create a
record with a given index, simply use the !( w command to write to it,
so if a file containing just ten empty is desired, the following ten line
script would create it:
!( a 0
!( a 1
!( a 2
!( a 3
!( a 4
!( a 5
!( a 6
!( a 7
!( a 8
!( a 9
This would set all the saved strings to empty, since string a will be
initially empty when the script starts. Note that while QTERM can add
records to an already existing file, the file must exist in order for
QTERM to access it. Several means exist for creating it:
A>SAVE 0 /QTERM.STR
under CP/M 2.2 will work, or using a text editor to create an empty
file, or even using the <ESCAPE> C command under QTERM to open a catch
file, and then immediately closing it with an <ESCAPE> Z command.
This function can be used to good effect when a script is used to
call a BBS, and you want to use a catch file to capture new messages.
If the BBS can't do this for you, then the ![ - and ![ : lines can
be used to catch the high message number in the 64 character buffer,
then the ![ ^ line can be used to pluck it out into a string, from
where it can be saved in the file. Then next time the script is
running, it can read the previous high message number back into a
string, and use it in a line line:
.read new $a\r..
to send it back to the BBS as the first message number required.
As a final note, any other command character is silently ignored,
this can be put to use to introduce comments. At this stage, !; is
not in use, and this is the official comment entry, it is guaranteed
that !; will never be used for a command line function in a QTERM
chat script. Further, when a script is being read in by QTERM, blank
lines and lines starting with !; are discarded fairly early. This has
two side effects, it means that comments can be used freely without
using up any of the 4K space available for saving scripts, but it
also means that line numbers should not be used in scripts as the
targets of jumps (i.e. the last two fields of a send / expect line)
since the target line number may well change. Use labels instead.


457
files/QTERM.DOC Normal file
View File

@ -0,0 +1,457 @@
QTERM
=====
If QTERM is invoked with no arguments, it starts up, and after signing
on, you are immediately connected with the modem. If an argument file
is provided, then it is assumed to be a chat script (see 'X'), and the
chat script is immediately activated. With this file as with all others
that can be entered, user numbers can be included in the filespecification:
B3:CHAT.XYZ will look for the file in user area 3 on drive B: Either the
drive or the user alone can be given: A:FOO.FOO and 7:BAZ.BAR are both
acceptable, anything not given defaults to the current values. On
completion of the chat script, command passes to normal connected
operation. All special actions are initiated by typing the escape
character, what happens next is determined by the next character typed.
Note that while all letters here are shown in upper case, lower case works
equally well: so <escape> b also activates the code to set the baud rate.
As delivered, the escape character is set to control backslash, however it
can be changed by patching QTERM: see QTERM.PAT for details, so to print
help type '^\' '?', etc. In all the descriptions that follow, references to
the escape character refer to this (i.e. '^\' and not the ESC key - '^[')
At several places in QTERM it is necessary to be able to encode control
characters and other "non-printing" characters in a visible mode, to
do this a special escape mechanism is used. To start one of these escape
sequences a backslash '\' is used, followed by one or more characters to
define the desired character. The following are provided: '\r' carriage
return (0x0d), '\n' linefeed (0x0a), '\t' tab (0x09), '\b' backspace
(0x08), '\e' escape (0x1b), '\k' break, and '\d' delay. '\k' causes a
break to be sent if this string is subsequently sent to the modem (as in
a chat script), and '\d' causes a delay of one second when used in a
chat script. In addition a backslash can be followed by up to three
octal digits to send the character with that representation: so '\177'
would send a delete, and '\003' or '\3' would send a control C; this can
also be done for hexadecimal representations: in this case '\x' is the
leadin, and it is followed by up to two hexadecimal digits: so '\x7f'
would again send a delete, and '\xd' could be used in place of '\r' to
send a carriage return. The rule for determining how many characters are
used when scanning an octal or hex number is as follows: octal has a
maximum of three, hex a maximum of two (not including the \ or \x
respectively): use at most that many characters, or stop early if an
inappropriate character is encountered.
Retyping the escape character (i.e. typing it twice) sends a single copy
of the escape character to the remote system.
Other characters and what they do are:
? - Print help - QTERM provides a brief synopsis of the available commands.
. - Send a break - If QTERM has been patched to do it, this will transmit
a 3/10th second break.
, - Hang up modem - This is done by deactivating DTR for a short time, which
causes most modems to hang up. Again QTERM has to be patched to do this.
Alternatively, if your modem doesn't respond to DTR, it is possible to
have QTERM transmit a string to cause a hangup: for example the:
'<delay> +++ <delay> ATH0'
as required by a HAYES compatible modem. See the patch documentatin for
details.
B - Change baud rate and mode - This will first prompt you, your response
must look like the following:
nnnn
nnnn mmm
* mmm
nnnn mmm -3 20 500 +AB
where 'nnnn' is a number specifying the baud rate. Up to eight options
are available: 300 600 1200 2400 4800 9600 19200 and 38400, although not
all of these may be enabled. 'mmm' is a byte format specifier made up
of three characters. The first must be '7 ' or '8' to specify the number
of data bits; the second 'E', 'O', or 'N' for even, odd, or no parity;
and the third '1' or '2' for the number of stop bits. The * in the third
example is used as a place holder when the mode is to be changed, but
not the baud rate. So, for example: '1200' would change to 1200 baud
leaving the mode as is; '300 8n1' would switch to 300 baud, and select
8 data bits, no parity, and 1 stop bit; and '* 7E2' would change the
format to 7 data bits, even parity, and 2 stop bits, while leaving the
baud rate alone. Two other options can be added to this line: the '-'
option is a way of specifying three delays that can be set, and the '+'
option can set the characters used to enable and disable character
transmission from the remote system.
If both the '-' and '+' options are used, then the '+' must follow the '-'
(as above in the example).
The '+' option changes the characters that QTERM will use for flow
control. When a system is sending text to QTERM, which is being saved
in a file, QTERM needs to be able to stop the remote system from
sending when it writes to disk. Most of the time ^S and ^Q are
recognised, but for the few systems that use other characters, this
option allows them to be changed. Following the '+' should be exactly two
characters ('A' and 'B' in the example), the first becomes the "stop"
character, and the second the "start" character. These characters can
be '\' escapes if needed.
If the '-' option is used, it should be followed by up to three numbers.
The first is a delay in seconds after the "stop" character is sent.
Since some systems take longer to respond to the "stop" character than
others, the delay time can be changed. QTERM starts up with one second
of delay, but by specifying -3 or -6 or whatever, this delay can be
changed. -0 is possible, but not recommended unless your remote system
responds instantly. The second number is a delay in milliseconds between
character sends in 'P' transmits (see below). Note that this time is
the time between the start of each character transmission, rather than
a time between the end of one and the start of the next. So if this
delay was set to 15 milliseconds at 1200 BPS, where each character
takes about 8 milliseconds to transmit, there would be 8 milliseconds
spent sending the character, and then 7 milliseconds of idle time: the
total being 15. As an addition to this, if a non-numeric character
precedes the number (as in .20), "echo-check" pacing will be used for
printable characters. What that means is that when a printable character
is sent, i.e. between space: ' ' (20H) and tilde '~' (07EH) inclusive,
the next will be sent either when the delay runs out, or when a copy of
the sent character is seen returning from the remote system. This can be
useful when the delay would normally need fine tuning for maximum
performance, by using "echo-check" pacing the throughput becomes close
to optimal. The third number is the delay at the end of a line in 'P'
transmission: this is also a count of milliseconds, and this delay occurs
after transmission of a carriage return. As with the character delay, a
non-numeric character can precede the number, this is a "new-line prompt"
character that will terminate the wait early. So if 'P' transmission
is being used to upload text to a BBS that prompts for each line with
a string like ' 23:', then by giving the number as :300, that would
provide a 300 millisecond delay, but when a ':' was seen after sending
a new line, transmission would begin again immediately. So, in that
case, a string like:
-2 .20 :300
would get close to optimal throughput for 'P' transmission. Note that it
is possible to selectively set these values: if a '*' is entered as a place
holder then the delay value for that position will not be changed, i.e.
-* 20
would leave the stop delay alone, set the character delay to 20
milliseconds, and leave the end of line delay alone.
Although QTERM always claims to have made the changes to the baud rate
and communication mode, they will only happen if the necessary patches
are applied. Note that for the second character of the mode specifier,
both lower and upper case are accepted.
C - Open an input catch file - This prompts for a filename, and then opens
that file for output. All subsequent data received up the line from the
modem port will be written to the file.
Y - Put catch file on hold - This keeps the output file open, but temporarily
disables transfer of data. A second <escape> 'Y' will re-enable capture
of data.
Z - Close a catch file - This closes the output file, and disables data
capture until another catch file is opened.
D - Display local directory - This prompts for a single CP/M wildcard
file specificier, and then lists all files that match. Note that an
empty filename is assumed to be '*.*'. When the files are being printed,
QTERM will stop after each screenful (23 lines), hitting return will
print a single line, any other key will print a full page.
E - Toggle remote echo - This toggles echo to the remote system. This will
most likely be used when the remote system is a terminal or another
computer running a terminal program. It causes all characters received
from the modem to be re-transmitted back to the modem, creating the
impression that the far end is running in half duplex mode. Caution
should be used to make sure that you don't set up an 'infinite loop'
where the remote system is also echoing: because then the first
character that returns will be sent out again by QTERM, to be returned
by the remote, to be sent out again by QTERM .....
H - Toggle half duplex - This simply causes all keyboard input to be
echoed to the screen.
I - Print status information - This prints a summary of QTERM's current
state, showing the state of the various toggles, delays, what the
current drive and user are, etc.
J - Junk control characters - This causes QTERM to discard all control
characters received from the remote system that are not considered
important. Important control characters are: carriage return (0x0d);
linefeed (0x0a); backspace (0x08); and tab (0x09). In this mode, if
the remote system is sending characters with the MSB set, and bit 7
masking is not enabled (see 'M'), then all characters with bit 7 set
will also be discarded.
L - Toggle linefeed transmit for 'P' - When 'P' is used to send a file
to a remote system, it normally transmits all useful characters: i.e.
all printable ascii characters from ' ' to '~', tabs, and carriage
returns. This toggle ensables the transmission of line feeds, for
cases where it is needed. Note that when QTERM starts, this is off,
i.e. the default is not to transmit linefeeds.
M - Toggle bit 7 mask - When this is enabled, all characters received from
the remote have the most significant bit stripped. This may be useful
when QTERM is running in 8n1 mode, but the remote is transmitting in
7e1 mode - the top bit will contain parity, and this strips it off.
N - New default drive and user. This will prompt, and allow entry of a drive
user specification (i.e 'A7:' or 'B14:' or 'C:' or '9:'), this then
becomes the default for all file operations. Note that it is possible
to user the CP/M BDOS functions to set drive and user during the entry
hook code (see QTERM.PAT), so if the entry code selects D2:, and all
scripts are on D2: just entering QTERM SCRIPT at the CCP prompt would
find SCRIPT on D2:. Also note that after the entry hook code, QTERM makes
a note of where it is (i.e. in the above case D2: ) When a chat script
is invoked with the 'X' command, QTERM will first look at the drive
given, or on the default if no drive is specified. If that fails, then
QTERM will take a second look in the drive/user area as saved after the
entry hook. The rationale behind this is to place all chat scripts in
one place: these can subsequently move the default around (see the '!'
section of chat scripts), or 'N' commands can be used to move around.
However it does not matter what the current default drive/user is, QTERM
can always find the scripts by lookng back at the area it noted.
O - Toggle output to the printer - This simply toggles a switch that causes
all data received to be transmitted to the printer.
P - Print a file to remote - This prompts for a filename, and then transmits
that file to the remote system. While this transfer is in progress, the
keyboard is ignored, except that typing control 'X' will cancel the
transfer. Note that the 'L' command may come in useful with this command,
check how your remote system behaves.
T - Type a local file - This also prompts for a filename, and then prints that
file to the screen locally. While this is in progress, a control 'X' will
cancel it, Output can also be paused by typing control 'S', which will
halt until another character is typed. If this character is control 'X'
the output will be aborted, any other continues the printout.
U - Invoke user function - QTERM can be patched to include a user defined
function, this is the command to call it. This subroutine can be used for
any purpose required, for example keyboard mapping can be enabled, or some
special screen sequence can be printed, or whatever is needed. The patch
documentation provides information on how to patch this into QTERM, and
also explains how it is possible to prompt for information from within
this subroutine.
V - Toggle VT100 emulation - This function requires the following screen
abilities be specified for full operation (see QTERM.PAT for details):
clear to end of line, clear to end of screen, insert and delete line.
If only the first two are available (partial screen clears), then all
functions will work, except for reverse index (scroll backwards), and
scrolling regions. Note that the VT100 emulation is as complete as it
can be, however the alternate character sets are not recognised, and all
the display attribute commands are mapped to the single highlight mode
encoded in the patch area. Also note that QTERM does not check if a
screen capability is present, so if insert and delete line are missing,
QTERM will still try to emulate a scrolling region, probably causing
somewhat confusing output. As a final comment, (especially for people
without interrupt drivers), try to set the delays after the special
functions as big as you can: to do some operations (like odd things
with scrolling regions, and some of the partial screen clears) require
sending a collection of screen codes that'd probably make you lose your
lunch if you saw them. In particular, ^[[1J - clear from start of screen
to current position will take forever if you're at the bottom of the
screen or towards the right margin. Caveat Emptor!
W - Toggle split window mode - This requires either the insert line and
delete line screen abilities be specified, or it can also function with
just clear to end of line. (see QTERM.PAT for details). It puts QTERM
into a mode where send and receive text are shown in two separate windows.
This can be useful when using QTERM to communicate with another communication
program running in terminal mode, because it keeps what is typed on the
keyboard separate from what is received from the remote system. After
selecting window mode, QTERM prompts for window size: there are two options,
'b' or 's' (big or small). This refers to the receive window: when small, the
screen is split exactly in half: 11 lines for both send and receive. Big mode
makes the receive window 18 lines deep, the send window is only 4 lines: this
will be useful when far more text is being received than is being sent.
R - Receive a file using protocol - This option prompts for a mode and
optional receive file information. Xmodem and Kermit are both supported.
Respond with 'k' to go into Kermit receive, or 'x' to go into Xmodem
receive. Normally files are received on the current default drive,
however by entering a drive or a user (e.g. 'k b7:') files will be
received in the specified location. In addition, if Xmodem is not
being used in batch mode, a filename can be given here. Non-batch
Xmodem has a default filename, this can be used to override it. Note
that a space MUST be present between the k or the x and the
filename / drive specification for proper operation. While the transfer
is in progress, a control 'X' will abort it.
Options can be given by adding them right after the 'k' or 'x' protocol
specifier, before the space that precedes the filename. Some options are
applicable to both protocols:
'a': Normally QTERM is silent, however if this option is given, QTERM
will alert on termination of transfer by ringing the terminal bell.
'q': QTERM normally keeps the screen active, displaying the status of
a transfer, however by using one or two 'q' characters, the amount of
output can be reduced. A single 'q' just turns off the packet count
and the data transfer count (how many K have been received), whereas
two 'q's turn off everything.
Xmodem only has one receive option:
'c': Xmodem starts by trying CRC mode, and will switch automatically
to Checksum if CRC fails. However some very naive implementations will
work better if QTERM starts in checksum mode, this option causes QTERM
to do so. Note that information for Xmodem 1K, Ymodem, Modem7 batch etc.
need not be given for a receive (in fact QTERM ignores any such options
on an Xmodem receive), instead QTERM determines what the transfer type is
by inspecting the data received from the remote, and it then acts as
appropriate.
Kermit receive recognises the following options:
'b': binary file transfer - by default QTERM treats files as text files
when doing a Kermit transfer, this causes files to received as binary,
useful when transferring an executable program.
'8': try full 8 bit data transfer - normally QTERM tries to negotiate the
use of 8th bit prefixing with the remote, however if both ends can handle
8 bit transfers, this considerably improves throughput.
'x': use extended packet size - if not given QTERM will use the standard
maximum packet size (about 90 characters), this allows the packet size to
increase to about 1K, thereby providing a performance boost.
'g': request files from a server - a typical use might be:
kg a3:*.txt
This will request a server to send all files that match *.txt, and they will
be received on a3:
S - Send a file using protocol - This also prompts, the response should be
'k filelist ....' or 'x filelist ....' where 'filelist ....' is a list
of CP/M filespecifiers: wildcards are permitted. Single filespecifiers
are separated from one another by spaces, and as with receive, there must
be a space between the 'x' / 'k' / options, and the first filespecifier.
As with receive, a control 'X' will abort the transfer.
Options are given right after the 'x' or 'k', the following are available:
'a' and 'q' work for both Xmodem and Kermit, and in the same manner as in
a receive.
Xmodem takes these options:
'b': use Xmodem batch (AKA Modem7 batch mode)
'y': use Ymodem batch mode
'k': use 1K packets.
So 'xyk a12:*.com' would send all .COM files on drive A:, user area 12,
using Ymodem batch mode and 1K packets. To match names to various
combinations: xyk will give true Ymodem (known sometimes as ymodem batch),
xk gives Xmodem 1K (sometimes incorrectly called ymodem), xy gives Ymodem
batch, but forces 128 byte packets, xbk will use Modem7 batch mode, but with
1K packets.
For Kermit, the options available are:
'b': Kermit usually sends files in text mode, i.e. 0x1a is taken as
end of file. If you want to transfer a binary file, specify the mode as
'kb filename.com'.
'2': when Kermit is sending data, it will ask for type 3 block checks
during the Send-Init negotiation. Unfortunately, the only fall back from
a type 3 request is to type 1 (i.e. if the receiver does not agree to use
type 3). This means that if QTERM is trying to send to a system that can
do type 1 and type 2, but not type 3 checks, it'll be limited to type 1.
However, if the '2' option is used, Kermit will attempt to negotiate type 2
block checks, thus allowing it to communicate with a remote using type 2
checks. It should be noted that this is only useful when sending: when
receiving Kermit data, QTERM will see the remote's Send-Init request first,
and will agree to whatever the remote asks for.
'8': this will cause QTERM to send data with the high bit set as is, on the
assumption that the data channel can transfer full 8 bit data. Use this only
if the remote Kermit can also handle 8 bit transfers. If the '8' option is
not given QTERM will try to negotiate high bit prefixing to send 8 bit data.
'x': allow extended packets, this is the same as for receive.
The last two send options are used to issue server requests:
'f': finish the server,
'l': finish server operations and logoff.
These two do not need filename, and they should not be used with any other
options, i.e. the response to the 'Mode?' prompt from QTERM should simply
be 'kf' or 'kl'.
K - Program a function key - This prompts for a key number and a string
to be loaded under that key. The first character entered may be an
's' to specify the string should be sent slowly. Normally function
key strings are transmitted at full speed, however the 's' creates
a tenth second delay between characters. Following the 's' (if given)
or as the first character if no 's' is given, must be a digit between
'0' and '9': this specifies the key number. Finally comes the string
that will be loaded under the key. Maximum string length is 14
characters, longer strings are truncated. Backslash escape sequences
are permitted, see the description in the section on chat scripts
for a full explanation of what is available. As a few examples:
s2hello\r
would program function key 2 to send 'hello <cr>' slowly, and:
3userid = 17\e
would program function key 3 to send 'userid = 17 <esc>' at full speed.
0-9 - Send function key string - After <escape> 'K' has been used to load
strings into the function keys, <escape> '0' etc. will activate the
function key, causing the string it contains to be sent. Note that if a
function key string contains the QTERM <escape> character, it will not
invoke the function in question. So loading \x1c,\x1cq
(<escape> , <escape> q) under a key cannot be used to provide a
"hangup and exit" from QTERM.
X - Activate a chat script - This prompts for a filename, then it reads
the file, and does the chat script given. Following the filename can be
parameters for use in the script, much as SUBMIT.COM allows parameters
to be passed to a .SUB file. If a chat script is given to QTERM as a
command line argument when it is invoked from the CCP, then the following
command line arguments will become the parameters to the chat script.
A chat script is a means for getting QTERM to automatically send and
receive text, this can be used to auto-dial, connect to remote systems,
log in to them, and do whatever else is wanted. A companion file
QTCHAT.DOC explains the workings of chat scripts.


13
files/QTERM.FOR Normal file
View File

@ -0,0 +1,13 @@
QTERM is a terminal program which provides the following:
Capture of text files
Send text files to remote
Xmodem / Modem7 / Ymodem protocol transfer
Kermit protocol transfer
VT100 emulation
Split screen mode to separate typed and received text
Script mechanism for automatic dialing and automation of
other operations
Transfer of text to printer
Full user area support


333
files/QTERM.PAT Normal file
View File

@ -0,0 +1,333 @@
Patching QTERM for your system.
This explains the patches in QTERM, and can be used to patch QTERM
directly (it is written as if being used in that manner), however
it also provides an explanation of the subroutines that would be
needed if a QT-?????.Z patch source were to be written, based on the
template QT-PATCH.Z provided.
The first thing to do is to back QTERM up, and then invoke DDT, SID, ZSID,
Z8E, or whatever your local patch utility is, in the following way:
A>DDT QTERM.COM
DDT (etc.) will read in QTERM, and then prompt. The following is a list of
patch areas where QTERM should be changed to reflect your system. Some of
these are mandatory (i.e. QTERM won't work without them), whereas others
can be changed to null subroutines or empty data without preventing QTERM
from working, it just won't have all the features available.
1. Modem input status: 0110 - 011F
QTERM calls here to check modem input status. Return with the zero flag
set if no character is available, or with the zero flag clear if a char
is available. Generally this can be an input from the usart / sio / dart
status port followed by an 'and'.
2. Read modem character: 0120 - 012F
This gets a character from the modem input port once the input status has
decided it's there. Return the character in the a register. Generally this
can be an input from the usart / sio / dart data port.
3. Modem output status: 0130 - 013F
Check if the modem output port can accept another character. Return with the
zero flag set if the output port can't receive a character, or with the zero
flag clear if the output port is ready. Generally this can be an input from
the usart / sio / dart status port followed by an 'and'.
4. Write modem character: 0140 - 014F
Send the character in the a register to the modem output port. This will only
be called after the output status routine has returned a non-zero status.
Generally this can be an output to the usart / sio / dart data port.
These first four patches are all necessary for QTERM to work. The next few
are not necessary, but they will be useful.
5. Start break: 0150 - 015F
End break: 0160 - 016F
The start break subroutine at 0150 should initiate a break condition on
the modem output line, and 0160 should clear the break condition. If these
are to be omitted, then just put return (C9) instructions at 0150 and 0160.
Note that the Start Break routine need not check that the transmit buffer
is empty, since there will always be a 1/10th. second delay after the last
character is sent, before calling this subroutine.
6. Drop DTR: 0170 - 017F
Restore DTR: 0180 - 018F
The drop DTR subroutine causes DTR to be made inactive, and restore DTR
returns DTR to an active state. If your modem does not respond to DTR, but
can be made to hang up by sending a string, then put a return (C9) at 0170.
Use the space from 0171 to 018F to contain the string, with the following
notes: at 0171 should be the length of the string, to transmit a break,
use an 0FFH byte, to cause a two second delay use an 0FEH byte. Hence the
following could be used to hang up a Hayes compatible:
0C FE FE 2B 2B 2B FE FE 41 54 48 30 0D
0C - length: 12 bytes follow
FE - delay (twice)
2B - '+' sent three times
FE - delay (twice)
41 54 48 30 0D - ATH0 <return>
If neither DTR nor a string is to be used, then place a return (C9) at
0180 and 0171, and a nop (00) at 0170. The string is used only if a C9
is found at 0170, so by placing the C9 at 0171 the string print is
inhibited.
7. Baud rate setting: 0190 - 019F
Baud rate table: 01A0 - 01AF
These two patch areas work together to allow QTERM to change the baud rate
of the modem port. The baud rate table holds pairs of bytes for setting the
baud rate to eight different values: 38400, 19200, 9600, 4800, 2400, 1200,
600 and 300, in that order. In these pairs, the first byte will be passed
to the subroutine at 0190, and the second byte is used to enable that baud
rate: an 0FFH in the second byte enables the rate, and a zero disables.
So if your system only went up to 9600, (using a value of 1 to get 9600)
the first six bytes in the table would be:
00 00 no value for 38400: disable by the 00
00 00 no value for 19200: disable by the 00
01 FF 01 is the value for 9600: enable by the FF
In all cases of enabled baud rates, the subroutine at 0190 gets the
appropriate value in the a register and should use it to set the baud rate.
If this is to be omitted, then just put a return (C9) instruction at 0190,
and fill the table from 01A0 to 01AF with 00's.
8. Communication mode setting: 01B0 - 01BF
Communication mode table: 01C0 - 01CB
These two patch areas work together to allow QTERM to change the
communications format of the modem port. The mode table holds bytes for
setting 12 different formats, selecting number of data bits (7 or 8)
parity (odd, even, or none) and number of stop bits (1 or 2). In order
the 12 values are for 7n1, 8n1, 7n2, 8n2, 7e1, 8e1, 7e2, 8e2, 7o1, 8o1,
7o2, and 8o2. The subroutine at 01B0 gets one of these values in the a
register and should use it to set the communications mode. If this is to
be omitted, then just put a return (C9) instruction at 01B0.
9. Reserved for later use: 01CC
This byte is reserved for later expansion, and should not be used.
10. Protocol transfer size: 01CD
During protocol transfers, disk reads and writes take place every 8K. This
is normally possible without causing a timeout, and reduces disk access to
a minimum. However if your disk is slow, you can drop this to 4, 2 or even
1 to reduce the size of transfer, and hence prevent timeouts.
11. Processor speed: 01CE
This is the speed in Mhz that your Z80 runs at: 4, 6 or whatever. For
a 2.5Mhz cpu, use 3.
12. Escape character: 01CF
All special functions of QTERM are activated by the use of escape sequences.
At 01CF is the byte used for the escape character (the default is ^\). Any
byte can be used, but a little used value is best selected, also using a
printable character (' ' thru '~') may have undesirable results. Note that to
transmit the escape value itself, just type it twice.
These previous three are necessary.
13. Signon message: 01D0 - 01EF
This must be a string that identifies your system / terminal. It must be
present, and is printed when QTERM first starts. It should be composed of
printable characters, and terminated by a zero byte.
14. Clear screen: 01F0 - 01FF
This must be a string that clears the terminal screen, and leaves the
cursor in the top left hand corner. This should also be terminated by a
zero byte.
15. Moveto: 0200 - 022E
QTERM requires the ability to move the cursor around the screen. It calls
this subroutine with the required coordinates in hl: where h is the row,
and l the column to move to. The top left hand corner of the screen is 0,0;
and the bottom right corner is 23,79. This subroutine will have to do
terminal output: at 0109H is a routine that prints a character in the c
register, and at 010CH is a routine to print a decimal number in hl (mainly
for the use of vt100 and vt220 compatibles). Note that the above two
subroutines may destroy all registers, so appropriate action should be
taken if needed.
16. Teminal capability bit map: 022F
This byte contains one bit set for each of the following terminal
capabilities:
bit 0: (01H) end highlight mode
bit 1: (02H) start highlight mode
bit 2: (04H) delete line
bit 3: (08H) insert line
bit 4: (10H) delete character
bit 5: (20H) insert character
bit 6: (40H) clear to end of line
bit 7: (80H) clear to end of screen
17. Terminal capability strings: 0230 - 026F
In this area are eight strings, each of which can be at most seven characters
long. They are the strings to be printed to perform the terminal capabilities
mentioned above. Each one of them should be terminated by a zero byte. Hence
at 0230 is the string for end highlight, at 0238 is the string for start
highlight, etc., with 0268 being the string for clear to end of screen.
Programs that use these will check the terminal capability bitmap at 022F
before using them, to determine if they are available.
18. Entry subroutine: 0270 - 0272
Upon entry to QTERM, this subroutine will be called. If it is not needed
then a return instruction (0C9H) should be placed at 0270, otherwise there
is enough space to put in a jump to code that is to be executed when QTERM
starts. This can be used for several purposes: if custom initialisation is
needed to enable communications, or select a particular baud rate, or
whatever, this can be done here. In addition, if all chat scripts and disk
access is to be done on a specific drive, then by using the CP/M BDOS
functions to set drive (and set user if desired), QTERM can be made to
automatically be in the correct place to find scripts. This is explained
in QTCHAT.DOC
19. Exit subroutine: 0273 - 0275
After an <Escape> Q has been issued to exit QTERM, this subroutine will
be called immediately before exiting back to CP/M. As with the entry
subroutine, if not needed, a return instruction (0C9H) should be placed at
0273H, otherwise any termination code can be added.
20. User subroutine: 0276 - 0278
The <Escape> U command from terminal mode, and !U in chat scripts cause
a call to this location. This can be used to do whatever is wanted,
enabling special features, selecting different ports for communication
whatever. Note that at 027C is a jump to ilprmt: an inline prompt
subroutine. If the user subroutine is invoked from terminal mode, then
calling this subroutine will prompt, and read a line of text into the
buffer at 0080, it is terminated with a zero byte. If invoked with a !u
from a chat script, then the remaining text on the line will be moved
to the buffer, creating the impression it had just come from the
keyboard. Following the call to ilprmt should be a prompt message,
terminated by a null byte. NOTE: if no prompt is required, then two zero
bytes are needed.
call ilprmt
db 'Prompt message\0'
call ilprmt
db 0,0
are examples. This subroutine should only be called once per invocation of
the user subroutine, since a second call when used in a chat script may
have unpredictable results.
21. Keyboard map: 0279 - 027B
All keystrokes read from the keyboard are passed through the keyboard map
subroutine, so that actions like mapping arrow keys to VT100 escape
sequences can be performed. When this is called, the value of the key
just pressed is in the a register, and the b register is zero. On exit
the value in b determines what action is to be taken. If b is zero, then
the value passed on to QTERM is whatever vaule is in the a register, so
that placing a 'RET' instruction at 0279H causes no effect at all. If b
contains 1, then QTERM will assume that the keyboard map routine "swallowed"
the character, and instead of passing it on, QTERM immediately polls the
keyboard for another character. If b contains 2, then QTERM takes this
to mean that the keyboard map routine wishes to output another character
without further input from the keyboard. In this case, QTERM passes the
current value in a along, then calls straight into the keyboard map routine
again, without polling the keyboard. To provide some examples:
A. Assume that your system has some function keys that send the following
strings:
^A 1, ^A 2, ^A 3, ^A 4,
and you wish to map those keys to ^H ^J ^K and ^L, with ^A followed by
any other character being mapped to just the second character. The
keyboard map would start by looking for ^A, if it saw any other character,
it would return it unchanged with b equal to zero. On getting a ^A, it
wants to see the next character from the keyboard without sending anything
on, so it sets b to 1, and is at liberty to return any value in a. QTERM
immediately gets the next key value, and passes it to the keyboard map. If
it's one of 1, 2, 3, or 4, then the keyboard map sets a to ^H, ^J, ^K, or
^L as appropriate, and returns with zero in b, otherwise it simply returns
the value in a, again with b holding zero.
B. Assume you want to do the reverse mapping: ^H ^J ^K and ^L to ^A 1, ^A 2
etc. Here, the keyboard map is looking for ^H ^J etc., passing all other
characters unchanged, with b zero. Assume it sees a ^H, which is to be
mapped to ^A 1. It sets b to 2 (to say that there is more to come) and
returns a ^A in the a register. QTERM will pass the ^A on, and then call
te map again, at which point it would return 1, with b set to zero this
time: this is because there are no more characters to be sent.
C. In the most complex case, assume that ^E followed by any other character
is to be mapped to two copies of the character, followed by ^A. In this
case, all characters save ^E are passed unchanged, with zero in b. When a
^E is detected, b is returned with 1, to say that the ^E was swallowed,
and when the next character is passed to the map, it should be saved, but
also returned, however b should be 2. QTERM will process the character,
then since b was 2, it will call the map subroutine. The map routine
returns the character again, with b set to 2 a second time. On the third
call to the map routine, it should return the terminating ^A, with b equal
to zero to say all the work is done.
22. ILPRMT subroutine jump: 027C - 027E
These three bytes are reserved to hold a jump to the in line prompt
subroutine, and should not be overwritten by the patch.
23. Patch area: 0280 - 04FF
Since the area provided for the above patches is limited, it may be necessary
to use more space. The block of memory from 0280 to 04FF is set aside for
custom patches, this can be used if the individual spaces are not big enough.
Once all the patches have been made, exit the patch program (usually by
typing ^C), and finish up by saving a new copy of QTERM:
A>SAVE 69 QTERMNEW.COM
In addition, the patch area only can be saved as follows:
A>SAVE 4 QTERMPAT.XXX
Which will create a 1K file containing all the patches needed to make this
particular version of QTERM work. By doing this, when a new release of QTERM
needs to be patched, all that is necessary is to read in the new unpatched
version with DDT or whatever, then overlay the patch area. This is typically
done by typing:
IQTERMPAT.XXX
to DDT, SID, ZSID etc. to set up the command line to read QTERMPAT.XXX, then
follow this with a:
R
to read it. This should overlay the saved patch area on the new version,
hence doing all the patches at once. Then exit DDT with ^C, and do the
first save shown above to save the new working version.
NOTE: With V4.2 and later, the patch area has grown yet again, so again the
overlaying of earlier patches will not work. By and large, overlaying patches
in this manner is not recommended, it is far easier to work with the patch
sources available, applying them with ZSM and ZPATCH as needed. However, the
V4.3 patch area is the same as the V4.2 patch area, so no changes are needed
to convert from V4.2 to V4.3


BIN
files/QTERM43F.COM Normal file

Binary file not shown.

16
files/QTZP.DOC Normal file
View File

@ -0,0 +1,16 @@
These two files: ZSM and ZPATCH are needed to apply QTERM patches (such
as QT-ALB.ZY etc.). To apply a patch to QTERM enter:
A>ZSM QT-ALB.Z
which will create QT-ALB.O. Then enter:
A>ZPATCH QTERM.COM QT-ALB.O
which applies the patch to QTERM. This can be used with other programs,
WANDERER, ROGUE, and several programs in the UUCP21B.LBR library will
need this done to them.
To decompress the two programs in here, EXL.LBR or CRLZH11.LBR will both
provide tools to do the job.


74
files/WHATS.NEW Normal file
View File

@ -0,0 +1,74 @@
What's new in QTERM for V4.3 - in no particular order:
^\ P sends have some more sophisticated flow control, for both individual
character transmission, and line breaks, based on echo of characters
back from the remote system.
When QTERM is in local echo mode <cr> characters receivced are expanded to
<cr> / <lf> pairs, and if half duplex or split screen is invoked as well
as local echo, locally typed <cr>'s also get expanded in the same manner.
This makes local echo a bit more useful since it means that neither the
local user nor someone talking remotely will need to add a <lf> after
their <cr>'s - QTERM does it as needed.
'q' option to make protocol transfers quiet
'c' option to get Xmodem receive to start in Checksum mode
Major overhaul of Kermit - the bugs in the 4.2g implementation have been
fixed, and several extensions added: extended block checks, long packets,
and server operation.
!% m and !% o have become !& m and !& o, and a third option has been added:
!& l to turn on and off "Looking for" logging. m and o are initially on,
and l is off: !& l 0 forces it off, !& m 1 forces it on, and !& o switches
to the other state.
!@ and !# (numeric variable manipulation) have gained two counterparts:
!$ and !% to set and test string variables (these include the parameters
of the script)
It is now possible to "type" through a waiting script: while a script is
waiting for a match in a normal /send/expect/ line, or a ![ - or ![ :
line, characters typed at the keyboard are sent to the modem, and two
^\ escapes are recognised: ^\ . to send a break, and ^\ , to hang up.
When expect string is matching (or not) in a .send.expect. line,
the last 64 characters received from the modem are kept in the buffer
used by the ![ - command, so that tests can be made later with ![ =
(etc.) commands, this buffer is also used by the ![ : "wait for silence"
command.
!< - and !< . (read buffered from keyboard and read single character from
keyboard) now take a variable name (i.e. a single letter). For !< -, the
letter is the target string variable that will receive the input text,
for !< . the numeric variable receives the value of the character typed.
This means that !< = and !< , are no longer needed: !% and !# will permit
testing keyboard input.
Strings and variables can be used in lines: giving $a anywhere in a script
line gets substituted by string variable a (and $1 becomes the first
parameter to the script), similarly @a anywhere on a script line gets
replaced by the numeric value of variable a.
The VT100 emulation code has been almost totally re-written, and does a
far better job than the 4.2 code. There are limits - double size characters
can't be done, nor can alternate character sets, and some operations will
take a long time (i.e. set up lots of delay). However, the special VT100.TC
termcap file is no longer needed, since a standard VT100 termcap will
suffice. However read QTERM.DOC for comments on how it behaves when certain
screen codes are missing
!~ ? to test the existance of a file has been split into two commands:
!~ Y filename `label jumps if the file does exist, and !~ N filename `label
jumps if the file doesn't exist - The second is most useful in a script
when you only want to do something if a file exists (e.g. upload it, ^\ P
it or whatever), that way !~ N allows a jump over the code if the file is
not there.
The ^\ D code has stopped using the BIOS to read the directory, instead
it uses BDOS calls 17 and 18. The bad news is that the statistics line
is not shown (maybe something will be put in for the next version), however
the good news is that it will work under CP/M 3.0, and also this change
has reduced QTERM's memory requirement by about 5 to 6 K.


BIN
files/ZPATCH.COM Normal file

Binary file not shown.

BIN
files/ZSM.COM Normal file

Binary file not shown.

155
qt-cpm3.z Normal file
View File

@ -0,0 +1,155 @@
; QT-CPM3.Z - QTerm patch for CP/M 3 AUX: device
;
; August 2020, Anna Christina Nass
;
.var BDOS 5
.var RDY 0xF0
.org 0x0110 ; modem input status
; ZERO flag if no char is available
modist: ld c, 7
call BDOS
and RDY
ret
.org 0x0120 ; modem input
modin: ld c, 3
call BDOS
ret
.org 0x0130 ; modem output status
; ZERO flag if output is busy
modost: ld c, 8
call BDOS
and RDY
ret
.org 0x0140 ; modem output
modout: ld e, a
ld c, 4
call BDOS
ret
.org 0x0150 ; start break
sbreak: ret
.org 0x0160 ; stop break
ebreak: ret
.org 0x0170 ; drop DTR
dtroff: ret
db 0x0c ;length of modem hang up string
db 0xfe,0xfe ;two delays
db 0x2b,0x2b,0x2b ;+++
db 0xfe,0xfe ;two delays
db 'ATH0',0x0d ;ATH0 <return>
.org 0x0180 ; restore DTR
dtron: ret
.org 0x0190 ; set baud rate
setbd: ret
.org 0x01a0 ; baud rate table
baudtb:
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
.org 0x01b0 ; set communication mode
setmod: ret
.org 0x01c0 ; communication mode table
modetb:
db 0,0,0,0,0,0,0,0
db 0,0,0,0
.org 0x01cc
resrvd: db 0 ; reserved for later use
.org 0x01cd ; protocol transfer size
xfersz: db 8
.org 0x01ce ; processor speed
speed: db 8 ; cpu speed in Mhz;
.org 0x01cf ; escape character
escape: db 0x19 ; 0x19: ^Y
.org 0x01d0 ; signon message
signon: db 'CP/M 3 by @acn128\0'
.org 0x01f0 ; clear screen
clrs: db '\e[2J'
db '\e[1;1H\0'
.var scrout 0x0109 ; print character in C
.var decout 0x010c ; print string of value in HL
.org 0x0200 ; moveto routine
moveto: push HL
ld C,'\e'
call scrout
ld C,'['
call scrout
pop HL
push HL
ld L,H
ld H,00
inc L
call decout
ld C,';'
call scrout
pop HL
ld H,00
inc L
call decout
ld C,'H'
jp scrout
.org 0x022f
tcbits: db 0b00000011 ;terminal capabilities
.org 0x0230
;brites: db '\e[1m\0' ;bright
brites: db '\0' ;bright
.org 0x0238
;dims: db '\e[0m\0' ;dim
dims: db '\0' ;dim
.org 0x0240
dlstr: db '\0' ;delete line
.org 0x0248
ilstr: db '\0' ;insert line
.org 0x0250
dcstr: db '\0' ;Delete character
.org 0x0258
icstr: db '\0' ;Insert character
.org 0x0260
ceol: db '\e[K\0' ;Clear to end of line
.org 0x0268
ceos: db '\e[J\0' ;Clear to end of screen
.org 0x0270 ;entry subroutine
entry: jp init
.org 0x0273 ;exit subroutine
exit: jp uninit
.org 0x0276 ;user subroutine
user: ret
.org 0x0279 ;keyboard map subroutine
kbmap: ret
.org 0x0280 ;user patch area
init: ret
uninit: ret


172
qt-rc82.z Normal file
View File

@ -0,0 +1,172 @@
; QT2014.Z - QTerm patch for RC2014 with VT 100 terminal
;
; September 2019, Anna Christina Nass
; based on IMSAI8080 patch: September 2019, Udo Munk
;
.var SIOC 0x82 ;sio control port (2nd port)
.var SIOD 0x83 ;sio data port (2nd port)
.var SDEV 1 ;RomWBW device number
;.var SIOC 0x84 ;sio control port (3rd port)
;.var SIOD 0x85 ;sio data port (3rd port)
;.var SDEV 2 ;RomWBW device number
.var RXRDY 1 ;receiver ready
.var TXRDY 4 ;transmitter ready
.org 0x0110 ; modem input status
modist: in a,(SIOC)
and RXRDY
ret
.org 0x0120 ; modem input
modin: in a,(SIOD)
ret
.org 0x0130 ; modem output status
modost: in a,(SIOC)
and TXRDY
ret
.org 0x0140 ; modem output
modout: out (SIOD),a
ret
.org 0x0150 ; start break
sbreak: ret
.org 0x0160 ; stop break
ebreak: ret
.org 0x0170 ; drop DTR
dtroff: ret
db 0x0c ;length of modem hang up string
db 0xfe,0xfe ;two delays
db 0x2b,0x2b,0x2b ;+++
db 0xfe,0xfe ;two delays
db 'ATH0',0x0d ;ATH0 <return>
.org 0x0180 ; restore DTR
dtron: ret
.org 0x0190 ; set baud rate
setbd: ret
.org 0x01a0 ; baud rate table
baudtb:
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
.org 0x01b0 ; set communication mode
setmod: ret
.org 0x01c0 ; communication mode table
modetb:
db 0,0,0,0,0,0,0,0
db 0,0,0,0
.org 0x01cc
resrvd: db 0 ; reserved for later use
.org 0x01cd ; protocol transfer size
xfersz: db 8
.org 0x01ce ; processor speed
speed: db 8 ; cpu speed in Mhz;
.org 0x01cf ; escape character
escape: db 0x19 ; 0x19: ^Y
.org 0x01d0 ; signon message
signon: db 'RC2014 SIO/2 - VT100\0'
.org 0x01f0 ; clear screen
clrs: db '\e[2J'
db '\e[1;1H\0'
.var scrout 0x0109 ; print character in C
.var decout 0x010c ; print string of value in HL
.org 0x0200 ; moveto routine
moveto: push HL
ld C,'\e'
call scrout
ld C,'['
call scrout
pop HL
push HL
ld L,H
ld H,00
inc L
call decout
ld C,';'
call scrout
pop HL
ld H,00
inc L
call decout
ld C,'H'
jp scrout
.org 0x022f
tcbits: db 0b11000011 ;terminal capabilities
.org 0x0230
;brites: db '\e[1m\0' ;bright
brites: db '\0' ;bright
.org 0x0238
;dims: db '\e[0m\0' ;dim
dims: db '\0' ;dim
.org 0x0240
dlstr: db '\0' ;delete line
.org 0x0248
ilstr: db '\0' ;insert line
.org 0x0250
dcstr: db '\0' ;Delete character
.org 0x0258
icstr: db '\0' ;Insert character
.org 0x0260
ceol: db '\e[K\0' ;Clear to end of line
.org 0x0268
ceos: db '\e[J\0' ;Clear to end of screen
.org 0x0270 ;entry subroutine
entry: jp init
.org 0x0273 ;exit subroutine
exit: jp uninit
.org 0x0276 ;user subroutine
user: ret
.org 0x0279 ;keyboard map subroutine
kbmap: ret
.org 0x0280 ; user patch area
init: ld hl,SIOINI
ld B,9
ld C,SIOC
otir
ret
SIOINI: db 0b00011000 ; Wr0 Channel reset
db 0b00010100 ; Wr0 Pointer R4 + reset ex st int
db 0b11000100 ; Wr4 /64, async mode, no parity
db 0b00000011 ; Wr0 Pointer R3
db 0b11000001 ; Wr3 Receive enable, 8 bit
db 0b00000101 ; Wr0 Pointer R5
db 0b11101010 ; Wr5 Transmit enable, 8 bit, flow ctrl
db 0b00010001 ; Wr0 Pointer R1 + reset ex st int
db 0b00000000 ; Wr1 No Tx interrupts
uninit: ld B,4 ; HBIOS CIOINIT function 0x04
ld C,SDEV ; device number (0,1,2,3)
ld DE,-1 ; "Reset with current settings"
rst 8 ; do it
ret ; not initialized, so no un-initialize


172
qt-rc84.z Normal file
View File

@ -0,0 +1,172 @@
; QT2014.Z - QTerm patch for RC2014 with VT 100 terminal
;
; September 2019, Anna Christina Nass
; based on IMSAI8080 patch: September 2019, Udo Munk
;
;.var SIOC 0x82 ;sio control port (2nd port)
;.var SIOD 0x83 ;sio data port (2nd port)
;.var SDEV 1 ;RomWBW device number
.var SIOC 0x84 ;sio control port (3rd port)
.var SIOD 0x85 ;sio data port (3rd port)
.var SDEV 2 ;RomWBW device number
.var RXRDY 1 ;receiver ready
.var TXRDY 4 ;transmitter ready
.org 0x0110 ; modem input status
modist: in a,(SIOC)
and RXRDY
ret
.org 0x0120 ; modem input
modin: in a,(SIOD)
ret
.org 0x0130 ; modem output status
modost: in a,(SIOC)
and TXRDY
ret
.org 0x0140 ; modem output
modout: out (SIOD),a
ret
.org 0x0150 ; start break
sbreak: ret
.org 0x0160 ; stop break
ebreak: ret
.org 0x0170 ; drop DTR
dtroff: ret
db 0x0c ;length of modem hang up string
db 0xfe,0xfe ;two delays
db 0x2b,0x2b,0x2b ;+++
db 0xfe,0xfe ;two delays
db 'ATH0',0x0d ;ATH0 <return>
.org 0x0180 ; restore DTR
dtron: ret
.org 0x0190 ; set baud rate
setbd: ret
.org 0x01a0 ; baud rate table
baudtb:
db 0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0
.org 0x01b0 ; set communication mode
setmod: ret
.org 0x01c0 ; communication mode table
modetb:
db 0,0,0,0,0,0,0,0
db 0,0,0,0
.org 0x01cc
resrvd: db 0 ; reserved for later use
.org 0x01cd ; protocol transfer size
xfersz: db 8
.org 0x01ce ; processor speed
speed: db 8 ; cpu speed in Mhz;
.org 0x01cf ; escape character
escape: db 0x19 ; 0x19: ^Y
.org 0x01d0 ; signon message
signon: db 'RC2014 SIO/2 - VT100\0'
.org 0x01f0 ; clear screen
clrs: db '\e[2J'
db '\e[1;1H\0'
.var scrout 0x0109 ; print character in C
.var decout 0x010c ; print string of value in HL
.org 0x0200 ; moveto routine
moveto: push HL
ld C,'\e'
call scrout
ld C,'['
call scrout
pop HL
push HL
ld L,H
ld H,00
inc L
call decout
ld C,';'
call scrout
pop HL
ld H,00
inc L
call decout
ld C,'H'
jp scrout
.org 0x022f
tcbits: db 0b11000011 ;terminal capabilities
.org 0x0230
;brites: db '\e[1m\0' ;bright
brites: db '\0' ;bright
.org 0x0238
;dims: db '\e[0m\0' ;dim
dims: db '\0' ;dim
.org 0x0240
dlstr: db '\0' ;delete line
.org 0x0248
ilstr: db '\0' ;insert line
.org 0x0250
dcstr: db '\0' ;Delete character
.org 0x0258
icstr: db '\0' ;Insert character
.org 0x0260
ceol: db '\e[K\0' ;Clear to end of line
.org 0x0268
ceos: db '\e[J\0' ;Clear to end of screen
.org 0x0270 ;entry subroutine
entry: jp init
.org 0x0273 ;exit subroutine
exit: jp uninit
.org 0x0276 ;user subroutine
user: ret
.org 0x0279 ;keyboard map subroutine
kbmap: ret
.org 0x0280 ; user patch area
init: ld hl,SIOINI
ld B,9
ld C,SIOC
otir
ret
SIOINI: db 0b00011000 ; Wr0 Channel reset
db 0b00010100 ; Wr0 Pointer R4 + reset ex st int
db 0b11000100 ; Wr4 /64, async mode, no parity
db 0b00000011 ; Wr0 Pointer R3
db 0b11000001 ; Wr3 Receive enable, 8 bit
db 0b00000101 ; Wr0 Pointer R5
db 0b11101010 ; Wr5 Transmit enable, 8 bit, flow ctrl
db 0b00010001 ; Wr0 Pointer R1 + reset ex st int
db 0b00000000 ; Wr1 No Tx interrupts
uninit: ld B,4 ; HBIOS CIOINIT function 0x04
ld C,SDEV ; device number (0,1,2,3)
ld DE,-1 ; "Reset with current settings"
rst 8 ; do it
ret ; not initialized, so no un-initialize


BIN
qterm43f.lbr Normal file

Binary file not shown.

BIN
qterm82.com Normal file

Binary file not shown.

BIN
qterm84.com Normal file

Binary file not shown.

BIN
qtermc3.com Normal file

Binary file not shown.