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) change85-09-09Farley, approve85-09-09MCR6979,
11 " audit86-03-05GDixon, install86-03-21MR12.0-1033:
12 " Support IMU.
13 " 2) change86-05-13GJohnson, approve86-05-13MCR7387,
14 " audit86-05-13Martinson, install86-05-14MR12.0-1056:
15 " Correct error message documentation.
16 " 3) change87-10-02Farley, approve88-02-26MCR7794,
17 " audit88-03-04Fawcett, install88-03-15MR12.2-1035:
18 " Added code to set the new flag bootload_info$imu_style_iom.
19 " 4) change88-02-12Farley, approve88-03-18MCR7859,
20 " audit88-04-11Fawcett, install88-04-19MR12.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,fill0 " 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 ,prrl,fill0 " 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