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