{File name dbNewBLT.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: uSaveTT ← 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}anotherBLTnoint3, BLTnoint3], c3; {%M BLT ints disabled here}
anotherBLTnoint3: GOTO[BLTnoint1], c1;
BLTIntNow:
ClrIntErr, Rx ← 1, c1, at[EmuInt];
uWDC ← Rx, c2;
Rx ← KbdFXP, L2 ← 0, GOTO[PUNT], c3;
BLTnoint1: CANCELBR[$], c2;
BLTnoint2: CANCELBR[BLTRemap], c3;
BLTSrc: {BLTRemap returns here}
Rx ← rhRx ← MD, ReadXRefBr, c3;
Q ← rhRx, ReadBRANCH[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}
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, XwdDisp{XDirtyDisp}, c3;
Q ← rhRx, DISP2[BLTDMap], c1,at[L0.RedoBLT,10,WMapFixCaller];
rhTOS ← Q LRot0, c2, at[PgDirty, 4, BLTDMap];{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, at[PgClean, 4, BLTDMap];
CALL[WLMapFix], c2, at[PgProt, 4, BLTDMap];
CALL[WLMapFix], c2, at[PgVacant, 4, BLTDMap];
{****************************************************}
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}, L2Disp, BRANCH[BLTdone1, $], c3;
MAR ← [rhS, S - 1], BRANCH[$, BLTsavedest, 1], c1;
TT ← TT + TOS, CarryBr, CANCELBR[$, 2], c2;
rhTT ← MD{addrH}, BRANCH[BLT64NoCross, BLT64Cross], c3;
BLTsavedest:
uTOS ← TT, CANCELBR[$, 2], c2;
Q ← rhTT ← MD, c3;
uTOSH ← Q, c1;
TT ← TT + TOS, CarryBr, c2;
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:
CANCELBR[$, 3], c1;
TOSH ← uTOSH, GOTO[BLTdone2], c2;
BLTdone:
TOSH ← uTOSH, CANCELBR[$, 2], c2;
BLTdone2:
TOS ← uTOS, 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 }