-- RamtektoPacked.mesa - September 1981
-- Ramtek module to generate packed bitmap ".ram" files
-- LastEdit: September 28, 1981 6:59 PM by R. Pasco
--".ram" file format: <line><line><line>...<line>
--Where <line> is <run><run>...<run><endline>
--And <run> is a pair of bytes <count><pixelPair>:
--First byte = count, an 8-bit integer:
--Specify count (where 1 <= count <= 255) repetitions of stipple
--defined by second byte.
--Second byte = msb BCMYBCMY lsb:
--Specifies a 2-pixel-wide by 1-pixel-high by 4-color-deep stipple
--pixelPair, where:
--"0" = white; "1" = color.
--"B" = Black; "C" = Cyan; "M" = Magenta; "Y" = Yellow.
--The left pixel occupies the high 4 bits; the right pixel occupies
--the low 4 bits.
--And <endline> is a pair of zero bytes:
--A scan line need not be completely filled before this end-of-line
--designator.
--If an end-of-scan-line byte comes before the line is filled, the
--remainder of the line is white.
--The Ramtek 4100 printer is only 918 pixels (459 stipples) per
--scanline. Longer lines will be truncated by Aries.
--The last word in the file must be this "end-of-line" designator.
DIRECTORY
InlineDefs: FROM "InlineDefs" USING [LongCOPY],
StreamDefs: FROM "StreamDefs" USING [StreamHandle, NewByteStream, Write, Append],
SystemDefs: FROM "SystemDefs" USING [AllocateHeapNode, FreeHeapNode],
RamtekDefs: FROM "RamtekDefs";
Ramtek: PROGRAM
IMPORTS InlineDefs, StreamDefs, SystemDefs
EXPORTS RamtekDefs =
BEGIN OPEN InlineDefs, StreamDefs, SystemDefs;
RamFileStream: StreamHandle;
BlackLine: POINTER ← NIL;
CyanLine: POINTER ← NIL;
MagentaLine: POINTER ← NIL;
YellowLine: POINTER ← NIL;
ScanLineLength: CARDINAL;
ScanLineBits: CARDINAL;
LineNumber: CARDINAL;
Word: TYPE = POINTER TO WordRecord;
WordRecord: TYPE = MACHINE DEPENDENT RECORD [n1,n2,n3,n4,n5,n6,n7,n8: [0..3]];
StartRamtekPlot: PUBLIC PROCEDURE[fileName: STRING, width,height: CARDINAL] =
BEGIN
ScanLineBits ← ((width+3)/4)*4;
ScanLineLength ← (width+15)/16;
BlackLine ← AllocateHeapNode[ScanLineLength];
CyanLine ← AllocateHeapNode[ScanLineLength];
MagentaLine ← AllocateHeapNode[ScanLineLength];
YellowLine ← AllocateHeapNode[ScanLineLength];
LineNumber ← 0;
RamFileStream ← NewByteStream[fileName, Write + Append];
END;
EndRamtekPlot: PUBLIC PROCEDURE =
BEGIN
FreeHeapNode[BlackLine];
FreeHeapNode[CyanLine];
FreeHeapNode[MagentaLine];
FreeHeapNode[YellowLine];
RamFileStream.destroy[RamFileStream];
END;
WriteRamtekLine: PUBLIC PROCEDURE [bline,cline,mline,yline: LONG POINTER, nBytes: CARDINAL] =
BEGIN
bword: Word ← BlackLine;-- point to first word of each scanline
cword: Word ← CyanLine;
mword: Word ← MagentaLine;
yword: Word ← YellowLine;
nCount: CARDINAL ← 0;-- number of pairs taken from this word
nBits: CARDINAL ← 0;-- number of bits taken from this line
count,pixelPair,nextPair: CARDINAL;
Assemble: PROC [b,c,m,y: CARDINAL] RETURNS[nextPair: CARDINAL] =
BEGIN
nextPair ← 128*(b/2)+64*(c/2)+32*(m/2)+16*(y/2) + 8*(b MOD 2)+4*(c MOD 2)+2*(m MOD 2)+(y MOD 2);
END;
GetPixelPair: PROC RETURNS[nextPair: CARDINAL] =
BEGIN
nCount ← nCount + 1;
nBits ← nBits + 2;
SELECT nCount FROM
1=> nextPair ← Assemble[bword.n1,cword.n1,mword.n1,yword.n1];
2=> nextPair ← Assemble[bword.n2,cword.n2,mword.n2,yword.n2];
3=> nextPair ← Assemble[bword.n3,cword.n3,mword.n3,yword.n3];
4=> nextPair ← Assemble[bword.n4,cword.n4,mword.n4,yword.n4];
5=> nextPair ← Assemble[bword.n5,cword.n5,mword.n5,yword.n5];
6=> nextPair ← Assemble[bword.n6,cword.n6,mword.n6,yword.n6];
7=> nextPair ← Assemble[bword.n7,cword.n7,mword.n7,yword.n7];
8=> {nextPair←Assemble[bword.n8,cword.n8,mword.n8,yword.n8];
bword ← bword + 1;-- point to next word of scanline
cword ← cword + 1;
mword ← mword + 1;
yword ← yword + 1;
nCount ← 0;
};
ENDCASE;
END;
LongCOPY[bline, ScanLineLength, BlackLine];
LongCOPY[cline, ScanLineLength, CyanLine];
LongCOPY[mline, ScanLineLength, MagentaLine];
LongCOPY[yline, ScanLineLength, YellowLine];
pixelPair ← GetPixelPair[];
count ← 1;
WHILE nBits<ScanLineBits DO
nextPair ← GetPixelPair[];
IF nextPair=pixelPair THEN
{IF count<377B THEN count ← count+1
ELSE
{RamFileStream.put[RamFileStream,count];
RamFileStream.put[RamFileStream,pixelPair];
count ← 1;
};
}
ELSE
{RamFileStream.put[RamFileStream,count];
RamFileStream.put[RamFileStream,pixelPair];
pixelPair ← nextPair;
count ← 1;
};
ENDLOOP;
RamFileStream.put[RamFileStream,count];
RamFileStream.put[RamFileStream,pixelPair];
RamFileStream.put[RamFileStream,0];-- endline is two zero bytes
RamFileStream.put[RamFileStream,0];
LineNumber ← LineNumber + 1;
END;
END.