



		    broadcast_.alm                  11/04/82  1859.6rew 11/04/82  1632.0       10998



" ***********************************************************
" *                                                         *
" * Copyright, (C) Honeywell Information Systems Inc., 1982 *
" *                                                         *
" * Copyright (c) 1972 by Massachusetts Institute of        *
" * Technology and Honeywell Information Systems, Inc.      *
" *                                                         *
" ***********************************************************

"	Outer Module Transfer Vector for the broadcast_ outer module.

	entry	broadcast_module
broadcast_module:
	tra	*+1,6		go to proper transfer instruction

	tra	<broadcaster_>|[broadcast_attach]
	tra	<broadcaster_>|[broadcast_detach]
	tra	<ios_>|[no_entry]
	tra	<broadcaster_>|[broadcast_write]
	tra	<broadcaster_>|[broadcast_abort]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<broadcaster_>|[broadcast_resetwrite]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]
	tra	<ios_>|[no_entry]

	end




		    broadcaster_.pl1                11/04/82  1859.6rew 11/04/82  1612.8       83367



/* ***********************************************************
   *                                                         *
   * Copyright, (C) Honeywell Information Systems Inc., 1982 *
   *                                                         *
   * Copyright (c) 1972 by Massachusetts Institute of        *
   * Technology and Honeywell Information Systems, Inc.      *
   *                                                         *
   *********************************************************** */


/*	This DIM serves to allow I/O operations to fan out. A single
	stream may be attached to several streams by the braodcast
	module.

	Originally coded by R. J. Feiertag on June 10,1971.

	declare ios_$attach ext entry(char(*),char(*),char(*),char(*),bit(72) aligned);
	call ios_$attach(stream,"broadcast_",object_stream1,"",status);
	call ios_$attach(stream,"broadcast_",object_stream2,"",status);
					.
					.
					.
					.
	call ios_$attach(stream,"broadcast_",object_streamn,"",status);

	All the object streams will be attached to stream and all I/O calls
	 on stream will result in identical calls to all the object streams.
*/

broadcaster_$broadcast_attach: proc(stream,type,object_stream,mode,status,sdb_ptr);

	dcl stream char(*), /* stream being attached to */
	    type char(*), /* name of broadcaster */
	    object_stream char(*), /* stream being attached */
	    mode char(*), /* mode of attachment */
	    status bit(72) aligned, /* status of call */
	    sdb_ptr ptr, /* pointer to sdb */
	    sp ptr, /* points to status */
	    i fixed bin, /* index */
	    next_list ptr, /* points to block of sdb entries */
	    stream_found bit(1), /* indicates a stream has been found */
	    last_dev ptr, /* points to previous device name entry */
	    next_dev ptr, /* points to current device name entry */
	    entry_size fixed bin internal static init(-12),
	    area_ptr ptr internal static init(null), /* pointer to area for allocation */
	    space area based(area_ptr), /* area for allocation */
	    bstatus bit(72) aligned; /* status for call outs */

	dcl 1 status_structure aligned based(sp), /* structure of status string */
		2 error_code fixed bin, /* error code */
		2 pad1 bit(15) unaligned,
		2 detach bit(1) unaligned, /* indicates if stream is to be detached */
		2 pad2 bit(20) unaligned;

	dcl 1 sdb aligned based(sdb_ptr), /* stream data block */
		2 dim_name char(32), /* name of this dim */
		2 device_name_list ptr, /* points to threaded list of device names */
		2 name_list(5) aligned, /* array of device name entries */
		     3 next_device ptr, /* points to next device name entry */
		     3 name_size fixed bin, /* number of chars in device name */
		     3 name char(32), /* name of device */
		     3 index fixed bin, /* index in block of entries */
		2 next ptr, /* points to next block of entries */
		2 last ptr; /* points to last block of entries */

	dcl 1 sdbi aligned based(next_list), /* a block of device name entries */
		2 name_list(5) aligned,
		     3 next_device ptr,
		     3 name_size fixed bin,
		     3 name char(32),
		     3 index fixed bin,
		2 next ptr,
		2 last ptr;

	dcl 1 ne aligned based(next_dev), /* a device name entry */
		2 next_device ptr,
		2 name_size fixed bin,
		2 name char(32),
		2 index fixed bin;

	dcl (error_table_$no_room_for_dsb,error_table_$ioname_not_found) ext fixed bin; /* error codes */

	dcl ios_$write ext entry(char(*) aligned,ptr,fixed bin,fixed bin,fixed bin,bit(72) aligned),
	    ios_$abort ext entry(char(*) aligned,bit(72) aligned,bit(72) aligned),
	    ios_$resetwrite ext entry(char(*) aligned,bit(72) aligned),
              get_system_free_area_ entry () returns (ptr);

	dcl (addr,null,addrel) builtin;
/**/
	status = "0"b;
	if area_ptr = null then area_ptr = get_system_free_area_ (); /* get pointer to area */
	sp = addr(status); /* get pointer to status */
	if sdb_ptr = null then do; /* new stream */
		allocate sdb set(sdb_ptr); /* create an sdb */
		if sdb_ptr = null then do; /* could not allocate sdb */
			sp->status_structure.detach = "1"b; /* stream not attached */
alloc_err:		sp->status_structure.error_code = error_table_$no_room_for_dsb;
			return;
			end;
		sdb.dim_name = "broadcast_"; /* initialize sdb */
		sdb.device_name_list = null;
		sdb.next = null;
		sdb.last = null;
		do i = 1 to 5; /* initialize device name entries */
			sdb.name_list(i).name_size = 0; /* indicates entry is empty */
			end;
		end;
	next_list = addr(sdb.name_list(1)); /* get first block of entries */
try_again:
	do i = 1 to 5; /* look at each entry in block */
		if sdbi.name_list(i).name_size = 0 then do; /* have found empty entry */
			sdbi.name_list(i).name_size = 32; /* fill in entry */
			sdbi.name_list(i).name = object_stream;
			sdbi.name_list(i).index = i;
			sdbi.name_list(i).next_device = sdb.device_name_list; /* thread in entry */
			sdb.device_name_list = addr(sdbi.name_list(i));
			return;
			end;
		end;
	if sdbi.next = null then do; /* there are no free entries, so create some */
		allocate sdbi set(sdbi.next); /* create a new block of entries */
		sdbi.next->sdbi.last = next_list; /* back thread this entry */
		next_list = sdbi.next; /* go to this new entry */
		if next_list = null then go to alloc_err; /* cannot allocate more entries */
		do i = 1 to 5; /* initialize new entries */
			sdbi.name_list(i).name_size = 0;
			end;
		sdbi.next = null; /* this is last block */
		end;
	 else next_list = sdbi.next; /* get next block */
	go to try_again; /* look through the new block */
/**/
broadcast_detach: entry(sdb_ptr,object_stream,disposal,status);

	dcl disposal char(*); /* special action to be taken */

	status = "0"b;
	sp = addr(status); /* get pointer to status */
	last_dev = null; /* no previous device yet */
	next_dev = sdb.device_name_list; /* start at first entry */
	stream_found = "0"b; /* no entry found yet */
	do while(next_dev ^= null); /* look through all entries */
		if (object_stream = "") | (object_stream = ne.name) then do; /* have found stream */
			stream_found = "1"b; /* remember stream is found */
			if last_dev = null then if ne.next_device = null then do; /* this is only entry */
				if sdb.next ^= null then free sdb.next->sdbi;
					/* free extra block if one exists */
				free sdb; /* free sdb */
				sp->status_structure.detach = "1"b; /* detach the stream */
				return;
				end;
			 else sdb.device_name_list = ne.next_device; /* new first entry */
			 else last_dev->ne.next_device = ne.next_device; /* thread out entry */
			ne.name_size = 0; /* indicate entry is free */
			next_list = addrel(next_dev,ne.index*entry_size); /* get pointer to beginning
									of block */
			next_dev = ne.next_device; /* move to next device */
			if sdbi.last ^= null then do; /* if not sdb itself the try to free */
				do i = 1 to 5 while(sdbi.name_list(i).name_size = 0);
					end; /* find first non-free entry */
				if i = 6 then do; /* all entries in block are free */
					sdbi.last->sdbi.next = sdbi.next; /* unthread forward list */
					if sdbi.next ^= null then sdbi.next->sdbi.last = sdbi.last;
						/* unthread from backward list */
					free sdbi;
					end;
				end;
			end;
		else do; /* entry not correct one */
			last_dev = next_dev; /* move to next entry */
			next_dev = ne.next_device;
			end;
		end;
	if ^stream_found then sp->status_structure.error_code = error_table_$ioname_not_found; /* stream not found */
	return;
/**/
broadcast_write: entry(sdb_ptr,workspace,offset,nelem,nelemt,status);

	dcl workspace ptr, /* points to caller's buffer area */
	    offset fixed bin, /* offset at which to begin writing from */
	    nelem fixed bin, /* number of elements to write */
	    nelemt fixed bin; /* number of elements written */

	status = "0"b;
	sp = addr(status); /* get pointer to status */
	next_dev = sdb.device_name_list; /* get pointer to first entry */
	nelemt = nelem; /* maximum possible number of elements written */
	do while(next_dev ^= null); /* do a write for each entry */
		call ios_$write(ne.name,workspace,offset,nelem,i,bstatus); /* write on this stream */
		nelemt = min(nelemt,i); /* return minimum elements written */
		if sp->status_structure.error_code = 0 then status = bstatus; /* return status */
		next_dev = ne.next_device; /* go to next stream */
		end;
	return;
/**/
broadcast_abort:	entry(sdb_ptr,old_status,status);

	dcl old_status bit(72) aligned; /* status from previous transaction */

	status = "0"b;
	sp = addr(status);
	next_dev = sdb.device_name_list; /* get pointer to list of stream names */
	do while(next_dev ^= null); /* make one call for each stream */
		call ios_$abort(ne.name,old_status,bstatus); /* abort this stream */
		if sp->status_structure.error_code = 0 then status = bstatus; /* return bad status */
		next_dev = ne.next_device; /* go to next stream */
		end;
	return;
/**/
broadcast_resetwrite:	entry(sdb_ptr,status);

	status = "0"b;
	sp = addr(status);
	next_dev = sdb.device_name_list; /* get pointer to list of stream names */
	do while(next_dev ^= null); /* make one call for each stream */
		call ios_$resetwrite(ne.name,bstatus);
		if sp->status_structure.error_code = 0 then status = bstatus; /* return status */
		next_dev = ne.next_device; /* go to next stream */
		end;
	return;
	end;




		    discard_output_.alm             11/04/82  1859.6rew 11/04/82  1632.1       19728



" ***********************************************************
" *                                                         *
" * Copyright, (C) Honeywell Information Systems Inc., 1982 *
" *                                                         *
" * Copyright (c) 1972 by Massachusetts Institute of        *
" * Technology and Honeywell Information Systems, Inc.      *
" *                                                         *
" ***********************************************************

"	Interface Module Transfer Vector for the discard_output_ interface module.

	entry	discard_output_module
discard_output_module:
	tra	*+1,6		go to proper transfer instruction

	tra	<discard_output_util_>|[discard_output_attach]
	tra	<discard_output_util_>|[discard_output_detach]
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<discard_output_util_>|[discard_output_write]
	tra	<discard_output_util_>|[discard_output_abort]
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<discard_output_util_>|[discard_output_resetwrite]
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry] this entry not implemented
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused
	tra	<ios_>|[no_entry]	this slot currently unused

	end




		    discard_output_util_.pl1        11/04/82  1859.6rew 11/04/82  1612.8       31482



/* ***********************************************************
   *                                                         *
   * Copyright, (C) Honeywell Information Systems Inc., 1982 *
   *                                                         *
   * Copyright (c) 1972 by Massachusetts Institute of        *
   * Technology and Honeywell Information Systems, Inc.      *
   *                                                         *
   *********************************************************** */


	/* This procedure is a I/O System Interface Module that simply ignores calls
		made to it. All output written to this DIM is discarded.

	   Originally coded by R. J. Feiertag on September 24, 1971			*/

discard_output_util_$discard_output_attach: proc(stream_name,type,device,mode,status,sdb_ptr);

	dcl stream_name char(*), /* name of stream to which this DIM is attached */
	    type char(*), /* name of this DIM */
	    device char(*), /* name of device, must be "" */
	    mode char(*), /* mode of attachment, should be "" */
	    status bit(72) aligned, /* status of call */
	    sp ptr, /* points to status */
	    sdb_ptr ptr; /* pointer to stream data block */

	dcl 1 status_structure aligned based(sp), /* structure of status string */
		2 error_code fixed bin, /* standard error code */
		2 pad15 bit(15) unaligned,
		2 detach bit(1) unaligned, /* 1 indicates stream should be detached */
		2 pad20 bit(20) unaligned;

	dcl 1 sdb internal static aligned, /* stream data block */
		2 interface_module_name char(32) init("discard_output_"), /* name of IOSIM */
		2 device_list ptr init(null), /* pointer to threaded list of device names */
		2 next_device ptr init(null), /* points to next entry on device name list */
		2 name_length fixed bin init(0); /* length of device name is zero */

	dcl (error_table_$ionmat,error_table_$invalid_device) ext fixed bin;

	dcl (addr,null) builtin;

	sp = addr(status); /* get pointer to status */
	if sdb_ptr ^= null then do; /* attempt to perform multiple attachment */
		error_code = error_table_$ionmat; /* return error code */
		detach = "1"b; /* unsuccessfull attachment */
		end;
	 else if device ^= "" then do; /* invalid device id */
		error_code = error_table_$invalid_device; /* return error code */
		detach = "1"b; /* unsuccessful attachment */
		end;
	  else sdb_ptr = addr(sdb); /* return pointer to sdb */
	if sdb.device_list = null then sdb.device_list = addr(sdb.next_device); /* construct valid sdb */
	return;

discard_output_write: entry(sdb_ptr,workspace,offset,nelem,nelemt,status);

	dcl workspace ptr, /* points to user buffer area */
	    offset fixed bin, /* indicates first element to be written */
	    nelem fixed bin, /* indicates number of elements to be written */
	    nelemt fixed bin; /* indicates number of elements actually written */

	nelemt = nelem; /* pretend wrote out all elements asked for */
	return;

discard_output_abort: entry(sdb_ptr,old_status,status);

	dcl old_status bit(72) aligned; /* status from previous transaction */

	return; /* don't do anything */

discard_output_resetwrite: entry(sdb_ptr,status);

	return;

discard_output_detach: entry(sdb_ptr,device,disposal,status);

	dcl disposal char(*); /* indicates special action to be taken, should be "" */

	sp = addr(status); /* get pointer to status string */
	if device ^= "" then error_code = error_table_$invalid_device; /* return error code */
	 else detach = "1"b; /* otherwise stream should be detached */
	return;
	end;





		    bull_copyright_notice.txt       08/30/05  1008.4r   08/30/05  1007.3    00020025

                                          -----------------------------------------------------------


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
