›› The 8-Bit Parallel Interface››› This is a spin-off from the various articles I've read describing parallel interfaces that use two of the joystick ports on Atari computers. All the interfaces I've seen allow only 7 bits of data, using the remaining PIA (the 6520 Peripheral Interface Adapter) bit for handshaking. This is also true of Paul Swanson's printer interface article (Analog Computing issue 16).› For those of you who need a full 8-bit interface, here's a simple hardware project that'll give you almost full blown parallel interface, with eight data lines and 4 handshaking lines. I'm not going into the various ways in which such an interface can be used, but I've worked out an almost complete IEEE-488 interface and also use it for a ham radio telephone patch controller. Intrigued? Read on...›› How It Works›› The basic idea is very simple. the PIA chip has two 8-bit ports, PORTA (port A) and PORTB (port B), assessiable though the computer's operating system (OS). The joystick ports are connected to PORTA on the PIA chip, and 8 bits of PORTA are split up into 4 bits each for the two joystick ports.› The older 400/800 machines used all 16 bits on the PIA ports, split up among four joystick ports. However we'll confine our discussion to PORTA only, in order to keep it valid for the XL/XE series of computers.› Each of the joystick ports has an input-only line that normally comes from the trigger on the joystick. These lines don't go to the PIA, but head elsewhere in the machine. Because any handshaking protocol must involve outgoing control lines, it's clear that some of the 8 PIA bits must be reserved for this purpose.› This means that, for any 8-bit data transfer, all 8 bits cannot go out of the PIA port at the same time. Fortunately, they don't have to. an 8-bit word can be split up into two 4-bit nibbles, which can be sent out one at a time though one half the PIA port.› The other half can be used to suitably latch the two halves, so that the final output is a full 8-bit word. The latching needs only 2 of the 4 remaining bits of PORTA, leaving the other 2 bits free for outgoing handshaking signals. (Actually, 1 bit is sufficient for the latching, but using 2 is slightly better). The two trigger inputs can be used for incoming signals, giving an 8 bit data bus with a 4-bit control bus.› Two 74LS75 4-bit latches are used to store the two halves of the 8-bit word as they come out of the joystick port 1 (PIA PORTA bits 0-3). Bits 4 and 5 of PORTA, available at joystick port 2, are used to alternately enable the latches to store the data, and bits 6 and 7 are available for handshaking.››› ›  1 2 3 4 5 ›Joystick port  ›Pin assignment  6 7 8 9 › ››› 1-4 Data (PIA PORTA)› 5 Ignore (no connection)› 6 Trigger input› 7 +5V (ignore)› 8 Ground› 9 Ignore››››Circuit Parts List:››IC1: 74LS244 Octal noninverting buffer› pin 20 Vcc (+5V), Pin 10 ground››IC2: 74LS75 Quad F Flipflops› Pin 5 Vcc (+5V), pin 12 ground››› Circuit schematic and pin connections››››Joystick› Port 1› pins›  (LSB)›   › 1 | Éñ | | Éò |b0 › o2 182 16o › 2 | | || |b1 › o4 16|3 15o › 3 | | | || |b2 › o6 14||6 10o › 4 | | | | || |b3 › o8 12|||7 9o › 1 | | | | | || 4 13 | ›P 11 9|||| ›O 2 | | | | || ›R 13 7| | | | ›T 3 | | || | | || Éó |b4 › 15 5|| | | 2 16o ›2 4 | | ||| | | | |b5 › 17 3||| | 3 15o › | 1 19 ||||| | | |b6 › |||| 6 10o › o |||| | |b7 › port 2 | |||7 9o › pin 8  ||| | 4 13 | › GND |||  › || (MSB)› || › |> DAV › | › > SIGNAL› › › Port 1 << Input 1› Pin 6 › › Port 2 << Input 2› Pin 6 ›››› A 74LS244 octal buffer is used to buffer the otputs of the joystic ports. the 74LS244 may use up quite a bit of current, so it's not advisable to use 5V available at the joystick ports (pin®7). the current capacity there is only 50ma, and my prove bothersome if you have something else on the serial bus that draws power form the computer (eg; P:R: Connection).› It's quite simple to rig up a +5V regulated power supply, using a 7805 and just about any 9 or 12 volt adapter. one of those old cassette recorder adapters that you usually find lying around wil do very nicely. A couple of decoupling capacitors should be used - as a general rule.› ››› Power supply schematic››› 117 Éô Vcc › VAC T1 D1 9-12VDC  +5V ›  >o----o1 3o › | | | | | | 2 | | › o 8||8 | |  | › 8||8 | | | | › 8||8 ’C1 ’C2 | ’C3 › o 8||8 | | | | › | | | | | | | ›  o----o › |  ›  GND› GND›› Éô ›  › Heatsink-->| o | ›  › |7805 | › | | ›  › | | | › 1 2 3 › ›› IC4: 7805 5-V Regultor (TO5 package)› T1: Power Supply transformer› 117 VAC primary› 9 VAC secondary, @200ma› D1: IN4005 diode› C1: 100 MF 25V electrolytic capacitor› C2: .01 MF disk capacitor› C3: 25 MF 16V electrolytic capacitor››› Programming the interface››› We now come to the interesting part of the story: making the interface work. As you've probably gathered from the above discussion, some bit manipulation is required to do the job. This leads to one immediate problem, namely that BASIC by itself just won't do. (As it turns out, BASIC is too slow for most purposes, anyways, so it doesn't really matter.)› Assembly language is, of course, the best, but in the interest of general sanity I've gone through an example below, describing with words and figures the various steps that need to be followed.› Being a covert to Action!, The following program example will be in Action! containing a couple of Action! procedures that will do the job. (BTW If you ever dissassebled a compiled Action! program, the compiled code is very neat and straight forward. As oppossed to other compilers, the code reasembles spegatti). Well back to the topic. Between the these examples you ought to get the general picture well enough to program the interface any way you want to. That, believe me, is where half the fun lies.› The first step is to set uo PORTA for output. The port is set up by OS during initialization, so your program will have to reconfigure it. This can be done very simply, as follows:›› (1) POKE $38 into register PACTL at $D302.› (2) POKE $FF into register PORTA at $D300.› (3) POKE $3C into register PACTL at $D302.›› At This stage, PORTA is ready for output, and any byte put into it will appear at the joystick ports. Now, let's see how to break up a byte and latch it's two halves separately.› As shown below, the four Least Significant Bits (LSBs) of PIA PORTA (address $D300) appear at pins 1-4 of joystick 1. The four MOST Significant Bits (MSBs) appear at pins 1-4 of joystick port . As you can see, bits 0-3 are used for the data, bit 4 to latch the LSBs, bit 5 to latch the MSBs, bit 6 as DAtaValid signal, and bit 7 as another output signal.››› PORTA› | | › Joystick Joystick › b7 Signalout › b6 DAta Valid (DAV) › b5 Latch MSBs › Port 2 b4 Latch LSBs Port 1|›  ›  › b7 b6 b5 b4 |b3 b2 b1 b0|› ››› b3 ›  › b2  › DATA nibble› b1  ›  › b0 ›››› Accordingly, these bits have to be manipulated to do the required actions. In the discussion that follows, AND and OR operations described are strictly bit-wise operastions. The figures show the state of the output byte as a various operations are performed.› Assume the data byte to be output is:›› (MSB) d7 d6 d5 d4 d3 d2 d1 d0 (LSB)›› (1) Assume a working byte VAR. All surgery will be done on this byte.› (2) Copy the data byte into VAR and AND it with $0F.›› 0 0 0 0 d3 d2 d1 d0›› (3) OR VAR wit $20 to put a 0 in bit 4 and a 1 in bit 5, thus enabling the LSB latch and disabling the MSB latch. Note that these latches work on an active low. Note also that the DAv bit, bit 6 is 0.›› 0 0 1 0 d3 d2 d1 d0›› (4) POKE VAR into PORTA; this will latch the LSBs.› (5) OR VAR with $30 and POKE into PORTA. This disables the LSB latch, while keeping the LSB bits the same. We do this because it's disirable NOT to change the data outputs while disabling the latch.›› 0 0 1 1 d3 d2 d1 d0›› (6)Copy the data byte into VAR again and do four right shifts on VAR, to get the MSBs of the dta byte into the LSB positions of VAR.› 0 0 0 0 d7 d6 d5 d4›› (7) AND VAR with $0F. Then OR VAR with $10, to set bit 5=0, and enable MSB latch. Bit 4 =1, so the LSB latch is disabled. POKE VAR into PORTA. this latches the MSBs.›› 0 0 0 1 d7 d6 d5 d4›› (8) OR VAr with $70 to keep MSBs intact, then set bits 4 and 5 to 1 to disable both latches. Bit 6 is set to 1 tell whatever's sitting on the interface bus the data is now valid.› Now, if the signal on the outgoing control line, bit 7, is to be 0 POKE VAR into PORTA. If the signl is to be a 1, OR VAR with $80, then POKE VAR into PORTA.›› 0 1 1 1 d7 d6 d5 d4›› To read incoming signals, youhave to know that they're coming into pin 6 (the trigger input pins) on each joystick port. Therefore, all you have to do is the equivalent of a BASIC STRIG function.› The trigger values are available in memory locations $D010 (53264 and $D011 (53265) for joystick ports 1 and 2, respectively. The values will be: 1 if a high signal is preseant. No special stuff here, just a starightforward read on the locations will tell you the logic level of the incoming signal.› That's all there is to it. Simple, isn't it? Incidently, it's a fairly straightforward matter to build this right inot Paul Swanson's printer inerface software, to get an 8-bit printer interface. the addition of a few lines of machine code should do the trick. (Hint: all you really need to modify is the PUTBYTE subroutine.)› Well, I hope that's all thats necesary. this isn't a very big project, so extensive construction details aren't really needed. i built the interface (along with some other stuff) on a breadboard, never got around to make a printed circuit board (PCB) for it YET...›››››› Action! listing›› PROC Configure( BYTE inout)› ;sets PORTA for output if› ;inout=$255, for input if› ;inout=$0›› Poke(54018,56)› Poke(54016,inout)› Poke(54018,60)› RETURN›› PROC OutByte( BYTE data, outsignal)› ;puts out 'data' byte› ;puts DAtaValid on PORTA› ;bit 7 & 'outsignal' on› ;PORTA bit 8 when both› ;nibbles have been latched› ;outsignal must =0 for LO› ; or =128 for HI›› BYTE var› CARD port=[54016]› ;latching LSBs› var=data&$0F› var==%$20› Poke(porta,var)› ;PrintF("%H%E",var)› var==%$30› Poke(porta,var› ;PrintF("%H$E",var)› ;tackling MSBs now› var=data RSH 4› var==%$10› Poke(porta,var)› ;Printf("%H%E",var)› var==%$70› var==%outsignal› Poke(porta,var› ;PrintF("%H%E",var)› RETURN›› PROC main()› BYTE data,outsignal=[128],END=[0]›› WHILE END=0› DO› Put('?):data=InputB()› OutByte(data,outsignal)› OD› RETURN›› ;NOTE: PROC main & the PrintF's in› ; PROC OutByte can be used to› ; follow thw workings of the› ; PROC. Just remove the ':'s› ; from the PrintF statements.››››››