mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-04-19 17:32:52 +00:00
39 lines
9.8 KiB
Plaintext
39 lines
9.8 KiB
Plaintext
head 1.1;
|
||
branch 1.1.1;
|
||
access ;
|
||
symbols start:1.1.1.1 Xerox:1.1.1;
|
||
locks ; strict;
|
||
comment @# @;
|
||
|
||
|
||
1.1
|
||
date 2001.08.12.22.22.18; author freier; state Exp;
|
||
branches 1.1.1.1;
|
||
next ;
|
||
|
||
1.1.1.1
|
||
date 2001.08.12.22.22.18; author freier; state Exp;
|
||
branches ;
|
||
next ;
|
||
|
||
|
||
desc
|
||
@@
|
||
|
||
|
||
|
||
1.1
|
||
log
|
||
@Initial revision
|
||
@
|
||
text
|
||
@{
|
||
File name BandBLTBBLoops.mc
|
||
Description: Bit Transfer inner loops for BandBLT op-code
|
||
Author: CrF CRF
|
||
Created: May 28, 1982 1:36 PM
|
||
LOG
|
||
1-Sep-84 19:11:30 DEG added copyright notice.
|
||
July 6, 1982 3:07 PM CRF Created file (adapted from BBLoops.mc of 18-Jun-81 8:48:19).
|
||
}
|
||
|
||
{ Copyright (C) 1982 by Xerox Corporation. All rights reserved.}
|
||
|
||
|
||
{*****************************************************************************
|
||
Transfer character scan line -- transfer first (perhaps partial) word
|
||
*****************************************************************************}
|
||
{Click1 -- Read source}
|
||
{TransferCharScan:}
|
||
MAR ¬ [rhSrcA,SrcA + 0] ,c1, at[gr.notgray,grM,chooseLoop];
|
||
scDisp ,c2;
|
||
Src ¬ MD, scDisp, sc2DISP[Rotate1sc2] ,c3;
|
||
|
||
{Click2 -- Mask and rotate source}
|
||
Rotate1sc2: Src ¬ Src LRot0, scDisp, sc1DISP[Rotate1sc1] ,c1, at[3,10,Rotate1sc2];
|
||
Src ¬ Src LRot4, scDisp, sc1DISP[Rotate1sc1] ,c1, at[7,10,Rotate1sc2];
|
||
Src ¬ Src LRot8, scDisp, sc1DISP[Rotate1sc1] ,c1, at[0B,10,Rotate1sc2];
|
||
Src ¬ Src LRot12, scDisp, sc1DISP[Rotate1sc1] ,c1, at[0F,10,Rotate1sc2];
|
||
Rotate1sc1: Src ¬ RRot1 Src, sc3DISP[MaskRotate1sc3] ,c2, at[0E,10,Rotate1sc1];
|
||
Src ¬ Src, sc3DISP[MaskRotate1sc3] ,c2, at[0F,10,Rotate1sc1];
|
||
MaskRotate1sc3: Hold ¬ RRot1 (Src and Q), GOTO[ReadDest1] ,c3, at[0D,10,MaskRotate1sc3];
|
||
Hold ¬ LRot1 (Src and Q), GOTO[ReadDest1] ,c3, at[0F,10,MaskRotate1sc3];
|
||
|
||
{Click3 -- Read destination, decrement word count, check for single-word case}
|
||
ReadDest1: DstA ¬ MAR ¬ [rhDstA,DstA + 0] ,c1;
|
||
Lcount ¬ Lcount - 1, NegBr ,c2;
|
||
Dst ¬ MD, scDisp, BRANCH[ChLoop,SingleWordExit1] ,c3;
|
||
|
||
|
||
{*****************************************************************************
|
||
Transfer character scan line -- transfer full words (INNER LOOP)
|
||
[Note that (S1 or Q) xor (~S2 and Q) = (S1 and ~Q) or (S2 and Q). Using
|
||
the xor form is more convenient, because it avoids having to invert Q.]
|
||
*****************************************************************************}
|
||
{Click1 -- Mask and rotate previous source and read next source}
|
||
ChLoop: SrcA ¬ MAR ¬ [rhSrcA,SrcA +1], sc3DISP[MaskRotate2sc3] ,c1;
|
||
MaskRotate2sc3: Save ¬ RRot1 (Src or Q), BRANCH[ReadSrc, SrcPgCross, 1] ,c2, at[0D,10,MaskRotate2sc3];
|
||
Save ¬ LRot1 (Src or Q), BRANCH[ReadSrc, SrcPgCross, 1] ,c2, at[0F,10,MaskRotate2sc3];
|
||
ReadSrc: Src ¬ MD ,c3;
|
||
|
||
{Click2 -- Write destination word from last time through}
|
||
MAR ¬ [rhDstA,DstA + 0], scDisp ,c1;
|
||
MDR ¬ Hold or Dst, scDisp, sc1DISP[Rotate2sc1], Write OK ,c2;
|
||
Rotate2sc1: Src ¬ RRot1 (Src), sc2DISP[Rotate2sc2] ,c3, at[0E,10,Rotate2sc1];
|
||
Src ¬ (Src), sc2DISP[Rotate2sc2] ,c3, at[0F,10,Rotate2sc1];
|
||
|
||
{Click3 -- Rotate/mask source read in this iteration, decrement counter, check for done}
|
||
Rotate2sc2: Src ¬ Src LRot0, scDisp, GOTO[CheckCount] ,c1, at[3,10,Rotate2sc2];
|
||
Src ¬ Src LRot4, scDisp, GOTO[CheckCount] ,c1, at[7,10,Rotate2sc2];
|
||
Src ¬ Src LRot8, scDisp, GOTO[CheckCount] ,c1, at[0B,10,Rotate2sc2];
|
||
Src ¬ Src LRot12, scDisp, GOTO[CheckCount] ,c1, at[0F,10,Rotate2sc2];
|
||
CheckCount: Lcount ¬ Lcount - 1, NegBr, sc3DISP[MaskRotate2sc3a] ,c2;
|
||
MaskRotate2sc3a: Hold ¬ RRot1 (~Src and Q), BRANCH[ReadDest2, ChDone] ,c3, at[0D,10,MaskRotate2sc3a];
|
||
Hold ¬ LRot1 (~Src and Q), BRANCH[ReadDest2, ChDone] ,c3, at[0F,10,MaskRotate2sc3a];
|
||
|
||
{Click4 -- Finish masking source and read destination; quit on page cross}
|
||
ReadDest2: DstA ¬ MAR ¬ [rhDstA,DstA + 1] ,c1;
|
||
Hold ¬ Hold xor Save, BRANCH[$,DstPageCross1,1] ,c2;
|
||
Dst ¬ MD, scDisp, GOTO[ChLoop] ,c3;
|
||
|
||
|
||
{*****************************************************************************
|
||
Transfer character scan line -- transfer last word
|
||
-- regular termination (last partial word) comes through ChDone,
|
||
-- single-word case termination comes through SingleWordExit1.
|
||
*****************************************************************************}
|
||
{Click1 -- Finish masking source and read last destination; quit on page cross}
|
||
ChDone: DstA ¬ MAR ¬ [rhDstA,DstA + 1] ,c1;
|
||
Hold ¬ Hold xor Save, BRANCH[$, DstPageCross2, 1] ,c2;
|
||
Dst ¬ MD ,c3;
|
||
|
||
{Click2 -- Get last word mask and take common exit}
|
||
SingleWordExit1: Src ¬ Hold, dfDisp, CANCELBR[$,Sub[dfM,1] ] ,c1;
|
||
Mask2 ¬ Umask2, dfDISP[DstFunc] ,c2;
|
||
|
||
|
||
{*****************************************************************************
|
||
Transfer inked scan line -- transfer first (perhaps partial) word
|
||
*****************************************************************************}
|
||
{Click1 -- Read source and apply source function}
|
||
{TransferInkedScan:}
|
||
MAR ¬ [rhSrcA,SrcA + 0], sfDisp ,c1, at[gr.gray,grM,chooseLoop];
|
||
Q ¬ ~Mask1, sfDISP[InkSrcFunc] ,c2;
|
||
Src ¬ MD, GOTO[ReadDest3] ,c3, at[sf.true,sfM,InkSrcFunc];
|
||
Src ¬ ~MD, GOTO[ReadDest3] ,c3, at[sf.comp,sfM,InkSrcFunc];
|
||
|
||
{Click2 -- Read destination, decrement word count, check for single-word case}
|
||
ReadDest3: MAR ¬ [rhDstA,DstA + 0] ,c1;
|
||
Lcount ¬ Lcount - 1, NegBr ,c2;
|
||
Dst ¬ MD, dfDisp, BRANCH[$,SingleWordExit2] ,c3;
|
||
|
||
{Click3 -- Mask destination and dispatch on destination function}
|
||
Hold ¬ Dst and Q{~Mask1}, dfDISP[InkDstFunc1] ,c1;
|
||
Q ¬ Src and Mask1 ,c2, at[df.null,dfM,InkDstFunc1];
|
||
Noop ,c3;
|
||
|
||
{Click4 -- One click inner loop case: write first word and enter loop}
|
||
MAR ¬ [rhDstA,DstA + 0] ,c1;
|
||
MDR ¬ Hold or Q, GOTO[OneClickEntry] ,c2;
|
||
|
||
{Click3 alternate -- destination functions other than null}
|
||
Q ¬ Src and Dst, GOTO[TwoClickCase] ,c2, at[df.and,dfM,InkDstFunc1];
|
||
Q ¬ Src or Dst, GOTO[TwoClickCase] ,c2, at[df.or,dfM,InkDstFunc1];
|
||
Q ¬ Src xor Dst, GOTO[TwoClickCase] ,c2, at[df.xor,dfM,InkDstFunc1];
|
||
TwoClickCase: Q ¬ Q and Mask1 ,c3;
|
||
|
||
{Click4 alternate -- Two click inner loop case: write first word and enter loop}
|
||
MAR ¬ [rhDstA,DstA + 0] ,c1;
|
||
MDR ¬ Hold or Q, GOTO[TwoClickEntry] ,c2;
|
||
|
||
{*****************************************************************************
|
||
Transfer inked scan line -- transfer full words (INNER LOOP #1)
|
||
This is the one click inner loop for the null destination function case.
|
||
We don't have to read the destination word in this case.
|
||
*****************************************************************************}
|
||
{Click1 -- Store destination}
|
||
OneClickLoop: DstA ¬ MAR ¬ [rhDstA,DstA + 1], BRANCH[$,OneClickExit] ,c1;
|
||
MDR ¬ Src, BRANCH[OneClickEntry,DstPageCross3,1] ,c2;
|
||
OneClickEntry: Lcount ¬ Lcount - 1, NegBr, GOTO[OneClickLoop] ,c3;
|
||
|
||
{*****************************************************************************
|
||
Transfer inked scan line -- transfer full words (INNER LOOP #2)
|
||
This is the two click inner loop for the non-null destination function case.
|
||
We have to read the destination word in this case.
|
||
*****************************************************************************}
|
||
{Click1 -- Store destination}
|
||
TwoClickLoop: MAR ¬ [rhDstA,DstA + 0], dfDISP[InkDstFunc2] ,c1;
|
||
MDR ¬ Src and Dst, GOTO[TwoClickEntry] ,c2, at[df.and,dfM,InkDstFunc2];
|
||
MDR ¬ Src or Dst, GOTO[TwoClickEntry] ,c2, at[df.or,dfM,InkDstFunc2];
|
||
MDR ¬ Src xor Dst, GOTO[TwoClickEntry] ,c2, at[df.xor,dfM,InkDstFunc2];
|
||
TwoClickEntry: Noop, GOTO[$] ,c3;
|
||
|
||
{Click2 -- Read destination}
|
||
MAR ¬ DstA ¬ [rhDstA,DstA + 1] ,c1;
|
||
Lcount ¬ Lcount - 1, NegBr, BRANCH[$,DstPageCross4,1] ,c2;
|
||
Dst ¬ MD, dfDisp, BRANCH[TwoClickLoop,TwoClickExit] ,c3;
|
||
|
||
{*****************************************************************************
|
||
Transfer inked scan line -- transfer last word
|
||
-- OneClickLoop termination (last partial word) comes through OneClickExit
|
||
-- TwoClickLoop termination (last partial word) comes through TwoClickExit
|
||
-- single-word case termination comes through SingleWordExit2.
|
||
*****************************************************************************}
|
||
OneClickExit: Mask2 ¬ Umask2, BRANCH[$,DstPageCross5,1] ,c2;
|
||
Dst ¬ MD, GOTO[MaskBoth] ,c3;
|
||
|
||
{Single-word case: combine starting and ending masks; take common exit}
|
||
SingleWordExit2:
|
||
Mask2 ¬ Umask2, dfDisp, CANCELBR[$,0F] ,c1;
|
||
Mask2 ¬ Mask1 and Mask2, dfDISP[DstFunc] ,c2;
|
||
|
||
TwoClickExit: Mask2 ¬ Umask2, dfDisp, CANCELBR[$,0F] ,c1;
|
||
dfDISP[DstFunc] ,c2;
|
||
|
||
{*****************************************************************************
|
||
Common Exit for both characters and inked objects that are not clipped.
|
||
(See below for clipped object exit.)
|
||
*****************************************************************************}
|
||
Src ¬ Src, GOTO[MaskBoth] ,c3, at[df.null,dfM,DstFunc];
|
||
Src ¬ Src and Dst, GOTO[MaskBoth] ,c3, at[df.and,dfM,DstFunc];
|
||
Src ¬ Src or Dst, GOTO[MaskBoth] ,c3, at[df.or,dfM,DstFunc];
|
||
Src ¬ Src xor Dst, GOTO[MaskBoth] ,c3, at[df.xor,dfM,DstFunc];
|
||
|
||
MaskBoth: Src ¬ Src and Mask2 ,c1;
|
||
Dst ¬ Dst and ~Mask2 ,c2;
|
||
Noop ,c3;
|
||
|
||
{Store the last destination and exit}
|
||
MAR ¬ [rhDstA,DstA + 0] ,c1;
|
||
MDR ¬ Src or Dst, GOTO[ItemRefill3] ,c2;
|
||
|
||
{*****************************************************************************
|
||
Source page cross handling.
|
||
*****************************************************************************}
|
||
SrcPgCross: rhRet ¬ SRcRet, CALL[SrcLRemap] {PageCross} ,c3;
|
||
|
||
{rtn here} MAR ¬ [rhSrcA,SrcA + 0] ,c1, at[SRcRet,10,SrcRemapReturn];
|
||
GOTO[ReadSrc] ,c2;
|
||
|
||
{*****************************************************************************
|
||
Destination page cross handling.
|
||
Because scan lines are at most one page long (4096 bits or 13.65" @@ 300
|
||
bits per inch), any character that extends past the end of the destination
|
||
page is clipped. Thus we simply quit on any destination page cross.
|
||
*****************************************************************************}
|
||
DstPageCross1: GOTO[CommonExit] ,c3;
|
||
DstPageCross2: GOTO[CommonExit] ,c3;
|
||
DstPageCross3: GOTO[CommonExit] ,c3;
|
||
DstPageCross4: CANCELBR[CommonExit] ,c3;
|
||
DstPageCross5: GOTO[CommonExit] ,c3;
|
||
|
||
CommonExit: Noop ,c1;
|
||
GOTO[ItemRefill3] ,c2;
|
||
|
||
{END}
|
||
|
||
@
|
||
|
||
|
||
1.1.1.1
|
||
log
|
||
@first add
|
||
@
|
||
text
|
||
@@
|