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,Farley), approve(85-09-09,MCR6979),
 11 "     audit(86-03-05,GDixon), install(86-03-21,MR12.0-1033):
 12 "      Support IMU.
 13 "  2) change(86-05-13,GJohnson), approve(86-05-13,MCR7387),
 14 "     audit(86-05-13,Martinson), install(86-05-14,MR12.0-1056):
 15 "     Correct error message documentation.
 16 "  3) change(87-10-02,Farley), approve(88-02-26,MCR7794),
 17 "     audit(88-03-04,Fawcett), install(88-03-15,MR12.2-1035):
 18 "     Added code to set the new flag bootload_info$imu_style_iom.
 19 "  4) change(88-02-12,Farley), approve(88-03-18,MCR7859),
 20 "     audit(88-04-11,Fawcett), install(88-04-19,MR12.2-1037):
 21 "     Added code to $init entry to properly setup the fault and special
 22 "     interrupt channel mailboxes to handle the storing of statuses in the
 23 "     proper places (instead of overwritting the interrupt vectors).
 24 "                                                      END HISTORY COMMENTS
 25 
 26           name      bootload_io
 27 
 28 " The bootload I/O package.
 29 " Rewritten October 1982 by C. Hornig
 30 " Modified September 1983 by Keith Loepere for adp.
 31 " Modified July 1984 by Paul Farley for IMU.
 32 
 33           equ       imw_size,128
 34           equ       iom_mailbox_size,256
 35           equ       channel_mailbox.lpw,0
 36           equ       channel_mailbox.scw,2
 37           equ       channel_mailbox.dcw,3
 38           equ       fault_status_base,32
 39           equ       special_status_base,80
 40           equ       status_queue_size,12
 41           bool      IOTP,010000                   " DU
 42           bool      cold_tape_mpc_mask,400000     " DU
 43           bool      imu_bit_mask,200000           " DU
 44           equ       imu_bit_shift,1
 45 
 46           mod       16
 47 status:   bss       ,16
 48 ignore_status:
 49           bss       ,16
 50 save_regs:bss       ,8
 51 
 52           even
 53 pcw:      bss       ,2
 54 
 55 esw:      bss       ,1
 56 temp:     bss       ,1
 57 " ^L
 58 " This routine copies the bootload program and sets up bootload_info
 59 "
 60 "         tsx2      bootload_io$preinit
 61 "
 62           segdef    preinit
 63 
 64 preinit:  epp       seg,bootload_info$iom_boot_info
 65           mlr       (pr),(pr),fill(0)             " copy the boot program
 66           desc9a    fv|0,64
 67           desc9a    seg|0,64
 68 
 69           lda       seg|0
 70           ana       =o770000,du         " check for adp vs l68 iom => system
 71           tnz       adp_init
 72 
 73           lda       L68_SYSTEM,dl
 74           sta       bootload_info$system_type
 75 
 76           lda       seg|2               " interrupt base
 77           ana       =o777770,dl
 78           cmpa      template_slt_$iom_mailbox_absloc
 79           tnz       bad_iom_interrupt_base
 80 
 81           lda       seg|2               " IOM number
 82           ana       =o7,dl
 83           sta       bootload_info$tape_iom_number
 84           aos       bootload_info$tape_iom_number
 85           als       8                   " offset in mailbox
 86           ada       seg|2               " absolute address in AL
 87           ana       =o777770,dl
 88           eax7      imw_size,al
 89           cmpx7     seg|2               " compare with IOM base
 90           tnz       bad_iom_base
 91 
 92           lda       seg|3               " get the device number
 93           arl       24
 94           ana       =o77,dl
 95           sta       bootload_info$tape_device_number
 96 
 97           ldq       seg|1
 98           qrl       27                  " and the channel
 99           anq       =o77,dl
100           stq       bootload_info$tape_channel_number
101 
102           ldq       bootload_info$tape_iom_number
103           lda       seg|1               " get the port number
104           ana       =o7,dl
105           sta       bootload_info$iom_port_table-1,ql
106 
107 " Make initial guesses about the presence of BOS.  If thsi test succeeds,
108 " then bootload_flagbox will check the BOS flagbox for the sentinel.
109 
110           lda       seg|7               " get cold boot flag
111           ana       cold_tape_mpc_mask,du
112           sta       bootload_info$cold_tape_mpc
113           era       =o400000,du         " not flag
114           sta       bootload_info$assume_config_deck
115 
116           lda       seg|7               " get imu flag
117           ana       imu_bit_mask,du
118           als       imu_bit_shift
119           sta       bootload_info$imu_style_iom
120 
121           tra       0,x2                " return
122 
123 adp_init:
124           lda       ADP_SYSTEM,dl
125           sta       bootload_info$system_type
126 
127           lda       seg|4               " IOX number and channel
128           sba       8,dl
129           lrs       7
130           ana       =o7,dl
131           sta       bootload_info$tape_iom_number
132           aos       bootload_info$tape_iom_number
133           qrs       36-7
134           stq       bootload_info$tape_channel_number
135 
136           lda       seg|0               " get the device number
137           arl       24
138           ana       =o77,dl
139           sta       bootload_info$tape_device_number
140 
141           stz       bootload_info$cold_tape_mpc
142 
143           tra       0,x2                " return
144 
145 bad_iom_interrupt_base:
146           lda       =o777777000001
147           dis
148           tra       -1,ic
149 
150 bad_iom_base:
151           lda       =o777777000002
152           dis
153           tra       -1,ic
154 " ^L
155 " This routine initializes the bootload I/O package.
156 "
157 "         tsx2      bootload_io$init
158 "
159           segdef    init
160 
161 init:     sreg      save_regs
162           lda       imw_size+4*64*4,dl
163           mlr       (),(pr,rl),fill(0)            " clear everything
164           desc9a    0,0
165           desc9a    mb|0,al
166 
167           lda       bootload_info$tape_iom_number " IOM tag (1-4)
168           als       8                             " 256 words/mailbox
169           eax3      imw_size-iom_mailbox_size,al  " X3 -> IOM mailbox
170           ldq       bootload_info$tape_iom_number " IOM tag (1-4)
171           mpy       status_queue_size,dl
172           eax4      -status_queue_size,ql         " X4 -> status Q index
173 
174           absa      mb|fault_status_base,x4       " get address of status Q
175           als       6
176           ora       IOTP+status_queue_size,dl     " setup status DCW
177           sta       mb|1*4+channel_mailbox.dcw,x3 " save DCW in fault chnl mbx
178           sta       mb|1*4+channel_mailbox.scw,x3 " save DCW for refresh
179           absa      mb|1*4+channel_mailbox.scw,x3 " get address of refresh DCW
180           als       6
181           ora       =o020001,dl                   " setup LPW
182           sta       mb|1*4+channel_mailbox.lpw,x3 " save LPW in fault chnl mbx
183 
184           absa      mb|special_status_base,x4     " get address of status Q
185           als       6
186           ora       IOTP+status_queue_size,dl     " setup status DCW
187           sta       mb|6*4+channel_mailbox.dcw,x3 " save DCW in spec-stat mbx
188           sta       mb|6*4+channel_mailbox.scw,x3 " save DCW for refresh
189           absa      mb|6*4+channel_mailbox.scw,x3 " get address of refresh DCW
190           als       6
191           ora       =o020001,dl                   " setup LPW
192           sta       mb|6*4+channel_mailbox.lpw,x3 " save LPW in spec-stat mbx
193 
194           lreg      save_regs
195           tra       0,x2
196 " ^L
197 " This routine issues a connect to the IOM using the caller's PCW
198 " and DCW lists.  The caller must insure a spare word in front of the
199 " dcw list so that, in the iox case, we can insert his pcw (made non-
200 " terminate) as another idcw in front.
201 "
202 "         tsx2      bootload_io$connect
203 "         arg       iom_no
204 "         arg       channel_no
205 "         arg       PCW_address
206 "         arg       DCW_address
207 "
208 "         tsx2      bootload_io$connect_timeout
209 "         arg       iom_no
210 "         arg       channel_no
211 "         arg       PCW_address
212 "         arg       DCW_address
213 "         tra       timeout_return
214 "
215 " The status from the IOM is returned in the AQ.
216 "
217           equ       con.iom,0
218           equ       con.channel,1
219           equ       con.pcw,2
220           equ       con.dcw,3
221           equ       con.nargs,4
222           equ       con_t.timeout,4
223           equ       con_t.nargs,5
224 
225           segdef    connect
226 
227 connect:  stc1      esw
228           tra       join
229 
230           segdef    connect_timeout
231 
232 connect_timeout:
233           stz       esw
234 
235 join:     sreg      save_regs
236           lda       bootload_info$system_type
237           cmpa      ADP_SYSTEM,dl
238           tze       adp_connect
239 
240 " Make check to see if the connect is for the console.
241 " If so we need to wait fifteen milliseconds after the status
242 " returns, so that the console adapter will have time
243 " to properly do the terminate interrupt.
244 " If not the console then set the wait time to one millisecond.
245 
246           stz       doing_console_io
247           szn       bootload_info$console_available
248           tze       not_console_io      " Haven't found one, yet!
249           lda       con.iom,x2*
250           cmpa      bootload_info$console_iom_number
251           tnz       not_console_io
252           lda       con.channel,x2*
253           cmpa      bootload_info$console_channel_number
254           tnz       not_console_io
255           lda       fifteen_millisec
256           sta       wait_time+1         " set wait time
257           lda       =o400000,du
258           sta       doing_console_io    " set console IO flag
259           tra       connect_continue
260 not_console_io:
261           lda       one_millisec
262           sta       wait_time+1
263 connect_continue:
264           lda       con.iom,x2*         " IOM tag (1-4)
265           eax1      -1,al               " IOM number in X1
266           als       8                   " 256 words/mailbox
267           eax3      imw_size-iom_mailbox_size,al
268                                         " X3 -> IOM mailbox
269           stx3      temp                " save it
270 
271           ldq       con.channel,x2*     " channel number
272           qls       2                   " 4 words/channel
273           eax4      0,ql                " in X4
274           adx4      temp
275 
276           qls       27-2                " now in high byte
277           lda       con.pcw,x2*         " get caller's PCW
278           staq      pcw                 " save it
279 
280           absa      con.dcw,x2*         " get address of DCW list
281           als       6                   " in AU
282           sta       mb|channel_mailbox.lpw,x4
283           stz       mb|channel_mailbox.lpw+1,x4
284                                         " store LPW
285 
286           absa      status              " get address of status area
287           als       6                   " in AU
288           sta       mb|channel_mailbox.scw,x4
289                                         " set SCW
290 
291           absa      pcw                 " get address of PCW
292           als       6                   " in AU
293           ora       =o020001,dl         " set bits for connect LPW
294           sta       mb|2*4+channel_mailbox.lpw,x3
295 
296           stz       status
297           ldx7      =o100000,du         " set status timer
298           lda       pcw                 " look at the PCW
299           cana      =o040000,dl         " was it a mask?
300           tze       connect_n_wait      " no, must wait for status
301           cioc      bootload_info$iom_port_table,x1 " fire up the IOM
302           tra       no_status           " don't wait for status
303 connect_n_wait:
304           cioc      bootload_info$iom_port_table,x1 " fire up the IOM
305 status_wait:
306           lda       status              " status yet?
307           tmi       got_status
308           adlx7     -1,du               " count down to timeout
309           tnz       status_wait
310           szn       esw                 " timer running?
311           tnz       status_wait
312 
313           stc1      esw                 " pretend we are not $timeout
314 
315 " IMU only does single precision stores, so after status word
316 " arrives we need to wait for the second word to be stored...
317 "
318 " IMU adapters also take awhile, after the status service, to do the
319 " status interrupt. Must wait for this, so a new connect will not cause
320 " the adapter to be faulted.
321 "
322 " The IMU console does not use PCWs and if the opcode in the IDCW causes
323 " a status return to have bit 16 (initiate) on then it needs to be processed.
324 " The LCC on an IOM does use the PCW, which has a opcode of reset-status, and
325 " the status will have bit 16 on. This status can be ignored and a better one,
326 " from the IDCW will come along.
327 
328 got_status:
329           szn       doing_console_io
330           tze       pause_for_status    " not console IO
331 
332           szn       bootload_info$console_pcw_check
333           tze       pause_for_status    " no...
334           stz       bootload_info$console_pcw_check " reset the check flag
335           era       initiate_status     " only sync & initiate bits ON?
336           tze       pause_for_status    " yes, console uses the PCW
337           stz       bootload_info$console_uses_pcw " no, console didn't use it.
338 
339 pause_for_status:
340           rscr      32                  " get current time
341           staq      status_time
342 
343           rscr      32
344           sbaq      status_time
345           cmpaq     wait_time
346           tmi       -3,ic
347 
348           ldaq      status              " should be there now!!
349           staq      save_regs+4         " save the status
350 
351           szn       doing_console_io
352           tze       no_status
353           szn       bootload_info$console_uses_pcw
354           tze       no_status           " pcw isn't used, so don't worry.
355           era       initiate_status     " only sync & initiate bits ON?
356           tnz       no_status           " no, don't try for another one.
357           stz       status              " zero out status
358           ldx7      =o100000,du         " reset timer
359           tra       status_wait         " and wait for good status
360 
361 no_status:
362           absa      ignore_status       " make sure no more status arrives
363           als       6
364           sta       mb|channel_mailbox.scw,x4
365 
366           lreg      save_regs
367           szn       esw
368           tnz       con.nargs,x2        " return
369           tra       con_t.nargs,x2
370 "^L
371 adp_connect:
372           eax0      con.dcw,x2*         " address of dcw list
373           lda       con.pcw,x2*         " get pcw
374           ora       =o020000,dl         " turn on proceed
375           sta       -1,x0               " insert in front of list
376 
377           absa      -1,x0               " get address of DCW list
378           als       8                   " in AU
379           sta       iox_mailbox_lpw     " store LPW
380 
381           lda       con.iom,x2*         " IOX tag (1-4)
382           ada       -1,dl
383           als       7                   " 128 channels / iox
384           ada       con.channel,x2*     " channel number
385           ada       8,dl                " iox channel index
386           ora       =o700000,du         " form cioc word
387 
388           stz       iox_mailbox_status  " zero status
389           cioc      iox_mailbox         " fire up the IOM
390 
391           lda       con.pcw,x2*         " look at the PCW
392           cana      =o040000,dl         " was it a mask?
393           tnz       adp_no_status       " yes, no status
394 
395           ldx7      =o100000,du         " timer
396 adp_status_wait:
397           ldaq      iox_mailbox_status  " status yet?
398           tmi       adp_got_status
399           adlx7     -1,du               " count down to timeout
400           tnz       adp_status_wait
401           szn       esw                 " timer running?
402           tnz       adp_status_wait
403 
404           stc1      esw                 " pretend we are not $timeout
405 
406 adp_got_status:
407           staq      save_regs+4         " save the status
408 
409 adp_no_status:
410           lreg      save_regs
411           szn       esw
412           tnz       con.nargs,x2        " return
413           tra       con_t.nargs,x2
414 
415           mod       8
416 iox_mailbox:
417           vfd       36o/0               " base addresses for 256k blocks
418           vfd       36o/1000000
419           vfd       36o/2000000
420           vfd       36o/3000000
421           vfd       18o/777777,18o/777777
422           vfd       18o/777777,18o/777777
423           vfd       24/0,12o/5034
424 iox_mailbox_lpw:
425           vfd       36/0                " lpw
426 iox_mailbox_status:
427           bss       ,16                 " status
428 
429           even
430 status_time:
431           bss       ,2
432 wait_time:
433           bss       ,2
434 fifteen_millisec:
435           dec       15000
436 one_millisec:
437           dec       1000
438 doing_console_io:
439           bss       ,1
440 initiate_status:
441           oct       400002000000        " sync and initiate bits
442 " ^L
443           include   bootload_equs
444           include   system_types
445 
446 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
447 "                                                                     "
448 "         Error message documentation.                                "
449 "                                                                     "
450 "                                                                     "
451 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
452 
453 "BEGIN MESSAGE DOCUMENTATION
454 
455 
456 "         Message:
457 "         HALT with octal 777777000001 in the A register.
458 
459 "         S:    $crash
460 
461 "         T:    $init
462 
463 "         M:    The interrupt base set on the bootload IOM is not 1200 octal.
464 
465 "         A:    Set the switches correctly.
466 
467 
468 "         Message:
469 "         HALT with octal 777777000002 in the A register.
470 
471 "         S:   $crash
472 
473 "         T:   $init
474 
475 "         M:   The iom base set on the bootload IOM is not correct. I.e.,
476 "         for IOM's 0, 1, 2 and 3 it should be 1400, 2000, 2400 and 3000 octal
477 "         respectively.
478 
479 "         A:   Set the switches correctly.
480 
481 "         END MESSAGE DOCUMENTATION
482 
483           end       bootload_io