COMPILATION LISTING OF SEGMENT tdcm_ Compiled by: Multics PL/I Compiler, Release 27d, of October 11, 1982 Compiled at: Honeywell LISD Phoenix, System M Compiled on: 11/30/82 1337.4 mst Tue Options: optimize map 1 /* *********************************************************** 2* * * 3* * Copyright, (C) Honeywell Information Systems Inc., 1982 * 4* * * 5* * Copyright (c) 1972 by Massachusetts Institute of * 6* * Technology and Honeywell Information Systems, Inc. * 7* * * 8* *********************************************************** */ 9 10 11 /* format: style4,delnl,insnl,indattr,ifthen,dclind9 */ 12 tdcm_: 13 procedure; 14 15 /* This is the non-ring 0 version of the tape DCM. 16* * Recoded from ring 0 version by Bill Silver on 09/30/74. 17* * Modified for preloaded volumes by Michael R. Jordan on 04/28/78. 18* * Modified 7/79 by R.J.C. Kissel to user version 1 tseg. 19* * Modified 03/82 by Chris Jones for version 2 tseg. 20* * Modified 3/82 by J. A. Bush for Marker interrupt processing 21* * Modified 7/13/82 by J. A. Bush to fix some interrupt processing bugs 22* * 23* * This version of this program is part of the initial "dummy" 24* * installation of RCP. 25* * 26* * tdcm_ interfaces with RCP in order to perform device management 27* * functions. It interfaces with IOI in order to perform the 28* * actual tape I/O. Notes about this procedure: 29* * 1. In general all entry points function in the same way. 30* * 2. The caller of tdcm_ must be aware that the first tseg buffer 31* * and tseg.drive_number are not valid between the call to 32* * tdcm_$tdcm_attach and the first call to tdcm_$tdcm_message. 33* * 3. tdcm_$tdcm_message must be called after the call to tdcm_attach or 34* * after a call to tdcm_$tdcm_detach in which the drive assignment has 35* * been retained. Subsequent calls to tdcm_$tdcm_message will temporarily 36* * still type a mount message on the operator's console. 37* * 4. I/O modules no longer need to check that the tape drive is ready or 38* * that the volume is at BOT or that the write ring is set correctly. 39* * RCP does all of this checking. 40* * 5. tdcm_$tdcm_priv_attach is no longer supported. RCP checks to see 41* * if a process is privileged. 42* * 6. tdcm_$tdcm_mount_bit_set and tdcm_$tdcm_mount_bit_get are no 43* * longer supported. 44* * 7. A new entry point, tdcm_set_disposition, is available. 45* * It allows the user to specify a disposition value to be given 46* * to RCP when the tape drive is detached. 47* * 8. Two new entry points are now available: tdcm_set_buf_size and 48* * tdcm_get_buf_size; They allow the caller to adjust the size of 49* * the tdcm_ I/O buffer. 50**/ 51 52 /* ARGUMENT DATA */ 53 54 dcl arg_buf_size fixed bin; /* (I/O) Size of tdcm_ I/O buffer. */ 55 dcl arg_call_data_ptr ptr; /* (I) Pointer to event call data structure. */ 56 dcl arg_disposition bit (*); /* (I) Disposition value given to RCP. */ 57 dcl arg_ecode fixed bin (35); /* (O) Standard error_table_ code. */ 58 dcl arg_reel_name char (*); /* (I) Tape reel ID name plus qualifiers. */ 59 dcl arg_tsegp ptr; /* (I) Pointer to user's tseg. */ 60 dcl arg_val_level fixed bin; /* (I) Validation level to be set. */ 61 dcl arg_write_sw fixed bin (1); /* (I) 1 => write, 0 => read. */ 62 63 64 /* AUTOMATIC DATA */ 65 66 dcl 1 event_data like call_data; /* Not really used. */ 67 68 dcl call_data_ptr ptr; /* Pointer to event call data structure. */ 69 dcl wbuf_ptr ptr; /* Pointer to buffer in IOIworkspace. */ 70 71 dcl buf_size fixed bin; /* Used to copy buffer size argument. */ 72 dcl data_size fixed bin; /* Number of words to be moved by based_data. */ 73 dcl dcw_tally fixed bin (18); /* Number of words to be move by single DCW. */ 74 dcl ecode fixed bin (35); /* Temporary error code. */ 75 dcl fix fixed bin; /* Used to correct read count. */ 76 dcl tmr bit (1) aligned; 77 dcl ck_level fixed bin (3); /* interrupt level returned by CK_STATQ */ 78 dcl (i, sqx) fixed bin; 79 dcl listx fixed bin; /* Index to last IDCW that was executed. */ 80 dcl new_val_level fixed bin; /* Used to copy validation level argument. */ 81 dcl op_count fixed bin; /* Number of commands or buffers in I/O. */ 82 dcl (tbuf_num, wbuf_num) fixed bin; /* Number of tseg buffer. */ 83 dcl tot_data_size fixed bin; /* Tot num of words written with 1 connect. */ 84 dcl special_flag bit (1) aligned; /* ON => we have special status. */ 85 dcl special_status_word bit (36) aligned; /* Status word for special interrupts. */ 86 dcl data_idcw bit (36) aligned; /* to copy current data xfer idcw into */ 87 dcl (io_time, delta) fixed bin (71); 88 dcl (pfs, pf_code) fixed bin (35); 89 90 /* BASED DATA */ 91 92 dcl based_data (data_size) fixed bin (35) aligned based; 93 /* Used to move data. */ 94 95 dcl based_idcw bit (36) aligned based (idcwp); 96 97 dcl 1 call_data based (call_data_ptr) aligned, 98 /* Data structure for event calls. */ 99 2 channel_id fixed bin (71), 100 2 message fixed bin (71), 101 2 sender bit (36), 102 2 orgin, 103 ( 3 dev_signal bit (18), 104 3 ring bit (18) 105 ) unaligned, 106 2 data_ptr ptr; /* Points to IOIworkspace. */ 107 108 109 /* EXTERNAL ENTRIES CALLED */ 110 111 dcl (addr, addrel, baseptr, bin, bit, clock, divide, hbound, min, ptr, rel, string, substr) 112 builtin; 113 114 dcl ( 115 error_table_$bad_arg, 116 error_table_$buffer_big, 117 error_table_$invalid_state, 118 error_table_$out_of_main_memory, 119 error_table_$unimplemented_version, 120 error_table_$net_timeout, 121 error_table_$too_many_buffers 122 ) fixed bin (35) external; 123 124 dcl display_meters bit (1) aligned static options (constant) init ("0"b); 125 /* if meters are to be displayed at detach time, set to ("1"b) */ 126 127 dcl convert_ipc_code_ entry (fixed bin (35)); 128 dcl hcs_$wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35)); 129 dcl ioi_$connect entry (fixed bin, fixed bin, fixed bin (35)); 130 dcl ioi_$set_event entry (fixed bin, fixed bin (71), fixed bin (35)); 131 dcl ioi_$get_special_status 132 entry (fixed bin, bit (1) aligned, bit (36) aligned, fixed bin (35)); 133 dcl ipc_$drain_chn entry (fixed bin (71), fixed bin (35)); 134 dcl ipc_$block entry (ptr, ptr, fixed bin (35)); 135 dcl rcp_$promote entry (bit (36) aligned, fixed bin, fixed bin (35)); 136 dcl tdcm_$tdcm_reset_signal 137 entry (ptr, fixed bin (35)); 138 dcl tdcm_attach_ entry (ptr, fixed bin (35)); 139 dcl tdcm_detach_ entry (ptr, fixed bin (35)); 140 dcl tdcm_message_ entry (ptr, ptr, char (*), fixed bin (1), fixed bin (35)); 141 dcl mhcs_$get_seg_usage_ptr 142 entry (ptr, fixed bin (35), fixed bin (35)); 143 dcl ioa_ entry options (variable); 144 1 1 /* Include segment tseg.incl.pl1 --- declaration for Tape DSM-DCM Interface Segment */ 1 2 /* Modified 10 July 1973 by MJ Grady */ 1 3 /* Modified 7/79 by R.J.C. Kissel to add a version number, tracks, density, and drive_name, and get rid of drive_number. */ 1 4 /* Modified 5 August 1981 by Chris Jones to add speed specification */ 1 5 1 6 /* NB: tape_ansi_cseg.incl.pl1 has a parallel version of this tseg declared in it. Any changes made here MUST 1 7* be made there too. */ 1 8 1 9 /* format: style4,delnl,insnl,indattr,ifthen,dclind9 */ 1 10 dcl ( 1 11 nbuffs init (12), /* # of buffers in structure */ 1 12 max_rec_size init (2080) 1 13 ) fixed bin (17) int static; /* Max # of words that may be transmitted (2 * 1040) */ 1 14 1 15 dcl tsegp ptr; /* Used to access Ring-0/Ring-4 shared structure */ 1 16 dcl tseg_version_2 fixed bin internal static options (constant) init (2); 1 17 1 18 declare 1 tseg based (tsegp) aligned, 1 19 2 version_num fixed bin, 1 20 2 areap ptr, /* pointer to DSM area */ 1 21 2 ev_chan fixed bin (71), /* event channel number */ 1 22 2 write_sw fixed bin (1), /* 0 = read, 1 = write */ 1 23 2 sync fixed bin (1), /* non-zero for synchronous i/o */ 1 24 2 get_size fixed bin (1), /* ON for record sizes to be returned */ 1 25 2 ws_segno bit (18), /* segment number of IOI workspace */ 1 26 2 drive_name char (32), /* physical drive name. */ 1 27 2 tracks fixed bin, /* 0 = 9-track, 1 = 7-track. */ 1 28 2 density bit (36), /* bits are 200, 556, 800 1600, 6250 respectively. */ 1 29 2 speed bit (36), /* bits are 75, 125, 200 ips respectively */ 1 30 2 pad99 bit (36), /* so that buffers start on an evenword boundary */ 1 31 2 buffer_offset fixed bin (12), /* offset (from 1) of first buffer to be processed */ 1 32 2 buffer_count fixed bin (12), /* number of buffers to be processed */ 1 33 2 completion_status fixed bin (2), /* 0 = no pending i/o or no status */ 1 34 /* 1 = normal termination of i/o */ 1 35 /* 2 = non-zero major status from previous i/o */ 1 36 2 hardware_status bit (36) aligned, /* major and sub-status */ 1 37 2 error_buffer fixed bin (12), /* buffer in which i/o error occurred */ 1 38 2 command_count fixed bin (12), /* number of non-data commands to execute */ 1 39 2 command_queue (10) fixed bin (6) aligned, /* non-data-transfer commands */ 1 40 2 bufferptr (12) fixed bin (18) aligned,/* relative ptrs to buffers */ 1 41 2 buffer_size (12) fixed bin (18) aligned,/* size of buffer */ 1 42 2 mode (12) fixed bin (2) aligned, /* 0 = bin, 1 = bcd, 2 = 9 track */ 1 43 2 buffer (12) bit (37440) aligned, /* data buffers - 1040 words */ 1 44 2 dsm_area area ((100 /* strictly nominal */)); 1 45 /* DSM workspace */ 1 46 1 47 /* End include segment tseg.incl.pl1 */ 145 146 2 1 /* Begin include file ... tdcm_info.incl.pl1 2 2* * 2 3* * Created on 02/20/75 by Bill Silver. 2 4* * Modified 5/20/77 by Noel I. Morris for DCC. 2 5* * Modified 3/19/82 by J. A. Bush for Marker interrupt processing 2 6* * This include file defines the IOI workspace used by tdcm_. 2 7**/ 2 8 dcl ws_ptr ptr; /* Pointer to base of tdcm_ IOI workspace. */ 2 9 2 10 dcl 1 ws based (ws_ptr) aligned, /* Starts at base of ioi_ workspace. */ 2 11 2 info like ws_info, /* See ws_info structure below. */ 2 12 2 ndt_list (10), /* List of non-data transfer IDCWs. */ 2 13 3 idcw bit (36), /* IDCWs. */ 2 14 2 rw_list (12), /* DCW list for reads and writes. */ 2 15 3 idcw bit (36), /* IDCW. */ 2 16 3 dcw bit (36), /* DCW. */ 2 17 2 mark_tdcw bit (36), /* TDCW to chain the DCW list when processing Markers */ 2 18 2 statq (4) like istat, /* A queue of IOI status entries. */ 2 19 2 pad_ev ptr, /* to force buffer to even location */ 2 20 2 buffer (0 refer (ws.info.buf_size)) bit (36) aligned, 2 21 2 buf_end bit (36); /* Marks end of data buffer. */ 2 22 2 23 dcl 1 ws_info based aligned, /* Control information. */ 2 24 2 flags, /* All flags in one word. */ 2 25 (3 attached bit (1), /* ON => tape drive has been attached. */ 2 26 3 connected bit (1), /* ON => there is a connect in progress. */ 2 27 3 get_size bit (1), /* ON => return actual read count. */ 2 28 3 ndtrans bit (1), /* ON => non-data transfer type connect. */ 2 29 3 reading bit (1), /* ON => connect issued for reading. */ 2 30 3 large_rec bit (1), /* ON => transmitting record longer than 4096 words */ 2 31 3 allow_marker bit (1), /* ON => Set up DCW list for marker interrupt processing */ 2 32 3 good_ws bit (1)) unaligned, /* ON => can get a workspace big enough to satisfy user. */ 2 33 2 buf_size fixed bin, /* Current size of tdcm_ I/O buffer. */ 2 34 2 rcp_id bit (36) aligned, /* ID used to communicate with rcp_. */ 2 35 2 ioix fixed bin, /* Index used to communicate with ioi_. */ 2 36 2 statqx fixed bin, /* Index of current status queue entry. */ 2 37 2 process_id bit (36) aligned, /* User's process ID. */ 2 38 2 tracks fixed bin, /* Temporary place to save track type. */ 2 39 2 wait_list, /* Used to block. */ 2 40 3 num_ev_chans fixed bin, /* Number of channels in list. */ 2 41 3 wait_echan fixed bin (71), /* Used to wait when blocked. */ 2 42 2 fast_echan fixed bin (71), /* Fast event channel used to wait. */ 2 43 2 special_echan fixed bin (71), /* Event call channel for special interrupts. */ 2 44 2 user_echan fixed bin (71), /* Event channel set up by user in tseg. */ 2 45 2 init_echan fixed bin (71), /* Event channel to use after drive attached. */ 2 46 2 meters, /* temporary meters */ 2 47 3 last_io_time fixed bin (71), /* clock time of last data xfer I/O */ 2 48 3 io_delta fixed bin (71), /* total delta times */ 2 49 3 low_delta fixed bin (71), /* lowest time between data xfer i/os */ 2 50 3 high_delta fixed bin (71), /* longest time between data xfer i/os */ 2 51 3 number_ios fixed bin (35), /* number of data xfer i/os */ 2 52 3 block fixed bin (35), /* # of times we went blocked awaiting I/O to complete */ 2 53 3 no_block fixed bin (35), /* # of times status queue precessed w/o going blocked */ 2 54 3 mark_st fixed bin (35), /* # of marker interrupts received */ 2 55 3 term_st fixed bin (35), /* # of term interrupts received */ 2 56 3 term_ne fixed bin (35), /* # of term interrupts received with no error status */ 2 57 3 most_consec_mark fixed bin (35), /* longest burst of marker interrupts processed */ 2 58 3 consec_mark fixed bin (35), /* counter for keeping track of consecutive markers */ 2 59 3 block_count fixed bin, /* highest number of blocks per I/O call */ 2 60 2 subset_size fixed bin, /* max block size of data xfer I/O */ 2 61 2 detachx fixed bin, /* Index that tells what has been set up. */ 2 62 2 disposition bit (1), /* RCP assignment disposition. */ 2 63 2 read_start fixed bin, /* First tseg buffer we are reading into. */ 2 64 2 buffer_size (12) fixed bin, /* Data size in each workspace buffer. */ 2 65 2 ndt_offsetx fixed bin, /* Offset of non-data transfer DCW list. */ 2 66 2 rw_offsetx fixed bin, /* Offset of read/write DCW list. */ 2 67 2 mark_offset fixed bin, /* buffer offset of last marker interrupt */ 2 68 2 error_count fixed bin, /* Count of errors during attachment. */ 2 69 2 read_idcws (0:5) bit (36) aligned, /* An array of read and write IDCW's. */ 2 70 2 write_idcws (0:5) bit (36) aligned; /* One for each possible buffer in 1 connect. */ 2 71 2 72 /* End of include file ... tdcm_info.incl.pl1 */ 147 148 3 1 3 2 /* Begin include file ...... ioi_stat.incl.pl1 */ 3 3 /* Last modified 3/24/75 by Noel I. Morris */ 3 4 3 5 dcl isp ptr; /* pointer to status structure */ 3 6 3 7 dcl 1 istat based (isp) aligned, /* I/O Interfacer status structure */ 3 8 2 completion, /* completion flags */ 3 9 (3 st bit (1), /* "1"b if status returned */ 3 10 3 er bit (1), /* "1"b if status indicates error condition */ 3 11 3 run bit (1), /* "1"b if channel still running */ 3 12 3 time_out bit (1)) unal, /* "1"b if time-out occurred */ 3 13 2 level fixed bin (3), /* IOM interrupt level */ 3 14 2 offset fixed bin (18), /* DCW list offset */ 3 15 2 absaddr fixed bin (24), /* absolute address of workspace */ 3 16 2 iom_stat bit (72), /* IOM status */ 3 17 2 lpw bit (72); /* LPW residue */ 3 18 3 19 dcl imp ptr; /* pointer to message structure */ 3 20 3 21 dcl 1 imess based (imp) aligned, /* I/O Interfacer event message structure */ 3 22 (2 completion like istat.completion, /* completion flags */ 3 23 2 pad bit (11), 3 24 2 level bit (3), /* interrupt level */ 3 25 2 offset bit (18), /* DCW list offset */ 3 26 2 status bit (36)) unal; /* first 36 bits of status */ 3 27 3 28 /* End of include file ...... ioi_stat.incl.pl1 */ 3 29 149 150 4 1 4 2 /* Begin include file ...... iom_stat.incl.pl1 */ 4 3 /* Last modified on 10/31/74 by Noel I. Morris */ 4 4 4 5 dcl statp ptr; /* pointer to status */ 4 6 4 7 dcl 1 status based (statp) aligned, /* IOM status information */ 4 8 (2 t bit (1), /* set to "1"b by IOM */ 4 9 2 power bit (1), /* non-zero if peripheral absent or power off */ 4 10 2 major bit (4), /* major status */ 4 11 2 sub bit (6), /* substatus */ 4 12 2 eo bit (1), /* even/odd bit */ 4 13 2 marker bit (1), /* non-zero if marker status */ 4 14 2 soft bit (2), /* software status */ 4 15 2 initiate bit (1), /* initiate bit */ 4 16 2 abort bit (1), /* software abort bit */ 4 17 2 channel_stat bit (3), /* IOM channel status */ 4 18 2 central_stat bit (3), /* IOM central status */ 4 19 2 mbz bit (6), 4 20 2 rcount bit (6), /* record count residue */ 4 21 2 address bit (18), /* DCW address residue */ 4 22 2 char_pos bit (3), /* character position residue */ 4 23 2 r bit (1), /* non-zero if reading */ 4 24 2 type bit (2), /* type of last DCW */ 4 25 2 tally bit (12)) unal; /* DCW tally residue */ 4 26 4 27 dcl 1 faultword based (statp) aligned, /* system fault word */ 4 28 (2 mbz1 bit (9), 4 29 2 channel bit (9), /* channel number */ 4 30 2 serv_req bit (5), /* service request */ 4 31 2 mbz2 bit (3), 4 32 2 controller_fault bit (4), /* system controller fault code */ 4 33 2 io_fault bit (6)) unal; /* I/O fault code */ 4 34 4 35 dcl 1 special_status based (statp) aligned, /* special status from PSIA */ 4 36 (2 t bit (1), /* entry present bit */ 4 37 2 channel bit (8), /* channel number */ 4 38 2 pad1 bit (3), 4 39 2 device bit (6), /* device address */ 4 40 2 pad2 bit (1), 4 41 2 byte2 bit (8), /* device dependent information */ 4 42 2 pad3 bit (1), 4 43 2 byte3 bit (8)) unal; /* device dependent information */ 4 44 4 45 /* End of include file iom_stat.incl.pl1 */ 4 46 151 152 5 1 5 2 /* Begin include file ...... iom_pcw.incl.pl1 */ 5 3 5 4 dcl pcwp ptr; /* pointer to PCW */ 5 5 5 6 dcl 1 pcw based (pcwp) aligned, /* Peripheral Control Word */ 5 7 (2 command bit (6), /* device command */ 5 8 2 device bit (6), /* device code */ 5 9 2 ext bit (6), /* address extension */ 5 10 2 code bit (3), /* should be "111"b for PCW */ 5 11 2 mask bit (1), /* channel mask bit */ 5 12 2 control bit (2), /* terminate/proceed and marker control bits */ 5 13 2 chan_cmd bit (6), /* type of I/O operation */ 5 14 2 count bit (6), /* record count or control character */ 5 15 2 mbz1 bit (3), 5 16 2 channel bit (6), /* channel number */ 5 17 2 mbz2 bit (27)) unal; 5 18 5 19 dcl idcwp ptr; /* pointer to IDCW */ 5 20 5 21 dcl 1 idcw based (idcwp) aligned, /* Instruction DCW */ 5 22 (2 command bit (6), /* device command */ 5 23 2 device bit (6), /* device code */ 5 24 2 ext bit (6), /* address extension */ 5 25 2 code bit (3), /* should be "111"b for PCW */ 5 26 2 ext_ctl bit (1), /* "1"b if address extension to be used */ 5 27 2 control bit (2), /* terminate/proceed and marker control bits */ 5 28 2 chan_cmd bit (6), /* type of I/O operation */ 5 29 2 count bit (6)) unal; /* record count or control character */ 5 30 5 31 /* End include file ...... iom_pcw.incl.pl1 */ 5 32 153 6 1 6 2 /* Begin include file ...... iom_dcw.incl.pl1 */ 6 3 6 4 dcl dcwp ptr, /* pointer to DCW */ 6 5 tdcwp ptr; /* pointer to TDCW */ 6 6 6 7 dcl 1 dcw based (dcwp) aligned, /* Data Control Word */ 6 8 (2 address bit (18), /* address for data transfer */ 6 9 2 char_pos bit (3), /* character position */ 6 10 2 m64 bit (1), /* non-zero for mod 64 address */ 6 11 2 type bit (2), /* DCW type */ 6 12 2 tally bit (12)) unal; /* tally for data transfer */ 6 13 6 14 dcl 1 tdcw based (tdcwp) aligned, /* Transfer DCW */ 6 15 (2 address bit (18), /* address to transfer to */ 6 16 2 mbz1 bit (4), 6 17 2 type bit (2), /* should be "10"b for TDCW */ 6 18 2 mbz2 bit (9), 6 19 2 ec bit (1), /* non-zero to set LPW AE bit */ 6 20 2 res bit (1), /* non-zero to restrict further use of IDCW */ 6 21 2 rel bit (1)) unal; /* non-zero to set relative mode after transfer */ 6 22 6 23 /* End of include file ...... iom_dcw.incl.pl1 */ 6 24 154 155 156 tdcm_attach: 157 entry (arg_tsegp, arg_ecode); 158 159 /* The following entry points will be implemented as external procedures. 160* * This is done in order to reduce the size of tdcm_.pl1. 161**/ 162 call tdcm_attach_ (arg_tsegp, arg_ecode); 163 return; 164 165 166 167 168 tdcm_message: 169 entry (arg_tsegp, arg_reel_name, arg_write_sw, arg_ecode); 170 171 call SETUP; /* Initialize and validate. */ 172 ws.info.subset_size = divide (hbound (ws.rw_list, 1), 2, 17, 0); 173 /* set up max subset size */ 174 call tdcm_message_ (tsegp, ws_ptr, arg_reel_name, arg_write_sw, arg_ecode); 175 return; 176 177 178 179 180 tdcm_detach: 181 entry (arg_tsegp, arg_ecode); 182 183 call SETUP; /* Initialize and validate. */ 184 185 if ws.info.flags.good_ws then do; 186 call REWIND_TAPE; /* TERMPORARY for DUMMY RCP. */ 187 call tdcm_$tdcm_reset_signal (tsegp, ecode); /* set up to ignore special interrupt */ 188 if display_meters then do; /* this will normally be shut off */ 189 call mhcs_$get_seg_usage_ptr (tsegp, pfs, pf_code); 190 call ioa_ ("^/Total number of data xfer I/O calls:^2-^d", ws.number_ios + 1); 191 call ioa_ ("Highest number of blocks/data xfer I/O call:^-^d", ws.info.block_count); 192 call ioa_ ("Average Time between data xfer I/O calls:^-^.3f MS", 193 float (ws.io_delta / ws.number_ios) / 1000); 194 call ioa_ ("Longest time between data xfer I/O calls:^-^.3f MS", float (ws.high_delta) / 1000); 195 call ioa_ ("Shortest time between data xfer I/O calls:^-^.3f MS", float (ws.low_delta) / 1000); 196 call ioa_ ("Number of calls to ipc_$block:^2-^d", ws.info.block); 197 call ioa_ ("Times status queue processed w/o going blocked:^-^d", ws.info.no_block); 198 call ioa_ ("Total number of terminate interrupts:^2-^d", ws.info.term_st); 199 call ioa_ ("Number of terminate interrupts without errors:^-^d", ws.info.term_ne); 200 call ioa_ ("Total number of marker interrupts:^2-^d", ws.info.mark_st); 201 call ioa_ ("Most consecutive number of marker interrupts:^-^d", ws.most_consec_mark); 202 call ioa_ ("Number of page faults taken on tseg:^2-^d", pfs); 203 call mhcs_$get_seg_usage_ptr (ws_ptr, pfs, pf_code); 204 call ioa_ ("Number of page faults taken on workspace:^-^d^/", pfs); 205 end; 206 end; 207 call tdcm_detach_ (ws_ptr, arg_ecode); 208 return; 209 210 tdcm_set_signal: 211 entry (arg_tsegp, arg_ecode); 212 213 /* This entry point is called whenever the caller wants to be waked 214* * up when a special interrupt is received from the tape drive. 215* * Until this entry is called all special interrupts will be ignored. 216* * In order to implement this feature we must change the event 217* * channel that IOIis using to communicate with us. We will 218* * use an event call channel instead of the fast event channel. 219* * This means that when IOI sends a wakeup we will enter the call 220* * handler tdcm_$special_handler rather than being waked up in 221* * WAIT_FOR_STATUS. If the tape drive is not yet attached we will save 222* * the ID of the event channel we want to use. It will be set up with 223* * IOIafter the attachment is made. 224**/ 225 call SETUP; /* Initialize and validate. */ 226 227 if ws.info.flags.attached /* If attached switch, else save. */ 228 then call ioi_$set_event (ws.info.ioix, ws.info.special_echan, ecode); 229 else ws.info.init_echan = ws.info.special_echan; 230 231 arg_ecode = ecode; 232 return; 233 234 235 236 237 238 tdcm_reset_signal: 239 entry (arg_tsegp, arg_ecode); 240 241 /* This entry point is called when the caller is no longer 242* * interrested in special interrupts. We will swap back the 243* * the event channels that we changed in tdcm_set_signal. 244* * We will use the fast event channel again. 245**/ 246 call SETUP; /* Initialize and validate. */ 247 248 if ws.info.flags.attached /* If attached switch back, else save. */ 249 then call ioi_$set_event (ws.info.ioix, ws.info.fast_echan, ecode); 250 else ws.info.init_echan = ws.info.fast_echan; 251 252 arg_ecode = ecode; 253 return; 254 255 tdcm_promote: 256 entry (arg_tsegp, arg_val_level, arg_ecode); 257 258 /* This entry point is called to promote the validation level of the 259* * specified tape drive. The validation level will already be set 260* * to the caller's validation level. If this entry point is called 261* * before this drive is attached we will get an error from IOI. 262**/ 263 call SETUP; /* Initialize and validate. */ 264 265 new_val_level = arg_val_level; /* Copy validation level caller wants to set. */ 266 call rcp_$promote (ws.info.rcp_id, new_val_level, ecode); 267 268 arg_ecode = ecode; 269 return; 270 271 272 273 274 275 tdcm_set_disposition: 276 entry (arg_tsegp, arg_disposition, arg_ecode); 277 278 /* This entry is called to specify a disposition to be passed to RCP 279* * when this drive is detached. If this entry point is called 280* * before this drive is attached we will return an error. 281**/ 282 call SETUP; 283 284 if ^ws.info.flags.attached /* Make sure tape drive is attached. */ 285 then do; /* Not attached, return error. */ 286 arg_ecode = error_table_$invalid_state; 287 return; 288 end; 289 290 ws.info.disposition = arg_disposition; /* Save caller's disposition. */ 291 292 arg_ecode = ecode; 293 return; 294 295 tdcm_set_buf_size: 296 entry (arg_tsegp, arg_buf_size, arg_ecode); 297 298 /* This entry point is called to set the size of the tdcm_ I/O buffer. 299* * The default tdcm_ I/O buffer size is 2080 words. The actual buffer size 300* * used is also a function of the maximum workspace size available from IOI. 301* * This entry point must be called before the first call to tdcm_$tdcm_message. 302**/ 303 call SETUP; 304 305 buf_size = arg_buf_size; /* Copy argument. */ 306 307 if ws.info.flags.attached then do; /* Is tape drive already attached? */ 308 arg_ecode = error_table_$invalid_state; /* Yes, buffer size already established. */ 309 return; 310 end; 311 312 if buf_size < 1 then do; /* Is buffer size too small? */ 313 arg_ecode = error_table_$bad_arg; /* Yes, don't change the buffer size. */ 314 315 return; 316 end; 317 if buf_size = 1040 * 6 then do; /* tape_mult_ with "-sys" option? */ 318 ws.info.flags.allow_marker = "1"b; /* yes, do marker interrupt processing */ 319 buf_size = hbound (ws.rw_list, 1) * 1040; /* set wks to mak size allowed */ 320 end; 321 ws.info.buf_size = buf_size; /* Set buffer size. */ 322 323 arg_ecode = 0; 324 return; 325 326 327 328 tdcm_get_buf_size: 329 entry (tsegp, arg_buf_size, arg_ecode); 330 331 call SETUP; 332 333 if ^ws.info.flags.attached then do; /* Is tape drive attached? */ 334 arg_buf_size = 0; /* No, buffer size value not valid yet. */ 335 arg_ecode = error_table_$invalid_state; 336 return; 337 end; 338 339 if ws.info.flags.allow_marker then /* if we phonied up buffer size.. */ 340 arg_buf_size = ws.info.subset_size * 1040; /* don't tell user */ 341 else arg_buf_size = ws.info.buf_size; /* Return actual buffer size. */ 342 arg_ecode = 0; 343 return; 344 345 tdcm_iocall: 346 entry (arg_tsegp, arg_ecode); 347 348 /* This entry point is called to perform actual I/O operations on the 349* * specified tape drive. There are two main types of I/O operations 350* * performed: non-data transfer commands, and reads or writes. 351* * If this entry point is called before the tape drive is attached 352* * we will get an error from IOI. 353**/ 354 call SETUP; /* Initialize and verify. */ 355 356 tseg.completion_status = 0; /* Initialize to imply no status. */ 357 358 IOCALL_LOOP: /* Check status and perform I/O. */ 359 if ws.info.flags.connected then /* Are _w_e currently performing I/O? */ 360 if ^ws.info.flags.allow_marker then /* and not doing marker processing? */ 361 call CHECK_STATUS; /* Yes, wait for it to complete. */ 362 else if tseg.command_count > 0 | /* allowing markers, but non-data xfer or */ 363 tseg.command_count + tseg.buffer_count <= 0 then 364 /* if no I/O to perform */ 365 call CHECK_STATUS; /* then wait for terminate status */ 366 if tseg.command_count + tseg.buffer_count <= 0 then 367 goto IOCALL_RETURN; /* No I/O to perform. */ 368 369 /* Write switch in tseg => error type. */ 370 if tseg.command_count > 0 then /* Are there any non-data transfer commands? */ 371 call NON_DATA_TRANSFER; /* Yes, do them first. */ 372 else if ws.info.flags.allow_marker then /* if doing marker interrupt processing... */ 373 call MARKER_READ_WRITE; /* go to that routine */ 374 else call READ_WRITE; /* No, caller must want to read or write. */ 375 376 if tseg.sync ^= 0 then /* Does caller want us to wait? */ 377 goto IOCALL_LOOP; /* Yes, wait until operation complete. */ 378 379 IOCALL_RETURN: 380 arg_ecode = ecode; 381 return; 382 383 special_handler: 384 entry (arg_call_data_ptr); 385 386 /* This entry point is called to handle wakeups on the event call 387* * channel, special_echan. This event channel is given to IOI when 388* * the user calls tdcm_set_signal. We will call IOI to get the 389* * status for the current interrupt. 390**/ 391 call_data_ptr = arg_call_data_ptr; /* Get pointer to event call data. */ 392 ws_ptr = call_data.data_ptr; /* The event data ptr is the workspace ptr. */ 393 394 isp = addr (ws.statq (ws.info.statqx)); /* Get pointer to current IOI status queue entry. */ 395 if ^istat.completion.st then /* If no status then ignore status queue. */ 396 goto GET_SPECIAL_STATUS; /* Go see if there is special status. */ 397 398 goto SLEVEL (istat.level); /* Go process according to level. */ 399 400 SLEVEL (7): /* Should not get special status in queue. */ 401 if ws.info.statqx = hbound (ws.statq, 1) then /* Get index of next status queue entry. */ 402 ws.info.statqx = 1; /* If at end wraparound. */ 403 else ws.info.statqx = ws.info.statqx + 1; 404 405 istat.completion.st = "0"b; /* Free this status queue entry. */ 406 407 goto GET_SPECIAL_STATUS; 408 409 /* This is a terminate of system fault interrupt. Either of these 410* * interrupts signals the completion of a connect. tdcm_iocall will 411* * always wait on the wait list event channel for the completion 412* * of a connect. Therefore we must send a wakeup over that channel. 413* * We will not actually process the status from this interrupt. 414* * It will be processed by WAIT_FOR_STATUS when it wakes up. 415**/ 416 SLEVEL (1): /* System fault or terminate interrupt. */ 417 SLEVEL (3): /* Send a wakeup to WAIT_FOR_STATUS. */ 418 SLEVEL (5): /* Marker, treat like terminate */ 419 call hcs_$wakeup (ws.info.process_id, ws.info.wait_list.wait_echan, 0, ecode); 420 421 /* One way or another we have processed any status in the queue. 422* * Now we must look for a special interrupt. Since this entry 423* * was called we know that the caller wants to be signalled 424* * when there is a special interrupt. We will send a wakeup to him 425* * over the user event channel. The caller should be blocked himself 426* * waiting for this wakeup. 427**/ 428 GET_SPECIAL_STATUS: 429 call ioi_$get_special_status (ws.info.ioix, special_flag, special_status_word, ecode); 430 if ecode ^= 0 then 431 return; 432 if special_flag then /* If we got a special signal user. */ 433 call hcs_$wakeup (ws.info.process_id, ws.info.user_echan, 0, ecode); 434 return; 435 436 /* This label defines the location where all internal procedures will 437* * return if they encounter a fatal error. This non-structured bit 438* * of programming is done for the sake of efficiency. It means that 439* * there does not have to be a check for errors after each call to 440* * an internal procedure. 441**/ 442 443 INTERNAL_PROC_RETURN: 444 arg_ecode = ecode; /* Return error code. */ 445 return; 446 447 448 449 450 451 SETUP: 452 procedure; 453 454 /* This procedure is called by all entry points except tdcm_attach. 455* * It gets a pointer to the IOI workspace that we are using. 456* * If we don't have a real IOI workspace yet we will temporarily 457* * use part of the tseg. 458**/ 459 tsegp = arg_tsegp; /* Copy argument. */ 460 461 if tseg.version_num ^= tseg_version_2 then do; 462 ecode = error_table_$unimplemented_version; 463 goto INTERNAL_PROC_RETURN; 464 end; 465 466 ecode = 0; 467 468 if tseg.ws_segno = "0"b /* Do we have a real IOI workspace yet? */ 469 then ws_ptr = addr (tseg.buffer (1)); /* No, use temporary workspace area. */ 470 else ws_ptr = baseptr (tseg.ws_segno); 471 472 end SETUP; 473 474 WAIT_FOR_STATUS: 475 procedure; 476 477 /* This procedure is called when we must wait for a connect to terminate. 478* * We will always block on the status_echan event channel. This is the 479* * event channel that we try to initiate as a fast channel. If the 480* * interrupt which caused IOI to send this wakeup is not a terminate 481* * or system fault we will ignore the wakeup and go blocked again. 482* * When we return all the necessary processing of the interrupt will have 483* * been performed. Then the connect will be considered complete. 484**/ 485 WAIT_LOOP: /* Come here if we have to block again. */ 486 ws.info.meters.block = ws.info.meters.block + 1; /* increment meter */ 487 call ipc_$block (addr (ws.info.wait_list), addr (event_data), ecode); 488 if ecode ^= 0 then do; 489 call convert_ipc_code_ (ecode); 490 goto INTERNAL_PROC_RETURN; 491 end; 492 go to PROC_QUEUE; 493 494 PROCESS_QUEUE: 495 entry; /* entry called when we know a status queue entry is full */ 496 ws.info.meters.no_block = ws.info.meters.no_block + 1; 497 /* increment meter */ 498 PROC_QUEUE: 499 isp = addr (ws.statq (ws.info.statqx)); /* Get pointer to current IOI status queue entry. */ 500 if ^istat.completion.st then /* If no status then we got an extra wakeup. */ 501 goto WAIT_LOOP; /* Wait again. */ 502 503 if ws.info.statqx = hbound (ws.statq, 1) then /* Get index of next status queue entry. */ 504 ws.info.statqx = 1; /* If at end wraparound. */ 505 else ws.info.statqx = ws.info.statqx + 1; 506 507 istat.completion.st = "0"b; /* Free this status queue entry. */ 508 statp = addr (istat.iom_stat); /* Get pointer to IOM status. */ 509 listx = istat.offset; /* Get absolute listx from IOI. */ 510 if ws.info.flags.ndtrans then /* Convert listx depending upon type of DCW list. */ 511 op_count = listx - ws.info.ndt_offsetx + 1; 512 else if ws.info.flags.large_rec then /* One record longer than 4096 words? */ 513 op_count = 1; 514 else op_count = divide ((listx - ws.info.rw_offsetx + 2), 2, 17, 0); 515 goto WLEVEL (istat.level); /* Go process according to level. */ 516 517 WLEVEL (7): /* Should not get special status in queue. */ 518 goto WAIT_LOOP; /* Ignore, wait for real status. */ 519 520 WLEVEL (1): /* System fault. */ 521 istat.iom_stat = "0"b; /* Clear IOM status. */ 522 status.major = "1111"b; /* This denotes a system fault. */ 523 524 WLEVEL (3): /* Terminate interrupt. Process together. */ 525 ws.info.term_st = ws.info.term_st + 1; /* increment meter */ 526 ws.info.consec_mark = 0; /* reset this meter */ 527 if op_count > ws.info.subset_size then do; /* if doing marker processing, must be on second half */ 528 op_count = op_count - ws.info.subset_size; /* set for only number of buffers since last marker */ 529 ws.info.mark_offset = ws.info.subset_size; /* set base buffer */ 530 end; 531 else ws.info.mark_offset = 0; /* first buffer subset */ 532 ws.info.flags.connected = "0"b; /* Connect has now completed. */ 533 if ws.info.flags.reading then /* Was this connect for a read? */ 534 call PROCESS_INPUT; /* Yes, extra processing needed for input. */ 535 536 tseg.hardware_status = istat.iom_stat; /* Return iom status to user. */ 537 538 if ^istat.completion.er then do; /* Was there an error? */ 539 tseg.completion_status = 1; /* No, tell user everything is OK. */ 540 ws.info.term_ne = ws.info.term_ne + 1; /* increment meter */ 541 end; 542 else do; /* Yes, there was an error. */ 543 tseg.completion_status = 2; /* Tell user that he got bad status. */ 544 tseg.error_buffer = op_count; /* Tell him how far he got. */ 545 if (status.major = "0011"b) | (status.major = "1011"b) then 546 /* Count data alert errors. */ 547 /* And MPC data alert errors. */ 548 ws.info.error_count = ws.info.error_count + 1; 549 if istat.completion.time_out then /* IF time-out set error code. */ 550 ecode = error_table_$net_timeout; 551 goto INTERNAL_PROC_RETURN; /* Return directly to user. */ 552 end; 553 return; 554 555 WLEVEL (5): /* Marker interrupt */ 556 ws.info.mark_st = ws.info.mark_st + 1; /* increment meter */ 557 ws.consec_mark = ws.consec_mark + 1; /* increment meter */ 558 if ws.consec_mark > ws.most_consec_mark then /* if this is bigger than previous high */ 559 ws.most_consec_mark = ws.consec_mark; /* change the value */ 560 if ws.info.flags.reading then do; /* if reading extra processing required */ 561 tmr = "0"b; /* reset terminate condition */ 562 do i = op_count by -1 while (^tmr); /* find the real marker index */ 563 if i = 0 then /* if we got to the beginning of the list.. */ 564 i = hbound (ws.rw_list, 1); /* reset back to the end */ 565 idcwp = addr (ws.rw_list (i).idcw); 566 if idcw.control = "11"b then do; /* if true, we found the marker */ 567 tmr = "1"b; /* set terminate conditon */ 568 op_count = i; /* adjust op_count to corrected value */ 569 end; 570 end; 571 if op_count > ws.info.subset_size then do; /* if doing marker processing, must be on second half */ 572 op_count = op_count - ws.info.subset_size; 573 /* set for only number of buffers since last marker */ 574 ws.info.mark_offset = ws.info.subset_size; 575 /* set base buffer */ 576 end; 577 else ws.info.mark_offset = 0; /* first buffer subset */ 578 call PROCESS_INPUT; /* Yes, extra processing needed for input. */ 579 end; 580 tseg.hardware_status = istat.iom_stat; /* copy marker status to return to user */ 581 tseg.completion_status = 1; /* indicate no error */ 582 583 end WAIT_FOR_STATUS; 584 585 PROCESS_INPUT: 586 procedure; 587 588 /* This procedure is called to process input data found in the IOI workspace. 589* * We will copy the input data from the workspace into the tseg buffers. 590* * We must copy the input buffers one at a time since the size of each tseg 591* * buffer may be much larger than the number of words that are actually used 592* * in each buffer. 593**/ 594 if ws.info.flags.allow_marker then /* if doing marker processing */ 595 tbuf_num = ws.info.mark_offset + 1; /* 1 to 1 relation between tseg buf and ws buf */ 596 else tbuf_num = ws.info.read_start; /* otherwise start where he told us */ 597 598 if ws.info.flags.get_size then do; /* Does caller want actual read count? */ 599 /* Yes, special case. */ 600 fix = 0; /* We may have to fix the read count. */ 601 if (status.char_pos = "1"b3) & (^istat.completion.er) then 602 /* NZ char count & no error? */ 603 if (status.sub & "04"b3) = "04"b3 then 604 if addr (ws.rw_list (1).idcw) -> idcw.command ^= addr (ws.read_idcws (2)) -> idcw.command then 605 fix = 1; /* Fix, 9 track _a_n_d _n_o_t read tape 9. */ 606 else ; 607 else if (^status.eo) & ((status.sub & "60"b3) = "40"b3) then 608 fix = 1; /* Fix, 7 track _a_n_d even _a_n_d 4 bit fill. */ 609 dcw_tally = bin (status.tally, 12) + fix; /* Compute correct tally residue. */ 610 /* Now return read count of first buffer. */ 611 if (listx - ws.info.rw_offsetx) >= (divide (ws.info.buffer_size (1) + 4095, 4096, 17)) then 612 data_size = ws.info.buffer_size (1) - dcw_tally; 613 else data_size = (listx - ws.info.rw_offsetx) * 4096 - dcw_tally; 614 tseg.buffer_size (ws.info.read_start) = data_size; 615 end; 616 617 do i = ws.info.mark_offset + 1 to ws.info.mark_offset + op_count; 618 /* Copy buffers from workspace to tseg. */ 619 data_size = ws.info.buffer_size (i); /* Get size of this input buffer. */ 620 dcwp = addr (ws.rw_list (i).dcw); /* get correct dcw */ 621 wbuf_ptr = ptr (addr (ws.buffer), dcw.address); 622 /* and get ptr to data */ 623 /* Copy one input buffer into tseg. */ 624 ptr (tsegp, tseg.bufferptr (tbuf_num)) -> based_data = wbuf_ptr -> based_data; 625 tbuf_num = tbuf_num + 1; /* Move to next tseg buffer. */ 626 end; 627 628 end PROCESS_INPUT; 629 630 NON_DATA_TRANSFER: 631 procedure; 632 633 /* This procedure is called to set up non-data transfer IDCWs. 634* * Most fields in these non-data transfer IDCWs were set up when the 635* * the tape drive was attached. We just have to fill in the actual 636* * device command codes and turn OFF the continue bits in the last 637* * IDCW. We get the device commands from the tseg command queue. 638**/ 639 op_count = tseg.command_count; /* Get number of non-data transfer operations. */ 640 if op_count > hbound (ws.ndt_list, 1) /* Make sure there are not too many. */ 641 then do; 642 ecode = error_table_$too_many_buffers; 643 goto INTERNAL_PROC_RETURN; 644 end; 645 646 do i = 1 to op_count; /* Set up specified number of IDCWs. */ 647 idcwp = addr (ws.ndt_list (i).idcw); /* Get pointer to non-data transfer IDCW. */ 648 idcw.command = bit (tseg.command_queue (i), 6); 649 /* Copy device command. */ 650 idcw.control = "10"b; /* Turn ON continue in each IDCW. */ 651 end; 652 653 idcw.control = "00"b; /* Terminate list with last IDCW. */ 654 655 tseg.command_count = 0; /* Tell caller we have picked up all commands. */ 656 ws.info.flags.reading = "0"b; /* Not reading or writing. */ 657 ws.info.flags.ndtrans = "1"b; /* Non-data transfer commands. */ 658 659 call TRY_TO_CONNECT (ws.info.ndt_offsetx); 660 if ecode ^= 0 then 661 goto INTERNAL_PROC_RETURN; 662 ws.info.flags.connected = "1"b; /* Connect has been made. */ 663 664 end NON_DATA_TRANSFER; 665 666 /* CK_STATQ - subroutine to check if any status queue entry is full */ 667 668 CK_STATQ: 669 proc returns (bit (1) aligned); 670 671 if ws.statq (ws.info.statqx).completion.st then /* if status stored in this queue entry */ 672 return ("1"b); /* return true */ 673 else return ("0"b); /* no status stored */ 674 675 end CK_STATQ; 676 677 MARKER_READ_WRITE: 678 procedure; 679 680 /* This procedure is called to set up the IDCWs and DCWs used to read 681* * or write data. The write switch in the tseg tells us which type 682* * of operation is to be performed. 683**/ 684 op_count = tseg.buffer_count; /* Get number of buffers to read or write. */ 685 if op_count > ws.info.subset_size then do; /* Did caller specify too many buffers? */ 686 ecode = error_table_$too_many_buffers; 687 goto INTERNAL_PROC_RETURN; 688 end; 689 690 wbuf_ptr = addr (ws.buffer); /* Get pointer to buffer area in IOI workspace. */ 691 tbuf_num = tseg.buffer_offset + 1; /* Get number of first tseg buffer. */ 692 if tbuf_num > ws.info.subset_size then do; /* if setting up second subset of buffers */ 693 wbuf_num = ws.info.subset_size + 1; 694 wbuf_ptr = addrel (wbuf_ptr, ws.info.subset_size * 1040); 695 /* start at end of first subset */ 696 end; 697 else wbuf_num = 1; /* no set up for first subset */ 698 if tseg.write_sw ^= 0 then do; /* Are we reading or writing? */ 699 ws.info.flags.reading = "0"b; /* Writing not reading. */ 700 data_idcw = ws.info.write_idcws (tseg.mode (tbuf_num)); 701 /* Writing. */ 702 end; 703 else do; /* Reading. */ 704 ws.info.flags.reading = "1"b; 705 ws.info.read_start = tbuf_num; /* Save number of first tseg buffer read into. */ 706 data_idcw = ws.info.read_idcws (tseg.mode (tbuf_num)); 707 /* Reading. */ 708 end; 709 if substr (ws.rw_list (1).idcw, 1, 12) ^= substr (data_idcw, 1, 12) then do; 710 /* set up DCW list, 1st time */ 711 ws.info.flags.large_rec = "0"b; 712 data_size = tseg.buffer_size (tbuf_num); /* set physical record size */ 713 do i = 1 to hbound (ws.rw_list, 1); 714 idcwp = addr (ws.rw_list (i).idcw); /* set up IDCW */ 715 based_idcw = data_idcw; 716 dcwp = addr (ws.rw_list (i).dcw); /* set up DCW */ 717 string (dcw) = "0"b; /* make sure its zero first */ 718 dcw.address = rel (wbuf_ptr); /* set relative workspace address */ 719 dcw.tally = bit (bin (data_size, 12)); /* set tally */ 720 wbuf_ptr = addrel (wbuf_ptr, data_size);/* increment workspace ptr */ 721 ws.info.buffer_size (i) = data_size; /* set up buffer size for reads */ 722 end; 723 wbuf_ptr = addr (ws.buffer); /* reset workspace buffer ptr */ 724 tdcwp = addr (ws.mark_tdcw); /* set up tdcw to chain list */ 725 tdcw.address = rel (addr (ws.rw_list (1).idcw)); 726 tdcw.type = "10"b; /* make it a tdcw */ 727 tdcw.rel = "1"b; /* and set relative mode */ 728 end; 729 call METER_IO; /* go meter the IO time */ 730 do i = wbuf_num to wbuf_num + op_count - 1; /* Set up IDCW and and copy data if writing */ 731 if tseg.write_sw ^= 0 then do; /* if writing... */ 732 data_size = tseg.buffer_size (tbuf_num);/* get buffer size */ 733 wbuf_ptr -> based_data = ptr (tsegp, tseg.bufferptr (tbuf_num)) -> based_data; 734 wbuf_ptr = addrel (wbuf_ptr, data_size);/* go to next buffer */ 735 tbuf_num = tbuf_num + 1; /* increment tseg buffer number */ 736 end; 737 idcwp = addr (ws.rw_list (i).idcw); /* set idcw ptr */ 738 idcw.control = "10"b; /* set all idcws to continue */ 739 end; 740 idcw.control = "00"b; /* Terminate list with last IDCW. */ 741 742 tseg.buffer_count = 0; /* Tell caller that we picked up all buffers. */ 743 ws.info.flags.ndtrans = "0"b; /* These are not non-data transfer commands. */ 744 745 if ^ws.info.flags.connected then do; /* if no I/O in progress, get it going now */ 746 call TRY_TO_CONNECT (ws.info.rw_offsetx + ((wbuf_num - 1) * 2)); 747 ws.info.flags.connected = "1"b; /* Connect has been made. */ 748 end; 749 else do; /* I/O in progress, must be processing markers */ 750 if op_count = ws.info.subset_size then do; /* if we can, set up marker to keep I/O going */ 751 if tseg.buffer_offset = 0 then /* if this I/O was for first subset */ 752 idcwp = addr (ws.rw_list (hbound (ws.rw_list, 1)).idcw); 753 /* set idcw ptr for last idcw */ 754 else idcwp = addr (ws.rw_list (tseg.buffer_offset).idcw); 755 /* otherwise set for middle idcw */ 756 idcw.control = "11"b; /* set marker control bits in appropriate idcw */ 757 end; 758 call CHECK_STATUS; /* wait for status to come in */ 759 if ^ws.info.flags.connected & /* if no I/O in progress */ 760 tseg.completion_status = 1 then do; /* and no error, get I/O going */ 761 call TRY_TO_CONNECT (ws.info.rw_offsetx + ((wbuf_num - 1) * 2)); 762 ws.info.flags.connected = "1"b; /* Connect has been made. */ 763 end; 764 end; 765 766 end MARKER_READ_WRITE; 767 768 READ_WRITE: 769 procedure; 770 771 /* This procedure is called to set up the IDCWs and DCWs used to read 772* * or write data. The write switch in the tseg tells us which type 773* * of operation is to be performed. 774**/ 775 op_count = tseg.buffer_count; /* Get number of buffers to read or write. */ 776 if op_count > ws.info.subset_size then do; /* Did caller specify too many buffers? */ 777 ecode = error_table_$too_many_buffers; 778 goto INTERNAL_PROC_RETURN; 779 end; 780 781 wbuf_ptr = addr (ws.buffer); /* Get pointer to buffer area in IOI workspace. */ 782 tbuf_num = tseg.buffer_offset + 1; /* Get number of first tseg buffer. */ 783 /* tseg buffer offset starts with 0. */ 784 785 if tseg.write_sw ^= 0 then /* Are we reading or writing? */ 786 ws.info.flags.reading = "0"b; /* Writing not reading. */ 787 else do; /* Reading. */ 788 ws.info.flags.reading = "1"b; 789 ws.info.read_start = tbuf_num; /* Save number of first tseg buffer read into. */ 790 if tseg.get_size ^= 1 then /* Does caller want actual data size read? */ 791 ws.info.flags.get_size = "0"b; /* No. */ 792 else do; /* Yes. */ 793 ws.info.flags.get_size = "1"b; 794 if op_count > 1 then do; /* Only works if reading one buffer. */ 795 ecode = error_table_$too_many_buffers; 796 goto INTERNAL_PROC_RETURN; 797 end; 798 end; 799 end; 800 call METER_IO; /* go meter this I/O */ 801 tot_data_size = 0; /* Keep count of combined buffer sizes. */ 802 do i = 1 to op_count; /* Set up IDCW and DCW for each buffer. */ 803 data_size = tseg.buffer_size (tbuf_num); /* Num of words to process in this buf. */ 804 tot_data_size = tot_data_size + data_size; /* Get total num of words to process. */ 805 if (tot_data_size > ws.info.buf_size) | (data_size <= 0) then do; 806 /* Is total more than we can handle? */ 807 /* Or is number for this buffer invalid? */ 808 ecode = error_table_$buffer_big; 809 goto INTERNAL_PROC_RETURN; 810 end; 811 if data_size > 4096 then /* If more than one DCW needed ... */ 812 if op_count > 1 then do; /* Can only allow one operation. */ 813 ecode = error_table_$too_many_buffers; 814 go to INTERNAL_PROC_RETURN; 815 end; 816 else ws.info.flags.large_rec = "1"b; 817 else ws.info.flags.large_rec = "0"b; 818 819 idcwp = addr (ws.rw_list (i).idcw); /* Now set up IDCW. */ 820 if tseg.write_sw ^= 0 then do; /* Are we writing or reading? */ 821 based_idcw = ws.info.write_idcws (tseg.mode (tbuf_num)); 822 /* Writing, copy data from tseg to workspace. */ 823 wbuf_ptr -> based_data = ptr (tsegp, tseg.bufferptr (tbuf_num)) -> based_data; 824 end; 825 else do; /* Reading. */ 826 based_idcw = ws.info.read_idcws (tseg.mode (tbuf_num)); 827 ws.info.buffer_size (i) = data_size; /* Remember how many words we are to read. */ 828 end; 829 830 dcwp = addr (ws.rw_list (i).dcw); /* Set up DCW first. */ 831 do while (data_size > 0); /* Make as many DCWs as needed. */ 832 string (dcw) = "0"b; 833 dcw.address = rel (wbuf_ptr); 834 dcw_tally = min (data_size, 4096); 835 dcw.tally = bit (bin (dcw_tally, 12)); 836 if data_size > 4096 then 837 dcw.type = "01"b; 838 dcwp = addrel (dcwp, 1); 839 wbuf_ptr = addrel (wbuf_ptr, dcw_tally); 840 data_size = data_size - dcw_tally; 841 end; 842 843 tbuf_num = tbuf_num + 1; /* Move to next tseg buffer. */ 844 end; 845 idcw.control = "00"b; /* Terminate list with last IDCW. */ 846 847 tseg.buffer_count = 0; /* Tell caller that we picked up all buffers. */ 848 ws.info.flags.ndtrans = "0"b; /* These are not non-data transfer commands. */ 849 850 call TRY_TO_CONNECT (ws.info.rw_offsetx); 851 ws.info.flags.connected = "1"b; /* Connect has been made. */ 852 853 end READ_WRITE; 854 855 /* METER_IO - subroutine to meter time of each I/O */ 856 857 METER_IO: 858 proc; 859 860 if ^display_meters then 861 return; /* if not doing metering, forget it */ 862 if ws.last_io_time = 0 then /* if first I/O... */ 863 ws.last_io_time, ws.low_delta = clock (); /* initialize meters */ 864 else do; /* do some metering */ 865 io_time = clock (); /* get the current clock reading */ 866 delta = io_time - ws.last_io_time; /* get time between ios */ 867 ws.last_io_time = io_time; /* save current time */ 868 ws.io_delta = ws.io_delta + delta; /* add in current increment */ 869 if delta > ws.high_delta then /* if this increment is larger than previous.. */ 870 ws.high_delta = delta; /* save this one */ 871 if delta < ws.low_delta then /* if this icrement is smaller than previous */ 872 ws.low_delta = delta; /* save this one */ 873 if tseg.buffer_count > ws.info.block_count then 874 /* if block count > whats saved */ 875 ws.info.block_count = tseg.buffer_count;/* change it */ 876 ws.number_ios = ws.number_ios + 1; /* increment number of data xfer ios */ 877 end; 878 879 end METER_IO; 880 881 /* CHECK_STATUS - subroutine to check status queue. If status queue entry full, 882* we will process it without going blocked. */ 883 884 CHECK_STATUS: 885 proc; 886 887 if CK_STATQ () then /* if there is status to process.. */ 888 call PROCESS_QUEUE; /* go do it, don't wait for it */ 889 else do; /* currently no status, drain the channel... */ 890 call ipc_$drain_chn (ws.info.wait_list.wait_echan, ecode); 891 /* get ride of any pending wakeups */ 892 if ecode ^= 0 then do; 893 call convert_ipc_code_ (ecode); 894 goto INTERNAL_PROC_RETURN; 895 end; 896 if CK_STATQ () then /* if there is status to process.. */ 897 call PROCESS_QUEUE; /* go do it, don't wait for it */ 898 else call WAIT_FOR_STATUS; /* go wait for marker or terminate status */ 899 end; 900 901 end CHECK_STATUS; 902 903 TRY_TO_CONNECT: 904 proc (P_idx); 905 906 /* * This procedure is used to perform connects; if there is insufficient 907* * main memory for a buffer when it is called, it waits for one half second, 908* * and tries again. If it fails after 25 tries, or encounters some other 909* * error, it aborts and goes to INTERNAL_PROC_RETURN. This is done in 910* * tdcm_ because it is necessary to go blocked while waiting; the error 911* * of not having sufficient memory used to crash the system. */ 912 913 dcl P_idx fixed bin parameter; 914 dcl connect_retries fixed bin; 915 dcl MAX_CONNECT_RETRIES fixed bin internal static options (constant) init (25); 916 917 connect_retries = 0; /* haven't tried at all yet */ 918 919 TRY_AGAIN_TO_CONNECT: 920 call ioi_$connect (ws.info.ioix, P_idx, ecode); 921 922 if ecode = 0 then 923 return; /* successfully accomplished */ 924 else if ecode ^= error_table_$out_of_main_memory then 925 /* lossage, some unexpected error */ 926 goto INTERNAL_PROC_RETURN; 927 else do; /* not enough room now, wait a while */ 928 if connect_retries > MAX_CONNECT_RETRIES then/* we've tried too often, let's just give up */ 929 goto INTERNAL_PROC_RETURN; 930 connect_retries = connect_retries + 1; 931 932 call WAIT_FOR_A_MOMENT (); 933 934 goto TRY_AGAIN_TO_CONNECT; 935 end; /* end of loop trying to connect */ 936 937 end TRY_TO_CONNECT; 938 939 WAIT_FOR_A_MOMENT: 940 proc (); 941 942 /* * This procedure is used to sleep for a short period of time, while 943* * waiting for more buffer space to become available. It is stolen 944* * more or less bodily from set_lock_. */ 945 946 dcl ALRM_STRING (1) char (32) internal static options (constant) init ("alrm"); 947 dcl A_BRIEF_MOMENT fixed bin (71) internal static options (constant) init (500000); 948 /* half a second, really */ 949 dcl RELATIVE_MICROSECONDS bit (2) aligned internal static options (constant) init ("10"b); 950 951 dcl initialized_for_waiting 952 bit (1) aligned internal static init ("0"b); 953 dcl this_is_initial_ring bit (1) aligned internal static; 954 dcl alrm_mask bit (36) aligned internal static; 955 dcl 1 wait_list aligned internal static, 956 2 count fixed bin, 957 2 channel fixed bin (71); 958 dcl saved_alarm_channel fixed bin (71); 959 dcl saved_alarm_time fixed bin (71); 960 dcl ignore_message fixed bin (71); 961 dcl saved_mask bit (36) aligned; 962 963 dcl create_ips_mask_ entry (ptr, fixed bin, bit (36) aligned); 964 dcl get_lock_id_ ext entry (bit (36) aligned); 965 dcl get_ring_ ext entry returns (fixed bin (3)); 966 dcl get_initial_ring_ ext entry returns (fixed bin (3)); 967 dcl hcs_$get_alarm_timer ext entry (fixed bin (71), fixed bin (71)); 968 dcl hcs_$get_ips_mask entry (bit (36) aligned); 969 dcl hcs_$set_alarm_timer ext entry (fixed bin (71), fixed bin, fixed bin (71)); 970 dcl ipc_$create_ev_chn ext entry (fixed bin (71), fixed bin (35)); 971 dcl ipc_$block ext entry (ptr, ptr, fixed bin (35)); 972 dcl timer_manager_$sleep ext entry (fixed bin (71), bit (2) aligned); 973 974 975 if ^initialized_for_waiting then do; /* prepare to wait for a moment */ 976 call create_ips_mask_ (addr (ALRM_STRING), 1, alrm_mask); 977 alrm_mask = substr (^alrm_mask, 1, 35); /* complement it for later tests */ 978 this_is_initial_ring = (get_ring_ () = get_initial_ring_ ()); 979 call ipc_$create_ev_chn (wait_list.channel, (0)); 980 wait_list.count = 1; 981 initialized_for_waiting = "1"b; 982 end; 983 984 call hcs_$get_ips_mask (saved_mask); /* See if IPS are masked. */ 985 if this_is_initial_ring & ((substr (saved_mask, 1, 35) & alrm_mask) = alrm_mask) then do; 986 /* we can call timer_manager_ */ 987 call timer_manager_$sleep (A_BRIEF_MOMENT, RELATIVE_MICROSECONDS); 988 end; /* sleep for a moment */ 989 990 else do; /* we cannot call timer_manager_ */ 991 call hcs_$get_alarm_timer (saved_alarm_time, saved_alarm_channel); 992 /* remember current alarm settings */ 993 call hcs_$set_alarm_timer (A_BRIEF_MOMENT, 1, wait_list.channel); 994 /* get awakened later */ 995 call ipc_$block (addr (wait_list), addr (ignore_message), ecode); 996 /* wait for wakeup */ 997 call hcs_$set_alarm_timer (saved_alarm_time, 2, saved_alarm_channel); 998 /* reset original timer settings */ 999 if ecode ^= 0 then /* if trouble then give up */ 1000 goto INTERNAL_PROC_RETURN; 1001 end; 1002 1003 return; /* we have waited */ 1004 end; /* internal procedure WAIT_FOR_A_MOMENT */ 1005 1006 REWIND_TAPE: 1007 procedure; 1008 1009 /* Temporary procedure used with the dummy version of RCP. 1010**/ 1011 dcl tdcm_$tdcm_iocall entry (ptr, fixed bin (35)); 1012 1013 tseg.sync = 1; 1014 tseg.get_size = 0; 1015 tseg.buffer_count = 0; 1016 tseg.command_count = 1; 1017 tseg.command_queue (1) = 111000b; /* REWIND */ 1018 1019 call tdcm_$tdcm_iocall (tsegp, ecode); 1020 1021 end REWIND_TAPE; 1022 1023 end tdcm_; SOURCE FILES USED IN THIS COMPILATION. LINE NUMBER DATE MODIFIED NAME PATHNAME 0 11/30/82 1207.1 tdcm_.pl1 >spec>on>11/30/82>tdcm_.pl1 145 1 06/10/82 1045.4 tseg.incl.pl1 >ldd>include>tseg.incl.pl1 147 2 06/09/82 2051.4 tdcm_info.incl.pl1 >ldd>include>tdcm_info.incl.pl1 149 3 08/17/79 2215.0 ioi_stat.incl.pl1 >ldd>include>ioi_stat.incl.pl1 151 4 01/10/75 1343.6 iom_stat.incl.pl1 >ldd>include>iom_stat.incl.pl1 153 5 05/06/74 1742.1 iom_pcw.incl.pl1 >ldd>include>iom_pcw.incl.pl1 154 6 11/12/74 1550.1 iom_dcw.incl.pl1 >ldd>include>iom_dcw.incl.pl1 NAMES DECLARED IN THIS COMPILATION. IDENTIFIER OFFSET LOC STORAGE CLASS DATA TYPE ATTRIBUTES AND REFERENCES (* indicates a set context) NAMES DECLARED BY DECLARE STATEMENT. ALRM_STRING 000020 constant char(32) initial array unaligned dcl 946 set ref 976 976 A_BRIEF_MOMENT 000016 constant fixed bin(71,0) initial dcl 947 set ref 987* 993* MAX_CONNECT_RETRIES constant fixed bin(17,0) initial dcl 915 ref 928 P_idx parameter fixed bin(17,0) dcl 913 set ref 903 919* RELATIVE_MICROSECONDS 000031 constant bit(2) initial dcl 949 set ref 987* addr builtin function dcl 111 ref 394 468 487 487 487 487 498 508 565 601 601 620 621 647 690 714 716 723 724 725 737 751 754 781 819 830 976 976 995 995 995 995 addrel builtin function dcl 111 ref 694 720 734 838 839 address based bit(18) level 2 in structure "dcw" packed unaligned dcl 6-7 in procedure "tdcm_" set ref 621 718* 833* address based bit(18) level 2 in structure "tdcw" packed unaligned dcl 6-14 in procedure "tdcm_" set ref 725* allow_marker 0(06) based bit(1) level 4 packed unaligned dcl 2-10 set ref 318* 339 358 372 594 alrm_mask 000012 internal static bit(36) dcl 954 set ref 976* 977* 977 985 985 arg_buf_size parameter fixed bin(17,0) dcl 54 set ref 295 305 328 334* 339* 341* arg_call_data_ptr parameter pointer dcl 55 ref 383 391 arg_disposition parameter bit unaligned dcl 56 ref 275 290 arg_ecode parameter fixed bin(35,0) dcl 57 set ref 156 162* 168 174* 180 207* 210 231* 238 252* 255 268* 275 286* 292* 295 308* 313* 323* 328 335* 342* 345 379* 443* arg_reel_name parameter char unaligned dcl 58 set ref 168 174* arg_tsegp parameter pointer dcl 59 set ref 156 162* 168 180 210 238 255 275 295 345 459 arg_val_level parameter fixed bin(17,0) dcl 60 ref 255 265 arg_write_sw parameter fixed bin(1,0) dcl 61 set ref 168 174* attached based bit(1) level 4 packed unaligned dcl 2-10 ref 227 248 284 307 333 based_data based fixed bin(35,0) array dcl 92 set ref 624* 624 733* 733 823* 823 based_idcw based bit(36) dcl 95 set ref 715* 821* 826* baseptr builtin function dcl 111 ref 470 bin builtin function dcl 111 ref 609 719 835 bit builtin function dcl 111 ref 648 719 835 block 35 based fixed bin(35,0) level 4 dcl 2-10 set ref 196* 485* 485 block_count 44 based fixed bin(17,0) level 4 dcl 2-10 set ref 191* 873 873* buf_size 1 based fixed bin(17,0) level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 321* 341 805 buf_size 000114 automatic fixed bin(17,0) dcl 71 in procedure "tdcm_" set ref 305* 312 317 319* 321 buffer 112 based bit(37440) array level 2 in structure "tseg" dcl 1-18 in procedure "tdcm_" set ref 468 buffer 212 based bit(36) array level 2 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 621 690 723 781 buffer_count 27 based fixed bin(12,0) level 2 dcl 1-18 set ref 362 366 684 742* 775 847* 873 873 1015* buffer_offset 26 based fixed bin(12,0) level 2 dcl 1-18 ref 691 751 754 782 buffer_size 62 based fixed bin(18,0) array level 2 in structure "tseg" dcl 1-18 in procedure "tdcm_" set ref 614* 712 732 803 buffer_size 51 based fixed bin(17,0) array level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 611 611 619 721* 827* bufferptr 46 based fixed bin(18,0) array level 2 dcl 1-18 ref 624 733 823 call_data based structure level 1 dcl 97 call_data_ptr 000110 automatic pointer dcl 68 set ref 391* 392 channel 2 000014 internal static fixed bin(71,0) level 2 dcl 955 set ref 979* 993* char_pos 1(18) based bit(3) level 2 packed unaligned dcl 4-7 ref 601 clock builtin function dcl 111 ref 862 865 command based bit(6) level 2 packed unaligned dcl 5-21 set ref 601 601 648* command_count 33 based fixed bin(12,0) level 2 dcl 1-18 set ref 362 362 366 370 639 655* 1016* command_queue 34 based fixed bin(6,0) array level 2 dcl 1-18 set ref 648 1017* completion 150 based structure array level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" completion based structure level 2 in structure "istat" dcl 3-7 in procedure "tdcm_" completion_status 30 based fixed bin(2,0) level 2 dcl 1-18 set ref 356* 539* 543* 581* 759 connect_retries 000264 automatic fixed bin(17,0) dcl 914 set ref 917* 928 930* 930 connected 0(01) based bit(1) level 4 packed unaligned dcl 2-10 set ref 358 532* 662* 745 747* 759 762* 851* consec_mark 43 based fixed bin(35,0) level 4 dcl 2-10 set ref 526* 557* 557 558 558 control 0(22) based bit(2) level 2 packed unaligned dcl 5-21 set ref 566 650* 653* 738* 740* 756* 845* convert_ipc_code_ 000036 constant entry external dcl 127 ref 489 893 count 000014 internal static fixed bin(17,0) level 2 dcl 955 set ref 980* create_ips_mask_ 000072 constant entry external dcl 963 ref 976 data_idcw 000133 automatic bit(36) dcl 86 set ref 700* 706* 709 715 data_ptr 6 based pointer level 2 dcl 97 ref 392 data_size 000115 automatic fixed bin(17,0) dcl 72 set ref 611* 613* 614 619* 624 712* 719 720 721 732* 733 734 803* 804 805 811 823 827 831 834 836 840* 840 dcw 120 based bit(36) array level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 620 716 830 dcw based structure level 1 dcl 6-7 in procedure "tdcm_" set ref 717* 832* dcw_tally 000116 automatic fixed bin(18,0) dcl 73 set ref 609* 611 613 834* 835 839 840 dcwp 000152 automatic pointer dcl 6-4 set ref 620* 621 716* 717 718 719 830* 832 833 835 836 838* 838 delta 000136 automatic fixed bin(71,0) dcl 87 set ref 866* 868 869 869 871 871 display_meters constant bit(1) initial dcl 124 ref 188 860 disposition 47 based bit(1) level 3 dcl 2-10 set ref 290* divide builtin function dcl 111 ref 172 514 611 ecode 000117 automatic fixed bin(35,0) dcl 74 set ref 187* 227* 231 248* 252 266* 268 292 379 416* 428* 430 432* 443 462* 466* 487* 488 489* 549* 642* 660 686* 777* 795* 808* 813* 890* 892 893* 919* 922 924 995* 999 1019* eo 0(12) based bit(1) level 2 packed unaligned dcl 4-7 ref 607 er 0(01) based bit(1) level 3 packed unaligned dcl 3-7 ref 538 601 error_buffer 32 based fixed bin(12,0) level 2 dcl 1-18 set ref 544* error_count 70 based fixed bin(17,0) level 3 dcl 2-10 set ref 545* 545 error_table_$bad_arg 000020 external static fixed bin(35,0) dcl 114 ref 313 error_table_$buffer_big 000022 external static fixed bin(35,0) dcl 114 ref 808 error_table_$invalid_state 000024 external static fixed bin(35,0) dcl 114 ref 286 308 335 error_table_$net_timeout 000032 external static fixed bin(35,0) dcl 114 ref 549 error_table_$out_of_main_memory 000026 external static fixed bin(35,0) dcl 114 ref 924 error_table_$too_many_buffers 000034 external static fixed bin(35,0) dcl 114 ref 642 686 777 795 813 error_table_$unimplemented_version 000030 external static fixed bin(35,0) dcl 114 ref 462 event_data 000100 automatic structure level 1 unaligned dcl 66 set ref 487 487 fast_echan 14 based fixed bin(71,0) level 3 dcl 2-10 set ref 248* 250 fix 000120 automatic fixed bin(17,0) dcl 75 set ref 600* 601* 607* 609 flags based structure level 3 dcl 2-10 get_initial_ring_ 000076 constant entry external dcl 966 ref 978 get_ring_ 000074 constant entry external dcl 965 ref 978 get_size 10 based fixed bin(1,0) level 2 in structure "tseg" dcl 1-18 in procedure "tdcm_" set ref 790 1014* get_size 0(02) based bit(1) level 4 in structure "ws" packed unaligned dcl 2-10 in procedure "tdcm_" set ref 598 790* 793* good_ws 0(07) based bit(1) level 4 packed unaligned dcl 2-10 ref 185 hardware_status 31 based bit(36) level 2 dcl 1-18 set ref 536* 580* hbound builtin function dcl 111 ref 172 319 400 503 563 640 713 751 hcs_$get_alarm_timer 000100 constant entry external dcl 967 ref 991 hcs_$get_ips_mask 000102 constant entry external dcl 968 ref 984 hcs_$set_alarm_timer 000104 constant entry external dcl 969 ref 993 997 hcs_$wakeup 000040 constant entry external dcl 128 ref 416 432 high_delta 32 based fixed bin(71,0) level 4 dcl 2-10 set ref 194 869 869* i 000122 automatic fixed bin(17,0) dcl 78 set ref 562* 563 563* 565 568* 617* 619 620* 646* 647 648* 713* 714 716 721* 730* 737* 802* 819 827 830* idcw 117 based bit(36) array level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 565 601 709 714 725 737 751 754 819 idcw 105 based bit(36) array level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 647 idcw based structure level 1 dcl 5-21 in procedure "tdcm_" idcwp 000150 automatic pointer dcl 5-19 set ref 565* 566 647* 648 650 653 714* 715 737* 738 740 751* 754* 756 819* 821 826 845 ignore_message 000300 automatic fixed bin(71,0) dcl 960 set ref 995 995 info based structure level 2 dcl 2-10 init_echan 22 based fixed bin(71,0) level 3 dcl 2-10 set ref 229* 250* initialized_for_waiting 000010 internal static bit(1) initial dcl 951 set ref 975 981* io_delta 26 based fixed bin(71,0) level 4 dcl 2-10 set ref 192 868* 868 io_time 000134 automatic fixed bin(71,0) dcl 87 set ref 865* 866 867 ioa_ 000070 constant entry external dcl 143 ref 190 191 192 194 195 196 197 198 199 200 201 202 204 ioi_$connect 000042 constant entry external dcl 129 ref 919 ioi_$get_special_status 000046 constant entry external dcl 131 ref 428 ioi_$set_event 000044 constant entry external dcl 130 ref 227 248 ioix 3 based fixed bin(17,0) level 3 dcl 2-10 set ref 227* 248* 428* 919* iom_stat 4 based bit(72) level 2 dcl 3-7 set ref 508 520* 536 580 ipc_$block 000110 constant entry external dcl 971 in procedure "WAIT_FOR_A_MOMENT" ref 995 ipc_$block 000052 constant entry external dcl 134 in procedure "tdcm_" ref 487 ipc_$create_ev_chn 000106 constant entry external dcl 970 ref 979 ipc_$drain_chn 000050 constant entry external dcl 133 ref 890 isp 000144 automatic pointer dcl 3-5 set ref 394* 395 398 405 498* 500 507 508 509 515 520 536 538 549 580 601 istat based structure level 1 dcl 3-7 large_rec 0(05) based bit(1) level 4 packed unaligned dcl 2-10 set ref 512 711* 816* 817* last_io_time 24 based fixed bin(71,0) level 4 dcl 2-10 set ref 862 862* 866 867* level 1 based fixed bin(3,0) level 2 dcl 3-7 ref 398 515 listx 000123 automatic fixed bin(17,0) dcl 79 set ref 509* 510 514 611 613 low_delta 30 based fixed bin(71,0) level 4 dcl 2-10 set ref 195 862* 871 871* major 0(02) based bit(4) level 2 packed unaligned dcl 4-7 set ref 522* 545 545 mark_offset 67 based fixed bin(17,0) level 3 dcl 2-10 set ref 529* 531* 574* 577* 594 617 617 mark_st 37 based fixed bin(35,0) level 4 dcl 2-10 set ref 200* 555* 555 mark_tdcw 147 based bit(36) level 2 dcl 2-10 set ref 724 meters 24 based structure level 3 dcl 2-10 mhcs_$get_seg_usage_ptr 000066 constant entry external dcl 141 ref 189 203 min builtin function dcl 111 ref 834 mode 76 based fixed bin(2,0) array level 2 dcl 1-18 ref 700 706 821 826 most_consec_mark 42 based fixed bin(35,0) level 4 dcl 2-10 set ref 201* 558 558* ndt_list 105 based structure array level 2 dcl 2-10 set ref 640 ndt_offsetx 65 based fixed bin(17,0) level 3 dcl 2-10 set ref 510 659* ndtrans 0(03) based bit(1) level 4 packed unaligned dcl 2-10 set ref 510 657* 743* 848* new_val_level 000124 automatic fixed bin(17,0) dcl 80 set ref 265* 266* no_block 36 based fixed bin(35,0) level 4 dcl 2-10 set ref 197* 496* 496 number_ios 34 based fixed bin(35,0) level 4 dcl 2-10 set ref 190 192 876* 876 offset 2 based fixed bin(18,0) level 2 dcl 3-7 ref 509 op_count 000125 automatic fixed bin(17,0) dcl 81 set ref 510* 512* 514* 527 528* 528 544 562 568* 571 572* 572 617 639* 640 646 684* 685 730 750 775* 776 794 802 811 pf_code 000141 automatic fixed bin(35,0) dcl 88 set ref 189* 203* pfs 000140 automatic fixed bin(35,0) dcl 88 set ref 189* 202* 203* 204* process_id 5 based bit(36) level 3 dcl 2-10 set ref 416* 432* ptr builtin function dcl 111 ref 621 624 733 823 rcp_$promote 000054 constant entry external dcl 135 ref 266 rcp_id 2 based bit(36) level 3 dcl 2-10 set ref 266* read_idcws 71 based bit(36) array level 3 dcl 2-10 set ref 601 706 826 read_start 50 based fixed bin(17,0) level 3 dcl 2-10 set ref 596 614 705* 789* reading 0(04) based bit(1) level 4 packed unaligned dcl 2-10 set ref 533 560 656* 699* 704* 785* 788* rel 0(35) based bit(1) level 2 in structure "tdcw" packed unaligned dcl 6-14 in procedure "tdcm_" set ref 727* rel builtin function dcl 111 in procedure "tdcm_" ref 718 725 833 rw_list 117 based structure array level 2 dcl 2-10 set ref 172 319 563 713 751 rw_offsetx 66 based fixed bin(17,0) level 3 dcl 2-10 set ref 514 611 613 746 761 850* saved_alarm_channel 000274 automatic fixed bin(71,0) dcl 958 set ref 991* 997* saved_alarm_time 000276 automatic fixed bin(71,0) dcl 959 set ref 991* 997* saved_mask 000302 automatic bit(36) dcl 961 set ref 984* 985 special_echan 16 based fixed bin(71,0) level 3 dcl 2-10 set ref 227* 229 special_flag 000131 automatic bit(1) dcl 84 set ref 428* 432 special_status_word 000132 automatic bit(36) dcl 85 set ref 428* st based bit(1) level 3 in structure "istat" packed unaligned dcl 3-7 in procedure "tdcm_" set ref 395 405* 500 507* st 150 based bit(1) array level 4 in structure "ws" packed unaligned dcl 2-10 in procedure "tdcm_" set ref 671 statp 000146 automatic pointer dcl 4-5 set ref 508* 522 545 545 601 601 607 607 609 statq 150 based structure array level 2 dcl 2-10 set ref 394 400 498 503 statqx 4 based fixed bin(17,0) level 3 dcl 2-10 set ref 394 400 400* 403* 403 498 503 503* 505* 505 671 status based structure level 1 dcl 4-7 string builtin function dcl 111 set ref 717* 832* sub 0(06) based bit(6) level 2 packed unaligned dcl 4-7 ref 601 607 subset_size 45 based fixed bin(17,0) level 3 dcl 2-10 set ref 172* 339 527 528 529 571 572 574 685 692 693 694 750 776 substr builtin function dcl 111 ref 709 709 977 985 sync 7 based fixed bin(1,0) level 2 dcl 1-18 set ref 376 1013* tally 0(24) based bit(12) level 2 in structure "dcw" packed unaligned dcl 6-7 in procedure "tdcm_" set ref 719* 835* tally 1(24) based bit(12) level 2 in structure "status" packed unaligned dcl 4-7 in procedure "tdcm_" ref 609 tbuf_num 000126 automatic fixed bin(17,0) dcl 82 set ref 594* 596* 624 625* 625 691* 692 700 705 706 712 732 733 735* 735 782* 789 803 821 823 826 843* 843 tdcm_$tdcm_iocall 000114 constant entry external dcl 1011 ref 1019 tdcm_$tdcm_reset_signal 000056 constant entry external dcl 136 ref 187 tdcm_attach_ 000060 constant entry external dcl 138 ref 162 tdcm_detach_ 000062 constant entry external dcl 139 ref 207 tdcm_message_ 000064 constant entry external dcl 140 ref 174 tdcw based structure level 1 dcl 6-14 tdcwp 000154 automatic pointer dcl 6-4 set ref 724* 725 726 727 term_ne 41 based fixed bin(35,0) level 4 dcl 2-10 set ref 199* 540* 540 term_st 40 based fixed bin(35,0) level 4 dcl 2-10 set ref 198* 524* 524 this_is_initial_ring 000011 internal static bit(1) dcl 953 set ref 978* 985 time_out 0(03) based bit(1) level 3 packed unaligned dcl 3-7 ref 549 timer_manager_$sleep 000112 constant entry external dcl 972 ref 987 tmr 000121 automatic bit(1) dcl 76 set ref 561* 562 567* tot_data_size 000130 automatic fixed bin(17,0) dcl 83 set ref 801* 804* 804 805 tseg based structure level 1 dcl 1-18 tseg_version_2 constant fixed bin(17,0) initial dcl 1-16 ref 461 tsegp parameter pointer dcl 1-15 set ref 174* 187* 189* 328 356 362 362 362 366 366 370 376 459* 461 468 468 470 536 539 543 544 580 581 614 624 624 639 648 655 684 691 698 700 706 712 731 732 733 733 742 751 754 759 775 782 785 790 803 820 821 823 823 826 847 873 873 1013 1014 1015 1016 1017 1019* type 0(22) based bit(2) level 2 in structure "tdcw" packed unaligned dcl 6-14 in procedure "tdcm_" set ref 726* type 0(22) based bit(2) level 2 in structure "dcw" packed unaligned dcl 6-7 in procedure "tdcm_" set ref 836* user_echan 20 based fixed bin(71,0) level 3 dcl 2-10 set ref 432* version_num based fixed bin(17,0) level 2 dcl 1-18 ref 461 wait_echan 12 based fixed bin(71,0) level 4 dcl 2-10 set ref 416* 890* wait_list 000014 internal static structure level 1 dcl 955 in procedure "WAIT_FOR_A_MOMENT" set ref 995 995 wait_list 10 based structure level 3 in structure "ws" dcl 2-10 in procedure "tdcm_" set ref 487 487 wbuf_num 000127 automatic fixed bin(17,0) dcl 82 set ref 693* 697* 730 730 746 761 wbuf_ptr 000112 automatic pointer dcl 69 set ref 621* 624 690* 694* 694 718 720* 720 723* 733 734* 734 781* 823 833 839* 839 write_idcws 77 based bit(36) array level 3 dcl 2-10 ref 700 821 write_sw 6 based fixed bin(1,0) level 2 dcl 1-18 ref 698 731 785 820 ws based structure level 1 dcl 2-10 ws_info based structure level 1 dcl 2-23 ws_ptr 000142 automatic pointer dcl 2-8 set ref 172 172 174* 185 190 191 192 192 194 195 196 197 198 199 200 201 203* 207* 227 227 227 229 229 248 248 248 250 250 266 284 290 307 318 319 321 333 339 339 341 358 358 372 392* 394 394 400 400 400 403 403 416 416 428 432 432 468* 470* 485 485 487 487 496 496 498 498 503 503 503 505 505 510 510 512 514 524 524 526 527 528 529 529 531 532 533 540 540 545 545 555 555 557 557 558 558 558 558 560 563 565 571 572 574 574 577 594 594 596 598 601 601 611 611 611 613 614 617 617 619 620 621 640 647 656 657 659 662 671 671 685 690 692 693 694 699 700 704 705 706 709 711 713 714 716 721 723 724 725 737 743 745 746 747 750 751 751 754 759 761 762 776 781 785 788 789 790 793 805 816 817 819 821 826 827 830 848 850 851 862 862 862 866 867 868 868 869 869 871 871 873 873 876 876 890 919 ws_segno 11 based bit(18) level 2 dcl 1-18 ref 468 470 NAMES DECLARED BY DECLARE STATEMENT AND NEVER REFERENCED. ck_level automatic fixed bin(3,0) dcl 77 faultword based structure level 1 dcl 4-27 get_lock_id_ 000000 constant entry external dcl 964 imess based structure level 1 dcl 3-21 imp automatic pointer dcl 3-19 max_rec_size internal static fixed bin(17,0) initial dcl 1-10 nbuffs internal static fixed bin(17,0) initial dcl 1-10 pcw based structure level 1 dcl 5-6 pcwp automatic pointer dcl 5-4 special_status based structure level 1 dcl 4-35 sqx automatic fixed bin(17,0) dcl 78 NAMES DECLARED BY EXPLICIT CONTEXT. CHECK_STATUS 003327 constant entry internal dcl 884 ref 358 362 758 CK_STATQ 002464 constant entry internal dcl 668 ref 887 896 GET_SPECIAL_STATUS 001603 constant label dcl 428 ref 395 407 INTERNAL_PROC_RETURN 001647 constant label dcl 443 ref 463 490 551 643 660 687 778 796 809 814 894 924 928 999 IOCALL_LOOP 001453 constant label dcl 358 ref 376 IOCALL_RETURN 001520 constant label dcl 379 ref 366 MARKER_READ_WRITE 002501 constant entry internal dcl 677 ref 372 METER_IO 003256 constant entry internal dcl 857 ref 729 800 NON_DATA_TRANSFER 002373 constant entry internal dcl 630 ref 370 PROCESS_INPUT 002212 constant entry internal dcl 585 ref 533 578 PROCESS_QUEUE 001740 constant entry internal dcl 494 ref 887 896 PROC_QUEUE 001746 constant label dcl 498 ref 492 READ_WRITE 003010 constant entry internal dcl 768 ref 374 REWIND_TAPE 003633 constant entry internal dcl 1006 ref 186 SETUP 001652 constant entry internal dcl 451 ref 171 183 225 246 263 282 303 331 354 SLEVEL 000000 constant label array(7) dcl 400 ref 398 TRY_AGAIN_TO_CONNECT 003377 constant label dcl 919 ref 934 TRY_TO_CONNECT 003374 constant entry internal dcl 903 ref 659 746 761 850 WAIT_FOR_A_MOMENT 003430 constant entry internal dcl 939 ref 932 WAIT_FOR_STATUS 001700 constant entry internal dcl 474 ref 898 WAIT_LOOP 001701 constant label dcl 485 ref 500 517 WLEVEL 000007 constant label array(7) dcl 517 ref 515 special_handler 001526 constant entry external dcl 383 tdcm_ 000313 constant entry external dcl 12 tdcm_attach 000325 constant entry external dcl 156 tdcm_detach 000434 constant entry external dcl 180 tdcm_get_buf_size 001373 constant entry external dcl 328 tdcm_iocall 001436 constant entry external dcl 345 tdcm_message 000354 constant entry external dcl 168 tdcm_promote 001223 constant entry external dcl 255 tdcm_reset_signal 001160 constant entry external dcl 238 tdcm_set_buf_size 001325 constant entry external dcl 295 tdcm_set_disposition 001262 constant entry external dcl 275 tdcm_set_signal 001117 constant entry external dcl 210 NAME DECLARED BY CONTEXT OR IMPLICATION. float builtin function ref 192 194 195 STORAGE REQUIREMENTS FOR THIS PROGRAM. Object Text Link Symbol Defs Static Start 0 0 4376 4514 3706 4406 Length 5106 3706 116 355 467 10 BLOCK NAME STACK SIZE TYPE WHY NONQUICK/WHO SHARES STACK FRAME tdcm_ 312 external procedure is an external procedure. SETUP internal procedure shares stack frame of external procedure tdcm_. WAIT_FOR_STATUS internal procedure shares stack frame of external procedure tdcm_. PROCESS_INPUT internal procedure shares stack frame of external procedure tdcm_. NON_DATA_TRANSFER internal procedure shares stack frame of external procedure tdcm_. CK_STATQ internal procedure shares stack frame of external procedure tdcm_. MARKER_READ_WRITE internal procedure shares stack frame of external procedure tdcm_. READ_WRITE internal procedure shares stack frame of external procedure tdcm_. METER_IO internal procedure shares stack frame of external procedure tdcm_. CHECK_STATUS internal procedure shares stack frame of external procedure tdcm_. TRY_TO_CONNECT internal procedure shares stack frame of external procedure tdcm_. WAIT_FOR_A_MOMENT internal procedure shares stack frame of external procedure tdcm_. REWIND_TAPE internal procedure shares stack frame of external procedure tdcm_. STORAGE FOR INTERNAL STATIC VARIABLES. LOC IDENTIFIER BLOCK NAME 000010 initialized_for_waiting WAIT_FOR_A_MOMENT 000011 this_is_initial_ring WAIT_FOR_A_MOMENT 000012 alrm_mask WAIT_FOR_A_MOMENT 000014 wait_list WAIT_FOR_A_MOMENT STORAGE FOR AUTOMATIC VARIABLES. STACK FRAME LOC IDENTIFIER BLOCK NAME tdcm_ 000100 event_data tdcm_ 000110 call_data_ptr tdcm_ 000112 wbuf_ptr tdcm_ 000114 buf_size tdcm_ 000115 data_size tdcm_ 000116 dcw_tally tdcm_ 000117 ecode tdcm_ 000120 fix tdcm_ 000121 tmr tdcm_ 000122 i tdcm_ 000123 listx tdcm_ 000124 new_val_level tdcm_ 000125 op_count tdcm_ 000126 tbuf_num tdcm_ 000127 wbuf_num tdcm_ 000130 tot_data_size tdcm_ 000131 special_flag tdcm_ 000132 special_status_word tdcm_ 000133 data_idcw tdcm_ 000134 io_time tdcm_ 000136 delta tdcm_ 000140 pfs tdcm_ 000141 pf_code tdcm_ 000142 ws_ptr tdcm_ 000144 isp tdcm_ 000146 statp tdcm_ 000150 idcwp tdcm_ 000152 dcwp tdcm_ 000154 tdcwp tdcm_ 000264 connect_retries TRY_TO_CONNECT 000274 saved_alarm_channel WAIT_FOR_A_MOMENT 000276 saved_alarm_time WAIT_FOR_A_MOMENT 000300 ignore_message WAIT_FOR_A_MOMENT 000302 saved_mask WAIT_FOR_A_MOMENT THE FOLLOWING EXTERNAL OPERATORS ARE USED BY THIS PROGRAM. r_e_as call_ext_out_desc call_ext_out return ext_entry ext_entry_desc divide_fx3 clock THE FOLLOWING EXTERNAL ENTRIES ARE CALLED BY THIS PROGRAM. convert_ipc_code_ create_ips_mask_ get_initial_ring_ get_ring_ hcs_$get_alarm_timer hcs_$get_ips_mask hcs_$set_alarm_timer hcs_$wakeup ioa_ ioi_$connect ioi_$get_special_status ioi_$set_event ipc_$block ipc_$block ipc_$create_ev_chn ipc_$drain_chn mhcs_$get_seg_usage_ptr rcp_$promote tdcm_$tdcm_iocall tdcm_$tdcm_reset_signal tdcm_attach_ tdcm_detach_ tdcm_message_ timer_manager_$sleep THE FOLLOWING EXTERNAL VARIABLES ARE USED BY THIS PROGRAM. error_table_$bad_arg error_table_$buffer_big error_table_$invalid_state error_table_$net_timeout error_table_$out_of_main_memory error_table_$too_many_buffers error_table_$unimplemented_version LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC 12 000312 156 000320 162 000335 163 000346 168 000347 171 000372 172 000373 174 000377 175 000431 180 000432 183 000444 185 000445 186 000450 187 000451 188 000463 189 000465 190 000501 191 000526 192 000547 194 000602 195 000632 196 000662 197 000703 198 000724 199 000745 200 000766 201 001007 202 001030 203 001050 204 001063 207 001103 208 001114 210 001115 225 001127 227 001130 229 001150 231 001153 232 001155 238 001156 246 001170 248 001171 250 001211 252 001214 253 001216 255 001217 263 001233 265 001234 266 001237 268 001253 269 001255 275 001256 282 001300 284 001301 286 001304 287 001307 290 001310 292 001320 293 001322 295 001323 303 001335 305 001336 307 001341 308 001344 309 001347 312 001350 313 001352 315 001355 317 001356 318 001360 319 001362 321 001365 323 001367 324 001370 328 001371 331 001403 333 001404 334 001407 335 001411 336 001414 339 001415 341 001426 342 001432 343 001433 345 001434 354 001446 356 001447 358 001453 362 001463 366 001473 370 001501 372 001505 374 001512 376 001513 379 001520 381 001522 383 001523 391 001533 392 001537 394 001541 395 001545 398 001550 400 001552 403 001560 405 001561 407 001563 416 001564 428 001603 430 001621 432 001623 434 001646 443 001647 445 001651 451 001652 459 001653 461 001657 462 001662 463 001665 466 001666 468 001667 470 001674 472 001677 474 001700 485 001701 487 001706 488 001725 489 001727 490 001736 492 001737 494 001740 496 001741 498 001746 500 001753 503 001756 505 001764 507 001765 508 001767 509 001771 510 001773 512 002002 514 002010 515 002014 517 002016 520 002017 522 002022 524 002024 526 002030 527 002031 528 002034 529 002036 530 002040 531 002041 532 002042 533 002044 536 002050 538 002056 539 002061 540 002063 541 002070 543 002071 544 002073 545 002075 549 002107 551 002115 553 002116 555 002117 557 002123 558 002127 560 002132 561 002135 562 002136 563 002142 565 002146 566 002152 567 002157 568 002161 570 002163 571 002166 572 002172 574 002174 576 002176 577 002177 578 002200 580 002201 581 002207 583 002211 585 002212 594 002213 596 002223 598 002226 600 002231 601 002232 606 002263 607 002264 609 002275 611 002301 613 002316 614 002321 617 002326 619 002337 620 002342 621 002346 624 002354 625 002367 626 002370 628 002372 630 002373 639 002374 640 002401 642 002403 643 002406 646 002407 647 002415 648 002420 650 002430 651 002434 653 002436 655 002440 656 002444 657 002446 659 002450 660 002457 662 002461 664 002463 668 002464 671 002466 673 002477 677 002501 684 002502 685 002507 686 002512 687 002515 690 002516 691 002520 692 002523 693 002525 694 002530 696 002534 697 002535 698 002537 699 002541 700 002543 702 002547 704 002550 705 002552 706 002554 709 002557 711 002566 712 002570 713 002573 714 002600 715 002604 716 002606 717 002610 718 002611 719 002614 720 002621 721 002624 722 002626 723 002630 724 002633 725 002635 726 002640 727 002644 729 002646 730 002647 731 002660 732 002665 733 002670 734 002700 735 002703 737 002704 738 002711 739 002715 740 002717 742 002721 743 002725 745 002727 746 002732 747 002742 748 002744 750 002745 751 002751 754 002756 756 002761 758 002763 759 002764 761 002775 762 003005 766 003007 768 003010 775 003011 776 003016 777 003021 778 003024 781 003025 782 003027 785 003032 788 003037 789 003041 790 003043 793 003051 794 003053 795 003056 796 003061 800 003062 801 003063 802 003064 803 003073 804 003101 805 003102 808 003110 809 003113 811 003114 813 003121 814 003124 816 003125 817 003130 819 003132 820 003136 821 003141 823 003144 824 003155 826 003156 827 003161 830 003164 831 003170 832 003172 833 003173 834 003177 835 003203 836 003211 838 003220 839 003223 840 003226 841 003230 843 003231 844 003232 845 003234 847 003236 848 003242 850 003244 851 003253 853 003255 857 003256 860 003257 862 003262 865 003272 866 003274 867 003277 868 003301 869 003304 871 003310 873 003313 876 003322 879 003326 884 003327 887 003330 890 003337 892 003351 893 003353 894 003362 896 003363 898 003372 901 003373 903 003374 917 003376 919 003377 922 003414 924 003417 928 003422 930 003425 932 003426 934 003427 939 003430 975 003431 976 003434 977 003452 978 003460 979 003502 980 003513 981 003516 984 003520 985 003526 987 003536 988 003546 991 003547 993 003557 995 003574 997 003613 999 003630 1003 003632 1006 003633 1013 003634 1014 003641 1015 003642 1016 003643 1017 003645 1019 003647 1021 003660 ----------------------------------------------------------- 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