lyo@uk.ac.newcastle.cheviot (Jim Lyons) (05/06/87)
Another problem has illustrated the errors that can appear when a routine written for a one machine is run on another with different timing characteristics. With the exception of the first invocation - when the call is from a user - the pr_char() procedure in printer.c is called directly by the interrupt handler lpr_int in mpx88.s. Pr_char() checks the status of the printer (specifically that the busy bit is not set) collects the next character to be printed, puts it in the data register and strobes the printer: line 264: port_out(port_base, ch); /* output character */ port_out(port_base + 2, ASSERT_STROBE); port_out(port_base + 2, NEGATE_STROBE); The pointer to the buffer is then adjusted and the count decremented: offset++; pcount--; However, the printer can "ack" the data transfer before these last two operations are carried out, producing and interrupt and an additional invocation of the procedure. The end result is when the stack unwinds, the characters appear in unpredictable positions on the paper. One cure is to make the writing action "atomic" by completing the increment and decrement operations before strobing the printer: port_out(port_base, ch); /* output character */ offset++; pcount--; port_out(port_base + 2, ASSERT_STROBE); port_out(port_base + 2, NEGATE_STROBE); Printer.c needs to be re-written!