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