:TITLE[CdcTask]; *Microcode for Color Display SETTASK[cdcTask]; *Output Registers SET[cdcCReg,0]; *Control register SET[cdcBuf,ADD[LSHIFT[cdcTask,4],1]]; *Data buffer - use with IOFetch *Input Register SET[cdcID,0]; *R Regsters SET[cdcRB,LSHIFT[AND[cdcTask,3],4]]; *enforces register allocation conventions RV[cdcTemp,ADD[cdcRB,0]]; RV[cdcTemp1,ADD[cdcRB,1]]; RV[cdcDataPointer,ADD[cdcRB,4]]; *Long pointer to bitmap RV[cdcDataPointer1,ADD[cdcRB,5]]; RV[cdcCMPointer,ADD[cdcRB,6]]; *Long pointer to color map data (60d words) RV[cdcCMPointer1,ADD[cdcRB,7]]; RV[cdcScanLineCount,ADD[cdcRB,10]]; RV[cdcWordCount,ADD[cdcRB,11]]; RV[cdcMDS,76]; *contains 400 (initialized elsewhere) RV[cdcMDShi,77]; *contains MDShi (initialized elsewhere) ONPAGE[ColorDisplayPage]; *Get here 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. cdcInit: cdcTemp _ 6c, AT[cdcInitLoc]; *Clear Sync wakeup, enable Sync wakeup, no data wakeup Output[cdcTemp, cdcCReg]; cdcTemp _ cdcTemp; *interlock the output nop; *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 T _ 14c, skip[IOAtten]; *skips if SyncWakeup goto[cdcInit]; *should have seen SyncWakeup. PFetch4[cdcMDS,cdcDataPointer]; *Fetch the Data and ColorMap (long) pointers from 414b - 417b. T _ cdcDataPointer1; *check for display on (pointer >64k) cdcTemp1 _ 17c, skip[alu#0]; *clear sync wakeup, SWE, DWE, ForceBActive goto[cdcInit]; *display is off Output[cdcTemp1,cdcCReg]; cdcDataPointer1 _ T _ (lsh[cdcDataPointer1,10]) + (T) + 1; *long data pointer to base register cdcDataPointer1 _ T _ (fixVA[cdcDataPointer1]) or (T); cdcTemp1 _ 23c; *interlock and set up for next output: ForceAActive, SWE, DWE lu _ cdcTemp, dblgoto[cdcFieldA,cdcFieldB, ROdd], IOStrobe; *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; cdcCMPointer1 _ T _ (lsh[cdcCMPointer1,10]) + (T) + 1; *convert long pointer to base register cdcCMPointer1 _ (fixVA[cdcCMPointer1]) or (T); cdcDataPointer _ (cdcDataPointer) + (240c); *data must be placed so that this doesn't carry 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 call[.+1]; cdcDataLoop: IOFetch16[cdcDataPointer,cdcBuf,0]; cdcDataPointer _ (cdcDataPointer) + (20c), skip[NoAtten]; goto[cdcInit]; *Field ended prematurely IOStrobe, skip[NoCarry]; 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[cdcInit]; *end of field cdcDataPointer _ (cdcDataPointer) + (240c); *Increment base by 160d for interlace cdcWordCount _ 10c, skip[NoCarry]; cdcDataPointer1 _ (cdcDataPointer1) + (400c) + 1; *64K boundary return; cdcIncCMPtr: cdcCMPointer _ (cdcCMPointer) + (20c), return; :END[CdcTask]; (635)