UNIT Y767DISP (* Y767 Display routines  D. J. Wilke N3HGQ 09/26/89 *);

INTERFACE

USES CRT, DOS, Y767GLO, Y767UTIL;

PROCEDURE PrFKeys;
PROCEDURE PrMessage(Mstring : String86; Tc : INTEGER);
PROCEDURE PrFrame (LeftCol,RightCol,TopRow,BottomRow : INTEGER);
PROCEDURE PrLines(Dir : STRING; X,X1,Y,Y1,Fg,Bg,Ch : INTEGER);
PROCEDURE PrRule;
PROCEDURE PrBox;
PROCEDURE PrFreq (Update : String86; ByteNo,Col,Row : INTEGER);
PROCEDURE PrMode (Param : String86; ByteNo,Col,Row : INTEGER);
PROCEDURE PrCTCSS(Param : String86; ByteNo,Col,Row : INTEGER);
PROCEDURE PrMem(Sb,Eb,SR,FC,MC,TC : INTEGER);
PROCEDURE PrStatusByte;
PROCEDURE PrBandLimits;
PROCEDURE PrDfPage(Pg,Rec,Nlines : INTEGER);

IMPLEMENTATION

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrFKeys (* Display Function keys on line 25 *);

BEGIN (* PrFKeys *)
    ScreenWrite('1 DF'+CHR(26)+'Mem',1,25,FKA);
    ScreenWrite('2 DF'+CHR(26)+'VFO',10,25,FKA);
    ScreenWrite('3 '+CHR(25)+'Band',19,25,FKA);
    ScreenWrite('4 '+CHR(24)+'Band',27,25,FKA);
    ScreenWrite('5 Splt'+CHR(18),35,25,FKA);
    ScreenWrite('6 Clar'+CHR(29),43,25,FKA);
    ScreenWrite('7 M'+CHR(26)+'VFO',51,25,FKA);
    ScreenWrite('8 VFO'+CHR(26)+'M',59,25,FKA);
    ScreenWrite('9 Swap*',67,25,FKA);
    ScreenWrite('0 Exit',75,25,FKA);
END; (* PrFKeys *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrMessage(Mstring : String86; Tc : INTEGER);
(* Display message at line Tc centered horizontally *)

VAR
    Lc : INTEGER;

BEGIN (* PrMessage *)
    TEXTCOLOR(DFG);
    TEXTBACKGROUND(DBG);                     (* Default screen colors *)
    GOTOXY(40 - (LENGTH(Mstring) DIV 2) + 1,Tc);
    WRITE(Mstring);                          (* Display Message centered *) 
END; (* PrMessage *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrFrame (LeftCol,RightCol,TopRow,BottomRow : INTEGER);
(* Draw basic screen frame using graphics characters *)

VAR
    Vert,HorizLength : INTEGER;

BEGIN (* PrFrame *)
    (* Do the corners *)
    ScreenWrite(CHR(201),LeftCol,TopRow,SBA);
    ScreenWrite(CHR(187),RightCol,TopRow,SBA);
    ScreenWrite(CHR(200),LeftCol,BottomRow,SBA);
    ScreenWrite(CHR(188),RightCol,BottomRow,SBA);

    (* Do the vertical lines *)
    FOR Vert := TopRow + 1 TO BottomRow - 1 DO
    BEGIN
        ScreenWrite(CHR(186),LeftCol,Vert,SBA);
        ScreenWrite(CHR(186),RightCol,Vert,SBA);
    END;

    (* Do the horizontal lines *)
    HorizLength := RightCol - LeftCol - 1;
    FOR Index := 1 TO HorizLength DO BEGIN
        ScreenWrite(CHR(205),Index + 1,TopRow,SBA);
        ScreenWrite(CHR(205),Index + 1,BottomRow,SBA);
    END; (* FOR Index *)
END; (* PrFrame *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrLines(Dir : STRING; X,X1,Y,Y1,Fg,Bg,Ch : INTEGER);
(* Draw horiz or vert ruling lines *)

BEGIN (* PrLines *)                          (* Ch=graphics character *)
    IF Dir = 'H' THEN BEGIN                  (* Draw horiz line *)
        FOR Index := X TO X1 DO              (* X=start col, X1=end col *)
            ScreenWrite(CHR(Ch),Index,Y,Fg); (* Draw @row Y, in color Fg *)
    END; (* IF Dir *)
    IF Dir = 'V' THEN BEGIN                  (* Draw vert line *)
        FOR Index := Y TO Y1 DO              (* Y=start row, Y1=end row *)
            ScreenWrite(CHR(Ch),X,Index,Fg); (* Draw @col X, in color Fg *)
    END; (* IF Dir *)
END; (* PrLines *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrRule (* Display ruled lines at top of screen *);

BEGIN (* PrRule *)
    ScreenWrite(CHR(204),1,5,SBA);           (* Dbl tee, left *)
    PrLines('H',2,79,5,0,SBA,DBG,205);       (* Dbl H line, top *)
    ScreenWrite(CHR(185),80,5,SBA);          (* Dbl tee, right *)
END; (* PrRule *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrBox (* Display selected parameter box *);
    (* Note: ABSOLUTE positions, not relative to window *)

BEGIN (* PrBox *)
    ScreenWrite(CHR(201),57,7,SBA);          (* Dbl corner, UL *)
    PrLines('H',58,74,7,0,SBA,DBG,205);      (* Top dbl line, box *)
    ScreenWrite(CHR(187),75,7,SBA);          (* Dbl corner, UR *)
    ScreenWrite(CHR(186),57,8,SBA);          (* Dbl V line, left *)
    ScreenWrite(CHR(186),75,8,SBA);          (* Dbl V line, right *)
    ScreenWrite(CHR(200),57,9,SBA);          (* Dbl corner, LL *)
    PrLines('H',58,74,9,0,SBA,DBG,205);      (* Bot dbl line, box *)
    ScreenWrite(CHR(188),75,9,SBA);          (* Dbl corner, LR *)
END;

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrFreq (Update : String86; ByteNo,Col,Row : INTEGER);
(* Decode and Display VFO, Operating & Memory frequencies *)

VAR
    S    : STRING[2];
    Temp : STRING[8];
    Freq : REAL;
    Code : INTEGER;

BEGIN (* PrFreq *)
    Temp := '';
    TEXTCOLOR(SFG);
    IF Col <> 8 THEN
        TEXTBACKGROUND(DBG)                  (* Returned status colors *)
    ELSE
        TEXTBACKGROUND(BLUE);                (* Special status colors *)
    GOTOXY(Col,Row);
    FOR Index := ByteNo TO ByteNo + 3 DO BEGIN (* Grab the 4 Freq bytes *)
        STR(Bin2BCDHex(ORD(Update[Index])),S);(* Make string of BCD Hex *)
        IF LENGTH(S) < 2 THEN
            S := '0' + S;                    (* Must have leading zero *)
        Temp := Temp + S;                    (* Build 8 byte Temp string *)
    END; (* FOR Index *)
    VAL(Temp,Freq,Code);                     (* Convert to REAL number *)
    WRITE((Freq/100000):9:5);                (* Display 5 decimal places *)
    IF Col > 8 THEN BEGIN
        TEXTCOLOR(DFG);
        TEXTBACKGROUND(DBG);             (* Default screen colors *)
        GOTOXY(Col+10,Row); WRITE('MHz.');
    END (* IF Col *)
    ELSE WRITE(' ');
    TEXTCOLOR(DFG);
    TEXTBACKGROUND(DBG);                     (* Default screen colors *)
END; (* PrFreq *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrMode (Param : String86; ByteNo,Col,Row : INTEGER);
(* Decode and Display modes *)

VAR
    Mode     : INTEGER;
    ModeByte : CHAR;

BEGIN (* PrMode *)
    IF Row = 4 THEN BEGIN
        TEXTCOLOR(SFG);
        TEXTBACKGROUND(BLUE);                (* Special status colors *)
    END (* IF *)
    ELSE BEGIN
        TEXTCOLOR(SFG);
        TEXTBACKGROUND(DBG);                 (* Returned status colors *)
    END; (* ELSE *)
    ModeByte := Param[ByteNo];               (* nth byte of Update stream *)
    Mode     := Bin2BCDHex(ORD(ModeByte) AND 7); (* Mask off Mode bits *)
    GOTOXY(Col,Row);
    CASE Mode OF
        0 : WRITE('LSB');
        1 : WRITE('USB');
        2 : WRITE(' CW');
        3 : WRITE(' AM');
        4 : WRITE(' FM');
        5 : WRITE('FSK');
    END; (* CASE *)
    TEXTCOLOR(DFG);
    TEXTBACKGROUND(DBG);                     (* Default screen colors *)
END; (* PrMode *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrCTCSS(Param : String86; ByteNo,Col,Row : INTEGER);
(* Decode and Display CTCSS tone frequencies *)

VAR
    Tone  : INTEGER;
    CTCSS : REAL;

BEGIN (* PrCTCSS *)
    Tone := ORD(Param[ByteNo]);              (* nth byte of Update stream *)
    IF (Tone < 33) OR (Tone > 62) THEN
        CTCSS := 0;
    CASE Tone OF
        21     : CTCSS := 91.5;              (* 15h *)
        22     : CTCSS := 88.5;
        23     : CTCSS := 85.4;
        24     : CTCSS := 82.5;
        25     : CTCSS := 79.7;
        26     : CTCSS := 77.0;
        27     : CTCSS := 74.7;
        28     : CTCSS := 71.9;
        29     : CTCSS := 67.0;
        30     : CTCSS := 250.3;
        31     : CTCSS := 241.8;
        32     : CTCSS := 233.6;
        33     : CTCSS := 225.7;             (* 21h *)
        34     : CTCSS := 218.1;
        35     : CTCSS := 210.7;
        36     : CTCSS := 203.5;
        37     : CTCSS := 192.8;
        38     : CTCSS := 186.2;
        39     : CTCSS := 179.9;
        40     : CTCSS := 173.8;
        41     : CTCSS := 167.9;
        42     : CTCSS := 162.2;
        43     : CTCSS := 156.7;
        44     : CTCSS := 151.4;
        45     : CTCSS := 146.2;
        46     : CTCSS := 141.3;
        47     : CTCSS := 136.5;
        48     : CTCSS := 131.8;
        49     : CTCSS := 127.3;
        50     : CTCSS := 123.0;
        51     : CTCSS := 118.8;
        52     : CTCSS := 114.8;
        53     : CTCSS := 110.9;
        54     : CTCSS := 107.2;
        55     : CTCSS := 103.5;
        56     : CTCSS := 100.0;
        57     : CTCSS := 94.8;
        58     : CTCSS := 88.5;
        59     : CTCSS := 82.5;
        60     : CTCSS := 77.0;
        61     : CTCSS := 71.9;
        62     : CTCSS := 67.0;
    END; (* CASE *)
    TEXTCOLOR(SFG);
    TEXTBACKGROUND(DBG);                     (* Returned status colors *)
    GOTOXY(Col,Row);
    IF ToneEnc THEN BEGIN                    (* Is CTCSS bd installed? *)
        WRITE(CTCSS:3:1);
        TEXTCOLOR(DFG);
        TEXTBACKGROUND(DBG);                 (* Default screen colors *)
        GOTOXY(Col + 7,Row); WRITE ('Hz.');
    END
    ELSE BEGIN
        TEXTCOLOR(SFG);
        TEXTBACKGROUND(DBG);             (* Returned status colors *)
        WRITE ('   None   ');            (* No CTCSS board installed *)
    END; (* ELSE *)
    TEXTCOLOR(DFG);
    TEXTBACKGROUND(DBG);                     (* Default screen colors *)
END; (* PrCTCSS *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrMem(Sb,Eb,SR,FC,MC,TC : INTEGER);
(* Decode & display memory Frequencies, Mode, Tone
    Sb = Start byte in Update
    Eb = Ending byte in Update
    SR = Starting screen row
    FC = Frequency column
    MC = Mode column
    TC = CTCSS tone column *)

BEGIN (* PrMem *)
    IF LENGTH(Update) = 86 THEN BEGIN
        WHILE Sb <= Eb DO BEGIN
            PrFreq(Update,Sb,FC,SR);
            PrMode(Update,Sb + 5,MC,SR);
            PrCTCSS(Update,Sb + 4,TC,SR);
            SR := SR + 1;
            Sb := Sb + 6;
        END; (* WHILE *)
    END; (* IF LENGTH *)
END; (* PrMem *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrStatusByte (* Decode and Display status byte *);

VAR
    SBStr : STRING[8];
    PTT,HamGen,TXInh,Split,VFO,MemR,Clar,CATS : INTEGER;

BEGIN (* PrStatusByte *)
    PTT    := Bin2BCDHex(ORD(Update[1]) AND $1); (* Mask off PTT bit *)
    HamGen := Bin2BCDHex(ORD(Update[1]) AND $2); (* Mask off H/G bit *)
    TXInh  := Bin2BCDHex(ORD(Update[1]) AND $4); (* Mask off T/R bit *)
    Split  := Bin2BCDHex(ORD(Update[1]) AND $8); (* Mask off Split bit *)
    VFO    := Bin2BCDHex(ORD(Update[1]) AND $10); (* Mask off VFO bit *)
    MemR   := Bin2BCDHex(ORD(Update[1]) AND $20); (* Mask off MR bit *)
    Clar   := Bin2BCDHex(ORD(Update[1]) AND $40); (* Mask off Clar bit *)
    CATS   := Bin2BCDHex(ORD(Update[1]) AND $80); (* Mask off CatS bit *)

    TEXTCOLOR(SFG);
    TEXTBACKGROUND(DBG);                     (* Returned status colors *)
    GOTOXY(65,11);
    IF PTT <> 0 THEN WRITE('Transmit')
    ELSE WRITE('Receive ');
    GOTOXY(65,12);
    IF HamGen <> 0 THEN WRITE('Gen Coverage')
    ELSE WRITE('Ham Bands');
    GOTOXY(65,13);
    IF TXInh <> 0 THEN WRITE('Inhibited')
    ELSE WRITE('Enabled  ');
    GOTOXY(65,14);
    IF Split <> 0 THEN WRITE('Active   ')
    ELSE WRITE('Inactive ');
    GOTOXY(65,15);
    IF VFO <> 0 THEN WRITE(' < B >   ')
    ELSE WRITE(' < A >   ');
    GOTOXY(65,16);
    IF MemR <> 0 THEN WRITE('Active   ')
    ELSE WRITE('Inactive ');
    GOTOXY(65,17);
    IF Clar <> 0 THEN WRITE('Active   ')
    ELSE WRITE('Inactive ');
    GOTOXY(65,18);
    IF CATS <> 0 THEN WRITE('Active   ')
    ELSE WRITE('Inactive ');
END; (* PrStatusByte *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrBandLimits;
(* Display legal band boundaries & transmitter limits *)

BEGIN (* PrBandLimits *)
    (* Display Ham Band limits headings *)
    GOTOXY(14,5); WRITE ('Band');
    GOTOXY(27,5); WRITE ('Legal Band Limits');
    GOTOXY(50,5); WRITE ('Transmitter Band Limits');
    PrLines('H',6,75,11,11,SBA,DBG,196);     (* Display divider line *)
    TEXTCOLOR(RFG);
    TEXTBACKGROUND(DBG);                     (* Requested parameter colors *)
    GOTOXY(10,7); WRITE('160 Meters      1.800 -   2.000 MHz.');
    GOTOXY(52,7); WRITE('1.5 -   1.99999 MHz.');
    GOTOXY(11,8); WRITE('80 Meters      3.500 -   4.000 MHz.');
    GOTOXY(52,8); WRITE('3.5 -   3.99999 MHz.');
    GOTOXY(11,9); WRITE('40 Meters      7.000 -   7.300 MHz.');
    GOTOXY(52,9); WRITE('7.0 -   7.49999 MHz.');
    GOTOXY(11,10); WRITE('30 Meters     10.000 -  10.150 MHz.');
    GOTOXY(51,10); WRITE('10.0 -  10.49999 MHz.');
    GOTOXY(11,11); WRITE('20 Meters     14.000 -  14.350 MHz.');
    GOTOXY(51,11); WRITE('14.0 -  14.49999 MHz.');
    GOTOXY(11,12); WRITE('17 Meters     18.068 -  18.168 MHz.');
    GOTOXY(51,12); WRITE('18.0 -  18.49999 MHz.');
    GOTOXY(11,13); WRITE('15 Meters     21.000 -  21.450 MHz.');
    GOTOXY(51,13); WRITE('21.0 -  21.49999 MHz.');
    GOTOXY(11,14); WRITE('12 Meters     24.890 -  24.990 MHz.');
    GOTOXY(51,14); WRITE('24.0 -  24.99999 MHz.');
    GOTOXY(11,15); WRITE('10 Meters     28.000 -  29.700 MHz.');
    GOTOXY(51,15); WRITE('28.0 -  29.99999 MHz.');
    GOTOXY(11,16); WRITE(' 6 Meters     50.000 -  54.000 MHz.');
    GOTOXY(51,16); WRITE('50.0 -  53.99999 MHz.');
    GOTOXY(11,17); WRITE(' 2 Meters    144.000 - 148.000 MHz.');
    GOTOXY(50,17); WRITE('144.0 - 147.99999 MHz.');
    GOTOXY(11,18); WRITE('70 Cm.       420.000 - 450.000 MHz.');
    GOTOXY(50,18); WRITE('430.0 - 439.99999 MHz.');
END; (* PrBandLimits *)

(*²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²*)
PROCEDURE PrDfPage(Pg,Rec,Nlines : INTEGER);
(* Display Nlines records at a time from datafile *)

VAR
    Item       : INTEGER;
    Mode       : CHAR;
    Freq,Offset,
    Desc       : STRING;
    ModeStr    : STRING[3];
    LineOfData : STRING[70];

BEGIN (* PrDfPage *)
    FOR Index := 1 TO Nlines DO BEGIN
        Freq       := '';
        Offset     := '';
        Mode       := ' ';
        Desc       := '';
        LineOfData := '';
        IF Rec = 0 THEN BEGIN                (* No Rec # means do a page *)
            Item := Pg * 10 + Index;
            GOTOXY(2,Index);
        END
        ELSE BEGIN                           (* Rec # means do specific record *)
            Item := Rec;
            IF Item MOD(10) = 0 THEN GOTOXY(2,Item MOD(10) +10)
            ELSE GOTOXY(2,Item MOD(10));
        END;
        Freq   := COPY(MemArray[Item],15,7);
        Offset := MemArray[Item,23];
        Mode   := MemArray[Item,13];
        Desc   := COPY(MemArray[Item],25,44);
        CASE Mode OF
            'L' : ModeStr := 'LSB';
            'U' : ModeStr := 'USB';
            'C' : ModeStr := 'CW ';
            'A' : ModeStr := 'AM ';
            'K' : ModeStr := 'FSK';
            'F' : ModeStr := 'FM ';
        END; (* CASE *)
        LineOfData := '';
        LineOfData := '   ' +Freq +'   ' +Offset +'   ' +ModeStr +'  ' +Desc;
        WRITE(Item:3);
        IF LENGTH(LineOfData) >= 34 THEN WRITE(LineOfData);
    END; (* FOR Index *)
END; (* PrDfPage *)

END (* of UNIT Y767DISP *).
