{File name XLispMakeGraph.mc Description: DandeLion InterLisp Emulator LispFloatArray Author: Charnley Last modified: Charnley 20-Aug-84 15:55:49 Created: 8-Jun-84 10:04:55 } RegDef[umaskrealLo, U, 045], RegDef[umaskrealHi, U, 046]; { MAKEGRAPH 337 Args: S-12 Ptr to list of Kount values: value in [0..255] S-10 Ptr to list of 256 patterns: pattern[i] used to display value = i S-8 X: x-displacement of first bit in target bitmap S-6 Addr of target map: first word of target bitmap {left edge} S-4 Target map width: words wide of target bitmap: in [0..255] S-2 Pattern height: number of bits high {repeated} of pattern: in [1..16] S-0 Pattern width: number of bits wide of pattern: in [1..16] TOS Kount } { u regs uS2Hi, uS2Lo ptr to patterns uS1Hi, uS1Lo ptr to values uXdisp value of x-displacement uDHi, uDLo ptr to leftmost top dest address uWidth map width in words {width-1 if two dest words} uICount pattern height uNBits pattern width in bits umaskrealLo saves mask for source into dest low word umaskrealHi saves mask for source into dest high word uShiftedPattLo bits to be ored into first dest word uShiftedPattHi bits to be ored into second dest word } { r regs S1 real address of next value S2 real address of pattern, and temp D real address of next dest Zorch remap temp Zimph remap temp Stemp general temp Kount outer loop count } { link regs L0 LMGremapDret Set[L0.LMGDinit, 4], Set[L0.LMGD1, 2], Set[L0.LMGD2, 3], Set[L0.LMGD3, 5], LMGremapS1ret Set[L0.LMGS1init, 4], Set[L0.LMGS1S2, 6], LMGremapS2ret Set[L0.LMGS1S2, 6], AllignRet Set[L0.LMGS1S2, 6], L1 return link for reg saving LFASaveRegsRet Set[L1.LMGprep, 5], amount to left shift source L2 0 -- plot each value 1 -- plot every other value L3 0 first inner loop, one dest word 1 first inner loop, two dest words 2 other inner loop, one dest word 3 other inner loop, two dest words } { {init} {generate: 1st target word mask, 2nd target word mask, Shift count for pattern} {for OCount in [0..Kount - 1]} {get next value} {get pattern[value]} {shift pattern} {mask pattern}{not needed for 'or' -- assumes pattern is zero filled} {for ICount in [0..Pattern height - 1]} {merge pattern into target word(s)} {next ICount} {next OCount} } LMG: at[IBLT], Xbus ← ibNA, XDisp, c1; L2 ← 0, BRANCH[iblt, iblt2], c2;{put ib into L2} iblt: GOTO[ibltstart], c3; iblt2: GOTO[ibltstart], c3; ibltstart: L1 ← L1.LMGprep, c1; CALL[LFASaveRegsHere], c2;{this does S ← S - 4} MAR ← S ← [rhS, S - 8], c1, at[L1.LMGprep, 10, LFASaveRegsRet]; LMGS1ret: BRANCH[$, LMGS1, 1], c2; Stemp{S1Lo} ← MD, c3;{S-12} MAR ← [rhS, S - 1], c1; uS1Lo ← Stemp, CANCELBR[$, 2], c2; Stemp{S1Hi} ← MD, c3; MAR ← S ← [rhS, S + 2], c1; LMGS2ret: uS1Hi ← Stemp, BRANCH[$, LMGS2, 1], c2; Stemp {S2Lo}← MD, c3;{S-10} MAR ← [rhS, S - 1], c1; uS2Lo ← Stemp, CANCELBR[$, 2], c2; Stemp{S2Hi} ← MD, c3; MAR ← S ← [rhS, S + 2], c1; LMGS3ret: uS2Hi ← Stemp, BRANCH[$, LMGS3, 1], c2; Stemp {Xdisp}← MD, c3;{S-8} MAR ← S ← [rhS, S + 2], c1; LMGS4ret: uXdisp ← Stemp, BRANCH[$, LMGS4, 1], c2; Stemp{DLo} ← MD, c3;{S-6} MAR ← [rhS, S - 1], c1; uDLo ← Stemp, CANCELBR[$, 2], c2; Stemp{DHi} ← MD, c3; MAR ← S ← [rhS, S + 2], c1; LMGS5ret: uDHi ← Stemp, BRANCH[$, LMGS5, 1], c2; Stemp{Width} ← MD, c3;{S-4} MAR ← S ← [rhS, S + 2], c1; LMGS6ret: uWidth ← Stemp, BRANCH[$, LMGS6, 1], c2; Stemp{ICount} ← MD, c3;{S-2} MAR ← S ← [rhS, S + 2], c1; LMGS7ret: uICount ← Stemp, BRANCH[$, LMGS7, 1], c2; Stemp{NBits} ← MD, c3;{S-0} uNBits ← Stemp, GOTO[LMGprep], c1; LMGS1: S ← S - 0FF - 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS1ret], c1; LMGS2: S ← S + 0FF + 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS2ret], c1; LMGS3: S ← S + 0FF + 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS3ret], c1; LMGS4: S ← S + 0FF + 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS4ret], c1; LMGS5: S ← S + 0FF + 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS5ret], c1; LMGS6: S ← S + 0FF + 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS6ret], c1; LMGS7: S ← S + 0FF + 1, c3; MAR ← S ← [rhS, S + 0], GOTO[LMGS7ret], c1; LMGprep: S2 ← uXdisp, c2; Zimph ← S2 and ~0F, c3; Zimph ← Zimph LRot12, c1;{Zimph set to dest word offset from Xdisp} Ybus ← S2, YDisp, c2; Xbus ← 1, XDisp, DISP4[Mask], c3; {build a mask of left zero's, with one's starting at first bit} {one cycle subroutine returns mask in Stemp} {c1} umaskrealLo ← Stemp, c2, at[1, 10, MaskRet]; Q ← uNBits, c3; Ybus ← S2 + Q, YDisp, c1; Xbus ← 3, XDisp, DISP4[Mask], c2; {build a mask of left one's, with zero's starting past last bit} {one cycle subroutine returns mask in Stemp} {c3} Ybus ← ~Stemp, ZeroBr, c1, at[3, 10, MaskRet];{mask is wrong for position 0; test and fix} S1 ← 0 - S2, BRANCH[Tmask, Fmask], c2; Tmask: umaskrealHi ← ~Stemp, GOTO[LMGz], c3; Fmask: umaskrealHi ← Stemp, GOTO[LMGz], c3; LMGz: D ← uNBits, c1; Ybus ← S1 - D, YDisp, c2;{left shift amount = - NBits - Xdisp} Xbus ← 2, XDisp, DISP4[Mask], L1 ← 0, c3;{place left cycle amount in L1} {one cycle subroutine returns garbage in Stemp}{c1} D ← D - 1, c2, at[2, 10, MaskRet]; Ybus ← D + S2, NibCarryBr, c3; S2 ← uWidth, L3 ← 0, BRANCH[oneDW, twoDW], c1;{place oneDW{0} / twoDW{1} into L3} oneDW: Q ← umaskrealLo, c2; Q ← Q and umaskrealHi, c3; umaskrealLo ← Q, c1; GOTO[anyDW], c2; twoDW: S2 ← S2 - 1, GOTO[anyDW], c2;{sub one from width if two dest words} anyDW: , c3; uWidth ← S2, c1;{now in words or words - 1} L0 ← L0.LMGDinit, Zorch ← uDLo, c2; Q ← rhZorch ← uDHi, CALL[LMGremapDinit], c3; {Zimph set up with word offset} rhZorch ← Q ← uS1Hi, c2, at[L0.LMGDinit, 10, LMGremapDret]; Zorch ← uS1Lo, CALL[LMGremapS1init], c3; L0 ← L0.LMGS1S2, c2, at[L0.LMGDinit, 10, LMGremapS1ret]; Zimph ← MD, CALL[LMGremapS2], c3; LMGdoubleouter: MAR ← S1 ← [rhS1, S1 - 2], BRANCH[LMGout, LMGend], c1; LMGouterloop: {get next value} MAR ← S1 ← [rhS1, S1 - 1], BRANCH[LMGout, LMGend], c1; LMGout: BRANCH[$, LMGremapS1, 1], c2, at[L0.LMGS1S2, 10, LMGremapS1ret];; Zimph ← MD, CALL[LMGremapS2], c3; {use value as index into pattern table} S2 ← umaskrealLo, L1Disp, c2, at[L0.LMGS1S2, 10, LMGremapS2ret]; Stemp ← MD, DISP4[Allign], c3; LMGpause: uShiftedPattLo ← Stemp and S2, c1, at[L0.LMGS1S2, 10, AllignRet]; S2 ← umaskrealHi, c2; uShiftedPattHi ← Stemp and S2, c3; Q ← ~umaskrealLo, c1; S2 ← uWidth, L3Disp, c2; Stemp ← uICount, DISP2[Innerloop], c3; MAR ← [rhD, D + 0], GOTO[SInner], L3 ← 2, c1, at[0, 4, Innerloop]; MAR ← D ← [rhD, D + S2{Width}], GOTO[SInner], L0 ← L0.LMGD1, c1, at[2, 4, Innerloop]; SInner: Stemp{ICount} ← Stemp - 1, ZeroBr, BRANCH[$, LMGremapD1, 1], c2; remapD1ret: Q ← MD and Q, BRANCH[Smoreinner, Snomoreinner], c3; Smoreinner: MAR ← [rhD, D + 0], c1; MDR ← Q or uShiftedPattLo, L3Disp, c2; Q ← ~umaskrealLo, DISP2[Innerloop], c3; Snomoreinner: MAR ← [rhD, D + 0], L0 ← L0.LMGS1S2, c1; MDR ← Q or uShiftedPattLo, L2Disp, c2; Kount{OCount} ← Kount - 1, ZeroBr, BRANCH[LMGouterloop, LMGdoubleouter], c3; MAR ← [rhD, D + 0], GOTO[DInner], L3 ← 3, c1, at[1, 4, Innerloop]; MAR ← D ← [rhD, D + S2{Width - 1}], GOTO[DInner], L0 ← L0.LMGD2, c1, at[3, 4, Innerloop]; DInner: BRANCH[$, LMGremapD2, 1], c2; remapD2ret: Q ← MD and Q, c3; MAR ← [rhD, D + 0], c1; MDR ← Q or uShiftedPattLo, c2; Q ← ~umaskrealHi, c3; MAR ← D ← [rhD, D + 1], L0 ← L0.LMGD3, c1; Stemp{ICount} ← Stemp - 1, ZeroBr, BRANCH[$, LMGremapD3, 1], c2; remapD3ret: Q ← MD and Q, BRANCH[Dmoreinner, Dnomoreinner], c3; Dmoreinner: MAR ← [rhD, D + 0], c1; MDR ← Q or uShiftedPattHi, L3Disp, c2; Q ← ~umaskrealLo, DISP2[Innerloop], c3; Dnomoreinner: MAR ← [rhD, D + 0], L0 ← L0.LMGS1S2 c1; MDR ← Q or uShiftedPattHi, L2Disp, c2; Kount{OCount} ← Kount - 1, ZeroBr, BRANCH[LMGouterloop, LMGdoubleouter], c3; LMGend: Q ← 14'd, CANCELBR[$, 3], c2; L1 ← L1.LFAexit, c3; GOTO[LFACommonExit], c1; { , c3, at[L1.LFGexit, 10, RestoreRegsRet]; {instruction dispatch} Bank ← EmuBank, c1; PC ← PC + PC16, L2 ← L2.0, IBDisp, c2; L2 ← L2.0, DISPNI[OpTable], c3; } LMGremapD1: Zorch ← uDLo, CANCELBR[LMGremapD], c3; Ybus ← Stemp, ZeroBr, GOTO[remapD1ret], c2, at[L0.LMGD1, 10, LMGremapDret]; LMGremapD2: Zorch ← uDLo, GOTO[LMGremapD], c3; GOTO[remapD2ret], c2, at[L0.LMGD2, 10, LMGremapDret]; LMGremapD3: Zorch ← uDLo, CANCELBR[LMGremapD], c3; Ybus ← Stemp, ZeroBr, GOTO[remapD3ret], c2, at[L0.LMGD3, 10, LMGremapDret]; LMGremapD: MAR ← Zorch ← [Zorch, D + 0], c1;{byte merge only} Zimph ← 0FF + 1, c2; rhZorch ← uDHi, c3; LMGremapDinit: Zorch ← Zorch + Zimph, CarryBr, c1; uDLo ← Zorch, BRANCH[LMGDnocar, LMGDcar], c2; LMGDcar: Zimph ← Zorch, c3; Zorch ← rhZorch + 1, LOOPHOLE[byteTiming], c1; rhZorch ← Zorch LRot0, c2; Zorch ← Zimph, c3; uDHi ← Zorch, c1; , c2; GOTO[LMGDmap], c3; LMGDnocar: , c3; LMGDmap: Map ← [rhZorch, Zorch], c1; , c2; rhD ← D ← MD, XwdDisp, c3; Map ← [rhZorch, Zorch], DISP2[LMGmapD, 1], c1; MDR ← D or 30, GOTO[LMGDok], c2, at[1, 4, LMGmapD]; Rx ← D, GOTO[LMGpagefault], c2, at[3, 4, LMGmapD]; LMGDok: L0Disp, c3; MAR ← D ← [rhD, Zorch + 0], DISP4[LMGremapDret], c1; LMGremapS1init: Zimph ← Kount - 1, L2Disp, c1; Zorch ← Zorch + Zimph, CarryBr, BRANCH[LMGsingleS1, LMGdoubleS1], c2; LMGdoubleS1: Zorch ← Zorch - Zimph, CANCELBR[$], c3; Zimph ← Zimph + Zimph, c1; Zorch ← Zorch + Zimph, CarryBr, c2; LMGsingleS1: uS1Lo ← Zorch, BRANCH[LMGremapS1map, LMGS1initS1car], c3; LMGS1initS1car: Q ← Q + 1, c1; rhZorch ← Q LRot0, c2; GOTO[LMGremapS1map], c3; LMGremapS1: Zorch ← uS1Lo, GOTO[LMGremapS1sub], c3; LMGremapS1sub: MAR ← Zorch ← [Zorch, S1 + 0], c1;{byte merge only} Zimph ← 0FF + 1, c2; Q ← rhZorch ← uS1Hi, c3; Zorch ← Zorch - Zimph, CarryBr, c1; uS1Lo ← Zorch, BRANCH[LMGS1car, LMGS1nocar], c2; LMGS1car: Q ← Q - 1, c3; rhZorch ← Q LRot0, c1; , c2; LMGS1nocar: , c3; LMGremapS1map: Map ← [rhZorch, Zorch], c1; uS1Hi ← Q, c2; rhS1 ← S1 ← MD, XwdDisp, c3; Map ← [rhZorch, Zorch], DISP2[LMGmapS1], c1; MDR ← S1 or 10, GOTO[LMGS1ok], c2, at[0, 4, LMGmapS1]; MDR ← S1 or 10, GOTO[LMGS1ok], c2, at[1, 4, LMGmapS1]; MDR ← S1 or 10, GOTO[LMGS1ok], c2, at[2, 4, LMGmapS1]; Rx ← S1, GOTO[LMGpagefault], c2, at[3, 4, LMGmapS1]; LMGS1ok: L0Disp, c3; MAR ← S1 ← [rhS1, Zorch + 0], DISP4[LMGremapS1ret] c1; {---- S2 REMAP ----} LMGremapS2: Zorch ← uS2Lo, c1; Zorch ← Zorch + Zimph, CarryBr, c2; rhZorch ← uS2Hi, BRANCH[LMGS2nocar, LMGS2car], c3; LMGS2car: Q ← rhZorch, c1; Q ← Q + 1, c2; rhZorch ← Q LRot0, c3; LMGS2nocar: {map S2} Map ← [rhZorch, Zorch], c1; , c2; rhS2 ← S2 ← MD, XwdDisp, c3; Map ← [rhZorch, Zorch], DISP2[LMGmapS2], c1; MDR ← S2 or 10, GOTO[LMGS2ok], c2, at[0, 4, LMGmapS2]; MDR ← S2 or 10, GOTO[LMGS2ok], c2, at[1, 4, LMGmapS2]; MDR ← S2 or 10, GOTO[LMGS2ok], c2, at[2, 4, LMGmapS2]; Rx ← S2, GOTO[LMGpagefault], c2, at[3, 4, LMGmapS2]; LMGS2ok: L0Disp, c3; MAR ← S2 ← [rhS2, Zorch + 0], RET[LMGremapS2ret] c1; LMGpagefault: TOS ← uTOS, c3; LMGfault: , c1; GOTO[LFApagefault], c2; { Left Allign by dispatched amount, return thru L0} Stemp ← Stemp LRot0, GOTO[SHzero], c*, at[00, 10, Allign]; Stemp ← Stemp LRot0, GOTO[SHone], c*, at[01, 10, Allign]; Stemp ← Stemp LRot0, GOTO[SHtwo], c*, at[02, 10, Allign]; Stemp ← Stemp LRot4, GOTO[SHmin1], c*, at[03, 10, Allign]; Stemp ← Stemp LRot4, GOTO[SHzero], c*, at[04, 10, Allign]; Stemp ← Stemp LRot4, GOTO[SHone], c*, at[05, 10, Allign]; Stemp ← Stemp LRot4, GOTO[SHtwo], c*, at[06, 10, Allign]; Stemp ← Stemp LRot8, GOTO[SHmin1], c*, at[07, 10, Allign]; Stemp ← Stemp LRot8, GOTO[SHzero], c*, at[08, 10, Allign]; Stemp ← Stemp LRot8, GOTO[SHone], c*, at[09, 10, Allign]; Stemp ← Stemp LRot8, GOTO[SHtwo], c*, at[0A, 10, Allign]; Stemp ← Stemp LRot12, GOTO[SHmin1], c*, at[0B, 10, Allign]; Stemp ← Stemp LRot12, GOTO[SHzero], c*, at[0C, 10, Allign]; Stemp ← Stemp LRot12, GOTO[SHone], c*, at[0D, 10, Allign]; Stemp ← Stemp LRot12, GOTO[SHtwo], c*, at[0E, 10, Allign]; Stemp ← Stemp LRot0, GOTO[SHmin1], c*, at[0F, 10, Allign]; SHzero: Stemp ← Stemp, L0Disp, GOTO[SHF0], c*; SHone: Stemp ← LRot1 Stemp, L0Disp, GOTO[SHF0], c*; SHtwo: Stemp ← LRot1 Stemp, L0Disp, GOTO[SHF1], c*; SHmin1: Stemp ← RRot1 Stemp, L0Disp, GOTO[SHF0], c*; SHF0: Stemp ← Stemp, RET[AllignRet], c*; SHF1: Stemp ← LRot1 Stemp, RET[AllignRet], c*; {Mask generation subroutine} Stemp ← 1, RET[MaskRet], c*, at[0F, 10, Mask]; Stemp ← 3, RET[MaskRet], c*, at[0E, 10, Mask]; Stemp ← 7, RET[MaskRet], c*, at[0D, 10, Mask]; Stemp ← 0F, RET[MaskRet], c*, at[0C, 10, Mask]; Stemp ← 1F, RET[MaskRet], c*, at[0B, 10, Mask]; Stemp ← 3F, RET[MaskRet], c*, at[0A, 10, Mask]; Stemp ← 7F, RET[MaskRet], c*, at[09, 10, Mask]; Stemp ← 0FF, RET[MaskRet], c*, at[08, 10, Mask]; Stemp ← LShift1 0FF, SE←1, RET[MaskRet], c*, at[07, 10, Mask]; Stemp ← RShift1 u7FF, RET[MaskRet], c*, at[06, 10, Mask]; Stemp ← u7FF, RET[MaskRet], c*, at[05, 10, Mask]; Stemp ← RShift1 u1FFF, RET[MaskRet], c*, at[04, 10, Mask]; Stemp ← u1FFF, RET[MaskRet], c*, at[03, 10, Mask]; Stemp ← uTT3FFF, RET[MaskRet], c*, at[02, 10, Mask]; Stemp ← RShift1 (Stemp xor ~Stemp), RET[MaskRet], c*, at[01, 10, Mask]; Stemp ← Stemp xor ~Stemp, RET[MaskRet], c*, at[00, 10, Mask]; { E N D }