" Begin include file ...... bos_iom_manager.incl.alm " This is the IOM manager for BOS. " Written in August 1971 by R F Mabee. " Modified 9/12/75 by N. I. Morris for 2 IOM operation. " Modified 8/25/76 by Noel I. Morris " Last modified by Sherman D. Sprague 02/11/81 " Modified November 1981 by C. Hornig to remove iom_connect_rel. " Modified September 1983 by Sherman D. Sprague to fix overhead channel bug. " This routine must be called first to initialize things. " Calling sequence: tsx2 init_io init_io: stx2 iiox2 save X2 rscr 1*8 read CFG arl 16-6 get processor port number ana =o700,dl mask sta bootload_cpu_port and save for later absa 0 absolute address of segment base als 6 adjust for 18 bit address sta abs_base_addr save for future use stba LPWX,40 set base for relative I/O ldq ds|pgm*2+1 get SDW for this segment qrl 3+5 shift and divide by 32 adq 1,du round to nearest 512 stbq LPWX,20 set bound for relative I/O lrl 36 place address in QU adq stop_lpw relocate stopper LPW absa mem|iom_status+ioms*chans*2 get abs addr of status area als 6 get low order address bits ldx7 com|iom_mbbase mailbox addr in X7 eax7 ioms*chans*4-4,7 prepare to set up channel mailboxes initmbx: sba 2,du decrement address of SCW sta mem|iombx.scw,7 set SCW stq mem|iombx.lpw,7 and LPW stz mem|iombx.lpwx,7 clear LPWX stz mem|iombx.dcw,7 and DCW sbx7 4,du step to next channel cmpx7 com|iom_mbbase are we finished? tpnz initmbx .. mlr (),(pr),fill(0) clear the status area desc9a *,0 desc9a mem|iom_status,ioms*chans*2*4 lda com|iom_mxbase get address of IMW area arl 18-2 as character offset mlr (),(pr,al),fill(0) clear IMW area desc9a *,0 desc9a mem|0,128*4 lda fault_lpw set up system fault channel eax6 fault_channel*4 .. tsx7 set_overhead_channel .. lda fault_lpw+1 set up for second IOM eax6 fault_channel*4+chans*4 .. tsx7 set_overhead_channel .. lda special_lpw set up special status channel eax6 special_channel*4 .. tsx7 set_overhead_channel .. lda special_lpw+1 set up for second IOM eax6 special_channel*4+chans*4 .. tsx7 set_overhead_channel .. stc1 dcw_reloc_flag remember relocation was done. stz special_handler reset special handler stz status_handler reset status handler lda =aiom " look for IOM config cards tsx2 getconf .. tra iiox2 exit if no card lxl6 com|2,7 get port number ldq com|1,7 get IOM tag cmpq ioms,dl see if too big tpnz getmore if too big, ignore sbq 1,dl minus 1 tze getmore in case Martinson has wrong IOM card qls 18+6+2 multiply by size of mailbox adlq com|iom_mbbase relocate to mailbox base sxl6 mem|iom_cow,qu set COW in correct mailbox tra getmore look for additional IOMs iiox2: eax2 * restore X2 tra 0,2 set_overhead_channel: eax6 com|iom_mbbase,*6 get address of channel mailbox ldq 0,au Get DCW for overhead channel. szn dcw_reloc_flag only relocate once. tnz set_overhead_dcw if already relocated. adlq com|iom_mxbase Relocate to IMW area. stq 0,au Replace DCW. set_overhead_dcw: stq mem|iombx.dcw,6 Set DCW in mailbox. adla abs_base_addr Relocate LPW address. sta mem|iombx.lpw,6 Set overhead channel LPW. tra 0,7 Return to caller. " This routine issues a connect to the IOM using the caller's PCW and DCW list. " Calling sequence: tsx2 connect_iom " zero PCW_address,DCW_list_address connect_iom: stz LPW clear all bits in LPW. connect_join: lda 0,2 get argument pointers ldq 1,au get channel # from PCW word B qrl 9-2 shift and multiply by 4 eax7 com|iom_mbbase,*qu channel mailbox address in X7 absa 0,al get DCW list address als 6 in AU ora LPW insert LPW bits sta mem|iombx.lpw,7 and store completed LPW lda LPWX set LPWX in case of relative connect sta mem|iombx.lpwx,7 for LPW extension qrl 1 2 * channel # in QU stz mem|iom_status,qu clear the status for this channel stz mem|iom_status+1,qu .. lda 0,2 get argument pointers absa 0,au get absolute address of PCW als 6 in AU ora =o020001,dl insert LPW bits anx7 -chans*4,du get address of correct mailbox sta mem|iombx.lpw+connect_channel*4,7 set connect channel LPW reconnect: eax6 50000 wait a while for connect to take cioc mem|iom_cow,7 ZAP cmpa mem|iombx.lpw+connect_channel*4,7 has connect channel LPW changed? tnz 1,2 if so, the connect has taken. Return. sbx6 1,du wait for a while tpl *-3 .. tra reconnect then try connect again " This entry point issues a connect to a DCW list which has not been relocated. " It sets the REL bit in the LPW and sets the offset and bound of the LPW ext. " to reference segment "pgm". " connect_iom_rel: " lda =o010000,dl get REL bit " sta LPW store into LPW template " tra connect_join now join common code " " This routine picks up the status word for a particular channel " and checks for abnormal status. " Calling sequence: tsx2 check_status " arg channel_info_address " zero 0 " No status stored yet. " tra error " Abnormal status. " - - - " Normal return. check_status_no_stat: "Special feature for DIA stc1 checkstat_nostat_sw tra check_status_1 check_status: stz checkstat_nostat_sw check_status_1: eax5 3*4 Get interrupt cell number. eax6 TIMW Get address for IMW's. tsx7 get_imws Pick up IMW's. test_status: lda 0,2* Channel number in AU. tsx7 test_imw Has terminate occurred on this channel? descb TIMW,1 tra none_waiting If not, skip following code. als 1 Channel * 2 in AU. eax7 0,au ldaq mem|iom_status,7 Current status word for the channel. tnz checkstat_status_waits szn checkstat_nostat_sw Magic return? tze none_waiting No, there's no status checkstat_status_waits: stz mem|iom_status,7 Clear word. stz mem|iom_status+1,7 cana status_mask Check for abnormal status. tze 3,2 Normal return. tra 2,2 Error return. none_waiting: " Do some other work while waiting for channel. szn status_lock Check before using static storage. tnz nostatus No status - callout lock set. Take no status action. stc1 status_lock Lock it to me before using stat_x0. stx0 stat_x0 stx2 stat_x2 szn status_handler If no status handler, tze no_stat_call Do not check for call. tsx2 test_status Test for status. arg status_handler tra no_stat_call If none, skip call. tra *+1 lxl7 status_handler Handler address in X7. tsx2 0,7 Perform call. no_stat_call: eax5 7*4 Interrupt level in X5. eax6 SIMW Place to store special IMW's. tsx2 overhead_queue_search Check for special status. zero special_channel arg process_special_status lda special_handler If no special handler, tze no_spec_int Do not check for call. tsx7 test_imw Test for special status. descb SIMW,1 .. tra no_spec_int If none, skip call. tsx2 0,al Perform call. tra no_spec_int And continue. process_special_status: arl 9 Shift the channel #. ana =o77,du Mask it. ora iomno Insert IOM #. csl (),(au),bool(17) Set IMW bit for channel. descb *,0 descb SIMW,1 tra 0,7 Return to caller. no_spec_int: eax5 1*4 Interrupt level in X5. eax6 FIMW Place to store system fault IMW's. tsx2 overhead_queue_search Check for system fault status. zero fault_channel arg process_system_fault tra stat_x0 All finished with status checking. process_system_fault: eaq 0,au Channel # in QU. orq iomno Insert IOM #. qls 1 Multiply by 2. ana =o777777,dl Mask info in AL. ora =o770074,du Manufacture status with "abort" bit set. sta mem|iom_status,qu Set status in status area. csl (),(id,qu),bool(17) Set terminate IMW bit for channel. descb *,0 descb TIMW,1 tra 0,7 Return to caller. stat_x0: eax0 * stat_x2: eax2 * stz status_lock nostatus: tsx7 iowait Wait for I/O to complete. tra check_status_1 Then, check for status again. iowait: szn 1,2 Action to take on no status? tnz 1,2 If so, take it. lxl6 bootload_cpu_port Get CPU port * 64. lda =o777776,du Open mask for all interrupts. ldq =o777776,du .. inhibit on <+><+><+><+><+><+><+><+><+><+><+><+> sscr 2*8,6 .. lda 0,2* Display channel number. inhibit off <-><-><-><-><-><-><-><-><-><-><-><-> dis 0 Wait for interrupt. inhibit on <+><+><+><+><+><+><+><+><+><+><+><+> fld 0,dl Close mask again. sscr 2*8,6 .. inhibit off <-><-><-><-><-><-><-><-><-><-><-><-> tra 0,7 Return to caller. get_imws: adlx5 com|iom_mxbase Relocate IMW address. ldqc mem|0,5 Get first IMW. lls 36-4 Take first 32 bits. ldqc mem|-4,5 Get second IMW. lls 4 Insert 4 more bits. orsa 0,6 Store first word. lls 36-8 Get 28 more bits. ldqc mem|1,5 Get third IMW. lls 8 Insert 8 bits. orsa 1,6 Store second word. lls 36-12 Get 24 more bits. ldqc mem|-4+1,5 Get last IMW. lls 12 Insert 12 bits. orsa 2,6 Store third word. orsq 3,6 And fourth word. tra 0,7 Return to caller. test_imw: sztl (),(id,au),bool(05) Has interrupt occurred on this channel? descb *,0 arg 0,7 tze 1,7 If not, take failure return. csl (),(id,au),bool(00) Turn off IMW bit. descb *,0 arg 0,7 tra 2,7 Take success return. overhead_queue_search: stx6 oqsdesc Set descriptor to IMW. tsx7 get_imws Pick up IMW's. stz iomno Zero IOM # to start. lda 0,dl Clear the A. overhead_loop: ada 0,2 Add in the channel #. tsx7 test_imw See if interrupt present. oqsdesc: descb *,1 tra noovh If not, skip following. als 2 Multiply channel # by 4. eaa com|iom_mbbase,*au Get address of appropriate mailbox. ldx5 mem|iombx.lpw,au Get address of DCW from LPW. ldx5 mem|0,5 Get address of queue from DCW. ldx0 *+1 Set up X0 for RPT. oqsrpt: rptx overhead_qlth,1,tnz Search through queue. ldac mem|0,5 .. ttn noovh If empty, try other IOM. tsx7 1,2* Process queue entry. canx0 =o776000,du Did RPT tally run out? tnz oqsrpt If not, continue the search. noovh: lda chans,du Bump IOM #. ada iomno .. sta iomno .. cmpa ioms*chans,du All finished? tmi overhead_loop If not, loop. tra 2,2 Return to caller. " This routine checks for a special interrupt on a particular channel. " Calling sequence: tsx2 check_special_status " arg channel_info_address " tra no_special " - - - " Normal return. check_special_status: stx2 cksp_x2 Save X2. eax5 7*4 Pick up IMW's for level 7. eax6 SIMW And place in SIMW. tsx2 overhead_queue_search zero special_channel arg process_special_status cksp_x2: eax2 * Restore X2. test_special: lda 0,2* Channel # in AU. tsx7 test_imw Test IMW bit for this channel. descb SIMW,1 tra *+2 If off, return no special. tra 2,2 Normal return. tsx7 iowait Wait for interrupt. tra check_special_status " This routine establishes a handler for special interrupts for a particular channel. " Calling sequence: tsx2 get_special_interrupt " zero channel_info_address,handler_address get_special_interrupt: eax7 special_handler Set special handler address. tra get_interrupt_common Join common code. " This routine sets up a handler for all status from a particular channel. " Calling sequence: tsx2 get_status_interrupt " zero channel_info,handler_address get_status_interrupt: eax7 status_handler Set status handler address. get_interrupt_common: lda 0,2 Channel info addr, handler addr in A. ldq 0,au Channel # in QU. lls 18 Handler address, channel # in A. alr 18 Swap them. sta 0,7 Set handler entry. tra 1,2 " This routine makes the PCW and DCW list for a single record or non-data operation. " Control does not return to the user until the operation has terminated. " Calling sequence: tsx2 xio_wait " vfd 18/buffer,12/tally,6/character_position " zero channel_info_address,device_opcode " tra error " Error return. " - - - " Normal return. " " Modified for Compatibility between Common Peripheral Channel " Peripheral Subsystem Interface Adapter - 10/29/72 by N. I. Morris xio_wait: stx2 io_x2 save X2 lda 0,2 pick up buffer address tze non_data_transfer if zero, non-data transfer eaq 0,al tally in QU. cana =o700000,du look at pointer reg. bits tnz *+2 if non-zero, already set ora pgm*32768,du otherwise, set to this program stca *+1,70 store into absa instruction absa 0|0 ****** THIS INSTRUCTION GETS MODIFIED ****** alr 6 shift address stca DCW,70 place address in DCW als 18 shift the address extension stca IDCW,10 and place in IDCW qlr 12 shift the tally to correct place stcq DCW,03 and store the tally in DCW qlr 6 get the character position qls 15 shift the character position stcq DCW,04 and store char. pos. in DCW lda 0,dl pick up low-order IDCW bits tra set_idcw non_data_transfer: lda stop_dcw pick up DCW to stop channel sta DCW in case things get out of hand lda =o0201,dl pick up low-order IDCW bits for NDT set_idcw: stca IDCW,03 set IDCW control bits lda 1,2 pick up second argument stca channel_ptr,70 save it ldq 0,au pick up channel info. qls 9 shift channel # to PCW position stbq PCW+1,40 and place channel # in PCW qls 3 now shift the device code stcq PCW,20 and store in PCW stcq IDCW,20 place in IDCW also, for PSIA operation als 30 shift the op-code stca IDCW,40 and place op-code in IDCW tsx2 connect_iom start up the channel zero PCW,IDCW tsx2 check_status wait for status to come back channel_ptr: zero zero tra abnormal_return io_x2: eax2 * tra 3,2 abnormal_return: ldx2 io_x2 tra 2,2 equ ioms,2 equ chans,64 " Addresses relative to mailbox. bool iom_cow,1 Address of COW. " Addresses relative to IMW area. bool system_fault_queue,100 Address of system fault status queue. bool special_status_queue,110 Address of special status queue. " Absolute addresses. bool iom_status,200 Address of place to store status. " IOM Mailbox Equivalences. equ iombx.lpw,0 equ iombx.lpwx,1 equ iombx.scw,2 equ iombx.dcw,3 " Overhead Channel Equivalences. equ fault_channel,1 equ connect_channel,2 equ special_channel,6 equ overhead_qlth,4 even PCW: vfd o6/40,6/0,6/0,3/7,3/2,6/2,6/1,9/0,27/0 IDCW: vfd 6/0,6/0,6/0,3/7,3/0,6/0,6/0 DCW: oct 0 stop_dcw: vfd 18/0,3/7,3/0,6/2,6/1 Terminate IDCW. stop_lpw: vfd 18/stop_dcw,o6/04,12/0 LPW with tally update suppressed. LPW: bss ,1 LPWX: bss ,1 FIMW: bss ,4 System fault IMW. TIMW: bss ,4 Terminate IMW. SIMW: bss ,4 Special interrupt IMW. iomno: bss ,1 IOM # abs_base_addr: oct 0 bootload_cpu_port: oct 0 status_lock: oct 0 status_mask: oct 370000770000 Ignore normally on bits. dcw_reloc_flag: oct 0 non-zero if overhead dcw's relocated. fault_lpw: vfd 18/fault_dcw,o6/04,12/0 NC LPW - no tally update. vfd 18/fault_dcw+1,o6/04,12/0 NC LPW - no tally update. fault_dcw: vfd 18/system_fault_queue,3/0,3/1,12/overhead_qlth IOTP DCW. vfd 18/system_fault_queue+overhead_qlth,3/0,3/1,12/overhead_qlth IOTP DCW. special_lpw: vfd 18/special_dcw,o6/4,12/0 vfd 18/special_dcw+1,o6/4,12/0 special_dcw: vfd 18/special_status_queue,3/0,3/1,12/overhead_qlth-2 vfd 18/special_status_queue+overhead_qlth,3/0,3/1,12/overhead_qlth-2 status_handler: bss ,1 special_handler: bss ,1 checkstat_nostat_sw: bss ,1 " End of include file ...... bos_iom_manager.incl.alm " " " ----------------------------------------------------------- " " " " Historical Background " " This edition of the Multics software materials and documentation is provided and donated " to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. " as a contribution to computer science knowledge. " This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, " Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull " and Bull HN Information Systems Inc. to the development of this operating system. " Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), " renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership " of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for " managing computer hardware properly and for executing programs. Many subsequent operating systems " incorporated Multics principles. " Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., " as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . " " ----------------------------------------------------------- " " Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without " fee is hereby granted,provided that the below copyright notice and historical background appear in all copies " and that both the copyright notice and historical background and this permission notice appear in supporting " documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining " to distribution of the programs without specific prior written permission. " Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. " Copyright 2006 by Bull HN Information Systems Inc. " Copyright 2006 by Bull SAS " All Rights Reserved " "