*-----------------------------------------------------------
Title[DisplayDefs.mc...November 23, 1982  1:23 PM...Taft];
*** Pilot-only version ***
*-----------------------------------------------------------

*-----------------------------------------------------------
* Display data structures
*-----------------------------------------------------------

* DisplayControllerStatusBlock: TYPE = MACHINE DEPENDENT RECORD [
	MC[DCSB.width, DisplayCSB, 0];		* width: CARDINAL, -- in words
	MC[DCSB.height, DisplayCSB, 1];		* height: CARDINAL, -- scan lines per field
						* -- zero height is legal
	MC[DCSB.bitMap, DisplayCSB, 2];		* bitMap: LONG POINTER, -- must be even
	MC[DCSB.cursorXCoord, DisplayCSB, 4];	* cursorXCoord: CARDINAL,
	MC[DCSB.cursorYCoord, DisplayCSB, 5];	* cursorYCoord: CARDINAL,
	MC[DCSB.wakeups, DisplayCSB, 6];	* wakeups: WORD, -- vertical field wakeup
	MC[DCSB.flags, DisplayCSB, 7];		* flags: DisplayFlags,
	MC[DCSB.mouseXCoord, DisplayCSB, 10];	* mouseXCoord: CARDINAL,
	MC[DCSB.mouseYCoord, DisplayCSB, 11];	* mouseYCoord: CARDINAL,
	MC[DCSB.keyboard, DisplayCSB, 12];	* keyboard: ARRAY [0..5] OF WORD,
*	MC[DCSB.cursorBitMap, DisplayCSB, 20];	* cursorBitMap: ARRAY [0..17B] OF WORD,
*						* -- actually defined in IODefs
	MC[DCSB.borderEven, DisplayCSB, 40];	* borderEven, borderOdd:
	MC[DCSB.borderOdd, DisplayCSB, 60];	*   ARRAY [0..17B] OF WORD];

* DisplayFlags: TYPE = MACHINE DEPENDENT RECORD [
	MC[DF.background, 100000];		* background: {white, black},

*-----------------------------------------------------------
* Register assignments
* Note that the RMRegions themselves are defined in RegisterDefs.mc.
* The "T" prefix refers to the 7-wire Terminal, which may be connected to
* the Dorado using either the DispY board or the DispM board.
* "THT" means either DHT or AHT, whichever is doing the terminal emulation,
* and similarly for "TWT".
*-----------------------------------------------------------

*-----------------------------------------------------------
SetRMRegion[TWTRegion];		* Terminal word task registers
*-----------------------------------------------------------

* Following registers are accessed by TWT, and must parallel AChannelRegion
* and BChannelRegion so that the word task microcode may be shared.
	RVN[TAddress];		* Next munch address; also used as WCB flag
	RVN[TCount];		* Munch count
	RVN[TNextCount];	* Initial munch count for next scan line
	RVN[TNextAddrLo];	* Long pointer to start of next scan line
	RVN[TNextAddrHi];

* Following registers hold parameters NOT accessed by TWT, and must parallel
* AChannelRegion and BChannelRegion so that DHT subroutines may be shared. 
	RVN[TReaderPtrReg];	* Initial FIFO address for next scan line
	RVN[TNWrdsMinus1];	* (Scan line length in words)-1
	RVN[TSetNextWCB];	* DHTFlags Output command to set NextWCB flag
	RV[TChannelReg, 0];	* 0 for channel A, 100000B for channel B
	RVN[TScratch];

* Following registers are specialized to 7-wire Terminal service, and have
* no counterparts in AChannelRegion and BChannelRegion.
	RVN[TDCBChainReg];	* Pointer to next DCB
	RVN[TSLCReg];		* (Remaining scan lines)-1 for current DCB
	RVN[LMargConst];	* Left margin NLCB constant

*-----------------------------------------------------------
SetRMRegion[THTRegion];		* Terminal horizontal task registers
*-----------------------------------------------------------

* Following registers must parallel DHTRegion so that DHT subroutines
* may be shared. 
	RVN[TVCWShadowReg];	* Vertical Control bits
	RVN[TFieldAreaReg];	* Remaining scan lines in field
	RV[TReg400C, 400];	* Constant 400B
	RVN[TTemp0];
	RVN[TTemp1];
	RVN[TTemp2];

* Following registers are specialized to 7-wire Terminal service, and have
* no counterparts in DHTRegion.
	RVN[DisplayConfig];	* Bit 0 = 1 iff DispM board is installed
				* Bit 15 = 1 iff LF monitor is connected
	RV[TCursorBaseMinus2, Sub[DCSB.cursorBitMap!, 2]];
	RVN[TCursorYReg];	* -2 * (scan lines remaining until cursor)
	RVN[TerminalHi];	* Accumulated terminal message
	RVN[TerminalLo];
	RVN[BootTimer];		* 0 or duration of boot button push
	RVN[BootState];		* Boot timer and action
	RVN[VBlankToVSyncCnt];	* Scan lines from start of VBlank to start of VSync
	RVN[VSyncToVBlankCnt];	* Scan lines from end of VSync to end of VBlank
	RVN[CursorXConst];	* Cursor X NLCB constant

*-----------------------------------------------------------
SetRMRegion[AChannelRegion];	* Display A-channel registers
*-----------------------------------------------------------

* Following registers are accessed by DWT, and must parallel BChannelRegion
* and TChannelRegion so that the word task microcode may be shared.
	RVN[AAddress];		* Next munch address; also used as WCB flag
	RVN[ACount];		* Munch count
	RVN[ANextCount];	* Initial munch count for next scan line
	RVN[ANextAddrLo];	* Long pointer to start of next scan line
	RVN[ANextAddrHi];

* Following registers hold parameters NOT accessed by DWT, and must parallel
* BChannelRegion and TChannelRegion so that DHT subroutines may be shared. 
	RVN[AReaderPtrReg];	* Initial FIFO address for next scan line
	RVN[ANWrdsMinus1];	* (Scan line length in words)-1
	RVN[ASetNextWCB];	* DHTFlags Output command to set NextWCB flag
	RV[AChannelReg, 0];	* 0 for channel A, 100000B for channel B
	RVN[AScratch];

* Remaining registers are available for special uses.
	Set[nStandardDWTRegs, And[IP[RLC], 17]];

*-----------------------------------------------------------
SetRMRegion[BChannelRegion];	* Display B-channel registers.
*-----------------------------------------------------------

* Following registers are accessed by DWT, and must parallel AChannelRegion
* and TChannelRegion so that the word task microcode may be shared.
	RVN[BAddress];		* Next munch address; also used as WCB flag
	RVN[BCount];		* Munch count
	RVN[BNextCount];	* Initial munch count for next scan line
	RVN[BNextAddrLo];	* Long pointer to start of next scan line
	RVN[BNextAddrHi];

* Following registers hold parameters NOT accessed by DWT, and must parallel
* AChannelRegion and TChannelRegion so that DHT subroutines may be shared. 
	RVN[BReaderPtrReg];	* Initial FIFO address for next scan line
	RVN[BNWrdsMinus1];	* (Scan line length in words)-1
	RVN[BSetNextWCB];	* DHTFlags Output command to set NextWCB flag
	RV[BChannelReg, 100000]; * 0 for channel A, 100000B for channel B
	RVN[BScratch];

*-----------------------------------------------------------
SetRMRegion[DHTRegion];		* Display horizontal task (DHT) registers
*-----------------------------------------------------------

* Following registers must parallel THTRegion so that DHT subroutines
* may be shared. 
	RVN[VCWShadowReg];	* Vertical Control bits
	RVN[FieldAreaReg];	* Remaining scan lines in field
	RV[Reg400C, 400];	* Constant 400B
	RVN[HTemp0];
	RVN[HTemp1];
	RVN[HTemp2];
	RVN[HTemp3];

* Remaining registers are available for special uses.
	Set[nStandardDHTRegs, And[IP[RLC], 17]];

*-----------------------------------------------------------
* Device Assignments
*-----------------------------------------------------------
* DispY board:
	Device[Statics, 377];
	Device[NLCB, 376];
	Device[HRam, 375];
	Device[DHTFlag, 374];
	Device[DWTFlag, 373];
	Device[MiniMixer, 372];
	Device[DDCStatus, 370];

* DispM board:
* Note that some of the devices are assigned parallel to DispY so that
* terminal code can control either set of devices simply by initializing
* TIOA properly and subsequently changing only TIOA[5:7].
	Device[TStatics, 367];		* Parallel to DispY
	Device[TNLCB, 366];		* Parallel to DispY
	Device[BMap, 365];
	Device[AHTFlag, 364];		* Parallel to DispY
	Device[AWTFlag, 363];		* Parallel to DispY
	Device[CMap, 362];
	Device[Mixer, 361];
	Device[TStatus, 360];		* Parallel to DispY
	Device[VCOClock, 360];

*-----------------------------------------------------------
* MemBase Assignments
*-----------------------------------------------------------
* A channel MemBase value must =0 in MemBase.2; B channel MemBase value
* must be same as A channel EXCEPT =1 in MemBase.2
*	BR[AChannelBR, ??];	* See ADefs.mc
*	BR[BChannelBR, ??];
*	BR[TChannelBR, ??];


*-----------------------------------------------------------
* Statics register constants -- DHT/DWT or AHT/AWT
*-----------------------------------------------------------
	MC[DHTShutUp, 1];
	MC[DWTShutUp, 2];
	MC[AllShutUp, DHTShutUp, DWTShutUp];

*-----------------------------------------------------------
* NLCB address constants
*-----------------------------------------------------------
	Set[NLCBAddrShift, 14];		*12D
	MC[VCW, LShift[0, NLCBAddrShift]];
	MC[ALMarg, LShift[1, NLCBAddrShift]];
	MC[AWidth, LShift[2, NLCBAddrShift]];
	MC[APointer, LShift[3, NLCBAddrShift]];
	MC[AScan, LShift[4, NLCBAddrShift]];
	MC[Modes, LShift[5, NLCBAddrShift]];
	MC[BLMarg, LShift[11, NLCBAddrShift]];
	MC[BWidth, LShift[12, NLCBAddrShift]];
	MC[BPointer, LShift[13, NLCBAddrShift]];
	MC[BScan, LShift[14, NLCBAddrShift]];
	MC[CursorX, LShift[15, NLCBAddrShift]];
	MC[CursorLo, LShift[16, NLCBAddrShift]];
	MC[CursorHi, LShift[17, NLCBAddrShift]];

*-----------------------------------------------------------
* NLCB Data Constants
*-----------------------------------------------------------
	MC[NLCBDataMask, 7777];
	MC[CursorXDataMask, CursorX, NLCBDataMask];
	MC[ALMargDataMask, ALMarg, NLCBDataMask];
	MC[AWidthDataMask, AWidth, NLCBDataMask];
	MC[BLMargDataMask, BLMarg, NLCBDataMask];
	MC[BWidthDataMask, BWidth, NLCBDataMask];

	MC[VSync, 2];
	MC[VBlank, 4];

	MC[Size1, 1];
	MC[Size2, 2];
	MC[Size4, 4];
	MC[Size8, 10];
	Set[ResShift, 4];
	MC[FullRes, LShift[3, ResShift]];
	MC[HalfRes, LShift[2, ResShift]];
	MC[QuarterRes, LShift[1, ResShift]];
	MC[Polarity, LShift[4, ResShift]];

	MC[A8B2Mode, 1];
	MC[BBypassMode, 2];
	MC[ABypassMode, 4];
	MC[24BitMode, 12];		* Really 24BitMode OR BBypassMode

	MC[MaxMarg, 377];		* anything >40 (easy for hardware)
	MC[AMaxMarg, ALMarg, MaxMarg];
	MC[BMaxMarg, BLMarg, MaxMarg];

*-----------------------------------------------------------
* Ram Control Constants -- HRam, Mixer, BMap, CMap
*-----------------------------------------------------------
	Set[RamCtrlShift, 14];		*12D
	MC[DontKeep, LShift[10, RamCtrlShift]];
	MC[DontWrite, LShift[4, RamCtrlShift]];
	MC[LoadAddress, LShift[2, RamCtrlShift], DontWrite];
	MC[ReleaseRam, DontKeep, DontWrite];
	MC[HRamSize, 2000];
	MC[HRamMaxAddr, 173];		* 400B+173B=379D

*-----------------------------------------------------------
* HRam Data Constants
*-----------------------------------------------------------
	MC[HalfLine, 1];
	MC[HBlank, 2];
	MC[HSync, 4];

*-----------------------------------------------------------
* DHTFlag constants
*-----------------------------------------------------------
	MC[BNextWCBFlag, 4];
	MC[ANextWCBFlag, 2];

*-----------------------------------------------------------
* Vertical Constants for Alto/LF Monitor
*-----------------------------------------------------------
	MC[VBlankToVSyncCntAlto, 2]; 
	MC[VBlankToVSyncCntLF, 11]; 
	MC[VSyncToVSyncCnt, 23];	*large pulse for OIS terminal
	MC[VSyncToVBlankCntAlto, 14];
	MC[VSyncToVBlankCntLF, 20];
	MC[VisibleLineCnt, 624];	* 624B=404D
						* unused: [0..77777B]];

*-----------------------------------------------------------
* Constants for booting
*-----------------------------------------------------------
	MC[MinimumWait, 270];	* 2 * (90D => 1.5 seconds @ 60 ticks/second)
	MC[MinimumPush, 322];	* 210D => 8 ms @ 1 tick/38 us

*-----------------------------------------------------------
* Constant Offsets for DDC Hardware Counters
*-----------------------------------------------------------
	MC[WidthOffset, 377];
	MC[MaxWidthWordsAlto, 46];	* 38 words
	MC[MaxWidthWordsLF, 100];	* 64 words

*-----------------------------------------------------------
* Display horizontal waveforms
*-----------------------------------------------------------

* The two lines in the HorizontalWaveforms macro define, respectively, waveforms for:
*   Alto monitor
*   LF monitor with full-screen picture

* The arguments are:
*   #1  total pixels/scan line
*   #2  visible pixels/scan line
*   #3  distance from end of visible scan to start of sync pulse
*   #4  width of sync pulse
*   #5  name of waveform (Alto, LFFull)
* All numbers must be even, because they all get divided by 2 since the HRam
* is clocked on PixelClk/2.  Additionally, it is required that #1 MOD 4 = 0, since
* it must be possible to position the HalfLine pulse in the exact middle of
* the scan line.  Finally, it is required that (#1-#2-#3) MOD 4 = 2
* and #2 MOD 4 = 0, because, due to a bug in the display controller,
* horizontal blanking may change only on even PixelClk/2 boundaries.

M[HorizontalWaveforms,
  #1[Dec[0,7,6,0], Dec[0,6,0,8], Dec[0,0,3,8], Dec[0,0,7,0], Alto]
  #1[Dec[1,4,4,0], Dec[1,0,2,4], Dec[0,0,2,6], Dec[0,3,6,0], LFFull]
  ];

* Macro Dec[a,b,c,d] returns the value of the decimal number abcd,
* where a,b,c,d are decimal digits.

M[Dec, Add[X1000[#1], X100[#2], X10[#3], #4]];
M[X10, LShift[Add[LShift[#1, 2], #1], 1]];
M[X100, LShift[Add[LShift[Add[#1, #1, #1], 3], #1], 2]];
M[X1000, LShift[Add[LShift[Sub[LShift[#1, 5], #1], 2], #1], 3]];
M[8, 10]; M[9, 11];