/* ****************************************************** * * * * * Copyright (c) 1979 by the University of Calgary * * * * * * * ****************************************************** */ /* printronix_: An I/O module for communicating with a printronix or la120 printer. */ /* Adapted November 1979 by T. Oke */ printronix_: proc; la120_: entry; /* Parameters */ dcl a_iocbp ptr; dcl a_option (*) char (*) var; /* Options for attach */ dcl a_sw bit (1); /* com_err_ switch for attach */ dcl a_code fixed bin (35); dcl a_mode fixed bin; /* The open mode */ dcl a_data_ptr ptr; dcl a_data_chars fixed bin (21); dcl a_pos_type fixed bin; dcl a_pos_value fixed bin (21); dcl a_order char (*); dcl a_infop ptr; dcl (new_mode, old_mode) char (*); /* Automatic */ dcl com_err_sw bit (1); /* Set if com_err_ sould be called on attach error */ dcl ptr_array (1) ptr; /* For allocating temp segment */ dcl attach_tag picture "99"; dcl code fixed bin (35); dcl iocbp ptr; dcl mask bit (36) aligned; /* For setting ips mask */ dcl i fixed bin (21); dcl open_mode fixed bin; dcl device_type fixed bin; dcl module_type fixed bin; dcl device char (32); dcl order char (32); dcl infop ptr; dcl tty_attach_name char (32) var; dcl tty_attach_desc char (256) var; dcl attach_desc char (256) var; dcl tty char (32) var static; dcl tty_modes char (256); dcl 1 set_term_type_info aligned, 2 version fixed bin, 2 name char (32) unaligned, 2 flags, 3 initial_string bit (1) unaligned, 3 modes bit (1) unaligned, 3 ignore_line_type bit (1) unaligned, 3 mbz bit (33)unaligned; dcl 1 delay aligned, 2 version fixed bin, 2 default fixed bin, 2 vert_nl fixed bin, 2 horz_nl float bin, 2 const_tab fixed bin, 2 var_tab float bin, 2 backspace fixed bin, 2 vt_ff fixed bin; /* Internal static */ /* ..... the next six variables should be per tty attachment rather than int static */ dcl printer_module fixed bin int static options (constant) init (1); dcl plotter_module fixed bin int static options (constant) init (2); dcl devices (4) char (32) static init ("reader", "printer", "teleprinter", "punch"); dcl tty_iocb ptr int static init (null); dcl attach_count fixed bin init (0) int static; dcl tty_open bit (1) int static init ("0"b); /* Constants */ dcl terminal_device_name char (11) int static init ("printronix_"); dcl space char (1) static int init (" ") options (constant); /* External stuff */ dcl requote_string_ entry (char (*)) returns (char (*)); dcl continue_to_signal_ entry (fixed bin (35)); dcl get_temp_segments_ entry (char (*), dim (*) ptr, fixed bin (35)); dcl release_temp_segments_ entry (char (*), dim (*) ptr, fixed bin (35)); dcl hcs_$reset_ips_mask entry (bit (36) aligned, bit (36) aligned); dcl hcs_$set_ips_mask entry (bit (36) aligned, bit (36) aligned); dcl ioa_ entry options (variable); dcl iox_$propagate entry (ptr); dcl iox_$position entry (ptr, fixed bin, fixed bin (21), fixed bin (35)); dcl com_err_ entry options (variable); dcl iox_$close entry (ptr, fixed bin (35)); dcl iox_$open entry (ptr, fixed bin, bit (36), fixed bin (35)); dcl iox_$modes entry (ptr, char (*), char (*), fixed bin (35)); dcl iox_$put_chars entry (ptr, ptr, fixed bin (21), fixed bin (35)); dcl iox_$control entry (ptr, char (*), ptr, fixed bin (35)); dcl iox_$err_no_operation entry; dcl attach_tty_$attach_chan entry (char (*), ptr, char (*), bit (1) aligned, fixed bin (35)); dcl attach_tty_$detach_chan entry (ptr, fixed bin (35)); dcl attach_tty_$hangup_proc entry (ptr, fixed bin (35)); dcl (addr, bin, hbound, length, min, null, substr, rtrim) builtin; dcl sys_info$max_seg_size fixed bin ext; dcl error_table_$no_operation fixed bin (35) ext; dcl error_table_$bad_arg ext fixed bin (35); dcl error_table_$bad_mode ext fixed bin (35); dcl error_table_$wrong_no_of_args ext fixed bin (35); dcl error_table_$noarg ext fixed bin (35); dcl error_table_$ionmat ext fixed bin (35); dcl error_table_$badopt ext fixed bin (35); dcl any_other condition; dcl adp ptr; dcl 1 ad aligned based (adp), 2 attach_description char (256) var, 2 open_description char (32) var, 2 device char (32), 2 module_type fixed bin, 2 device_type fixed bin; /* specific global information for UofC mods. 79-08-08. */ dcl print char (400) varying static; /* space to hold line ended in CR. */ dcl 01 pr_line based (addr (print)), 02 pr_length fixed bin (35), 02 pr_print char (400); dcl la120 bit (1) static initial ("0"b); /* indicates if running as la120 or printronix. */ dcl printronix_initial_string char (1) var static options (constant) initial ( " "), la120_initial_string char (146) var static options (constant) initial ( " 2 "); dcl 01 printronix_init based (addr (printronix_initial_string)), 02 printronix_len fixed bin (35), 02 printronix_initial char (1); dcl 01 la120_init based (addr (la120_initial_string)), 02 la120_len fixed bin (35), 02 la120_initial char (146); /* Printronix_initial_string simply form feeds to keep paper positioning. La120_initial_string form feeds to keep position, changes to the US char set, sets newline->CR, sets 10 pitch, sets margins as 1,132, clears tabs, sets tabs every 10, sets 8 lpi, sets forms length as 88 lines per page, sets vertical margins at 1,88 lines, and sets the vertical tabs every 10. */ %include iocb; %include iox_modes; %include io_call_info; /* Attach entry point */ printronix_attach: entry (a_iocbp, a_option, a_sw, a_code); la120 = "0"b; /* initialize as a printronix. */ terminal_device_name = "printronix_"; go to COMMON; la120_attach: entry (a_iocbp, a_option, a_sw, a_code); la120 = "1"b; /* initialize as an la120. */ terminal_device_name = "la120_"; go to COMMON; COMMON: adp = null; iocbp = a_iocbp; com_err_sw = "1"b; /* ALWAYS PRINT ERRORS !!!!!!! */ code, a_code = 0; code = 0; if iocbp -> iocb.attach_descrip_ptr ^= null then do; code = error_table_$ionmat; call abort_attach ("Already attached", ""); end; if hbound (a_option, 1) < 1 then do; code = error_table_$wrong_no_of_args; call abort_attach ("No attach description", ""); end; attach_desc = "printronix_"; do i = 1 to hbound (a_option, 1); if a_option (i) = "-device" then do; attach_desc = attach_desc || space || requote_string_ ((a_option (i))); device = get_arg (); end; else if a_option (i) = "-tty" then do; attach_desc = attach_desc || space || requote_string_ ((a_option (i))); tty = get_arg (); end; else attach_desc = attach_desc || space || requote_string_ ((a_option (i))); end; tty_attach_desc = "tty_" || space || tty; attach_tag = attach_count; tty_attach_name = rtrim (terminal_device_name) || attach_tag; attach_count = attach_count + 1; if tty_iocb = null () then do; call attach_tty_$attach_chan ((tty_attach_name), tty_iocb, (tty), "0"b, code); if code ^= 0 then call abort_attach ("Cannot attach tty", (tty)); end; do i = 1 to hbound (devices, 1) while (device ^= devices (i)); end; if i > hbound (devices, 1) then do; code = error_table_$badopt; call abort_attach ("Invalid device specified", (device)); end; else device_type = i; call get_temp_segments_ (terminal_device_name, ptr_array, code); if code ^= 0 then call abort_attach ("Unable to create attach data seg", ""); adp = ptr_array (1); unspec (ad) = "0"b; ad.device_type = device_type; /* record attach type */ ad.module_type = printer_module; /* indicate as printer. */ ad.attach_description = attach_desc; ad.device = device; /* set device device in here also */ mask = "0"b; on any_other call handler; call hcs_$set_ips_mask ("0"b, mask); iocbp -> iocb.attach_descrip_ptr = addr (ad.attach_description); iocbp -> iocb.attach_data_ptr = adp; iocbp -> iocb.open = printronix_open; iocbp -> iocb.detach_iocb = printronix_detach; call iox_$propagate (iocbp); call hcs_$reset_ips_mask (mask, mask); revert any_other; attach_return: return; no_arg: code = error_table_$noarg; call abort_attach ("No argument after ^a.", (a_option (i-1))); /* Detach entry point */ printronix_detach: entry (a_iocbp, a_code); iocbp = a_iocbp; code, a_code = 0; adp = iocbp -> iocb.attach_data_ptr; if tty_iocb ^= null then do; /* call iox_$detach_iocb (tty_iocb, a_code); */ call attach_tty_$detach_chan (tty_iocb, a_code); tty_iocb = null; end; mask = "0"b; on any_other call handler; call hcs_$set_ips_mask ("0"b, mask); iocbp -> iocb.attach_descrip_ptr = null; call iox_$propagate (iocbp); call hcs_$reset_ips_mask (mask, mask); revert any_other; ptr_array (1) = adp; call release_temp_segments_ (terminal_device_name, ptr_array, (0)); return; /* Open entry point */ printronix_open: entry (a_iocbp, a_mode, a_sw, a_code); iocbp = a_iocbp -> iocb.actual_iocb_ptr; code, a_code = 0; adp = iocbp -> iocb.attach_data_ptr; open_mode = a_mode; if ^((open_mode = Stream_output) | (open_mode = Stream_input_output)) then do; bad_mode: a_code = error_table_$bad_mode; return; end; ad.open_description = rtrim (iox_modes (open_mode), space); if ^tty_open & tty_iocb ^= null then do; call iox_$open (tty_iocb, a_mode, "0"b, a_code); if a_code ^= 0 then return; tty_open = "1"b; unspec (set_term_type_info.flags) = "0"b; set_term_type_info.version = 1; if la120 then set_term_type_info.name = "LA120_F"; /* setup as la120 */ else set_term_type_info.name = "LA36"; /* setup as printronix */ set_term_type_info.initial_string = "1"b; set_term_type_info.modes = "1"b; set_term_type_info.ignore_line_type = "0"b; call iox_$control (tty_iocb, "set_term_type", addr (set_term_type_info), a_code); if a_code ^= 0 then return; tty_modes = "rawo"; call iox_$modes (tty_iocb, tty_modes, "", a_code); if a_code ^= 0 then return; delay.version = 1; delay.default = 0; delay.vert_nl = 0; delay.horz_nl = 0; delay.const_tab = 0; delay.var_tab = 0; delay.backspace = 0; delay.vt_ff = 0; call iox_$control (tty_iocb, "set_delay", addr (delay), a_code); if a_code ^= 0 then return; if la120 then call iox_$put_chars (tty_iocb, addr (la120_initial_string), length (la120_initial), code); else call iox_$put_chars (tty_iocb, addr (printronix_initial_string), length (printronix_initial), code); end; mask = "0"b; on any_other call handler; call hcs_$set_ips_mask ("0"b, mask); iocbp -> iocb.put_chars = printronix_put_chars; iocbp -> iocb.control = printronix_control; iocbp -> iocb.modes = printronix_modes; iocbp -> iocb.position = printronix_position; iocbp -> iocb.close = printronix_close; iocbp -> iocb.open_descrip_ptr = addr (ad.open_description); call iox_$propagate (iocbp); call hcs_$reset_ips_mask (mask, mask); revert any_other; if la120 then do; tty_modes = "^rawo"; call iox_$modes (tty_iocb, tty_modes, "", a_code); if a_code ^= 0 then return; end; pr_length = 0; /* clear out UofC stuff */ return; /* Close entry point */ printronix_close: entry (a_iocbp, a_code); iocbp = a_iocbp -> iocb.actual_iocb_ptr; code, a_code = 0; adp = iocbp -> iocb.attach_data_ptr; if tty_iocb ^= null then do; call iox_$close (tty_iocb, a_code); tty_open = "0"b; end; mask = "0"b; on any_other call handler; call hcs_$set_ips_mask ("0"b, mask); iocbp -> iocb.open_descrip_ptr = null; iocbp -> iocb.open = printronix_open; iocbp -> iocb.detach_iocb = printronix_detach; iocbp -> iocb.control = iox_$err_no_operation; iocbp -> iocb.position = iox_$err_no_operation; iocbp -> iocb.modes = iox_$err_no_operation; call iox_$propagate (iocbp); call hcs_$reset_ips_mask (mask, mask); revert any_other; return; /* Put_chars entry point */ printronix_put_chars: entry (a_iocbp, a_data_ptr, a_data_chars, a_code); dcl a_line char (a_data_chars) based (a_data_ptr); dcl last_char char (1) based (addr (substr (a_line, a_data_chars))); /* end of line */ dcl cur_pos fixed bin static, /* delimiter position after current _ */ i_pos fixed bin static, /* processing position in underline fixup */ a_limit fixed bin static, /* limit of 1st line in a_line */ save char (400) varying static, /* save of a_line during underline processing */ 01 save_line based (addr (save)), 02 sv_length fixed bin (35), 02 sv_save char (400); iocbp = a_iocbp -> iocb.actual_iocb_ptr; code, a_code = 0; if tty_iocb = null then do; a_code = error_table_$no_operation; return; end; adp = iocbp -> iocb.attach_data_ptr; if a_data_chars < 0 | a_data_chars > 400 then do; call ioa_ ("Length of print line out of range - ^d", a_data_chars); a_code = error_table_$bad_arg; return; end; /* if we are running as an la120 then simply skip a lot of stuff. */ sv_length = 0; /* kill save */ if la120 then goto sv_continue; /* if a line ends in CR then it will be overprinted and must be saved. Then the print routine can move underlines to the last line of the print. Otherwise they will be overstruck and lost. We can be sent lines with extra slew lfs, on them, which will have to be ignored, when moving underlines. a-limit is the length of the true data line passed in, omitting the post-line-feeds. */ if pr_length > 0 then do; /* need to process overstruck line */ cur_pos = index (print, "_"); if cur_pos ^= 0 then do; /* underlines need to be advanced to latest line */ a_limit = min (a_data_chars, search (a_line, " ")); save = a_line; i_pos = 1; do while (cur_pos>0&i_pos iocb.actual_iocb_ptr; code, a_code = 0; if tty_iocb = null then do; a_code = error_table_$no_operation; return; end; adp = iocbp -> iocb.attach_data_ptr; if code ^= 0 then return; if new_mode = "default" then return; /* THIS IS A NO NO FOR TTY_ */ call iox_$modes (tty_iocb, new_mode, old_mode, a_code); return; /* Control entry point */ printronix_control: entry (a_iocbp, a_order, a_infop, a_code); iocbp = a_iocbp -> iocb.actual_iocb_ptr; adp = iocbp -> iocb.attach_data_ptr; infop = a_infop; order = a_order; code, a_code = 0; if tty_iocb = null then do; code = error_table_$no_operation; go to control_ret; end; if order = "select_device" then do; end; else if order = "paper_info" then do; end; else if order = "hangup_proc" then do; call attach_tty_$hangup_proc (infop, a_code); end; else if order = "runout" then do; end; else if order = "io_call" then call printronix_io_call; else do_control: call iox_$control (tty_iocb, order, infop, code); control_ret: a_code = code; return; /* Position entry point */ printronix_position: entry (a_iocbp, a_pos_type, a_pos_value, a_code); iocbp = a_iocbp -> iocb.actual_iocb_ptr; adp = iocbp -> iocb.attach_data_ptr; code, a_code = 0; if tty_iocb = null then do; a_code = error_table_$no_operation; return; end; call iox_$position (tty_iocb, a_pos_type, a_pos_value, a_code); return; get_arg: proc returns (char (*) var); /* This proc picks up the next arg in the option array */ i = i + 1; if i > hbound (a_option, 1) then goto no_arg; attach_desc = attach_desc || " " || requote_string_ ((a_option (i))); return ((a_option (i))); end get_arg; abort_attach: proc (str1, str2); dcl (str1, str2) char (*) aligned; /* This proc handles attach errors */ if com_err_sw then call com_err_ (code, terminal_device_name, str1, str2); a_code = code; tty_iocb = null; if ptr_array (1) ^= null then call release_temp_segments_ (terminal_device_name, ptr_array, code); go to attach_return; end abort_attach; printronix_io_call: proc; /* This proc handles the io_call orders by mapping then into control order calls to this dim */ io_call_infop = infop; order = io_call_info.order_name; if order = "select_device" then do; end; else call iox_$control (tty_iocb, "io_call", infop, code); return; end printronix_io_call; handler: proc; /* This proc handles faults that occur while masked */ call continue_to_signal_ (code); return; end handler; end printronix_; */ ----------------------------------------------------------- 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 */