{ Filename: dbDrawLineB1.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 ← 4, c1;
uYCount ← TOS, c2;
S ← S - 14'd, CROSS[DLEntry], c3;
}
Noop, c3, at[DLEntry];
MAR ← [rhS,S + 0], c1; {- 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, WMapFixCallerB1];
, c2, at[PgDirty, 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[WLMapFixB1], c2, at[PgClean, 4, DLMapFix];
GOTO[WLMapFixB1], c2, at[PgProt, 4, DLMapFix];
GOTO[WLMapFixB1], c2, at[PgVacant, 4, DLMapFix];
MAR ← [rhS,S + 0], c1, at[L1.DLFixesB2, 10, TrapFixesB1]; {- 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;
, c1;
TOSH ← smallpl, L1 ← L1.NoFixes, c2;
TOS ← uYCount, c3;
Bank ← 0, c1;
CROSS[PFaultB0], c2;
{dlNormExit: When we are finished drawing, execution comes here.
The opcode returns the address of the end of the line.}
dlNormExit:
, c1;
TOS ← TT, c2;
TOSH ← Q, c3;
Bank ← 0, c1;
, CROSS[DLExit], c2;
{ 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 }