Using the Bar Code Reader on the PX-8 Introduction Bar code input on the PX-8 occurs at the standard bar code 3-pin plug connector while using any normal bar reader wand. The architecture and addressing scheme of the PX-8 interface is different from the HX-20, which uses the 6301 internal timer logic to capture bar code input. While there is a 6301 slave CPU in the PX-8, it is not used for PX-8 bar code operations. Instead, separate timer logic has been designed external to the PX-8 CPU chips, to perform the same basic function as the HX-20 6301 timer. Consequently, any existing HX-20 assembly code driver would be unusable for this reason alone, not to mention the obvious fact that the HX-20 runs 6301 code while the PX-8 requires Z80 code. Since this is the first exposure to PX-8 hardware for almost everyone, the following discussion of bar code is meant to be a guideline only, and does not represent the final, authoritative word on how to write bar code software for this machine. Bar code interface architecture The theory of operation of the bar code interface is basically this: A 16- bit Free Running Counter (FRC), similar to the one inside the 6301 CPU, is driven by a 614 kHz clock (1.6 us period). Its output is applied to a 16- bit Input Capture Register (ICR) comprised of two 8-bit (low and high byte) addressable registers ICRL and ICRH. The current value of the FRC is latched in the ICR by any enabled bar code data edge. Hence, as the wand scans across a bar symbol, each bar's leading and trailing edge will latch a count in the ICR, that can then be read directly and interpreted by the bar code driver software. The signal to the software that an edge has been detected, and therefore a count latched, is provided by the Input Capture Flag (ICF) bit, which is set simultaneously with the latching of the ICR. This ICF bit is sensed by polling or interrupt handling, and is immediately reset by the ICRH-B read operation that follows. (Note: ICRH-B refers to I/O port 03H, the Input Capture High Byte bar code Trigger Register and should not be confused with ICRH-C port 01H, the Input Capture Register High Byte Command Trigger.) When the 16-bit FRC reaches 0000H, the Overflow Flag (OVF) is set to signal the end of a 64K count. The driver software also senses for this bit through polling or interrupt handling and resets the flag with a WRITE operation to port 01H (Command Register) to set bit 2 (the RES OVF bit). After power up, the OVF and ICF bits are in an indeterminant state and must be initialized to the reset condition before reading any bar code. Software operations The following discussion illustrates the I/O protocol required in communicating with the bar code I/F. All the registers that are directly related to bar code input capture are accessed with I/O instructions, in contrast to the memory mapped I/O of the HX-20. One such register is control register 1. It is a write only register that controls the power to the bar code port, enables input data edge triggering, switches memory banks, and sets baud rates. Its I/O port address is 00H. Example: LD A,0FH ;Bit 3 puts bar code power on. Bits 2 & 1 enable ; rising and falling edge detect. Bit 0 enables Bank 1. OUT (00H),A ;write to port 0, Control Register 1. The status register at port 5 is a read only register that has 4 bits of information (0 to 3 bits) regarding machine status. Bit 1 indicates the level of the data signal (BRDT) input from the bar code reader. The other three bits don't relate to bar code. The BRDT bit is therefore usable as a means of monitoring the particular bar type (black bar or white space) that is being read. Since most bar readers have an open-collector output, a black bar or an "off-the-paper" condition will produce a TTL high (+5v) output reading. The white margin before a bar code symbol will normally produce a low (0v) reading. However, in the PX-8, this input logic level is inverted at the status register to produce a binary 1 state for a white input and a binary 0 for a black input. BRDT polling therefore can be used to indicate the white "quiescent" state before actual bar code scanning can be validly performed. After identification of the white margin, the edge triggering bits 1 and 2 of port 0 can be enabled, and reader scanning can proceed with automatic edge activated latching of the FRC count into the ICR. Example: WMAR: LD B,80H ;arbitrary count down value for a white margin WMLOOP: ;white margin loop IN A,(05H) ;get status BIT 1,A ;test for high input indicating a white margin JP Z,WMAR ;if low, then no white input detected yet. DJNZ WMLOOP ;if on white, then decrement the B reg and loop ; until 0 JP MAIN ;satisfied that we're on white margin, proceed ; with scanning. The Interrupt Enable Register (IER) at port 4 is used to enable or disable (mask or unmask) the six major interrupt sources. Sending an all 0 output to this register will disable all interrupts. Port 4 also allows the reading of the interrupt status. The six interrupt status bits, 0 to 5, can be read even if interrupts had been masked by an earlier port 4 write. The ICF (bit 3) and OVF (bit 4) are polled here during bar code operations. It is much easier to keep interrupts disabled during bar code ops, since software to handle the usual interrupts, along with ICF and OVF interrupts, introduces the problem of learning what the operating system is doing with the 7508 CPU clock interrupts and the serial port interrupts. (It was discovered that the 7508 and serial chip interrupts cause bank switching to occur, thereby inadvertently turning off bar code port power, since the power bit is in the same register as the bank bit. This problem can be overcome by modifying certain operatins system memory locations. But now you need operating system source listings.) Example: LD A,0 OUT (04H),A ;disable all interrupts during bar code ops LOOP: ;edge detection polling loop IN A,(04H) ;read the interrupt status register BIT 4,A ;test for OVF from the FRC JP NZ,OVFSUB ;if OVF bit set, jump to overflow subroutine BIT 3,A ;test for ICF JP Z,LOOP ;if ICF received, detected bar edge, continue MAIN: ; with main program The 16-bit ICR itself is a read only type accessed by four different ports. Ports 0 and 1 are used for reading the FRC value at any time desired by the software. The ICRL-C (low byte read command) directed to port 0 latches in the full 16-bit FRC count in ICR, and then reads the LS byte of ICR. The subsequent ICRH-C read through port 1 inputs the MS byte of ICR. Ports 2 and 3, however, are dedicated to the reading of the FRC count after a bar code edge has previously latched the FRC count in ICR. The ICRL-B (low byte bar code read) is directed to port 2. The ICRH-B (high byte bar code read) is directed to port 3 and performs the necessary extra function of reseting the ICF. Example: IN A,(02H) ;ICRL-B read LD (CNT),A ;save low byte in CNT location IN A,(03H) ;ICRH-B read. Resets ICF also. LD (CNT+1),A ;save high byte A discussion of a sample PX-8 bar code driver program in Z80 code is continued in a document on the Epson BBS named MBRCD.DOC; its companion listing, MBRCD.MAC, is also available on the BBS.