/* * Output segment */ .org 1024 seg1: /* * The code in this segment is entered via label 'outreq' when it is * recognized that a DZ11 has requested an output character */ statesw: br disable br odrst1 br odrst2 br odrst3 br odrst4 br odrst5 ERROR(INVALCD) br . /* * The following table of jump instructions is accessed by a * calculated branch instruction using the ASCII character * as index. It provides a fast implementation of tests * for specific control characters */ charsw: br sendit /* 0 - NUL */ br sendit /* 1 - SOH */ br sendit /* 2 - STX */ br sendit /* 3 - ETX */ br sendit /* 4 - EOT */ br sendit /* 5 - ENQ */ br sendit /* 6 - ACK */ br sendit /* 7 - BEL */ br isbs /* 010 - BS */ br isht /* 011 - HT */ br isnl /* 012 - NL */ br isvt /* 013 - VT */ br isff /* 014 - FF */ br iscr /* 015 - CR */ br sendit /* 016 - SO */ br sendit /* 017 - SI */ br sendit /* 020 - DLE */ br sendit /* 021 - DC1 */ br sendit /* 022 - DC2 */ br sendit /* 023 - DC3 */ br sendit /* 024 - DC4 */ br sendit /* 025 - NAK */ br sendit /* 026 - SYN */ br sendit /* 027 - ETB */ br sendit /* 030 - CAN */ br sendit /* 031 - EM */ br sendit /* 032 - SUB */ br sendit /* 033 - ESC */ br sendit /* 034 - FS */ br sendit /* 035 - GS */ br sendit /* 036 - RS */ br sendit /* 037 - US */ /* * Entered here from main segment */ outreq: /* * The DZ11 has requested an output character. Get the line * number and look up the address of the line-table entry. * Save the address of the line-table entry in register r10. */ mov idh,brg mov 7,r7 and brg,r7,r7|mar mov mem,r10|mar /* * Get flags */ mov FLAGS1,brg add brg,r10,mar mov mem,r0 /* * If a break is being sent then go to disable */ mov OUTBRK,brg orn brg,r0,- brz disable /* * See if there is an express character */ mov ~SNDEXP,brg or brg,r0,- brz 1f br 2f /* * Send express character reguardless of state of line */ 1: and brg,r0,mem mov EXPCHR,brg add brg,r10,mar mov mem,odl br sendit 2: /* * If TTSTOP is set then go to disable */ mov TTSTOP,brg orn brg,r0,- brz disable /* * Get OFLAG into r6 */ mov OFLAG,brg add brg,r10,mar mov mem,r6 /* * Get the current state of this line */ mov STATE,brg add brg,r10,mar mov mem,r0 /* * If state == 0 then go to disable * else if state == 1 then go to odrst1 * else if state == 2 then go to odrst2 * else if state == 3 then go to odrst3 * else if state == 4 then go to odrst4 * else if state == 5 then go to odrst5 */ mov statesw,brg br (add,brg,r0),%statesw /* * Output data request with state == 1 (sending normal data) */ odrst1: /* * If there is a saved byte to be sent then go to sendsave */ mov FLAGS,brg add brg,r10,mar mov mem,brg br4 sendsave /* * If there are no characters remaining in the current * buffer for this line then go to odrst1a */ mov NCH,brg add brg,r10,mar mov mem,r0 dec r0,- brz odrst1a /* * Decrement the number of characters remaining in the current * buffer for this line */ dec r0 mov r0,mem /* * If this was the last character queue the line */ dec r0,- brc odrst1b CALL(oqueue) mov %dzst,brg add brg,r8,%mar br odrst1b /* * There are no more characters remaining in the current * buffer for this line */ odrst1a: /* * If the host computer has not yet presented a new buffer then * go to nomore */ mov OUTBUF,brg add brg,r10,mar mov mem,r4 brz nomore /* * Get the buffer address from the queue entry */ mov 03,brg and brg,r4,%mar mov ~03,brg and brg,r4,mar mov 0,r0|mar++ mov mem,r3|mar++ mov mem,r2|mar++ mov mem,r1 mov 3,brg and brg,r1 /* * Set the page register to the page for this DZ11 */ mov %dzst,brg add brg,r8,%mar /* * Get the index of the first and last characters */ mov C_FIRST,brg add brg,r3,brg mov brg,ial adc r2,brg mov brg,iah adc r1,brg mov brg,r0 mov 3,brg and brg,r0 asl r0 asl r0 mov NRQ,brg or brg,r0,npr BUSWAIT(buserr1) /* * Compute the character count - 1 for the new output * buffer and record the result as the remaining character * count for the current buffer. */ mov NCH,brg add brg,r10,mar mov idh,r0 mov idl,brg sub brg,r0 dec r0 mov r0,mem /* * If there was only one character in this buffer release it */ dec r0,- brc 1f CALL(oqueue) mov %dzst,brg add brg,r8,%mar 1: /* * Set bufad = address of the first character */ mov BUFAD,brg add brg,r10,mar mov idl,r0 mov C_DATA,brg add brg,r0,brg add brg,r3,mem|mar++ adc r2,mem|mar++ adc r1,mem /* * If the buffer address is even then go to odrst1c */ mov BUFAD,brg add brg,r10,mar mov mem,brg br0 1f br odrst1c 1: /* * Clear the low-order bit of the buffer address */ mov 1,r1 xor mem,r1,mem /* * Fetch two bytes */ mov mem,ial|mar++ mov mem,iah|mar++ mov mem,r0 mov 3,brg and brg,r0 asl r0 asl r0 mov NRQ,brg or brg,r0,npr BUSWAIT(buserr1); /* * Save the high-order byte as the current output character */ mov idh,odl /* * Set buffer address += 2 */ mov BUFAD,brg add brg,r10,mar mov 2,r2 add mem,r2,mem|mar++ mov mem,r0 adc r0,mem|mar++ mov mem,r0 adc r0,mem /* * Go to sendtest */ br sendtest /* * The DZ has just started sending the last byte of the * current output buffer. Call oflush which just * bookkeeps the lte and dispable the line. * The next buffer-send command will reactivate the line. */ nomore: CALL(oflush) mov %dzst,brg add brg,r8,%mar br disable /* * Output data request with non-empty buffer */ odrst1b: /* * If there is a high-order byte to send then go to sendhigh */ mov FLAGS,brg add brg,r10,mar mov mem,brg br1 sendhigh /* * We need to get another word of data for this line. */ odrst1c: /* * Get the buffer address field of the line-table entry, * then set up a unibus request for the next two bytes. */ mov BUFAD,brg add brg,r10,mar mov mem,ial|mar++ mov mem,iah|mar++ mov mem,r0 asl r0 asl r0 mov NRQ,brg or brg,r0,npr /* * Wait for the unibus transfer to complete. * If an error occurs then go to buserr1. */ BUSWAIT(buserr1) /* * Set the bit that says to send the high-order byte */ mov FLAGS,brg add brg,r10,mar mov SENDHIGH,brg mov mem,r0 or brg,r0,mem|mar++ /* * Save the high-order data byte in the line-table entry */ mov HIBYTE,brg add brg,r10,mar mov idh,mem /* * Move the low-order data byte to the output data register */ mov idl,odl /* * Increment the buffer address */ mov BUFAD,brg add brg,r10,mar mov 2,r2 add mem,r2,mem|mar++ mov mem,r2 adc r2,mem|mar++ mov mem,r2 adc r2,mem /* * Go to sendtest */ br sendtest /* * Prepare to send the high-order byte. */ sendhigh: /* * Move the high-order data byte from the line-table entry * to the output data register */ mov HIBYTE,brg add brg,r10,mar mov mem,odl /* * Clear the flag that says to send the high-order byte */ mov FLAGS,brg add brg,r10,mar mov mem,r0 mov ~SENDHIGH,brg and brg,r0,mem /* * Go to sendtest */ br sendtest /* * Prepare to send the byte in SAVECHAR */ sendsave: /* * Clear the flag that says there is a saved byte to be sent */ mov ~SENDSAVE,brg mov mem,r0 and brg,r0,mem /* * Move the saved byte into odl */ mov SAVECHAR,brg add brg,r10,mar mov mem,odl /* * Go to sendtest */ br sendtest /* * The following code acts as a filter for outgoing characters */ sendtest: /* * Get output flags */ mov OFLAG,brg add brg,r10,mar mov mem,r6 /* * If output post-processing is not enabled then go to sendit */ mov OPOST,brg orn brg,r6,- brz 1f br sendit 1: /* * Get the delays */ mov DELAYS,brg add brg,r10,mar mov mem,r5 /* * Get the output character */ mov odl,r0 /* * If the character is a control character then go to iscc */ mov 040,brg sub brg,r0,- brc 1f br iscc 1: /* * If the character is a DEL then go to sendit */ mov 0177,brg addn brg,r0,- brz sendit /* * Increment the column pointer */ mov ICOL,brg add brg,r10,mar mov mem,r1 inc r1,mem /* * If OLCUC is set then translate lower case alpha to upper case */ mov OLCUC,brg orn brg,r6,- brz 1f br 2f 1: mov 'a',brg sub brg,r0,- brc 1f br 2f 1: mov 'z',brg addn brg,r0,- brc 2f mov ~040,brg and brg,r0 mov r0,odl 2: /* * Go to sendit */ br sendit /* * Process an ASCII control character */ iscc: /* * If the character is a backspace then go to isbs; * else if the character is a horizontal tab then go to isht; * else if the character is a newline then go to isnl; * else if the character is a vertical tab then go to isvt; * else if the character is a form-feed then go to isff; * else if the character is a carriage return then go to iscr; * else go to sendit */ mov charsw,brg br (add,brg,r0),%charsw /* * Process a newline character */ isnl: /* * If ONLRET is set then go to iscr2 */ mov ONLRET,brg orn brg,r6,- brz iscr2 /* * If we are not expanding NL for this line then go to nlpart3 */ mov ONLCR,brg orn brg,r6,- brz 1f br nlpart3 1: /* * If column pointer == 0 and ONOCR is set then go to iscr2. * (We omit the carriage return in this case.) */ mov ICOL,brg add brg,r10,mar mov mem,r0 dec r0,- brc 1f mov ONOCR,brg orn brg,r6,- brz iscr2 1: /* * If this NL has already been expanded then go to nlpart2 */ mov FLAGS,brg add brg,r10,mar mov mem,brg br0 nlpart2 /* * Set flags to indicate that there is a saved byte in SAVECHAR * and that the NL character has already been expanded */ mov SENDSAVE|NLEXP,brg mov mem,r0 or brg,r0,mem /* * Put a new-line character into SAVECHAR */ mov SAVECHAR,brg add brg,r10,mar mov NL,mem /* * Put a carriage-return character into odl */ mov CR,brg mov brg,odl /* * Go to sendit */ br sendit /* * Part two of newline character processing * * The generated carriage return has already been sent. * * At this point we just have to send the saved newline character * and generate the appropriate time delay, if any. */ nlpart2: /* * Clear the flag which indicates that this particular newline * has already been expanded */ mov FLAGS,brg add brg,r10,mar mov mem,r0 mov ~NLEXP,brg and brg,r0,mem /* * Go to iscr2 */ br iscr2 /* * Process a carriage-return character */ iscr: /* * If translate-CR-to-NL is set then go to xmtnl */ mov OCRNL,brg orn brg,r6,- brz xmtnl /* * If at col 0 and ONOCR is set do not send out carriage return */ mov ICOL,brg add brg,r10,mar mov mem,r2 dec r2 brc iscr2 mov ONOCR,brg orn brg,r6,- brz odrst1 /* * Entered here from isnl */ iscr2: /* * Save column pointer */ mov ICOL,brg add brg,r10,mar mov mem,r2 /* * Set column pointer = 0 */ mov 0,mem /* * Get delay type for carriage-return. * If delay type == 0 then go to sendit * else if delay type == 1 then go to cr1 * else if delay type == 2 then go to cr2 * else go to cr3 */ mov CRDELAY,brg and brg,r5,brg mov 0,brg>> br1 1f br0 cr1 br sendit 1: br0 cr3 br cr2 /* * Carriage-return delay type 1 */ cr1: /* * If OFILL is set then go to filltwo */ mov OFILL,brg orn brg,r6,- brz filltwo /* * Set delay ticks = (icol>>4)+3 */ mov 017<<4,brg and brg,r2,brg mov brg,brg>> mov brg,brg>> mov brg,brg>> mov brg,brg>> mov 3,r3 add brg,r3 /* * If delay > 6 then set delay = 6 */ mov 6,brg sub brg,r3,- brc 1f mov r3,brg 1: /* * Go to delay */ br delay /* * Carriage-return delay type 2 */ cr2: /* * If OFILL is set then go to fillfour */ mov OFILL,brg orn brg,r6,- brz fillfour /* * Schedule a delay */ mov 5,brg /* * Go to delay */ br delay /* * Carriage-return delay type 3 */ cr3: /* * If OFILL is set then go to fill40 */ mov OFILL,brg orn brg,r6,- brz fill40 /* * Schedule a .15 second delay */ mov 9,brg /* * Go to delay */ br delay /* * Translate carriage return to newline */ xmtnl: mov NL,brg mov brg,odl br nlpart3 /* * Entered here from isnl when neither ONLRET nor ONLCR is set */ nlpart3: /* * If newline delay is not enabled then go to sendit */ mov NLDELAY,brg orn brg,r5,- brz 1f br sendit 1: /* * Schedule a .083 second delay */ mov 5,brg /* * Go to delay */ br delay /* * Process a horizontal tab control character. */ isht: /* * If we are expanding tabs into spaces then go to ht3 */ mov HTDELAY,brg orn brg,r5,- brz ht3 /* * Save the column pointer */ mov ICOL,brg add brg,r10,mar mov mem,r2 /* * Update the column pointer */ mov mem,r1 mov 7,brg or brg,r1 inc r1,mem /* * Get the delay type for horizontal tabs. If the delay type is * one then go to ht1; else if the delay type is two then go to ht2; * else go to sendit */ mov HTDELAY,brg and brg,r5,brg mov 0,brg>> mov 0,brg>> mov 0,brg>> br0 ht1 br1 ht2 br sendit /* * HT delay type 1 */ ht1: /* * If OFILL is set then go to filltwo */ mov OFILL,brg orn brg,r6,- brz filltwo /* * Calculate delay ticks = 1 - (icol|~7) */ mov 7,brg orn brg,r2,brg mov 1,r1 sub brg,r1 /* * If delay < 5 then go to sendit */ mov 5,brg sub brg,r1,- brc sendit mov r1,brg /* * Go to delay */ br delay /* * HT delay type 2 */ ht2: /* * If OFILL is set then go to filltwo */ mov OFILL,brg orn brg,r6,- brz filltwo /* * Schedule a .1 second delay */ mov 6,brg /* * Go to delay */ br delay /* * HT delay type 3: Expand horizontal tab into spaces */ ht3: /* * Calculate the number of spaces needed * * The number is calculated by evaluating 7 & ~icol */ mov ICOL,brg add brg,r10,mar mov 0,r0 orn mem,r0 mov 7,brg and brg,r0 /* * Update the column pointer */ mov mem,r1 or brg,r1 inc r1,mem /* * Save the count of the number of spaces needed */ mov COUNT,brg add brg,r10,mar mov r0,mem /* * Put a space into odl */ mov SP,brg mov brg,odl /* * Set state = 3 (expanding horizontal tab) */ mov STATE,brg add brg,r10,mar mov 3,mem /* * Go to sendit */ br sendit /* * Process a backspace character */ isbs: /* * If the column pointer is not already zero then decrement it */ mov ICOL,brg add brg,r10,mar mov mem,r1 dec r1 brz 1f mov r1,mem 1: /* * If backspace delays have not been requested then go to sendit */ mov BSDELAY,brg orn brg,r5,- brz 1f br sendit 1: /* * If OFILL is set then go to fillone */ mov OFILL,brg orn brg,r6,- brz fillone /* * Schedule a .05 second delay */ mov 3,brg /* * Go to delay */ br delay /* * Process a vertical-tab character */ isvt: /* * If form-feed delays have not been requested then go to sendit */ mov VTDELAY,brg orn brg,r5,- brz 1f br sendit 1: /* * Schedule a two-second delay */ mov 127,brg /* * Go to delay */ br delay /* * Process a form-feed character */ isff: /* * If form-feed delays have not been requested then go to sendit */ mov FFDELAY,brg orn brg,r5,- brz 1f br sendit 1: /* * Schedule a two-second delay */ mov 127,brg /* * Go to delay */ br delay /* * Schedule one fill character */ fillone: mov 1,brg br fdelay /* * Schedule two fill characters */ filltwo: mov 2,brg br fdelay /* * Schedule four fill characters */ fillfour: mov 4,brg br fdelay /* * Schedule the appropriate number of fill characters for a * Teletype 40 printer or a GE Terminet 1200 */ fill40: mov 36,brg sub brg,r2,brg brc sendit mov 0,r0 sub brg,r0,brg br fdelay /* * Schedule a time delay on a given line * * The amount of delay needed has already been calculated. * Register brg contains the number of 16.7 msec ticks needed * for the delay. The character which requires time fill has not * yet been passed to the DZ11. */ delay: /* * If delay == 0 then go to sendit */ mov brg,r1 dec r1 brz sendit /* * Add 6 to the delay count and save the result in the LTE * * The reason for adding 6 to the delay count is roughly as follows: * * 6/60 = .1 second, which is one character time at 110 baud; * this compensates for the double-buffering in the DZ11; * at speeds greater than 110 baud it overcompensates, but this is * traditional */ mov COUNT,brg add brg,r10,mar mov 6,brg add brg,r1,mem /* * Set STATE = 2 */ mov STATE,brg add brg,r10,mar mov 2,mem /* * Go to sendit */ br sendit /* * Schedule a time delay on a given line * * The amount of delay needed has already been calculated. * Register brg contains the number of character times needed * for the delay. The character which requires time fill has not * yet been passed to the DZ11. * * This code differs from the delay code above by using fill * characters rather than timed pauses */ fdelay: /* * If delay == 0 then go to sendit */ mov brg,r1 dec r1,- brz sendit /* * Put the delay count in the lte */ mov COUNT,brg add brg,r10,mar mov r1,mem /* * Set STATE = 4 (Sending fill characters) */ mov STATE,brg add brg,r10,mar mov 4,mem /* * Go to sendit */ br sendit /* * Output data request with state == 2 (sending a character that needs * time fill) * * Note: The line was put into state 2 when we passed the * character that needs time fill to the DZ11. Since the DZ11 * is double-buffered, we get another output data request when * the DZ11 actually starts sending the character that needs * time fill. * At this point we turn off the enable bit and put the lte into the * twait state. * * Note that, because of double-buffering in the DZ11, the wait * time is overlapped with the time required to send the character * that needs time fill. */ odrst2: /* * Put this lte into the twait state */ mov r10,mar mov 5,mem /* * Go to disable */ br disable /* * Output data request with state == 3 (expanding horizontal tab) */ odrst3: /* * Decrement the count field of the lte. If the result is * negative then go to resume */ mov COUNT,brg add brg,r10,mar mov mem,r0 dec r0,mem brz resume /* * Put a space character into odl */ mov SP,brg mov brg,odl /* * Go to sendit */ br sendit /* * Output data request with state == 4 (sending fill characters) */ odrst4: /* * Decrement the count field of the lte. If the result is * negative then go to resume */ mov COUNT,brg add brg,r10,mar mov mem,r0 dec r0,mem brz resume /* * Put a fill character into odl */ mov DEL,brg mov brg,odl mov OFDEL,brg orn brg,r6,- brz 1f mov NUL,brg mov brg,odl 1: /* * Go to sendit */ br sendit /* * Output data request with state == 5 (twait) * * This may happen if an express character has been sent while in this state */ odrst5: br disable /* * The following code is used to restart a line which has been * delaying or expanding a horizontal tab character */ resume: /* * Set state = 1 (sending normal data) */ mov STATE,brg add brg,r10,mar mov 1,mem /* * Go to odrst1 */ br odrst1 /* * Send one character on the specified line. The character to be * sent has already been placed in odl */ sendit: /* * Set up a unibus request to put one byte into TBUF */ mov csrget,mar mov mem,r0|mar++ mov mem,r1|mar++ mov mem,r2 mov 6,brg add brg,r0,oal adc r1,brg mov brg,oah adc r2 mov nprx,r0 mov VEC4,brg and brg,r0 asl r2 asl r2,brg or brg,r0,nprx mov BYTE|OUT|NRQ,brg mov brg,npr /* * Wait for the unibus transfer to complete. * If an error occurs then go to buserr1. */ BUSWAIT(buserr1) /* * Go to dispret */ br dispret /* * Set the break bit in the dz. This code is entered from * cmdin after output is drained. */ break: /* * Set up a unibus request to set the break bit */ mov enblbits,brg add brg,r7,mar mov %enblbits,%mar mov mem,r0 mov brkbits,mar mov %dzst,brg add brg,r8,%mar or mem,r0,mem mov mem,odh mov csrget,mar mov mem,r0|mar++ mov mem,r1|mar++ mov mem,r2 mov 7,brg add brg,r0,oal adc r1,brg mov brg,oah adc r2 mov nprx,r0 mov VEC4,brg and brg,r0 asl r2 asl r2,brg or brg,r0,nprx mov BYTE|OUT|NRQ,brg mov brg,npr /* * Wait for the unibus transfer to complete. * If an error occurs then go to buserr1. */ BUSWAIT(buserr1) /* * Set OUTBRK */ mov FLAGS1,brg add brg,r10,mar mov mem,r0 mov OUTBRK,brg or brg,r0,mem /* * Delay for 250 milliseconds before turning off the break bit */ mov COUNT,brg add brg,r10,mar mov 15,mem /* * Set state = 5 */ mov STATE,brg add brg,r10,mar mov 5,mem /* * Return to caller */ RETURN /* * The following code is used to turn off the break bit */ ubreak: /* * Clear the KMC copy of the break bit for this line * and set up a unibus request to clear the corresponding bit * in the DZ11 */ mov enblbits,brg add brg,r7,mar mov %enblbits,%mar mov mem,r0 mov brkbits,mar mov %dzst,brg add brg,r8,%mar and mem,r0 xor mem,r0,mem mov mem,odh mov csrget,mar mov mem,r0|mar++ mov mem,r1|mar++ mov mem,r2 mov 7,brg add brg,r0,oal adc r1,brg mov brg,oah adc r2 mov nprx,r0 mov VEC4,brg and brg,r0 asl r2 asl r2,brg or brg,r0,nprx mov BYTE|OUT|NRQ,brg mov brg,npr /* * Wait for the unibus transfer to complete. * If an error occurs then go to buserr1. */ BUSWAIT(buserr1) /* * Reset OUTBRK */ mov FLAGS1,brg add brg,r10,mar mov mem,r0 mov ~OUTBRK,brg and brg,r0,mem /* * Schedule a delay for uart to reset */ mov COUNT,brg add brg,r10,mar mov 2,mem /* * Return to caller */ RETURN /* * Subroutine to enable a line */ enable: /* * Set up a unibus request to enable the line */ mov enblbits,brg add brg,r7,mar mov %enblbits,%mar mov mem,r0 mov actline,mar mov %dzst,brg add brg,r8,%mar or mem,r0,mem mov mem,odl mov csrget,mar mov mem,r0|mar++ mov mem,r1|mar++ mov mem,r2 mov 4,brg add brg,r0,oal adc r1,brg mov brg,oah adc r2 mov nprx,r0 mov VEC4,brg and brg,r0 asl r2 asl r2,brg or brg,r0,nprx mov BYTE|OUT|NRQ,brg mov brg,npr /* * Wait for the unibus transfer to complete. * If an error occurs then go to buserr0. */ BUSWAIT(buserr1) /* * Return to caller */ RETURN /* * The following code is used to turn off the transmit-enable bit * at the beginning of a timed delay period or when there are no * characters to transmit */ disable: /* * Clear the KMC copy of the transmit-enable bit for this line * and set up a unibus request to clear the corresponding bit * in the DZ11 */ mov enblbits,brg add brg,r7,mar mov %enblbits,%mar mov mem,r0 mov actline,mar mov %dzst,brg add brg,r8,%mar and mem,r0 xor mem,r0,mem mov mem,odl mov csrget,mar mov mem,r0|mar++ mov mem,r1|mar++ mov mem,r2 mov 4,brg add brg,r0,oal adc r1,brg mov brg,oah adc r2 mov nprx,r0 mov VEC4,brg and brg,r0 asl r2 asl r2,brg or brg,r0,nprx mov BYTE|OUT|NRQ,brg mov brg,npr /* * Wait for the unibus transfer to complete. * If an error occurs then go to buserr1. */ BUSWAIT(buserr1) /* * Go to dispret */ br dispret /* * This two entry point subroutine is called at oflush to * flush any current output regardless of the current state * of the line. Oflush is also called when the last character * of normal output has been sent out and the dz is requesting * another character. This simply bookkeeps the LTE. The * entry point oqueue is called when the last character in * the current output buffer is used so the host may reload * another buffer before the dz requests another character. */ oflush: mov %dzst,brg add brg,r8,%mar /* * Clear output flags */ mov FLAGS,brg add brg,r10,mar mov ~(SENDSAVE|SENDHIGH|NLEXP),brg mov brg,r0 and mem,r0,mem mov FLAGS1,brg add brg,r10,mar mov mem,r0 mov ~(TTSTOP|PREVNB),brg and brg,r0,mem mov NCH,brg add brg,r10,mar mov 0,mem /* * Set state = 0 */ mov STATE,brg add brg,r10,mar mov 0,mem /* * See if there is an output buffer */ oqueue: mov %dzst,brg add brg,r8,%mar mov OUTBUF,brg add brg,r10,mar mov mem,r4 brz oqret mov NIL,mem mov 03,brg and brg,r4,%mar mov ~03,brg and brg,r4,mar /* * Set link to next queue entry = NIL */ mov NIL,mem|mar++ /* * Chain this queue entry to the end of the output-buffer-completion- * report queue */ mov tailoutq,mar mov %tailoutq,%mar mov mem,r5 brz 1f mov r4,mem mov 3,brg and brg,r5,%mar mov ~3,brg and brg,r5,mar mov r4,mem br 2f 1: mov r4,mem mov headoutq,mar mov r4,mem 2: /* * Set a flag to indicate that the output-buffer-completion-report * queue is non-empty */ mov CHKOUTQ,brg or brg,r14 oqret: RETURN /* * The unibus transfer failed to complete within a reasonable time */ buserr1: /* * Clear the non-existent memory bit */ mov nprx,r0 mov ~(BRQ|ACLO|NEM),brg and brg,r0,nprx ERROR(BUSERR1) /* * Go to dispret */ br dispret /* * Return to top of dispatcher loop in main segment */ dispret: mov %disp,brg mov brg,pcr jmp disp /* * Error loops for debugging */ errh: mov NIL,mem ERROR(ERRH) br dispret endseg1: