]>
Commit | Line | Data |
---|---|---|
e58a7a25 L |
1 | ; CPSPK1.ASM\r |
2 | ; KERMIT - (Celtic for "FREE")\r | |
3 | ;\r | |
4 | ; This is the CP/M-80 implementation of the Columbia University\r | |
5 | ; KERMIT file transfer protocol.\r | |
6 | ;\r | |
7 | ; Version 4.0\r | |
8 | ;\r | |
9 | ; Copyright June 1981,1982,1983,1984\r | |
10 | ; Columbia University\r | |
11 | ;\r | |
12 | ; Originally written by Bill Catchings of the Columbia University Center for\r | |
13 | ; Computing Activities, 612 W. 115th St., New York, NY 10025.\r | |
14 | ;\r | |
15 | ; Contributions by Frank da Cruz, Daphne Tzoar, Bernie Eiben,\r | |
16 | ; Bruce Tanner, Nick Bush, Greg Small, Kimmo Laaksonen, Jeff Damens, and many\r | |
17 | ; others. \r | |
18 | ;\r | |
19 | ; This file contains the (system-independent) routines that implement\r | |
20 | ; the KERMIT protocol, and the commands that use them:\r | |
21 | ; RECEIVE, SEND, FINISH, and LOGOUT.\r | |
22 | ;\r | |
23 | ; revision history:\r | |
24 | ;\r | |
25 | ;edit 23, 16-Jan-1991 by MF. The bug of (22) was not fixed (although\r | |
26 | ; the error described needed to be corrected). Really fixed the bug this:\r | |
27 | ; time. changed "lda 'E'" after "ptch9b" to "mvi a,'E'" -- Zilog\r | |
28 | ; mnemonic thinking must've addled my brain!\r | |
29 | ;edit 22, 14-Jan-1991 by MF. Fix bug in the code which sends an "E" packet\r | |
30 | ; to the remote Kermit on encountering "disk full" so that\r | |
31 | ; uncontrollified <CR><LF> is not copied to the packet data area (and\r | |
32 | ; hence sent to the remote Kermit). This should fix a bug reported\r | |
33 | ; by Russell Lang of Monash University in Australia wherein a PC\r | |
34 | ; running Kermit in Server mode complained of invalid characters when\r | |
35 | ; receiving the "disk full" error packet from CP/M Kermit.\r | |
36 | ;edit 21 of 3-Jan-1991 by MF. Reverse part of edit 20 which flushes comm\r | |
37 | ; input at EOF send: the problem of multiple copies of packets being\r | |
38 | ; sent when a stream of files being sent is partially interrupted with\r | |
39 | ; ^X has been fixed by modifying "inchr" in CPSPK2.ASM.\r | |
40 | ;edit 20, 2-Jan-1991 by MF. Tightened up code just after "sdata1" and around\r | |
41 | ; "sdat14". Added code to flush comm input after user has typed ^X\r | |
42 | ; or ^Z to interrupt file sends so that duplicate packets are not\r | |
43 | ; sent after the interrupt character (especially ^X) has been typed.\r | |
44 | ;edit 19, 14-Dec-1990 by MF. Place "<<>>" around "F" and "X" packets coming\r | |
45 | ; as replies to REMOTE commands a la VMS Bliss Kermit.\r | |
46 | ; Also type each character of "X" or "F" packet explicitly in case\r | |
47 | ; dollar-signs are part of the filename (as in VMS Bliss Kermit\r | |
48 | ; when a REMOTE TYPE is given and SET FILE NAMING FULL is in effect).\r | |
49 | ; Expanded code is at label rfil3f.\r | |
50 | ;edit 18, 27-Nov-1990 by MF. Fix bug introduced with edit 17 which resulted\r | |
51 | ; in "E" packet being sent twice when receiving file(s) and disk-full\r | |
52 | ; occurred. Sorry about that, folks!\r | |
53 | ;edit 17, 27-Nov-1990 by MF. When receiving files, make the decision as to\r | |
54 | ; whether to delete a partially-received file on a "disk full"\r | |
55 | ; condition subject to the setting of the SET INCOMPLETE-FILES\r | |
56 | ; switch in conformity with the behavior of MSDOS Kermit.\r | |
57 | ; An "E" packet is still sent to the remote Kermit. Also try to close\r | |
58 | ; any incomplete file whether deleting it or not (labels rdat16 and\r | |
59 | ; rdat3a). If keeping incomplete files, try to write outstanding\r | |
60 | ; buffers to disk, giving an error if the disk is full.\r | |
61 | ;edit 16, 23-Nov-1990 by MF. When receiving, cause the file being written\r | |
62 | ; to disk to **always** be deleted and an "E" packet to be sent when a\r | |
63 | ; "disk full" condition is encountered (per suggestion of\r | |
64 | ; RJL@MONU1.CC.MONASH.EDU.AU).\r | |
65 | ;edit 15, 15-Nov-1990 by MF. Changed code for the Receive Complete state\r | |
66 | ; to always go into RECEIVE if AUTORECEIVE is on. This will happen\r | |
67 | ; most of the time anyway as most mainframe Kermits issue a prompt\r | |
68 | ; after a single SEND command (wild-carded or not), thus guaranteeing\r | |
69 | ; that the modem status check of Kermit-80 ver. 4.09 would **always**\r | |
70 | ; have characters ready for input (the mainframe Kermit's prompt),\r | |
71 | ; defeating the status check and the Console input check (originally\r | |
72 | ; intended to drop the user out of the loop if he/she typed a key with\r | |
73 | ; no comm input present). Eliminate "any key" message there also.\r | |
74 | ; the user can drop out by hitting ^C.\r | |
75 | ; Of course, none of the foregoing applies if the Receive Complete\r | |
76 | ; state occurs as the result of a "Get" command where Autoreceive\r | |
77 | ; is meaningless and we just drop back to Kermit command-level.\r | |
78 | ;edit 14, 1-Oct-1990 by MF. Added code to send an "I" packet before an\r | |
79 | ; "R" packet in GET command.\r | |
80 | ; Modified routine "sinit" to ignore "E" packets when sending an\r | |
81 | ; "i" packet (per KPROTO.DOC).\r | |
82 | ;edit 13, 14-Sep-1990 by MF. Added code to implement SET FILE COLLISION\r | |
83 | ; and SET INCOMPLETE commands.\r | |
84 | ;edit 12, 9-Sep-1990 by MF. Added code to prevent packet counts\r | |
85 | ; from being displayed during Remote commands. Fixed\r | |
86 | ; AUTORECEIVE code, file colision Rename algorithm and eliminated\r | |
87 | ; multiple display of initial messages during GET/RECEIVE.\r | |
88 | ; edit 11, 28 July, 1987 by OBSchou. Commented out capas etc support\r | |
89 | ; (Long packets etc) as this is not worth the effort coding... but\r | |
90 | ; I have left what WAS done for any enthusiast. Also set in a few\r | |
91 | ; to NOT write to screen if SET TERMINAL QUIET set. Hopefully speeds\r | |
92 | ; up transfers on systems taking forever to update screens.\r | |
93 | ;\r | |
94 | ; edit 10, 8 April, 1987 by OBSchou. Tarted up all sorts of bits n bobs\r | |
95 | ; to cope with all the new aditions for Kermit-80 V 4.09\r | |
96 | ; Look for the [10] for most cahnges. spar and rpar largely replaced\r | |
97 | ;\r | |
98 | ; edit 9, March 30th by OBSchou. Set bits for automatically receiving\r | |
99 | ; another file if a remote sender sends files in seperate sessions.\r | |
100 | ; The code simply checks the serial line, and if there is some\r | |
101 | ; activity, assume its another SEND INIT packet. As there is no\r | |
102 | ; simple way to go to receive with the control-a, just ignore the\r | |
103 | ; packet. Causes one retry on the sender, but so what. Really \r | |
104 | ; should make it a server gizzmo.\r | |
105 | ;\r | |
106 | ; edit 8: January 28, 1987 by OBSchou\r | |
107 | ; Two major issues: firstly split CPSPKT.ASM into CPSPK(1 2).ASM\r | |
108 | ; making it far easier to handle this file.\r | |
109 | ; Second, some mode to the GET routines to correctly print the file\r | |
110 | ; name instead of the fireworks. Trouble was with GET <file> <file>\r | |
111 | ; and RECEIVE <file>. However, new bugs discovered...\r | |
112 | ;\r | |
113 | ; edit 7: August 11, 1986 Godfrey N. Nix [gnn] Nottingham University\r | |
114 | ; To ignore echoed packets (ie send 'S' receive 'S' before 'A');\r | |
115 | ; To allow character other than SOH for packet header (see also\r | |
116 | ; updates to CP4MIT and CP4UTL for other code needed);\r | |
117 | ; To permit SEND and RECEIVE to specify a host filename which\r | |
118 | ; is of a different structure to that of CP/M.\r | |
119 | ;\r | |
120 | ; edit 6a: [OBSchou] 7 March, 1985.\r | |
121 | ; Edited file with additions from MJ Carter. He writes:\r | |
122 | ; 25th September 1985, M J Carter [majoc], Nottingham University\r | |
123 | ; Code in gofil() amended, for exactly the same reasons to the \r | |
124 | ; alteration to cmifil() in cpscmd.asm. If there is any deep\r | |
125 | ; reason why gofil() has to be used instead of a call to comnd(cmofil), \r | |
126 | ; I can't see it. The bug (on a British Micro Mimi 803) caused \r | |
127 | ; gofil() to overwrite existing files in GET and RECEIVE, even \r | |
128 | ; with file warning SET ON.\r | |
129 | ;\r | |
130 | ;edir 6: November 22, 1984\r | |
131 | ; Change SEND's 'Unable to find file' error exit from calling\r | |
132 | ; error3 to calling prtstr instead. I don't know about you, but\r | |
133 | ; I greatly dislike having messages dumped into pre-existing\r | |
134 | ; junk on the screen where I have to spend lots of time hunting\r | |
135 | ; for them. [Hal Hostetler]\r | |
136 | ;\r | |
137 | ; edit 5: September 9, 1984\r | |
138 | ; Call flsmdm in init to flush old input when starting transfers.\r | |
139 | ; Select console before returning from inpkt.\r | |
140 | ; Replace inline code with calls to makfil/clofil to set up for\r | |
141 | ; multisector buffering on output.\r | |
142 | ; Remove superfluous call to clrlin in error3.\r | |
143 | ;\r | |
144 | ; edit 4: August 21, 1984 (CJC)\r | |
145 | ; Fix comment in inpkt: packet is terminated by NUL on return, not CR.\r | |
146 | ; If debugging, display the outgoing packet before putting the EOL\r | |
147 | ; character on, so the dumped packet doesn't get overwritten.\r | |
148 | ;\r | |
149 | ; edit 3: July 27, 1984\r | |
150 | ; add link directive for LASM. CP4PKT is linked by CP4MIT, and links\r | |
151 | ; to CP4TT. Add Toad Hall TACtrap to permit operations through a TAC.\r | |
152 | ;\r | |
153 | ; edit 2: June 8, 1984\r | |
154 | ; formatting and documentation; remove some unused labels; move setpar\r | |
155 | ; to cp4mit.m80; add module version string; make all arithmetic on\r | |
156 | ; 'pktnum' modulo 64; apply defaults correctly for missing parameters\r | |
157 | ; in send-init packet (and corresponding ack).\r | |
158 | ;\r | |
159 | ; edit 1: May, 1984\r | |
160 | ; extracted from CPMBASE.M80 version 3.9; modifications are described\r | |
161 | ; in the accompanying .UPD file.\r | |
162 | ;\r | |
163 | pk1ver: db 'CPSPK1.ASM (23) 16-Jan-1991$' ; name, edit number, date\r | |
164 | \r | |
165 | ; GET command [gnn]\r | |
166 | ; here from: kermit\r | |
167 | \r | |
168 | read: mvi a,0ffh ;[obs 8] we are doing a get\r | |
169 | sta getrxflg ;[obs 8] so set flag\r | |
170 | lxi d,remdat ;Where to put the text (if any.)\r | |
171 | mvi a,cmtxt\r | |
172 | call comnd ;Get either some text or a confirm.\r | |
173 | jmp kermt3 ; Didn't get anything.\r | |
174 | ora a ;Get any chars?\r | |
175 | jz kermt3 ;[gnn] GET must have a filename\r | |
176 | sta rdl ;Store the number of chars.\r | |
177 | xchg ;Get pointer into HL.\r | |
178 | mvi m,'$' ;Put in a dollar sign for printing.\r | |
179 | call init ;Clear the line and initialize the buffers.\r | |
180 | lda quietd ; quiet display?\r | |
181 | ana a\r | |
182 | jz read01 ;[MF]No, go ahead and position cursor\r | |
183 | call prcrlf ;[MF]Yes, keep from overwriting the prompt\r | |
184 | jmp read00 ;[MF]and write filename\r | |
185 | read01: call scrfln ;Position cursor [MF]\r | |
186 | read00: lxi d,remdat ;Print the file name, in either case\r | |
187 | call prtstr\r | |
188 | jmp read0a ;[gnn] go get local name if any\r | |
189 | \r | |
190 | \r | |
191 | ; enter here for RECEIVE command [gnn]\r | |
192 | read0: mvi a,0 ;[gnn]\r | |
193 | sta rdl ;[gnn][MF] flag entry as receive, not get\r | |
194 | sta getrxflg ;[obs 8] doing a receive, so reset flag\r | |
195 | call init ;clear line, initialise buffers\r | |
196 | read0a: lxi d,remnam ;[gnn] save local name here\r | |
197 | mvi a,cmtxt ;[gnn]\r | |
198 | call comnd ;[gnn] read second filename if present\r | |
199 | jmp kermt3 ;[gnn] error exit\r | |
200 | sta remlen ;[gnn] save length of name, may be zero\r | |
201 | sta getrxflg ;[obs 8] May also be receive <fnam> so \r | |
202 | ;[obs 8]pretend get for printing filename\r | |
203 | lda rdl ;[gnn] look at first name\r | |
204 | ora a ;[gnn] receive or get?\r | |
205 | jz read1 ;[gnn] receive\r | |
206 | \r | |
207 | mvi a,'I' ;[MF]Set state to send "I" packet\r | |
208 | sta state ;[MF]...\r | |
209 | \r | |
210 | ; jmp read12 ;[obs] [gnn] does not want this\r | |
211 | \r | |
212 | read1: ;call init ;Clear the line and initialize the buffers.\r | |
213 | read12: xra a\r | |
214 | sta czseen ;Clear the ^X/^Z flag initially.\r | |
215 | lxi h,0\r | |
216 | shld numpkt ;Set the number of packets to zero.\r | |
217 | shld numrtr ;Set the number of retries to zero.\r | |
218 | sta pktnum ;Set the packet number to zero.\r | |
219 | sta numtry ;Set the number of tries to zero.\r | |
220 | lda quietd ; quiet display?\r | |
221 | ana a\r | |
222 | jnz read13 ; yes, so dont write...\r | |
223 | call scrnrt ;Position cursor\r | |
224 | lxi h,0\r | |
225 | call nout ;Write the number of retries.\r | |
226 | read13: lda rdl ;[MF]Get or receive?\r | |
227 | ora a ;[MF]...\r | |
228 | jnz read2 ;[MF]Get, don't reset state\r | |
229 | mvi a,'R'\r | |
230 | sta state ;Set the state to receive initiate.\r | |
231 | ;...\r | |
232 | ;\f\r | |
233 | ;RECEIVE state table switcher.\r | |
234 | \r | |
235 | read2: lda quietd ; noisy display?\r | |
236 | ana a\r | |
237 | jnz read21 ; no, a quiet one\r | |
238 | lda remtxt ;[MF] In Remote command?\r | |
239 | ora a\r | |
240 | jnz read21 ;[MF] Yes, don't write to screen\r | |
241 | call scrnp ;Position cursor\r | |
242 | lhld numpkt\r | |
243 | call nout ;Write the current packet number.\r | |
244 | read21: lda state ;Get the state.\r | |
245 | cpi 'D' ;Are we in the DATA receive state?\r | |
246 | jnz read22\r | |
247 | call rdata\r | |
248 | jmp read2\r | |
249 | \r | |
250 | read22: cpi 'X' ; F packet but not an F packet?\r | |
251 | jnz read3 ; nope, so try next one\r | |
252 | call rfile ; 'get' the filename (but dont open it)\r | |
253 | jmp read2\r | |
254 | \r | |
255 | read3: cpi 'F' ;Are we in the FILE receive state?\r | |
256 | jnz read4\r | |
257 | call rfile ;Call receive file.\r | |
258 | jmp read2\r | |
259 | \r | |
260 | read4: cpi 'R' ;Are we in the Receive-Initiate state?\r | |
261 | jnz read5\r | |
262 | call rinit\r | |
263 | lda state ;[jd] get new state\r | |
264 | cpi 'F' ;[jd] went into receive state?\r | |
265 | jnz read2 ;[jd] no\r | |
266 | lxi d,inms24 ;[jd] yes, get receiving... message\r | |
267 | call finmes ;[jd] go print it\r | |
268 | jmp read2\r | |
269 | \r | |
270 | read5: cpi 'C' ;Are we in the Receive-Complete state?\r | |
271 | jnz read6\r | |
272 | lxi d,infms3 ;Put in "Complete" message.\r | |
273 | lda czseen ;Or was it interrupted?\r | |
274 | ora a ; . . .\r | |
275 | jz read5a ;No.\r | |
276 | xra a ;Yes, clear flag.\r | |
277 | sta czseen ; ...\r | |
278 | lxi d,inms13 ;Issue "interrupted" message.\r | |
279 | read5a: lda remtxt ;[MF] Doing a Remote command?\r | |
280 | ora a\r | |
281 | cz finmes ;Print completion message in right place if not\r | |
282 | ;\r | |
283 | lda rdl ;[MF]Receive or Get?\r | |
284 | ora a ;[MF]...\r | |
285 | jnz kermit ;[MF]Get, Autoreceive means nothing.\r | |
286 | lda autorc ; see if we want autoreceives\r | |
287 | ana a\r | |
288 | jz kermit ;[MF]No autoreceives, so drop out\r | |
289 | lxi d,autmes ;[MF]Yes, tell the user what we're doing\r | |
290 | call prtstr ;[MF]...\r | |
291 | jmp read1 ;[MF]Try another Receive (we get one\r | |
292 | ;[MF]retry from the sender as the ^A is lost)\r | |
293 | \r | |
294 | read6: cpi 'Y' ;[MF]Simple ack (from remote command)?\r | |
295 | jz kermit ;[MF]Yes\r | |
296 | \r | |
297 | cpi 'I' ;[MF]Exchanging parameters via info packet?\r | |
298 | jnz read7 ;[MF]No\r | |
299 | call sinit ;[MF]Yes, send the packet\r | |
300 | lda state ;[MF]Now see what happened\r | |
301 | cpi 'X' ;[MF]Did we exchange parameters successfully?\r | |
302 | jz read6a ;[MF]Yes, go send the filespec\r | |
303 | cpi 'A' ;[MF]No, are we in abort state?\r | |
304 | jnz read2 ;[MF]No, try again\r | |
305 | jmp kermit ;[MF]Yes, it's a real disaster, we must stop\r | |
306 | read6a: lda rdl ;[MF]Get length of filespec\r | |
307 | sta argblk+1 ;[MF]as length of packet\r | |
308 | mov c,a ;[MF]We must copy the filespec\r | |
309 | mvi b,0 ;[MF]...\r | |
310 | lxi h,remdat ;[MF]from the temporary buffer\r | |
311 | lxi d,data ;[MF]to the packet data area\r | |
312 | call mover ;[MF]Do it.\r | |
313 | ; for GET we must send the name of the file we want [gnn]\r | |
314 | \r | |
315 | mvi a,'1' ;Start with single character checksum\r | |
316 | sta curchk ;Save the type\r | |
317 | xra a ;Start a packet zero.\r | |
318 | sta argblk\r | |
319 | mvi a,'R' ;Receive init packet.\r | |
320 | call spack ;Send the packet.\r | |
321 | jmp kermt3 ; Die!\r | |
322 | xra a\r | |
323 | sta czseen ;Clear the ^X/^Z flag initially.\r | |
324 | lxi h,0\r | |
325 | shld numpkt ;Set the number of packets to zero.\r | |
326 | sta pktnum ;Set the packet number to zero.\r | |
327 | sta numtry ;Set the number of tries to zero.\r | |
328 | mvi a,'R' ;[MF]Set state to Receive-Initiate\r | |
329 | sta state ;[MF]...\r | |
330 | jmp read21 ;[MF]and go around again\r | |
331 | ;[MF]without retyping packet-number\r | |
332 | \r | |
333 | read7: cpi 'A' ;Are we in the Receive-"Abort" state?\r | |
334 | jnz read8\r | |
335 | read8: lxi d,infms4 ;Anything else is equivalent to "abort".\r | |
336 | call finmes\r | |
337 | jmp kermit\r | |
338 | ;\f\r | |
339 | ; Receive routines\r | |
340 | \r | |
341 | ; Receive init\r | |
342 | ; called by: read\r | |
343 | \r | |
344 | rinit: lda numtry ;Get the number of tries.\r | |
345 | cpi imxtry ;Have we reached the maximum number of tries?\r | |
346 | jm rinit2\r | |
347 | lxi d,ermes4\r | |
348 | call error3 ;Move cursor and print an error message.\r | |
349 | jmp abort ;Change the state to abort.\r | |
350 | \r | |
351 | rinit2: inr a ;Increment it.\r | |
352 | sta numtry ;Save the updated number of tries.\r | |
353 | mvi a,'1' ;Reset block check type to single character\r | |
354 | sta curchk ;Store as current type for initialization\r | |
355 | call rpack ;Get a packet.\r | |
356 | jmp nak ; Trashed packet: nak, retry.\r | |
357 | cpi 'S' ;Is it a send initiate packet?\r | |
358 | jnz rinit3 ;If not see if its an error.\r | |
359 | rini2a: lda numtry ;Get the number of tries.\r | |
360 | sta oldtry ;Save it.\r | |
361 | xra a\r | |
362 | sta numtry ;Reset the number of tries.\r | |
363 | lda argblk ;Returned packet number. (Synchronize them.)\r | |
364 | call countp\r | |
365 | lda argblk+1 ;Get the number of arguments received.\r | |
366 | lxi h,data ;Get a pointer to the data.\r | |
367 | call spar ;Get the data into the proper variables.\r | |
368 | lxi h,data ;Get a pointer to our data block.\r | |
369 | call rpar ;Set up the receive parameters.\r | |
370 | sta argblk+1 ;Store the returned number of arguments.\r | |
371 | mvi a,'Y' ;Acknowledge packet.\r | |
372 | call spack ;Send the packet.\r | |
373 | jmp abort ; Failed, abort.\r | |
374 | lda inichk ;Now switch to agreed upon check-type\r | |
375 | sta curchk ;For all future packets\r | |
376 | mvi a,'F' ;Set the state to file send.\r | |
377 | sta state\r | |
378 | ret\r | |
379 | \r | |
380 | rinit3: cpi 'E' ;Is it an error packet.\r | |
381 | jnz nak0 ;If not NAK whatever it is.\r | |
382 | call error\r | |
383 | jmp abort\r | |
384 | ;\f\r | |
385 | ; Receive file\r | |
386 | ; called by: read\r | |
387 | \r | |
388 | rfile: lda numtry ;Get the number of tries.\r | |
389 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
390 | jm rfile1\r | |
391 | lxi d,ermes5\r | |
392 | call error3 ;Move cursor and print an error message.\r | |
393 | jmp abort ;Change the state to abort.\r | |
394 | \r | |
395 | rfile1: inr a ;Increment it.\r | |
396 | sta numtry ;Save the updated number of tries.\r | |
397 | call rpack ;Get a packet.\r | |
398 | jmp nak ; Trashed packet: nak, retry.\r | |
399 | cpi 'S' ;Is it a send initiate packet?\r | |
400 | jnz rfile2 ; No, try next type.\r | |
401 | lda oldtry ;Get the number of tries.\r | |
402 | cpi imxtry ;Have we reached the maximum number of tries?\r | |
403 | jm rfil12 ;If not proceed.\r | |
404 | lxi d,ermes4\r | |
405 | call error3 ;Move cursor and print an error message.\r | |
406 | jmp abort ;Change the state to abort.\r | |
407 | \r | |
408 | rfil12: inr a ;Increment it.\r | |
409 | sta oldtry ;Save the updated number of tries.\r | |
410 | lda pktnum ;Get the present packet number.\r | |
411 | dcr a ;Decrement\r | |
412 | ani 3FH ; modulo 64\r | |
413 | mov b,a\r | |
414 | lda argblk ;Get the packet's number\r | |
415 | cmp b ;Is the packet's number one less than now?\r | |
416 | jnz nak0 ;No, NAK and try again.\r | |
417 | call updrtr ;Update the retry count.\r | |
418 | xra a\r | |
419 | sta numtry ;Reset the number of tries.\r | |
420 | lxi h,data ;Get a pointer to our data block.\r | |
421 | call rpar ;Set up the parameter information.\r | |
422 | sta argblk+1 ;Save the number of arguments.\r | |
423 | mvi a,'Y' ;Acknowledge packet.\r | |
424 | call spack ;Send the packet.\r | |
425 | jmp abort ; Failed, abort.\r | |
426 | ret\r | |
427 | \r | |
428 | rfile2: cpi 'Z' ;Is it an EOF packet?\r | |
429 | jnz rfile3 ; No, try next type.\r | |
430 | lda oldtry ;Get the number of tries.\r | |
431 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
432 | jm rfil21 ;If not proceed.\r | |
433 | lxi d,ermes6\r | |
434 | call error3 ;Move cursor and print an error message.\r | |
435 | jmp abort ;Change the state to abort.\r | |
436 | \r | |
437 | rfil21: call tryagn\r | |
438 | ret\r | |
439 | \r | |
440 | rfile3: cpi 'F' ;Start of file?\r | |
441 | jnz rfil3b\r | |
442 | mov c,a ;[MF]Save packet type\r | |
443 | lda remtxt ;[MF]Doing a remote server command?\r | |
444 | ora a ;[MF]...\r | |
445 | mov a,c ;[MF]Restore packet type\r | |
446 | jnz rfil3d ;[MF]If yes, same as x packet\r | |
447 | call compp\r | |
448 | jnz nak0 ;No, NAK it and try again.\r | |
449 | call countp\r | |
450 | mov c,a ;[MF]\r | |
451 | lda remtxt ;[MF]Doing a remote command?\r | |
452 | ora a ;[MF]...\r | |
453 | mov a,c ;[MF]\r | |
454 | jnz rfil3a ;[MF]Yes, don't open a file\r | |
455 | call gofil ;Get a file to write to, and init output buffer.\r | |
456 | jmp abort\r | |
457 | rfil3a: lda numtry ;Get the number of tries.\r | |
458 | sta oldtry ;Save it.\r | |
459 | call ackp\r | |
460 | mvi a,'D' ;Set the state to data receive.\r | |
461 | sta state\r | |
462 | lda czseen ;Check if we punted a file\r | |
463 | cpi 'Z' ;and didn't want any more\r | |
464 | rz ;If that was the request, keep telling other end\r | |
465 | xra a ;Otherwise, clear flag (^X is only for one file)\r | |
466 | sta czseen ;And store the flag back\r | |
467 | ret\r | |
468 | \r | |
469 | rfil3b: cpi 'X' ;Start of 'file?' , but not a file?\r | |
470 | jnz rfile4\r | |
471 | rfil3d: call compp\r | |
472 | jnz nak0 ;No, NAK it and try again.\r | |
473 | call countp\r | |
474 | \r | |
475 | call selcon ;[MF]Select Console\r | |
476 | lda argblk+1 ; get length\r | |
477 | ora a ;[MF]Anything to write?\r | |
478 | jz rfil3e ;[MF]No\r | |
479 | push psw ;[MF]Yes, save character count\r | |
480 | mvi e,'<' ;[MF]Write "<<" as in VMSKermit\r | |
481 | push d ;[MF]...\r | |
482 | call outcon ;[MF]...\r | |
483 | pop d ;[MF]...\r | |
484 | call outcon ;[MF]...\r | |
485 | pop psw ;[MF]Restore character count\r | |
486 | lxi h,data ; lets write the filename (?) to display\r | |
487 | rfil3f: push psw ;[MF]Save loop counter\r | |
488 | mov e,m ;[MF]Get character to write\r | |
489 | inx h ;[MF]and increment character pointer\r | |
490 | push h ;[MF]Save the pointer\r | |
491 | call outcon ;[MF]Write character to display\r | |
492 | pop h ;[MF]Restore pointer\r | |
493 | pop psw ;[MF]and loop counter\r | |
494 | dcr a ;[MF]Decrement the counter\r | |
495 | jnz rfil3f ;[MF]Display entire filename\r | |
496 | mvi e,'>' ;[MF]Put in ">>" as in VMSKermit\r | |
497 | push d ;[MF]...\r | |
498 | call outcon ;[MF]...\r | |
499 | pop d ;[MF]...\r | |
500 | call outcon ;[MF]...\r | |
501 | call prcrlf ;[MF]New line\r | |
502 | rfil3e: lda numtry ;Get the number of tries.\r | |
503 | sta oldtry ;Save it.\r | |
504 | call ackp\r | |
505 | mvi a,'D' ; expecting a D packet\r | |
506 | sta state\r | |
507 | lda czseen ;Check if we punted a file\r | |
508 | cpi 'Z' ;and didn't want any more\r | |
509 | rz ;If that was the request, keep telling other end\r | |
510 | xra a ;Otherwise, clear flag (^X is only for one file)\r | |
511 | sta czseen ;And store the flag back\r | |
512 | ret\r | |
513 | \r | |
514 | rfile4: cpi 'B' ;End of transmission.\r | |
515 | jnz rfile5\r | |
516 | call compp\r | |
517 | jnz nak0 ;No, NAK it and try again.\r | |
518 | xra a ;No data. (Packet number already in argblk).\r | |
519 | sta argblk+1\r | |
520 | mvi a,'Y' ;Acknowledge packet.\r | |
521 | call spack ;Send the packet.\r | |
522 | jmp abort\r | |
523 | mvi a,'C' ;Set the state to complete.\r | |
524 | sta state\r | |
525 | ret\r | |
526 | \r | |
527 | rfile5: cpi 'E' ;Is it an error packet.\r | |
528 | jnz abort\r | |
529 | call error\r | |
530 | jmp abort\r | |
531 | ;\f\r | |
532 | ; Receive data\r | |
533 | ; called by: read\r | |
534 | \r | |
535 | rdata: lda numtry ;Get the number of tries.\r | |
536 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
537 | jm rdata1\r | |
538 | lxi d,erms10\r | |
539 | call error3 ;Display error message.\r | |
540 | rdat16: lda remtxt ;[MF]Is a Remote command in progress?\r | |
541 | ora a ;[MF]...\r | |
542 | jnz abort ;[MF]Yes, don't worry about file disposition\r | |
543 | lda incflg ;[MF]Are we keeping incomplete files?\r | |
544 | ora a ;[MF]...\r | |
545 | jnz rdat17 ;[MF]Yes\r | |
546 | lxi d,fcb ;[MF]No, close the file, ignoring errors\r | |
547 | push d ;[MF]while protecting the pointer\r | |
548 | mvi c,closf ;[MF]...\r | |
549 | call bdos ;[MF]...\r | |
550 | pop d ;[MF]Now delete the file, ignoring errors\r | |
551 | mvi c,delf ;[MF]...\r | |
552 | call bdos ;[MF]...\r | |
553 | jmp abort ;Change the state to abort.\r | |
554 | rdat17: call clofil ;[MF]Try to close the file, writing\r | |
555 | ;[MF]outstanding buffers to disk\r | |
556 | jmp rdat37 ;[MF]We can't, the disk is full\r | |
557 | jmp abort ;[MF]Change the state to "abort"\r | |
558 | \r | |
559 | rdata1: inr a ;Increment it.\r | |
560 | sta numtry ;Save the updated number of tries.\r | |
561 | call rpack ;Get a packet.\r | |
562 | jmp nak ; Trashed packet: nak, retry.\r | |
563 | cpi 'D' ;Is it a data packet?\r | |
564 | jnz rdata2 ; No, try next type.\r | |
565 | call compp ;check for correct packet number (zero flag = ok)\r | |
566 | jz rdat14 ;its correct\r | |
567 | lda oldtry ;Get the number of tries.\r | |
568 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
569 | jm rdat12 ;If not proceed.\r | |
570 | lxi d,erms10\r | |
571 | call error3 ;Display err msg.\r | |
572 | jmp rdat16 ;[MF]Change the state to abort.\r | |
573 | \r | |
574 | rdat12: call tryagn\r | |
575 | ret\r | |
576 | \r | |
577 | rdat14: call countp\r | |
578 | lda numtry ;Get the number of tries.\r | |
579 | sta oldtry ;Save it.\r | |
580 | lda argblk+1 ;Get the length of the data.\r | |
581 | call ptchr\r | |
582 | jmp rdat3b ;[MF] Unable to write out chars;abort.\r | |
583 | xra a\r | |
584 | sta numtry ;Reset the number of tries.\r | |
585 | sta argblk+1 ;No data. (Packet number still in argblk.)\r | |
586 | mov c,a ;Assume no data\r | |
587 | lda czseen ;Check if control-X typed\r | |
588 | ora a ; . . .\r | |
589 | jz rdat15 ;Zero if not typed\r | |
590 | mov c,a ;Get the type of character typed\r | |
591 | mvi a,1 ;One data character\r | |
592 | sta argblk+1 ;Save the count\r | |
593 | mov a,c ;Get the possible data character\r | |
594 | sta data ;Store in data area\r | |
595 | rdat15: mvi a,'Y' ;Acknowledge packet.\r | |
596 | call spack ;Send the packet.\r | |
597 | jmp rdat16 ;[MF]\r | |
598 | ret\r | |
599 | \r | |
600 | rdata2: cpi 'F' ;Start of file?\r | |
601 | jnz rdata3 ; No, try next type.\r | |
602 | lda oldtry ;Get the number of tries.\r | |
603 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
604 | jm rdat21 ;If not proceed.\r | |
605 | lxi d,ermes5\r | |
606 | call error3 ;Display err msg.\r | |
607 | jmp rdat16 ;[MF]Change the state to abort.\r | |
608 | \r | |
609 | rdat21: call tryagn\r | |
610 | ret\r | |
611 | \r | |
612 | rdata3: cpi 'Z' ;Is it a EOF packet?\r | |
613 | jnz rdata4 ;Try and see if its an error.\r | |
614 | call compp\r | |
615 | jnz nak0 ;No, NAK it and try again.\r | |
616 | call countp\r | |
617 | lda argblk+1 ;Get the data length\r | |
618 | cpi 1 ;Have one item?\r | |
619 | jnz rdat33 ;If not, ignore data\r | |
620 | lda data ;Yes, get the character\r | |
621 | cpi 'D' ;Is it a 'D' for discard?\r | |
622 | jz rdat36 ;If so, punt file\r | |
623 | rdat33: lda remtxt ;[MF]Writing text to disk?\r | |
624 | ora a ;[MF]...\r | |
625 | jnz rdat38 ;[MF]No, don't close file\r | |
626 | call clofil ;Finish off the file.\r | |
627 | jmp rdat37 ; Give up if the disk is full.\r | |
628 | rdat38: xra a ;Since we kept the file,\r | |
629 | sta czseen ;don't say it was discarded.\r | |
630 | lda numtry ;Get the number of tries. [MF]\r | |
631 | sta oldtry ;Save it. [MF]\r | |
632 | call ackp ;[MF]\r | |
633 | jmp rdat39 ;[MF]and get ready to get more files\r | |
634 | rdat36: lda numtry ;Get the number of tries.\r | |
635 | sta oldtry ;Save it.\r | |
636 | call ackp\r | |
637 | lda remtxt ;[MF]Is a Remote command in progress?\r | |
638 | ora a ;[MF]...\r | |
639 | jnz rdat39 ;[MF]Yes, don't worry about file disposition\r | |
640 | lda dscflg ;[MF]Is the file being punted because\r | |
641 | ora a ;[MF]of a collision?\r | |
642 | jnz rdat39 ;[MF]Yes, don't delete the existing file\r | |
643 | lda incflg ;[MF]No, are we keeping incomplete files?\r | |
644 | ora a ;[MF]...\r | |
645 | jnz rdat3a ;[MF]Yes\r | |
646 | lxi d,fcb ;[MF]No, close the file,\r | |
647 | mvi c,closf ;[MF]ignoring errors\r | |
648 | push d ;[MF]...\r | |
649 | call bdos ;[MF]...\r | |
650 | pop d ;[MF]Now delete the file,\r | |
651 | mvi c,delf ;[MF]ignoring errors\r | |
652 | call bdos ;[MF]...\r | |
653 | jmp rdat39 ;[MF]and continue\r | |
654 | rdat3a: call clofil ;[MF]Try to close the file, writing\r | |
655 | ;[MF]outstanding buffers to disk\r | |
656 | jmp rdat37 ;[MF]Can't, disk is full\r | |
657 | rdat39: mvi a,'F'\r | |
658 | sta state\r | |
659 | ret\r | |
660 | \r | |
661 | rdat37: call ptchr9 ; Send "?Disk full" on the error line [MF]\r | |
662 | ; and to the remote Kermit [MF]\r | |
663 | rdat3b: lda remtxt ;[MF]Doing a Remote command?\r | |
664 | ora a ;[MF]...\r | |
665 | jnz abort ;[MF]Yes, just abort\r | |
666 | lxi d,fcb ;[MF]Close the file, ignoring errors\r | |
667 | push d ;[MF]Protect fcb pointer\r | |
668 | mvi c,closf ;[MF]...\r | |
669 | call bdos ;[MF]...\r | |
670 | pop d ;[MF]Restore pointer\r | |
671 | lda incflg ;[MF]Are we keeping incomplete files?\r | |
672 | ora a ;[MF]...\r | |
673 | jnz abort ;[MF]Yes, just abort transfer\r | |
674 | mvi c,delf ;[MF]No, delete the file, ignoring errors\r | |
675 | call bdos ;[MF]...\r | |
676 | jmp abort ;[MF] abort transfer\r | |
677 | \r | |
678 | rdata4: cpi 'E' ;Is it an error packet.\r | |
679 | jnz rdat16 ;[MF]\r | |
680 | call error\r | |
681 | jmp rdat16 ;[MF]\r | |
682 | ;\f\r | |
683 | ; SEND command\r | |
684 | ; here from: kermit\r | |
685 | \r | |
686 | send: mvi a,cmifi ;Parse an input file spec.\r | |
687 | lxi d,fcb ;Give the address for the FCB.\r | |
688 | call comnd\r | |
689 | jmp kermit ; Give up on bad parse.\r | |
690 | ; section to get remote filename [gnn]\r | |
691 | lxi d,remnam ;[gnn] where to put filename\r | |
692 | mvi a,cmtxt ;[gnn] \r | |
693 | call comnd ;[gnn] get the text to end of the line\r | |
694 | jmp kermt3 ;[gnn] failure in reading buffer\r | |
695 | sta remlen ;[gnn] save length (may be zero)\r | |
696 | ;\r | |
697 | xra a\r | |
698 | sta mfflg1 ; clear flags...\r | |
699 | sta mfflg2\r | |
700 | sta mfflg3 ;[gnn]\r | |
701 | sta fcbcnt ;[gnn] clear fcbcount\r | |
702 | lxi h,fcb0 ;[gnn] and fcb pointer\r | |
703 | shld xfcbptr\r | |
704 | ;\r | |
705 | call mfname ;handle (multi) files\r | |
706 | jnc send14 ;got a valid file-name\r | |
707 | lxi d,erms15\r | |
708 | call prtstr ;Display error msg. ([hh] where it's visible)\r | |
709 | jmp kermit\r | |
710 | \r | |
711 | send14: call init ;Clear the line and initialize the buffers.\r | |
712 | xra a\r | |
713 | sta pktnum ;Set the packet number to zero.\r | |
714 | sta numtry ;Set the number of tries to zero.\r | |
715 | sta wrn8 ;[jd] we haven't sent the 8-bit-lost warning\r | |
716 | lxi h,0\r | |
717 | shld numpkt ;Set the number of packets to zero.\r | |
718 | shld numrtr ;Set the number of retries to zero.\r | |
719 | lda quietd ; a quiet display?\r | |
720 | ana a\r | |
721 | jnz send15 ; yup, dont write\r | |
722 | call scrnrt ;Position cursor\r | |
723 | lxi h,0\r | |
724 | call nout ;Write the number of retries.\r | |
725 | send15: mvi a,'1' ;Reset to use single character checksum\r | |
726 | sta curchk ;For startup\r | |
727 | mvi a,'S'\r | |
728 | sta state ;Set the state to receive initiate.\r | |
729 | ;...\r | |
730 | ;\f\r | |
731 | ;SEND state table switcher\r | |
732 | \r | |
733 | send2: lda quietd ; a quiet display?\r | |
734 | ana a\r | |
735 | jnz send21 ; yes, so dont write\r | |
736 | call scrnp ;Position cursor\r | |
737 | lhld numpkt\r | |
738 | call nout ;Write the packet number.\r | |
739 | send21: lda state ;Get the state.\r | |
740 | cpi 'D' ;Are we in the data send state?\r | |
741 | jnz send3\r | |
742 | call sdata\r | |
743 | jmp send2\r | |
744 | \r | |
745 | send3: cpi 'F' ;Are we in the file send state?\r | |
746 | jnz send4\r | |
747 | call sfile ;Call send file.\r | |
748 | jmp send2\r | |
749 | \r | |
750 | send4: cpi 'Z' ;Are we in the EOF state?\r | |
751 | jnz send5\r | |
752 | call seof\r | |
753 | jmp send2\r | |
754 | \r | |
755 | send5: cpi 'S' ;Are we in the send initiate state?\r | |
756 | jnz send6\r | |
757 | call sinit\r | |
758 | lda state ;[jd] get state back\r | |
759 | cpi 'F' ;[jd] into file send state yet?\r | |
760 | jnz send2 ;[jd] no\r | |
761 | lxi d,inms23 ;[jd] yes, print sending...\r | |
762 | call finmes ;[jd] \r | |
763 | jmp send2\r | |
764 | \r | |
765 | send6: cpi 'B' ;Are we in the eot state?\r | |
766 | jnz send7\r | |
767 | call seot\r | |
768 | jmp send2\r | |
769 | \r | |
770 | send7: cpi 'C' ;Are we in the send complete state?\r | |
771 | jnz send8 ;No...\r | |
772 | lxi d,infms3 ;Yes, write "Complete" message.\r | |
773 | lda czseen ;Or was it interrupted?\r | |
774 | ora a ; . . .\r | |
775 | jz send7a ;No.\r | |
776 | lxi d,inms13 ;Yes, then say "Interrupted" instead.\r | |
777 | send7a: call finmes\r | |
778 | jmp kermit\r | |
779 | \r | |
780 | send8: cpi 'A' ;Are we in the send "abort" state?\r | |
781 | jnz send9\r | |
782 | lxi d,infms4 ;Print message.\r | |
783 | call finmes\r | |
784 | jmp kermit\r | |
785 | \r | |
786 | send9: lxi d,infms4 ;Anything else is equivalent to "abort".\r | |
787 | call finmes\r | |
788 | jmp kermit\r | |
789 | ;\f\r | |
790 | ; Send routines\r | |
791 | \r | |
792 | ; Send initiate\r | |
793 | ; called by: send\r | |
794 | \r | |
795 | sinit: lda numtry ;Get the number of tries.\r | |
796 | cpi imxtry ;Have we reached the maximum number of tries?\r | |
797 | jm sinit2\r | |
798 | lxi d,erms14\r | |
799 | call error3 ;Display ermsg\r | |
800 | jmp abort ;Change the state to abort.\r | |
801 | \r | |
802 | sinit2: inr a ;Increment it.\r | |
803 | sta numtry ;Save the updated number of tries.\r | |
804 | mvi a,'1' ;Reset to use single character checksum\r | |
805 | sta curchk ;For startup\r | |
806 | lda chktyp ;Get our desired block check type\r | |
807 | sta inichk ;Store so we tell other end\r | |
808 | lxi h,data ;Get a pointer to our data block.\r | |
809 | call rpar ;Set up the parameter information.\r | |
810 | sta argblk+1 ;Save the number of arguments.\r | |
811 | lda numpkt ;Get the packet number.\r | |
812 | sta argblk\r | |
813 | lda state ; load state (I or S)\r | |
814 | \r | |
815 | call spack ;Send the packet.\r | |
816 | jmp abort ; Failed, abort.\r | |
817 | call rpack ;Get a packet.\r | |
818 | jmp r ; Trashed packet don't change state, retry.\r | |
819 | cpi 'Y' ;ACK?\r | |
820 | jnz sinit3 ;If not try next.\r | |
821 | call compp ;compare packets. If ok, zero flag set\r | |
822 | rnz ;If not try again.\r | |
823 | call countp ;increment packet number modulo 64\r | |
824 | lda argblk+1 ;Get the number of pieces of data.\r | |
825 | lxi h,data ;Pointer to the data.\r | |
826 | call spar ;Read in the data. (decode what they want)\r | |
827 | lda numtry ;Get the number of tries.\r | |
828 | sta oldtry ;Save it.\r | |
829 | xra a\r | |
830 | sta numtry ;Reset the number of tries.\r | |
831 | lda state ; se if S or I state\r | |
832 | cpi 'I' ; I state, so set X as next state\r | |
833 | jnz sinita\r | |
834 | sinitb: mvi a,'X'\r | |
835 | sta state\r | |
836 | ret\r | |
837 | \r | |
838 | sinita: lda inichk ;Get the agreed upon block check type\r | |
839 | sta curchk ;Store as type to use for packets now\r | |
840 | mvi a,'F' ;Set the state to file send. (Assumed)\r | |
841 | sta state\r | |
842 | call getfil ;Open the file.\r | |
843 | ret ; assume success; mfname thinks the file exists.\r | |
844 | \r | |
845 | sinit3: cpi 'N' ;NAK?\r | |
846 | jnz sinit4 ;If not see if its an error.\r | |
847 | call updrtr ;Update the number of retries.\r | |
848 | lda pktnum ;Get the present packet number.\r | |
849 | inr a ;Increment\r | |
850 | ani 3FH ; modulo 64\r | |
851 | mov b,a\r | |
852 | lda argblk ;Get the packet's number.\r | |
853 | cmp b ;Is the packet's number one more than now?\r | |
854 | rnz ;If not assume its for this packet, go again.\r | |
855 | xra a\r | |
856 | sta numtry ;Reset number of tries.\r | |
857 | mvi a,'F' ;Set the state to file send.\r | |
858 | sta state\r | |
859 | ret\r | |
860 | \r | |
861 | sinit4: cpi 'E' ;Is it an error packet.\r | |
862 | jnz abort\r | |
863 | lda state ;[MF]Get state\r | |
864 | cpi 'I' ;[MF]If an "I" packet was sent,\r | |
865 | jz sinitb ;[MF]Ignore the error, pretend success\r | |
866 | call error ;[MF]else display the error info\r | |
867 | jmp abort ;[MF]and abort\r | |
868 | ;\f\r | |
869 | ; Send file header\r | |
870 | ; called by: send\r | |
871 | ;[5a] Question [majoc]: Why could not the filename\r | |
872 | ; parsing have been done by comnd, like all the rest?\r | |
873 | \r | |
874 | sfile: lda numtry ;Get the number of tries.\r | |
875 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
876 | jm sfile1\r | |
877 | lxi d,erms14\r | |
878 | call error3\r | |
879 | jmp abort ;Change the state to abort.\r | |
880 | \r | |
881 | sfile1: inr a ;Increment it.\r | |
882 | sta numtry ;Save the updated number of tries.\r | |
883 | xra a ;Clear A\r | |
884 | sta czseen ;No control-Z or X seen\r | |
885 | lxi h,data ;Get a pointer to our data block.\r | |
886 | shld datptr ;Save it.\r | |
887 | ; use remote name if given, else use local name [gnn]\r | |
888 | lda remlen ;[gnn] anything given?\r | |
889 | ora a ;[gnn] \r | |
890 | jnz sfile4 ;[gnn] use remote name\r | |
891 | \r | |
892 | lxi h,fcb+1 ;Pointer to the file name in the FCB.\r | |
893 | shld fcbptr ;Save position in FCB.\r | |
894 | mvi b,0 ;No chars yet.\r | |
895 | mvi c,0\r | |
896 | sfil11: mov a,b\r | |
897 | cpi 8H ;Is this the ninth char?\r | |
898 | jnz sfil12 ;If not proceed.\r | |
899 | mvi a,'.' ;Get a dot.\r | |
900 | lhld datptr\r | |
901 | mov m,a ;Put the char in the data packet.\r | |
902 | inx h\r | |
903 | shld datptr ;Save position in data packet.\r | |
904 | inr c\r | |
905 | sfil12: inr b ;Increment the count.\r | |
906 | mov a,b\r | |
907 | cpi 0CH ;Twelve? \r | |
908 | jp sfil13\r | |
909 | lhld fcbptr\r | |
910 | mov a,m\r | |
911 | ani 7fH ;Turn off CP/M 2 or 3's high bits.\r | |
912 | inx h\r | |
913 | shld fcbptr ;Save position in FCB.\r | |
914 | cpi '!' ;Is it a good character?\r | |
915 | jm sfil11 ;If not get the next.\r | |
916 | lhld datptr\r | |
917 | mov m,a ;Put the char in the data packet.\r | |
918 | inx h\r | |
919 | shld datptr ;Save position in data packet.\r | |
920 | inr c\r | |
921 | jmp sfil11 ;Get another.\r | |
922 | \r | |
923 | sfil13: mov a,c ;Number of char in file name.\r | |
924 | sta argblk+1\r | |
925 | lhld datptr\r | |
926 | mvi a,'$'\r | |
927 | mov m,a ;Put in a dollar sign for printing.\r | |
928 | lda quietd ; a quiet display\r | |
929 | ana a\r | |
930 | jnz sfi13a ; yes, dont write\r | |
931 | call scrfln ;Position cursor\r | |
932 | sfi13a: lxi d,data ;Print the file name though, in either case\r | |
933 | call prtstr\r | |
934 | lda pktnum ;Get the packet number.\r | |
935 | sta argblk\r | |
936 | mvi a,'F' ;File header packet.\r | |
937 | call spack ;Send the packet.\r | |
938 | jmp abort ; Failed, abort.\r | |
939 | call rpack ;Get a packet.\r | |
940 | jmp r ; Trashed packet don't change state, retry.\r | |
941 | cpi 'Y' ;ACK?\r | |
942 | jnz sfile2 ;If not try next.\r | |
943 | call compp\r | |
944 | rnz ;If not hold out for the right one.\r | |
945 | sfil14: call countp\r | |
946 | lda numtry ;Get the number of tries.\r | |
947 | sta oldtry ;Save it.\r | |
948 | xra a\r | |
949 | sta numtry ;Reset the number of tries.\r | |
950 | sta bytes ;[10] clear the "bytes transferred" counter\r | |
951 | sta bytes+1 ;[10]\r | |
952 | sta bytes+2 ;[10]\r | |
953 | sta bytes+3 ;[10]\r | |
954 | call gtchr ;Fill the first data packet\r | |
955 | jmp sfil16 ;Error go see if its EOF.\r | |
956 | ; ;Got the chars, proceed.\r | |
957 | sta size ;Save the size of the data gotten.\r | |
958 | mvi a,'D' ;Set the state to data send.\r | |
959 | sta state\r | |
960 | ret\r | |
961 | \r | |
962 | sfil16: cpi 0FFH ;Is it EOF?\r | |
963 | jnz abort ;If not give up.\r | |
964 | mvi a,'Z' ;Set the state to EOF.\r | |
965 | sta state\r | |
966 | ret\r | |
967 | \r | |
968 | sfile2: cpi 'N' ;NAK?\r | |
969 | jnz sfile3 ;Try if error packet.\r | |
970 | call updrtr ;Update the number of retries.\r | |
971 | lda pktnum ;Get the present packet number.\r | |
972 | inr a ;Increment\r | |
973 | ani 3FH ; modulo 64\r | |
974 | mov b,a\r | |
975 | lda argblk ;Get the packet's number.\r | |
976 | cmp b ;Is the packet's number one more than now?\r | |
977 | rnz ;If not go try again.\r | |
978 | jmp sfil14 ;Just as good as a ACK;go to the ACK code.\r | |
979 | \r | |
980 | sfile3: cpi 'E' ;Is it an error packet.\r | |
981 | jnz abort\r | |
982 | call error\r | |
983 | jmp abort\r | |
984 | \r | |
985 | ; copy remote name into packet to send [gnn]\r | |
986 | sfile4: xchg ;[gnn] keep pointer to packet\r | |
987 | lxi h,remnam ;[gnn] set pointer to name\r | |
988 | mov c,a ;[gnn] keep count of length\r | |
989 | mov b,a ;[gnn] and set as loop counter\r | |
990 | sfil41: mov a,m ;[gnn] get a character\r | |
991 | stax d ;[gnn] copy it to packet\r | |
992 | inx h ;[gnn] \r | |
993 | inx d ;[gnn] move pointers\r | |
994 | dcr b ;[gnn] \r | |
995 | mov a,b ;[gnn] \r | |
996 | ora a ;[gnn] done them all?\r | |
997 | jnz sfil41 ;[gnn] repeat until done\r | |
998 | xchg ;[gnn] get final position\r | |
999 | shld datptr ;[gnn] and save it\r | |
1000 | jmp sfil13 ;[gnn] now go and send packet\r | |
1001 | \r | |
1002 | ;\f\r | |
1003 | ; Send data\r | |
1004 | ; called by: send\r | |
1005 | \r | |
1006 | sdata: lda numtry ;Get the number of tries.\r | |
1007 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
1008 | jm sdata1\r | |
1009 | lxi d,erms14\r | |
1010 | call error3\r | |
1011 | jmp abort ;Change the state to abort.\r | |
1012 | \r | |
1013 | sdata1: inr a ;Increment it.\r | |
1014 | sta numtry ;Save the updated number of tries.\r | |
1015 | lxi h, data ;Get a pointer to our data block.\r | |
1016 | shld datptr ;Save it.\r | |
1017 | lxi h,filbuf ;Pointer to chars to be sent.\r | |
1018 | shld cbfptr ;Save position in char buffer.\r | |
1019 | mvi b,1 ;First char.\r | |
1020 | sdat11: lhld cbfptr\r | |
1021 | mov a,m\r | |
1022 | inx h\r | |
1023 | shld cbfptr ;Save position in char buffer.\r | |
1024 | mov c,a ;[jd] preserve character temporarily\r | |
1025 | lda quot8 ;[jd] doing eighth-bit quoting?\r | |
1026 | ora a ;[jd] \r | |
1027 | mov a,c ;[jd] restore char\r | |
1028 | jnz sdat4 ;[jd] using eighth-bit quoting, no warning\r | |
1029 | lda parity ;[jd] get parity\r | |
1030 | cpi parnon ;[jd] none?\r | |
1031 | mov a,c ;[jd] restore character\r | |
1032 | jz sdat4 ;[jd] no parity, leave char alone\r | |
1033 | lda wrn8 ;[jd] look at warning flag\r | |
1034 | ora a ;[jd] have we already given the warning?\r | |
1035 | jnz sdat5 ;[jd] yes, skip this\r | |
1036 | mov a,c ;[jd] restore character...\r | |
1037 | ani 80h ;[jd] examine parity\r | |
1038 | jz sdat5 ;[jd] no parity, no warning.\r | |
1039 | call parwrn ;[jd] ...print warning - parity lost\r | |
1040 | mvi a,0ffh ;[jd] remember that we sent the message\r | |
1041 | sta wrn8 ;[jd]\r | |
1042 | sdat5: mov a,c ;[jd] restore character again\r | |
1043 | ani 7fh ;[jd] strip parity so not checksummed\r | |
1044 | sdat4: lhld datptr\r | |
1045 | mov m,a ;Put the char in the data packet.\r | |
1046 | inx h\r | |
1047 | shld datptr ;Save position in data packet.\r | |
1048 | inr b ;Increment the count.\r | |
1049 | lda size ;Get the number of chars in char buffer.\r | |
1050 | cmp b ;Have we transfered that many?\r | |
1051 | jp sdat11 ;If not get another.\r | |
1052 | lda size ;Number of char in char buffer.\r | |
1053 | sta argblk+1\r | |
1054 | lda pktnum ;Get the packet number.\r | |
1055 | sta argblk\r | |
1056 | mvi a,'D' ;Data packet.\r | |
1057 | call spack ;Send the packet.\r | |
1058 | jmp abort ; Failed, abort.\r | |
1059 | call rpack ;Get a packet.\r | |
1060 | jmp r ; Trashed packet don't change state, retry.\r | |
1061 | cpi 'Y' ;ACK?\r | |
1062 | jnz sdata2 ;If not try next.\r | |
1063 | call compp\r | |
1064 | rnz ;If not hold out for the right one.\r | |
1065 | lda argblk ;Get the packet number back\r | |
1066 | call countp\r | |
1067 | lda numtry ;Get the number of tries.\r | |
1068 | sta oldtry ;Save it.\r | |
1069 | xra a\r | |
1070 | sta numtry ;Reset the number of tries.\r | |
1071 | lda argblk+1 ;Get the data length\r | |
1072 | cpi 1 ;Check if only 1 character?\r | |
1073 | jnz sdat15 ;If not, just continue\r | |
1074 | lda data ;Got one character, get it from data\r | |
1075 | cpi 'Z' ;Want to abort entire stream?\r | |
1076 | jnz sdat14 ;If not, check for just this file\r | |
1077 | sta czseen ;Yes, remember it\r | |
1078 | jmp sdat16 ;[MF] and set EOF state\r | |
1079 | sdat14: cpi 'X' ;Desire abort of current file?\r | |
1080 | jnz sdat15 ;If not, just continue\r | |
1081 | sta czseen ;Yes, remember that\r | |
1082 | jmp sdat16 ;[MF] and set EOF\r | |
1083 | sdat15: lda czseen ;Also get control-Z flag\r | |
1084 | ora a ;Check if either given\r | |
1085 | jz sdat12 ;If neither given, continue\r | |
1086 | sdat16: mvi a,'Z' ;Change state to EOF\r | |
1087 | sta state ; . . .\r | |
1088 | ret ;And return\r | |
1089 | \r | |
1090 | sdat12: call gtchr\r | |
1091 | jmp sdat13 ;Error go see if its EOF.\r | |
1092 | sta size ;Save the size of the data gotten.\r | |
1093 | ret\r | |
1094 | \r | |
1095 | sdat13: cpi 0FFH ;Is it EOF?\r | |
1096 | jnz abort ;If not give up.\r | |
1097 | mvi a,'Z' ;Set the state to EOF.\r | |
1098 | sta state\r | |
1099 | ret\r | |
1100 | \r | |
1101 | sdata2: cpi 'N' ;NAK?\r | |
1102 | jnz sdata3 ;See if is an error packet.\r | |
1103 | call updrtr ;Update the number of retries.\r | |
1104 | lda pktnum ;Get the present packet number.\r | |
1105 | inr a ;Increment\r | |
1106 | ani 3FH ; modulo 64\r | |
1107 | mov b,a\r | |
1108 | lda argblk ;Get the packet's number.\r | |
1109 | cmp b ;Is the packet's number one more than now?\r | |
1110 | rnz ;If not go try again.\r | |
1111 | jmp sdat12 ;Just as good as a ACK;go to the ACK code.\r | |
1112 | \r | |
1113 | sdata3: cpi 'E' ;Is it an error packet.\r | |
1114 | jnz abort\r | |
1115 | call error\r | |
1116 | jmp abort\r | |
1117 | ;\f\r | |
1118 | ; Send EOF\r | |
1119 | ; called by: send\r | |
1120 | \r | |
1121 | seof: lda numtry ;Get the number of tries.\r | |
1122 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
1123 | jm seof1\r | |
1124 | lxi d,erms14\r | |
1125 | call error3\r | |
1126 | jmp abort ;Change the state to abort.\r | |
1127 | \r | |
1128 | seof1: inr a ;Increment it.\r | |
1129 | sta numtry ;Save the updated number of tries.\r | |
1130 | lda pktnum ;Get the packet number.\r | |
1131 | sta argblk\r | |
1132 | xra a\r | |
1133 | sta argblk+1 ;No data.\r | |
1134 | lda czseen ;Check if C-Z or C-X typed\r | |
1135 | ora a ; . . .\r | |
1136 | jz seof14 ;If not aborted, just keep going\r | |
1137 | mvi a,'D' ;Tell other end to discard packet\r | |
1138 | sta data ;Store in data portion\r | |
1139 | mvi a,1 ;One character\r | |
1140 | sta argblk+1 ;Store the length\r | |
1141 | seof14: mvi a,'Z' ;EOF packet.\r | |
1142 | call spack ;Send the packet.\r | |
1143 | jmp abort ; Failed, abort.\r | |
1144 | call rpack ;Get a packet.\r | |
1145 | jmp r ; Trashed packet don't change state, retry.\r | |
1146 | cpi 'Y' ;ACK?\r | |
1147 | jnz seof2 ;If not try next.\r | |
1148 | call compp\r | |
1149 | rnz ;If not hold out for the right one.\r | |
1150 | seof12: call countp\r | |
1151 | lda numtry ;Get the number of tries.\r | |
1152 | sta oldtry ;Save it.\r | |
1153 | xra a\r | |
1154 | sta numtry ;Reset the number of tries.\r | |
1155 | mvi c,closf ;Close the file.\r | |
1156 | lxi d,fcb\r | |
1157 | call bdos\r | |
1158 | ;* Check if successful\r | |
1159 | lda czseen ;Desire abort of entire stream?\r | |
1160 | cpi 'Z' ;Desire abort of entire stream?\r | |
1161 | jz seof13 ;If so, just give up now\r | |
1162 | call mfname ;Get the next file.\r | |
1163 | jc seof13 ; No more.\r | |
1164 | call getfil ;and open it (assume success)\r | |
1165 | xra a ;Clear A\r | |
1166 | sta czseen ;Since we have not aborted this file\r | |
1167 | mvi a,'F' ;Set the state to file send.\r | |
1168 | sta state\r | |
1169 | ret\r | |
1170 | \r | |
1171 | seof13: mvi a,'B' ;Set the state to EOT.\r | |
1172 | sta state\r | |
1173 | ret\r | |
1174 | \r | |
1175 | seof2: cpi 'N' ;NAK?\r | |
1176 | jnz seof3 ;Try and see if its an error packet.\r | |
1177 | call updrtr ;Update the number of retries.\r | |
1178 | lda pktnum ;Get the present packet number.\r | |
1179 | inr a ;Increment\r | |
1180 | ani 3FH ; modulo 64\r | |
1181 | mov b,a\r | |
1182 | lda argblk ;Get the packet's number.\r | |
1183 | cmp b ;Is the packet's number one more than now?\r | |
1184 | rnz ;If not go try again.\r | |
1185 | jmp seof12 ;Just as good as a ACK;go to the ACK code.\r | |
1186 | \r | |
1187 | seof3: cpi 'E' ;Is it an error packet.\r | |
1188 | jnz abort\r | |
1189 | call error\r | |
1190 | jmp abort\r | |
1191 | ;\f\r | |
1192 | ; Send EOT\r | |
1193 | ; called by: send\r | |
1194 | \r | |
1195 | seot: lda numtry ;Get the number of tries.\r | |
1196 | cpi maxtry ;Have we reached the maximum number of tries?\r | |
1197 | jm seot1\r | |
1198 | lxi d,erms14\r | |
1199 | call error3\r | |
1200 | jmp abort ;Change the state to abort.\r | |
1201 | \r | |
1202 | seot1: inr a ;Increment it.\r | |
1203 | sta numtry ;Save the updated number of tries.\r | |
1204 | lda pktnum ;Get the packet number.\r | |
1205 | sta argblk\r | |
1206 | xra a\r | |
1207 | sta argblk+1 ;No data.\r | |
1208 | mvi a,'B' ;EOF packet.\r | |
1209 | call spack ;Send the packet.\r | |
1210 | jmp abort ; Failed, abort.\r | |
1211 | call rpack ;Get a packet.\r | |
1212 | jmp r ; Trashed packet don't change state, retry.\r | |
1213 | cpi 'Y' ;ACK?\r | |
1214 | jnz seot2 ;If not try next.\r | |
1215 | call compp\r | |
1216 | rnz ;If not hold out for the right one.\r | |
1217 | seot12: call countp\r | |
1218 | lda numtry ;Get the number of tries.\r | |
1219 | sta oldtry ;Save it.\r | |
1220 | xra a\r | |
1221 | sta numtry ;Reset the number of tries.\r | |
1222 | mvi a,'C' ;Set the state to file send.\r | |
1223 | sta state\r | |
1224 | ret\r | |
1225 | \r | |
1226 | seot2: cpi 'N' ;NAK?\r | |
1227 | jnz seot3 ;Is it error.\r | |
1228 | call updrtr ;Update the number of retries.\r | |
1229 | lda pktnum ;Get the present packet number.\r | |
1230 | inr a ;Increment\r | |
1231 | ani 3FH ; modulo 64\r | |
1232 | mov b,a\r | |
1233 | lda argblk ;Get the packet's number.\r | |
1234 | cmp b ;Is the packet's number one more than now?\r | |
1235 | rnz ;If not go try again.\r | |
1236 | jmp seot12 ;Just as good as a ACK;go to the ACK code.\r | |
1237 | \r | |
1238 | seot3: cpi 'E' ;Is it an error packet.\r | |
1239 | jnz abort\r | |
1240 | call error\r | |
1241 | jmp abort\r | |
1242 | ;\f\r | |
1243 | ; This routine sets up the data for init packet (either the\r | |
1244 | ; Send_init or ACK packet).\r | |
1245 | ; called by: rinit, rfile, sinit\r | |
1246 | ;\r | |
1247 | ; Called by rinit, rfile and sinit. See what WE want from the other fella\r | |
1248 | ;\r | |
1249 | ; [11] by OBS - Stripped out all the new capas code etc and reverted\r | |
1250 | ; to Good Ol' Basic Kermit again!\r | |
1251 | ; Those keen should study the followin gode with care, and remove\r | |
1252 | ; or add semicolons as indicated.\r | |
1253 | ;\r | |
1254 | ; See also SPAR which decodes what comes in. It also decodes bits in \r | |
1255 | ; the "capability" fields. (Two CAPAS files allowed from remote\r | |
1256 | ; machines, but we will only send one at max.) Note that not all \r | |
1257 | ; if any of the capability bits will be used.\r | |
1258 | ;\r | |
1259 | ; Definitions - init packet (data section only.. rest of header assumed OK)\r | |
1260 | ; Byte 0 Maximum length I want to send\r | |
1261 | ; 1 The Timeout I want you to use\r | |
1262 | ; 2 Number of PAD characters I want tot use (May be null)\r | |
1263 | ; 3 The PAD character I want to use (May be Null)\r | |
1264 | ; 4 The End-of-Line character I will use (Carriage Return)\r | |
1265 | ; 5 The control character Quote Character I will use (#)\r | |
1266 | ; 6 The parity bit Quote Character I will use (&)\r | |
1267 | ; 7 The Checktype I will use\r | |
1268 | ; 8 The repeat prefix I will use (Null, as we cannot to repeats)\r | |
1269 | ; 9 Capability Byte 0 (See SPAR for defs)\r | |
1270 | ; 10 Capability byte 1 ( --- " --- but we will not send it.)\r | |
1271 | ; 11 The number of packets I will send per window (not used)\r | |
1272 | ; 12 MAXL1 - Long packet size, ms count\r | |
1273 | ; 13 MAXL2 - Long packet size, ls count\r | |
1274 | ;\r | |
1275 | ;\r | |
1276 | ; Enter with HL pointing to the "data" part of the packet.\r | |
1277 | \r | |
1278 | ;\r | |
1279 | ; older part of rpar follows...\r | |
1280 | ;\r | |
1281 | ;\r | |
1282 | rpar: lda rpsiz ;Get the receive packet size.\r | |
1283 | adi space ;Add a space to make it printable.\r | |
1284 | mov m,a ;Put it in the packet.\r | |
1285 | inx h ;Point to the next char.\r | |
1286 | lda rtime ;Get the receive packet time out.\r | |
1287 | adi space ;Add a space.\r | |
1288 | mov m,a ;Put it in the packet.\r | |
1289 | inx h\r | |
1290 | lda rpad ;Get the number of padding chars.\r | |
1291 | adi space\r | |
1292 | mov m,a\r | |
1293 | inx h\r | |
1294 | lda rpadch ;Get the padding char.\r | |
1295 | adi 100O ;Uncontrol it.\r | |
1296 | ani 7FH\r | |
1297 | mov m,a\r | |
1298 | inx h\r | |
1299 | lda reol ;Get the EOL char.\r | |
1300 | adi space\r | |
1301 | mov m,a\r | |
1302 | inx h\r | |
1303 | lda rquote ;Get the quote char.\r | |
1304 | mov m,a\r | |
1305 | inx h\r | |
1306 | mvi m,'Y' ;[jd] we know how to do 8-bit quoting\r | |
1307 | lda parity ;[jd]\r | |
1308 | cpi parnon ;[jd] parity none?\r | |
1309 | jz rpar1 ;[jd] yes, keep going\r | |
1310 | lda qbchr ;[jd] no, better request 8-bit quoting\r | |
1311 | mov m,a\r | |
1312 | \r | |
1313 | rpar1:\r | |
1314 | inx h ;Advance to next\r | |
1315 | lda chktyp ;Get desired block check type\r | |
1316 | mov m,a ;Store it\r | |
1317 | inx h ;Advance pointer\r | |
1318 | \r | |
1319 | ; Comment out the next two lines for capas etc. WILL require debugging\r | |
1320 | mvi a,8 ; this id the older end for this routine. May be useful.\r | |
1321 | ret\r | |
1322 | \r | |
1323 | ; [11] Rest not needed for now, commented out\r | |
1324 | ; [10] (to ret)\r | |
1325 | ; New additions to rpar follows...\r | |
1326 | \r | |
1327 | ; lda rcap1 ; get the first capability byte\r | |
1328 | ; ani 3eh ; mask out bit 0, ie only one CAPAS byte\r | |
1329 | ; adi space ; tochar it\r | |
1330 | ; mov m,a\r | |
1331 | ; inx h\r | |
1332 | ; mvi m,space ; No windows, ie space to packet\r | |
1333 | ; inx h\r | |
1334 | ; push h ; we need the HL regs for maths.\r | |
1335 | ; lhld rdpkt ; get receive packet length\r | |
1336 | ; lxi d,95 ; we want hl div 95 and hl mod 95\r | |
1337 | ; call divide ; return with divsion in hl, remainder in de\r | |
1338 | ; mov a,l ; two sets of bytes\r | |
1339 | ; pop h\r | |
1340 | ; adi space ; tochar(maxl1)\r | |
1341 | ; mov m,a\r | |
1342 | ; inx h\r | |
1343 | ; mov a,l\r | |
1344 | ; adi space ; tochar(maxl2)\r | |
1345 | ; mov m,a\r | |
1346 | ;\r | |
1347 | ; done all, set databytes = 12 and return\r | |
1348 | ; mvi a,12 ; 12 bits of data\r | |
1349 | ; ret\r | |
1350 | \r | |
1351 | ;[11] End of commented out code for rpar\r | |
1352 | \r | |
1353 | \r | |
1354 | ;\f\r | |
1355 | ; This routine reads in all the send_init packet information.\r | |
1356 | ; called by: rinit, sinit\r | |
1357 | \r | |
1358 | ;[11] As for rpar, restore the "old" kermit code for non-capas Kermit.\r | |
1359 | ;[10] (to ret at end)\r | |
1360 | ;\r | |
1361 | ; SPAR - routine to decode parameters received from the remote end\r | |
1362 | ;\r | |
1363 | ; Called by rinit,sinit\r | |
1364 | ;\r | |
1365 | ; Entry: a: Number of databytes in packet\r | |
1366 | ; hl: Pointer to "data" part of packet\r | |
1367 | ;\r | |
1368 | ;spar: sta temp4 ; save for a while\r | |
1369 | ; ; first clear some variables\r | |
1370 | ; lda dspsiz ; get default "send" packet length\r | |
1371 | ; sta spktl\r | |
1372 | ; lda dstime ; get default time-out\r | |
1373 | ; sta stimeo\r | |
1374 | ; xra a ; set no pad characters by default\r | |
1375 | ; sta spad\r | |
1376 | ; lda dspadc ; get the default padding character\r | |
1377 | ; sta spadc\r | |
1378 | ; mvi a,cr ; default end of line character (CR)\r | |
1379 | ; sta seol\r | |
1380 | ; mvi a,dsquot ; default quote character\r | |
1381 | ; sta squote\r | |
1382 | ; mvi a,dsbqut ; default binary quote character\r | |
1383 | ; sta qbchr\r | |
1384 | ; mvi a,dschkt ; set checktype = 1 for inits\r | |
1385 | ; sta inichk\r | |
1386 | ; mvi a,space ; no repeat prefixing ( otherwise ~)\r | |
1387 | ; sta srept\r | |
1388 | ;\r | |
1389 | ; Now follows the "capabilities" bits... 5 bits per capas byte.\r | |
1390 | ;\r | |
1391 | ; Note: Before extracting any data bits, apply unchar() to get the \r | |
1392 | ; six ls bits. If bit 0 = 1 the a subsequent capaa byte follows\r | |
1393 | ;\r | |
1394 | ; Byte0: Bit 0: Set to 1 if there are subsequent CAPAS bytes\r | |
1395 | ; 1: (Cap. 5) Set to 1 for long packets. Second byte\r | |
1396 | ; AFTER the last capas byte has packet length DIV 95\r | |
1397 | ; and Thire byte has length MOD 95\r | |
1398 | ; 2: (Cap. 4) Sliding Windows. If used, first byte AFTER\r | |
1399 | ; last capas byte has TOCHAR(no. of packets in window)\r | |
1400 | ; 3: (Cap. 3) Ability to accept "A" (attribute packets)\r | |
1401 | ; 4: (Cap. 2) Reserved\r | |
1402 | ; 5: (Cap. 1) Reserved\r | |
1403 | ; Byte 2 onward: not used in this implementation. Any capas bytes sent \r | |
1404 | ; will be stored, however.\r | |
1405 | ;\r | |
1406 | ; lda temp4 ; get the number of bytes to test\r | |
1407 | ; mov c,a ; to a count register\r | |
1408 | ; mov a,m ; get first byte\r | |
1409 | ; call decc ; unchar it, and decrement c\r | |
1410 | ; sta spsiz ; save a send packet size\r | |
1411 | ; jz sparx ; if no more, exit\r | |
1412 | ;\r | |
1413 | ; mov a,m ; get timout\r | |
1414 | ; call decc\r | |
1415 | ; sta stime ; save timeout\r | |
1416 | ; jz sparx\r | |
1417 | ;\r | |
1418 | ; mov a,m ; get pad characters\r | |
1419 | ; call decc \r | |
1420 | ; sta spadc ; save it\r | |
1421 | ; jz sparx\r | |
1422 | ;\r | |
1423 | ; mov a,m ; get pad character count\r | |
1424 | ; call decc\r | |
1425 | ; sta spad\r | |
1426 | ; jz sparx\r | |
1427 | ;\r | |
1428 | ; mov a,m ; get send EOL\r | |
1429 | ; call decc\r | |
1430 | ; sta seol\r | |
1431 | ; jz sparx\r | |
1432 | ;\r | |
1433 | ; mov a,m ; get control quote character\r | |
1434 | ; call decc\r | |
1435 | ; sta squote\r | |
1436 | ; jz sparx\r | |
1437 | ;\r | |
1438 | ; mov a,m ; get binary (parity) quote char\r | |
1439 | ; mov b,a ; this time we actually WANT accumulator\r | |
1440 | ; cpi space ; are we doing 8th bit quoteing\r | |
1441 | ; jz spar1 ; dont know, assume not\r | |
1442 | ; cpi 'N' ; definately not?\r | |
1443 | ; jz spar1\r | |
1444 | ; cpi 'Y' ; definately - use &\r | |
1445 | ; jz spar2\r | |
1446 | ; sta squote ; else save the new character\r | |
1447 | ;spar2: lda parity ; see if we are using the parity bit\r | |
1448 | ; cpi parnon ; no parity => no quoting\r | |
1449 | ; jz spar3 ; yup, so use the default quote character &\r | |
1450 | ;\r | |
1451 | ;spar1: xra a ; save not quoting\r | |
1452 | ; sta squote\r | |
1453 | ;spar3: call decc ; update counters etc\r | |
1454 | ; jz sparx\r | |
1455 | ;\r | |
1456 | ; mov a,m ; get repeat prefixing\r | |
1457 | ; call decc\r | |
1458 | ; push psw ; save flags\r | |
1459 | ; cpi space-32 ; we want it?\r | |
1460 | ; jz spar4\r | |
1461 | ; sta srept\r | |
1462 | ;spar4: pop psw ; restore flags\r | |
1463 | ; jz sparx\r | |
1464 | ;\r | |
1465 | ; lxi d,scapas ; point to start of capability byte(s)\r | |
1466 | ; push psw ; must do this...\r | |
1467 | ;spar5: pop psw ; cos we restore the spack\r | |
1468 | ; mov a,m\r | |
1469 | ; call decc ; get scap1 (or n)\r | |
1470 | ; sta scap1\r | |
1471 | ; push psw\r | |
1472 | ; ani 01 ; another byte following?\r | |
1473 | ; jnz spar5\r | |
1474 | ; pop psw ; see if any other data bytes (Windows etc)\r | |
1475 | ; jz sparx\r | |
1476 | ;\r | |
1477 | ; mov a,m ; get window size\r | |
1478 | ; call decc\r | |
1479 | ; sta swindo\r | |
1480 | ; jz sparx\r | |
1481 | ;\r | |
1482 | ; mov a,m ; get long packets ms bits\r | |
1483 | ; call decc ;\r | |
1484 | ; mov d,a ; unchared ms bits-ish\r | |
1485 | ; mov a,m\r | |
1486 | ; call decc ; ls bits-ish\r | |
1487 | ; push h ; and we are doing maths\r | |
1488 | ; push b ; and an intermediate result in c\r | |
1489 | ; push psw ; we want flags and the ls bits...\r | |
1490 | ; mvi b,0\r | |
1491 | ; mov c,d ; get ms bits-ish to bc\r | |
1492 | ; push b ; get number to hl\r | |
1493 | ; pop h\r | |
1494 | ; now multipy by 95\r | |
1495 | ; dad h ;*2\r | |
1496 | ; dad h ;*4\r | |
1497 | ; dad h ;*8\r | |
1498 | ; dad h ;*16\r | |
1499 | ; push h ; *16 to ...\r | |
1500 | ; pop d ; ... de\r | |
1501 | ; dad h ;*32\r | |
1502 | ; dad d ; *(32+16) = *48\r | |
1503 | ; dad h ; *96\r | |
1504 | ; mov a,l ; *(96-1)\r | |
1505 | ; sub c\r | |
1506 | ; mov l,a\r | |
1507 | ; mov a,0\r | |
1508 | ; sbb h\r | |
1509 | ; mov h,a\r | |
1510 | ; pop psw ; restore ls bitsish\r | |
1511 | ; mov e,a\r | |
1512 | ; mvi d,0\r | |
1513 | ; dad d ; *95 + ls bits. Phew.\r | |
1514 | ; shld sdpkt ; save long packet length\r | |
1515 | ; pop b\r | |
1516 | ; pop h ; restore regs\r | |
1517 | ;\r | |
1518 | ;sparx: ret ; if here, (assume) no more data to read in\r | |
1519 | ;[10] routines required follow\r | |
1520 | ;decc: mov a,m ; get data byte\r | |
1521 | ; sui space ; unchar it\r | |
1522 | ; inx h ; increment input pointer\r | |
1523 | ; dcr c ; decrement data counter\r | |
1524 | ; ret ; return\r | |
1525 | ;[10] end or spar replacement\r | |
1526 | \r | |
1527 | ;[11] Restore older spar....\r | |
1528 | ; Older spar follows...\r | |
1529 | spar: sta temp4 ;Save the number of arguments.\r | |
1530 | ; Initialize some variables to their required default values, so we use\r | |
1531 | ; the right values even if the remote Kermit doesn't send the full packet:\r | |
1532 | ; ; we don't do anything with timeout values yet.\r | |
1533 | ; ; no default pad count/pad character?\r | |
1534 | mvi a,cr ; EOL character = carriage-return\r | |
1535 | sta seol\r | |
1536 | mvi a,'#' ; quote character = '#'\r | |
1537 | sta squote\r | |
1538 | mvi a,'&' ; eighth-bit quote character = '&'\r | |
1539 | sta qbchr\r | |
1540 | mvi a,'1' ; block-check = 1-character-checksum\r | |
1541 | sta inichk\r | |
1542 | ; \r | |
1543 | mov a,m ;Get the max packet size.\r | |
1544 | sbi space ;Subtract a space.\r | |
1545 | sta spsiz ;Save it.\r | |
1546 | lda temp4\r | |
1547 | cpi 3 ;Fewer than three pieces?\r | |
1548 | rm ;If so we are done.\r | |
1549 | inx h\r | |
1550 | inx h ;Increment past the time out info.\r | |
1551 | mov a,m ;Get the number of padding chars.\r | |
1552 | sbi space\r | |
1553 | sta spad\r | |
1554 | lda temp4\r | |
1555 | cpi 4 ;Fewer than four pieces?\r | |
1556 | rm ;If so we are done.\r | |
1557 | inx h\r | |
1558 | mov a,m ;Get the padding char.\r | |
1559 | adi 100O ;Re-controlify it.\r | |
1560 | ani 7FH\r | |
1561 | sta spadch\r | |
1562 | lda temp4\r | |
1563 | cpi 5 ;Fewer than five pieces?\r | |
1564 | rm ;If so we are done.\r | |
1565 | inx h\r | |
1566 | mov a,m ;Get the EOL char.\r | |
1567 | sbi space\r | |
1568 | sta seol\r | |
1569 | lda temp4\r | |
1570 | cpi 6 ;Fewer than six pieces?\r | |
1571 | rm ;If so we are done.\r | |
1572 | inx h\r | |
1573 | mov a,m ;Get the quote char.\r | |
1574 | sta squote\r | |
1575 | lda temp4 ;Get the amount of data supplied\r | |
1576 | cpi 7 ;Have an 8-bit quote?\r | |
1577 | rm ;If not there, all done\r | |
1578 | inx h ;Yes, get the character\r | |
1579 | mvi a,0 ;[jd] \r | |
1580 | sta quot8 ;[jd] assume not quoting\r | |
1581 | mov a,m ;Get the supplied character\r | |
1582 | cpi 'N' ;[jd] No?\r | |
1583 | jz spar1 ;[jd] then don't try to do it\r | |
1584 | cpi space ;[jd] maybe they don't know about it...\r | |
1585 | jz spar1 ;[jd] then don't try to do it.\r | |
1586 | cpi 'Y' ;[jd] Yes?\r | |
1587 | jnz spar2 ;[jd] if not 'Y', assume it's a quote char.\r | |
1588 | lda parity ;[jd] using parity?\r | |
1589 | cpi parnon ;[jd] no, don't need quoting...\r | |
1590 | jz spar1 ;[jd] \r | |
1591 | mvi a,0ffh ;[jd] else turn on...\r | |
1592 | sta quot8 ;[jd] ...quote flag\r | |
1593 | jmp spar1\r | |
1594 | \r | |
1595 | ;[11] Note: If capas etc required, beware of the next two lables, as these \r | |
1596 | ; are used elswhere.\r | |
1597 | \r | |
1598 | spar2: sta qbchr ;[jd] use their quote char (should validate)\r | |
1599 | mvi a,0ffh\r | |
1600 | sta quot8 ;[jd] turn quote flag and fall thru...\r | |
1601 | \r | |
1602 | spar1: lda temp4 ;Determine if block check type given\r | |
1603 | cpi 8 ;Is the field there?\r | |
1604 | rm ;If not, all done\r | |
1605 | inx h ;Point to the character\r | |
1606 | mov a,m ;Get the value\r | |
1607 | mov b,a ;Copy value\r | |
1608 | lda chktyp ;Get our type\r | |
1609 | cmp b ;Is it our desired type?\r | |
1610 | rnz ; If not, use default (1-character-checksum)\r | |
1611 | sta inichk ; Match, store as type to use after init\r | |
1612 | ret ; and return\r | |
1613 | ;[10] end of replacement\r | |
1614 | ;[11] end of replacement of replacement (ie back to original code)\r | |
1615 | ;\f\r | |
1616 | \r | |
1617 | ; Copy characters from packet to disk (or screen)\r | |
1618 | ; called by: rdata\r | |
1619 | \r | |
1620 | ptchr: sta temp1 ;Save the size.\r | |
1621 | lda remtxt ;[MF]Get remote command flag\r | |
1622 | ora a ;[MF]Remote command in progress?\r | |
1623 | jnz ptchr0 ;[MF]Yes, don't check for file collisions\r | |
1624 | lda flwflg ;[MF]Get File Warning (Set Collision) flag\r | |
1625 | cpi 3 ;[MF]SET COLLISION DISCARD?\r | |
1626 | jnz ptchr0 ;[MF]No\r | |
1627 | lda dscflg ;[MF]Yes, get "discard" flag\r | |
1628 | ora a ;[MF]Discarding file?\r | |
1629 | jz ptchr0 ;[MF]No\r | |
1630 | mvi a,'X' ;[MF]Yes, simulate a user rejection\r | |
1631 | sta czseen ;[MF]...\r | |
1632 | jmp rskp ;[MF]and pretend success\r | |
1633 | ptchr0: ;[MF]\r | |
1634 | lxi h,data ;Beginning of received packet data.\r | |
1635 | shld outpnt ;Remember where we are.\r | |
1636 | lda rquote\r | |
1637 | mov b,a ;Keep the quote char in b.\r | |
1638 | mvi c,0 ;[jd] assume no 8-bit quote char\r | |
1639 | lda quot8 ;[jd] doing 8-bit quoting?\r | |
1640 | ora a\r | |
1641 | jz ptchr1 ;[jd] no, keep going\r | |
1642 | lda qbchr ;[jd] else get 8-bit quote char\r | |
1643 | mov c,a ;[jd] keep this in c\r | |
1644 | ptchr1: lxi h,temp1\r | |
1645 | dcr m ;Decrement # of chars in packet.\r | |
1646 | jm rskp ;Return successfully if done.\r | |
1647 | lda remtxt ; to screen only?\r | |
1648 | ana a\r | |
1649 | jnz ptchr2 ; dont do any disk stuff\r | |
1650 | lxi h,chrcnt ;Number of chars remaining in dma.\r | |
1651 | dcr m ;Decrement.\r | |
1652 | jp ptchr2 ;Continue if space left.\r | |
1653 | call outbuf ;Output it if full.\r | |
1654 | jmp ptchr9 ; Error return if disk is full.\r | |
1655 | ptchr2: lhld outpnt ;Get position in output buffer.\r | |
1656 | mov a,m ;Grab a char.\r | |
1657 | inx h\r | |
1658 | shld outpnt ;and bump pointer.\r | |
1659 | mvi e,0 ;[jd] assume nothing to OR in.\r | |
1660 | cmp c ;[jd] is it the binary quote char?\r | |
1661 | jnz ptch2a ;[jd] no, keep going\r | |
1662 | mvi e,80h ;[jd] include parity bit\r | |
1663 | lda temp1\r | |
1664 | dcr a\r | |
1665 | sta temp1 ;[jd] decrement character count\r | |
1666 | mov a,m ;[jd] get next character\r | |
1667 | inx h\r | |
1668 | shld outpnt\r | |
1669 | ptch2a: cmp b ;Is it the quote char?\r | |
1670 | jnz ptchr3 ;[jd] changed to ptchr3 so includes parity\r | |
1671 | mov a,m ;Get the quoted character\r | |
1672 | inx h\r | |
1673 | shld outpnt ;and bump pointer.\r | |
1674 | lxi h,temp1\r | |
1675 | dcr m ;Decrement # of chars in packet.\r | |
1676 | mov d,a ;Save the char.\r | |
1677 | ani 80H ;Turn off all but the parity bit.\r | |
1678 | ora e ;[jd] let parity come from either (???)\r | |
1679 | mov e,a ;Save the parity bit.\r | |
1680 | mov a,d ;Get the char.\r | |
1681 | ani 7FH ;Turn off the parity bit.\r | |
1682 | cmp b ;Is it the quote char?\r | |
1683 | jz ptchr3 ;If so just go write it out.\r | |
1684 | cmp c ;[jd] maybe it's the 8-bit prefix character?\r | |
1685 | jz ptchr3 ;[jd] then don't controllify.\r | |
1686 | mov a,d ;Get the char.\r | |
1687 | adi 40H ;Make the character a control char again.\r | |
1688 | ani 7FH ;Modulo 128.\r | |
1689 | ptchr3: ora e ;Or in the parity bit.\r | |
1690 | sta temp3 ; save for a while\r | |
1691 | lda remtxt ; to screen or disk?\r | |
1692 | ana a\r | |
1693 | lda temp3\r | |
1694 | jz ptch31 ; to disk\r | |
1695 | push h\r | |
1696 | push d\r | |
1697 | push b\r | |
1698 | mov e,a ; to display\r | |
1699 | mvi c,dconio\r | |
1700 | call bdos\r | |
1701 | pop b\r | |
1702 | pop d\r | |
1703 | pop h\r | |
1704 | jmp ptchr1 ; continue\r | |
1705 | \r | |
1706 | ptch31: lhld bufpnt ;Destination buffer.\r | |
1707 | mov m,a ;Store it.\r | |
1708 | inx h\r | |
1709 | shld bufpnt ;Update the pointer\r | |
1710 | jmp ptchr1 ;and loop to next char.\r | |
1711 | \r | |
1712 | ptchr9: lxi d,erms11 ; "?Disk full"\r | |
1713 | push d ;[MF] Save pointer\r | |
1714 | call error3 ; put it on the error line\r | |
1715 | pop d ;[MF] Restore pointer\r | |
1716 | lxi h,data ;[MF] Where to put the message for "e" packet\r | |
1717 | lda argblk ;[MF] Get packet-number\r | |
1718 | call countp ;[MF]Increment it\r | |
1719 | sta argblk ;[MF] as packet to send\r | |
1720 | xra a ;[MF] Zero length of packet data\r | |
1721 | sta temp1 ;[MF] ...\r | |
1722 | ptch9a: ldax d ;[MF] Get a character to copy\r | |
1723 | cpi cr ;[MF] No more to copy?\r | |
1724 | jz ptch9b ;[MF] Yes, we can send the packet\r | |
1725 | mov m,a ;[MF] No, copy the character\r | |
1726 | inx d ;[MF] and increment source/dest pointers\r | |
1727 | inx h ;[MF] ...\r | |
1728 | lda temp1 ;[MF] Get character count\r | |
1729 | inr a ;[MF] and increment it\r | |
1730 | sta temp1 ;[MF] ...\r | |
1731 | jmp ptch9a ;[MF] Copy entire error message\r | |
1732 | ptch9b: mvi m,0 ;[MF]Put in a zero\r | |
1733 | lda temp1 ;[MF] Get number of characters in the message\r | |
1734 | sta argblk+1 ;[MF] and store as number of packet data chars\r | |
1735 | mvi a,'E' ;[MF] Make it an error packet\r | |
1736 | call spack ;[MF] Send the error packet\r | |
1737 | nop ;[MF] Don't really care if\r | |
1738 | nop ;[MF] the send fails since we're\r | |
1739 | nop ;[MF] bombing off anyway\r | |
1740 | ret ; take error return.\r | |
1741 | ;\f\r | |
1742 | ; Fill a data packet from file\r | |
1743 | ; called by: sfile, sdata\r | |
1744 | \r | |
1745 | gtchr: lda squote ;Get the quote char.\r | |
1746 | mov c,a ;Keep quote char in c.\r | |
1747 | lda curchk ;Get current block check type\r | |
1748 | sui '1' ;Get the extra overhead\r | |
1749 | mov b,a ;Get a copy\r | |
1750 | lda spsiz ;Get the maximum packet size.\r | |
1751 | sui 5 ;Subtract the overhead.\r | |
1752 | sub b ;Determine max packet length\r | |
1753 | sta temp1 ;This is the number of chars we are to get.\r | |
1754 | lxi h,filbuf ;Where to put the data.\r | |
1755 | shld cbfptr ;Remember where we are.\r | |
1756 | mvi b,0 ;No chars.\r | |
1757 | gtchr1: lda temp1\r | |
1758 | dcr a ;Decrement the number of chars left.\r | |
1759 | jp gtchr2 ;Go on if there is more than one left.\r | |
1760 | mov a,b ;Return the count in A.\r | |
1761 | jmp rskp\r | |
1762 | \r | |
1763 | gtchr2: sta temp1\r | |
1764 | lda chrcnt ;Space left in the DMA.\r | |
1765 | dcr a\r | |
1766 | ;* Can improve order here.\r | |
1767 | jm gtchr3\r | |
1768 | sta chrcnt\r | |
1769 | jmp gtchr4\r | |
1770 | \r | |
1771 | gtchr3: call inbuf ;Get another buffer full.\r | |
1772 | jmp gtch30 ; If no more return what we got.\r | |
1773 | jmp gtchr4 ;If we got some, proceed.\r | |
1774 | \r | |
1775 | gtch30: mov a,b ;Return the count in A.\r | |
1776 | ora a ;Get any chars?\r | |
1777 | jnz rskp ;If so return them.\r | |
1778 | jmp gtceof ;If not, say we found the end of the file.\r | |
1779 | \r | |
1780 | gtchr4: lhld bufpnt ;Position in DMA.\r | |
1781 | mov a,m ;Get a char from the file.\r | |
1782 | inx h\r | |
1783 | shld bufpnt\r | |
1784 | mov d,a ;Save the char.\r | |
1785 | ani 80H ;Turn off all but parity.\r | |
1786 | mov e,a ;Save the parity bit.\r | |
1787 | jz gtch4a ;[jd] no parity, skip this check...\r | |
1788 | lda quot8 ;[jd] doing eighth-bit quoting?\r | |
1789 | ora a\r | |
1790 | jz gtch4a ;[jd] no, just proceed normally\r | |
1791 | lda temp1 ;[jd] get space remaining\r | |
1792 | cpi 2 ;[jd] 3 chrs left (one cnted already)?\r | |
1793 | jm gtchr9 ;[jd] no, skip this\r | |
1794 | dcr a ;[jd] decrement space remaining\r | |
1795 | sta temp1 ;[jd] put back.\r | |
1796 | lhld cbfptr ;[jd] Position in character buffer.\r | |
1797 | lda qbchr ;[jd] get quote character\r | |
1798 | mov m,a ;]jd] Put the quote char in the buffer.\r | |
1799 | inx h ;[jd] increment destination buffer pointer\r | |
1800 | shld cbfptr ;[jd] store the pointer back\r | |
1801 | inr b ;[jd] Increment the char count.\r | |
1802 | mvi e,0 ;[jd] no parity bit to OR in.\r | |
1803 | ;[jd] fall thru...\r | |
1804 | \r | |
1805 | gtch4a: mov a,d ;Restore the char.\r | |
1806 | ani 7FH ;Turn off the parity.\r | |
1807 | mov d,a ;[jd] save here for later...\r | |
1808 | cpi space ;Compare to a space.\r | |
1809 | jm gtchr5 ;If less then its a control char, handle it.\r | |
1810 | cpi del ;Is the char a delete?\r | |
1811 | jz gtchr5 ;Go quote it.\r | |
1812 | lda quot8 ; Are we doing 8th-bit quoting?\r | |
1813 | ora a\r | |
1814 | jz gtch4c ; if not, skip this test and restore character.\r | |
1815 | lda qbchr ; get 8th-bit quote character\r | |
1816 | cmp d ; same as current character?\r | |
1817 | jz gtch4b ; yes, have to quote it...\r | |
1818 | gtch4c: mov a,d ; no. get character back again.\r | |
1819 | cmp c ;Is it the quote char?\r | |
1820 | jnz gtchr8 ;If not proceed.\r | |
1821 | gtch4b: lxi h,temp1 ;[jd] point to char count\r | |
1822 | dcr m ;[jd] decrement (know room for at least one)\r | |
1823 | lhld cbfptr ;Position in character buffer.\r | |
1824 | mov m,c ;Put the (quote) char in the buffer.\r | |
1825 | inx h\r | |
1826 | shld cbfptr\r | |
1827 | inr b ;Increment the char count.\r | |
1828 | mov a,d ;[jd] restore character again\r | |
1829 | jmp gtchr8\r | |
1830 | \r | |
1831 | gtchr5: \r | |
1832 | ;[gnn] ignore parity for checking\r | |
1833 | ; ora e ;Turn on the parity bit.\r | |
1834 | \r | |
1835 | cpi ('Z'-100O) ;Is it a ^Z?\r | |
1836 | jnz gtchr7 ;If not just proceed.\r | |
1837 | lda cpmflg ;Was the file created by CPM...\r | |
1838 | cpi 1 ;in ASCII-mode ?\r | |
1839 | jz gtch52 ;Control-Z stops text\r | |
1840 | cpi 2 ;in BINARY mode?\r | |
1841 | jz gtchr6 ;Yes, pass the ^Z\r | |
1842 | ;At this point file-mode is DEFAULT.\r | |
1843 | ;If the rest of the record is filled with ^Zs, we're at EOF, otherwise\r | |
1844 | ;its a regular character.\r | |
1845 | lhld bufpnt ;since CHRCNT is ZERO at EOF-time\r | |
1846 | lda chrcnt ;(set by INBUF5 B.G.E)\r | |
1847 | mov d,a ;Get the number of chars left in the DMA.\r | |
1848 | gtch51: dcr d\r | |
1849 | mov a,d\r | |
1850 | jp gtch53 ;Any chars left?\r | |
1851 | gtch52: xra a ;If not, get a zero.\r | |
1852 | sta chrcnt ;Say no more chars in buffer.\r | |
1853 | mov a,b ;Return the count in A.\r | |
1854 | jmp rskp\r | |
1855 | \r | |
1856 | ;Scan rest of buffer for non ^Z -- If we find a non ^Z, fall into gtchr6.\r | |
1857 | ;If we get to the end of the buffer before finding a non ^Z, fall into gtch52.\r | |
1858 | gtch53: mov a,m ;Get the next char.\r | |
1859 | inx h ;Move the pointer.\r | |
1860 | cpi ('Z'-100O) ;Is it a ^Z?\r | |
1861 | jz gtch51 ;If so see if the rest are.\r | |
1862 | \r | |
1863 | gtchr6: mvi a,('Z'-100O) ;Restore the ^Z.\r | |
1864 | gtchr7: sta temp2 ;Save the char.\r | |
1865 | lxi h,temp1 ;Point to the char total remaining.\r | |
1866 | dcr m ;Decrement it.\r | |
1867 | lhld cbfptr ;Position in character buffer.\r | |
1868 | mov m,c ;Put the quote in the buffer.\r | |
1869 | inx h\r | |
1870 | shld cbfptr\r | |
1871 | inr b ;Increment the char count.\r | |
1872 | lda temp2 ;Get the control char back.\r | |
1873 | adi 40H ;Make the non-control.\r | |
1874 | ani 7fH ;Modulo 200 octal.\r | |
1875 | gtchr8: lhld cbfptr ;Position in character buffer.\r | |
1876 | ora e ;Or in the parity bit.\r | |
1877 | mov m,a ;Put the char in the buffer.\r | |
1878 | inx h\r | |
1879 | shld cbfptr\r | |
1880 | inr b ;Increment the char count.\r | |
1881 | jmp gtchr1 ;Go around again.\r | |
1882 | \r | |
1883 | gtchr9: ;[jd] not enough room left in buffer...\r | |
1884 | lhld bufpnt\r | |
1885 | dcx h\r | |
1886 | shld bufpnt ;[jd] back up over last character\r | |
1887 | lxi h,chrcnt ;[jd] point to character count\r | |
1888 | inr m ;[jd] increment it\r | |
1889 | mov a,b ;[jd] count of chars transferred\r | |
1890 | jmp rskp ;[jd] return it\r | |
1891 | \r | |
1892 | gtceof: mvi a,0FFH ;Get a minus one.\r | |
1893 | ret\r | |
1894 | ;\f\r | |
1895 | \r | |
1896 | ; Little code to allow some expansion of code without changing\r | |
1897 | ; every futher address, only up to the end of this file.\r | |
1898 | ; TO BE REMOVED FRO RELEASE!\r | |
1899 | \r | |
1900 | ; org ($+100h) AND 0FF00H\r | |
1901 | \r | |
1902 | IF lasm\r | |
1903 | LINK CPSPK2 ;[obs] Link to part two of the packet file\r | |
1904 | ENDIF ;lasm\r |