Parino3 : control the Parino relay card

In 1993 I created a relay board that used all bits of the LPT port. the Parino card: 12 relays and 5 opto coupled inputs. Full galvanic isolation between LPT port and Real World. Sold quite a few over the years. The first problem still has to be reported.

The Parino card was driven through device drivers written in assembly language. This program was an attempt to create a test program, using the newly developed VGAlib module. It worked. Here's the source:

   MODULE Parino;

IMPORT  ASCII;

FROM    barith      IMPORT  MulDiv;
FROM    FileSystem  IMPORT  File, Lookup, Response, Close, ReadChar, WriteChar;
FROM    InOut       IMPORT  WriteString, WriteCard;
FROM    Keyboard    IMPORT  KeyPressed, GetKey;
FROM    Mouse       IMPORT  ShowMouse, MouseRecord, GetMouseStatus, InitMouse, SetMouseCursor, HideMouse,
                            ConfineMouse;
FROM    VgaLib3     IMPORT  WinData, COLOUR, SetVGA, ChrWid, Center, SetColour, MakeBox, EraseBox,
                            FillBox, PlotChar, WriteNumber, DrawH, PlotText;
FROM    SYSTEM      IMPORT  ADDRESS, ASSEMBLER;
FROM    System      IMPORT  GetArg;


VAR MainScreen, TopWin, BotLin, TopLin, MousWin                 : WinData;

    Inimini                     : MouseRecord;
    Number, StopCondition,
    OldMode                     : CARDINAL;
    Relays                      : ARRAY [1..12] OF BOOLEAN;
    Sensors                     : ARRAY  [1..5] OF BOOLEAN;
    RelayNames                  : ARRAY [0..24] OF CHAR;
    LptPort                     : CHAR;


PROCEDURE KeyW8 () : CHAR;             (* Wait for keypress    *)

VAR k   : CHAR;

BEGIN
    LOOP
        IF KeyPressed () THEN
            GetKey (k);
            RETURN k
        END
    END
END KeyW8;


PROCEDURE InitWins;

BEGIN
(*  MainScreen is a dummy for the all around framework.     *)

    MainScreen.TopX   :=   0;       MainScreen.TopY   :=   0;
    MainScreen.Width  := 640;       MainScreen.Height := 480;
    MainScreen.CurX   :=   0;       MainScreen.CurY   :=   0;
    MainScreen.DeltaX :=   0;       MainScreen.DeltaY :=   0;
    MainScreen.Indent :=   5;
    MainScreen.TexCol := GREEN;     MainScreen.BoxCol := YELLOW;
    MainScreen.BckCol := black;     MainScreen.MnuCol :=    red;

(*  TopLin describes the upper status bar for action keys.  *)

    TopLin.TopX     :=  60;         TopLin.TopY     :=  20;
    TopLin.Width    := 550;         TopLin.Height   :=  60;
    TopLin.CurX     :=   0;         TopLin.CurY     :=   0;
    TopLin.DeltaX   :=   0;         TopLin.DeltaY   :=   0;
    TopLin.Indent   :=   4;
    TopLin.TexCol   := RED;         TopLin.BoxCol   := green;
    TopLin.BckCol   := pink;        TopLin.MnuCol   :=   RED;

(*  MousWin describes the window for the mouse coordinates  *)

    MousWin.TopX    :=  10;         MousWin.TopY    :=  10;
    MousWin.Width   :=  50;         MousWin.Height  :=  60;
    MousWin.CurX    :=   0;         MousWin.CurY    :=   0;
    MousWin.DeltaX  :=   0;         MousWin.DeltaY  :=   0;
    MousWin.Indent  :=   4;
    MousWin.TexCol  :=  white;      MousWin.BoxCol  :=  white;
    MousWin.BckCol  :=   blue;      MousWin.MnuCol  := YELLOW;


(*  TopWin describes the uppermost window for the parameters.   *)

    TopWin.TopX     :=  10;         TopWin.TopY     :=  75;
    TopWin.Width    := 620;         TopWin.Height   := 375;
    TopWin.CurX     :=   0;         TopWin.CurY     :=   0;
    TopWin.DeltaX   :=   0;         TopWin.DeltaY   :=   0;
    TopWin.Indent   :=   4;
    TopWin.TexCol   := YELLOW;      TopWin.BoxCol   := cyan;
    TopWin.BckCol   :=  black;      TopWin.MnuCol   :=  red;

(*  BotLin describes the Copyright notice.                  *)

    BotLin.TopX     :=   5;         BotLin.TopY     := 460;
    BotLin.Width    := 620;         BotLin.Height   :=  20;
    BotLin.CurX     :=   0;         BotLin.CurY     :=   0;
    BotLin.DeltaX   :=   0;         BotLin.DeltaY   :=   0;
    BotLin.Indent   :=   4;
    BotLin.TexCol   := brown;       BotLin.BoxCol   := green;
    BotLin.BckCol   := black;       BotLin.MnuCol   := green;

END InitWins;


PROCEDURE FillScreen;

VAR Index       : CARDINAL;
    Token       : CHAR;

BEGIN
    SetColour (TopWin.TexCol, TopWin.BckCol);
    FOR Index := 1 TO 12 DO
        TopWin.CurX := 50;
        TopWin.CurY := 25 * Index + 5;
        PlotText (TopWin, "Relay ");
        IF Index < 9 THEN
            WriteNumber (TopWin, Index, 1);
        ELSE
            Token := CHR (Index + 56);
            PlotChar (TopWin, Token);
        END;
        PlotText (TopWin, " : ");
        IF Relays [Index] THEN
            PlotText (TopWin, "ON ");
        ELSE
            PlotText (TopWin, "OFF");
        END;
    END;
    FOR Index := 1 TO 5 DO
        TopWin.CurX := 400;
        TopWin.CurY := 25 * Index + 5;
        PlotText (TopWin, "Sensor ");
        Token := CHR (Index + 80);
        PlotChar (TopWin, Token);
        IF Sensors [Index] THEN
            PlotText (TopWin, " = ACTIVE ");
        ELSE
            PlotText (TopWin, " = PASSIVE");
        END;
    END;
END FillScreen;


PROCEDURE UpdateScreen;

VAR Index       : CARDINAL;
    Token       : CHAR;

BEGIN
    SetColour (TopWin.TexCol, TopWin.BckCol);
    FOR Index := 1 TO 12 DO
        TopWin.CurX := 140;
        TopWin.CurY := 25 * Index + 5;
        IF Relays [Index] THEN
            PlotText (TopWin, "ON ");
        ELSE
            PlotText (TopWin, "OFF");
        END;
    END;
    FOR Index := 1 TO 5 DO
        TopWin.CurX := 400;
        TopWin.CurY := 25 * Index + 5;
        IF Sensors [Index] THEN
            PlotText (TopWin, "ACTIVE ");
        ELSE
            PlotText (TopWin, "PASSIVE");
        END;
    END;
END UpdateScreen;


PROCEDURE SetUpScreen;

BEGIN
    OldMode := SetVGA (18);
    InitMouse (Inimini);
    InitWins;
        MakeBox (MainScreen);
        MakeBox (TopWin);
        MakeBox (MousWin);
    TopLin.CurX := 10;
    TopLin.CurY :=  0;
    Center (TopLin, "Parino_debugger Use_the_mouse");
    BotLin.CurX := 10;
    BotLin.CurY :=  0;
    Center (BotLin, "Copyleft_2003: Jan_Verhoeven NL-5012_GH_272 fruttenboel@tomaatnet.nl");
END SetUpScreen;


PROCEDURE SetUpMouse;

BEGIN
    ShowMouse;
    IF Inimini.Buttons = 2 THEN
        StopCondition := 3;
    ELSE
        StopCondition := 7;
    END;
    SetMouseCursor (30, 30);
END SetUpMouse;


PROCEDURE ShowMouseXY;                      (*  Show current mouse data on screen.      *)

BEGIN
    SetColour (MousWin.TexCol, MousWin.BckCol);
    MousWin.CurX := MousWin.Indent;
    MousWin.CurY := 4;
    WriteNumber (MousWin, Inimini.MouseX, 4);
    MousWin.CurX := MousWin.Indent;
    MousWin.CurY := 23;
    WriteNumber (MousWin, Inimini.MouseY, 4);
    MousWin.CurX := MousWin.Indent;
    MousWin.CurY := 42;
    WriteNumber (MousWin, Inimini.Status, 4);
END ShowMouseXY;


PROCEDURE FindClick (Inimini : MouseRecord) : CARDINAL;

BEGIN
    RETURN 1;
END FindClick;


PROCEDURE CheckSensors (VAR Array : ARRAY OF BOOLEAN);

VAR Index       : CARDINAL;
    Token       : CHAR;

BEGIN
    Token := 'P';
    REPEAT
        CASE Token OF
         'P' :  Array [1] := TRUE;  |
         'Q' :  Array [2] := TRUE;  |
         'R' :  Array [3] := TRUE;  |
         'S' :  Array [4] := TRUE;  |
         'T' :  Array [5] := TRUE;
        END;
    UNTIL Token = ASCII.EOL
END CheckSensors;


PROCEDURE CheckRelays (VAR Array : ARRAY OF BOOLEAN);

VAR Index       : CARDINAL;
    Token       : CHAR;

BEGIN
    Token := '1';
    REPEAT
        CASE Token OF
         '1' :  Array [0] := TRUE;  |
         '2' :  Array [1] := TRUE;  |
         '3' :  Array [2] := TRUE;  |
         '4' :  Array [3] := TRUE;  |
         '5' :  Array [4] := TRUE;  |
         '6' :  Array [5] := TRUE;  |
         '7' :  Array [6] := TRUE;  |
         '8' :  Array [7] := TRUE;  |
         '9' :  Array [8] := TRUE;  |
         'A' :  Array [9] := TRUE;  |
         'B' :  Array [10] := TRUE; |
         'C' :  Array [11] := TRUE; |
         '0' :  FOR Index := 0 TO 11 DO
                    Array [Index] := FALSE;
                END;
        END;
        INC (Token)
    UNTIL Token = ASCII.EOL
END CheckRelays;


PROCEDURE InitVars;

VAR Index       : CARDINAL;
    Option      : ARRAY [0..11] OF CHAR;

BEGIN
    RelayNames := '123456789ABC';
    GetArg (Option, Index);
    IF Index = 0 THEN
        LptPort := '1'
    ELSE
        LptPort := Option [0]
    END;
    FOR Index := 1 TO 12 DO
        Relays [Index] := FALSE
    END;
    FOR Index := 1 TO 5 DO
        Sensors [Index] := FALSE
    END;
    SetMouseCursor (200, 200)
END InitVars;


BEGIN
    SetUpScreen;
    SetUpMouse;
    InitVars;
    FillScreen;

    REPEAT
        GetMouseStatus (Inimini);
        ShowMouseXY;
        IF Inimini.Status > 0 THEN
            Number := FindClick (Inimini)
        END;
(*        CheckSensors (Sensors);
        CheckRelays (Relays);       *)
        UpdateScreen;
    UNTIL Inimini.Status = StopCondition;

    OldMode := SetVGA (OldMode);
END Parino.
   
Exit the program by pressing all mouse buttons at once.

Page created Sptember 15, 2012 and