mirror of
https://github.com/livingcomputermuseum/Darkstar.git
synced 2026-02-28 09:37:43 +00:00
39 lines
22 KiB
Plaintext
39 lines
22 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.28; author freier; state Exp;
|
|
branches 1.1.1.1;
|
|
next ;
|
|
|
|
1.1.1.1
|
|
date 2001.08.12.22.22.28; author freier; state Exp;
|
|
branches ;
|
|
next ;
|
|
|
|
|
|
desc
|
|
@@
|
|
|
|
|
|
|
|
1.1
|
|
log
|
|
@Initial revision
|
|
@
|
|
text
|
|
@{
|
|
File name TextBlt.mc
|
|
Description: Mesa TextBlt op-code
|
|
Last edited by JAC 23-Sep-87 15:31:31 get notInFont exit correct....
|
|
Last edited by JAC 21-Aug-87 10:51:26 get notInFont exit in correct cycle
|
|
Last edited by JGS 7-Jan-85 17:33:08: New font format, long resolve buffer.
|
|
Last edited by DEG 1-Sep-84 19:52:38: Add copyright notice.
|
|
Last edited by AXD 14-Nov-83 15:43:44: undo previous change.
|
|
Last edited by AXD 16-Aug-83 14:03:25: RRot1 uPMask2 due to new PSB format.
|
|
Last edited by Jim JXF February 12, 1982 12:39 PM: Nothing on the Xbus when calling CycleMask; Set L2 ¬ sd.spec for call to SrcMapSpec.
|
|
Last edited by Jim JXF February 10, 1982 2:31 AM: fix exit bug.
|
|
Last edited by Jim JXF January 7, 1982 1:02 PM: Change to new FontBits format.
|
|
Last edited by JGS October 5, 1981 3:51 PM: Added JXF 's fixes.
|
|
Last edited by JGS 8-Sep-81 7:49:04: New Instruction Set.
|
|
Last edited by Jim JXF August 20, 1981 2:20 PM: Margin is a CARDINAL; Update MicaPos after call to BitBlt in case of page fault.
|
|
Last edited by Jim August 20, 1981 2:20 PM: Fix for new assembler.
|
|
Last edited by Jim JXF : July 21, 1981 10:50 AM: Test for Resolve before testing for Stop char.
|
|
Last edited by Jim JXF : July 7, 1981 11:06 AM: General rewrite to make it small and wonderful.
|
|
Last edited by Jim JXF : March 17, 1981 4:09 PM: Fix label bug: change tbFunction to tbFunction. Put one on XBus when calling CycleMask. Return with uStack6 in TOS.
|
|
Last edited by Jim JXF : March 16, 1981 2:14 PM: Bug fix: save MicaWidth instead of MicaPos at TestMargin. Change to call TextBltToBitBltEntry instead of LSEPNormEntry.
|
|
Last edited by Jim JXF : March 15, 1981 5:35 PM: Move definitions from Dandelion into TextBlt.
|
|
Last edited by Jim JXF : February 17, 1981 2:55 PM: Change to check for margin before function.
|
|
Last edited by Jim JXF : February 11, 1981 11:04 AM: use symbol to call SavebbRegs.
|
|
Author: Jim JXF
|
|
Created: December, 1980
|
|
}
|
|
|
|
{ Copyright (C) 1980, 1981, 1982, 1983, 1984, 1985 by Xerox Corporation. All rights reserved.}
|
|
|
|
{REGISTER USAGE:
|
|
|
|
|
|
Number Name
|
|
|
|
0 VS holds the Virtual Address when calling SrcMapSpec in BitBlt.
|
|
TOS used by CycleMask to return cycled result.
|
|
1 T temporary used by CycleMask.
|
|
VD temporary used by DstVAMod subroutine
|
|
2 TT temporary
|
|
Used to hold Index parameter
|
|
3 L temporary
|
|
Used to hold Last parameter.
|
|
TempBpl used to hold BitPos when calling DstVAMod subroutine
|
|
4 G temporary
|
|
SrcA Used by SrcMapSpec to return real address
|
|
5 PC Used by ExtractByte to return value
|
|
6 TempB temporary used by DstVAMod subroutine
|
|
Rx used to hold character MicaPos
|
|
}
|
|
|
|
{SUBROUTINES }
|
|
{*****************************************************************************
|
|
Subroutine FetchVS
|
|
Fetch word pointed to by Virtual Address in VS and rhVS, offset by T.
|
|
Timing: 5 clicks
|
|
Called from cycle 3, returns to cycle 1
|
|
Returns thru L0
|
|
|
|
Input:
|
|
VS (TOS) virtual address
|
|
rhVS (rhMDS) virtual address (high order)
|
|
T offset of virtual address
|
|
|
|
Output:
|
|
T word pointed to by Virtual Address
|
|
SrcA (G) real address page and word
|
|
rhSrcA (rhG) real address rh
|
|
USrcValoSav
|
|
used to save VS
|
|
Q real page and word
|
|
rhRet tbMap (used to call SrcMapSpec)
|
|
|
|
Side Effects:
|
|
UDstBit ¬ 0;
|
|
UHeight ¬ UtbHeight, TOS ¬ UtbHeight
|
|
*****************************************************************************}
|
|
|
|
|
|
MacroDef[FetchVSRet,at[#1,10,FetchVSRtn]];
|
|
|
|
{Return values for FetchVS and ExtractByte Subroutines}
|
|
{0 = restore.int is reserved for use at tbFaultOrInt}
|
|
Set[FetchFlags, 1], {fetch RgFlags}
|
|
{2 = restore.pf is reserved for use at tbFaultOrInt}
|
|
Set[FetchPrinterWidth, 3], {fetch PrinterWidth}
|
|
Set[StoreCoord,4], {get address of Coord[Index]}
|
|
Set[FetchWidth, 5], {fetch width of character}
|
|
Set[FetchChar, 6], {fetch next character}
|
|
Set[FetchInfo, 7], {fetch raster info}
|
|
Set[FetchEntry, 8], {fetch raster info}
|
|
|
|
FetchVS:
|
|
VS ¬ VS + T, CarryBr, L2 ¬ sd.spec {in case of fault in SrcMapSpec}, c1;
|
|
tbFetch: UDstBit ¬ 0, BRANCH[$, tbCarry], c2;
|
|
rhRet ¬ Fetch, CALL[SrcMapSpec], c3;
|
|
|
|
{SrcMapSpec subroutine here for 2 Clicks, c1-c3;}
|
|
{On return, SrcA and rhSrcA contain real address.}
|
|
|
|
SrcMapSpecRet[Fetch]
|
|
MAR ¬ [rhSrcA, SrcA + 0], c1;
|
|
TOS ¬ UtbHeight, L0Disp, c2;
|
|
T ¬ MD, UHeight ¬ TOS, RET[FetchVSRtn], c3;
|
|
|
|
tbCarry: Q ¬ rhVS + 1 {Increment rh portion of VA}, LOOPHOLE[byteTiming], c3;
|
|
rhVS ¬ Q LRot0, GOTO[tbFetch], c1;
|
|
|
|
{*****************************************************************************
|
|
Subroutine ExtractByte
|
|
Extract byte from T depending on Index:
|
|
Index even => extract left byte
|
|
index odd => extract right byte
|
|
Timing: 2 cycles
|
|
Calling Sequence:
|
|
...L0 ¬ ,...
|
|
[] ¬ UtbIndex, XDisp, CALL[ExtractByte], c*;
|
|
Returns thru L0
|
|
|
|
Input:
|
|
T word contains 2 bytes
|
|
|
|
Output:
|
|
PC word contains left byte or right byte
|
|
*****************************************************************************}
|
|
|
|
MacroDef[ExtractByteRet,at[#1,8,ExtractByteRet]];
|
|
ExtractByte:
|
|
TT ¬ T LRot8, L0Disp, BRANCH[tbEvenChar, tbOddChar,0E], c*;
|
|
|
|
tbOddChar:
|
|
PC ¬ T and 0FF, DISP3[ExtractByteRet], c*;
|
|
tbEvenChar:
|
|
PC ¬ TT and 0FF, DISP3[ExtractByteRet], c*;
|
|
|
|
{*****************************************************************************
|
|
Subroutine GgetsBitPos
|
|
Disp is pending for return
|
|
*****************************************************************************}
|
|
|
|
Set[Kern,1];
|
|
Set[Update,0];
|
|
MacroDef[GgetsBitPosRet,at[#1,4,GgetsBitPosRet]];
|
|
GgetsBitPos:
|
|
G ¬ UtbBitPos, DISP2[GgetsBitPosRet], c*;
|
|
|
|
{*****************************************************************************
|
|
Subroutine TTgetsSTK
|
|
Pop stack into TT and set rhType for TextBlt
|
|
Disp on Stack pointer is pending for return
|
|
*****************************************************************************}
|
|
|
|
MacroDef[TTgetsSTKRet,at[#1,10,TTgetsSTKRet]];
|
|
TTgetsSTK:
|
|
SavebbRegsRet[Savebb.TXTBLT]
|
|
TT ¬ STK, pop, RET[TTgetsSTKRet], c*;
|
|
|
|
{*****************************************************************************
|
|
Begin TextBlt.
|
|
Come here from ESC on a Misc 15 opcode.
|
|
PC points to the byte code because BitBlt counts on this in case of a page fault.
|
|
Save R and RH registers. Move the parameters passed in the stack to other U registers.
|
|
If we need to call BitBlt, BitBlt will need to use the stack.
|
|
Input:
|
|
stackP = 5
|
|
uStack6 = ArgPtr => UtbArgPtr
|
|
uStack5 = Count => UtbCount
|
|
uStack4 = MicaPos => UtbMicaPos
|
|
uStack3 = BitPos => UtbBitPos
|
|
uStack2 = Index => UtbIndex
|
|
*****************************************************************************}
|
|
|
|
TextBlt:
|
|
at[0C,10,ESC2n]
|
|
ULsave ¬ L, L2 ¬ Savebb.TXTBLT, c1;
|
|
T ¬ uStack6 {ArgPtr}, CALL[SavebbRegs], c2;
|
|
|
|
{SavebbRegs subroutine here for 2 2/3 Clicks, c3-c1;}
|
|
{Return to TTgetsSTK}
|
|
|
|
{TT ¬ STK {Count}, pop {MicaPos: stackP ¬ 4}, c2;}
|
|
TTgetsSTKRet[0]
|
|
UtbCount ¬ TT {Count}, Xbus ¬ ErrnIBnStkp, XDisp, CALL[TTgetsSTK], c3;
|
|
|
|
{TT ¬ STK {MicaPos}, pop {BitPos stackP ¬ 3}, c1;}
|
|
TTgetsSTKRet[0B] {1011 is one's complement of stackP = 4}
|
|
UtbMicaPos ¬ TT {MicaPos}, {next line}
|
|
Xbus ¬ ErrnIBnStkp, XDisp, CALL[TTgetsSTK], c2;
|
|
{TT ¬ STK {BitPos}, pop {Index: stackP ¬ 2}, c3;}
|
|
TTgetsSTKRet[0C] {1100 is one's complement of stackP = 3}
|
|
|
|
UtbBitPos ¬ TT {BitPos}, {next line}
|
|
Xbus ¬ ErrnIBnStkp, XDisp, CALL[TTgetsSTK], c1;
|
|
{TT ¬ STK {Index}, pop {next: stackP ¬ 1}, c2;}
|
|
TTgetsSTKRet[0D] {1101 is one's complement of stackP = 2}
|
|
{Set L2 for SrcMapSpec subroutine in case of a page fault.}
|
|
UtbIndex ¬ TT {Index}, L2 ¬ sd.spec, c3;
|
|
|
|
{*****************************************************************************
|
|
Move TextBlt arguments pointed to by ArgPtr to U registers. The following loop loads U registers as follows:
|
|
60 junk
|
|
61 not touched
|
|
62 saved and restored
|
|
63 UtbFunction: arg word 0 = function
|
|
64 UtbLast: arg word 1 = Last
|
|
65 UtbTextLo: arg word 2 = TextLo
|
|
66 UtbTextHi: arg word 3 = TextHi
|
|
67 UtbFontLo: arg word 4 = FontLo
|
|
68 UtbFontHi: arg word 5 = FontHi
|
|
69 UtbDstLow: arg word 6 = DestLow
|
|
6A UtbDstHigh: arg word 7 = DestHigh
|
|
6B UtbDstBpl: arg word 8 = DestBpl
|
|
6C UtbMargin: arg word 9 = Margin
|
|
6D UtbSpace: arg word A = Space
|
|
6E UtbCoordLo: arg word B = CoordLo
|
|
6F UtbCoordHigh: arg word B = CoordHigh
|
|
In case of a page fault, we must be able to restore the stack and the registers.
|
|
Set rhType to return to us in case of a page fault or interrupt.
|
|
rhVS = MDS, so we don't need to load it.
|
|
*****************************************************************************}
|
|
|
|
VS ¬ UtbArgPtr ¬ T {ArgPtr}, c1;
|
|
rhType ¬ Type.TextBlt, c2;
|
|
rhRet ¬ MapArg, CALL[SrcMapSpec], c3;
|
|
|
|
{SrcMapSpec subroutine here for 2 Clicks, c1-c3;}
|
|
{On return, SrcA (G) and rhSrcA contain real address of TextBltArg.}
|
|
|
|
SrcMapSpecRet[MapArg]
|
|
L ¬ UtbFlags , c1;
|
|
UFlags ¬ L {UtbFlags -- Set up for BitBlt}, c2;
|
|
Rx ¬ uPMask2 {save u62, which will be wiped out}, c3;
|
|
|
|
tbFetchArgLoop:
|
|
MAR ¬ [rhSrcA,SrcA ], SrcA ¬ SrcA + 1, NibCarryBr, c1;
|
|
Ybus ¬ SrcA+1, AltUaddr, BRANCH[$, tbFetchFontRecord, 2], c2;
|
|
tbParmBlock ¬ Rx, Rx ¬ MD, GOTO[tbFetchArgLoop], c3;
|
|
|
|
{*****************************************************************************
|
|
Fetch FontRecord data pointed to by FontLo,,FontHi into U registers.
|
|
NOTE: for this to work, FontRecord must be hex aligned.
|
|
The following loop loads U registers as follows:
|
|
50 UtbHeight: FontRecord word 10 = Height
|
|
51 UtbRasterLo: FontRecord word 0 = RasterLo
|
|
52 UtbRasterHi: FontRecord word 1 = RasterLHi
|
|
53 UtbSpacingWidthLo: FontRecord word 2 = SpacingWidthLo
|
|
54 UtbSpacingWidthHi: FontRecord word 3 = SpacingWidthHi
|
|
55 UtbPrinterWidthLo: FontRecord word 4 = PrinterWidthLo
|
|
56 UtbPrinterWidthHi: FontRecord word 5 = PrinterWidthHi
|
|
57 UtbFlagsLo: FontRecord word 6 = FlagsLo
|
|
58 UtbFlagsHi: FontRecord word 7 = FlagsHi
|
|
59 UtbRasterInfoLo: FontRecord word 8 = RasterInfoLo
|
|
5A UtbRasterInfoHi: FontRecord word 9 = RasterInfoHi
|
|
5B not touched
|
|
5C not touched
|
|
5D not touched
|
|
5E not touched
|
|
5F not touched
|
|
*****************************************************************************}
|
|
|
|
tbFetchFontRecord:
|
|
rhRet ¬ MapFont {NOTE: this instruction follows AltUaddr, so beware of
|
|
any instruction with a U address here!}, c3;
|
|
|
|
VS ¬ UtbFontLo, c1;
|
|
rhVS ¬ UtbFontHi, c2;
|
|
CALL[SrcMapSpec], c3;
|
|
|
|
{SrcMapSpec subroutine here for 2 Clicks, c1-c3;}
|
|
{On return SrcA and rhSrcA point to FontRecord.}
|
|
|
|
SrcMapSpecRet[MapFont]
|
|
tbFetchFontDataLoop:
|
|
MAR ¬ [rhSrcA,SrcA+0], c1;
|
|
Ybus ¬ SrcA, SrcA ¬ SrcA+1, YDisp, AltUaddr, c2;
|
|
UtbFontData ¬ PC, PC ¬ MD, {next line}
|
|
BRANCH[tbFetchFontDataLoop,$,7], c3;
|
|
|
|
{We have just stored UtbFlagsHi, and PC = RasterInfoLo}
|
|
|
|
MAR ¬ [rhSrcA,SrcA+0], c1;
|
|
Rx ¬ UtbDstBpl, c2;
|
|
UtbRasterInfoLo ¬ PC, PC ¬ MD, c3;
|
|
|
|
MAR ¬ [rhSrcA,SrcA+1], c1;
|
|
UDstBpl ¬ Rx {Prepare for BitBlt}, CANCELBR[$,0], c2;
|
|
UtbRasterInfoHi ¬ PC, PC ¬ MD, c3;
|
|
|
|
UtbHeight ¬ PC, GOTO[tbLoop], c1;
|
|
|
|
{*****************************************************************************
|
|
Begin TextBlt loop.
|
|
We come through here for each character.
|
|
Subtract Index of current character from index of Last character.
|
|
If carry, then I'm done.
|
|
*****************************************************************************}
|
|
|
|
tbLoop: L {Last} ¬ UtbLast, c2;
|
|
L ¬ L {Last} - TT {Index}, UtbIndex ¬ TT {Index}, CarryBr, c3;
|
|
|
|
Xbus ¬ UtbFunction {test for resolve}, XDisp, BRANCH[tbFinished,$], c1;
|
|
Q ¬ UtbCoordLo, BRANCH[tbFetchChar, tbResolve, 1], c2;
|
|
|
|
{*****************************************************************************
|
|
Come here if function is Resolve.
|
|
*****************************************************************************}
|
|
tbResolve:
|
|
rhVD ¬ UtbCoordHigh, c3;
|
|
|
|
VD ¬ Q + TT, CarryBr, c1;
|
|
L ¬ UtbBitPos, BRANCH[tbR, $], c2;
|
|
Q ¬ rhVD + 1, LOOPHOLE[byteTiming], c3;
|
|
|
|
rhVD ¬ Q LRot0, c1;
|
|
Noop, c2;
|
|
tbR: rhRet ¬ argMap, CALL[DstMapSpec], c3;
|
|
|
|
{DstMapSpec subroutine here for 2 Clicks, c1-c3;}
|
|
{On return, DstA and rhDstA contain real address.}
|
|
|
|
MAR ¬ [rhDstA, DstA + 0], c1, at[argMap,4,DstMapRet];
|
|
MDR ¬ L, c2;
|
|
tbFetchChar:
|
|
TT ¬ UtbIndex, c3;
|
|
|
|
{FetchText[Index]: word that contains next character.}
|
|
VS ¬ UtbTextLo, L0 ¬ FetchChar, c1;
|
|
rhVS ¬ UtbTextHi, c2;
|
|
T {offset} ¬ RShift1 TT {Index}, CALL[FetchVS], c3;
|
|
|
|
{FetchVS subroutine here for 5 clicks, c1-c3}
|
|
{On return, T contains word that contains next character.}
|
|
|
|
FetchVSRet[FetchChar]
|
|
Xbus ¬ UtbIndex, XDisp, CALL[ExtractByte], c1;
|
|
|
|
{ExtractByte subroutine here c2-c3}
|
|
{On return, PC contains next character}
|
|
|
|
ExtractByteRet[FetchChar]
|
|
Rx ¬ UtbMicaPos {Prepare for tbTestMargin}, c1;
|
|
|
|
tbFetchFlags: {Fetch RgFlags[char/8]. }
|
|
VS ¬ UtbFlagsLo, L0 ¬ FetchFlags, c2;
|
|
rhVS ¬ UtbFlagsHi, c3;
|
|
|
|
T ¬ LShift1 (PC {next char} and 0F8) {mask off low 3 bits}, c1;
|
|
T ¬ T LRot12 {Char/8}, c2;
|
|
{Prepare L for CycleMask below.}
|
|
L ¬ LShift1 (PC {next char} and 7), CALL[FetchVS], c3;
|
|
|
|
{FetchVS subroutine here for 5 clicks, c1-c3}
|
|
|
|
{*****************************************************************************
|
|
On return, T contains RgFlags[char/8]. Call CycleMask to right justify RgFlags.
|
|
We rotate RgFlags 2*(n+1), where n is the low 3 bits of Char. If n = 7, our Disp4 will cause a zero rotation.
|
|
Calling sequence to CycleMask:
|
|
T = data to be rotated (RgFlags)
|
|
TT = pre-rotated version of T
|
|
We must set INIA.11.
|
|
*****************************************************************************}
|
|
|
|
FetchVSRet[FetchFlags]
|
|
Ybus ¬ L {LShift1 (nextChar and 7)} + 2, YDisp, L2 ¬ maskRet.flags, c1;
|
|
TT ¬ LRot1 T {RgFlags}, DISP4[CycleMask], c2;
|
|
|
|
{CycleMask subroutine here for 1 click, c3-c2}
|
|
{On return, TOS contains RgFlags right justified. }
|
|
|
|
tbTestStop: {Dispatch on low order bit to test for Stop character.} at[maskRet.flags,10,MaskRet]
|
|
UtbRgFlags ¬ TOS, L0 ¬ FetchPrinterWidth, YDisp, c3;
|
|
|
|
L {Margin} ¬ UtbMargin, BRANCH[$,tbStopChar,0E], c1;
|
|
VS ¬ UtbPrinterWidthLo, c2;
|
|
rhVS ¬ UtbPrinterWidthHi, c3;
|
|
|
|
VS ¬ VS + PC, CarryBr, L2 ¬ sd.spec, CALL[tbFetch], c1;
|
|
{FetchVS subroutine here for 4-2/3 clicks, c2-c3}
|
|
{On return, T contains word that contains printer width of character. }
|
|
|
|
{
|
|
IF printerWidth = CARDINAL.LAST THEN GOTO NotInFont;
|
|
IF micaPos + printerWidth > ptr.margin THEN GOTO Margin;
|
|
}
|
|
|
|
FetchVSRet[FetchPrinterWidth]
|
|
Q ¬ 0-T-1, ZeroBr, c1;
|
|
Rx ¬ Rx - Q - 1 , BRANCH[$, tbNotInFont], c2;
|
|
[] ¬ L - Rx, CarryBr, c3;
|
|
|
|
tbTestMargin:
|
|
T ¬ RShift1 PC, BRANCH[tbMargin,$], c1;
|
|
VS ¬ UtbSpacingWidthLo, L0 ¬ FetchWidth, c2;
|
|
rhVS ¬ UtbSpacingWidthHi, CALL[FetchVS], c3;
|
|
|
|
{FetchVS subroutine here for 5 clicks, c2-c3}
|
|
{On return, T contains word that contains width of character. }
|
|
|
|
FetchVSRet[FetchWidth]
|
|
Ybus ¬ Q ¬ PC {nextChar}, YDisp, CALL[ExtractByte], c1;
|
|
{ExtractByte subroutine here, c2-c3}
|
|
{On return, PC contains width of Char, Q contains char}
|
|
|
|
ExtractByteRet[FetchWidth]
|
|
UtbWidth ¬ PC, c1;
|
|
UtbNewMicaPos ¬ Rx c2;
|
|
L {Src} ¬ UtbRasterLo, c3;
|
|
|
|
Xbus ¬ UtbFunction, T ¬ Q, XDisp, L0 ¬ FetchEntry, c1;
|
|
VS ¬ UtbRasterInfoLo, DISP2[tbFunction], c2;
|
|
|
|
{*****************************************************************************
|
|
Come here if function is Display.
|
|
L2 = OffsetPlus256
|
|
PC = UtbWidth = width of character
|
|
T = character.
|
|
|
|
Set up parameters for BitBlt:
|
|
L2 = sd.spec
|
|
UDstBpl contains dstBpl
|
|
UWidth contains width of Char
|
|
UFlags contains flags
|
|
USrcBpl contains srcBpl (width of character)
|
|
UHeight contains height (from FontRecord)
|
|
UDstValo contains low order of dest BitAddress
|
|
UDstBit contains bit portion of dest BitAddress
|
|
USrcValo contains low order of source BitAddress
|
|
USrcBit contains bit portion of source BitAddress (Zero)
|
|
UrhVS and rhVS contain high order of source BitAddress
|
|
UrhVD and rhVD contain high order of dest BitAddress
|
|
*****************************************************************************}
|
|
|
|
tbDisplay:
|
|
at[0,4,tbFunction]
|
|
rhVS ¬ UtbRasterInfoHi, CALL[FetchVS], c3;
|
|
|
|
{FetchVS subroutine here for 5 clicks, c1-c3}
|
|
|
|
{*****************************************************************************
|
|
On return, T contains RasterInfo[Char].
|
|
This contains the left and right kern bits and the offset of the character in the rasters.
|
|
*****************************************************************************}
|
|
FetchVSRet[FetchEntry]
|
|
{Calculate source address for BitBlt. Extract offset to FontTable from low 14 bits of first word of CharEntry.
|
|
Calculate address of entry for this Char in FontTable: FontChar + offset.}
|
|
|
|
Q ¬ UtbDstLo, c1;
|
|
UDstVALo ¬ Q, c2;
|
|
TT {offset} ¬ T {CharEntry} and u3FFF, {nextLine}, c3;
|
|
|
|
TOS {SrcHi} ¬ rhVS ¬ UtbRasterHi, c1;
|
|
L {Src} ¬ L {Src} + TT {offset}, CarryBr, c2;
|
|
tbTestFontCarry:
|
|
USrcVALo ¬ L {Src}, BRANCH[tbNoFontCarry, tbFontCarry], c3;
|
|
tbFontCarry:
|
|
TOS {SrcHi} ¬ TOS + 1, c1;
|
|
rhVS {SrcHi} ¬ TOS LRot0, GOTO[tbTestFontCarry], c2;
|
|
|
|
tbNoFontCarry:
|
|
UrhVS ¬ TOS {SrcHi}, TOS ¬ 0, c1;
|
|
USrcBit ¬ TOS {0}, TOS ¬ {8000} RShift1 TOS, SE ¬ 1, c2;
|
|
|
|
{Extract left kern and right kern bits.}
|
|
L {LKern} ¬ LRot1 T {Left kern in low order bit}, c3;
|
|
|
|
TOS {RKern} ¬ (L LRot1) and TOS {8000}, c1;
|
|
L {LKern} ¬ L {LKern} and 1 , c2;
|
|
|
|
{Calculate Width as Width + left kern + right kern.}
|
|
PC {Width} ¬ PC {Width} + L {LKern}, c3;
|
|
|
|
TOS {Width} ¬ PC {Width} + TOS {RKern}, L0 ¬ Kern, c1;
|
|
USrcBpl ¬ TOS {Width}, c2;
|
|
UWidth ¬ TOS {Width}, L0Disp, CALL[GgetsBitPos], c3;
|
|
|
|
{Calculate bitPos as bitPos - left kern.}
|
|
{G ¬ UtbBitPos, c1;}
|
|
GgetsBitPosRet[Kern]
|
|
L {BitPos} ¬ G {UtbBitPos} - L {LKern}, rhWho ¬ Dest, c2;
|
|
|
|
{*****************************************************************************
|
|
|
|
Calculate Dst address for BitBlt. Call DstVAMod to add BitPos to Dst address. Parameters must be set up as follows:
|
|
rhWho caller
|
|
TempBpl increment for the destination address (L)
|
|
UDstValo virtual destination page and word,
|
|
set from UtbDstLo by FetchVA
|
|
UDstBit virtual destination bit (set to 0)
|
|
UrhVD virtual destination rh
|
|
*****************************************************************************}
|
|
|
|
T ¬ UtbDstHi, rhVD ¬ UtbDstHi, c3;
|
|
|
|
tbCalculateDst:
|
|
UrhVD ¬ T, CALL[DstVAMod], c1;
|
|
|
|
{DstVAMod subroutine here for 4 clicks, c2 - c1}
|
|
{On return, uDstValo has been updated by the number of words in BitPos.
|
|
TempB and UDstBit contain BitPos.
|
|
We must mask off the high order bits of BitPos from UDstBit.}
|
|
|
|
DstVAModRet[Dest]
|
|
TempB {BitPos} ¬ TempB and 0F, L2 ¬ sd.spec, c2;
|
|
UDstBit ¬ TempB, CALL[TextBltToBitBltEntry], c3;
|
|
|
|
{BitBlt runs here for lots of clicks., c1 - c2}
|
|
|
|
{*****************************************************************************
|
|
Return here from BitBlt. L0 = restore.term.
|
|
Increment BitPos.
|
|
*****************************************************************************}
|
|
tbNextChar:
|
|
at[6,8,LSEPReturn]
|
|
T ¬ UtbWidth {width}, {0 disp}, CALL[GgetsBitPos], c3;
|
|
|
|
{G ¬ UtbBitPos GOTO[tbNextCharx], c1;}
|
|
|
|
{*****************************************************************************
|
|
Come here if function is Resolve.
|
|
*****************************************************************************}
|
|
at[2,4,tbFunction]
|
|
T ¬ UtbWidth {width}, {0 disp}, CALL[GgetsBitPos], c3;
|
|
|
|
{G ¬ UtbBitPos GOTO[tbNextCharx], c1;}
|
|
|
|
tbNextCharx:
|
|
GgetsBitPosRet[Update]
|
|
G {BitPos} ¬ G {BitPos} + T {Width}, {next line}
|
|
Xbus ¬ UtbRgFlags, XDisp, {Test for pad character (2 bit of RgFlags).} c2;
|
|
tbTestPad:
|
|
{Come here from tbCountPos or tbCountNotPos to delay 1 cycle.}
|
|
TT {Count} ¬ UtbCount, BRANCH[tbNoPad,tbPad,0D], c3;
|
|
|
|
tbPad:
|
|
T {Count} ¬ TT {Count} + 1, c1;
|
|
Xbus ¬ UtbFunction, XLDisp, {test low order bit: 1 if format} c2;
|
|
|
|
{Test for function = format. 0 => display, 1 => format, 2=> resolve.}
|
|
UtbCount ¬ T {Count}, TT ¬ TT {count-1}, NegBr, {next line}
|
|
BRANCH[$,tbNoPad], c3;
|
|
|
|
{Continue if function is not Format.
|
|
Increment BitPos by Space. If count <= 0, increment BitPos by one more.}
|
|
|
|
T ¬ UtbSpace, BRANCH[tbCountPos, tbCountNotPos], c1;
|
|
tbCountPos:
|
|
G {BitPos} ¬ G {BitPos} + T {Space}, GOTO[tbTestPad], c2;
|
|
tbCountNotPos:
|
|
G {BitPos} ¬ G {BitPos} + T {Space} + 1, GOTO[tbTestPad], c2;
|
|
|
|
tbNoPad:
|
|
TT {Index} ¬ UtbIndex, CANCELBR[$,1], c1;
|
|
UtbBitPos ¬ G {BitPos}, TT {Index} ¬ TT {Index} + 1, c2;
|
|
L ¬ UtbNewMicaPos, c3;
|
|
|
|
UtbMicaPos ¬ L, GOTO[tbLoop], c1;
|
|
|
|
{*****************************************************************************
|
|
Come here if function is Format.
|
|
*****************************************************************************}
|
|
tbFormat:
|
|
at[1,4,tbFunction]
|
|
T ¬ UtbWidth {width}, {0 disp}, CALL[GgetsBitPos], c3;
|
|
{G ¬ UtbBitPos, GOTO[tbNextCharx], c1;}
|
|
|
|
tbFinished:
|
|
TOS ¬ 0 {normal}, CANCELBR[tbDone,3], L0 ¬ restore.term, c2;
|
|
tbMargin:
|
|
TOS ¬ 1 {margin}, CANCELBR[tbDone,3], L0 ¬ restore.term, c2;
|
|
|
|
tbStopChar:
|
|
TOS ¬ 2 {stop}, L0 ¬ restore.term, GOTO[tbDone], c2;
|
|
|
|
tbNotInFont:
|
|
TOS ¬ 3 {notInFont}, L0 ¬ restore.term, GOTO[tbWait], c3;
|
|
|
|
{*****************************************************************************
|
|
Come here from BitBlt if we get a page fault (L0 = restore.pf) or a request for an interrupt (L0 = restore.int).
|
|
Restore the Stack so that it will be set up when our opcode gets executed again.
|
|
Then go to RestoreRandRHRegs subroutine, which will return to the appropriate place in BitBlt.
|
|
*****************************************************************************}
|
|
at[7,8,MoverhVToStkandRestore]
|
|
|
|
TOS ¬ UtbArgPtr, c2;
|
|
tbWait:
|
|
Noop, c*; {c1, c3}
|
|
tbFault:
|
|
Noop, c*; {c2, c1}
|
|
|
|
{*****************************************************************************
|
|
Subroutine RestoreStack
|
|
Timing: 3 2/3 cycles
|
|
Input:
|
|
T value to place in Stack6
|
|
Restore the Stack with TextBlt parameters. We do this at completion, to process an interrupt, or to process a page fault.
|
|
We then exit to RestoreRandRHRegs, which will return to the appropriate place in BitBlt.
|
|
On completion, we must come here on c3.
|
|
On interrupt or page fault, we must come here on c2.
|
|
*****************************************************************************}
|
|
{fin int}
|
|
tbDone:
|
|
uStack6 ¬ TOS, TT ¬ 0, c*; {c3 c2}
|
|
tbRestoreStack:
|
|
stackP ¬ TT {0}, T ¬ UtbIndex, c*; {c1 c3}
|
|
uStack2 ¬ T, c*; {c2 c1}
|
|
T ¬UtbBitPos, push {stackP ¬ 1}, c*; {c3 c2}
|
|
|
|
uStack3 ¬ T, push {stackP ¬ 2}, c*; {c1 c3}
|
|
T ¬ UtbMicaPos, push {stackP ¬ 3}, c*; {c2 c1}
|
|
uStack4 ¬ T, push {stackP ¬ 4}, c*; {c3 c2}
|
|
|
|
T ¬ UtbCount, push {stackP ¬ 5}, c*; {c1 c3}
|
|
uStack5 ¬ T, GOTO[RestoreRandRHRegs], c*; {c2 c1}
|
|
|
|
{RestoreRandRHRegs here 2 1/3 cycles} {c3 - c3 c2 - c2}
|
|
{Continue at BBExit on c1 if finished (L0 = restore.term)}
|
|
{Continue at restore.pf on c3 if page fault (L0 = restore.pf)}
|
|
{Continue at restore.int on c3 if interrupt (L0 = restore.int)}
|
|
|
|
{END}
|
|
|
|
|
|
|
|
@
|
|
|
|
|
|
1.1.1.1
|
|
log
|
|
@first add
|
|
@
|
|
text
|
|
@@
|