{File name : PixelBlt.mc Author : Gwan Santosa & Don Charnley Date : 17-Apr-85 15:31:21 Original design by : Don Charnley Date : 18-Mar-85 11:58:22 combine the source and dest pixel-maps together using the Combine Array as follows: It is page alligned! The Combine Array is 256 entries of 4 nibl's each It is addressed by the source nibl value concatenated with the dest nibl value the dest nibl is replaced with the following nibl: (dstX even, dstY even) _ entry[0] (dstX odd, dstY even) _ entry[1] (dstX even, dstY odd) _ entry[2] (dstX odd, dstY odd) _ entry[3] This allows texturing, which increases the effective number of "colors" beyond 16. called with the following parameters: S-16 Combine Array: {pointer - page alligned!!} S-14 Source BitMap: {BitMap} S-12 Source X: {of "transfer area" upper left pixel} S-10 Source Y: {of "transfer area" upper left pixel} S-8 Dest BitMap: {BitMap} S-6 Dest X: {of "transfer area" upper left pixel} S-4 Dest Y: {of "transfer area" upper left pixel} S-2 Transfer width: {smallp - pixels} S-0 Untransfered width: {smallp - pixels / 0 on initial call} tos Transfer height: {smallp - lines} "BitMap" is a six word record of the following format: 0: BitMapBaseHi -- High word of Virtual Addr of [X = 0, Y = Height - 1] of BitMap {upper left screen corner} 1: BitMapBaseLo -- Low word of Virtual Addr of [X = 0, Y = Height - 1] of BitMap {upper left screen corner} 2: BitMapRasterWidth {words} 3: BitMapHeight {lines} 4: BitMapWidth {bits} 5: BitMapBitsPerPixel {1 or 4 or 8} 4 = nibl inner loop looks like the following: for each dest nibl: get next source nibl{4 bits} get next dest nibl{4 bits} Vals _ CombineArray[srcnibl,,dstnibl]{16 bits} newDstNibl _ Vals[2*(dstY mod 2) + (dstX mod 2)]{4 bits} replace dest nibl with newDstNibl registers and links Srclink -- {0, 1, 2, 3} which src nibl, used to know when to refill Dstlink -- {0, 1, 2, 3} which dst nibl, used to know when to refill Loclink -- {0, 1, 2, 3} which nibl of entry desired Share Dstlink and Loclink using three bits [dY mod 2, which dst nibl] SrcReg -- holds unprocessed src nibls DstReg -- holds partially processed dst nibls {old and new} DN -- temp dst nibl for lookup {=Q, in the inner loop} rSAddr -- address of current src word rDAddr -- address of current dst word rArray -- real address of array entry -- temp for array index and value {=Rx, in the inner loop} pixelcount -- number of pixels remaining Perform the operation from the bottom up, so that only the number of lines and tos-1 need to be updated in case of page fault or interrupt if page fault from within a line, save pixel count in tos-1 initialize: read stack parameters save regs calculate links: src start nibl, dst start nibl, (dst Y mod 2) calculate number of dest pixels LINE: fetch first dest word, and allign in DstReg fetch first source word and allign in SrcReg enter loop loop till line finished write last dest word refill: update number of lines remaining, exit if done test for interrupts update src and dest virtual addresses reload src start nibl, dst start nibl, (dst Y mod 2) GOTO[LINE] } Set[L2NBRET1, 02]; Set[L2NBRET2, 04]; Set[L0.PX.NR.0A, 0A]; Set[L0.PX.NR.04, 04]; Set[L0.PX.NR.05, 05]; Set[L0.PX.NR.06, 06]; Set[L0.PX.NR.07, 07]; Set[L0NB3, 0B]; Set[L0NB4, 0C]; Set[L0NB5, 0D]; Set[L1.PX.NR.0A, 0A]; Set[L1.PX.NR.04, 04]; Set[L1.PX.NR.05, 05]; Set[L1.PX.NR.06, 06]; Set[L1.PX.NR.07, 07]; Set[L1SAVE, 9]; RegDef[SrcReg, R, 3]; {=PV} RegDef[DstReg, R, 5]; {=PC} RegDef[rSAddr, R, 0]; {=TOS} RegDef[rhSAddr, RH, 0]; {=rhTOS} RegDef[rDAddr, R, 1]; {=TOSH} RegDef[rhDAddr, RH, 1]; {=rhTOSH} RegDef[rArray, R, 4]; {=S} RegDef[rhArray, RH, 4]; {=rhS} RegDef[urSAddr, U, 38]; {tmp, used in PixelBlt} RegDef[urhSAddr, U, 41]; {tmp, used in PixelBlt} RegDef[urDAddr, U, 43]; {tmp, used in PixelBlt} RegDef[urhDAddr, U, 19]; {tmp, used in PixelBlt} RegDef[upixelcount, U, 45]; {tmp, used in PixelBlt} RegDef[uXoffset, U, 46]; {tmp, used in PixelBlt} {RegDef[uSrcflag, U, 47]; {tmp, used in PixelBlt} RegDef[uDstflag, U, 0C]; {tmp, used in PixelBlt}} RegDef[uSrcBITMAPLo, U, 5D]; {tmp, used in PixelBlt} RegDef[uSrcBITMAPHi, U, 19]; {tmp, used in PixelBlt} RegDef[uSrcXLo, U,57]; {tmp, used in PixelBlt} RegDef[uSrcYLo, U,05]; {tmp, used in PixelBlt} RegDef[uDstBITMAPHi, U, 35]; {tmp, used in PixelBlt} RegDef[uDstBITMAPLo, U, 04]; {tmp, used in PixelBlt} RegDef[uDstXLo, U, 26]; {tmp, used in PixelBlt} RegDef[uDstYLo, U, 31]; {tmp, used in PixelBlt} RegDef[uTrnWidthLo, U, 3A]; {tmp, used in PixelBlt} RegDef[uUnTrnWidthLo, U, 5C]; {tmp, used in PixelBlt} RegDef[uTrnHeightLo, U, 0D]; {= uTOS, used in PixelBlt} { ============================================================================================== Fetch stack parameters ============================================================================================== @PIXELOP: opcode[305'b], Bank _ PIXELBank, c1; This section is stored in PixelBltB1.mc uTOS _ TOS, c2; uTOSH _ TOSH, CROSS[PIXEL], c3; at[PIXEL], Xbus _ ibNA, XDisp, c1; This section is stored in PixelBltB2.mc DISP4[PIXELDISP], c2; } uS _ S, c3, at[00, 10, PIXELDISP]; NNBOP: MAR _ [rhS, S - 1], c1; {Point to UnTrnWidthHi} Ybus _ TOSH xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {Check if transfer height not NIL} Q _ MD, BRANCH[NBTE3, $], c3; MAR _ [rhS, S + 0], c1; {Point to UnTrnWidthLo} S _ S - 2, L1 _ L1.NoFixesB2, c2; TT _ MD, c3; MAR _ [rhS, S -1], c1; {Point to TrnWidthHi} Ybus _ Q xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {Check if UnTrnWidth not NIL} Q _ MD, BRANCH[NBTE1, $], c3; MAR _ [rhS, S + 0], c1; {Point to TrnWidthLo} S _ S - 2, c2; Rx _ MD, c3; Ybus _ Q xor smallpl, ZeroBr, c1; {Check if transfer width not NIL} uUnTrnWidthLo _ TT, ZeroBr, BRANCH[NBTE2, $], c2; uTrnWidthLo _ Rx, ZeroBr, BRANCH[WNZ, WZ], c3; {Check TrnWidth} WZ: BRANCH[GOTR1, NOTR1], c1; {In between lines case} GOTR1: upixelcount _ Rx, c2; {Load number of pixel per line} uXoffset _ 0, GOTO[NFM], c3; {X offset = 0} WNZ: upixelcount _ TT, BRANCH[GOTR2, NOTR2], c1; {Load number of pixel left} GOTR2: Rx _ Rx - TT, CarryBr, c2; {Calculate X offset} uXoffset _ Rx, BRANCH[NOTR4, $], c3; NFM: MAR _ [rhS, S -1], c1; {Point to DstYHi} uTrnHeightLo _ TOS, CANCELBR[$, 2], ZeroBr, c2; {Check if transfer height is 0} Q _ MD, BRANCH[$, NOTR3], c3; MAR _ [rhS, S + 0], c1; {Point to DstYLo} S _ S - 2, L3 _ 1, c2; Rx _ MD, c3; MAR _ [rhS, S -1], c1; {Point to DstXHi} Ybus _ Q xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {Check if Dst Y not NIL} Q _ MD, BRANCH[NBYE1, $], c3; MAR _ [rhS, S + 0], c1; {Point to DstXLo} Ybus _ Q xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {Check if Dst X not NIL} TT _ MD, BRANCH[NBXE1, $], c3; L2 _ L2NBRET1, c1; S _ S - 2, c2; uDstXLo _ TT, c3; MAR _ [rhS, S -1], c1; {Point to DstBITMAPHi} uDstYLo _ Rx, CANCELBR[$, 2], c2; Rx _ MD, c3; MAR _ [rhS, S + 0], c1; {Point to DstBITMAPLo} S _ S + 8, c2; TT _ MD, CALL[GetandTestBitMapParams], c3; S _ S - 10'd, c3, at[L2NBRET1, 10, GetBitMapParamsRet]; PXBK1: MAR _ [rhS, S -1], c1; {Point to SrcYHi} Ybus _ Q xor 4, CANCELBR[$, 2], ZeroBr, c2; {Check if 4 bits per pixel bitmap} Q _ MD, BRANCH[NBPXE1, $], c3; MAR _ [rhS, S + 0], c1; {Point to SrcYLo} S _ S - 2, L1 _ L1.NoFixesB2, c2; TT _ MD, c3; MAR _ [rhS, S -1], c1; {Point to SrcXHi} Ybus _ Q xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {Check if Src Y not NIL} Q _ MD, BRANCH[NBYE2, $], c3; MAR _ [rhS, S + 0], L3 _ 0, c1; {Point to SrcXLo} Ybus _ Q xor smallpl, CANCELBR[$, 2], ZeroBr, c2; {Check if Src X not NIL} Rx _ MD, BRANCH[NBXE2, $], c3; S _ S - 2, c1; uSrcXLo _ Rx, c2; uSrcYLo _ TT, c3; MAR _ [rhS, S -1], c1; {Point to SrcBITMAPHi} CANCELBR[$, 2], c2; Rx _ MD, c3; MAR _ [rhS, S + 0], L2 _ L2NBRET2, c1; {Point to SrcBITMAPLo} S _ S + 14'd, c2; TT _ MD, CALL[GetandTestBitMapParams], c3; S _ S - 16'd, c3, at[L2NBRET2, 10, GetBitMapParamsRet]; PXBK2: MAR _ [rhS, S -1], c1; {Point to CmbARRAYHi} Ybus _ Q xor 4, CANCELBR[$, 2], ZeroBr, c2; {Check if 4 bits per pixel bitmap} Q _ MD, BRANCH[NBPXE2, $], c3; MAR _ [rhS, S + 0], c1; {Point to CmbARRAYLo} rhTT _ Q LRot0, c2; {Set up high VA of color table} TT _ MD, c3; {Set up low VA of color table} Map _ [rhTT, TT + 0], L1 _ L1.NoFixesB2, c1; S _ S + 16'd, L0 _ L0NB5, c2; rhRx _ Rx _ MD, XRefBr, c3; PXBK4: BRANCH[NBCH3, $], c1, at[L0NB5, 10, RMapFixCallerB2]; Q _ uBITMAPHEIGHT, L1 _ L1SAVE, c2; {Save registers} rhArray _ Rx LRot0, CALL[SaveAllRegsB2], c3; {Load the real address of color table} { ============================================================================================== Check boundaries ============================================================================================== } PXBK3: rArray _ Rx, c1, at[L1SAVE, 10, SaveRegsB2Ret]; TT _ uSrcYLo, c2; {Check 1st Y of Src} Ybus _ Q - TT - 1, CarryBr, c3; PXBKE: TT _ TOS + TT, BRANCH[NBE1, $], c1; {TOS = TrnHeight} Ybus _ Q - TT, CarryBr, c2; {Check 2nd Y of Src} TT _ uDstYLo, BRANCH[NBE2, $], c3; {Load Y Dst} Q _ uDBitMapHeight, c1; Ybus _ Q - TT - 1, CarryBr, c2; {Check 1st Y of Dst} TT _ TOS + TT, BRANCH[NBE3, $], c3; Ybus _ Q - TT, CarryBr, c1; {Check 2nd Y of Dst} Q _ uSrcXLo, BRANCH[NBE4, $], c2; {Load X Src} TT _ RShift1 uBITMAPWIDTH, SE _ 0, c3; {Divide Src Bitmapwidth by 4} TT _ RShift1 TT, SE _ 0, c1; Ybus _ TT - Q - 1, CarryBr, c2; {Check 1st X of Src} Rx _ uTrnWidthLo, BRANCH[NBE5, $], c3; Q _ Q + Rx, c1; Ybus _ TT - Q, CarryBr, c2; {Check 2nd X of Src} TT _ RShift1 uDBitMapWidth, SE _ 0, BRANCH[NBE6, $], c3; {Divide Dst Bitmapwidth by 4} TT _ RShift1 TT, SE _ 0, c1; Q _ uDstXLo, c2; Ybus _ TT - Q - 1, CarryBr, c3; {Check 1st X of Dst} Rx _ Q + Rx, BRANCH[NBE7, $], c1; Ybus _ TT - Rx, CarryBr, c2; {Check 2nd X of Dst} Q _ uDstYLo, BRANCH[NBE8, $], c3; LINE: Q _ Q + TOS, L0 _ L0NB3, c1; Rx _ uDBitMapHeight, c2; Q _ Rx - Q, c3; TOS _ uDBRasterWidth, CALL[MTPL], c1; {Calculate Y*Bitmaprasterwidth of Dst} Rx _ uDstYLo, c3, at[L0NB3, 10, MULCALLER]; TOS _ uTrnHeightLo, c1; TOS _ TOS - 1, c2; TOS _ TOS + Rx, c3; TOS _ TOS LShift1, SE _ 0, c1; PV _ TOS LShift1, SE _ 0, c2; {Multiply Y by 4} Rx _ uDstXLo, c3; Noop, c1; TOS _ uXoffset, c2; Rx _ Rx + TOS, c3; {Calculate the starting X for Dst} Rx _ Rx and 03, c1; Noop, c2; PV _ PV + Rx, YDisp, c3; Rx _ uDstXLo, DISP4[L3VAL, 8], c1; Rx _ Rx + TOS, L3 _ 00, c2, at[08, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 000} Rx _ Rx + TOS, L3 _ 01, c2, at[09, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 001} Rx _ Rx + TOS, L3 _ 02, c2, at[0A, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 010} Rx _ Rx + TOS, L3 _ 03, c2, at[0B, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 011} Rx _ Rx + TOS, L3 _ 04, c2, at[0C, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 100} Rx _ Rx + TOS, L3 _ 05, c2, at[0D, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 101} Rx _ Rx + TOS, L3 _ 06, c2, at[0E, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 110} Rx _ Rx + TOS, L3 _ 07, c2, at[0F, 10, L3VAL]; GOTO[DSCO], c3; {Current YXX = 111} DSCO: Rx _ RShift1 Rx, SE _ 0, c1; {Divide X by 4} Rx _ RShift1 Rx, SE _ 0, c2; Q _ Rx + Q, CarryBr, c3; Rx _ uDBMBaseLo, BRANCH[NBNA1, NBA1], c1; {Load low word of base VA of Dst bitmap} NBA1: TT _ TT + 1, GOTO[NBCM1], c2; {Propagate carry to high word} NBNA1: Noop, c2; NBCM1: Rx _ Rx + Q, CarryBr, c3; {Set up low word of VA of Dst bitmap} Q _ uDBMBaseHi, BRANCH[NBNA2, NBA2], c1; {Load high word of base VA of Dst bitmap} NBA2: TT _ TT + 1, GOTO[NBCM2], c2; {Propagate carry to high word} NBNA2: Noop, c2; NBCM2: Q _ TT + Q, c3; rhTT _ Q LRot0, c1; {Set up high word of VA of Dst bitmap} urhDAddr _ Q, c2; {Save it} urDAddr _ Rx, c3; PXBK5: Map _ TT _ [rhTT, Rx], L1 _ L1.PX.NR.0A, c1; TOS _ uBITMAPRASTERWIDTH, L0 _ L0.PX.NR.0A, c2; {Save low word of VA for remapping} rhRx _ Rx _ MD, XwdDisp, c3; PXBK6: MAR _ Q _ [rhRx, TT + 0], DISP2[NBCH1], c1, at[L0.PX.NR.0A, 10, NRWMapFixCallerB2]; rDAddr _ Q, c2, at[1, 4, NBCH1]; {Save the low word of real address} DstReg _ MD, c3; {Fetch Dst} rhDAddr _ Rx LRot0, c1; {Save the high word of real address} Q _ uSrcYLo, L0 _ L0NB4, c2; TT _ uTrnHeightLo, c3; Rx _ uBITMAPHEIGHT, c1; Q _ TT + Q, c2; Q _ Rx - Q, c3; CALL[MTPL], c1; {Calculate Y*Bitmaprasterwidth of Src} TOS _ uSrcXLo, c3, at[L0NB4, 10, MULCALLER]; Rx _ uXoffset, c1; Rx _ TOS + Rx, YDisp, c2; {Calculate initial X of Src} DISP4[L2VAL, 0C], c3; L2 _ 0C, c1, at[0C, 10, L2VAL]; GOTO[SRCO], c2; {Current XX = 00} L2 _ 0D, c1, at[0D, 10, L2VAL]; GOTO[SRCO], c2; {Current XX = 01} L2 _ 0E, c1, at[0E, 10, L2VAL]; GOTO[SRCO], c2; {Current XX = 10} L2 _ 0F, c1, at[0F, 10, L2VAL]; GOTO[SRCO], c2; {Current XX = 11} SRCO: Rx _ RShift1 Rx, SE _ 0, c3; {Divide X by 4} Rx _ RShift1 Rx, SE _ 0, c1; Q _ Rx + Q, CarryBr, c2; Rx _ uBITMAPBASELO, BRANCH[NBNA3, NBA3], c3; NBA3: TT _ TT + 1, GOTO[NBCM3], c1; NBNA3: Noop, c1; NBCM3: Rx _ Rx + Q, CarryBr, c2; Q _ uBITMAPBASEHI, BRANCH[NBNA4, NBA4], c3; NBA4: TT _ TT + 1, GOTO[NBCM4], c1; NBNA4: Noop, c1; NBCM4: Q _ TT + Q, c2; rhTT _ Q LRot0, c3; urhSAddr _ Q, c1; {Save the high word of VA of Src for remapping} urSAddr _ Rx, c2; L1 _ L1.PX.NR.04, c3; PXBK7: Map _ TT _ [rhTT, Rx], c1; L0 _ L0.PX.NR.04, c2; {Save the low word of VA of Src for remapping} rhRx _ Rx _ MD, XwdDisp, c3; PXBK8: MAR _ Q _ [rhRx, TT + 0], DISP2[NBCH2], c1, at[L0.PX.NR.04, 10, NRWMapFixCallerB2]; rhSAddr _ Rx LRot0, c2, at[1, 4, NBCH2]; SrcReg _ MD, c3; {Fetch Src} rSAddr _ Q, L2Disp, c1; {Save the high word of real address of Src} DISP4[srcSel, 0C], c2; GOTO[SCO0], c3, at[0C, 10, srcSel]; {XX = 00} GOTO[SCO1], c3, at[0F, 10, srcSel]; {XX = 11} SrcReg _ SrcReg LRot12, GOTO[SCO2], c3, at[0E, 10, srcSel]; {XX = 10} SrcReg _ SrcReg LRot8, GOTO[SCO3], c3, at[0D, 10, srcSel]; {XX = 01} { ============================================================================================== Inner loop ============================================================================================== } {Case 1 : already have src nibl in SrcReg} SCO1: SrcReg _ SrcReg LRot4, L2 _ 0C, c1, at[0F, 10, srcNext]; {allign for curr nibl} {Current XX = 11, Next = 00} Rx _ SrcReg and 0F0, GOTO[GotSrcNibl], L3Disp, c2; {get nibl in bits 8-11} SCO2: SrcReg _ SrcReg LRot4, L2 _ 0F, c1, at[0E, 10, srcNext]; {allign for curr nibl} {Current XX = 10, Next = 11} Rx _ SrcReg and 0F0, GOTO[GotSrcNibl], L3Disp, c2; {get nibl in bits 8-11} SCO3: SrcReg _ SrcReg LRot4, L2 _ 0E, c1, at[0D, 10, srcNext];{allign for curr nibl} {Current XX = 01, Next = 10} Rx _ SrcReg and 0F0, GOTO[GotSrcNibl], L3Disp, c2; {get nibl in bits 8-11} {Case 2: need to read next src word} MAR _ rSAddr _ [rhSAddr, rSAddr + 1], c1, at[0C, 10, srcNext]; BRANCH[$, fixSAddr, 1], c2; SCONT: SrcReg _ MD, c3; SCO0: SrcReg _ SrcReg LRot8, L2 _ 0D, c1; {Current XX = 00, Next = 01} Rx _ SrcReg and 0F0, GOTO[GotSrcNibl], L3Disp, c2; {get src nibl in bits 8-11} GotSrcNibl: DISP4[dstNext, 04], c3; {First pass} DCO0: DstReg _ DstReg LRot4, c1, at[04, 10, dstNext]; {allign for curr nibl} {Current XX = 00, Next = 01} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} DCO1: DstReg _ DstReg LRot8, c1, at[05, 10, dstNext]; {allign for curr nibl} {Current XX = 01, Next = 10} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} DCO2: DstReg _ DstReg LRot12, c1, at[06, 10, dstNext]; {allign for curr nibl} {Current XX = 10, Next = 11} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} DCO3: DstReg _ DstReg LRot0, c1, at[07, 10, dstNext]; {Position the right nibble at bits 12 - 15} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get dst nibl in bits 12-15} {Case 1: already have dst nibl in DstReg} DCO00: DstReg _ DstReg LRot4, c1, at[0C, 10, dstNext]; {allign for curr nibl} {Current XX = 00, Next = 01} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} DCO01: DstReg _ DstReg LRot4, c1, at[0D, 10, dstNext]; {allign for curr nibl} {Current XX = 01, Next = 10} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} DCO03: DstReg _ DstReg LRot4, c1, at[0E, 10, dstNext]; {allign for curr nibl} {Current XX = 10, Next = 11} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} {Case 2: need next dest word} DCO02: DstReg _ DstReg LRot4, c1, at[0F, 10, dstNext]; {allign for curr nibl} {Current XX = 10, Next = 11} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get nibl in bits 12-15} { DCO03: MAR _ [rhDAddr, rDAddr + 0], c1, at[0F, 10, dstNext]; {write last value} MDR _ DstReg, c2; , c3; MAR _ rDAddr _ [rhDAddr, rDAddr + 1], c1; {read next value} BRANCH[$, fixDAddr, 1], c2; DstReg _ MD, c3; DCONT: DstReg _ DstReg LRot4, c1; {Position the right nibble at bits 12 - 15} Q _ DstReg and 0F, GOTO[GotDstNibl], c2; {get dst nibl in bits 12-15}} GotDstNibl: Rx _ Rx or Q, c3; {Concatenate Src and Dst} MAR _ [rhArray, Rx{src,,dst} + 0], c1; {Fetch entry from color table} DstReg _ DstReg and ~0F, L3Disp, c2; {erase orig value of Dst nibble} Rx{val} _ MD, DISP4[loc, 8], c3; CLY0: Rx _ Rx LRot4, L3 _ 09, c1, at[08, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 000, Entry 0, Next: YXX = 001, Entry 1} DstReg _ DstReg or Rx, GOTO[entryready], c3; CLY1: Rx _ Rx LRot8, L3 _ 0A, c1, at[09, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 001, Entry 1, Next: YXX = 010, Entry 0} DstReg _ DstReg or Rx, GOTO[entryready], c3; CLY2: Rx _ Rx LRot4, L3 _ 0B, c1, at[0A, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 010, Entry 0, Next: YXX = 011, Entry 1} DstReg _ DstReg or Rx, GOTO[entryready], c3; CLY3: Rx _ Rx LRot8, L3 _ 08, c1, at[0B, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 011, Entry 1, Next: YXX = 000, Entry 0} DstReg _ DstReg or Rx, c3; MAR _ [rhDAddr, rDAddr + 0], c1; {write} MDR _ DstReg, c2; , c3; MAR _ rDAddr _ [rhDAddr, rDAddr + 1], c1; {read next value} BRANCH[$, fixDAddr1, 1], c2; DstReg _ MD, GOTO[entryready], c3; CLY4: Rx _ Rx LRot12, L3 _ 0D, c1, at[0C, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 100, Entry 2, Next: YXX = 101, Entry 3} DstReg _ DstReg or Rx, GOTO[entryready], c3; CLY5: Rx _ Rx LRot0, L3 _ 0E, c1, at[0D, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 101, Entry 3, Next: YXX = 110, Entry 2} DstReg _ DstReg or Rx, GOTO[entryready], c3; CLY6: Rx _ Rx LRot12, L3 _ 0F, c1, at[0E, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 110, Entry 2, Next: YXX = 111, Entry 3} DstReg _ DstReg or Rx, GOTO[entryready], c3; CLY7: Rx _ Rx LRot0, L3 _ 0C, c1, at[0F, 10, loc]; Rx _ Rx and 0F, c2; {Current YXX = 111, Entry 3, Next: YXX = 100, Entry 2} DstReg _ DstReg or Rx, c3; {insert new value} MAR _ [rhDAddr, rDAddr + 0], c1; {write} MDR _ DstReg, c2; , c3; MAR _ rDAddr _ [rhDAddr, rDAddr + 1], c1; {read next value} BRANCH[$, fixDAddr2, 1], c2; DstReg _ MD, GOTO[entryready], c3; entryready: Q _ upixelcount, c1; Q _ Q - 1, ZeroBr, c2; {Decrement pixel count} BRANCH[$, LNFN], c3; PXBKB: Noop , c1; L2Disp, c2; upixelcount _ Q, DISP4[srcNext, 0C], c3; {loop back} { ============================================================================================== Update # of lines ============================================================================================== } LNFN: Q _ uTrnWidthLo, L3Disp, c1; upixelcount _ Q, DISP4[DstAllign, 0C], c2; {Initialize pixel count} DstReg _ DstReg LRot0, GOTO[PXBKC], c3, at[0C, 10, DstAllign]; DstReg _ DstReg LRot4, GOTO[PXBKC], c3, at[0F, 10, DstAllign]; DstReg _ DstReg LRot8, GOTO[PXBKC], c3, at[0E, 10, DstAllign]; DstReg _ DstReg LRot12, GOTO[PXBKC], c3, at[0D, 10, DstAllign]; PXBKC: MAR _ [rhDAddr, rDAddr + 0], c1; {Write the last value} MDR _ DstReg, c2; Q _ uTrnHeightLo, c3; Q _ Q - 1, ZeroBr, c1; uTrnHeightLo _ Q, BRANCH[$, NBEX], c2; { ============================================================================================== Handle Interrupts ============================================================================================== } uXoffset _ 0, MesaIntBr, c3; Ybus _ uWDC, NZeroBr, BRANCH[NBNI1, $], c1; Ybus _ uWP, ZeroBr, BRANCH[$, NBNI2], c2; uWP _ 0, BRANCH[NBIN, NBNI3], c3; NBIN: TOS _ uTrnHeightLo, c1; TOSH _ uTOSH, c2; rhS _ nRhS, c3; Noop, c1; S _ uS, c2; Q _ 0, c3; MAR _ [rhS, S + 0], c1; MDR _ Q, c2; PV _ uPVx, c3; Bank _ EmuBank, c1; rhPV _ nRhS, c2; PC _ uPC, CROSS[EmuInt], c3; { ClrIntErr, Rx _ 1, c1, at[EmuInt]; uWDC _ Rx, c2; Rx _ KbdFXP, L2 _ 0, GOTO[PUNT], c3;} NBNI1: Q _ uDstYLo, CANCELBR[$], c2; TOS _ uTrnHeightLo, GOTO[LINE], c3; NBNI2: CANCELBR[$], c3; NBNI3: Q _ uDstYLo, c1; TOS _ uTrnHeightLo, c2; GOTO[LINE], c3; { ============================================================================================== Remap ============================================================================================== } fixDAddr1: uRx _ Rx, c3; PXS0: TT _ urDAddr, c1; {Retrieve original rDAddr} Q _ 0FF + 1, c2; {Load Q with 100} TT _ TT + Q, CarryBr, c3; {Add rDAddr with 100} Q _ urhDAddr, BRANCH[NBND1, NBAD1], c1; NBAD1: Q _ Q + 1, c2; Noop, c3; Noop, c1; NBND1: rhTT _ Q LRot0, c2; urhDAddr _ Q, c3; NBMP1: Map _ [rhTT, TT + 0], L1 _ L1.PX.NR.05, c1; urDAddr _ TT, L0 _ L0.PX.NR.05, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, rDAddr + 0], DISP2[NBMAP1], c1, at[L0.PX.NR.05, 10, NRWMapFixCallerB2]; rDAddr _ Q, c2, at[1, 4, NBMAP1]; DstReg _ MD, c3; Q _ rhRx, c1; rhDAddr _ Q LRot0, c2; Rx _ uRx, GOTO[entryready], c3; fixDAddr2: uRx _ Rx, c3; PXS1: TT _ urDAddr, c1; {Retrieve original rDAddr} Q _ 0FF + 1, c2; {Load Q with 100} TT _ TT + Q, CarryBr, c3; {Add rDAddr with 100} Q _ urhDAddr, BRANCH[NBND10, NBAD10], c1; NBAD10: Q _ Q + 1, c2; Noop, c3; Noop, c1; NBND10: rhTT _ Q LRot0, c2; urhDAddr _ Q, c3; NBMP10: Map _ [rhTT, TT + 0], L1 _ L1.PX.NR.06, c1; urDAddr _ TT, L0 _ L0.PX.NR.06, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, rDAddr + 0], DISP2[NBMAP3], c1, at[L0.PX.NR.06, 10, NRWMapFixCallerB2]; rDAddr _ Q, c2, at[1, 4, NBMAP3]; DstReg _ MD, c3; Q _ rhRx, c1; rhDAddr _ Q LRot0, c2; Rx _ uRx, GOTO[entryready], c3; { ================================================================================= Set up registers and memories ================================================================================= } PXS3: S _ uS, c1, at[L1.PX.NR.06, 10, NTrapFixesB2]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q - 1, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB2], c1; PXS4: S _ uS, c1, at[L1.PX.NR.05, 10, NTrapFixesB2]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q - 1, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB2], c1; fixSAddr: TT _ urSAddr, c3; {Retrieve original rSAddr} Q _ 0FF + 1, c1; {Load Q with 100} TT _ TT + Q, CarryBr, c2; {Add rSAddr with 100} Q _ urhSAddr, BRANCH[NBNS1, NBAS1], c3; NBAS1: Q _ Q + 1, c1; rhTT _ Q LRot0, c2; urhDAddr _ Q, GOTO[NBMP2], c3; NBNS1: rhTT _ Q LRot0, c1; Noop, c2; Noop, c3; NBMP2: Map _ [rhTT, TT + 0], L1 _ L1.PX.NR.07, c1; urSAddr _ TT, L0 _ L0.PX.NR.07, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, rSAddr + 0], DISP2[NBMAP2], c1, at[L0.PX.NR.07, 10, NRWMapFixCallerB2]; rSAddr _ Q, c2, at[1, 4, NBMAP2]; SrcReg _ MD, c3; Q _ rhRx, c1; rhSAddr _ Q LRot0, c2; GOTO[SCO0], c3; { ================================================================================= Set up registers and memories ================================================================================= } PXS5: S _ uS, c1, at[L1.PX.NR.07, 10, NTrapFixesB2]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB2], c1; PXS6: S _ uS, c1, at[L1.PX.NR.0A, 10, NTrapFixesB2]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB2], c1; PXS7: S _ uS, c1, at[L1.PX.NR.04, 10, NTrapFixesB2]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB2], c1; NBCH3: CALL[RLMapFixB2], c2; GOTO[NRWLMapFixB2], c2, at[0, 4, NBCH1]; GOTO[NRWLMapFixB2], c2, at[2, 4, NBCH1]; GOTO[NRWLMapFixB2], c2, at[3, 4, NBCH1]; GOTO[NRWLMapFixB2], c2, at[0, 4, NBCH2]; GOTO[NRWLMapFixB2], c2, at[2, 4, NBCH2]; GOTO[NRWLMapFixB2], c2, at[3, 4, NBCH2]; GOTO[NRWLMapFixB2], c2, at[0, 4, NBMAP1]; GOTO[NRWLMapFixB2], c2, at[2, 4, NBMAP1]; GOTO[NRWLMapFixB2], c2, at[3, 4, NBMAP1]; GOTO[NRWLMapFixB2], c2, at[0, 4, NBMAP3]; GOTO[NRWLMapFixB2], c2, at[2, 4, NBMAP3]; GOTO[NRWLMapFixB2], c2, at[3, 4, NBMAP3]; GOTO[NRWLMapFixB2], c2, at[0, 4, NBMAP2]; GOTO[NRWLMapFixB2], c2, at[2, 4, NBMAP2]; GOTO[NRWLMapFixB2], c2, at[3, 4, NBMAP2]; { ================================================================================== Error cases ================================================================================== } NBYE1: S _ uS, GOTO[ufnX2], c1; NBYE2: S _ uS, GOTO[ufnX2], c1; NBXE1: S _ uS, GOTO[ufnX2], c1; NBXE2: S _ uS, GOTO[ufnX2], c1; NBPXE1: S _ uS, GOTO[ufnX2], c1; NBPXE2: S _ uS, GOTO[ufnX2], c1; NBTE1: S _ uS, GOTO[ufnX2], c1; NBTE2: S _ uS, CANCELBR[ufnX1, 3], c3; NBTE3: S _ uS, GOTO[ufnX2], c1; NBE1: S _ uS, c2; rhS _ nRhS, GOTO[ufnX1], c3; NBE2: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX3], c2;} NBE3: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX3], c2;} NBE7: Noop, c2; {S _ uS, c2; rhS _ nRhS, GOTO[ufnX1], c3;} NBE4: S _ uS, c3; rhS _ nRhS, GOTO[ufnX2], c1; NBE5: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX3], c2;} NBE6: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX3], c2;} NBE8: S _ uS, c1; NBE09: rhS _ nRhS, GOTO[ufnX3], c2; NOTR3: Noop, c1; NOTR1: S _ uS, GOTO[ufnX3], c2; NOTR4: Noop, c1; NOTR2: S _ uS, GOTO[ufnX3], c2; { NOTR1: S _ uS, GOTO[ufnX3], c2; NOTR2: S _ uS, GOTO[ufnX3], c2; NOTR3: S _ uS, GOTO[ufnX2], c1; NOTR4: S _ uS, GOTO[ufnX2], c1;} { ================================================================================== Exit ================================================================================== } NBEX: Q _ 18'd, c3; Xbus _ ib, GOTO[RestoreAllRegsAndExitB2], c1; { E N D }