{File name : PixelBltB0.mc Author : Gwan Santosa & Don Charnley Date : 20-Sep-85 10:37:24 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] 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} Stored in NewFuncDef.dfn } { ============================================================================================== Fetch stack parameters ============================================================================================== @PIXELOP: opcode[305'b], Bank _ PIXELBank, c1; This section is stored in LispPixelBltB1.mc uTOS _ TOS, c2; uTOSH _ TOSH, CROSS[PIXEL], c3; at[PIXEL], Xbus _ ibNA, XDisp, c1; This section is stored in LispPixelBltB0.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.NoFixesB0, 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 _ L2.FETCHBM.01, 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[GetTestBMParamsB0], c3; S _ S - 10'd, c3, at[L2.FETCHBM.01, 10, GetTestBMParamsB0Ret]; 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.NoFixesB0, 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 _ L2.FETCHBM.00, c1; {Point to SrcBITMAPLo} S _ S + 14'd, c2; TT _ MD, CALL[GetTestBMParamsB0], c3; S _ S - 16'd, c3, at[L2.FETCHBM.00, 10, GetTestBMParamsB0Ret]; 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.NoFixesB0, c1; S _ S + 16'd, L0 _ L0.RMAPB0.1, c2; rhRx _ Rx _ MD, XRefBr, c3; PXBK4: BRANCH[NBCH3, $], c1, at[L0.RMAPB0.1, 10, RMapFixCallerB0]; Q _ uBITMAPHEIGHT, L1 _ L1.RegSaveRet.1, c2; {Save registers} rhArray _ Rx LRot0, CALL[SaveAllRegsB0], c3; {Load the real address of color table} { ============================================================================================== Check boundaries ============================================================================================== } PXBK3: rArray _ Rx, c1, at[L1.RegSaveRet.1, 10, SaveRegsB0Ret]; 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 _ L0.MUL.02, c1; Rx _ uDBitMapHeight, c2; Q _ Rx - Q, c3; TOS _ uDBRasterWidth, CALL[MTPLB0], c1; {Calculate Y*Bitmaprasterwidth of Dst} Rx _ uDstYLo, c3, at[L0.MUL.02, 10, MULCALLERB0]; 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.TrapFixesB0.3, c1; TOS _ uBITMAPRASTERWIDTH, L0 _ L0.WMAPB0.0, c2; {Save low word of VA for remapping} rhRx _ Rx _ MD, XwdDisp, c3; PXBK6: MAR _ Q _ [rhRx, TT + 0], DISP2[NBCH1], c1, at[L0.WMAPB0.0, 10, WMapFixCallerB0]; 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 _ L0.MUL.01, c2; TT _ uTrnHeightLo, c3; Rx _ uBITMAPHEIGHT, c1; Q _ TT + Q, c2; Q _ Rx - Q, c3; CALL[MTPLB0], c1; {Calculate Y*Bitmaprasterwidth of Src} TOS _ uSrcXLo, c3, at[L0.MUL.01, 10, MULCALLERB0]; 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.TrapFixesB0.3, c3; PXBK7: Map _ TT _ [rhTT, Rx], c1; L0 _ L0.WMAPB0.1, 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.WMAPB0.1, 10, WMapFixCallerB0]; 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.TrapFixesB0.4, c1; urDAddr _ TT, L0 _ L0.WMAPB0.3, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, rDAddr + 0], DISP2[NBMAP1], c1, at[L0.WMAPB0.3, 10, WMapFixCallerB0]; 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.TrapFixesB0.4, c1; urDAddr _ TT, L0 _ L0.WMAPB0.4, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, rDAddr + 0], DISP2[NBMAP3], c1, at[L0.WMAPB0.4, 10, WMapFixCallerB0]; 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 ================================================================================= } 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.TrapFixesB0.3, c1; urSAddr _ TT, L0 _ L0.WMAPB0.2, c2; rhRx _ Rx _ MD, XwdDisp, c3; MAR _ Q _ [rhRx, rSAddr + 0], DISP2[NBMAP2], c1, at[L0.WMAPB0.2, 10, WMapFixCallerB0]; 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 ================================================================================= } PXSTR: S _ uS, c1, at[L1.TrapFixesB0.3, 10, TrapFixesB0]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB0], c1; S _ uS, c1, at[L1.TrapFixesB0.4, 10, TrapFixesB0]; rhS _ nRhS, c2; Q _ upixelcount, c3; MAR _ [rhS, S + 0], c1; MDR _ Q - 1, c2; Q _ 0, c3; GOTO[RestoreAllRegsAndPFB0], c1; NBCH3: CALL[RLMapFixB0], c2; GOTO[WLMapFixB0], c2, at[0, 4, NBCH1]; GOTO[WLMapFixB0], c2, at[2, 4, NBCH1]; GOTO[WLMapFixB0], c2, at[3, 4, NBCH1]; GOTO[WLMapFixB0], c2, at[0, 4, NBCH2]; GOTO[WLMapFixB0], c2, at[2, 4, NBCH2]; GOTO[WLMapFixB0], c2, at[3, 4, NBCH2]; GOTO[WLMapFixB0], c2, at[0, 4, NBMAP1]; GOTO[WLMapFixB0], c2, at[2, 4, NBMAP1]; GOTO[WLMapFixB0], c2, at[3, 4, NBMAP1]; GOTO[WLMapFixB0], c2, at[0, 4, NBMAP3]; GOTO[WLMapFixB0], c2, at[2, 4, NBMAP3]; GOTO[WLMapFixB0], c2, at[3, 4, NBMAP3]; GOTO[WLMapFixB0], c2, at[0, 4, NBMAP2]; GOTO[WLMapFixB0], c2, at[2, 4, NBMAP2]; GOTO[WLMapFixB0], c2, at[3, 4, NBMAP2]; { ================================================================================== Error cases ================================================================================== } NBYE1: S _ uS, GOTO[ufnX20], c1; NBYE2: S _ uS, GOTO[ufnX20], c1; NBXE1: S _ uS, GOTO[ufnX20], c1; NBXE2: S _ uS, GOTO[ufnX20], c1; NBPXE1: S _ uS, GOTO[ufnX20], c1; NBPXE2: S _ uS, GOTO[ufnX20], c1; NBTE1: S _ uS, GOTO[ufnX20], c1; NBTE2: S _ uS, CANCELBR[ufnX10, 3], c3; NBTE3: S _ uS, GOTO[ufnX20], c1; NBE1: S _ uS, c2; rhS _ nRhS, GOTO[ufnX10], c3; NBE2: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX30], c2;} NBE3: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX30], c2;} NBE7: Noop, c2; {S _ uS, c2; rhS _ nRhS, GOTO[ufnX10], c3;} NBE4: S _ uS, c3; rhS _ nRhS, GOTO[ufnX20], c1; NBE5: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX30], c2;} NBE6: S _ uS, GOTO[NBE09], c1; {rhS _ nRhS, GOTO[ufnX30], c2;} NBE8: S _ uS, c1; NBE09: rhS _ nRhS, GOTO[ufnX30], c2; NOTR3: Noop, c1; NOTR1: S _ uS, GOTO[ufnX30], c2; NOTR4: Noop, c1; NOTR2: S _ uS, GOTO[ufnX30], c2; { NOTR1: S _ uS, GOTO[ufnX30], c2; NOTR2: S _ uS, GOTO[ufnX30], c2; NOTR3: S _ uS, GOTO[ufnX20], c1; NOTR4: S _ uS, GOTO[ufnX20], c1;} { ================================================================================== Exit ================================================================================== } NBEX: Q _ 18'd, c3; Xbus _ ib, GOTO[RestoreAllRegsAndExitB0], c1; { ======================================================================= Test type of Bitmap and fetch record of Bitmap ======================================================================= subroutine to check BitMap type and get BitMap parameters Rx, TT have VA of BitMapTable L3 _ 0{Src}/1{Dst} has six or'd in at exit L2 used for return uses NoFixes if PageFault trashes L0, L1, TT, Rx, Q, rhTT, rhRx values from table are placed into: if Src then : uBITMAPBASEHI if Dst then : uDBMBaseHi uBITMAPBASELO uDBMBaseLo uBITMAPRASTERWIDTH uDRasterWidth uBITMAPHEIGHT uDBitMapHeight uBITMAPWIDTH uDBitMapWidth uBITMAPBITSPERPIXEL uDBitsPerPixel Set[L0.GBMP, 09];{must be odd! uses even also} Stored in NewFuncDef.dfn} GetTestBMParamsB0: MAR _ Q _ [TT, Rx + 0], c1;{not mem ref, byte merge} rhTT _ Rx LRot0, c2; Rx _ Q, rhRx _ crhTypeTable, c3; Rx _ Rx LRot8, c1; Rx _ Rx RShift1, getTypemsBit, c2; Q _ 0FF, c3; MAR _ [rhRx, Rx + 0], c1; Rx _ BitMapType, c2; Rx _ MD xor Rx, c3; GetBMParsB0: Map _ [rhTT, TT], L1 _ L1.NoFixesB0, c1; Ybus _ Q and Rx, ZeroBr, L0 _ L0.RMAPB0.9, c2; Rx _ rhRx _ MD, XRefBr, BRANCH[notBMufn, $], c3; MAR _ Q _ [rhRx, TT + 0], BRANCH[GBMremapit0, $], c1, at[L0.RMAPB0.9, 10, RMapFixCallerB0]; Rx _ Q, L3Disp, c2; Q _ MD, L3Disp, DISP3[GBMfixitret0, 1] c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest10], c1, at[1, 8, GBMfixitret0]; uBITMAPBASEHI _ Q, CANCELBR[$, 2], c2; GBMdest1ret0: Q _ MD, L3Disp, c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest20], c1; uBITMAPBASELO _ Q, BRANCH[$, GBMfixitA0, 1], c2; GBMdest2ret0: Q _ MD, L3Disp, c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest30, 2], c1, at[3, 8, GBMfixitret0]; uBITMAPRASTERWIDTH _ Q, CANCELBR[$, 2], c2; GBMdest3ret0: Q _ MD, L3Disp, c3; MAR _ Rx _ [rhRx, Rx + 1], BRANCH[$, GBMdest40, 6], L3 _ 6, c1; uBITMAPHEIGHT _ Q, BRANCH[$, GBMfixitB0, 1], c2; GBMdest4ret0: Q _ MD, L3Disp, c3; MAR _ [rhRx, Rx + 1], BRANCH[$, GBMdest50, 6], c1, at[7, 8, GBMfixitret0]; uBITMAPWIDTH _ Q, CANCELBR[$, 2], c2; GBMdest5ret0: Q _ MD, L3Disp, c3; BRANCH[$, GBMdest60, 6], L2Disp, c1; uBITMAPBITSPERPIXEL _ Q, DISP4[GetTestBMParamsB0Ret], c2; GBMdest10: uDBMBaseHi _ Q, CANCELBR[GBMdest1ret0, 2], c2; GBMdest20: uDBMBaseLo _ Q, BRANCH[GBMdest2ret0, GBMfixitA0, 1], c2; GBMdest30: uDBRasterWidth _ Q, CANCELBR[GBMdest3ret0, 2], c2; GBMdest40: uDBitMapHeight _ Q, BRANCH[GBMdest4ret0, GBMfixitB0, 1], c2; GBMdest50: uDBitMapWidth _ Q, CANCELBR[GBMdest5ret0, 2], c2; GBMdest60: uDBitsPerPixel _ Q, DISP4[GetTestBMParamsB0Ret], c2; GBMremapit0: CALL[RLMapFixB0], c2; GBMfixitA0: TT _ TT and ~0FF, GOTO[GBMallfixit0], c3; GBMfixitB0: TT _ TT and ~0FF, GOTO[GBMallfixit0], c3; GBMallfixit0: Q _ 0FF + 1, c1; TT _ TT + Q, CarryBr, c2; Rx _ 0, BRANCH[GetBMParsB0, GBMfixrh0], c3; GBMfixrh0: Q _ rhTT, c1; Q _ Q + 1, c2; rhTT _ Q LRot0, GOTO[GetBMParsB0], c3; notBMufn: CANCELBR[ufnX20, 3], c1; { E N D }