:TITLE[DisplayDefs];	*Last edited by Fiala 8 January 1981

SetTask[DpTask];	*Definitions for Alto-compatible UTVFC

Set[vCReg,0];		*Control register
Set[vfCReg,Add[LShift[DpTask,4],0]];	*For IOFetch4 to vCReg
  MC[ClrNC,1]; MC[AllowWU,2]; MC[OddFld,4]; MC[VS,10]; MC[Blank,20];
  MC[BlackBackground,100]; MC[IncNC,200];
  MC[AllowWU&Blank,AllowWU,Blank]; MC[OddFld&Blank,OddFld,Blank];
  MC[ClrNC&Blank,ClrNC,Blank]; MC[IncNC&Blank,IncNC,Blank];
Set[vBufStart,1];	*Buffer Starting Address
Set[vHCRam,2];		*Horizontal control ram
Set[vLdIAR,3];		*IAR[0:5] ← Start[0:5] (data is ignored)
Set[vCursor0,4];	*Channel 0 Cursor control register
*Set[vCursor1,5];	*Channel 1 Cursor control register
Set[vCursorMem0,6];	*Channel 0 Cursor Memory
*Set[vCursorMem1,7];	*Channel 1 Cursor Memory
Set[vBuf0,10];		*Channel 0 data buffer - use with Output
Set[vfBuf0,Add[LShift[DpTask,4],10]]; *Channel 0 data buffer for IOFetch
*Channel 1, 2, and 3 data buffers are 11, 12, and 13 (unused)

*Note: because more than 20b registers, Display cannot run as task 3 mod 4.
Set[vRB,LShift[And[DpTask,3],4]]; *enforces register allocation conventions
RV4[vDBuf0,vDBuf1,vTemp1,vTemp,Add[vRB,0]];	*general temporaries
				*(vTemp1 presently unused)
RV2[vLink,vNWrds,Add[vRB,4]];	*Holds DCB link word.
RV[vSize,Add[vRB,6]];		*vSize used when transmitting a DCB 
RV2[vDBA,vSLC,Add[vRB,6]];	*vDBA used when picking up a DCB
RV2[vBase,vBasehi,Add[vRB,10]];
RV[vCR,Add[vRB,12]];		*Copy of hardware control register
RV[vCursorY,Add[vRB,13]];
RV[vCurrentY,Add[vRB,14]];	*Current Display Y
RV[vCursorControl,Add[vRB,15]];
RV[vMsg,Add[vRB,16]];
RV[vCnt,Add[vRB,17]];
RV[vMsgStatus,Add[vRB,20]];
RV[vMouseXY,Add[vRB,21]];	*These three needed only for LF keyboard
RV[vButtons,Add[vRB,22]];
RV[vKeyBuffer,Add[vRB,23]];
RV[BadEndFlagCnt,Add[vRB,21]];	*These two error counters needed only for
RV[MsgType0Cnt,Add[vRB,22]];	*CSL keyboard (can deimplement if desired)

***Fix Initialize.Mc if any of these move***
RV2[vMDS177400,vMDS177400hi,72];	*base reg containing 177400b
RV2[vMDS420,vMDS420hi,74];	*base reg containing 420b
RV2[vMDS,vMDShi,76];		*base reg containing 0

RM[vZero,IP[vMDS]];

MC[WordsPerLine,46];		*38d words/scanline Alto compatible
Set[vBufSt,Sub[400,LShift[WordsPerLine!,2]]];
Set[vStart,LShift[vBufSt,6]];

%Allowed configurations are Ball monitor & Dallas keyboard with 50 mhz crystal
(ID code 3); Ball monitor and CSL keyboard with 50 mhz crystal (ID code 11b);
or CSL monitor and keyboard with 20 mhz crystal (ID code 5).  Initialization
here handles all combinations; the body of the code has two sections that are
conditionally assembled for either the CSL or Dallas keyboard.  The Dallas
keyboard driver uses a 40b-word table and about 34b mi on lfKBPage in
addition to code for the CSL keyboard.

A CSL monitor is 608 visible bits/scanline x 808 visible scanlines; the Ball
monitor is 1088 x 861, but this microcode reduces its capability to
compatibility with the CSL display by framing 608 visible bits by equal
size blanked areas to the left and right.

Monitors require that a certain amount of time be spent per scanline,
determined by the vertical sweep rate.  It was empirically determined on a
Ball (LF) monitor that sweep rate could be adjusted about +/- 15 percent, so
some flexibility in the io microcode is possible.  However, all microcode
systems must agree on timing.  Time/scanline ~ 29 us (77 fields/second) for
the LF monitor and 38 us (60 fields/sec) for the CSL monitor.

Also, time/scanline has to be divided in a specified ratio between forward
scan and horizontal sync--not much variation in this ratio is allowed.  For
the oscillators we are using, this is (1088+352) bits/scanline for the LF
monitor and (652+104) bits/scanline for the CSL monitor.  The forward scan
area consists of blanked area, image, visible constant, and blanked area.
The image+visible constant are limited by the controller to 1024 bits or less.
The visible constant would be setup by initializing the pingpong buffers to
some pattern, but this isn't done below (i.e., the size of the visible
constant is 0).

Differences among the monitors appear in initialization for HRam and in the
code commencing at vFDone, which controls vertical blank and sync timing;
HRam initialization considerations are as follows:

vBufStart = 150b, so 230b nibbles (=608 bits =38 words) of data are supplied
by the task per scanline, independent of what monitor is used.  The midline
control bit in HRam should appear half-way through the line.  For the Ball
monitor, there are 1088 bits (= 420b nibbles) in the forward scan, 352 bits
(= 130b nibbles) of horizontal sync; ML should appear 1/2 * 550b nibbles
after the start of the forward scan.  Since data begins at AAR=150b, ML
should appear at 150b+264b-number of blanked nibbles following horizontal
sync, or at AAR=434b-number of nibbles following horizontal sync.

Total vert blanking = xVSStart + xSyncLength + xBlankLength + 12d scanlines.

For the Ball monitor (LF display), lfVSStart may vary between about 11b and
300b, thereby controlling the field rate.  At 11b (77 fields/sec), no flicker
is noticeable; at 140b (65 fields/sec), flicker is just barely noticeable;
at 300b (55 fields/sec) flicker definitely degrades the picture.  Increasing
the parameter without adjusting the monitor spreads the picture vertically,
so not too much dynamic variation is permissible.

For the CSL monitor, very little variation in the vertical parameters is
possible; the current choice results in 60 fields/second.
%
MC[lfVSStart,11];	*Nscanlines - 1 before start of vert sync field B
			*(+1 added for field A).
MC[lfSyncLength,11];	*Nscanlines - 10d in which vert sync asserted
			*Spec is 18 lines of vertical sync/field
MC[lfBlankLength,15];	*Nscanlines - 1 after vert sync before starting frame

MC[cslVSStart,1];
MC[cslSyncLength,7];
MC[cslBlankLength,14];

*These are the Alto-compatible numbers
MC[vMaxYh,400];		*no. visible scan lines per field/2 -1
MC[vMaxYl,223];		*(= 808 visible scanlines/screen Alto compatible)