{ Filename: NewDrawLineB2.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[OpTableB2], c3; } { E N D }