home *** CD-ROM | disk | FTP | other *** search
- Date: Wed, 6 Jan 88 12:59 EST
- From: P150BK19@VB.CC.CMU.EDU
- Subject: Hercules-to-Epson Turbo Pascal code
- To: hicks@WALKER-EMH.ARPA
-
- Procedure HGCopy;
-
- (* This procedure produces a hard copy of a Hercules screen on an
- Epson-compatible printer (mode 1) using inline code, which is considerably
- faster than the HardCopy procedure provided with the Turbo Graphix ToolBox.
- On a Panasonic XK-P1080i, which can print 8-bit double-density graphics (mode
- 1) at 6 inches per second, this routine essentially keeps the printer fully
- occupied. About half of the speedup over the ToolBox version comes from
- using inline code to map the graphics bits to a print row, and the other half
- comes from using inline code to print the row itself (instead of a "write"
- call for each and every byte of dots). While the procedure uses variables
- which are defined from the Graphix ToolBox, owning the ToolBox is not
- strictly necessary (of course you must then supply your own drivers). The
- key variables are:
-
- GrafBase : segment address of active screen
- (hardware screen is $B000);
- XScreenMaxGlb : width of screen (in pixels) - 1;
- XMaxGlb : (XScreenMaxGlb - 7) / 8; width of screen in bytes - 1;
-
- The screen is mapped to a print row which is 8 bits high, corresponding to 8
- scan lines. The Hercules scan lines are stored in 4 sectors, the low address
- of which are separated by $2000. Each print row thus contains two successive
- scan lines from each sector. It is also assumed that the screen has 352 scan
- lines (as is used in the ToolBox, in spite of the Hercules specification of
- 348), corresponding to exactly 44 8-bit print rows. This can also be changed
- directly in the main portion of the procedure. *)
-
-
- type
-
- LineType = array [0..XScreenMaxGlb] of Byte;
-
- var
- PrintLine : LineType;
- PrntChrPtr,LinePtr,SectorPtr,ScanPtr,
- PrtLineNum, ByteNum : integer;
- WorkByte : Byte;
-
- Procedure MapLine(LinePtr, XMaxLoc, XScreenMaxLoc : integer;
- var PrintLine : LineType);
- {inline procedure to map a single print line }
-
- var
- ScanBitLoc : integer;
-
- begin {MapLine}
-
- XMaxLoc := XMaxGlb; {get Local variable versions for inline code}
- XScreenMaxLoc := XScreenMaxGlb; {which utilizes stack segment}
-
- Inline(
- $C4/$9E/>PrintLine/ { LES BX,>PrintLine[BP] }
- { set print line to zero }
- $89/$D9/ { MOV CX,BX }
- $03/$8E/>XScreenMaxLoc/ { ADD CX,>XScreenMaxLoc[BP] }
- $31/$C0/ { XOR AX,AX }
- { ZeroStringLoop: }
- $26/ { ES: ; PrintLine in extra segment! }
- $88/$07/ { MOV [BX],AL }
- $43/ { INC BX }
- $39/$CB/ { CMP BX,CX }
- $7E/$F8/ { JLE ZeroStringLoop }
- { SectorPtr := LinePtr }
- $8B/$BE/>LinePtr/ { MOV DI,>LinePtr[BP] ; SectorPtr }
- { for SectorBitLoc := 7 downto 4 do }
- { 4 Sectors in memory }
- $B9/$07/$00/ { MOV CX,7 }
- { SectorLoop: }
- { ScanBitLoc := SectorBitLoc }
- $89/$8E/>ScanBitLoc/ { MOV >ScanBitLoc[BP],CX }
- { ScanPtr := SectorPtr }
- $57/ { PUSH DI }
- $51/ { PUSH CX }
- $31/$C9/ { XOR CX,CX }
- { for ScanNum := 0 to 1 do }
- { 2 Scan Lines per Sector }
- { ScanLineLoop: }
- $C4/$9E/>PrintLine/ { LES BX,>PrintLine[BP] ; PrntChrPtr }
- $51/ { PUSH CX }
- $31/$C9/ { XOR CX,CX }
- { for ByteNum := 0 to XMaxLoc do }
- { 90 Bytes/Scan Line }
- { ByteScanLoop: }
- { WorkByte := mem[GrafBase:ScanPtr] }
- $06/ { PUSH ES }
- $A1/>GrafBase/ { MOV AX,[>GrafBase] }
- $8E/$C0/ { MOV ES,AX }
- $26/ { ES: }
- $8A/$05/ { MOV AL,[DI] }
- $07/ { POP ES }
- $51/ { PUSH CX }
- $BA/$07/$00/ { MOV DX,7 }
- { for BitNum := 7 downto 0 do }
- { Scan single Byte }
- { BitScanLoop: }
- { mem[PrntSeg:PrntChrPtr]
- := mem[PrntSeg:PrntChrPtr] or
- ( ( (WorkByte shr BitNum) and 1 ) shl ScanBitLoc ) }
- $88/$C4/ { MOV AH,AL }
- $89/$D1/ { MOV CX,DX }
- $D2/$EC/ { SHR AH,CL }
- $80/$E4/$01/ { AND AH,1 }
- $8B/$8E/>ScanBitLoc/ { MOV CX,>ScanBitLoc[BP] }
- $D2/$E4/ { SHL AH,CL }
- $26/ { ES: }
- { PrintLine in extra segment }
- $08/$27/ { OR [BX],AH }
- { PrntChrPtr := PrntChrPtr + 1 }
- $43/ { INC BX }
- $4A/ { DEC DX }
- $81/$FA/$00/$00/ { CMP DX,0 }
- $7D/$E6/ { JGE BitScanLoop }
- $59/ { POP CX }
- { ScanPtr := ScanPtr + 1 }
- $47/ { INC DI }
- $41/ { INC CX }
- $3B/$8E/>XMaxLoc/ { CMP CX,>XMaxLoc[BP] }
- $7E/$CF/ { JLE ByteScanLoop }
- $59/ { POP CX }
- { ScanBitLoc := ScanBitLoc - 4 }
- $8B/$9E/>ScanBitLoc/ { MOV BX,>ScanBitLoc[BP] }
- $81/$EB/$04/$00/ { SUB BX,4 }
- $89/$9E/>ScanBitLoc/ { MOV >ScanBitLoc[BP],BX }
- $41/ { INC CX }
- $81/$F9/$01/$00/ { CMP CX,1 }
- $7E/$B4/ { JLE ScanLineLoop }
- $59/ { POP CX }
- { SectorPtr := SectorPtr + $2000 }
- $5F/ { POP DI }
- $81/$C7/$00/$20/ { ADD DI,$2000 }
- $49/ { DEC CX }
- $81/$F9/$04/$00/ { CMP CX,4 }
- $7D/$9F); { JGE SectorLoop }
-
- end; {MapLine}
-
- Procedure PrintByte (OneByte : Byte);
-
- begin {PrintByte}
- Inline(
- $31/$D2/ { XOR DX,DX }
- $B4/$00/ { MOV AH,0 }
- $8A/$86/>OneByte/ { MOV AL,>OneByte[BP] }
- $CD/$17); { INT $17 }
- end; {PrintByte}
-
-
- Procedure PrintRow (XScreenMaxLoc : integer; var PrintLine : LineType);
-
- begin {PrintRow}
-
- Inline(
- $C4/$9E/>PrintLine/ { LES BX,>PrintLine[BP] }
- $89/$D9/ { MOV CX,BX }
- $03/$8E/>XscreenMaxLoc/ { ADD CX,>XScreenMaxLoc[BP] }
- { for ByteNum := 0 to XScreenMaxGlb do }
- {PrintLoop: }
- { Write(Lst, Chr( PrintLine[ByteNum]) ) }
- $31/$D2/ { XOR DX,DX }
- $B4/$00/ { MOV AH,0 }
- $26/ { ES: }
- $8A/$07/ { MOV AL,[BX] }
- $CD/$17/ { INT $17 }
- $43/ { INC BX }
- $39/$CB/ { CMP BX,CX }
- $7E/$F2); { JLE PrintLoop }
-
- end; {PrintRow}
-
-
- begin { HGCopy }
-
- PrintByte(27); {set Line spacing to 9/inch}
- PrintByte(Byte('3'));
- PrintByte(24);
-
- LinePtr := 0; {start with 0 offset from GrafBase}
- for PrtLineNum := 1 to 44 do {44 total print Lines}
- begin
-
- MapLine(LinePtr, XMaxGlb, XScreenMaxGlb, PrintLine);
- {map the Bits with an inLine procedure}
-
- {now print the Line}
-
- PrintByte(27); {force EPSON mode 1 for now}
- PrintByte(Byte('L'));
- PrintByte(Lo(XScreenMaxGlb + 1));
- PrintByte(Hi(XScreenMaxGlb + 1));
-
- PrintRow(XScreenMaxGlb, PrintLine); {print row of Bytes}
-
- PrintByte(10);
- LinePtr := LinePtr + 2 * (XMaxGlb + 1); {jump 2 scan lines / print row}
-
- end; {print Line Loop}
-
- PrintByte(27); {reset printer}
- PrintByte(Byte('2'));
-
- end; {HGCopy}
-