home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / QTERM / QTERM43E.LBR / QTERM.PYT / QTERM.PYT
Text File  |  2000-06-30  |  15KB  |  333 lines

  1. Patching QTERM for your system.
  2.  
  3. This explains the patches in QTERM, and can be used to patch QTERM
  4. directly (it is written as if being used in that manner), however
  5. it also provides an explanation of the subroutines that would be
  6. needed if a QT-?????.Z patch source were to be written, based on the
  7. template QT-PATCH.Z provided.
  8.  
  9. The first thing to do is to back QTERM up, and then invoke DDT, SID, ZSID,
  10. Z8E, or whatever your local patch utility is, in the following way:
  11.  
  12. A>DDT QTERM.COM
  13.  
  14. DDT (etc.) will read in QTERM, and then prompt. The following is a list of
  15. patch areas where QTERM should be changed to reflect your system. Some of
  16. these are mandatory (i.e. QTERM won't work without them), whereas others
  17. can be changed to null subroutines or empty data without preventing QTERM
  18. from working, it just won't have all the features available.
  19.  
  20.  
  21. 1. Modem input status: 0110 - 011F
  22.  
  23. QTERM calls here to check modem input status. Return with the zero flag
  24. set if no character is available, or with the zero flag clear if a char
  25. is available. Generally this can be an input from the usart / sio / dart
  26. status port followed by an 'and'.
  27.  
  28. 2. Read modem character: 0120 - 012F
  29.  
  30. This gets a character from the modem input port once the input status has
  31. decided it's there. Return the character in the a register. Generally this
  32. can be an input from the usart / sio / dart data port.
  33.  
  34. 3. Modem output status: 0130 - 013F
  35.  
  36. Check if the modem output port can accept another character. Return with the
  37. zero flag set if the output port can't receive a character, or with the zero
  38. flag clear if the output port is ready. Generally this can be an input from
  39. the usart / sio / dart status port followed by an 'and'.
  40.  
  41. 4. Write modem character: 0140 - 014F
  42.  
  43. Send the character in the a register to the modem output port. This will only
  44. be called after the output status routine has returned a non-zero status.
  45. Generally this can be an output to the usart / sio / dart data port.
  46.  
  47. These first four patches are all necessary for QTERM to work. The next few
  48. are not necessary, but they will be useful.
  49.  
  50. 5. Start break: 0150 - 015F
  51.    End break: 0160 - 016F
  52.  
  53. The start break subroutine at 0150 should initiate a break condition on
  54. the modem output line, and 0160 should clear the break condition. If these
  55. are to be omitted, then just put return (C9) instructions at 0150 and 0160.
  56. Note that the Start Break routine need not check that the transmit buffer
  57. is empty, since there will always be a 1/10th. second delay after the last
  58. character is sent, before calling this subroutine.
  59.  
  60. 6. Drop DTR: 0170 - 017F
  61.    Restore DTR: 0180 - 018F
  62.  
  63. The drop DTR subroutine causes DTR to be made inactive, and restore DTR
  64. returns DTR to an active state. If your modem does not respond to DTR, but
  65. can be made to hang up by sending a string, then put a return (C9) at 0170.
  66. Use the space from 0171 to 018F to contain the string, with the following
  67. notes: at 0171 should be the length of the string, to transmit a break,
  68. use an 0FFH byte, to cause a two second delay use an 0FEH byte. Hence the
  69. following could be used to hang up a Hayes compatible:
  70.  
  71. 0C FE FE 2B 2B 2B FE FE 41 54 48 30 0D
  72.  
  73. 0C - length: 12 bytes follow
  74. FE - delay (twice)
  75. 2B - '+' sent three times
  76. FE - delay (twice)
  77. 41 54 48 30 0D - ATH0 <return>
  78.  
  79. If neither DTR nor a string is to be used, then place a return (C9) at
  80. 0180 and 0171, and a nop (00) at 0170. The string is used only if a C9
  81. is found at 0170, so by placing the C9 at 0171 the string print is
  82. inhibited.
  83.  
  84. 7. Baud rate setting: 0190 - 019F
  85.    Baud rate table: 01A0 - 01AF
  86.  
  87. These two patch areas work together to allow QTERM to change the baud rate
  88. of the modem port. The baud rate table holds pairs of bytes for setting the
  89. baud rate to eight different values: 38400, 19200, 9600, 4800, 2400, 1200,
  90. 600 and 300, in that order. In these pairs, the first byte will be passed
  91. to the subroutine at 0190, and the second byte is used to enable that baud
  92. rate: an 0FFH in the second byte enables the rate, and a zero disables.
  93. So if your system only went up to 9600, (using a value of 1 to get 9600)
  94. the first six bytes in the table would be:
  95.  
  96.     00 00        no value for 38400: disable by the 00
  97.     00 00        no value for 19200: disable by the 00
  98.     01 FF        01 is the value for 9600: enable by the FF
  99.  
  100. In all cases of enabled baud rates, the subroutine at 0190 gets the
  101. appropriate value in the a register and should use it to set the baud rate.
  102. If this is to be omitted, then just put a return (C9) instruction at 0190,
  103. and fill the table from 01A0 to 01AF with 00's.
  104.  
  105. 8. Communication mode setting: 01B0 - 01BF
  106.    Communication mode table: 01C0 - 01CB
  107.  
  108. These two patch areas work together to allow QTERM to change the
  109. communications format of the modem port. The mode table holds bytes for
  110. setting 12 different formats, selecting number of data bits (7 or 8)
  111. parity (odd, even, or none) and number of stop bits (1 or 2). In order
  112. the 12 values are for 7n1, 8n1, 7n2, 8n2, 7e1, 8e1, 7e2, 8e2, 7o1, 8o1,
  113. 7o2, and 8o2. The subroutine at 01B0 gets one of these values in the a
  114. register and should use it to set the communications mode. If this is to
  115. be omitted, then just put a return (C9) instruction at 01B0.
  116.  
  117. 9. Reserved for later use: 01CC
  118.  
  119. This byte is reserved for later expansion, and should not be used.
  120.  
  121. 10. Protocol transfer size: 01CD
  122.  
  123. During protocol transfers, disk reads and writes take place every 8K. This
  124. is normally possible without causing a timeout, and reduces disk access to
  125. a minimum. However if your disk is slow, you can drop this to 4, 2 or even
  126. 1 to reduce the size of transfer, and hence prevent timeouts.
  127.  
  128. 11. Processor speed: 01CE
  129.  
  130. This is the speed in Mhz that your Z80 runs at: 4, 6 or whatever. For
  131. a 2.5Mhz cpu, use 3.
  132.  
  133. 12. Escape character: 01CF
  134.  
  135. All special functions of QTERM are activated by the use of escape sequences.
  136. At 01CF is the byte used for the escape character (the default is ^\). Any
  137. byte can be used, but a little used value is best selected, also using a
  138. printable character (' ' thru '~') may have undesirable results. Note that to
  139. transmit the escape value itself, just type it twice.
  140.  
  141. These previous three are necessary.
  142.  
  143. 13. Signon message: 01D0 - 01EF
  144.  
  145. This must be a string that identifies your system / terminal. It must be
  146. present, and is printed when QTERM first starts. It should be composed of
  147. printable characters, and terminated by a zero byte.
  148.  
  149. 14. Clear screen: 01F0 - 01FF
  150.  
  151. This must be a string that clears the terminal screen, and leaves the
  152. cursor in the top left hand corner. This should also be terminated by a
  153. zero byte.
  154.  
  155. 15. Moveto: 0200 - 022E
  156.  
  157. QTERM requires the ability to move the cursor around the screen. It calls
  158. this subroutine with the required coordinates in hl: where h is the row,
  159. and l the column to move to. The top left hand corner of the screen is 0,0;
  160. and the bottom right corner is 23,79. This subroutine will have to do
  161. terminal output: at 0109H is a routine that prints a character in the c
  162. register, and at 010CH is a routine to print a decimal number in hl (mainly
  163. for the use of vt100 and vt220 compatibles). Note that the above two
  164. subroutines may destroy all registers, so appropriate action should be
  165. taken if needed.
  166.  
  167. 16. Teminal capability bit map: 022F
  168.  
  169. This byte contains one bit set for each of the following terminal
  170. capabilities:
  171.  
  172. bit 0: (01H)    end highlight mode
  173. bit 1: (02H)    start highlight mode
  174. bit 2: (04H)    delete line
  175. bit 3: (08H)    insert line
  176. bit 4: (10H)    delete character
  177. bit 5: (20H)    insert character
  178. bit 6: (40H)    clear to end of line
  179. bit 7: (80H)    clear to end of screen
  180.  
  181. 17. Terminal capability strings: 0230 - 026F
  182.  
  183. In this area are eight strings, each of which can be at most seven characters
  184. long. They are the strings to be printed to perform the terminal capabilities
  185. mentioned above. Each one of them should be terminated by a zero byte. Hence
  186. at 0230 is the string for end highlight, at 0238 is the string for start
  187. highlight, etc., with 0268 being the string for clear to end of screen.
  188. Programs that use these will check the terminal capability bitmap at 022F
  189. before using them, to determine if they are available.
  190.  
  191. 18. Entry subroutine: 0270 - 0272
  192.  
  193. Upon entry to QTERM, this subroutine will be called. If it is not needed
  194. then a return instruction (0C9H) should be placed at 0270, otherwise there
  195. is enough space to put in a jump to code that is to be executed when QTERM
  196. starts. This can be used for several purposes: if custom initialisation is
  197. needed to enable communications, or select a particular baud rate, or
  198. whatever, this can be done here. In addition, if all chat scripts and disk
  199. access is to be done on a specific drive, then by using the CP/M BDOS
  200. functions to set drive (and set user if desired), QTERM can be made to
  201. automatically be in the correct place to find scripts. This is explained
  202. in QTCHAT.DOC
  203.  
  204. 19. Exit subroutine: 0273 - 0275
  205.  
  206. After an <Escape> Q has been issued to exit QTERM, this subroutine will
  207. be called immediately before exiting back to CP/M. As with the entry
  208. subroutine, if not needed, a return instruction (0C9H) should be placed at
  209. 0273H, otherwise any termination code can be added.
  210.  
  211. 20. User subroutine: 0276 - 0278
  212.  
  213. The <Escape> U command from terminal mode, and !U in chat scripts cause
  214. a call to this location. This can be used to do whatever is wanted,
  215. enabling special features, selecting different ports for communication
  216. whatever. Note that at 027C is a jump to ilprmt: an inline prompt
  217. subroutine. If the user subroutine is invoked from terminal mode, then
  218. calling this subroutine will prompt, and read a line of text into the
  219. buffer at 0080, it is terminated with a zero byte. If invoked with a !u
  220. from a chat script, then the remaining text on the line will be moved
  221. to the buffer, creating the impression it had just come from the
  222. keyboard. Following the call to ilprmt should be a prompt message,
  223. terminated by a null byte. NOTE: if no prompt is required, then two zero
  224. bytes are needed.
  225.  
  226.     call    ilprmt
  227.     db    'Prompt message\0'
  228.  
  229.     call    ilprmt
  230.     db    0,0
  231.  
  232. are examples. This subroutine should only be called once per invocation of
  233. the user subroutine, since a second call when used in a chat script may
  234. have unpredictable results.
  235.  
  236. 21. Keyboard map: 0279 - 027B
  237.  
  238. All keystrokes read from the keyboard are passed through the keyboard map
  239. subroutine, so that actions like mapping arrow keys to VT100 escape
  240. sequences can be performed. When this is called, the value of the key
  241. just pressed is in the a register, and the b register is zero. On exit
  242. the value in b determines what action is to be taken. If b is zero, then
  243. the value passed on to QTERM is whatever vaule is in the a register, so
  244. that placing a 'RET' instruction at 0279H causes no effect at all. If b
  245. contains 1, then QTERM will assume that the keyboard map routine "swallowed"
  246. the character, and instead of passing it on, QTERM immediately polls the
  247. keyboard for another character. If b contains 2, then QTERM takes this
  248. to mean that the keyboard map routine wishes to output another character
  249. without further input from the keyboard. In this case, QTERM passes the
  250. current value in a along, then calls straight into the keyboard map routine
  251. again, without polling the keyboard. To provide some examples:
  252.  
  253. A. Assume that your system has some function keys that send the following
  254. strings:
  255.  
  256. ^A 1, ^A 2, ^A 3, ^A 4,
  257.  
  258. and you wish to map those keys to ^H ^J ^K and ^L, with ^A followed by
  259. any other character being mapped to just the second character. The
  260. keyboard map would start by looking for ^A, if it saw any other character,
  261. it would return it unchanged with b equal to zero. On getting a ^A, it
  262. wants to see the next character from the keyboard without sending anything
  263. on, so it sets b to 1, and is at liberty to return any value in a. QTERM
  264. immediately gets the next key value, and passes it to the keyboard map. If
  265. it's one of 1, 2, 3, or 4, then the keyboard map sets a to ^H, ^J, ^K, or
  266. ^L as appropriate, and returns with zero in b, otherwise it simply returns
  267. the value in a, again with b holding zero.
  268.  
  269. B. Assume you want to do the reverse mapping: ^H ^J ^K and ^L to ^A 1, ^A 2
  270. etc. Here, the keyboard map is looking for ^H ^J etc., passing all other
  271. characters unchanged, with b zero. Assume it sees a ^H, which is to be
  272. mapped to ^A 1. It sets b to 2 (to say that there is more to come) and
  273. returns a ^A in the a register. QTERM will pass the ^A on, and then call
  274. te map again, at which point it would return 1, with b set to zero this
  275. time: this is because there are no more characters to be sent.
  276.  
  277. C. In the most complex case, assume that ^E followed by any other character
  278. is to be mapped to two copies of the character, followed by ^A. In this
  279. case, all characters save ^E are passed unchanged, with zero in b. When a
  280. ^E is detected, b is returned with 1, to say that the ^E was swallowed,
  281. and when the next character is passed to the map, it should be saved, but
  282. also returned, however b should be 2. QTERM will process the character,
  283. then since b was 2, it will call the map subroutine. The map routine
  284. returns the character again, with b set to 2 a second time. On the third
  285. call to the map routine, it should return the terminating ^A, with b equal
  286. to zero to say all the work is done.
  287.  
  288. 22. ILPRMT subroutine jump: 027C - 027E
  289.  
  290. These three bytes are reserved to hold a jump to the in line prompt
  291. subroutine, and should not be overwritten by the patch.
  292.  
  293. 23. Patch area: 0280 - 04FF
  294.  
  295. Since the area provided for the above patches is limited, it may be necessary
  296. to use more space. The block of memory from 0280 to 04FF is set aside for
  297. custom patches, this can be used if the individual spaces are not big enough.
  298.  
  299.  
  300. Once all the patches have been made, exit the patch program (usually by
  301. typing ^C), and finish up by saving a new copy of QTERM:
  302.  
  303. A>SAVE 69 QTERMNEW.COM
  304.  
  305. In addition, the patch area only can be saved as follows:
  306.  
  307. A>SAVE 4 QTERMPAT.XXX
  308.  
  309. Which will create a 1K file containing all the patches needed to make this
  310. particular version of QTERM work. By doing this, when a new release of QTERM
  311. needs to be patched, all that is necessary is to read in the new unpatched
  312. version with DDT or whatever, then overlay the patch area. This is typically
  313. done by typing:
  314.  
  315. IQTERMPAT.XXX
  316.  
  317. to DDT, SID, ZSID etc. to set up the command line to read QTERMPAT.XXX, then
  318. follow this with a:
  319.  
  320. R
  321.  
  322. to read it. This should overlay the saved patch area on the new version,
  323. hence doing all the patches at once. Then exit DDT with ^C, and do the
  324. first save shown above to save the new working version.
  325.  
  326.  
  327. NOTE: With V4.2 and later, the patch area has grown yet again, so again the
  328. overlaying of earlier patches will not work. By and large, overlaying patches
  329. in this manner is not recommended, it is far easier to work with the patch
  330. sources available, applying them with ZSM and ZPATCH as needed. However, the
  331. V4.3 patch area is the same as the V4.2 patch area, so no changes are needed
  332. to convert from V4.2 to V4.3
  333.