1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1984 *
  6 " *                                                         *
  7 " ***********************************************************
  8 
  9 " HISTORY COMMENTS:
 10 "  1) change(85-09-09,Fawcett), approve(85-09-09,MCR6979),
 11 "     audit(86-01-31,GDixon), install(86-03-21,MR12.0-1033):
 12 "     Support for FIPS.
 13 "  2) change(87-04-14,Farley), approve(87-07-06,MCR7717),
 14 "     audit(87-07-15,Fawcett), install(87-07-17,MR12.1-1043):
 15 "     Added test for unequal dcw list lengths.  In some cases save_dcws will
 16 "     be longer than handler_dcws.
 17 "                                                      END HISTORY COMMENTS
 18 
 19 
 20           name      toehold
 21 
 22 " This wired, privileged program resides in the low 256K
 23 " of memory at a known absolute location (toe_absloc). It is
 24 "
 25 " *** IMPURE
 26 " *** MODIFIED BY OTHER PROGRAMS
 27 " *** PRIVILEGED
 28 " *** RUNS IN ABSOLUTE MODE
 29 "
 30 " Started by Olin Sibert and Benson Margulies.
 31 " Finished by Keith Loepere in the glow of a maintenance panel.
 32 " Modified by Paul Farley and Rich Fawcett for large MSU3380 cylinders.
 33 " Modified by Keith Loepere to delay (AAARGHHH!!!) after status for DAU.
 34 
 35 "^L
 36           include   bootload_equs
 37 "^L
 38           include   coll0_segnos
 39 "^L
 40           include   fault_vector
 41 "^L
 42           include   flagbox
 43 "^L
 44           include   iom_data
 45 "^L
 46           include   scr
 47 "^L
 48           include   stack_frame
 49 "^L
 50           include   toehold_save_dcls_
 51 
 52 " *******************************************************************
 53 " Enter at the following in ABSOLUTE MODE, via processor switches   *
 54 " or derail.                                                        *
 55 " *******************************************************************
 56 
 57           inhibit   on                            <><><>ON<><><>
 58 
 59 " Entry sequences: each one saves the machine state and then transfers to
 60 " the correct code.  The ret instruction allows some indicators to be set
 61 " at the same time so as to give us a flag saying what entry was made.
 62 
 63           org       TOE_HOLD_CRASH_ENTRY*2
 64           scu       toe_absloc+temp_scu           " Operator Crash
 65           ret       toe_absloc+switch_entry
 66 
 67           org       TOE_HOLD_ESD_ENTRY*2
 68           scu       toe_absloc+temp_scu           " ESD
 69           ret       toe_absloc+esd_entry
 70 
 71           org       TOE_HOLD_DUMP_ENTRY*2
 72           scu       toe_absloc+temp_scu           " DUMP entry
 73           ret       toe_absloc+dump_entry
 74 
 75           org       TOE_HOLD_MULTICS_ENTRY*2
 76           scu       toe_absloc+temp_scu           " Multics Crash
 77           ret       toe_absloc+multics_crash_entry
 78 
 79           org       TOE_HOLD_RESTART_ENTRY*2
 80           scu       toe_absloc+temp_scu           " Multics restart point
 81           ret       toe_absloc+multics_restart_entry
 82 
 83           org       TOE_HOLD_BOOT_ENTRY*2
 84           nop                                     " boot entry
 85           tra       bootload_abs_mode$0+toe_absloc
 86 
 87           org       toehold.flagbox
 88 flagbox:  bss       ,64
 89 
 90           org       toehold.handler_mc
 91 handler_mc:
 92           bss       ,48
 93 
 94           org       toehold.paths                 " io paths to use to save/
 95           equ       n_paths,4                     " restore Multics memory
 96 paths:    bss       ,io_path_size*n_paths         " (and read us in)
 97 
 98           org       toehold.n_paths_used
 99 n_paths_used:
100           bss       ,1                            " no of slots above used
101 
102           org       toehold.memory_state
103 memory_state:                                     " key state of memory/Multics
104           dec       0
105 
106           org       toehold.bce_dbr
107 bce_dbr:  bss       ,2                            " used to restart bce
108 
109           org       toehold.bce_mode_reg
110 bce_mode_reg:
111           bss       ,2                            " and cache_mode reg
112 
113           org       toehold.esd_segnum
114 esd_segnum:
115           bss       ,1
116 
117           org       toehold.dcw_list_size
118 dcw_list_size:
119           bss       ,1                            " dcw_list_size in upper
120                                                   " dcws_per_cly in lower
121           org       toehold.seeks_used
122 seeks_used:
123           bss       ,1
124 
125           org       toehold.save_dcws
126 save_dcws:
127           bss       ,260                          " dcw lists for saving memory
128 
129           org       toehold.handler_dcws
130 handler_dcws:
131           bss       ,260                          " dcw lists for reading bce
132 "^L
133           org       toehold.handler_code          " toehold code
134           mod       16
135 status:
136           bss       ,16                           " iom status area
137 ignore_status:
138           bss       ,16                           " undesired iom status area
139 
140 temp_scu:                                         " scu data saved before we
141           bss       ,8                            " know if we want to save it
142 save_regs:                                        " regs saved before we have
143           bss       ,8                            " decided to save state
144 temp_mode_reg:
145           bss       ,2                            " mode reg save
146 temp:     bss       ,2
147 
148 pcw:      bss       ,2                            " for disk i/o
149 
150 new_cfg:  bss       ,2                            " scu config info
151 
152 cfg_mask_mask:
153           oct       000777777777        Mask out Mask A and Mask B
154           oct       000777777777
155 
156 status_mask:                                      " iom mask for finding good
157           vfd       o36/370000770000,36/0         " status
158 
159 io_timer: bss       ,2                            " clock timer for timout
160 
161 thirty_secs:
162           dec       0,30000000                    " in microseconds
163 
164 cow:      oct       0                             " connect operand word
165 
166 turn_off_hregs:
167           oct       0
168 turn_off_cache:
169           oct       3
170 
171 which_entry:
172           bss       ,1
173 
174 seeks_done:
175           bss       ,1                            " in disk i/o
176 
177 operation_type:                                   " read/write disk i/o
178           bss       ,1
179 
180 operation_not_mask:                               " for removing operation
181           oct       007777777777                  " code from idcw's
182 
183 low_memory_save_size_in_chars:
184           vfd       36/4*2048
185 
186           equ_o     mbx_absloc,1200
187 
188           bool      scr_mr.id.4mw,000002          " id for a 4mw scu
189 
190 " Index register usage
191 
192           equ       rscr_index,7
193           equ       last_controller_mask,6        " for mask setting
194           equ       zap_smcm_return_index,5
195 
196                                         " for per cylinder i/o
197           equ       iom,6               " Index Register to mailbox array
198           equ       seek_dcws_index,5 " index off toehold for dcw_list for this seek
199           equ       chn,4               " Index Register to channel_mailbox
200           equ       dcws_index,3        " index off toehold for dcw_list
201           equ       seek_return_index,2 " return from connect_timeout
202           equ       io_return_index,1   " return from perform_io
203           equ       io_path_index,0     " to io_path
204 "^L
205           even
206 
207 bbl0_ptr: its       bbl0_segno_,0       " for finding early dumper
208 
209 " operands for return instructions in entry sequences
210 
211 switch_entry:
212           vfd       18/toe_absloc+save_machine_conditions,18/scu.neg+scu.bm+scu.abs
213 
214 multics_crash_entry:
215           vfd       18/toe_absloc+save_machine_conditions,18/scu.bm+scu.abs
216 
217 esd_entry:
218           vfd       18/toe_absloc+save_machine_conditions,18/scu.zero+scu.bm+scu.abs
219 
220 multics_restart_entry:
221           vfd       18/toe_absloc+restore_machine,18/scu.bm+scu.abs
222 
223 dump_entry:
224           vfd       18/toe_absloc+go_to_dump,18/scu.bm+scu.abs
225 
226 go_to_dump:
227           ldt       -1,du
228           tra       bootload_early_dump$0+toe_absloc
229 "^L
230 " Main entry to toehold.  Temporarily save state.  See if we need to save this
231 " state.  If so, copy temporary state into machine state, continue saving.
232 " Otherwise, throw away state and proceed to read in bce.
233 
234 save_machine_conditions:
235           scpr      toe_absloc+temp_mode_reg,06
236           lcpr      toe_absloc+turn_off_hregs,04
237           lcpr      toe_absloc+turn_off_cache,02
238           sreg      toe_absloc+save_regs
239           sti       toe_absloc+temp
240           ldt       -1,du                         " no tro, please
241 
242           lda       toe_absloc+temp               " extract indicators that
243           arl       12                            " say how we entered toehold
244           ana       =o77,dl
245           sta       toe_absloc+which_entry
246           tnz       toe_absloc+no_ilc_bump
247           lda       1,du                " if Multics entry, must skip drl
248           adla      toe_absloc+temp_scu+scu.ilc
249           sta       toe_absloc+temp_scu+scu.ilc
250 no_ilc_bump:
251 
252 " check to see if we should save memory (and state)
253 
254           lda       toe_absloc+memory_state
255           tze       toe_absloc+save_state   " will later go to early dump
256           cmpa      At_bce__early,dl
257           tze       toe_absloc+save_state         " early bce crash
258           cmpa      At_bce__boot,dl
259           tze       toe_absloc+save_state         " real bce crash
260           cmpa      Multics,dl
261           tze       toe_absloc+save_state         " service crash/shut
262           cmpa      Undefined_saving_state,dl
263           tze       toe_absloc+just_save_mbx      " forget state but save mem
264           cmpa      Undefined_saving_mem,dl
265           tze       toe_absloc+just_write_Multics " state saved
266 
267           tsx       zap_smcm_return_index,toe_absloc+zap_smcm
268           tra       toe_absloc+read_bce           " just_read_bce
269 
270 just_save_mbx:
271           tsx       zap_smcm_return_index,toe_absloc+zap_smcm
272           tra       toe_absloc+done_regs
273 
274 just_write_Multics:
275           tsx       zap_smcm_return_index,toe_absloc+zap_smcm
276           tra       toe_absloc+write_Multics
277 
278 save_state:                                       " save total state
279           lda       toe_absloc+memory_state
280           sta       toe_absloc+multics_state+mc_state.old_memory_state
281           lda       Undefined_saving_state,dl
282           sta       toe_absloc+memory_state
283 
284           spri      toe_absloc+multics_state+mc_state.mc_+mc.prs
285           spl       toe_absloc+multics_state+mc_state.mc_+mc.eis_info
286 
287           lda       toe_absloc+which_entry
288           tze       toe_absloc+non_manual_flag
289 
290           ldq       fgbx.manual_crash,du          " manual entry
291           orsq      fgbx_absloc+fgbx.rtb          " let bce know
292 
293 non_manual_flag:
294           orsa      fgbx_absloc+fgbx.rtb          " bce_entry field
295 
296           rscr      SC_ETC*8            " Read clock
297           staq      toe_absloc+multics_state+mc_state.mc_+mc.fault_time
298 
299           rscr      SC_IC*8             " Read interrupt cells
300           staq      toe_absloc+multics_state+mc_state.interrupt
301 
302 " Next project is to grab an scu mask
303 
304           eax       rscr_index,7*64
305           eax       last_controller_mask,7*2      " for last controller mask
306 
307 smcm_loop:
308           rscr      2*8,rscr_index      " Read mask
309           staq      toe_absloc+multics_state+mc_state.masks,last_controller_mask " save it
310           fld       0,dl                " ldaq 0,dl
311           sscr      2*8,rscr_index      " zonk it
312           eax       rscr_index,-64,rscr_index     " reduce
313           eax       last_controller_mask,-2,last_controller_mask " reduce
314           tpl       toe_absloc+smcm_loop
315 
316           inhibit   off                 <><><>OFF<><><>
317                                         " Why not?  We're masked.
318 
319           fld       0,dl
320           staq      toe_absloc+multics_state+mc_state.cfg
321           rscr      SC_MR*8
322           canq      scr_mr.id.4mw,du    " we always have mask on 6000 sc
323           tze       toe_absloc+skip_mask_set
324 
325           rscr      SC_CFG*8            " proceed to set mask A to us, B off
326           staq      toe_absloc+multics_state+mc_state.cfg
327           anaq      toe_absloc+cfg_mask_mask
328           staq      toe_absloc+new_cfg
329           lrl       scr_cfg2.port_no_shift+36
330           anq       scr_cfg2.port_no_mask,dl      " port no. to QL
331           lda       =o400000,du                   " Mask A to port 0
332           arl       0,ql                          " Mask A to our port
333           ldq       =o001000,du                   " Mask B off
334           oraq      toe_absloc+new_cfg
335           sscr      SC_CFG*8
336 
337 skip_mask_set:
338           mlr       (),()                         " copy temp save state
339           desc9a    toe_absloc+temp_scu,8*4       " into real state
340           desc9a    toe_absloc+multics_state+mc_state.mc_+mc.scu,8*4
341           mlr       (),()
342           desc9a    toe_absloc+save_regs,8*4
343           desc9a    toe_absloc+multics_state+mc_state.mc_+mc.regs_word,8*4
344           ldaq      toe_absloc+temp_mode_reg
345           staq      toe_absloc+multics_state+mc_state.mode_reg
346 
347           sbar      toe_absloc+multics_state+mc_state.bar
348           scpr      toe_absloc+temp,01            " store two words
349           ldaq      toe_absloc+temp
350           sta       toe_absloc+multics_state+mc_state.mc_+mc.fault_reg
351           rsw       2                   " what kind of CPU?
352           arl       30                  " -- AL
353           ana       =o000003,dl         " just type
354           eax4      0,al                " following expects that in X4
355           lrl       mc.cpu_type_shift
356           stcq      toe_absloc+multics_state+mc_state.mc_+mc.cpu_type_word,70 " and store
357 
358 " Save history registers.
359 " The following is stolen from fim_util.
360 
361           ldq       2,du                          get a 2 for stepping address
362           eax6      4                             4 blocks of
363 scpr1:    eax7      16                            16 history registers
364           eax3      0                             set up for L68 CPU type initally
365           cmpx4     1,du                          is this a DPS8/70M CPU?
366           tnz       toe_absloc+scpr2              xfer if no, it is L68
367           eax3      48                            yes, set up to skip first 48 hregs
368 scpr2:    lda       toe_absloc+scpr-1,6           get correct instruction
369           sta       toe_absloc+temp               save in stack
370 scpr3:    xec       toe_absloc+temp               execute the instruction
371           cmpx3     0,du                          are we through skipping hregs?
372           tze       toe_absloc+scpr5              yes, go increment address
373           eax3      -1,3                          no, skip another
374           tra       toe_absloc+scpr3              and go execute scpr again
375 
376 scpr5:    asq       toe_absloc+temp               increment address of instruction
377           eax7      -1,7                          count down
378           tnz       toe_absloc+scpr3              more of this 16 double word block
379           eax6      -1,6                          count down
380           tnz       toe_absloc+scpr1              another kind of hreg
381 
382           eax7      64                            initially set clear count to 64
383           cmpx4     1,du                          is this a DPS8/70M CPU?
384           tze       2,ic                          yes, clear all 64 hregs
385           eax7      16                            no, clear only 16 hregs
386           lcpr      0,03                          set all history regs to zero
387           eax7      -1,7                          count down
388           tpnz      -2,ic                         xfer if more to do
389           tra       toe_absloc+do_ams
390 
391 scpr:     scpr      toe_absloc+multics_state+mc_state.ou_history_registers,40
392 "                                       OU History Regs for L68, OU/DU for DPS8
393           scpr      toe_absloc+multics_state+mc_state.cu_history_registers,20
394 "                                                 CU History Regs
395           scpr      toe_absloc+multics_state+mc_state.du_history_registers,10
396 "                             DU History Regs for L68, extended APU for DPS8
397           scpr      toe_absloc+multics_state+mc_state.apu_history_registers,00
398 "                                                 APU History Regs
399 
400 do_ams:   sptp      toe_absloc+multics_state+mc_state.ptwam_ptrs      " associative memories
401           sptr      toe_absloc+multics_state+mc_state.ptwam_regs
402           ssdp      toe_absloc+multics_state+mc_state.sdwam_ptrs
403           ssdr      toe_absloc+multics_state+mc_state.sdwam_regs
404           cmpx4     1,du
405           tnz       toe_absloc+done_regs                    for dps8, we must save other three banks
406           sptp      toe_absloc+multics_state+mc_state.ptwam_ptrs+16
407           sptp      toe_absloc+multics_state+mc_state.ptwam_ptrs+32
408           sptp      toe_absloc+multics_state+mc_state.ptwam_ptrs+48
409 
410           sptr      toe_absloc+multics_state+mc_state.ptwam_regs+16
411           sptr      toe_absloc+multics_state+mc_state.ptwam_regs+32
412           sptr      toe_absloc+multics_state+mc_state.ptwam_regs+48
413 
414           ssdp      toe_absloc+multics_state+mc_state.sdwam_ptrs+16
415           ssdp      toe_absloc+multics_state+mc_state.sdwam_ptrs+32
416           ssdp      toe_absloc+multics_state+mc_state.sdwam_ptrs+48
417 
418           ssdr      toe_absloc+multics_state+mc_state.sdwam_regs+32
419           ssdr      toe_absloc+multics_state+mc_state.sdwam_regs+64
420           ssdr      toe_absloc+multics_state+mc_state.sdwam_regs+96
421 "^L
422 
423 done_regs:
424 
425 " A transfer here in the normal case means that we are done saving state.
426 " This is not strictly correct.  Normally, it would not matter (except for
427 " certain obvious exceptions) in what order we saved state.  However, in the
428 " case in which the toehold itself is interrupted, we must be very careful.
429 " If the toehold is interrupted, in general, the state saved will not be
430 " correct.  It will not be possible to perform a go.  We must ensure, however,
431 " that an esd is possible.  To this end, we save certain toehold invariant
432 " state (information which the toehold doesn't change for its own purposes (as
433 " opposed to index registers, for instance)) which must be saved and restored
434 " for a successful esd.
435 
436 " The idea is to first save the iom_mailbox (two pages containing)
437 " and then "fix" it for this program's needs. The saved ones
438 " can then be saved in the image.
439 
440           sdbr      toe_absloc+multics_state+mc_state.dbr
441 
442           ldq       toe_absloc+low_memory_save_size_in_chars
443           mlr       (rl),(rl)
444           desc9a    0,ql
445           desc9a    toedata_absloc,ql
446 
447           eax0      bootload_early_dump$0
448           lda       toe_absloc+multics_state+mc_state.old_memory_state
449           tze       toe_absloc+bbl0_ptr,*x0
450                                         " not valid, perform an early
451                                         " dump- re-enter appending mode
452 
453           lda       Undefined_saving_mem,dl
454           sta       toe_absloc+memory_state
455 
456 write_Multics:
457 
458 " write out Multics memory image
459 
460           lda       =o310000,du                   " write
461           sta       toe_absloc+operation_type
462           eax       dcws_index,save_dcws
463           tsx       io_return_index,toe_absloc+perform_io
464 
465           lda       Undefined_reading_bce,dl
466           sta       toe_absloc+memory_state
467 
468 read_bce:
469           lda       toe_absloc+which_entry
470           als       12
471           ana       scu.zero,dl
472           tnz       toe_absloc+perform_esd
473 
474 " read in bootload Multics memory image
475 
476           lda       =o250000,du                   " read
477           sta       toe_absloc+operation_type
478           eax       dcws_index,handler_dcws
479           tsx       io_return_index,toe_absloc+perform_io
480 
481 " now return to bootload Multics
482 
483           ldt       -1,du
484 
485           ldq       toe_absloc+low_memory_save_size_in_chars " restore fault_vector
486           mlr       (rl),(rl)                               " iom_mailbox from
487           desc9a    toedata_absloc,ql                       " toehold_data
488           desc9a    0,ql
489 
490           ldbr      toe_absloc+bce_dbr                      " restore regs
491           lpl       toe_absloc+handler_mc+mc.eis_info
492           lpri      toe_absloc+handler_mc+mc.prs
493           ldaq      toe_absloc+handler_mc+mc.scu+4
494           staq      pr6|stack_frame.return_ptr    " save_handler_mc saved these
495                                                   " pointers here for us to
496                                                   " reload.  This was because
497                                                   " they were stored into the
498                                                   " stack after it was saved
499                                                   " to disk.
500           ldaq      toe_absloc+handler_mc+mc.scu+6
501           staq      pr6|stack_frame.operator_ptr
502 
503           ldq       At_bce__crash,dl              " new state = crash
504           lda       toe_absloc+multics_state+mc_state.old_memory_state
505           cmpa      Multics,dl                    " (will be refined during
506           tnz       toe_absloc+set_new_state      " collection 1)
507           lda       fgbx_absloc+fgbx.rtb
508           ana       fgbx.shut,du                  " = shutdown only if shut
509           tze       toe_absloc+set_new_state      " and old state = Multics
510           ldq       At_bce__shutdown,dl
511 set_new_state:
512           stq       toe_absloc+memory_state
513 
514           lreg      toe_absloc+handler_mc+mc.regs_word
515           ldi       toe_absloc+handler_mc+mc.scu+2
516           epp0      toe_absloc+handler_mc+mc.scu+0,*
517           lcpr      toe_absloc+bce_mode_reg,04    " mode and cache mode reg
518           lcpr      toe_absloc+bce_mode_reg+1,02
519           tra       pr0|1                         " go to short_return in
520                                                   " save_handler_mc
521 "^L
522 " esd from switches
523 
524 perform_esd:
525           lda       toe_absloc+esd_segnum         " force to emergency_shutdown|0
526           als       scu.psr_shift
527           ada       scu.p,dl
528           sta       toe_absloc+multics_state+mc_state.mc_+mc.scu+scu.ppr_word
529 
530           lda       scu.bm,dl
531           sta       toe_absloc+multics_state+mc_state.mc_+mc.scu+scu.ilc
532 
533           fld       0,dl
534           staq      toe_absloc+multics_state+mc_state.interrupt
535 
536           staq      toe_absloc+multics_state+mc_state.cfg
537 
538           tra       toe_absloc+restore_machine
539 "^L
540 " Restore the memory image
541 
542           inhibit   on                            <><><>ON<><><>
543 
544 restore_machine:
545           ldt       -1,du                         " no timer runout
546           lda       Undefined_continue,dl
547           sta       toe_absloc+memory_state
548 
549           tsx       zap_smcm_return_index,toe_absloc+zap_smcm  "mask us
550 
551           inhibit   off                           <><><>OFF<><><>
552 
553 " Read back Multics
554 
555           lda       =o250000,du                   " read
556           sta       toe_absloc+operation_type
557           eax       dcws_index,save_dcws
558           tsx       io_return_index,toe_absloc+perform_io
559 
560 " Restore the IOM Mailbox
561 
562           ldq       toe_absloc+low_memory_save_size_in_chars
563           mlr       (rl),(rl)
564           desc9a    toedata_absloc,ql
565           desc9a    0,ql
566 
567           ldbr      toe_absloc+multics_state+mc_state.dbr   " restore regs
568 
569           ldt       -1,du
570           lbar      toe_absloc+multics_state+mc_state.bar
571 
572 " Turn on cache and hregs here
573 
574           lcpr      toe_absloc+multics_state+mc_state.mode_reg,04
575           lcpr      toe_absloc+multics_state+mc_state.mode_reg+1,02
576 
577 " Restore system controllers
578 
579           inhibit   on                            <><><>ON<><><>
580 
581           ldaq      toe_absloc+multics_state+mc_state.cfg
582           tze       2,ic
583           sscr      SC_CFG*8
584 
585           ldaq      toe_absloc+multics_state+mc_state.interrupt
586           sscr      SC_IC*8             " restore interrupt cells
587 
588           eax       rscr_index,7*64
589           eax       last_controller_mask,7*2
590 
591 restore_mcm_loop:
592           ldaq      toe_absloc+multics_state+mc_state.masks,last_controller_mask
593           sscr      2*8,rscr_index
594           eax       rscr_index,-64,rscr_index
595           eax       last_controller_mask,-2,last_controller_mask
596           tpl       toe_absloc+restore_mcm_loop
597 
598           lpl       toe_absloc+multics_state+mc_state.mc_+mc.eis_info
599           lpri      toe_absloc+multics_state+mc_state.mc_+mc.prs
600 
601           lda       toe_absloc+multics_state+mc_state.old_memory_state
602           sta       toe_absloc+memory_state
603 
604           lda       scu.rfi,dl                    refetch instruction interrupted
605           sta       toe_absloc+multics_state+mc_state.mc_+mc.scu+scu.rfi_word
606 
607           lreg      toe_absloc+multics_state+mc_state.mc_+mc.regs_word
608           lra       toe_absloc+multics_state+mc_state.mc_+mc.regs_word+7
609           ldt       =o40000,dl                    wake up soon
610           rcu       toe_absloc+multics_state+mc_state.mc_+mc.scu
611 
612           inhibit   off                           <><><>OFF<><><>
613 "^L
614 perform_io:
615 
616 " internal procedure to perform io given a dcw_list.
617 " inputs are operation_type and dcws_index
618 " For now there are a maximum of 4 paths to try to use to do I/O
619 
620 try_first_path:
621           lda       toe_absloc+low_memory_save_size_in_chars
622           mlr       (),(rl),fill(000)   " zero mailboxes
623           desc9a    0,0
624           desc9a    0,al
625 
626           ldq       toe_absloc+n_paths_used
627           sbq       1,dl
628           mpy       io_path_size,dl
629           eax       io_path_index,0,ql  " point to last io_path
630 
631 try_another_path:
632           lda       toe_absloc+paths+io_path.port_number_word,io_path_index
633           tze       toe_absloc+bad_path
634 
635           eax       seek_dcws_index,dcw_list.seek_addresses,dcws_index " point into structure at first
636           stz       toe_absloc+seeks_done         " remember the number we have done.
637 
638 next_seek:
639           szn       toe_absloc+dcw_list.seek_idcw,seek_dcws_index " check for valid idcw
640           tze       0,io_return_index             " must be done
641           ldt       -1,du                         " try i/o through a path
642           tsx       seek_return_index,toe_absloc+connect_timeout
643 
644           ldaq      toe_absloc+status             " check for error
645           tze       toe_absloc+bad_path
646           anaq      toe_absloc+status_mask
647           tze       toe_absloc+done_seek
648 
649 bad_path:
650           eax       io_path_index,-io_path_size,io_path_index " down
651           tpl       toe_absloc+try_another_path
652           tra       toe_absloc+try_first_path
653 
654 done_seek:
655           adx       seek_dcws_index,toe_absloc+dcw_list_size " point to next list
656           lda       toe_absloc+seeks_done
657           ada       1,dl
658           sta       toe_absloc+seeks_done
659           cmpa      toe_absloc+seeks_used
660           tmi       toe_absloc+next_seek
661           tra       0,io_return_index             " finished  all seeks
662 "^L
663 " Subroutine to do the I/O
664 " inputs are operation type, io_path_index, seek_dcws_index
665 
666 connect_timeout:
667           lda       toe_absloc+paths+io_path.iom_number_word,io_path_index      " IOM tag (1-4)
668           arl       io_path.iom_number_shift      " upper half
669           ana       io_path.iom_number_mask,dl    " mask out port num
670           sba       1,dl                " (0-3)
671           als       8                   " 256 words/mailbox
672           eax       iom,iom_mailbox_seg.iom_mailbox,al
673 
674           ldq       toe_absloc+paths+io_path.channel_number,io_path_index " channel number
675           anq       =o777777,dl         " lower half
676           qls       2                   " 4 words/channel
677           eax       chn,0,ql
678           stx       iom,toe_absloc+pcw  " (temp)
679           adx       chn,toe_absloc+pcw  " point to the channel_mailbox
680 
681           qls       27-2                " now in high byte (invent PCW w/chan)
682           lda       toe_absloc+paths+io_path.pcw,io_path_index " get caller's PCW
683           staq      toe_absloc+pcw      " save it
684 
685           lda       toe_absloc+dcw_list.data_idcw,seek_dcws_index
686           ana       toe_absloc+operation_not_mask
687           ora       toe_absloc+operation_type     " make into appropriate idcw
688           sta       toe_absloc+dcw_list.data_idcw,seek_dcws_index
689 
690           absa      toe_absloc+dcw_list.seek_idcw,seek_dcws_index      " get address of DCW list
691           als       6                   " in AU
692           sta       mbx_absloc+channel_mailbox.lpw,chn      " set DCW addr, clear rest
693           stz       mbx_absloc+channel_mailbox.lpw+1,chn    " Unused
694                                         " store LPW
695 
696           absa      toe_absloc+status   " get address of status area
697           als       6                   " in AU
698           sta       mbx_absloc+channel_mailbox.scw,chn " status there
699                                         " set SCW
700 
701           absa      toe_absloc+pcw      " get address of PCW
702           als       6                   " in AU
703           ora       =o020001,dl         " set bits for connect LPW
704           sta       mbx_absloc+(connect_channel*4)+channel_mailbox.lpw,iom
705 
706           lda       toe_absloc+paths+io_path.port_number_word,io_path_index
707           arl       io_path.port_number_shift     " port number on scu of iom
708           ana       io_path.port_number_mask,dl   " into cow
709           sta       toe_absloc+cow
710 
711           stz       toe_absloc+status
712           cioc      toe_absloc+cow      " fire up the IOM
713 
714           lda       toe_absloc+pcw      " look at the PCW
715           cana      =o040000,dl         " was it a mask?
716           tnz       toe_absloc+no_status " yes, no status
717 
718           rscr      SC_ETC*8            " current time
719           adaq      toe_absloc+thirty_secs
720           staq      toe_absloc+io_timer " timeout time
721 
722 status_wait:
723           ldaq      toe_absloc+status   " status yet?
724           tmi       toe_absloc+got_status
725 
726           rscr      SC_ETC*8            " watch time go by
727           cmpaq     toe_absloc+io_timer " count down to timeout
728           tmi       toe_absloc+status_wait " fall through on timeout
729                                         " caller detects since status is 0
730 no_status:
731           fld       0,dl                " make sure status is 0 on timeout
732 got_status:                             " or mask PCW, for that matter
733           staq      toe_absloc+status
734 
735           absa      toe_absloc+ignore_status " make sure no more status arrives
736           als       6
737           sta       mbx_absloc+channel_mailbox.scw,chn
738 
739 " delay after status return so DAU/Dipper can reset themselves
740 
741           rscr      SC_ETC*8            " current time
742           staq      toe_absloc+io_timer
743 
744 status_delay:
745           rscr      SC_ETC*8            " watch time go by
746           sbaq      toe_absloc+io_timer " time gone by
747           cmpq      150,dl              " 150 usecs is good
748           tmi       toe_absloc+status_delay
749 
750           tra       0,seek_return_index
751 "^L
752           inhibit   on                            <><><>ON<><><>
753 
754 zap_smcm:                                         " mask all controllers
755           eax       rscr_index,7*64
756           eax       last_controller_mask,7*2      " for last controller mask
757 
758 zap_smcm_loop:                                    " mask us
759           fld       0,dl                          " ldaq 0,dl
760           sscr      2*8,rscr_index                " zonk it
761           eax       rscr_index,-64,rscr_index     " reduce
762           eax       last_controller_mask,-2,last_controller_mask " reduce
763           tpl       toe_absloc+zap_smcm_loop
764           tra       0,zap_smcm_return_index
765 
766           inhibit   off                           <><><>OFF<><><>
767 
768           org       toehold.multics_state         " machine state of Multics
769 multics_state:
770           bss       ,mc_state_size
771           end