8255(DOCS)              Optical Printer Control System          8255(DOCS)

NAME
    8255 - how to control 8255 based digital I/O cards

8255 PORTS
    The 8255 family of chips (82C55, etc) are usually one chip
    solutions to getting 24 bits of programmable digital I/O.

    Typically, the chip is configured at a base I/O address, 
    such as 0310. 
    
    There are four ports (base+0, base+1, base+2 and base+3)
    that are used to control the chip:

        base+0    - PORT #A
        base+1    - PORT #B
        base+2    - PORT #C
        base+3    - CONTROL REGISTER

8255 PROGRAMMING
    The "control register" controls the I/O direction of the 3 ports,
    and breaks out as follows:

        Bit   Description
        ---   --------------------------------------------------
         0    Port C (low 4 bits): 1=input, 0=output
         1    Port B (all 8 bits): 1=input, 0=output
         2    Mode selection: 0=MODE#0, 1=MODE#1
         3    Port C (hi 4 bits): 1=input, 0=output
         4    Port A (all 8 bits): 1=input, 0=output
            _
         5   |_ 00 = MODE#0 (basic I/O)
         6  _|  01 = MODE#1 (strobed I/O)
                1x = MODE#2 (bidirectional bus)

         7    Mode set flag (1=active, 0=normal)

    No initialization is required to achieve 24 bits of input, which
    is the default; during reset, all ports are programmed to be inputs. 

    The control register must be programmed before doing any I/O
    with the three ports A,B and C. Example values for the
    Control Register:

                0x80    - A,B,C outputs
                0x9b    - A,B,C inputs
                0x92    - A+B input, C=output

8255 PROGRAMMING EXAMPLES
    Here's a C programming example that shows how to setup the 8255
    such that A+B are inputs, and C is outputs:

        /* INITIALIZATION */
        base = 0x310;
        out(base+3), 0x92;      /* A+B=in, C=out */
        /* READ/WRITE */
        if ( inp(base+0) & 0x01 )         /* read A */
            printf("Bit #1 set on port A\n");
        else
            printf("Bit #1 clear on port A\n");
        /* SET PORT C, BIT #1 */
        out(base+2, inp(base+2) | 0x01 ); /* write C */

   This example shows similar 8255 programming example
   in the OPCS system's HOMEDEFS.HOM file, used by the HOME program:

        # homedefs.hom
        start init_8255
        {
            # INITIALIZATION
            outport 0313 92        # A+B=in, C=out

            # READ/WRITE
            portset? 0310 01       # test if bit 1 set on Port A
            {
                print "Bit #1 set on Port A"
            }
            portclr? 0310 01       # test if bit 1 clear on Port A
            {
                print "Bit #1 clear on Port A"
            }

            # SET PORT C, BIT #1
            setbit 0312 01
        }
        end init_8255

8255 CHIP PINOUT
    The 82C55A is most commonly found in a 40 pin DIP.

                          82C55A
                         Top View
                       _____  _____
                      |     \/     |
                PA3  [| 1       40 |]  PA4
                PA2  [| 2       39 |]  PA5
                PA1  [| 3       38 |]  PA6
                PA0  [| 4       37 |]  PA7
                 RD  [| 5       36 |]  WR
                 CS  [| 6       35 |]  RESET
                GND  [| 7       34 |]  D0
                 A1  [| 8       33 |]  D1
                 A0  [| 9       32 |]  D2
                PC7  [| 10      31 |]  D3
                PC6  [| 11      30 |]  D4
                PC5  [| 12      29 |]  D5
                PC4  [| 13      28 |]  D6
                PC0  [| 14      27 |]  D7
                PC1  [| 15      26 |]  VCC
                PC2  [| 16      25 |]  PB7
                PC3  [| 17      24 |]  PB6
                PB0  [| 18      23 |]  PB5
                PB1  [| 19      22 |]  PB4
                PB2  [| 20      21 |]  PB3
                      |____________|

8255 PORT MONITOR PROGRAM
    The OPCS software comes with 8255.exe which can monitor the
    real time status of the 8255's I/O ports. 

    Run '8255.exe' with the hex base address as the first argument:

        C:\OPCS\WORK> 8255.EXE 0310
                      -------- ----
                          |     |
                          |     Base address argument
                          |
                          Runs the 8255 program, usually in
                          the \OPCS\BIN directory.

    This tool can be downloaded from https://seriss.com/opcs/ftp/
    and the source code on githib at https://github.com/erco77/8255-dos/

CONTROL REGISTER: BASE+3
------------------------
    The control register is a single 8 bit port whose byte defines the
    I/O direction of all three 8 bit I/O ports A,B,C, and the mode for
    that I/O, modes 0,1 and 2 are supported by the 8255 chips.

    The control register for each 8255 should be programmed on boot
    or OPCS startup to define whether ports A, B and C are inputs
    or outputs.

    Initializing the control register can be done using the "home"
    program, creating a special entry in the HOMEDEFS.HOM file
    to initialize the port (see example below), and then invoking
    "home 8255_init" during the AUTOEXEC.BAT or via the OPCSDEFS.OPC
    setup file that's run when OPCS starts.

    Example 8255 init using HOMEDEFS.HOM, where the base address
    for the 8255 is 0200:

        1. Create a new entry called 'init_8255' in the HOMEDEFS.HOM file:

           # Initialize the 8255 CIO/DIO board
           start init_8255
           {
                    outport 0203 9b    # program the 8255 Control Register
           }
           end init_8255

           Replace 0203 with the base address+3 of your 8255 board, 
           and replace '9b' with the Control Register value appropriate
           for your setup, as it defines which ports are input vs. output. 

           See the table below "Control Register - "Mode 0" Operation"
           for a list of all the possible I/O configuration control
           register values.

        2. Create an entry in either the AUTOEXEC.BAT file, or the batch
           file you use to start OPCS, using:

                home init_8255

           ..which programs the 8255's control register based on the
           above HOMEDEFS.HOM file entry.

    Note that individual bits can NOT BE programmed separately;

        > Port A can be programmed to either be "all in" or "all out"
        > Same for Port B
        > Port C, the LOWER and UPPER 4 bits can be controlled
          separately for Input or Output.

    I strongly suggest referring to the 8255 and/or 82C55 data sheets
    for authoritative information about how to program the 8255 for
    I/O. Secondarily the manual for the CIO-DIO48 ISA card.

    What follows below is my reduction of those docs. (erco@seriss.com)

Control Register - "Mode 0" Operation
-------------------------------------
    This document ONLY covers "Mode 0" of the 8255, which is simple
    "real time I/O" for all ports. Mode 1 (Strobed I/O) and Mode 2
    (Bi-Directional Bus) are not covered here. For more info on those
    features, refer to the 8255 data sheet.

                 Group A      Group B
                 I/O Ctrl     I/O Ctrl
                 ______       _____
                /      \     /     \
     _______________________________________________________________________
    |   |   |   | GROUP |   | GROUP |   GROUP A       |   GROUP B       |   |
    |MS |M3 |M2 |   A   |M1 |   B   |_________________|_________________|   |
    |___|___|___|_______|___|_______|      |          |      |          |Ctl|
    |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 |PORT A|PORT C(HI)|PORT B|PORT C(LO)|Reg|
    |---|---|---|---|---|---|---|---|------|----------|------|----------|---|
    | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | OUT  |  OUT     | OUT  |  OUT     |80 |
    | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | OUT  |  OUT     | OUT  |  In      |81 |
    | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | OUT  |  OUT     |  In  |  OUT     |82 |
    | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | OUT  |  OUT     |  In  |  In      |83 |
    | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | OUT  |   In     | OUT  |  OUT     |88 |
    | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | OUT  |   In     | OUT  |  In      |89 |
    | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | OUT  |   In     |  In  |  OUT     |8A |
    | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | OUT  |   In     |  In  |  In      |8B |
    | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |  In  |  OUT     | OUT  |  OUT     |90 |
    | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |  In  |  OUT     | OUT  |  In      |91 |
    | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 |  In  |  OUT     |  In  |  OUT     |92 |
    | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 |  In  |  OUT     |  In  |  In      |93 |
    | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |  In  |   In     | OUT  |  OUT     |98 |
    | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |  In  |   In     | OUT  |  In      |99 |
    | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |  In  |   In     |  In  |  OUT     |9A |
    | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |  In  |   In     |  In  |  In      |9B |
     -----------------------------------------------------------------------
     /|\ /|\ /|\         /|\
      |   |   |           |
      |   |   |           All zeroes (for "Mode 0")
      |   |   All zeroes (for "Mode 0")
      |   All zeroes (for "Mode 0")
      All ones (for "Mode 0")
   
      MS = Mode Set bit (hi bit of control register), must be 1 for "Mode 0"
      M3,M2,M1 = must all be 0 for "Mode 0".


    Here are all the possible 8 bit Control Register values (in HEX) to
    program Ports A,B,C in "Mode 0" for all possible Input/Output combinations:

      Control Register           (HI 4)            (LO 4)
         Value (hex)    PORT A   PORT C   PORT B   PORT C
      ----------------  -------  -------  -------  -------
             80          Out     Out       Out     Out  <- Port A,B,C=Out
             81          Out     Out       Out     In
             82          Out     Out       In      Out
             83          Out     Out       In      In
             88          Out     In        Out     Out
             89          Out     In        Out     In
             8A          Out     In        In      Out
             8B          Out     In        In      In
             90          In      Out       Out     Out
             91          In      Out       Out     In
             92          In      Out       In      Out   <- Port A,B=In, C=Out
             93          In      Out       In      In
             98          In      In        Out     Out
             99          In      In        Out     In
             9A          In      In        In      Out
             9B          In      In        In      In    <- Port A,B,C=In

    (The above table is from the CIO-DIO48 ISA board manual for the 82C55)

    Put simply, the bit mask for the control register I/O control for Mode 0
    for ports A,B,C is:

        Data Bit  Mask  Description
        --------  ----  -----------
           D0     01h   Port C(LO)
           D1     02h   Port B
           D3     08h   Port C(HI)
           D4     10h   Port A

        NOTE: "D2" bit is skipped because it's the M1 mode bit

    So if the base address is 0310, one can program ports A,B and C
    of the first 24 bits of I/O to all be inputs using the C code: 

        outp(0x0313, 0x9b);         // Program ports A,B,C to be inputs

    And to read the input bits for ports A,B,C:

        int a_bits = inp(0x0310);   // Read PORT A bits
        int b_bits = inp(0x0311);   // Read PORT B bits
        int c_bits = inp(0x0312);   // Read PORT C bits

    The same can be done for the second 24 bits of I/O, by simply adding 4
    to all the addresses above, e.g.

        outp(0x0317, 0x9b);         // Program 8255#2 ports A,B,C to be inputs
        int a_bits = inp(0x0314);   // Read second 8255 PORT A bits
        int b_bits = inp(0x0315);   // Read second 8255 PORT B bits
        int c_bits = inp(0x0316);   // Read second 8255 PORT C bits

    Similarly, if ports are programmed to be outputs, you can WRITE bits
    to ports A,B,C using outp() instead of inp().

    NOTE: According to the 8255 data sheet, the Control Register can ONLY be
          written to, and not read! In practice I've noticed 82C55 chips
          let you read the Control Register and see the last value set.

          The 8255.EXE program by default reads the Control Register
          to see how to present the I/O data, unless the user specified
          the Control Register value byte as the optional argument
          after the base address, e.g.

              8255.EXE 0310 9b
              -------- ---- --
                  |     |   |
                  |     |   Control Register value optional argument
                  |     |
                  |     Base address optional argument
                  |
                  Runs the 8255 program, usually in
                  the \OPCS\BIN directory.

SEE ALSO
    CIODIO24(DOCS) - Docs on the 8255 based 24 channel Digital I/O card
    CIODIO48(DOCS) - Docs on the 8255 based 48 channel Digital I/O card

ORIGIN
    Gregory Ercolano, Topanga, California 04/12/00
© Copyright 1997 Greg Ercolano. All rights reserved.