diff options
Diffstat (limited to 'private/mvdm/softpc.new/base/comms/printer.c')
-rw-r--r-- | private/mvdm/softpc.new/base/comms/printer.c | 836 |
1 files changed, 836 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/base/comms/printer.c b/private/mvdm/softpc.new/base/comms/printer.c new file mode 100644 index 000000000..0ef68ce1d --- /dev/null +++ b/private/mvdm/softpc.new/base/comms/printer.c @@ -0,0 +1,836 @@ +#include "insignia.h" +#include "host_def.h" +#ifdef PRINTER + +/* + * VPC-XT Revision 1.0 + * + * Title: Parallel Printer Port Emulation + * + * Description: Emulates the IBM || Printer card as used in the original + * IBM XT, which is itself a H/W emulation of an Intel 8255. + * + * Author: Henry Nash + * + * Notes: None + * + * Mods: + * <chrisP 11Sep91> + * Allow transition to NOTBUSY in the OUTA state as well as the READY + * state. i.e. at the leading edge of the ACK pulse after just one + * INB (STATUS) rather than two. Our printer port emulation relies on + * these INB's to toggle the ACK line and set NOTBUSY true again. So + * the port could be left in the BUSY condition at the end of an app's + * print job (which can confuse the next print request). NOTE we could + * still have a problem if the PC app bypasses the BIOS and is too lazy + * to do even one INB(STATUS) after the last print byte. + */ + + + +/* for NTVDM port -- williamh + * There are such things called Dongles which many software companies have + * used for copy protection. Each software comes with its dedicated Dongle + * that records necessary indentification inforamtion. It is required + * to plug the device onto the parallel port in order to run the software + * correctly. The device has an outlet which can be connectted to parallel + * port printer so the the user doesn't sacrifice his parallel port when + * the device in plugged on the original connector. + * There are several Dongle vendors and each one of them provides their + * propietary library or driver for the applications to link to. These + * drivers know how to read/WRITE the Dongle to verify a legitmate copy. + * Since it has to maintain compatiblility with standard PC parallel port, + * the devices are designed in a way that it can be programmed without + * disturbing ordinary parallel port operation. To do this, it usually does + * this: + * (1) Turn off strobe. + * (2) output data pattern to data port + * (3) delay a little bit(looping in instructions) and then go to (2) + * until the chunk of data has been sent. NOTE THAT THE STROBE LINE + * IS NEVER "strobe" + * (4). Read status port and by interpreting the line differently, + * the driver decodes any id information it is looking for. + * + * In order to support these devices, we have to do these: + * (1). We can not fake printer status. We have to get the real + * status line states. + * (2). we have to output data to the printer without waiting the data + * to be qualified(strobing). + * (3). We must be smart enough to detect the application is done with + * its Dongle things and wants everything goes back to normal. + * We must adjust ourselves under this circumestances. + * (4). Down level printer driver must provide function that we can call + * to control the port directly. + * (5). Printer h/w interrupt is not allowed to be enabled under this + * circumstance --and how can we make sure of that????? + * + */ + +#ifdef SCCSID +static char SccsID[] = "@(#)printer.c 1.19 11/14/94 Copyright Insignia Solutions Ltd."; +#endif + +#ifdef SEGMENTATION +/* + * The following #include specifies the code segment into which this + * module will by placed by the MPW C compiler on the Mac II running + * MultiFinder. + */ +#include "SOFTPC_PRINTER.seg" +#endif + + +/* + * O/S include files. + */ +#include <stdio.h> +#include TypesH +#include TimeH +#ifdef SYSTEMV +#ifdef STINGER +#include <sys/termio.h> +#endif +#endif + +/* + * SoftPC include files + */ +#include "xt.h" +#include CpuH +#include "sas.h" +#include "ios.h" +#include "bios.h" +#include "printer.h" +#include "error.h" +#include "config.h" +#include "host_lpt.h" +#include "ica.h" +#include "quick_ev.h" + +#include "debug.h" +#ifndef PROD +#include "trace.h" +#endif + + +/* + * ============================================================================ + * Global data + * ============================================================================ + */ + + +/* + * ============================================================================ + * Static data and defines + * ============================================================================ + */ + +#define PRINTER_BIT_MASK 0x3 /* bits decoded from address bus */ +#define CONTROL_REG_MASK 0xE0; /* unused bits drift to HIGH */ +#define STATUS_REG_MASK 0x07; /* unused bits drift to HIGH */ + +#define DATA_OFFSET 0 /* ouput register */ +#define STATUS_OFFSET 1 /* status register */ +#define CONTROL_OFFSET 2 /* control register */ + +#ifdef ERROR +#undef ERROR +#endif + +static half_word output_reg[NUM_PARALLEL_PORTS]; +static half_word control_reg[NUM_PARALLEL_PORTS]; +#define NOTBUSY 0x80 +#define ACK 0x40 +#define PEND 0x20 +#define SELECT 0x10 +#define ERROR 0x08 + +static half_word status_reg[NUM_PARALLEL_PORTS]; +#define IRQ 0x10 +#define SELECT_IN 0x08 +#define INIT_P 0x04 +#define AUTO_FEED 0x02 +#define STROBE 0x01 + +LOCAL IU8 retryErrorCount = 0; /* num status inb before clearing ERROR */ + +static int state[NUM_PARALLEL_PORTS]; /* state control variable */ +/* + * set up arrays of all port addresses + */ +static io_addr port_start[] = {LPT1_PORT_START,LPT2_PORT_START,LPT3_PORT_START}; +static io_addr port_end[] = {LPT1_PORT_END, LPT2_PORT_END, LPT3_PORT_END}; +static int port_no[] = {LPT1_PORT_START & LPT_MASK, LPT2_PORT_START & LPT_MASK, + LPT3_PORT_START & LPT_MASK }; +static half_word lpt_adapter[] = {LPT1_ADAPTER, LPT2_ADAPTER, LPT3_ADAPTER}; +static sys_addr port_address[] = {LPT1_PORT_ADDRESS, LPT2_PORT_ADDRESS, LPT3_PORT_ADDRESS}; +static sys_addr timeout_address[] = {LPT1_TIMEOUT_ADDRESS, LPT2_TIMEOUT_ADDRESS, LPT3_TIMEOUT_ADDRESS}; +static q_ev_handle handle_for_out_event[NUM_PARALLEL_PORTS]; +static q_ev_handle handle_for_outa_event[NUM_PARALLEL_PORTS]; + +#if defined(NTVDM) && defined(MONITOR) +/* sudeepb 24-Jan-1993 for printing performance for x86 */ +sys_addr lp16BitPrtBuf; +sys_addr lp16BitPrtId; +sys_addr lp16BitPrtCount; +sys_addr lp16BitPrtBusy; +#endif + +#define STATE_READY 0 +#define STATE_OUT 1 +#define STATE_OUTA 2 +#if defined(NTVDM) +#define STATE_DATA 3 +#define STATE_DONGLE 4 +#endif + +/* + * State transitions: + * + * +-> STATE_READY + * | | + * | | ........ write char to output_reg, print on low-high strobe + * | V set NOTBUSY to false + * | STATE_OUT + * | | + * | | ........ (read status) set ACK low + * | V + * | STATE_OUTA + * | | + * | | ........ (read status) set ACK high + * +-----+ + * + * Caveat: if the control register interrupt request bit is set, + * we assume that the application isn't interested in getting the + * ACKs and just wants to know when the printer state changes back + * to NOTBUSY. I'm not sure to want extent you can get away with + * this: however, applications using the BIOS printer services + * should be OK. + */ + +#ifdef PS_FLUSHING +LOCAL IBOOL psFlushEnabled[NUM_PARALLEL_PORTS]; /* TRUE if PostScript flushing + is enabled */ +#endif /* PS_FLUSHING */ + + +/* + * ============================================================================ + * Internal functions & macros + * ============================================================================ + */ + +#define set_low(val, bit) val &= ~bit +#define set_high(val, bit) val |= bit +#define low_high(val1, val2, bit) (!(val1 & bit) && (val2 & bit)) +#define high_low(val1, val2, bit) ((val1 & bit) && !(val2 & bit)) +#define toggled(val1, val2, bit) ((val1 & bit) != (val2 & bit)) +#define negate(val, bit) val ^= bit + +/* + * Defines and variables to handle tables stored in 16-bit code for NT + * monitors. + */ +#if defined(NTVDM) && defined(MONITOR) + +static BOOL intel_setup = FALSE; + +static sys_addr status_addr; +static sys_addr control_addr; +static sys_addr state_addr; + +#define get_status(adap) (sas_hw_at_no_check(status_addr+(adap))) +#define set_status(adap,val) (sas_store_no_check(status_addr+(adap),(val))) + +#define get_control(adap) (sas_hw_at_no_check(control_addr+(adap))) +#define set_control(adap,val) (sas_store_no_check(control_addr+(adap),(val))) + +#define get_state(adap) (sas_hw_at_no_check(state_addr+(adap))) +#define set_state(adap,val) (sas_store_no_check(state_addr+(adap),(val))) + +#else /* NTVDM && MONITOR */ + +#define get_status(adap) (status_reg[adapter]) +#define set_status(adap,val) (status_reg[adapter] = (val)) + +#define get_control(adap) (control_reg[adapter]) +#define set_control(adap,val) (control_reg[adapter] = (val)) + +#define get_state(adap) (state[adapter]) +#define set_state(adap,val) (state[adapter] = (val)) + +#endif /* NTVDM && MONITOR */ + +static void printer_inb IPT2(io_addr, port, half_word *, value); +static void printer_outb IPT2(io_addr, port, half_word, value); +static void notbusy_check IPT1(int,adapter); + + +/* + * ============================================================================ + * External functions + * ============================================================================ + */ + +void printer_post IFN1(int,adapter) +{ + /* + * Set up BIOS data area. + */ + sas_storew(port_address[adapter],(word)port_start[adapter]); + sas_store(timeout_address[adapter], (half_word)0x14 ); /* timeout */ +} + +#if defined(NTVDM) && defined(MONITOR) +static void lpr_state_outa_event IFN1(long,adapter) +{ + set_status(adapter, get_status(adapter) | ACK); + set_state(adapter, STATE_READY); +} + +static void lpr_state_out_event IFN1(long,adapter) +{ + set_status(adapter, get_status(adapter) & ~ACK); + set_state(adapter, STATE_OUTA); + handle_for_outa_event[adapter]=add_q_event_t(lpr_state_outa_event,HOST_PRINTER_DELAY,adapter); +} + +#else /* NTVDM && MONITOR */ + +static void lpr_state_outa_event IFN1(long,adapter) +{ + set_high(status_reg[adapter],ACK); + state[adapter]=STATE_READY; +} + +static void lpr_state_out_event IFN1(long,adapter) +{ + set_low(status_reg[adapter], ACK); + state[adapter]=STATE_OUTA; + handle_for_outa_event[adapter]=add_q_event_t(lpr_state_outa_event,HOST_PRINTER_DELAY,adapter); +} +#endif /* NTVDM && MONITOR */ + +static void printer_inb IFN2(io_addr,port, half_word *,value) +{ + int adapter, i; + + note_trace1(PRINTER_VERBOSE,"inb from printer port %#x ",port); + /* + ** Scan the ports to find out which one is used. NB the + ** port must be valid one because we only used io_define_inb() + ** for the valid ports + */ + for(i=0; i < NUM_PARALLEL_PORTS; i++) + if((port & LPT_MASK) == port_no[i]) + break; + adapter = i % NUM_PARALLEL_PORTS; + + port = port & PRINTER_BIT_MASK; /* clear unused bits */ + + switch(port) + { + case DATA_OFFSET: + *value = output_reg[adapter]; + break; + + case STATUS_OFFSET: + switch(get_state(adapter)) + { +#if defined(NTVDM) + case STATE_DONGLE: + /* read directly from the port for Dongle */ + *value = host_read_printer_status_port(adapter); + set_status(adapter, *value); + break; + case STATE_DATA: + +#endif + + case STATE_READY: + notbusy_check(adapter); + *value = get_status(adapter) | STATUS_REG_MASK; + + + /* Clear ERROR as it will be set if we fail on the print. */ + /* Clear after two inbs as DOS seems to require this. */ + if (retryErrorCount > 0) + retryErrorCount--; + else + set_status(adapter, get_status(adapter) | ERROR); + break; + case STATE_OUT: + *value = get_status(adapter) | STATUS_REG_MASK; +#ifndef DELAYED_INTS + delete_q_event(handle_for_out_event[adapter]); + lpr_state_out_event(adapter); +#else + set_low(status_reg[adapter], ACK); + state[adapter] = STATE_OUTA; +#endif /* DELAYED INTS */ + break; + case STATE_OUTA: + notbusy_check(adapter); /* <chrisP 11Sep91> */ + *value = get_status(adapter) | STATUS_REG_MASK; +#ifndef DELAYED_INTS + delete_q_event(handle_for_outa_event[adapter]); + lpr_state_outa_event(adapter); +#else + set_high(status_reg[adapter], ACK); + state[adapter] = STATE_READY; +#endif + break; + default: + note_trace1(PRINTER_VERBOSE, + "<pinb() - unknown state %x>", + get_state(adapter)); + break; + } + break; + case CONTROL_OFFSET: + *value = get_control(adapter) | CONTROL_REG_MASK; + negate(*value, STROBE); + negate(*value, AUTO_FEED); + negate(*value, SELECT_IN); + break; + } + note_trace3(PRINTER_VERBOSE, "<pinb() %x, ret %x, state %x>", + port, *value, get_state(adapter)); + + +} + +static void printer_outb IFN2(io_addr,port, half_word,value) +{ + int adapter, i; + half_word old_control; +#ifdef PC_CONFIG + char variable_text[MAXPATHLEN]; + int softpcerr; + int severity; + + softpcerr = 0; + severity = 0; +#endif + + + note_trace2(PRINTER_VERBOSE,"outb to printer port %#x with value %#x", + port, value); + + /* + ** Scan the ports to find out which one is used. NB the + ** port must be valid one because we only used io_define_inb() + ** for the valid ports + */ + for(i=0; i < NUM_PARALLEL_PORTS; i++) + if((port & LPT_MASK) == port_no[i]) + break; + adapter = i % NUM_PARALLEL_PORTS; + + note_trace3(PRINTER_VERBOSE, "<poutb() %x, val %x, state %x>", + port, value, get_state(adapter)); + + port = port & PRINTER_BIT_MASK; /* clear unused bits */ + + switch(get_state(adapter)) + { +#if defined(NTVDM) + case STATE_DONGLE: + if (port == DATA_OFFSET) { + output_reg[adapter] = value; + host_print_byte(adapter, value); + break; + } + // fall through + case STATE_DATA: + if (port == DATA_OFFSET) { + if (host_set_lpt_direct_access(adapter, TRUE)) { + host_print_byte(adapter, output_reg[adapter]); + host_print_byte(adapter, value); + set_state(adapter, STATE_DONGLE); + /* Write char to internal buffer */ + output_reg[adapter] = value; + } + else { + /* unable to open the lpt for direct access, + mark the device busy */ + +#if !defined(MONITOR) + set_low(status_reg[adapter], NOTBUSY); +#else /* NTVDM && !MONITOR */ + set_status(adapter, 0x7F); +#endif + + + } + break; + } + + // fall through +#endif + case STATE_OUT: + case STATE_OUTA: + case STATE_READY: + switch(port) + { + case DATA_OFFSET: +#if defined(NTVDM) + set_state(adapter, STATE_DATA); +#endif + /* Write char to internal buffer */ + output_reg[adapter] = value; + break; + case STATUS_OFFSET: + /* Not possible */ + break; + + case CONTROL_OFFSET: + /* Write control bits */ + old_control = get_control(adapter); /* Save old value to see what's changed */ + set_control(adapter, value); + if (low_high(old_control, value, INIT_P)) +#ifdef PC_CONFIG + /* this was a call to host_print_doc - <chrisP 28Aug91> */ + host_reset_print(&softpcerr, &severity); + if (softpcerr != 0) + host_error(softpcerr, severity, variable_text); +#else + /* this was a call to host_print_doc - <chrisP 28Aug91> */ + host_reset_print(adapter); +#endif + + if (toggled(old_control, value, AUTO_FEED)) + host_print_auto_feed(adapter, + ((value & AUTO_FEED) != 0)); + + if (low_high(old_control, value, STROBE)) + { +#if defined(NTVDM) + if (get_state(adapter) == STATE_DONGLE) { + host_set_lpt_direct_access(adapter, FALSE); + /* pass through to print out the last byte + * which we have sent it out the data port + * while we are in DONGLE state. + */ + + set_state(adapter, STATE_READY); + } +#endif + +#ifdef PS_FLUSHING + /* + * If PostScript flushing is enabled for this + * port then we flush on a Ctrl-D + */ + if ( psFlushEnabled[adapter] && + output_reg[adapter] == 0x04 /* ^D */ ) { + host_print_doc(adapter); + } else { +#endif /* PS_FLUSHING */ + /* + * Send the stored internal buffer to + * the printer + */ + if(host_print_byte(adapter,output_reg[adapter]) == FALSE) + { + set_status(adapter, get_status(adapter) & ~ERROR); /* active Low */ + /* NTVDM had here(?): set_status(adapter, ACK|PEND|SELECT|ERROR); */ + /* two status inbs before we clear ERROR */ + retryErrorCount = 2; + } + else + { + /* clear ERROR condition */ + set_status(adapter, get_status(adapter) | ERROR); +#if defined(NTVDM) && !defined(MONITOR) + set_low(status_reg[adapter], NOTBUSY); +#else /* NTVDM && !MONITOR */ + set_status(adapter, + get_status(adapter) & ~NOTBUSY); +#endif /* NTVDM && !MONITOR */ + set_state(adapter, STATE_OUT); +#ifndef DELAYED_INTS + handle_for_out_event[adapter]=add_q_event_t(lpr_state_out_event,HOST_PRINTER_DELAY,adapter); +#endif /* DELAYED_INTS */ + } +#ifdef PS_FLUSHING + } +#endif /* PS_FLUSHING */ + } + else if (high_low(old_control, value, STROBE) + && get_state(adapter) == STATE_OUT) + { + if (value & IRQ) + { + /* + * Application is using + * interrupts, so we can't + * rely on INBs being + * used to check the + * printer status. + */ + set_state(adapter, STATE_READY); + notbusy_check(adapter); + } + } + +#if defined(NTVDM) + else if (low_high(old_control, value, IRQ) && + get_state(adapter) == STATE_DONGLE) { + + host_set_lpt_direct_access(adapter, FALSE); + set_state(adapter, STATE_READY); + } + +#endif + +#ifndef PROD + if (old_control & IRQ) + note_trace1(PRINTER_VERBOSE, "Warning: LPT%d is being interrupt driven\n", + number_for_adapter(adapter)); +#endif + break; + } + break; + default: + note_trace1(PRINTER_VERBOSE, "<poutb() - unknown state %x>", + get_state(adapter)); + break; + } +} + +void printer_status_changed IFN1(int,adapter) +{ + note_trace1(PRINTER_VERBOSE, "<printer_status_changed() adapter %d>", + adapter); + + /* check whether the printer has just changed state to NOTBUSY */ + notbusy_check(adapter); +} + +/* + * ============================================================================ + * Internal functions + * ============================================================================ + */ + +static void notbusy_check IFN1(int,adapter) +{ + /* + * This function is used to detect when the printer + * state transition to NOTBUSY occurs. + * + * If the parallel port is being polled, the port + * emulation will stop this transition occurring + * until the application has detected the ACK + * pulse. notbusy_check() is then called each time the + * port status is read using the INB; when the host + * says the printer is HOST_LPT_BUSY, the port status + * returns to the NOTBUSY state. + * + * If the parallel port is interrupt driven, we cannot + * rely on the application using the INB: so we first + * check the host printer status immediately after + * outputting the character. If the host printer isn't + * HOST_LPT_BUSY, then we interrupt immediately; + * otherwise, we rely on the printer_status_changed() + * call to notify us of when HOST_LPT_BUSY is cleared. + */ + + /* <chrisP 11Sep91> allow not busy at leading edge of ack pulse too */ + if ( (get_state(adapter) == STATE_READY || +#if defined(NTVDM) + get_state(adapter) == STATE_DATA || +#endif + get_state(adapter) == STATE_OUTA) + && !(get_status(adapter) & NOTBUSY) + && !(host_lpt_status(adapter) & HOST_LPT_BUSY)) + { +#if defined(NTVDM) && !defined(MONITOR) + set_high(status_reg[adapter], NOTBUSY); +#else /* NTVDM && !MONITOR */ + set_status(adapter, get_status(adapter) | NOTBUSY); +#endif /* NTVDM && !MONITOR */ + +#ifndef PROD + if (io_verbose & PRINTER_VERBOSE) + fprintf(trace_file, "<printer notbusy_check() - adapter %d changed to NOTBUSY>\n", adapter); +#endif + + if (get_control(adapter) & IRQ) + { + ica_hw_interrupt(0, CPU_PRINTER_INT, 1); + } + } +} +#ifdef SEGMENTATION +/* + * The following #include specifies the code segment into which this + * module will by placed by the MPW C compiler on the Mac II running + * MultiFinder. + */ +#include "SOFTPC_INIT.seg" +#endif + +/* +** Initialise the printer port required. +*/ +void printer_init IFN1(int,adapter) +{ + io_addr i; + + io_define_inb( lpt_adapter[adapter], printer_inb ); + io_define_outb( lpt_adapter[adapter], printer_outb ); + for(i = port_start[adapter]; i < port_end[adapter]; i++) + io_connect_port(i,lpt_adapter[adapter],IO_READ_WRITE); + +#if defined(NTVDM) && defined(MONITOR) + /* + * If we know the addresses of the 16-bit variables write directly + * to them, otherwise save the value until we do. + */ + if (intel_setup) + { + set_status(adapter, 0xDF); + set_control(adapter, 0xEC); + } + else +#endif /* NTVDM && MONITOR */ + { + control_reg[adapter] = 0xEC; + status_reg[adapter] = 0xDF; + } + output_reg[adapter] = 0xAA; + + /* + * The call to host_print_doc has been removed since it is + * sensible to distinguish between a hard flush (on ctl-alt-del) + * or menu reset and a soft flush under user control or at end + * of PC application. The calls to host_lpt_close() followed + * by host_lpt_open() should already cause a flush to occur, + * so no functionality is lost. The first time printer_init is + * called host_lpt_close() is not called, but this cannot + * matter since host_print_doc() can only be a no-op. + */ + /* host_print_doc(adapter); */ + host_print_auto_feed(adapter, FALSE); + +#if defined(NTVDM) && defined(MONITOR) + if (intel_setup) + set_state(adapter, STATE_READY); + else +#endif /* NTVDM && MONITOR */ + state[adapter] = STATE_READY; + +} /* end of printer_init() */ + +#if defined(NTVDM) && defined(MONITOR) +/* +** Store 16-bit address of status table and fill it with current values. +*/ +#ifdef ANSI +void printer_setup_table(sys_addr table_addr) +#else /* ANSI */ +void printer_setup_table(table_addr) +sys_addr table_addr; +#endif /* ANSI */ +{ + int i; + sys_addr lp16BufSize; + unsigned int cbBuf; + word lptBasePortAddr[NUM_PARALLEL_PORTS]; + + if (!intel_setup) + { + + /* + * Store the addresses of the tables resident in 16-bit code. These + * are: + * status register (NUM_PARALLEL_PORTS bytes) + * state register (NUM_PARALLEL_PORTS bytes) + * control register (NUM_PARALLEL_PORTS bytes) + * host_lpt_status (NUM_PARALLEL_PORTS bytes) + * + * Then transfer any values which have already been set up into the + * variables. This is in case printer_init has been called prior to + * this function. + */ + status_addr = table_addr; + state_addr = table_addr + NUM_PARALLEL_PORTS; + control_addr = table_addr + 2 * NUM_PARALLEL_PORTS; + for (i = 0; i < NUM_PARALLEL_PORTS; i++) + { + set_status(i, status_reg[i]); + set_state(i, state[i]); + set_control(i, control_reg[i]); + lptBasePortAddr[i] = port_start[i]; + } + + /* Let host know where host_lpt_status is stored in 16-bit code. */ + host_printer_setup_table(table_addr, NUM_PARALLEL_PORTS, lptBasePortAddr); +/* sudeepb 24-Jan-1993 for printing performance for x86 */ + lp16BufSize = table_addr + 4 * NUM_PARALLEL_PORTS; + cbBuf = (sas_w_at_no_check(lp16BufSize)); + lp16BitPrtBuf = table_addr + (4 * NUM_PARALLEL_PORTS) + 2; + lp16BitPrtId = lp16BitPrtBuf + cbBuf; + lp16BitPrtCount = lp16BitPrtId + 1; + lp16BitPrtBusy = lp16BitPrtCount + 2; + intel_setup = TRUE; + } +} +#endif /* NTVDM && MONITOR */ + +#endif + +#ifdef NTVDM +void printer_is_being_closed(int adapter) +{ + +#if defined(MONITOR) + set_state(adapter, STATE_READY); +#else + state[adapter] = STATE_READY; + +#endif +} + +#endif + + +#ifdef PS_FLUSHING +/*( +=========================== printer_psflush_change ============================ +PURPOSE: + Handle change of PostScript flush configuration option for a printer + port. +INPUT: + hostID - Configuration item I.D. + apply - TRUE if change to be applied +OUTPUT: + None +ALGORITHM: + If PostScript flushing is being enabled then; + set the PostScript flush enable flag for the port; + disable autoflush for the port; + else; + reset the PostScript flush enable flag for the port; + enable autoflush for the port; +=============================================================================== +)*/ + +GLOBAL void printer_psflush_change IFN2( + IU8, hostID, + IBOOL, apply +) { + IS32 adapter = hostID - C_LPT1_PSFLUSH; + + assert1(adapter < NUM_PARALLEL_PORTS,"Bad hostID %d",hostID); + + if ( apply ) + if ( psFlushEnabled[adapter] = (IBOOL)config_inquire(hostID,NULL) ) + host_lpt_disable_autoflush(adapter); + else + host_lpt_enable_autoflush(adapter); +} +#endif /* PS_FLUSHING */ |