:IF[WithTOR]; *********************************************

INSERT[UIBDefs];
TITLE[UIB];
%
Edit by Fiala 18 March 1982: add WithTOR conditional for integration.
Edit by Jim Frandeen September 15, 1980 4:34 PM Change DoInt to
NotifyInterrupt with tasking return

Edit by rej March 27, 1980 3:16 PM OUTPUT fix, cursY fix

Edit by rej March 27, 1980 10:10 AM remove LOADPAGE from cursor load

Edit by rej March 21, 1980 3:18 PM code for multiple channel buffer
transfers

Edit by rej March 19, 1980 1:23 PM pstore4 mod

Edit by fsb January 25, 1980 10:06 AM D0lang version 6 changes

Edit by rej December 27, 1979 10:26 AM htab←300 to sel 16x16 cursor

Edit by rej December 27, 1979 10:11 AM Loadpage bug fixed for vs and scb interrupts

Edit by rej October 19, 1979 2:28 PM change rtclow to 355
Edit by rej October 1, 1979 11:14 AM no more output to select
InputChannelBuffer

Edit by rej September 28, 1979 3:48 PM fix notify
Edit by SRD September 19, 1979 2:16 PM Make naked notify a NOP because it
destroys uibChannelTransferFlags.
Edit by rej September 12, 1979 10:58 AM init goes to EndField rather than vs
Edit by rej September 11, 1979 3:39 PM init state save

Edit by rej August 24, 1979 8:32 AM
both alto and d0 modes
Edit by rej August 24, 1979 11:12 AM
pull blanking out of alto cursor
Edit by rej August 24, 1979 5:03 PM got rid of D0 mode

%

SetTask[uibTask];

uibInit:
uibCSBbase←uibrhCSBbase, At[uibInitLoc];
uibCSBbase←(uibCSBbase) OR (uiblhCSBbase);
uibCSBbase1←uibrhCSBbase1;
uibCSBbase1←(uibCSBbase1) OR (uiblhCSBbase1);

uibControlReg ← (uibAllowWU);
OUTPUT[uibControlReg,uibControlRegAddr]; *ALLOW WAKEUPS
*set keyboard words to -1 (key up)
uibBase1←zero;
uibBase ← AuiblhMouseButtonBase;
uibBase ← (uibBase) or (AuibrhMouseButtonBase);* 177030
uibTempReg1 ← (ZERO)-1;
uibTempReg2← (ZERO)-1;
uibTempReg3 ← (ZERO)-1;
uibTempReg4 ← (ZERO)-1;
uibLink←zero;
PSTORE4[uibBase,uibTempReg1,0];* mouse,keyset,etc.
PSTORE4[uibBase,uibTempReg1,4];* keyboard[0:3].
t←uibSCBsavedQuadOffset;
PSTORE4[uibCSBbase, uibTempReg1];*just to be safe
t←uibChannelTransferFlagsOffset;*set to no transfer in progress
PSTORE1[uibCSBbase, uibLink];*uibLink just happens to have a zero

LoadPage[uibPage];
GoToP[.+1];

OnPage[uibPage];
CALL[uibInitReturn];
************************************************
*First wakeup comes here.
************************************************
uibFirstInst:
GOTO[AuibENDFIELD], uibBase← AuibMemPage1;*set base back to ALTO IO page
uibInitReturn:
RETURN;

**********************************************
*END DISPLAY
ALTO/UIB
**********************************************
SETTASK[uibTASK];

**********************************************
*end of display - send black background and fetch ALTO DCB head
**********************************************
ONPAGE[uibPage];
AuibENDFIELD:
uibHTAB←300C; *send black background
OUTPUT[uibHTAB,uibHTABaddr];
uibBASE1 ← zero;
uibBase← AuibMemPage1;
uibCSBbase←uibrhCSBbase;
uibCSBbase←(uibCSBbase) OR (uiblhCSBbase);
uibCSBbase1←uibrhCSBbase1;
uibCSBbase1←(uibCSBbase1) OR (uiblhCSBbase1);
t←AuibrhDCBheadAddr;
TASK, IOSTROBE, PFETCH2[uibBASE,uibLINK];*fetch alto DCBhead and INTmask

AuibUpdateRTC:
uibTempReg1 ← 355C; *Point to RTCLOW
t← nSTKP;
STKP ← uibTempReg1, uibTempReg1 ← T,NoRegILockOK;
uibTempReg1 ← (uibTempReg1) XOR (377C); *STKP read inverted
STACK ←(STACK) AND NOT (100000C),GOTO[AuibNORTCOV,R>=0];
*must update RTC
t←30c;
PFETCH1[uibBASE,uibTempReg2];*can’t return untill STKP restored
uibTempReg2 ← (uibTempReg2) + 1;
PSTORE1[uibBASE,uibTempReg2];
AuibNORTCOV:
STKP ← uibTempReg1;

CALL[uibSyncWithVS];
uibSyncWithVS:
INPUT[uibStatusReg1, uibStatusReg1Addr];
LU←LDF[uibStatusReg1, 15,1] ;*vertical ?
GOTO[AuibInitCursorLoading,ALU#0], uibScanLineCount←uibNonDisplayCount;
IOSTROBE;
RETURN;


**********************************************
*CURSOR LOADING
ALTO
**********************************************
ONPAGE[uibPage];
AuibInitCursorLoading:
t←LDF[uibStatusReg1,14,1];*check field
SKIP[ALU#0], uibCursX←AuibLoadHiOrderNibble;*select upper or lower half of RAM
uibCursX←(uibCursX) OR (100000c);
uibCursBitmapPtr←t;*t contains one or zero depending on field
t←uibCursBitmapPtr←(uibCursBitmapPtr)+(AuibrhCursBase);
uibCursLineCount←(7c);*eight lines/field

AuibCursNextLineSetup:
GOTO[AuibCursOff, R<0], uibCursLineCount←(uibCursLineCount)-1;
OUTPUT[uibCursX, uibCursorPointerAddr];*set RAM pointer for next line
CALL[uibSleep], PFETCH1[uibBase, uibCursWord];*fetch 4 alto nibbles/line

AuibCursLoad:
t←uibCursBitmapPtr←(uibCursBitmapPtr)+(2c);*set ptr for next word;
AuibCursOutputNibbles:
CALL[AuibCursAltoNibbleLoop], uibCursNibbleCount←(3c);*4 alto nibbles/line
GOTO[AuibCursNextLineSetup], uibCursX←(uibCursX)+(4000c);*add one to line number

**********************************************
*transfer subroutine
send 4 nibbles
**********************************************
AuibCursAltoNibbleLoop:
*loop thru 4 nibbles
GOTO[AuibCursAltoNibbleLoopRTN, R<0], uibCursNibbleCount←(uibCursNibbleCount)-1;
OUTPUT[uibCursWord, AuibCursMemAddr];
GOTO[AuibCursAltoNibbleLoop], uibCursWord←LSH[uibCursWord,4];
AuibCursAltoNibbleLoopRTN:
uibCursWord←uibCursWord, RETURN;*output gotcha

AuibCursOff:
CALL[uibSleep], uibCursX←(uibTurnOffCursor);
GOTO[uibFifo], OUTPUT[uibCursX, uibCursorPointerAddr]; *turn off cursor

**********************************************
*FIFO
**********************************************
ONPAGE[uibPage];
uibFifo:
**********************************************
*restore state:
*
1) retrieve saved quad from CSB
*
2) retrieve ChannelTransferFlags word from CSB
**********************************************
AuibFIFOstateRestore:
t←uibChannelTransferFlagsOffset;
PFETCH1[uibCSBbase, uibChannelTransferFlags];
t←uibSCBsavedQuadOffset;
GOTO[uibProcessFifo], PFETCH4[uibCSBbase, uibQuadWord0];

**********************************************
*process fifo entries
**********************************************
uibProcessFifo:
uibFifoScanLineLoop:
*** do untill time for display (uibScanlineCount<0)
CALL[uibNOPreturn], IOSTROBE;
GOTO[uibFIFOstateSave, R<0], uibScanLineCount←(uibScanLineCount)-1;
GOTO[uibEntryLoop], uibFifoEntryCount←(uibFifoEntriesPerScanLine);
uibEntryLoopEnd:
GOTO[uibFifoScanLineLoop,R<0], uibFifoEntryCount←(uibFifoEntryCount)-1;
NOP;*placement
CALL[uibNOPreturn];*task at end of each entry
uibEntryLoop:
*** do while entry in Fifo(IOATTEN) or channel transfer and entryCount >=0
GOTO[uibChannelTransfer, R<0], LU←uibChannelTransferFlags;*channel transfer
SKIP[IOATTEN];
GOTO[uibFifoScanLineLoop];*FIFO empty
INPUT[uibUIBdata,uibUIBdataAddr];*FIFO entry
SKIP[R<0], DISPATCH[uibUIBdata,3,4], LU←uibUIBdata;
DISP[uibFifoCommands], t←RHMASK[uibUIBdata];
DISP[uibFifoDataTypes], t←RHMASK[uibUIBdata];
**********************************************
*fifo state save
**********************************************
uibFIFOstateSave:
t←uibSCBsavedQuadOffset;
nop; *PSTORE4 rule
CALL[uibNOPreturn], PSTORE4[uibCSBbase, uibQuadWord0];
t←uibChannelTransferFlagsOffset;
PSTORE1[uibCSBbase, uibChannelTransferFlags];
uibALTOvsInterrupt:
nop;*LOADPAGE GOTCHA
LOADPAGE[NotifyInterruptPage];
IOSTROBE, CALLp[NotifyInterrupt], t←uibALTOvsInterruptMask;
GOTO[uibALTOdisplay];



**********************************************
*FIFO
COMMANDS AND DATA
**********************************************
uibFifoCommands:
uibFetchKeyQuad:
AT[uibFifoCommandsDispLoc,0],
AuibFetchKeyQuad:
uibBase←AuiblhKeyBoardBase;
uibBase←(uibBase) OR (AuibrhKeyBoardBase);
GOTO[uibEntryLoopEnd], PFETCH4[uibBase,uibQuadWord0,0];

uibStoreKeyQuad:
AT[uibFifoCommandsDispLoc,1],
AuibStoreKeyQuad:
uibBase←AuiblhKeyBoardBase;
uibBase←(uibBase) OR (AuibrhKeyBoardBase);
GOTO[uibEntryLoopEnd], PSTORE4[uibBase,uibQuadWord0,0];

uibUpdateMouse:
AT[uibFifoCommandsDispLoc,2],
t←uibMouseDelXY;*save before clobbering with PFETCH
CALL[uibNOPreturn], uibTempReg4←t;
AuibUpdateMouse:
uibBase←AuibMemPage1;
uibBase←(uibBase) + (AuibrhMouseXYBase);
CALL[uibCalcMouseXY], PFETCH4[uibBase,uibMouseXcoord,0];
GOTO[uibEntryLoopEnd], PSTORE4[uibBase,uibMouseXcoord,0];
uibCalcMouseXY:
t←RHMASK[uibTempReg4];
SKIP[NOH2BIT8], uibMouseXcoord←(uibMouseXcoord)+t;
uibMouseXcoord←(uibMouseXcoord) + (177400c);*extend sign bit
t←LDF[uibTempReg4,0,10];
SKIP[NOH2BIT8],uibMouseYcoord←(uibMouseYcoord)+t;
uibMouseYcoord←(uibMouseYcoord) + (177400c);*extend sign bit
USECTASK;
RETURN;

uibUpdateMouseButtons:
AT[uibFifoCommandsDispLoc,3],
AuibUpdateMouseButtons:
uibBase←AuiblhMouseButtonBase;
uibBase←(uibBase) OR (AuibrhMouseButtonBase);
PFETCH4[uibBase, uibMouseButtonWord,0];
t←uibMouseButtonWord←(LHMASK[uibMouseButtonWord]) OR t;*zero = depressed
uibQuadWord3←t;*update 0th and 3rd word of quad word
NOP;*here to allow write of uibTempReg4
GOTO[uibEntryLoopEnd], PSTORE4[uibBase, uibMouseButtonWord,0];

uibFetchSCBcsbQuad0:
AT[uibFifoCommandsDispLoc,4],
t←uibSCBcsbQuad0offset;
GOTO[uibEntryLoopEnd], PFETCH4[uibCSBbase,uibQuadWord0];

uibStoreSCBcsbQuad0:
AT[uibFifoCommandsDispLoc,5],
t←uibSCBcsbQuad0offset;
GOTO[uibEntryLoopEnd], PSTORE4[uibCSBbase,uibQuadWord0];

uibFetchSCBcsbQuad1:
AT[uibFifoCommandsDispLoc,6],
t←uibSCBcsbQuad1offset;
GOTO[uibEntryLoopEnd], PFETCH4[uibCSBbase,uibQuadWord0];

uibStoreSCBcsbQuad1:
AT[uibFifoCommandsDispLoc,7],
t←uibSCBcsbQuad1offset;
GOTO[uibEntryLoopEnd], PSTORE4[uibCSBbase,uibQuadWord0];

******
Set up control for transfer
uibInputChanTransfer:
AT[uibFifoCommandsDispLoc,10],
uibChannelTransferFlags←(uibChannelTransferFlags) OR (uibInputChannelFlag);
uibOutputChanTransfer:
AT[uibFifoCommandsDispLoc,11],
uibChannelTransferFlags←(uibChannelTransferFlags) OR (uibExecuteChannelTransfer);
t←uibChannelIOCBbaseOffset;
PFETCH2[uibCSBbase,uibChannelIOCBbase];*fetch pointer to IOCB table
t←LDF[uibUIBdata,12,6];*select IOCB
LU←uibChannelIOCBbase;
PFETCH4[uibChannelIOCBbase,uibChannelBuffBase];*fetch IOCB
uibUIBdata←(LDF[uibUIBdata,10,2]);*n th additional transfer of a multi-buffer transfer
t←LSH[uibUIBdata,10];*multiply by buffer size (256d)
GOTO[uibEntryLoopEnd], uibChannelBuffPtr←(uibChannelBuffPtr)+t; * (start+n*256)

uibStoreTouch:
AT[uibFifoCommandsDispLoc,12],
SKIP[R EVEN], LU←uibAltoModeSwitch;
uibDisplayStatus←(uibDisplayStatus) OR (uibDisplayStatusTouchMask);
GOTO[uibEntryLoopEnd], PSTORE2[uibCSBbase,uibTouchX,uibTouchOffset];


uibNotifyMesaSCBdriver:
AT[uibFifoCommandsDispLoc,13],
t←uibFifoEntryCount;*save it , since NotifyInterrupt uses registers 0&1
uibTempReg4←t;
t←uibSCBinterruptMaskOffset;
PFETCH1[uibCSBbase,uibSCBinterruptMask];
LOADPAGE[NotifyInterruptPage];
CALL[NotifyInterrupt], t←uibSCBinterruptMask;
t←uibTempReg4;*restore fifoentrycount and channeltransferflags
uibFifoEntryCount←t;
GOTO[uibEntryLoopEnd], uibChannelTransferFlags←zero;




uibFifoDataTypes:
uibReplaceQuadByte0:
AT[uibFifoDataTypesDispLoc,0],
GOTO[uibEntryLoopEnd], uibQuadWord0←(LHMASK[uibQuadWord0]) OR t;
uibReplaceQuadByte1:
AT[uibFifoDataTypesDispLoc,1],
t←LSH[uibUIBdata,10];
GOTO[uibEntryLoopEnd], uibQuadWord0←(RHMASK[uibQuadWord0]) OR t;
uibReplaceQuadByte2:
AT[uibFifoDataTypesDispLoc,2],
GOTO[uibEntryLoopEnd], uibQuadWord1←(LHMASK[uibQuadWord1]) OR t;
uibReplaceQuadByte3:
AT[uibFifoDataTypesDispLoc,3],
t←LSH[uibUIBdata,10];
GOTO[uibEntryLoopEnd], uibQuadWord1←(RHMASK[uibQuadWord1]) OR t;

uibReplaceQuadByte4:
AT[uibFifoDataTypesDispLoc,4],
GOTO[uibEntryLoopEnd], uibQuadWord2←(LHMASK[uibQuadWord2]) OR t;
uibReplaceQuadByte5:
AT[uibFifoDataTypesDispLoc,5],
t←LSH[uibUIBdata,10];
GOTO[uibEntryLoopEnd], uibQuadWord2←(RHMASK[uibQuadWord2]) OR t;
uibReplaceQuadByte6:
AT[uibFifoDataTypesDispLoc,6],
GOTO[uibEntryLoopEnd], uibQuadWord3←(LHMASK[uibQuadWord3]) OR t;
uibReplaceQuadByte7:
AT[uibFifoDataTypesDispLoc,7],
t←LSH[uibUIBdata,10];
GOTO[uibEntryLoopEnd], uibQuadWord3←(RHMASK[uibQuadWord3]) OR t;
uibMouseDeltaX:
AT[uibFifoDataTypesDispLoc,10],
GOTO[uibEntryLoopEnd], uibMouseDelXY←(LHMASK[uibMouseDelXY]) OR t;
uibMouseDeltaY:
AT[uibFifoDataTypesDispLoc,11],
t←LSH[uibUIBdata,10];
GOTO[uibEntryLoopEnd], uibMouseDelXY←(RHMASK[uibMouseDelXY]) OR t;


**********************************************
*CHANNEL TRANSFER
**********************************************
uibChannelTransfer:
GOTO[uibChannelTransferDone,R<0], uibChannelBlockCnt←(uibChannelBlockCnt)-1;
t←uibChannelBuffPtr;
SKIP[R EVEN], LU←uibChannelTransferFlags;
SKIP, IOSTORE16[uibChannelBuffBase,uibInChannelBuffAddr];
IOFETCH16[uibChannelBuffBase,uibOutChannelBuffAddr];
GOTO[uibEntryLoopEnd], uibChannelBuffPtr←(uibChannelBuffPtr)+(20c);
uibChannelTransferDone:
GOTO[uibFifoScanLineLoop], uibChannelTransferFlags←zero;

**********************************************
*ALTO DISPLAY
**********************************************
**********************************************
*set line count , cursor X and Y, and set up first DCB
**********************************************
uibALTOdisplay:
AuibLastNonDisplayLine:
uibBase←AuibMemPage1;
t←AuibrhCursXYbase;
Pfetch2[uibBase, uibCursX];*fetch cursor xy coordinates
CALL[uibSetCursXandY], uibVideoUnloadPtr←uibBufferSize;*sets video unload ptr to no unload
uibScanLineCount←uiblhLinesPerField;
GOTO[AuibDCBdone],uibScanLineCount ← (uibScanLineCount) OR (uibrhLinesPerField);
**********************************************
*check for new DCB
**********************************************
AuibDCBdone:
t←(uibLink);
uibBASE1 ← 0C, GOTO[AuibGetNextDCB,ALU#0];
*The DCB chain is exhausted.
uibVideoUnloadPtr←uibBufferSize;*set unload pointer to no unload
call[AuibCheckCursor], OUTPUT[uibVideoUnloadPtr,uibBPREG];*output unload pointer
goto[AuibNoMoreDCBs];
**********************************************
*We have displayed the entire chain and the field is not done.
*Wait for end of field.
**********************************************
AuibPreNoMoreDCBs:
NOP;
call[AuibCheckCursor];
AuibNoMoreDCBs:
uibScanLineCount ← (uibScanLineCount)-1, GOTO[AuibPreNoMoreDCBs,R>=0];
goto[AuibENDFIELD];

**********************************************
*FETCH NEXT DCB
ALTO
**********************************************
AuibGetNextDCB:
uibBASE ← T; *T contains LINK. Set base register to point to next DCB
nop;
PFETCH2[uibBASE,uibDBA,2]; *Fetch DBA,SLC
uibVideoUnloadPtr←377c;
TASK, PFETCH2[uibBASE,uibLINK,0]; *Fetch LINK,NWRDS
uibVideoLoadPtr ← uibBufferSize; *Init for later
**********************************************
*Check for long pointer addressing
**********************************************
LU←uibSLC,goto[AuibLong,R<0];
*Short Pointer
T ← uibDBA;
uibBASE ← T,goto[AuibEvenOdd];
*Long Pointer
AuibLong:
PFETCH2[uibBASE,uibBASE,4]; *fetch directly into the base register
uibSLC ← (uibSLC) AND NOT (100000C); *clear the sign bit
**********************************************
*adjust DBA for odd,even field
*Bias uibDCB.SLC by -2. Note that if uibDCB.SLC = 0 OR 1, at least one
*scan line will be displayed.
**********************************************
AuibEvenOdd:
T← RHMASK[uibNWRDS];
LU ← LDF[uibStatusReg1,14,1];*Check EvenField
uibSLC ← (uibSLC)-(2C),GOTO[AuibDBAok,ALU#0];
AuibDBAadjust:
uibBASE ← (uibBASE)+(T);
**********************************************
*set VideoLoadPtr for next scan, uibBufferSize-NWRDS-residue
*hex align base register (DBA and not 17)
*DBA contains residue (DBA(mod 20))
**********************************************
AuibDBAok:
uibVideoUnloadPtr←(uibVideoUnloadPtr)-t;
uibVideoLoadPtr←(uibVideoLoadPtr)-(t);
t←LDF[uibBASE,14,4]; *Set up VideoLoadPtr for the next scan
uibDBA ← t;
t←uibVideoLoadPtr←(uibVideoLoadPtr)-(t);
uibBASE ← (uibBASE) and not (17C);
uibVideoPtrs←(LSH[uibVideoUnloadPtr,10]) OR t;*OR in load pointer
uibVideoPtrs←LCY[uibVideoPtrs,10];*swap low and high bytes
OUTPUT[uibVideoPtrs,uibBPREG];*output video pointers
**********************************************
*fix up the high half of the base register
**********************************************
T ← lsh[uibBASE1,10];
call[AuibCheckCursor], uibBASE1 ← (RHMASK[uibBASE1])+(T)+1;

**********************************************
*VIDEO
ALTO
**********************************************
*uibBase points to closest hex word below the bitmap for the DCB
*uibDBA contains the offset from uibBase pointing to the first word of the scan line
*uibDWA is the offset from uibBase used in IOFETCHT16 transfers
*uibVideoLoadPtr is initially contains the pointer for writing video data into the haredware buffer
* after it is sent to the UIB, it is used as a counter which carries when all the data for a scanline has * been transferred
*uibVideoUnloadPtr contains the pointer for reading data out of the hardware buffer
**********************************************

**********************************************
*1st line of a DCB only - output HTAB
**********************************************
AuibNewDCB:
uibHTAB←377c;
T ← LDF[uibNWRDS,2,6]; *calculate HTAB
LU←LDF[uibNWRDS,1,1]; *black background bit
uibHTAB ← (uibHTAB) - (T),GOTO[.+2,ALU#0];
uibHTAB ← (uibHTAB) AND NOT (200C);
OUTPUT[uibHTAB,uibHTABaddr],goto[AuibVideoData]; *send it

**********************************************
*last thing you do after processing a scan line which is not the last of a DCB
**********************************************
AuibNormalVideoExit:
call[AuibCheckCursor], OUTPUT[uibVideoPtrs,uibBPREG];*output video pointers

**********************************************
*set pointer for writing into UIB buffer and start first transfer
**********************************************
AuibVideoData:
T ← (uibDBA) AND NOT (17C);
uibDWA ← T;
AuibDWT:
IOFETCH16[uibBASE,uibDATABUFaddr];

**********************************************
*Calculate the read buffer pointer, the count, and next line’s DBA
*in the shadow of the first IOFETCH (If there is to be more than one).
**********************************************
uibVideoLoadPtr ← (uibVideoLoadPtr)-(uibBuffLessOneBlk); *From here on, uibVideoLoadPtr
*is usedfor the count (-(NWRDS + (ADDRESS and 17B)))
T←RHMASK[uibNWRDS];
T← (RHMASK[uibNWRDS])+(T); * T ← 2*NWRDS
uibDBA←(uibDBA)+(T); *uiDBA is now set up for the next scan line
uibDWA←T←(uibDWA)+(20C),CALL[AuibDWT1];

**********************************************
*Loop for second through Nth IOFETCH.
**********************************************
AuibDWT1:
uibVideoLoadPtr←(uibVideoLoadPtr)+(20C),GOTO[AuibBUFD2,R>=0];
IOFETCH16[uibBASE,uibDATABUFaddr],GOTO[AuibBUFD2X,ALU>=0];
uibDWA←T←(uibDWA)+(20C),RETURN;

**********************************************
*finished with scan line; end of field? end of DCB?
**********************************************
AuibBUFD2:
uibScanLineCount ← (uibScanLineCount)-1,DBLGOTO[AuibENDFIELD,AuibCONT,R<0]; *check for field done
AuibBUFD2X:
uibScanLineCount ← (uibScanLineCount)-1,DBLGOTO[AuibENDFIELD,AuibCONT,R<0];
AuibCONT:
uibSLC←(uibSLC)-1,DBLGOTO[AuibDCBDONE,AuibMDCB2,R<0];

**********************************************
*more lines in current DCB
*Calculate the next line’s uibVideoLoadPtr
*in the shadow of the last IOFETCH16
**********************************************
AuibMDCB2:
T←LDF[uibDBA,14,4];
t ← (RHMASK[uibVideoPtrs])-(t);*unload and load video ptrs differ by LDF[uibDBA,14,4]
uibVideoPtrs←(LSH[uibVideoPtrs,10]) OR t;*OR ptrs into same word
uibVideoPtrs←LCY[uibVideoPtrs,10];*swap high and low bytes
GOTO[AuibNormalVideoExit], uibVideoLoadPtr ←t;*still need uibVideoLoadPtr for transfer counter

**********************************************
*ONE LINE NOP RETURN
**********************************************
ONPAGE[uibPage];
uibNOPreturn:
RETURN;
**********************************************
*CALL IT QUITS FOR THIS SCAN LINE
**********************************************
uibSleep:
IOSTROBE, uibScanLineCount←(uibScanLineCount)-1;
RETURN;

**********************************************
*set cursX and cursY
**********************************************
uibSetCursXandY:
uibCursY←(uibCursY)+(4c);
t←(uibCursX)-(3c);*kludge
uibCursX←(zero) - t;*negate x value
t ← LDF[uibStatusReg1,14,1];*check for even/odd field
t←(LDF[uibCursY,17,1] ) XOR t;
GOTO[uibSetCursXandYRTN,ALU#0], uibCursX←LDF[uibCursX,5,13];
uibCursX←(uibCursX) OR (uibCursXeven);
uibCursY←(uibCursY)-1;
uibSetCursXandYRTN:
RETURN;

**********************************************
*CHECK CURSOR
**********************************************
*CursX is written once to start the cursor and once to turn it off

ONPAGE[uibPage];
AuibCheckCursor:
GOTO[uibCursRet, r>=0], uibCursY←(uibCursY)-(2c);*start cursor ?
LU←(uibCursY)+(4c);
GOTO[.+2,ALU<0];
GOTO[uibSendCursX];*first line of cursor; send CursX
LU←(uibCursY)+(uibCursLinesPerFrame);
GOTO[.+2, ALU<0], uibCursX←LDF[uibCursX,16,2];*maintain XC8 and XC9
GOTO[uibCursRet];
uibCursX←(uibCursX) OR (uibTurnOffCursor);*finished w cursor; turn it off
uibCursY←uibLargePositiveNumber;
uibSendCursX:
OUTPUT[uibCursX, uibCursorPointerAddr];
NOP;
uibCursRet:
IOSTROBE;
RETURN;

END[UIB];

:ELSE; ****************************************************

TITLE[No.UIB.unless.WithTOR.eq.1];

:ENDIF; ***************************************************