{File name NewBLT.mc Description: new BLT code Author: Charnley Created: 9-Jun-83 11:01:00 Last edit by Charnley: 20-Jul-83 10:44:09 } SetTask[0]; {******************************************************************* BLT {daddr, saddr, nwords} ********************************************************************} { this code uses a two click inner loop to transfer words. the loop is exited when either the source or the dest cross a page boundary {and require remapping} or the required number of words has been moved. a test for pending interrupts is performed whenever the source is remapped {care must be taken to ignore uPCCrossL} AT ENTRY tos : number of words tos-1: virtual address of first source word tos-2: virtual address of first dest word AT INTERRUPT EXIT tos : number of words remaining tos-1: virtual address of first source word tos-2: virtual address of first dest word AT COMPLETION EXIT stkcnt ← stkcnt - 2 } { REGISTER USAGE Within Inner Loop: Q cnt of words to go TOSH Src Real Address TOS Dst Real Address TT Move Data rhTOSH High Src Real Address rhTOS High Dst Real Address } { BLTInnerLoop } BLTS1: MAR ← {SrcRA}TOSH ← [rhTOSH,TOSH - 1], BRANCH[BLTdone, $], c1; BLTS2: BRANCH[$, BLTSrcRemap, 1], c2; BLTS3: {Data}TT ← MD, c3; BLTD1: MAR ← {DstRA}TOS ← [rhTOS, TOS - 1], c1; BLTD2: MDR ← {Data}TT, BRANCH[$, BLTDstRemap, 1], c2; BLTD3: Q{BLTcnt} ← Q - 1, CarryBr, GOTO[BLTS1], c3; { Loop Exits} BLTSrcRemap: {restore state first} uSaveTOS ← TOS, L2 ← 1, c3;{save DstRA, set L2 for Src Remap} { test for interrupt} TOS ← Q + 1, L1 ← L1.NoFixes, c1;{restore TOS} Ybus ← Q and ~0F, ZeroBr, c2;{small counts don't interrupt} TOSH ← smallpl, MesaIntBr, BRANCH[$, BLTnoint0], c3;{restore TOSH} Ybus ← uWDC, NZeroBr, BRANCH[BLTnoint1, $], c1; Ybus ← uWP, ZeroBr, BRANCH[$, BLTnoint2], c2; uWP ← 0, BRANCH[BLTIntNow, BLTnoint3], c3; BLTIntNow: ClrIntErr, Rx ← 1, c1; uWDC ← Rx,{off interrupts} c2; Rx ← KbdFXP, L2 ← 0, GOTO[PUNT], c3; BLTnoint1: CANCELBR[$], c2; BLTnoint2: CANCELBR[BLTRemap], c3; BLTSrc: {BLTRemap returns here} Rx ← rhRx ← MD, XRefBr, c3; Q ← rhRx, BRANCH[BLTSMap, $], c1,at[L0.RedoBLT,10,RxMapFixCaller];{move rhRx,,Rx to rhTOSH,,TOSH} rhTOSH ← Q LRot0, c2; TOSH ← Rx, c3; Q ← TOS - 1, c1;{restore loop count} TOS ← uSaveTOS, c2;{restore DstRA} c3; MAR ← {SrcRA}TOSH ← [rhTOSH, TT + 0], GOTO[BLTS2], c1; BLTSMap: CALL[RLxMapFix], c2; BLTDstRemap: { restore state, prepare for Remap} uSaveTOSH ← TOSH, L2 ← 3, c3;{save SrcRA, set L2 for Dst Remap} uSaveTT ← TT, c1;{save Data} c2; c3; TOS ← Q + 1, L1 ← L1.PushOnly, c1;{restore TOS} TOSH ← smallpl, c2;{restore TOSH} S ← S - 2, GOTO[BLTRemap], c3;{point stack at Dest} BLTDst: {BLTRemap returns here} Rx ← rhRx ← MD, XDirtyDisp, c3; Q ← rhRx, BRANCH[BLTDMap, $, 1], c1,at[L0.RedoBLT,10,WMapFixCaller]; rhTOS ← Q LRot0, c2;{move rhRx,,Rx to rhTOS,,TOS} Q ← TOS - 1, c3;{restore loop count} TOS ← Rx, c1; TOSH ← uSaveTOSH, c2;{restore SrcRA} S ← S + 2, c3;{restore stack} MAR ← {DstRA}TOS ← [rhTOS, TT + 0], c1; MDR ← uSaveTT, GOTO[BLTD3], c2;{store saved data} BLTDMap: CALL[WLMapFix], c2; {****************************************************} BLTnoint0: MAR ← [rhS, S + 0], L0 ← L0.RedoBLT, CANCELBR[BLTReX], c1; BLTnoint3: MAR ← [rhS, S + 0], L0 ← L0.RedoBLT, CANCELBR[BLTReX], c1; { Remap Subroutine } BLTRemap: MAR ← [rhS, S + 0], L0 ← L0.RedoBLT, c1; BLTReX: TOS ← TOS - 1, CarryBr, c2; TT ← MD{addr}, BRANCH[BLTdone1, $], c3; MAR ← [rhS, S - 1], c1; TT ← TT + TOS, CarryBr, CANCELBR[$, 2], c2; rhTT ← MD{addrH}, BRANCH[BLT64NoCross, BLT64Cross], c3; BLT64Cross: Q ← rhTT + 1, LOOPHOLE[byteTiming], c1; rhTT ← Q LRot0, c2; GOTO[BLT64NoCross], c3; BLT64NoCross: Map ← [rhTT,TT], L2Disp, c1; TOS ← TOS + 1, BRANCH[BLTSrc, BLTDst, 1], c2;{restore count} {****************************************************} BLTdone1: c1; BLTdone: TOSH ← smallpl, CANCELBR[$, 2], c2; TOS ← 0, c3; PC ← PC + PC16, MesaIntRq, c1; S ← S - 4, IBDisp, L2 ← L2.0, GOTO[DISPNIonly], c2; BLTufn: Rx ← 304'b, GOTO[ufn2], c1; BLT: uSaveTOS ← 0, L2 ← 1, c1, opcode[304'b]; Ybus ← TOSH xor smallpl, ZeroBr, L1 ← L1.NoFixes, c2; rhTOS ← 0, BRANCH[BLTufn, BLTRemap], c3; { E N D }