DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T t

⟦5966f0cdd⟧ TextFile

    Length: 11327 (0x2c3f)
    Types: TextFile
    Names: »tek4010vdu.mod«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./DVIware/crt-viewers/others/dvitovdu/src/tek4010vdu.mod« 
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/crt-viewers/others/dvitovdu/src/tek4010vdu.mod« 

TextFile

IMPLEMENTATION MODULE tek4010vdu;

(* Author:         Andrew Trevorrow
   Implementation: Modula-2 under VAX/UNIX 4.2 BSD
   Date Started:   June, 1986

   Description:
   Implements the routines used in VDU-specific modules that emulate
   a Tektronix 4010 terminal (VIS500/550, VT640).
   The screen is assumed to be 780 pixels high by 1024 pixels wide.
   (The actual resolution of an emulating screen may be different, but
   such terminals provide automatic scaling.)
   The bottom left pixel is the point (x=0,y=0); x coordinates
   increase to the right and y coordinates increase up the screen.
   DVItoVDU uses a coordinate scheme in which horizontal (=h) coordinates
   also increase to the right but vertical (=v) coordinates increase DOWN the
   screen, i.e. the top left pixel on the screen is the point (h=0,v=0).
   This means that the Tektronix 4010 routines will have to do a
   simple translation of the vertical coordinates passed by DVItoVDU.
*)

FROM vduinterface IMPORT
   TeXtoASCII;

FROM screenio IMPORT
   Write;

CONST
   ESC = 33C;
   FF  = 14C;
   FS  = 34C;
   GS  = 35C;
   US  = 37C;

VAR
   oldhiy,                 (* for remembering old address in SendXY *)
   oldhix,
   oldloy : CARDINAL;
   charwidth,              (* set by LoadFont and used in ShowChar *)
   loadedsize,             (* remember alpha size set by last LoadFont; VT640,
                              VIS500/550 VDUs don't actually need to worry
                              about this since they use non-TEK4010 fonts to
                              draw in dialogue region.
                              VIS240 however uses alpha mode font. *)
   charsize : CARDINAL;    (* used to select alpha character size *)

(******************************************************************************)

PROCEDURE SendXY (x, y : CARDINAL);

(* Translates the given screen address into 4 bytes.
   havesentxy is used to minimize the number of bytes sent: after the first
   4 bytes have been sent, subsequent bytes that don't change need not be sent
   (except for the low x byte which is always sent).
   If the high x byte changes then the low y byte must also be sent.
*)

VAR hiy, loy, hix, lox : CARDINAL;
    sendhix : BOOLEAN;

BEGIN
(* we assume y is in [0..maxy] and x is in [0..1023] *)
hiy := ORD(' ') + (y DIV 32);
hix := ORD(' ') + (x DIV 32);
loy := ORD('`') + (y MOD 32);
lox := ORD('@') + (x MOD 32);
IF havesentxy THEN
   IF hiy <> oldhiy THEN
      Write(CHR(hiy));   oldhiy := hiy;
   END;
   sendhix := hix <> oldhix;
   IF (loy <> oldloy) OR sendhix THEN
      Write(CHR(loy));   oldloy := loy;
   END;
   IF sendhix THEN
      Write(CHR(hix));   oldhix := hix;
   END;
   Write(CHR(lox));
ELSE   (* send first 4 bytes *)
   Write(CHR(hiy));   oldhiy := hiy;
   Write(CHR(loy));   oldloy := loy;
   Write(CHR(hix));   oldhix := hix;
   Write(CHR(lox));
   havesentxy := TRUE;
END;
(* SYSDEP: We assume XON/XOFF flow control is enabled to avoid data loss. *)
END SendXY;

(******************************************************************************)

PROCEDURE TEK4010StartText;

(* DVItoVDU will only call MoveToTextLine, ClearTextLine, ClearScreen and
   ResetVDU while in text mode.
*)

BEGIN
Write(US);
END TEK4010StartText;

(******************************************************************************)

PROCEDURE TEK4010MoveToTextLine (line : CARDINAL);

(* Move cursor to start of given line using lineht.
   At the end of this routine we must be in alpha mode and ready to display
   characters in the default charsize.
*)


BEGIN
Write(GS);                          (* switch to graphics mode *)
SendXY(0,maxy+1 - (line*lineht));
Write(ESC);                         (* reset alpha character size *)
Write('0');
charsize := 0;
charwidth := 13;
Write(US);                          (* back to alpha mode *)
END TEK4010MoveToTextLine;

(******************************************************************************)

PROCEDURE TEK4010ClearScreen;

BEGIN
Write(GS);                (* make sure we're in graphics mode *)
Write(ESC); Write(FF);    (* erase graphics and put in alpha mode *)
havesentxy := FALSE;      (* ESC FF will home cursor *)
charsize := 0;            (* ESC FF resets character size *)
charwidth := 13;
END TEK4010ClearScreen;

(******************************************************************************)

PROCEDURE TEK4010StartGraphics;

(* DVItoVDU will only call LoadFont, ShowChar and ShowRectangle while
   in graphics mode.
*)

BEGIN
IF charsize <> loadedsize THEN      (* graphics mode was interrupted *)
   charsize := loadedsize;
   dragdown := (charsize + 1) * 5;  (* used by VIS500/550 ShowChar *)
   Write(GS);
   Write(ESC);
   Write(CHR(ORD('0')+charsize));   (* recall last LoadFont character size *)
END;
Write(GS);
havesentxy := FALSE;                (* safer to send all location bytes anew *)
END TEK4010StartGraphics;

(******************************************************************************)

PROCEDURE TEK4010LoadFont (fontname : ARRAY OF CHAR;
                           fontsize : CARDINAL;
                           mag, hscale, vscale : REAL);

(* Use the given fontsize to select an appropriate character size
   (based on horizontal scaling only!) for future ShowChar calls.
*)

VAR newsize : CARDINAL;

BEGIN
(* convert fontsize into scaled screen pixels using mag and hscale *)
fontsize := TRUNC( FLOAT(fontsize) * mag * hscale + 0.5 );
(* Chooose one of the 4 alpha mode character sizes based on fontsize:
   charsize    max chars/line    relative size     fontsize range
       0             80               x1               0..40
       1             40               x2              41..80
       2             26               x3              81..120
       3             20               x4             121...
   The fontsize ranges were chosen by trial and error.
*)
IF    fontsize < 41 THEN
   newsize := 0;
   charwidth := 13;   (* 1024/80 = 12.8 *)
ELSIF fontsize < 81 THEN
   newsize := 1;
   charwidth := 26;   (* 1024/40 = 25.6 *)
ELSIF fontsize < 121 THEN
   newsize := 2;
   charwidth := 40;   (* 1024/26 = 39.4 *)
ELSE
   newsize := 3;
   charwidth := 52;   (* 1024/20 = 51.2 *)
END;
loadedsize := newsize;   (* remember in case graphics mode is interrupted *)
IF charsize <> newsize THEN                  (* change character size *)
   charsize := newsize;
   Write(ESC);
   Write(CHR(ORD('0')+charsize));
END;
(* Alpha character reference pts on some emulating VDUs (VIS500/550) are below
   baselines to allow for descenders.
   Such VDUs can use dragdown to drag baselines down to TeX reference pts
   when calling ShowChar.
*)
dragdown := (charsize + 1) * 5;   (* used by VIS500/550 ShowChar *)
Write(GS);                        (* must exit in graphics mode *)
END TEK4010LoadFont;

(******************************************************************************)

PROCEDURE TEK4010ShowChar (screenh, screenv : CARDINAL;
                           ch : CHAR);

(* Show the given Terse character (mapped to ASCII) at the given ref pt.
   We use the charwidth set by last LoadFont call.
*)

VAR newch : CHAR;   (* = TeXtoASCII[ch] *)

BEGIN
(* shift character left if it will overlap right edge of screen *)
IF screenh + charwidth > 1023 THEN
   screenh := 1023 - charwidth;
END;
(* we assume StartGraphics, LoadFont or last ShowChar has just sent GS *)
SendXY(screenh,maxy-screenv);    (* move cursor to ref pt *)

(* We use TeXtoASCII to map ch into a comparable ASCII character, apart
   from most of the ? characters which we attempt to simulate.
*)

Write(US);   (* enter alpha mode *)
newch := TeXtoASCII[ch];
IF newch <> '?' THEN
   (* newch is similar to TeX ch *)
   Write(newch);
ELSE
   (* attempt to display something other than ? *)
   CASE ch OF
   13C..17C :   (* ff, fi, fl, ffi, ffl *)
       Write('f');
       (* only simulate rest of ligature if room at right edge *)
       IF screenh + 2 * charwidth - (charwidth DIV 2) <= 1023 THEN
          Write(GS);
          SendXY(screenh + charwidth - (charwidth DIV 2),maxy-screenv);
          Write(US);
          CASE ch OF
          13C : Write('f') |
          14C : Write('i') |
          15C : Write('l') |
          16C,
          17C : Write('f');
                IF screenh + 3 * charwidth - 2 * (charwidth DIV 2) <= 1023 THEN
                   Write(GS);
                   SendXY(screenh + 2 * charwidth - 2 * (charwidth DIV 2),
                          maxy-screenv);
                   Write(US);
                   IF ch = 16C THEN
                      Write('i');
                   ELSE
                      Write('l');
                   END;
                END;
          END;
       END;
       |
   31C : Write('B');   (* German sharp S *)
       |
   32C, 33C, 35C, 36C :   (* diphthongs: ae, oe, AE, OE *)
       CASE ch OF
       32C : Write('a') |
       33C : Write('o') |
       35C : Write('A') |
       36C : Write('O')
       END;
       IF screenh + 2 * charwidth - (charwidth DIV 2) <= 1023 THEN
          Write(GS);
          SendXY(screenh + charwidth - (charwidth DIV 2),maxy-screenv);
          Write(US);
          CASE ch OF
          32C, 33C : Write('e') |
          35C, 36C : Write('E')
          END;
       END;
       |
   34C, 37C :   (* Scandinavian slashed o and O *)
       CASE ch OF
       34C : Write('o') |
       37C : Write('O')
       END;
       Write(GS);
       SendXY(screenh,maxy-screenv);   (* overwrite *)
       Write(US);
       Write('/');
       |
   40C : Write("'");   (* Polish suppressed l and L *)
   ELSE
       Write('?');
   END;
END;
Write(GS);     (* must exit in graphics mode *)
END TEK4010ShowChar;

(******************************************************************************)

PROCEDURE TEK4010ShowRectangle (screenh, screenv,         (* top left pixel *)
                                width, height : CARDINAL; (* of rectangle *)
                                ch : CHAR);               (* black pixel *)

(* Display the given rectangle (without using the given black pixel character).
   DVItoVDU ensures that the top left position is visible and that the given
   dimensions do not go beyond the window edges.
*)

VAR i, endpt : CARDINAL;

BEGIN
(* DVItoVDU ensures width and height > 0 *)
IF height < width THEN   (* show row vectors *)
   endpt := screenh+width-1;
   FOR i := 0 TO height-1 DO
      Write(GS);
      SendXY(screenh,maxy-(screenv+i));   (* move cursor to start of row *)
      SendXY(endpt,maxy-(screenv+i));     (* draw vector to end of row *)
   END;
ELSE                     (* show column vectors *)
   endpt := maxy - (screenv+height-1);
   FOR i := 0 TO width-1 DO
      Write(GS);
      SendXY(screenh+i,maxy-screenv);     (* move cursor to start of column *)
      SendXY(screenh+i,endpt);            (* draw vector to end of column *)
   END;
END;
END TEK4010ShowRectangle;

(******************************************************************************)

BEGIN
havesentxy := FALSE;      (* for first SendXY call *)
charsize := 0;            (* the default character size *)
loadedsize := charsize;   (* for first StartGraphics call *)
charwidth := 13;          (* 1024 / 80 = 12.8 *)
maxy := 779;              (* some VDUs may want to change this *)
lineht := 26;             (* 30 text lines; 26 * 30 = 780 *)
END tek4010vdu.