1 " ***********************************************************
2 " * *
3 " * Copyright, C Honeywell Bull Inc., 1987 *
4 " * *
5 " * Copyright, C Honeywell Information Systems Inc., 1982 *
6 " * *
7 " ***********************************************************
8
9 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
10 " "
11 " BOOTLOAD_LOADER: Subroutine to read "
12 " collection 0.5 tape fw or collection 1. "
13 " "
14 " tsx2 bootload_loader$load_collection "
15 " tsx2 bootload_loader$skip_collection "
16 " tsx2 bootload_loader$init "
17 " "
18 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
19
20 " HISTORY COMMENTS:
21 " 1) change85-09-09Farley, approve85-09-09MCR6979,
22 " audit86-03-05GDixon, install86-03-21MR12.0-1033:
23 " Support IMU and FIPS.
24 " 2) change87-03-12Farley, approve87-07-06MCR7717,
25 " audit87-07-15Fawcett, install87-07-17MR12.1-1043:
26 " Corrected adjust_tape_device routine to only alter the IDCW if dealing
27 " with a non-cold MPC. Also added reset&mask to POF retry.
28 " 3) change87-07-23Farley, approve87-07-23PBF7717,
29 " audit87-07-24Fawcett, install87-07-28MR12.1-1047:
30 " Changed POF retry to only unwedge the tape controller one time. Found
31 " that more than once causes the IMU to fault..
32 " END HISTORY COMMENTS
33
34
35 " Created 10/02/80, W. Olin Sibert, from bootstrap1 and assorted oddments
36 " Modified 11/12/80, WOS, to add automatic tape firmware finder/loader.
37 " Modified 12/16/80, WOS, to construct SDWs for both ADP and Level 68, and
38 " to eliminate check_overflow, on the assumption that the MST checker
39 " should do that checking instead.
40 " Modified 04/21/81, Chris Jones for simplified I/O
41 " Modified 9/83, Keith Loepere for adp and paged wired segs.
42 " Modified 12/83, Keith Loepere for breakpoint_page support.
43 " Modified June-July 1984 by Paul Farley for IMU support.
44 " Modified 7/84, Keith Loepere to not clobber bkpt page.
45 " Modified 5/85, Chris Jones to calculate position of trailer correctly for
46 " padded records.
47
48 name bootload_loader
49
50 include bootload_equs
51 include bootload_cpu_macros
52 include coll0_segnos
53 include hc_definitions_seg
54 include hc_linkage_seg
55 include_nolist iom_word_macros
56 include_nolist make_data_macros
57 include mstr
58 include sdw_info
59 include slt
60 include slte
61 include system_types
62 include_nolist tape_io_commands
63 include unpaged_page_tables
64 " ^L
65 equ prb.ctl,0
66 equ prb.data,1
67 equ prb.nameptr,1041
68 equ prb.hdr,1042
69
70
71 Bentry init
72 init:
73 Bpush
74
75 absa_au prb|prb.data
76 stca read_tape_ddcw,70
77 neg 0 " adjust prb pointer
78 sba mst_label.head,du " correct for MSTRH
79 asa prb|prb.ctl
80
81 " Note ahem that the following code depends on the fact that:
82 " 1. data_bits_used and data_bit_len are in the same word upper and lower,
83 " 2. they are both multiples of 36 so the division leaves word oriented values
84 " in qu and ql, and
85 " 3. the upper half of ndata is the amount of real data, BUT
86 " the lower half is the actual amount of data read including the pad
87
88 ldq prb|prb.data+mstr_header.data_bits_used
89 div 36,dl
90 stq ndata
91
92 lda prb|prb.data+mstr_header_size+mstr_trailer.tot_rec_word,ql
93 " current record
94 ada 1,dl
95 sta exprec
96 stz unwedged " reset flag word
97 Breturn
98
99
100 segdef finish
101
102 finish: eax7 3*2
103 setclr: epp seg,clptrs,x7*
104 epbp seg2,seg|0
105 spri6 seg2|hc_linkage_seg.next_free_ptr
106 eax7 -2,x7 " on to next
107 tpl setclr
108
109 epp seg,cdptr,*
110 epbp seg2,seg|0
111 spri6 seg2|definitions.next_free_ptr
112
113 tra 0,x2
114 "^L
115 Bentry skip_collection
116
117 skip_collection:
118 Bpush
119
120 tsx2 adjust_tape_device
121
122 skip_next:
123 tsx2 readcw " Look at next control word
124 tra something_to_skip " data
125 tsx0 bootload_error$bad_cw
126
127 load.cmark:
128 tsx2 skip " skip the collection mark
129 arg k1
130 Breturn
131
132 something_to_skip: " First skip the SLTE
133 tsx2 skip " grab the header
134 arg cw
135
136 tsx2 readcw " Now read the CW
137 tsx0 bootload_error$bad_cw
138 tra skip.data
139 tsx0 bootload_error$bad_cw
140
141 skip.data:tsx2 skip
142 arg cw
143 tra skip_next " and again
144 " ^L
145 Bentry load_collection
146
147 load_collection:
148 Bpush
149
150 tsx2 adjust_tape_device
151
152 load.text:tsx2 read_header " read the header
153 tra load.cmark " we are done
154
155 lda prb|prb.hdr-1+slte.link_sect_word
156 " make sure this is the text
157 cana slte.link_sect+slte.defs,dl
158 tnz bootload_error$bad_sequence
159
160 tsx2 bootload_slt_manager$build_entry " build the SLTE
161 arg hcw
162 arg hdrp,*
163 tra bootload_error$too_many_segs
164
165 spri1 segptr " save pointer to it
166 spri6 lastsltptr
167
168 " check to see if this is an 'interesting' segment.
169
170 ldx7 seg|slte.names_ptr
171 lda nt|segnam.name,x7 get first 2 words of first name.
172 ldq nt|segnam.name+1,x7 "
173 eax6 interesting_names " x6 -> table of interesting names
174 rpt no_interesting_names,4,tze search the table
175 cmpaq 0,x6 compare first 8 characters
176 ttn load_segment skip if no compare
177
178 lxl0 seg|slte.segno get segment number again
179 stx0 -1,x6* store segment number for later use
180
181 " Make SDW for segment and load it.
182
183 load_segment:
184 tsx7 allocate routine to allocate core
185
186 tsx2 read " read the segment from tape
187 arg segptr,*
188 arg cw and store it in
189
190 tsx7 setaccess now set access on loaded segment
191
192 lda prb|prb.hdr-1+slte.link_provided_word
193 cana slte.link_provided,dl " linkage to read?
194 tze load.text " no
195 " ^L
196 " Process linkage segment.
197
198 tsx2 read_header
199 tsx0 bootload_error$bad_sequence
200
201 lda prb|prb.hdr+slte.link_sect_word-1 test for linkage segment
202 cana slte.link_sect,dl ..
203 tze bootload_error$bad_sequence
204
205 eax7 lastsltptr,* get index of text SLT entry
206 eax0 0 X0 will contain index to combined lkg ptr
207 lda slt|slte.init_seg_word,x7 init_seg?
208 cana slte.init_seg,dl ..
209 tze *+2 if so,
210 eax0 4,x0 increment index
211 lda slt|slte.link_sect_wired_word,x7 wired linkage?
212 cana slte.link_sect_wired,dl ..
213 tze *+2 if so,
214 eax0 2,0 increment index
215
216 epp seg,clptrs,x0* pr6 -> correct linkage segment free
217 " word
218 spri6 tempptr " save it
219 lxl1 slt|slte.segno,x7 X1 contains segment number of text segment
220 sprp seg,bootload_info$lot_ptr,*x1 set lot entry
221
222 lxl6 cw length of linkage in X6
223 adx6 1,du add one to size of this linkage
224 anx6 =o777776,du rounded up to next even
225 asx6 clptrs+1,x0 " update pointer
226
227 tsx2 read " read in the linkage
228 arg tempptr,*
229 arg cw
230
231 ldx7 segptr segment number of text in X7
232 epp seg,tempptr,* linkage header
233 stx7 seg|7 set text pointer in linkage header
234 " ^L
235 " Process definitions segment.
236
237 tsx2 read_header
238 tsx0 bootload_error$bad_sequence
239
240 lda prb|prb.hdr+slte.defs_word-1 test for defs segment
241 cana slte.defs,dl ..
242 tze bootload_error$bad_sequence
243
244 epbp seg,cdptr,* get ptr to base of defs
245 lda cw get length of defs section
246 ana =o777777,dl ..
247 ora cdptr+1 insert offset of place for defs
248 ldx7 segptr segment number of text in X7
249 sta seg|0,x7 add entry to definitions offset table
250
251 epp seg,cdptr,* pr6 -> place for defs
252 spri6 tempptr,* " save it in linkage
253 spri6 tempptr " and for reading
254 lxl6 cw get length of defs in X6
255 asx6 cdptr+1 set pointer for next time
256
257 tsx2 read " read the defs
258 arg tempptr,*
259 arg cw
260
261 tra load.text and loop
262 " ^L
263 " read in segment header information
264
265 read_header:
266 Bpush
267 tsx2 readcw " read the control word
268 tra rh.header
269 tsx0 bootload_error$bad_cw
270
271 Breturn
272
273 rh.header:lda cw " save away CW
274 sta hcw
275 tsx2 read " read in the logical segment header.
276 arg hdrp,*
277 arg hcw number of words wanted
278
279 tsx2 readcw " get cw of the segment
280 tsx0 bootload_error$bad_cw
281 tra read_header_returns
282 tsx0 bootload_error$bad_cw
283
284 read_header_returns:
285 Breturn 1
286
287
288 readcw: Bpush
289 tsx2 read
290 arg cw
291 arg k1
292 ldx7 cw " get CW type
293 tze rcw.0 " type 0
294 ersx7 cw " clear the word
295 cmpx7 1,du
296 tze rcw.1 " type 1
297 cmpx7 2,du " type 2
298 tnz bootload_error$bad_cw
299 Breturn 2
300 rcw.1: Breturn 1
301 rcw.0: Breturn 0
302 " ^L
303 segdef segptr
304
305 even
306 segptr: its -1,1
307 tempptr: its -1,1
308 lastsltptr:
309 its -1,1
310 clptrs: its -1,hc_linkage_seg.free_area active_sup_linkage
311 its -1,hc_linkage_seg.free_area wired_sup_linkage
312 its -1,hc_linkage_seg.free_area active_init_linkage
313 its -1,hc_linkage_seg.free_area wired_init_linkage
314 cdptr: its -1,definitions.first_free_word definitions_
315
316 hdrp: itp prb,prb.hdr-1
317
318 si: bss ,sdw_info_size
319 hcw: dec 0 control word for logical header
320 cw: dec 0 control word
321 k1: dec 1 " constant one
322 bit_count_mask:
323 oct 000077777777 " mask for slte.bit_count
324 " ^L
325 macro int_name
326 maclist object,save
327 aci @&1@,8
328 zero &l2,0
329 arg &3
330 maclist restore
331 &end
332
333 " Table of 'interesting' names.
334
335 even
336 interesting_names:
337
338 int_name bootload,bootload_1,bootload_info$bootload_1_ptr
339
340 int_name lot,lot,bootload_info$lot_ptr
341
342 int_name as_linka,as_linkage,clptrs
343 int_name ws_linka,ws_linkage,clptrs+2
344 int_name ai_linka,ai_linkage,clptrs+4
345 int_name wi_linka,wi_linkage,clptrs+6
346
347 int_name definiti,definitions_,cdptr
348
349 int_name sys_boot,sys_boot_info,bootload_info$sys_boot_info_ptr
350
351 equ no_interesting_names,*-interesting_names/4
352 " ^L
353 " ALLOCATE
354 "
355 " This subroutine is called via TSX7 to allocate storage for the segment
356 " described by the SLTE currently in the headersegment buffer. An sdw_info
357 " is constructed si, and bootload_dseg$make_sdw is called to fabricate
358 " the SDW. The SDW is initially constructed with RW access, so the segment
359 " contents can be read in. After the segment is read in, the set_access
360 " entrypoint is called, the SDW is refabricated with the appropriate access,
361 " and is stored into the DSEG again. The sdw_info is constructed in the area
362 " called "si".
363 "
364 " Segments are allocated according to the following rules. X1 is used
365 " as a flag to indicate where the segment is to be allocated.
366 "
367 " * If the segment is zero length on the tape, it gets an all zero
368 " SDW. This case is handled first.
369 "
370 " * If the segment is a paged supervisor segment, or any sort of
371 " init-seg, it is allocated in a contiguous region of high order
372 " memory, on a 1024 word boundary. Its page table is put in
373 " int_unpaged_page_tables.
374 "
375 " * If the segment is an unpaged supervisor segment, it is allocated
376 " on a 1024 word boundary starting from the low end of memory. Its
377 " page table is put in unpaged_page_tables.
378 "
379 " If the segment has e access, we add the breakpoint_page as an
380 " extra page to the end.
381
382 running_address:
383 dec 0
384 seg_text_length:
385 dec 0
386
387 allocate:
388 mlr ,,fill000 " Clear out sdw_info
389 desc9a 0,0
390 desc9a si,4*sdw_info_size
391
392 ldq seg|slte.bit_count_word " Find out how big it is
393 anq bit_count_mask
394 adq 35,dl " Round up to a word
395 div 36,dl " and figure out how many words it is
396
397 tze allocate_empty_seg " If nothing there, give up now
398
399 adq 1023,dl " round up to 1024 words
400 anq =o776000,dl
401 stq si+sdw_info.bound " Save the length
402 stq seg_text_length " amount to clear doesn't count bkpt page
403
404 lda slt|slt.free_core_size " See if we've got room
405 sba si+sdw_info.bound
406 sba 1024,dl " subtract a page to allow for slop
407 tmi bootload_error$out_of_main_memory
408
409 lda seg|slte.firmware_seg_word
410 cana slte.firmware_seg,du
411 tnz allocate_seg_low
412
413 lda seg|slte.paged_word " Is seg to be paged?
414 cana slte.paged,du
415 tnz allocate_seg_high
416
417 lda seg|slte.init_seg_word " Or is it an init-seg, maybe?
418 cana slte.init_seg,dl
419 tnz allocate_seg_high " Yup, place with paged segments
420
421 allocate_seg_low:
422 lda slt|slt.free_core_start " Get space in low memory
423 sta running_address " Save the address
424 ada si+sdw_info.bound " Add the length, and adjust the
425 sta slt|slt.free_core_start " beginning of free core
426 lda slt|slt.free_core_size " Also adjust the size
427 sba si+sdw_info.bound
428 sta slt|slt.free_core_size
429 epp seg2,=itsupt_segno_0,*
430 tra have_seg_address
431
432 allocate_seg_high:
433 lda slt|slt.free_core_start " Assume these are already
434 ada slt|slt.free_core_size " 1024 word aligned.
435 sba si+sdw_info.bound " Adjust down by the seg lth.
436 sta running_address " Save the address
437 sba slt|slt.free_core_start " and calculate the new size
438 sta slt|slt.free_core_size " of free core -- free_core_start
439 epp seg2,=itsiupt_segno_0,*
440 tra have_seg_address " is unchanged
441
442 have_seg_address: " prseg2 -> upt unpaged page table
443 lda seg|slte.access_word " see if we should add breakpoint_page
444 ana =o200000,du " e permission
445 tze non_bkpt
446 lda slte.breakpointable,du
447 orsa seg|slte.breakpointable_word
448 lda 1024,dl " lengthen for bkpt page
449 asa si+sdw_info.bound
450 lda 1,dl
451 als slte.cur_length_shift
452 adla seg|slte.cur_length_word
453 sta seg|slte.cur_length_word " record as lengthened
454 lda 1,dl
455 als slte.max_length_shift
456 adla seg|slte.max_length_word
457 sta seg|slte.max_length_word
458 non_bkpt:
459 ldq seg2|upt.current_length
460 lda si+sdw_info.bound
461 ars 10 " # of pages
462 eax3 0,al
463
464 ada 3,dl
465 ars 1
466 als 1 " round to next size upt entry
467 ada seg2|upt.current_length
468 sta seg2|upt.current_length " allocated page table
469 cmpa seg2|upt.max_length
470 tmoz 2,ic
471 tsx0 bootload_error$upt_overflow
472 epp seg2,seg2|0,ql " -> upt_entry
473
474 lda segptr
475 ars 18 " segno
476 sta seg2|upt_entry.segno
477 stz seg2|upt_entry.size
478 sxl3 seg2|upt_entry.size
479 epp seg2,seg2|upt_entry.ptws
480 absa_al seg2|0
481 sta si+sdw_info.address
482
483 lda seg|slte.breakpointable_word
484 cana slte.breakpointable,du
485 tze 2,ic
486 eax3 -1,x3 " last ptw is special for bkpt page
487
488 lda running_address
489 gen_ptw:
490 tsx2 bootload_dseg$make_core_ptw
491 stq seg2|0
492 ada 1024,dl
493 epp seg2,seg2|1
494 eax3 -1,x3
495 tnz gen_ptw
496
497 lda seg|slte.breakpointable_word " add bkpt ptw if necessary
498 cana slte.breakpointable,du
499 tze no_add_bkpt_ptw
500 lda bkpt_absloc,dl
501 tsx2 bootload_dseg$make_core_ptw
502 stq seg2|0
503
504 no_add_bkpt_ptw:
505 lda sdw_info.paged,du
506 orsa si+sdw_info.flags
507
508 lda sdw_info.read+sdw_info.write,du " Set RW access
509 sta si+sdw_info.access
510
511 epp seg,si
512 tsx2 bootload_dseg$make_sdw
513
514 ldx3 segptr " segno * 2 in X3
515 adlx3 segptr
516 staq ds|0,x3 " Ka-ching!
517 lda bootload_info$system_type
518 cmpa ADP_SYSTEM,dl
519 tze 2,ic
520 cams 0
521
522 lda seg_text_length " now clear the segment
523 als 2 " characters
524 epp seg,segptr,*
525 mlr ,prrl,fill0
526 desc9a 0
527 desc9a seg|0,al
528 tra 0,x7 " and return
529
530
531 allocate_empty_seg:
532 lda sdw_info.faulted,du " Make the segment empty
533 sta si+sdw_info.flags " All the rest of si is still zero
534 ldx3 segptr " segno * 2 in X3
535 adlx3 segptr
536 stz ds|0,x3 " Ka-ching!
537 stz ds|1,x3 " Ka-ching!
538 tra 0,x7 " and return
539 " ^L
540 " SETACCESS
541 "
542 " This entry is called to set the proper access for the segment, once it
543 " has been read in. This is also where the encacheable bit is set.
544 "
545
546 setaccess:
547 lda si+sdw_info.flags " Is it worth it?
548 cana sdw_info.faulted,du
549 tnz 0,x7 " Nope, SDW is unusable
550
551 epp seg,prb|prb.hdr-1 " PR6 -> slte
552
553 lda seg|slte.cache_word " Set the encacheability bit
554 ana slte.cache,du
555 tze 3,ic
556 lda sdw_info.cache,du
557 orsa si+sdw_info.flags
558
559 lda seg|slte.access_word " Set the correct access
560 arl slte.access_shift " To low 4 bits
561 als 36-4 " Now to high 4 bits
562 sta si+sdw_info.access " and store it
563
564 epp seg,si " Make the SDW again
565 tsx2 bootload_dseg$make_sdw
566
567 ldx3 segptr " segno * 2 in X3
568 adlx3 segptr
569 staq ds|0,x3 " Ka-ching!
570 lda bootload_info$system_type
571 cmpa ADP_SYSTEM,dl
572 tze 2,ic
573 cams 0
574 tra 0,x7 " and return
575 " ^L
576 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
577 " "
578 " read: subroutine to read the input. "
579 " "
580 " calling sequence: tsx2 read "
581 " arg loc "
582 " arg =nwords "
583 " "
584 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
585
586 even
587 segdef tape_status
588 tape_status:
589 bss ,2
590 ndata: bss ,1
591 exprec: dec 0
592 length: dec 0
593 read_skip:dec 0
594
595 read: stc1 read_skip " this is read
596 epp seg,0,x2* " get ptr to data loc
597 lxl7 1,x2* get length
598 tra read_join
599
600 skip: stz read_skip " this is skip
601 lxl7 0,x2* " length
602
603 read_join:
604 stx7 length
605 Bpush
606
607 readloop:
608 ldx6 ndata get data length of tape record
609 sblx6 prb|prb.ctl compute # of words remaining in buffer
610 tze readp read next record if no more words left
611 cmpx6 length get min length words_remaining
612 tmoz *+2 ..
613 ldx6 length ..
614
615 szn read_skip " reading?
616 tze no_read " no
617
618 ldq prb|prb.ctl tape buffer offset in QU
619 eaa 0,x6 words to copy in AU
620 lls 2 generate character count and offset
621 mlr prrlqu,prrl copy data from tape buffer
622 desc9a prb|prb.data+mstr_header_size,au
623 desc9a seg|0,au
624
625 epp seg,seg|0,x6 bump pr6 by # of words copied
626
627 no_read:
628 eaa 0,x6 words copied in AU
629 asa prb|prb.ctl bump record index
630 neg 0 complement
631 asa length decrement length
632 tpnz readloop loop if more data to copy
633
634 read_return:
635 szn read_skip " return to caller
636 tze skip.return " skip
637 Breturn 2
638 skip.return:
639 Breturn 1
640 " ^L
641 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
642 " "
643 " Subroutine to read one physical record from tape "
644 " "
645 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
646
647 readp: rscr 32 " get time
648 staq io_start_time " and save it
649 stz prb|prb.ctl reset pointer on PRB to zero wds xmitted.
650 stz prb|prb.data+mstr_header.c1 and smash the magic word
651 try_readp_again:
652 tsx2 bootload_io$connect " Read a record
653 arg bootload_info$tape_iom_number
654 arg bootload_info$tape_channel_number
655 arg tape_io_pcw
656 arg read_tape_idcw
657
658 staq tape_status
659 cana bootload_info$status_mask
660 tnz tape_error
661 canq =o7777,dl " tally residue?
662 tnz readp " yes, skip it
663
664 ldq prb|prb.data+mstr_header.c1 " a quick spot check of the record.
665 cmpq magic_first we know the first and last words.
666 tnz readp it is probably just noise
667
668 " See the longish comment earlier about the dependencies between data_bits_used
669 " and data_bit_len, and why the following code works despite its bad habits.
670
671 ldq prb|prb.data+mstr_header.data_bits_used " get bit count of data bits
672 div 36,dl compute data word count
673 stq ndata and save
674
675 eax2 0,ql x2 is trailer pointer
676 ldq prb|prb.data+mstr_header_size+mstr_trailer.c2,x2
677 cmpq magic_last
678 tnz readp " bad record
679
680 lda prb|prb.data+mstr_header_size+mstr_trailer.tot_rec_word,x2 currec
681 cmpa exprec expected record?
682 tnz bootload_error$bad_mst
683
684 aos exprec save for next read
685 tra readloop " keep reading
686
687 tape_error:
688 ana =o770000,du " get just major/minor status
689 cmpa =o440000,du " EOF?
690 tze readp " yes, skip it
691 cmpa =o600000,du " POF?
692 tze retry_pof " try again
693 tra bootload_error$tape_error
694
695 retry_pof:
696 szn bootload_info$cold_tape_mpc " F/W yet?
697 tze chk_pof_time " yes, leave it alone
698 szn unwedged " has unwedging been done
699 tnz chk_pof_time " yes, just chk time & retry I/O
700 tsx2 bootload_tape_fw$reset_and_mask " no, do the unwedging
701 stc1 unwedged " show that it has been done
702
703 chk_pof_time:
704 rscr 32 " get the time
705 sbaq io_start_time " rel-a-tize
706 cmpaq thirty_sec_limit " is thirty seconds up?
707 tmi try_readp_again " NO, try one mo time
708 tra bootload_error$tape_error " report error
709
710 adjust_tape_device:
711
712 szn bootload_info$cold_tape_mpc " F/W yet?
713 tnz 0,x2 " no, leave it alone
714 lda bootload_info$tape_device_number
715 als 24
716 stca read_tape_idcw,20
717 lda =o3000,dl
718 stca read_tape_idcw,2
719 tra 0,x2 " return
720 " ^L
721 magic_first:
722 oct 670314355245 magic number at word 1 of record
723 magic_last:
724 oct 265221631704 magic number at end of record
725
726 unwedged: bss ,1
727 even
728 io_start_time:
729 bss ,2
730 thirty_sec_limit:
731 dec 0,30000000 " thirty seconds in micros
732
733 make_pcw tape_io_pcw, " PCW to reset status before tape I/O
734 TAPE.reset_status,
735 0,
736 0,
737 nondata,
738 terminate,
739 1
740
741 read_tape_idcw:
742 vfd 6/TAPE.read_binary_record,6/0,6/0,3/7,1/0,2/0,6o/0,6/0
743
744 make_ddcw read_tape_ddcw, " DDCW describing physical_record_buffer
745 0,
746 mstr_header_size+1024+mstr_trailer_size,
747 iotd
748
749 end