:TITLE[CDCTask]; *Microcode for Color Display *Last edited: 16 January 1981 by Fiala SetTask[cdcTask]; *Output Registers Set[cdcCReg,0]; *Control register Set[cdcBuf,Add[LShift[cdcTask,4],1]]; *Data buffer - use with IOFetch Set[cdcID,0]; *Input register *R Regsters Set[cdcRB,LShift[And[cdcTask,3],4]]; *Enforce reg alloc convention RV[cdcTemp,Add[cdcRB,0]]; RV[cdcTemp1,Add[cdcRB,1]]; *Long pointer to bitmap & to color map data (60d words) RV4[cdcDataPointer,cdcDataPointer1,cdcCMPointer,cdcCMPointer1,Add[cdcRB,4]]; RV[cdcScanLineCount,Add[cdcRB,10]]; RV[cdcWordCount,Add[cdcRB,11]]; RV2[cdcMDS400,cdcMDS400hi,Add[cdcRB,12]]; *Must turn off CDC before overwriting its microcode. cdcOff: cdcTemp _ 0C, Skip, At[cdcOffLoc]; *Get to cdcIni during device initialization, or when the display has finished *sending all words for a field. Disable the data wakeup request, and wait *for the sync wakeup. cdcIni: cdcTemp _ 6C, At[cdcInitLoc]; *Clear Sync wakeup, enable Sync wakeup, no data wakeup Output[cdcTemp,cdcCReg]; cdcTemp _ cdcTemp; *interlock the output cdcMDS400 _ 400C; *wait for the wakeup pipe to empty Call[cdcRTN]; *Wake up here due to sync wakeup (we hope). Input[cdcTemp,cdcID]; *gets FieldA into bit 15 cdcTemp1 _ 17C, Skip[IOAtten]; *Skips if SyncWakeup Goto[cdcIni]; *should have seen SyncWakeup. *Fetch the Data and ColorMap (long) pointers from 414b - 417b. PFetch4[cdcMDS400,cdcDataPointer,14]; T _ cdcDataPointer1; *check for display on (pointer >64k) cdcDataPointer1 _ T _ (Lsh[cdcDataPointer1,10]) + T + 1, Skip[ALU#0]; Goto[cdcIni]; *display is off *clear sync wakeup, SWE, DWE, ForceBActive Output[cdcTemp1,cdcCReg]; cdcTemp1 _ 23C; *long data pointer to base register cdcDataPointer1 _ T _ (FixVA[cdcDataPointer1]) or T; *interlock and set up for next output: ForceAActive, SWE, DWE LU _ cdcTemp, IOStrobe, DblGoto[cdcFieldA,cdcFieldB,R Odd]; *load the wakeup counter with 0 *Sync wakeups occur at the end of the field, so FieldB is about to start. *We will load the color map, and add 160d (one scan line) to the Data address. *We cleared the wakeup request counter here, and will not increment it. We are writing bufferA, *and when we switch to sending data to buffer B, the wakeup counter will be zero. cdcFieldA: T _ cdcCMPointer1; *convert long pointer to base register cdcCMPointer1 _ T _ (Lsh[cdcCMPointer1,10]) + T + 1; cdcCMPointer1 _ (FixVA[cdcCMPointer1]) or T; *data must be placed so that this doesn't carry cdcDataPointer _ (cdcDataPointer) + (240C); IOFetch16[cdcCMPointer,cdcBuf,0], Call[cdcIncCMPtr]; IOFetch16[cdcCMPointer,cdcBuf,0], Call[cdcIncCMPtr]; IOFetch16[cdcCMPointer,cdcBuf,0], Call[cdcIncCMPtr]; IOFetch4[cdcCMPointer,cdcBuf,0], Call[cdcRTN]; IOFetch4[cdcCMPointer,cdcBuf,4], Call[cdcRTN]; IOFetch4[cdcCMPointer,cdcBuf,10]; cdcWordCount _ 10C, Goto[cdcFieldCommon]; *FieldA is about to start. *We will write 16 words into buffer A, then switch to buffer B and fill it. cdcFieldB: IOFetch16[cdcDataPointer,cdcBuf,0]; cdcDataPointer _ (cdcDataPointer) + (20C), Call[cdcRTN]; cdcWordCount _ 7C; cdcFieldCommon: Output[cdcTemp1,cdcCReg]; *cdcTemp1 _ ForceAActive, SWE, DWE earlier. cdcTemp _ 3C; *SWE, DWE Output[cdcTemp,cdcCReg]; *We are now set up to write into buffer A. Buffer B has been loaded with the *color map data or with the first 16 words of the first scan line, depending *on the field. Pump out the rest of the field. cdcScanLineCount _ 357C, Call[cdcRTN]; *240d - 1 cdcDataLoop: IOFetch16[cdcDataPointer,cdcBuf,0]; cdcDataPointer _ (cdcDataPointer) + (20C), Skip[IOAtten']; Goto[cdcIni]; *Field ended prematurely IOStrobe, Skip[Carry']; cdcDataPointer1 _ (cdcDataPointer1) + (400C) + 1; *64k boundary crossed cdcWordCount _ (cdcWordCount) - 1, Skip[R<0]; cdcRTN: cdcTemp _ cdcTemp, Return; *interlock Output at cdcFieldCommon+2 cdcScanLineCount _ (cdcScanLineCount) - 1, Skip[R>=0]; Goto[cdcIni]; *end of field cdcDataPointer _ (cdcDataPointer) + (240C); *Increment base by 160d for interlace cdcWordCount _ 10C, Skip[Carry']; cdcDataPointer1 _ (cdcDataPointer1) + (400C) + 1; *64K boundary Return; cdcIncCMPtr: cdcCMPointer _ (cdcCMPointer) + (20C), Return; :END[CDCTask];