'===========================================================================
' Subject: PARALLEL PORT TEST UTILITY         Date: 10-29-96 (19:33)       
'  Author: Marek Piotrowski                   Code: QB, QBasic, PDS        
'  Origin: ao487@freenet.toronto.on.ca      Packet: MISC.ABC
'===========================================================================
'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
'º                                                                            º
'º                                                                            º
'º PRNPORT.BAS is a parallel port test utility. It allows single bit toggle   º
'º          and single bit monitoring of a selected parallel port.            º
'º                                                                            º
'º         Author: Marek Piotrowski ao487@toronto.freenet.on.ca               º
'º                                                                            º
'º         Credits: Christoph Kummetat for FindPort subroutine.               º
'º                                                                            º
'ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼

DIM SHARED Bit(2, 7) AS INTEGER
DIM SHARED OldByte(2) AS INTEGER
DIM SHARED Byte(2) AS INTEGER
DIM SHARED Port(4) AS INTEGER

DECLARE SUB ToggleBit (PortNum$)
DECLARE SUB DrawBottomBar ()
DECLARE SUB FindPort (PortNum$)
DECLARE SUB DrawScreen ()
DECLARE SUB PrintPortHeaders (PortNum$)
DECLARE SUB ReadPort (PortNum$)
DECLARE SUB BitPinToggle (Q$, BitPinSw%)
DECLARE SUB MoveCursor (Q$)



BitPinSw% = 1                          'Bit or Pin number display switch
                                       '(1 = Bit numer display)
FOR Pt% = 0 TO 2
OldByte(Pt%) = NOT Byte(Pt%)
NEXT Pt%


CLS

DATA " 9"," 8"," 7"," 6"," 5"," 4"," 3"," 2"
DATA "11","10","12","13","15","  ","  ","  "
DATA "  ","  ","  ","  ","17","16","14"," 1"

FindPort PortNum$             'Find ports available
DrawBottomBar
DrawScreen                    'Draw screen subroutine
BitPinToggle Q$, BitPinSw%    'Bit/Pin number display toggle subroutine
PrintPortHeaders PortNum$     'PrintPortHeaders subroutine



DO
Q$ = INKEY$

ReadPort PortNum$   'read data from the ports subroutine




    IF Q$ = CHR$(9) THEN
        BitPinToggle Q$, BitPinSw%   'Bit/Pin number display toggle subroutine
    END IF

    IF LEN(Q$) > 1 THEN
        MoveCursor Q$                'Cursor movement subroutine
    END IF

    IF Q$ = CHR$(32) THEN     'Detect space bar to toggle single bit
                              'at cursor position.
ToggleBit PortNum$        'Toggle one bit


    END IF


LOOP WHILE Q$ <> CHR$(27)
COLOR 7, 0
CLS

SUB BitPinToggle (Q$, BitPinSw%)

        OldCurRow% = CSRLIN
        OldCurCol% = POS(0)


            IF BitPinSw% > 0 THEN          'Toggle Pin to Bit numbers
            COLOR 7, 0
            FOR Row% = 20 TO 21
                LOCATE Row%, 3: PRINT STRING$(77, 32)
            NEXT Row%


            COLOR 12, 1
            LOCATE 9, 4: PRINT "Bit"
                FOR i = 55 TO 48 STEP -1
                LOCATE 11 + (55 - i), 5
                PRINT " "; CHR$(i)
                NEXT i
            LOCATE 9, 29: PRINT "Bit"
                FOR i = 55 TO 48 STEP -1
                LOCATE 11 + (55 - i), 30
                PRINT " "; CHR$(i)
                NEXT i
            LOCATE 9, 53: PRINT "Bit"
                    FOR i = 55 TO 48 STEP -1
                    LOCATE 11 + (55 - i), 54
                    PRINT " "; CHR$(i)
                    NEXT i
            ELSE



            COLOR 10, 1
            LOCATE 9, 4: PRINT "Pin"        'Toggle Bit to Pin numbers
                FOR i = 55 TO 48 STEP -1
                READ A$
                LOCATE 11 + (55 - i), 5
                PRINT A$
                NEXT i
            LOCATE 9, 29: PRINT "Pin"
                FOR i = 55 TO 48 STEP -1
                READ A$
                LOCATE 11 + (55 - i), 30
                PRINT A$
                NEXT i
            LOCATE 9, 53: PRINT "Pin"
                    FOR i = 55 TO 48 STEP -1
                    READ A$
                    LOCATE 11 + (55 - i), 54
                    PRINT A$
                    NEXT i

            COLOR 7, 0
            LOCATE 20, 3: PRINT "Pin numbers apply to D-type 25 pin connector."
            LOCATE 21, 3: PRINT "Pins 18 through 25 are logic ground."
            RESTORE
            END IF

    COLOR 7, 0
    LOCATE OldCurRow%, OldCurCol%, 1, 0, 4

    BitPinSw% = -BitPinSw%


END SUB

SUB DrawBottomBar

LOCATE 23, 1
COLOR 7, 0: PRINT " ";
COLOR 0, 11: PRINT "       Esc ";
COLOR 15, 11: PRINT "- quit, ";
COLOR 0, 11: PRINT "Tab ";
COLOR 15, 11: PRINT "- Bit/Pin number toggle, ";
COLOR 0, 11: PRINT "Space Bar ";
COLOR 15, 11: PRINT "- toggle a bit      ";

COLOR 7, 0

END SUB

SUB DrawScreen
LOCATE 1, 1
PRINT STRING$(80, 32)
PRINT " "; : COLOR 14, 1: PRINT " ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º          PARALLEL PORT DIAGNOSTIC UTILITY - by Marek Piotrowski          º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¹ "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º                               PORT ADDRESS                               º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¶ "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º      ..... OUTPUT      º      ..... INPUT      º      ..... OUTPUT       º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " ÇÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¶ "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³Status³  Function   º   ³Status³  Function  º   ³Status³  Function    º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " ÇÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¶ "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³busy        º   ³ .... ³reserved      º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³acknowledge º   ³ .... ³reserved      º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³out of paperº   ³ .... ³reserved      º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³prn.selectedº   ³ .... ³enable IRQ    º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³error       º   ³ .... ³select prn.   º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³IRQ occured º   ³ .... ³initialize prnº "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³reserved    º   ³ .... ³auto line feedº "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " º   ³ .... ³ data        º   ³ .... ³reserved    º   ³ .... ³strobe        º "; : COLOR 7, 0: PRINT " "
PRINT " "; : COLOR 14, 1: PRINT " ÈÍÍÍÏÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÏÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÏÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼ "; : COLOR 7, 0: PRINT " "
LOCATE 22, 3: PRINT "Output pins 1, 14, 17 and input pin 11 operate in negative logic."
LOCATE 11, 8, 1, 0, 4

END SUB

SUB FindPort (PortNum$)

   DEF SEG = 0
   Count = 0
   FOR i = 1032 TO 1036 STEP 2
      PortAdd% = PEEK(i) + 256 * PEEK(i + 1)
      IF PortAdd% > 0 THEN
         Count = Count + 1
         Port(Count) = VAL("&H" + HEX$(PortAdd%))
         PRINT "Parallel port"; STR$(Count); " at ";
         PRINT "&H" + HEX$(PortAdd%)
      END IF
   NEXT i

    IF Count = 0 THEN                                          'no port found
        PRINT "No parallel port found on your PC !";
    ELSE
        PRINT "Which parallel port do you want to use : ";
            DO
            PortNum$ = INKEY$
            LOOP WHILE VAL(PortNum$) < 1 OR VAL(PortNum$) > Count

    END IF

END SUB

SUB MoveCursor (Q$)

         Q$ = RIGHT$(Q$, 1)
         SELECT CASE ASC(Q$)
            CASE 75 TO 77              'When left or right arrow key pressed
                IF POS(0) < 34 THEN    'toggle cursor column between 8 and 57.
                LOCATE , 57, 1, 0, 4
                ELSE
                LOCATE , 8, 1, 0, 4
                END IF
            CASE IS = 72                     'When up arrow key pressed
                IF CSRLIN > 11 THEN          'move cursor up or wrap from
                LOCATE CSRLIN - 1, , 1, 0, 4 'row 11 to 18.
                ELSE
                LOCATE 18, , 1, 0, 4
                END IF
            CASE IS = 80                     'When down arrow key pressed
                IF CSRLIN > 17 THEN          'move cursor down or wrap from
                LOCATE 11, , 1, 0, 4         'row 18 to 11.
                ELSE
                LOCATE CSRLIN + 1, , 1, 0, 4
                END IF


         END SELECT

END SUB

SUB PrintPortHeaders (PortNum$)

        OldCurRow% = CSRLIN
        OldCurCol% = POS(0)
        COLOR 14, 1
        LOCATE 7, 10
        PRINT "&H"; HEX$(Port(VAL(PortNum$)));
        LOCATE 7, 35
        PRINT "&H"; HEX$(Port(VAL(PortNum$)) + 1)
        LOCATE 7, 59
        PRINT "&H"; HEX$(Port(VAL(PortNum$)) + 2)
        LOCATE OldCurRow%, OldCurCol%

END SUB

SUB ReadPort (PortNum$)


    FOR Pt% = 0 TO 2                            'Read data from the port

                OldCurRow% = CSRLIN             'Save old cursor
                OldCurCol% = POS(0)             'position before screen update


        Byte(Pt%) = INP(Port(VAL(PortNum$)) + Pt%)

        IF Byte(Pt%) <> OldByte(Pt%) THEN       'If new byte differs from
                                                'old one write new bits

            FOR Bt% = 0 TO 7
            Bit(Pt%, Bt%) = (2 ^ Bt% AND Byte(Pt%)) \ (2 ^ Bt%)
            NEXT Bt%



            SELECT CASE Pt%
                CASE IS = 0
                    Clmn% = 9
                CASE IS = 1
                    Clmn% = 34
                CASE IS = 2
                    Clmn% = 58
            END SELECT

            FOR Bt% = 7 TO 0 STEP -1
                IF Bit(Pt%, Bt%) > 0 THEN
                    COLOR 15, 4
                    Tag$ = "High"
                    ELSE
                    COLOR 0, 2
                    Tag$ = "Low "
                END IF


                LOCATE 18 - Bt%, Clmn%
                PRINT Tag$
            NEXT Bt%

            COLOR 7, 0
            LOCATE OldCurRow%, OldCurCol%, 1, 0, 4     'Restore cursor position


        END IF

        OldByte(Pt%) = Byte(Pt%)

    NEXT Pt%


END SUB

SUB ToggleBit (PortNum$)


        SELECT CASE POS(0)    'Determine which output you will write to.
            CASE IS = 8
                Pt% = 0
            CASE IS = 57
                Pt% = 2
        END SELECT

        IF Bit(Pt%, 18 - CSRLIN) > 0 THEN        'Toggle sigle bit.
            Bit(Pt%, 18 - CSRLIN) = 0
            ELSE
            Bit(Pt%, 18 - CSRLIN) = 1
        END IF


        Byte(Pt%) = 0
        FOR i = 0 TO 7
            Byte(Pt%) = Byte(Pt%) + (Bit(Pt%, i) * 2 ^ i)
        NEXT i

        OUT (Port(VAL(PortNum$)) + Pt%), Byte(Pt%)

END SUB
