-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpup.mac
6712 lines (5676 loc) · 215 KB
/
pup.mac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;<134>PUP.MAC;109 28-MAY-81 14:50:03 EDIT BY TAFT
; Fix foreign address selection in PUPOPN -- just plain didn't work!
;<134>PUP.MAC;108 27-MAY-81 19:46:30 EDIT BY TAFT
; Adjust maximum BSP allocations to assume that all Pups are maximum-size.
; This ensures that the byte allocation doesn't run out before the Pup
; allocation, which confuses some BSP implementations (though not this one).
;<134>PUP.MAC;106 15-MAR-81 14:00:27 EDIT BY TAFT
;<134>PUP.MAC;105 14-MAR-81 20:09:30 EDIT BY TAFT
; Fix long-standing Pup performance problems:
; Time-stamp outgoing Pup earlier in SNDBSP so as not to confuse CHKADA.
; Implement adaptive timeout for BSP transmissions.
; Make retransmission timeout be double the measured round-trip delay,
; and make the AData/retransmission cutoff be half the round-trip delay.
; Disable the overlapped Data/Ack feature to reduce the "shooting down
; your Ack" effect.
;<134>PUP.MAC;104 10-MAR-81 12:29:23 EDIT BY TAFT
; Invoke Maxc2 CSUM16 opcode for Pup checksum.
;<134>PUP.MAC;103 2-MAR-81 11:00:55 EDIT BY TAFT
;<134>PUP.MAC;102 28-FEB-81 13:41:22 EDIT BY TAFT
; Remove Pup format definitions to separate UNIVERSAL file PUPFMT.MAC
;<134>PUP.MAC;101 27-FEB-81 15:14:29 EDIT BY TAFT
; Put NTDCHF flag in PUPPAR table
;<134>PUP.MAC;100 17-FEB-81 18:24:08 EDIT BY TAFT
; Add timeout option to PUPI.
; Improve net number defaulting in PUPO.
; Add "default" net number to PUPPAR table.
;<134>PUP.MAC;99 10-FEB-81 16:16:39 EDIT BY TAFT
; Make primitive queue routines internal for new PUPNM
;<134>PUP.MAC;98 15-OCT-80 15:07:43 EDIT BY TAFT
; Speed ADDTQI queue search by unrolling the loop.
;<134>PUP.MAC;97 13-OCT-80 15:08:37 EDIT BY TAFT
; Speed Pup checksum computation by running the main loop in the ACs.
;<134>PUP.MAC;96 8-OCT-80 10:58:43 EDIT BY TAFT
; Do not use stack for address table in PNMDEC -- causes
; stack overflow when PUP OPENF executed from inside another JSYS.
;<134>PUP.MAC;95 5-OCT-80 18:48:09 EDIT BY TAFT
; Make BSP stream buffer setup routines externally callable (for MTANET).
;<134>PUP.MAC;94 27-JAN-80 17:15:01 EDIT BY TAFT
; Fix SNDINT to save args around call to DOBSPL
;<134>PUP.MAC;93 17-MAY-79 13:06:41 EDIT BY TAFT
; Increase size of hop count field to 4 bits.
; Assemble both gateway and non-gateway code and switch to correct version
; at runtime.
;<134>PUP.MAC;92 18-NOV-78 17:41:42 EDIT BY TAFT
; Fix editing error
;<134>PUP.MAC;91 21-OCT-78 13:10:13 EDIT BY TAFT
; If a Pup arrives from an inaccessible net, change the routing table
; to route to net via the immediate source net/host.
;<134>PUP.MAC;90 26-SEP-78 12:36:23 EDIT BY TAFT
; Insert missing end test in RCVDA6 loop!
;<134>PUP.MAC;89 8-SEP-78 10:22:42 EDIT BY TAFT
; Fix PNVDBT to wake up on errors also
;<134>PUP.MAC;88 4-JUL-78 18:24:51 EDIT BY TAFT
; Fix bug at PUPOP4 causing loss of local port if BLDBSP fails
;<134>PUP.MAC;87 12-NOV-77 19:36:57 EDIT BY TAFT
; Fix PUPCLZ to turn FILLFW bit back on before waiting
;<134>PUP.MAC;86 18-JUL-77 15:24:14 EDIT BY TAFT
; Raise IBWDLY to 500 ms
;<134>PUP.MAC;85 6-JUL-77 10:19:34 EDIT BY TAFT
; Change BSP dispatch to update activity timeout only for certain types
;<134>PUP.MAC;84 6-JUL-77 09:56:08 EDIT BY TAFT
; Fix error introduced into RCVERR in last edit
;<134>PUP.MAC;83 3-JUL-77 15:06:09 EDIT BY TAFT
; Increase retransmission timeout when port IQ or gateway OQ error occurs
; Run background fork on SPQ
; Try to direct more freed PBs onto FREIBQ to reduce overhead
; Remove state saving code in previous edit
;<134>PUP.MAC;82 7-MAY-77 21:18:19 EDIT BY TAFT
; Add code to record state of Pup background fork when a port IQ overflows
;<134>PUP.MAC;81 28-APR-77 21:45:23 EDIT BY TAFT
; Make PBGCNT resident, dummy
;<134>PUP.MAC;80 22-APR-77 10:36:47 EDIT BY TAFT
; Add logic to detect potential deadlocks arising from timing marks
;<134>PUP.MAC;79 21-APR-77 16:59:02 EDIT BY TAFT
; Add PUPBGT -- hash table for counting PUPBUGs
;<134>PUP.MAC;78 15-APR-77 12:13:29 EDIT BY TAFT
; Make TTYPUP internal
;<134>PUP.MAC;77 6-APR-77 10:08:59 EDIT BY TAFT
; Lock out PSIs in PNVCOB so interrupt and DM will both be sent
;<134>PUP.MAC;76 25-JAN-77 21:18:40 EDIT BY TAFT
; Parameterize initial routing table
; Put gateway-dependent stuff in GATEWF conditional
; Other changes for Maxc2
;<134>PUP.MAC;74 21-SEP-76 01:43:21 EDIT BY TAFT
; Update routing table
;<134>PUP.MAC;73 17-JUL-76 18:33:51 EDIT BY TAFT
; Add net 6 to routing table
;<134>PUP.MAC;72 13-MAY-76 16:59:15 EDIT BY TAFT
; Repair bad call to RELPKT at FLSBS3+1
;<134>PUP.MAC;71 20-APR-76 22:53:22 EDIT BY TAFT
; Bug fixes
; Generate timing mark reply immediately if a fork is blocked for input
;<134>PUP.MAC;70 20-APR-76 17:42:56 EDIT BY TAFT
; Fix glitch at NVTSYN
;<134>PUP.MAC;69 19-APR-76 00:51:07 EDIT BY TAFT
; Add PUPROU function for OPRFN
;<134>PUP.MAC;67 18-APR-76 21:20:21 EDIT BY TAFT
; Add Telnet timing mark logic
;<134>PUP.MAC;66 18-APR-76 18:39:17 EDIT BY TAFT
; Add code to handle Error Pups
;<134>PUP.MAC;65 17-APR-76 15:33:03 EDIT BY TAFT
; Redo background wakeup strategy -- protective delay without
; added latency in most cases.
;<134>PUP.MAC;64 14-APR-76 20:21:41 EDIT BY TAFT
; Improve hashing algorithm, remove restriction that NPUPUN be prime
;<134>PUP.MAC;63 29-MAR-76 17:35:58 EDIT BY TAFT
; At PUPIN5, force immediate rather than delayed wakeup of background
; process for NVT ports
;<134>PUP.MAC;62 27-MAR-76 20:08:33 EDIT BY TAFT
; Increase some of the BSP retransmission timeouts
; Change probing strategy on zero allocation
;<134>PUP.MAC;61 7-MAR-76 00:53:56 EDIT BY TAFT
; Reject Pups claiming to be from host zero
;<134>PUP.MAC;60 23-FEB-76 17:24:03 EDIT BY TAFT
; Fix glitch in setting of NVT terminal type
;<134>PUP.MAC;59 25-JAN-76 17:32:23 EDIT BY TAFT
; Take out code to force AData in ATPNVT -- first data will do it anyway
;<134>PUP.MAC;58 22-JAN-76 16:12:41 EDIT BY TAFT
; Background fork back on HIQ -- SETHIQ bug was found
;<134>PUP.MAC;57 20-JAN-76 17:15:26 EDIT BY TAFT
; Run background fork in SPQ (SETHIQ seems not to work)
;<134>PUP.MAC;56 20-JAN-76 03:07:54 EDIT BY TAFT
; Pup received PSI now generated via scheduler request rather
; than by direct call to PSIRQ from interrupt level.
;<134>PUP.MAC;55 11-JAN-76 21:34:42 EDIT BY TAFT
; Fix assembly glitch -- need () around LOCK/UNLOCK macro args
; Add some ##
;<134>PUP.MAC;54 10-JAN-76 23:48:50 EDIT BY TAFT
; Revise LOCK/UNLOCK calls for 1.34 scheduler handling
; Background fork always runs in HIQ
; Copyright Xerox Corporation 1979, 1980, 1981
; The following declaration ensures that the symbols are linked externally
; rather than binding to local PC values in the UNIVERSAL file.
EXTERN PPUPUN,PPBPHN,PPBPHH,PPBPHS,PUPLEN,PUPTCB,PUPTYP
EXTERN PUPID,PPUPDN,PPUPDH,PPUPD0,PPUPD1,PPUPSN,PPUPSH,PPUPSS
SEARCH STENEX,PROLOG,PUPFMT
TITLE PUP
SUBTTL PUP I/O DRIVER FOR MAXC / E. A. Taft March 1975
; -----------------------------------------------------------------
; Pup Parameter Definitions
; -----------------------------------------------------------------
; Parameters defined in PARAMS.MAC
; NPUPUN # Pup "Units".
; NPUPLN # Pup NVT's.
; PUPLO TTY # of lowest Pup NVT
; PUPHI TTY # of highest Pup NVT
; NPNETS Maximum # of networks in routing table
; NPKTBF # pages of storage for packet buffer allocator
; NPUPBF # pages for other Pup storage
; PUPCHN PI assignment for Pup I/O interrupts
; PUPIBG Begin Pup input device # (Maxc -> NVIO)
; PUPOBG Begin Pup output device # (Maxc -> NVIO)
; PUPIDN Pup input done device # (NVIO -> Maxc)
; PUPODN Pup output done device # (NVIO -> Maxc)
; XPUPIB Pup input packet address
; XPUPOB Pup output packet address
; Accumulator assignments
; A-D ; Temps
; UNIT ; Pup "Unit" number -- for port-indexed tables
; PB=10 ; Packet Buffer pointer
BSP=12 ; BSP data block pointer
; If UCSUMF=1 then invoke CSUM16 microcode for Pup checksum
UCSUMF==MX(0,1)
LS PRSBEG,0 ; Start of Pup resident storage
NGS PNRBEG,0 ; Start of Pup nonresident storage
; Pup Type assignments
PT.ECH==1 ; Echo Me
PT.IEC==2 ; I'm An Echo
PT.BEC==3 ; I'm A Bad Echo
PT.ERR==4 ; Error
PT.RFC==10 ; Request for Connection
PT.ABT==11 ; Abort
PT.END==12 ; End
PT.ENR==13 ; End Reply
PT.DAT==20 ; Data
PT.ADA==21 ; AData
PT.ACK==22 ; Acknowledgment
PT.MRK==23 ; Mark
PT.INT==24 ; Interrupt
PT.INR==25 ; Interrupt Reply
PT.AMA==26 ; AMark
; Network-dependent stuff
; Network tables, indexed by net # -1
; The following is a documented GETAB table
GS PUPROU,NPNETS ; Network routing table
; B0 ; Network inaccessible
BROADF==1B1 ; Broadcast packets allowed on net
; B2-17 ; Net/host to which packets should
; be routed (0 => route directly)
; B18-35 ; Address of Maxc on this net (0 => not on net)
; Table for initializing routing table
USE SWAPPC
DEFINE HSTMAC(NET,HOST,BROADCAST) <
<IFNB <BROADCAST>,<BROADF>>+<NET>B17+<HOST>B35>
PUPIRT: PUPHST(HSTMAC) ; Expand def from PARAMS.MAC
LPUPIR==.-PUPIRT
USE RESPC
; Pup storage parameters and assignments
LS PKTFRE,7 ; Packet buffer free storage header (standard ASGFRE form)
NGSP PKTBUF,NPKTBF ; Packet buffer free storage region
LS PUPFRE,7 ; Pup free storage header
NGSP PUPBUF,NPUPBF ; Pup free storage region
NPKTBW==NPKTBF*1000 ; # words of packet buffer storage
MAXIQW==NPKTBW/^D15 ; Max # words on one port's input queue
MAXIQB==^D15 ; Max # buffers on one port's input queue
MAXOQW==NPKTBW/^D15 ; Max # words on one port's output queue
MAXOQB==^D15 ; Max # buffers on one port's output queue
MAXGQW==NPKTBW/^D10 ; Max # words allowed on gateway queue
MAXGQB==^D20 ; Max # buffers allowed on gateway queue
MINFIB==^D12 ; Min # free input buffers to maintain
MAXFIB==^D20 ; Max # free input buffers to maintain
; Pup parameter GETAB table
; Must be resident because it is referenced by the GATEWY code
PUPPAR::-NPUPLN,,PUPLO ; (0) -# of Pup NVT's, TTY# of first NVT
PUPBUF ; (1) Start of Pup free storage
DEFNET: <GATEWF>B0+<NTDCHF>B1+DFPNET ; (2) B0 set if we are a gateway
; B1 set if network directory is cached rather than kept in entirety
; B18-35: Default directly-connected net number
NPUPPR==:.-PUPPAR ; Length of this table
; Pup queues
; All queues are doubly-linked through 36-bit link words.
; A queue header is in the form
; Pointer to queue tail ,, Pointer to queue head
; where self-pointers denote an empty queue.
; A queue item (e.g. a packet link word) is in the form
; Pointer to predecessor ,, Pointer to successor
; All pointers point to other queue items or to header words.
; This permits uniform queue management without special cases.
; All Packet Buffers are linked through PBIOBQ except as noted
LS PBQBEG,0 ; Start of queue header block
; Queues referenced by input interrupt:
LS FREIBQ ; Free input buffer queue.
; Consists of max-length buffers, locked
; into core, for use by input interrupt
LS PUPIBQ,NPUPUN ; Input buffer queue, one per port.
; Packets received for that port
LS DSCIBQ ; Discarded input buffer queue.
; Packets waiting to be logged and discarded
; by job 0 or error process
; Queues referenced by output interrupt:
LS PUPOBQ ; Pup output buffer queue.
; Packets awaiting service by output interrupt
LS FREOBQ ; Free (discarded) output buffer queue.
; Waiting to be returned to free storage
LS PBQEND,0 ; End of queue header block
; Port-indexed tables
; ** The following are documented GETAB tables **
GS PUPLSK,NPUPUN ; Local socket number hash table
; 0 => free, -1 => deleted
GS PUPLNH,NPUPUN ; Local Net/Host and BSP linkage
PPRTLN: POINT 8,PUPLNH(UNIT),7 ; Local net # (0 => wildcard)
PPRTLH: POINT 8,PUPLNH(UNIT),15 ; Local host # (0 => wildcard)
; B16-17 ; Unused
; B18-35 ; Pointer to BSP data block
; 0 => not a BSP port
NGS PUPFPT,NPUPUN ; Foreign port: -length,,adr-1 of address table
; 0 => foreign port is fully wildcard
GS PUPSTS,NPUPUN ; Port status word (mostly for BSP)
BSLCKF==1B0 ; Port is locked (must be sign)
BSWAKF==1B1 ; BSP wakeup request pending
BSINPF==1B2 ; Input available
BSOUTF==1B3 ; Output possible
BSMRKF==1B4 ; Mark encountered in stream
BSENDF==1B5 ; End encountered in stream
BSTIMF==1B6 ; Timeout
BSNCHK==1B7 ; Supress checksumming
BSOPNR==1B8 ; Port open for reading
BSOPNW==1B9 ; Port open for writing
DSCRNF==1B10 ; Random discard enabled
BSSAKF==1B11 ; Need to send Ack
BSRAKF==1B12 ; Received Ack
BSZALF==1B13 ; Sent Ack with zero allocation
BSINTF==1B14 ; Interrupt outstanding
BSLISF==1B15 ; Port is or has been listening
BSNOQF==1B16 ; BSP output queue is non-empty
BSERRF==1B17 ; Set if port gets in bad state
; B18-31 unused
PBSSTM: POINT 4,PUPSTS(UNIT),35 ; State # in memory
PBSSTA: POINT 4,PUPSTS(A),35 ; State # in memory, indexed by A
PBSSTT: POINT 4,IOS,35 ; State # in usual ac
; ** End of documented GETAB tables **
LS PUPIBC,NPUPUN ; Input buffer counts
; B0-17 ; Number of buffers allocated
; B18-35 ; Number of words allocated
LS PUPOBC,NPUPUN+1 ; Output buffer counts
; B0-17 ; Number of buffers allocated
; B18-35 ; Number of words allocated
; Extra entry is for gateway output
LS PUPPSI,NPUPUN ; Port PSI assignments and other stuff
INTPSI: POINT 6,PUPPSI(UNIT),5 ; BSP Interrupt PSI channel
RECPSI: POINT 6,PUPPSI(UNIT),11 ; Received Packet PSI channel
STCPSI: POINT 6,PUPPSI(UNIT),17 ; BSP State Change PSI channel
; 18-35 ; Fork to interrupt (-1 => none)
; or 400000 + attached TTY #
; ***** Do not change the order of the following *****
LS PUPTQH ; Timer queue head
LS PUPTMQ,NPUPUN ; Timer queue linkage
LS PUPFTM ; Time word corresponding to PUPTQH
LS PUPTIM,NPUPUN ; BSP timer
; TODCLK at which BSP processing next
; required for timing retransmissions
PUPTQD==NPUPUN+1 ; PUPTIM-PUPTMQ displacement
; ***** End of do not change *****
; Definition of BSP data block
DEFINE BSWRD(LABEL) <
LABEL==BSPSIZ
BSPSIZ==BSPSIZ+1
>
BSPSIZ==0
BSWRD(BSPHDR) ; Header word
PBSMRK: POINT 8,BSPHDR(BSP),7 ; Value of most recent Mark
PBSTMO: POINT 8,BSPHDR(BSP),15 ; Error timeout interval / 2^12 ms
; B16-17 ; Unused
; B18-35 ; Size of BSP data block (words)
BSWRD(BSPTIM) ; BSP timing parameters
; B0-17 ; Estimated round-trip delay (ms)
; B18-35 ; Pointer to received Abort if any
; Timer words (TODCLK format) - for flow control and retransmission
BSWRD(BSPACT) ; Time of most recent activity
BSWRD(BSPDTM) ; Time at which to do BSP retransmissions
BSWRD(BSPATM) ; Time last AData was sent
; 0 => No AData outstanding
BSWRD(BSPITM) ; Time at which to retransmit Interrupt
BSWRD(BSPFTM) ; Time at which to check FSM
BSWRD(BSPSTM) ; Time of most recent FSM state change
; Packet buffer pointers and queues
BSWRD(BSPCUR) ; Current buffers being packed/unpacked
; B0-17 ; Current input buffer (0 => none)
; B18-35 ; Current output buffer (0 => none)
BSWRD(BSPIBQ) ; BSP Input queue (linked thru PBBSPQ)
BSWRD(BSPOBQ) ; BSP Output queue (linked thru PBBSPQ)
; Sequence numbers, allocations, counters, etc.
BSWRD(BSPCID) ; BSP Connection ID
; -1 => no ID assigned yet (listening)
BSWRD(BSPRII) ; BSP Receive Interrupt ID
BSWRD(BSPSII) ; BSP Send Interrupt ID
; B0 set => B18-35 point to unacknowledged send Interrupt PB
BSWRD(BSPILW) ; BSP Input left window edge
; ID of next byte to be removed by
; inputting process
BSWRD(BSPIQL) ; BSP Input queue length
; B0-17 ; # Pups in BSP input queue
; B18-35 ; # bytes from BSPILW to first hole
BSWRD(BSPIAL) ; BSP Input allocation
PBSIAP: POINT 8,BSPIAL(BSP),7 ; Total input Pups allowed
PBSIBP: POINT 10,BSPIAL(BSP),17 ; Maximum data bytes/Pup
; B18-35 ; Maximum # bytes allowed
BSWRD(BSPOLW) ; BSP Output left window edge
; Pup ID of last received Ack
BSWRD(BSPOQL) ; BSP Output queue length
; B0-17 ; # Pups in BSP output queue
; B18-35 ; # bytes spanned by BSP output queue
BSWRD(BSPOAL) ; BSP Output allocation
PBSOAP: POINT 8,BSPOAL(BSP),7 ; Additional Pups allowed
PBSOBP: POINT 10,BSPOAL(BSP),17 ; Maximum data bytes/Pup
; B18-35 ; Additional bytes allowed
; Statistics
BSWRD(BSPOPG) ; BSP Output packets generated
BSWRD(BSPOPR) ; BSP Output packets retransmitted
BSWRD(BSPPPG) ; BSP Probe packets generated
; BSP-related parameters
MXBSIP==<MAXIQW/MXPBLN>-1 ; Max # Pups we allow on BSP input queue
MXBSIB==MXBSIP*<MXPLEN-MNPLEN> ; Max # bytes we allow on BSP input queue
MXBSOP==<MAXOQW/MXPBLN>-1 ; Max # Pups we allow on BSP output queue
MXBSOB==MXBSOP*<MXPLEN-MNPLEN> ; Max # bytes we allow on BSP output queue
MXSACK==0 ; Max # Pos/NegAck blocks per Ack Pup
; 0 => Ignore incoming Pos/NegAcks also
MXPTXT==^D75 ; Max # bytes of text in Interrupt, Abort
MINBWI==^D100 ; Minimum background wakeup interval (ms)
; Background process waits at least this long
; when it dismisses before waking up again.
IBWDLY==^D500 ; Input background wakeup delay (ms)
; When an input packet arrives, wakeup of the
; background process is delayed this long in
; hopes that the user fork will process the input
RETINT==^D100 ; Nominal retransmission interval (ms)
MINRET==^D25 ; Minimum retransmission interval
MAXRET==^D10000 ; Maximum retransmission interval
HLDINT==^D1000 ; Hold interval (expiration forces AData)
PRBINT==^D15000 ; Probe interval for idle connection (ms)
DETINT==^D120 ; Default error timeout interval (sec)
ALLPCT==^D0 ; % of total allocation (Pups or bytes)
; below which an AData is sent to request
; new allocation. 0 = don't overlap Data/Acks.
; Macro to assemble bits corresponding to up to 8 listed port states
; Call by: STTBTS(STATE1,STATE2, ...)
DEFINE STTBTS(A,B,C,D,E,F,G,H) <<$S(A)+$S(B)+$S(C)+$S(D)+$S(E)+$S(F)+$S(G)+$S(H)>>
DEFINE $S(STATE) <IFNB <STATE>,<1B<S.'STATE>>>
; Macro to assemble code to skip if current state is among those listed
; Call by: CHKSTT(<STATE1,STATE2, ...>,AC)
; Assumes UNIT setup, clobbers A unless AC specified
DEFINE CHKSTT(STATES,AC<A>) <
LDB AC,PBSSTT ; Get current state
MOVE AC,BITS##(AC) ; Get bit corresponding to state
TLNN AC,(STTBTS(STATES)) ; Skip if among those listed
>
; Pup NVT data
; Indexed by Pup NVT # (= TTY # - PUPLO)
; ** This is a documented GETAB table **
GS NVTPUP,NPUPLN ; NVT data
TTYPUP=:NVTPUP-PUPLO ; NVTPUP indexable directly by TTY #
; B0 ; 1 => NVT assigned
PSYNCT: POINT 3,TTYPUP(B),3 ; Sync count (Int's - DM's)
SYNCNT==7B3 ; Mask of bits in sync count
PSYNTM: POINT 3,TTYPUP(B),6 ; Sync timer
PNVSTT: POINT 2,TTYPUP(B),8 ; NVT state for input processing
PNVMRK: POINT 4,TTYPUP(B),12 ; Pending Mark type if any
HUREQF==1B13 ; Hangup request already made
PTMKCT: POINT 3,TTYPUP(B),16 ; Count of incoming timing marks pending
TMKPNF==1B17 ; Outgoing timing mark pending
; B18-35 ; Pup unit # of attached port
SYNCHI==^D10000 ; Sync check interval (ms)
SYNTMO==^D20000/SYNCHI ; Sync timeout interval (20 seconds)
LS NVTLCK ; Lock for NVT assignment and management
; Error handling
; In addition to the usual BUGHLT, BUGCHK, and BUGNTE (for reporting
; internal errors), there is a collection of BUG types for
; reporting anomalies associated with a particular Pup and/or
; discarding that Pup.
; BUG(PUP,<message>,X)
; Copies the header of the packet pointed to by PB into cells
; looked at by job 0. If PUPBGF is nonzero, this data is printed
; on the logging console by job 0.
; BUG(DIP,<message>,X)
; Appends the packet pointer to by PB to the discarded input
; packet queue (DSCIBQ). The PC of the BUG is stored in the RH
; of the PBBSPQ word. If PUPBGF is nonzero, information
; about this packet is printed on the logging console by job 0.
; (Later we may provide a mechanism whereby a user process can
; arrange to receive all discarded Pups). The buffer is then
; deallocated.
; BUG(DPR,<message>,X)
; Same as BUG(DIP,...) except that an extra POPJ is executed
; so that the routine invoking the BUG is exited.
; JSYS error macros, adapted from JSYS.MAC
DEFINE ERROR(ERRORN,EXTRA,WHERE) <
IFB <ERRORN'EXTRA>,<JRST WHERE>
IFNB <ERRORN'EXTRA>,<
JRST [ EXTRA
IFNB <ERRORN>,<MOVEI A,ERRORN>
JRST WHERE]
>>
; Load error code and do POPJ P,
DEFINE ERPOPJ(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,CPOPJ##)>
; Store error code and give error return from JSYS
DEFINE ERR(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,ERRD##)>
; Store error code, unlock JFN, and give error return from JSYS
DEFINE ERUNLK(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,ERUNLD##)>
; Store error code and generate instruction trap
DEFINE ERABRT(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,ERABRD##)>
; Store error code, unlock JFN, and generate instruction trap
DEFINE FILABT(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,ABTDO##)>
; Store error code, unlock JFN, and give i/o data error psi
DEFINE FILINT(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,DOINT##)>
; Macro to activate Pup background process.
; SIGPBP(XXX) causes bit PBFXXX to be set in PUPFLG. This causes
; the Pup background process to wakeup and call the routine
; implementing the requested background task (see PUPBAK).
; Optional arguments:
; SIGPBP(FLAG,<INSTRUCTION>,AC)
; If <INSTRUCTION> is specified, the flag is set iff the
; instruction does not skip. If AC is specified, it (instead of
; A) is the ac clobbered by the generated code.
DEFINE SIGPBP(FLAG,INST,AC<A>) <
MOVSI AC,(PBF'FLAG)
INST
IORM AC,PUPFLG
>
LS PUPFLG ; Records Pup background process requests
LS NXTWAK ; Earliest time at which next wakeup permitted
; Random other data referenced in more than one place.
; (Storage used in only one place is defined at that place)
LS PRTLCK ; Lock for changes to port tables
LS LSKNDL ; # of deleted entries in local socket table
LS FREIBN ; # buffers in FREIBQ
GS PUPFRK ; FORKX of Pup background process
LS SYNTIM ; Time for next sync timeout check
; Notes on handling of locks:
; PRTLCK should be locked while attempting to lock a port, then
; unlocked once the port is locked.
; NVTLCK should be locked while doing anything to an NVT.
; No lock should be held while waiting for a port lock to become free.
; If both NVTLCK and PRTLCK need be locked simultaneously, NVTLCK
; must be locked first to prevent deadlocks.
; Lockers of PRTLCK should invoke SPQ (Special Queue), unless it is
; known that the locker is the Pup background fork, which already
; runs on HIQ.
; Lockers of NVTLCK should invoke HIQ unless it is known that the
; locker is the Pup background fork.
; -----------------------------------------------------------------
; Standard JSYS Routines for Pup
; -----------------------------------------------------------------
USE SWAPPC
; Pup device dispatch table
PUPDTB::PUPSET ; Directory setup
PUPNAM ; Name lookup
PUPEXT ; Extension lookup
GJSRET ; Version lookup
CPOPJ## ; Insert protection
CPOPJ## ; Insert account
CPOPJ## ; Insert status
PUPOPN ; Open
PUPSQI ; Sequential input
PUPSQO ; Sequential output
PUPCLZ ; Close
CPOPJ## ; Rename
CPOPJ## ; Delete
CPOPJ## ; Dump input
CPOPJ## ; Dump output
CPOPJ## ; Mount
CPOPJ## ; Dismount
CPOPJ## ; Initialize directory
PUPMTP ; MTOPR
PUPGST ; Get status
PUPSST ; Set status
; Lookup routines called by GTJFN
DEFINE GJERR(ERRORN) <ERROR(ERRORN,,GJERRX)>
; Directory setup routine
PUPSET: NOINT
JRST SK2RET## ; Always successful
; Name lookup routine
PUPNAM: JUMPE A,[GJERR(GJFX31)] ; * not allowed
HRLI A,(POINT 7,,35) ; Make string pointer
PUSHJ P,PNMDEC ; Decode name string
GJERR(GJFX18) ; Bad, say no such name
JRST GJ2RET ; Ok, take success return
; Extension lookup routine
PUPEXT: JUMPE A,[GJERR(GJFX31)] ; * not allowed
HRLI A,(POINT 7,,35) ; Make string pointer
PUSHJ P,PEXDEC ; Decode extension string
GJERR(GJFX19) ; Bad, say no such extension
MOVEI B,(A) ; Ok, now just throw the block away
PUSHJ P,RELPFR
; JRST GJ2RET ; Take success return
; Version lookup routine (always succeeds, does nothing)
; Returns from GTJFN routines
GJ2RET: AOS 0(P) ; Double skip
GJSRET: AOS 0(P) ; Single skip
TEST(NE,UNLKF) ; Should we unlock?
POPJ P, ; No
GJERRX: OKINT ; Yes
POPJ P,
; Open Pup network file (OPENF)
DEFINE OPNERR(ERRORN,EXTRA) <ERROR(ERRORN,<EXTRA>,OPNERX)>
; Check mode and byte size
PUPOPN: TEST(NN,XCTF,RNDF) ; Xct and append are illegal
TEST(NN,READF,WRTF) ; Must be reading or writing
ERPOPJ(OPNX13) ; Illegal access
TRNE STS,10 ; Raw packet mode (16)?
JRST PUPOP0 ; Yes, skip some checks
TEST(C,READF,WRTF) ; BSP can do only one or the other
TEST(CN,READF,WRTF)
ERPOPJ(OPNX13) ; Both read and write is illegal
LDB A,PBYTSZ## ; Get byte size
CAIE A,7 ; Only 7 and 8 allowed
CAIN A,8
CAIA
ERPOPJ(SFBSX2) ; Illegal byte size
; Re-parse the name and extension strings to yield addresses
PUPOP0: HRRZ A,FILNEN(JFN) ; Make byte ptr to extension
HRLI A,(POINT 7,,35)
PUSHJ P,PEXDEC ; Decode Pup extension string
ERPOPJ(OPNX2) ; Failed (maybe net dir changed?)
MOVE E,A ; Save address table pointer
HLRZ A,FILNEN(JFN) ; Make byte ptr to filename
HRLI A,(POINT 7,,35)
PUSHJ P,PNMDEC ; Decode Pup name string
OPNERR(OPNX2) ; Failed (maybe net dir changed?)
; Now have A/ <net>B7 + <host>B15, B/ socket for local port.
; Check for correct access to the specified socket number
MOVE C,CAPENB## ; Get privilege bits
TRNE C,WHEEL!OPR ; Wheel or operator?
JRST PUPOP1 ; Yes, can have any socket
MOVE C,B ; No, get high 17 bits
LSH C,-^D15
MOVE D,FORKX## ; Get fork number
SKIPGE D,FKDIR##(D) ; Connected,,login dir if top fork
JRST .-1 ; Pointer to top of group if not
CAIN C,(D) ; User-relative for login dir?
JRST PUPOP1 ; Yes, ok
HLRZ D,D ; Try connected dir
CAIL C,^D50000 ; Socket in free-for-all range?
CAILE C,^D99999
CAIN C,(D) ; No, user-relative for this fork?
JRST PUPOP1 ; Either of those, socket ok
MOVE D,JOBNO ; No, get job number
CAIE C,^D100000(D) ; Job-relative for this job?
OPNERR(OPNX13) ; No, illegal access to socket
; OPENF (cont'd)
; If mode 0, 1, or 4, ensure foreign port is not multiple or wild
PUPOP1: TRNE STS,12 ; Ok if mode 2, 3, or 16
JRST PUPOP3
CAML E,[-2,,0] ; Multiple?
JRST PUPOP2 ; No, go check for wildcard
; Multiple foreign address
; Pick the first one on a directly-connected network, or else the
; first one that is accessible.
PUSH P,A ; Save local port address
PUSH P,B
MOVE D,E ; Copy foreign address table ptr
SETZ C, ; No choice yet
PUPO1A: HLRZ A,1(D) ; Get a net from table
CAIL A,1 ; In range?
CAILE A,NPNETS
JRST PUPO1B ; No
SKIPGE B,PUPROU-1(A) ; Yes, get entry
JRST PUPO1B ; Inaccessible, ignore
TLNE B,(177777B17) ; Routing directly to network?
SKIPN C ; No, already have saved index?
MOVE C,D ; Local or no index yet, save index
TLNN B,(177777B17) ; Routing directly to net?
JRST PUPO1C ; Yes, use this entry
PUPO1B: AOBJN D,.+1 ; Advance table pointer (2 words)
AOBJN D,PUPO1A ; Try next if any remain
PUPO1C: JUMPE C,[POP P,B ; Fail if none found
POP P,A
OPNERR(PUPX2)]
MOVE A,1(C) ; Store selected address at
MOVEM A,1(E) ; start of block
MOVE A,2(C)
MOVEM A,2(E)
MOVEI A,0(E) ; Copy pointer to block
MOVEI B,3 ; New size of block
PUSHJ P,TRMPFR ; Trim the address block
HRLI E,-2 ; Now just 2 words in table
POP P,B ; Recover local port
POP P,A
; Give error if foreign port now has any wildcard elements.
; Substitute appropriate values for wildcard local net/host
PUPOP2: SKIPN 2(E) ; Wild socket?
OPNERR(PUPX2) ; Yes, address error
HLRZ C,1(E) ; Get net
SKIPE C ; Wildcard?
CAILE C,NPNETS ; Out of range?
OPNERR(PUPX2) ; Yes, address error
HRRZ D,1(E) ; Get host
SKIPE D ; Wildcard?
SKIPGE D,PUPROU-1(C) ; Dest net inaccessible?
OPNERR(PUPX2) ; Yes, address error
JUMPN A,PUPOP3 ; Local net/host specified?
TRNN D,-1 ; No, are we on dest net?
LDB C,[POINT 8,PUPROU-1(C),9] ; No, use net of gateway
HRRZ D,PUPROU-1(C) ; Get our address on that net
ROT D,-8 ; Concatenate net/host
LSHC C,-8 ; Left-justify in D
MOVE A,D ; Put in proper ac
; OPENF (cont'd)
; Now have A/ <net>B7 + <host>B15, B/ socket for local port.
; Attempt to assign the local port
PUPOP3: PUSHJ P,ASGPRT ; Assign local port
OPNERR(OPNX10) ; Failed, tables full
JRST PUPOP6 ; Duplicate, check for legal cases
HRLM UNIT,DEV ; Success, remember Pup unit #
HRLM UNIT,FILDEV(JFN)
MOVE A,FORKX## ; Record fork owning port
HRRM A,PUPPSI(UNIT)
MOVEM E,PUPFPT(UNIT) ; Save address table pointer
TRNN STS,10 ; Raw packet mode?
JRST PUPOP4 ; No, BSP, more to do
; Successful open in raw packet mode, finish up and return
UNLOCK(PRTLCK,RESIDENT,SPQ) ; Unlock local socket table
SKIPN 1(E) ; Is foreign port fully wildcard?
SKIPE 2(E)
JRST SKPRET## ; No, done
SETZM PUPFPT(UNIT) ; Yes, remember so
MOVEI B,(E) ; Release the address block
PUSHJ P,RELPFR
JRST SKPRET## ; Done, skip return
; Here if BSP mode. Lock port and setup BSP data block
PUPOP4: PUSHJ P,BLDBSP ; Allocate and build BSP data block
ERPOPJ(OPNX10,<UNLOCK(PRTLCK,RESIDENT,SPQ)
PUSHJ P,DELPRT>) ; Failed
HRRM BSP,PUPLNH(UNIT) ; Store pointer in standard place
MOVSI IOS,(BSLCKF+BSOPNR) ; Assume opening for reading
TEST(NE,WRTF) ; Writing?
MOVSI IOS,(BSLCKF+BSOPNW) ; Yes
MOVEM IOS,PUPSTS(UNIT) ; Initialize port status word
UNLOCK(PRTLCK,RESIDENT,SPQ) ; Unlock local socket table
XCTUU [HLRZ A,2] ; Get lh 2 from user
TRNE A,377 ; Timeout interval specified?
DPB A,PBSTMO ; Yes, set it
; Initiate appropriate operations to open a connection
TRNE STS,2 ; Listening?
JRST [ TLO IOS,(BSLISF) ; Yes, remember so
MOVEI A,E.OPNL ; Generate event OPENF(L)
JRST PUPOP5]
TRNE STS,4 ; Direct open (no rendezvous)?
JRST [ UMOVE A,3 ; Yes, get Connection ID from user
PUSHJ P,SETCID ; Set it in data block
MOVEI A,E.OPNN ; Generate event OPENF(N)
JRST PUPOP5]
MOVEI A,E.OPNC ; Initiating rendezvous, OPENF(C)
PUPOP5: PUSHJ P,PUPFSM ; Activate the FSM appropriately
JRST PUPOP7 ; Go wait if necessary
; Here if local port already in use, check for legal case
PUPOP6: HRRZ BSP,PUPLNH(UNIT)
SKIPE BSP ; Already open in raw packet mode?
TRNE STS,10 ; Opening in raw packet mode?
OPNERR(OPNX9,<UNLOCK(PRTLCK,RESIDENT,SPQ)>) ; Yes, fail
HRRZ A,PUPPSI(UNIT) ; No, get fork that did first open
HLRZ A,FKJOB##(A) ; Get job
CAME A,JOBNO ; Same as me?
OPNERR(OPNX9,<UNLOCK(PRTLCK,RESIDENT,SPQ)>) ; No, fail
MOVEI B,(E) ; Ok, get rid of address table
PUSHJ P,RELPFR
PUSHJ P,LCKBSA ; Attempt to lock the port
JRST [ UNLOCK(PRTLCK,RESIDENT,SPQ) ; Can't, unlock the table
MOVSI A,(UNIT) ; Set scheduler test
HRRI A,BSLCKT ; for port unlocked
JSYS EDISMS## ; Wait until unlocked
JRST PUPOP0] ; Try again
UNLOCK(PRTLCK,RESIDENT,SPQ) ; Ok, unlock the table
PUSHJ P,SETRWB ; Setup read/write bit for this opening
TDOE IOS,A ; Flag opening, check for conflict
ERPOPJ(OPNX9,<PUSHJ P,ULKBSP>) ; Already open, fail
HRLM UNIT,DEV ; Remember Pup unit #
HRLM UNIT,FILDEV(JFN)
; OPENF (cont'd)
; Here to wait for completion if necessary
PUPOP7: CHKSTT <OPEN,ENDI,ENDO,DALY,ABOR,CLOS> ; Beyond LIST/RFCO state?
TRNE STS,5 ; Immediate return OPENF?
JRST PUPOP8 ; Yes, bypass waiting
PUSHJ P,ULKBSP ; Unlock port
TEST(O,OPNF) ; Mark JFN as being open
MOVSI A,1 ; Fix reference count (?)
IORM A,FILLFW(JFN)
PUSHJ P,UNLCKF## ; Unlock file, go OKINT
MOVSI A,(ALLSTT-STTBTS(LIST,RFCO))
PUSHJ P,WATSTT ; In desired state now?
JSYS EDISMS## ; No, wait until get there
; Check whether the connection was opened successfully
; This is somewhat hairy since a PSI or another fork could have
; released and re-used the JFN in the meantime
LSH JFN,-SJFN
PUSHJ P,CHKJFN## ; NOINT, lock JFN again
ERR() ; Huh? (released by PSI maybe)
ERUNLK(DESX4)
ERUNLK(DESX4)
MOVSI A,(UNIT) ; Make sure JFN still refers to
HRRI A,PUPDTB ; the same Pup port
CAME A,DEV
ERPOPJ(DESX5) ; Not, fail
TEST(NE,OPNF) ; Make sure JFN still open
PUSHJ P,LCKBSQ ; Lock the port again
ERPOPJ(DESX5) ; Not open or not BSP port
MOVSI A,1 ; Undo reference count diddle
ANDCAM A,FILLFW(JFN)
; Come directly here in immediate-return modes
PUPOP8: CHKSTT <CLOS,ABOR> ; Connection closed or aborted?
TDZA A,A ; No, assume no error
MOVEI A,OPNX21 ; Yes, assume rejected by foreign host
TLNE IOS,(BSTIMF) ; Timed out?
MOVEI A,OPNX20 ; Yes, assume nobody there
JUMPN A,PUPOP9 ; Jump if failed to open
PUSHJ P,ULKBSP ; Succeeded, unlock port
JRST SKPRET## ; Give success return
; Here if rendezvous attempt failed
; Clean up and give error return, A/ error code
PUPOP9: HRLM A,0(P) ; Save error code
MOVEI A,E.CLST ; Generate CLOSF(T) event
HRROI C,0 ; Set code for Abort if any
HRROI D,[ASCIZ /Connection attempt timed out/]
PUSHJ P,PUPFSM ; Force state to closed
PUSHJ P,PUPCL3 ; Delete port if appropriate
BUG(HLT,<PUPOPN: Impossible +1 return from PUPCL3>)
TEST(Z,OPNF) ; JFN no longer open
HLRZ A,0(P) ; Recover error code
POPJ P, ; Fail return from OPENF
; Here to fail return from early parts of the OPENF when we have
; address table assigned but port not open yet (OPNERR macro)
; A/ error code, E/ address table pointer
OPNERX: PUSH P,A ; Save error code
MOVEI B,(E) ; Release address table
PUSHJ P,RELPFR
POP P,A
POPJ P,
; Close Pup network file (CLOSF)
PUPCLZ: HLRZ UNIT,DEV ; Setup Pup unit #
PUSHJ P,LCKBSQ ; Lock port if BSP
JRST PUPCL8 ; Not BSP, jump around BSP logic
SETZM FILCNT(JFN) ; Allow no further i/o
TLZE IOS,(BSTIMF) ; Timed out?
JRST [ MOVEI A,E.CLST ; Yes, generate CLOSF(T) event
HRROI C,0 ; Abort Code = 0 (need registered code ******)
HRROI D,[ASCIZ /Connection timed out/]
PUSHJ P,PUPFSM
TEST(O,ERRF) ; Set JFN error flag
ERPOPJ(IOX5,<PUSHJ P,ULKBSP>)] ; Give error return
TEST(NN,WRTF) ; Closing output JFN?
JRST [ TLNN IOS,(BSOPNW) ; No, is port also open for writing?
JRST PUPCL2 ; No, generate close event
JRST PUPCL3] ; Yes, do nothing for input close
CHKSTT <OPEN,ENDI> ; State ok for BSP output?
JRST PUPCL2 ; No, skip this
MOVE A,FILBYT(JFN) ; Yes, get byte ptr to last byte stored
PUSHJ P,FRCBSP ; Force out remaining data if any
PUSHJ P,CHKBOQ ; Any output pending?
JRST CLZWAT ; Yes, back out and wait til done
PUPCL2: MOVEI A,E.CLSN ; Generate CLOSF(N) event
HRROI C,0 ; Need registered code ************
HRROI D,[ASCIZ /Connection attempt abandoned/] ; In case RFC Out
PUSHJ P,PUPFSM
MOVSI A,(STTBTS(CLOS,ABOR)) ; Specify desired states
PUSHJ P,WATSTT ; Now closed or aborted?
JRST CLZWAT ; No, back out and wait until it is
LDB A,PBSSTT ; Yes, get current state
CAIE A,S.CLOS ; Now closed?
ERPOPJ(IOX5,<PUSHJ P,ULKBSP>) ; No, give error return
; Called here from OPENF code to clean up after rendezvous failure
PUPCL3: PUSHJ P,SETRWB ; Setup status bit for this opening
ANDCM IOS,A ; Mark no longer open this way
TLNE IOS,(BSOPNR+BSOPNW) ; Still open the other way?
JRST [ PUSHJ P,ULKBSP ; Yes, don't delete port yet
JRST SKPRET##] ; Success return
PUSHJ P,FLSBSQ ; Now closed both ways, flush queues
; Now delete the port (still locked if BSP port)
PUPCL8: MOVEI A,PUPOBC(UNIT) ; Check output counts
SKIPE 0(A) ; Output pending for this port?
PUSHJ P,DISE## ; Yes, wait until all gone
PUSHJ P,DELPRT ; Delete the port
JRST SKPRET## ; Done, skip return
; Must set bit in FILLFW before backing out of CLOSF.
; I don't really understand what the FILLFW bullshit is all about.
CLZWAT: MOVSI B,1
IORM B,FILLFW(JFN)
JRST ULKWAT
; Setup read/write bit appropriately for this opening of port
; STS/ File status
; Returns +1: A/ BSOPNR or BSOPNW set
SETRWB: MOVSI A,(BSOPNR) ; Assume opening for reading
TEST(NE,WRTF) ; Writing?
MOVSI A,(BSOPNW) ; Yes, say so