{ Filename: DrawLineB2.mc Description: Lisp line-drawing microcode. Author: Mitch Lichtenberg Creation date: 25-Jun-83 16:51:58 Modified: 17-Apr-84 9:17:48 Entry format: TOS --> Maximum number of Y steps allowed {uYCount} SP-0 --> Maximum number of X steps allowed {uXCount} SP-2 --> Initial Delta {Delta} SP-4 --> Function number: {L2} 0: Set pixel 1: Reset Pixel 2: Invert Pixel SP-6 --> Relative Y coordinate of end of line (for the bucket) {uYT} SP-8 --> Width of bitmap (in words), signed to indicate Y direction {uYIncHi - uYIncLo} SP-10 -> Relative X coordinate of end of line (for the bucket) {uXT} SP-12 -> bit index [0..15] of bit to start at {CurBit} SP-14 -> Pointer to first word in bitmap {uPAdrHi - uPAdrLo} *** Registers used: Delta{TOSH}: contains the delta counter for determining step direction rhTT,,TT: contain the Virtual address of the word containing the pixel to modify rhRx,,Rx: contain the Real Address of the word containing the pixel, and used as a temp reg CurBit{TOS}: contains the bit-mask for the current pixel uXT,uYT: values for X and Y slope {used to modify Delta} uXCount,uYCount: maximum pixels to be drawn in X/Y uYIncHi,uYIncLo: Y step value L0 holds Map update return value L1 holds Map fix for PFault value L2 holds Drawline Function {0: PAINT, 1: ERASE, 2,3: INVERT} L3 holds 2 if uYT > uXT {major direction} } { IN BANK 1 @DRAWLINE: opcode[73'b], Bank ← DLBank, c1; uYCount ← TOS, c2; S ← S - 14'd, CROSS[DLEntry], c3; } MAR ← [rhS,S + 0], c1, at[DLEntry]; {- 14 Lo} Q ← 3, L0 ← L0.DLMap, c2; TT ← MD, c3; MAR ← [rhS,S - 1], c1; {- 14 Hi} S ← S + 2, CANCELBR[$, 2], c2; rhTT ← MD, c3; MAR ← [rhS,S + 0], {Get bitindex} c1; {-12} S ← S + 2, L1 ← L1.DLFixesB2, c2; Rx ← MD, c3; { convert value to bit mask in CurBit} CurBit ← RRot1 1, c1; dlCBloop: Rx ← Rx - 1, NegBr, c2; BRANCH[dlCBshift, dlCBset], c3; dlCBshift: CurBit ← RRot1 CurBit, GOTO[dlCBloop], c1; dlCBset: MAR ← [rhS,S + 0], {Get X bucket stepper} c1; {-10} S ← S + 2, c2; Rx ← MD, c3; MAR ← [rhS,S - 1], {Get Y Increment sign} c1; {-8 Hi} uXT ← Rx, CANCELBR[$,2], c2; Xbus ← MD, XDisp, {width} c3; MAR ← [rhS, S + 0], BRANCH[PosInc,NegInc,0E], c1; {-8 Lo} PosInc: uYIncHi ← 0,{Positive Increment} GOTO[GetY], c2; NegInc: uYIncHi ← ~TOS xor TOS,{Negative Increment} GOTO[GetY], c2; GetY: Rx ← MD, c3; , c1; uYIncLo ← Rx, c2; S ← S + 2, c3; MAR ← [rhS, S + 0], c1; {-6} S ← S + 2, c2; Rx ← MD, {Y bucket stepper} c3; MAR ← [rhS,S + 0], c1; {-4} S ← S + 2, c2; Q ← MD and Q{3}, c3; {Drawing function} MAR ← [rhS,S + 0], c1; {-2} S ← S + 2, c2; Delta ← MD, c3; {Initial Delta} MAR ← [rhS,S + 0], c1; {-0} Ybus ← Q, YDisp, c2; Q ← MD, DISP2[DLsetL2], L2 ← 0{put function in L2}, c3; {X pixel count} uXCount ← Q, GOTO[dlhere], c1, at[0, 4, DLsetL2]; uXCount ← Q, GOTO[dlhere], c1, at[1, 4, DLsetL2]; uXCount ← Q, GOTO[dlhere], c1, at[2, 4, DLsetL2]; uXCount ← Q, GOTO[dlhere], c1, at[3, 4, DLsetL2]; dlhere: Q ← uXT, {Get X and Y bucket stepper values back} c2; uYT ← Rx, c3; {Delta is in the range 0..MAX(XT,YT).. } Ybus ← Q - Rx, NegBr, {normalize delta} c1; BRANCH[Xbig,Ybig], c2; Xbig: Delta ← Q - Delta - 1, GOTO[dlPlot], L3 ← 0, c3; Ybig: Delta ← Rx - Delta - 1, GOTO[dlPlottoo], L3 ← 2, c3; {All of the arguments are now set up.} {=======================================================================} dlPlottoo: Map ← [rhTT, TT], GOTO[dlPlot1], c1; dlPlot: Map ← [rhTT, TT], BRANCH[dlPlot1, dlXfixY], c1; dlPlot1: , c2; rhRx ← Rx ← MD, XwdDisp{XDirtyDisp}, c3; MAR ← [rhRx, TT + 0], DISP2[DLMapFix], c1, at[L0.DLMap, 10, WMapFixCallerB2]; , c2, at[1, 4, DLMapFix]; Q ← MD, L2Disp, c3; MAR ← [rhRx, TT + 0], DISP2[dlFnDisp], L3Disp, c1; MDR ← Q or CurBit, BRANCH[dlXStuff, dlYStuff, 1], c2, at[0, 4, dlFnDisp]; MDR ← Q and ~CurBit, BRANCH[dlXStuff, dlYStuff, 1], c2, at[1, 4, dlFnDisp]; MDR ← Q xor CurBit, BRANCH[dlXStuff, dlYStuff, 1], c2, at[2, 4, dlFnDisp]; MDR ← Q xor CurBit, BRANCH[dlXStuff, dlYStuff, 1], c2, at[3, 4, dlFnDisp]; {=======================================================================} dlXStuff: Rx ← uXCount, GOTO[dlXS1], c3; dlXStufftoo: Rx ← uXCount, GOTO[dlXS1], c3; dlXS1: Rx ← Rx - 1, ZeroBr, c1; uXCount ← Rx, BRANCH[$, dlXThru], c2; CurBit ← RRot1 CurBit, c3; dlXS3: Ybus ← CurBit, NegBr, L3Disp, c1; Rx ← uYT, DISP2[dlXDisp], c2; TT ← TT + 1, CarryBr, GOTO[dlXmore], c3, at[1, 4, dlXDisp]; TT ← TT + 1, CarryBr, GOTO[dlXmore], c3, at[3, 4, dlXDisp]; dlXmore: Q ← rhTT, BRANCH[dlXrhTTok, $], L3Disp, c1; Q ← Q + 1, CANCELBR[$, 3], c2; rhTT ← Q LRot0, c3; L3Disp, c1; dlXrhTTok: DISP2[dlXDisp], c2; Delta ← Delta - Rx, NegBr, GOTO[dlPlot], c3, at[0, 4, dlXDisp];{X only} Delta ← Delta + Rx, GOTO[dlYrem], c3, at[2, 4, dlXDisp];{X and Y} dlXfixY: Rx ← uXT, c2; Delta ← Delta + Rx, GOTO[dlYrem], c3; dlYStuff: Rx ← uXT, c3; Delta ← Delta - Rx, NegBr, c1; BRANCH[$, dlXStufftoo], c2; , c3; dlYrem: Rx ← uYCount, c1; Rx ← Rx - 1, ZeroBr, c2; uYCount ← Rx, BRANCH[$, dlYThru], c3; Rx ← uYIncLo, c1; Q ← rhTT, c2; TT ← TT + Rx, CarryBr, c3; Rx ← uYIncHi, BRANCH[dlYnocar, dlYcar], c1; dlYnocar: Q ← Q + Rx, GOTO[dlYdone], c2; dlYcar: Q ← Q + Rx + 1, GOTO[dlYdone], c2; dlYdone: rhTT ← Q LRot0, GOTO[dlPlot], c3; dlYThru: , c1; , c2; dlXThru: Q ← rhTT, GOTO[dlNormExit], c3; {=======================================================================} {MAP Update for DrawLine routine} GOTO[WLMapFixB2], c2, at[0, 4, DLMapFix]; GOTO[WLMapFixB2], c2, at[2, 4, DLMapFix]; GOTO[WLMapFixB2], c2, at[3, 4, DLMapFix]; {uses standard remap routines now! WMapDLFix: Xbus ← Rx LRot0, XwdDisp, c3; Map ← [rhTT,TT], DISP2[DLMFix], c1; MDR ← Rx or {0B0}030, GOTO[Retry], c2, at[0,4,DLMFix]; MDR ← Rx or {0B0}030, GOTO[Retry], c2, at[1,4,DLMFix]; GOTO[DLTrap], c2, at[2,4,DLMFix]; GOTO[DLTrap], c2, at[3,4,DLMFix]; Retry: , c3; MAR ← [rhRx, TT + 0], GOTO[GetWD], c1; {DLTrap : In the event of a page fault, we come here.} DLTrap: , c3; uses standard remap routines now!} MAR ← [rhS,S + 0], c1, at[L1.DLFixesB2, 10, TrapFixesB2]; {- 0} MDR ← uXCount, c2; S ← S - 2, c3; L3Disp, c1; BRANCH[dlX, dlY, 1], c2; dlX: Q ← uXT, GOTO[dlSaveDelta], c3; dlY: Q ← uYT, GOTO[dlSaveDelta], c3; dlSaveDelta: MAR ← [rhS, S + 0], c1; {- 2} DelPos: MDR ← Q - Delta - 1, GOTO[DLcont], c2; DLcont: S ← S - 10'd, c3; Rx ← 0, c1; dlSetBitLoop: Ybus ← CurBit, NegBr, c2; CurBit ← LRot1 CurBit, BRANCH[dlAdd1toBit, dlBitok], c3; dlAdd1toBit: Rx ← Rx + 1, GOTO[dlSetBitLoop], c1; dlBitok: MAR ← [rhS, S + 0], c1; {- 12} MDR ← Rx, c2; S ← S - 2, c3; MAR ← [rhS,S + 0], c1; {- 14} MDR ← TT, c2; S ← S - 1, L1 ← L1.NoFixes, c3; MAR ← [rhS, S + 0], c1; MDR ← rhTT, c2; S ← S + 15'd, c3; Bank ← EmuBank, c1; TOSH ← smallpl, L1 ← L1.NoFixes, c2; TOS ← uYCount, CROSS[PFaultB1], c3; {dlNormExit: When we are finished drawing, execution comes here. The opcode returns the address of the end of the line.} dlNormExit: Bank ← EmuBank, c1; TOS ← TT, c2; TOSH ← Q, CROSS[DLExit], c3; { IN BANK 1 S ← S - 16'd, c1, at[DLExit]; L2 ← L2.0, PC ← PC + PC16, IBDisp, c2; L2 ← L2.0, DISPNI[OpTable], c3; } { E N D }