Path: utzoo!utgpu!water!watmath!watdragon!trillium!swklassen From: swklassen@trillium.waterloo.edu (Steven W. Klassen) Newsgroups: comp.sys.atari.8bit Subject: Re: Linking two computers Message-ID: <5240@watdragon.waterloo.edu> Date: 19 Feb 88 15:42:41 GMT References: <578NU109703@NDSUVM1> Sender: daemon@watdragon.waterloo.edu Reply-To: swklassen@trillium.waterloo.edu (Steven W. Klassen) Organization: U. of Waterloo, Ontario Lines: 253 > I would like to be able to hook up two atari computers for interactive games, > etc. that require that you do not see the screen of the other person. > > My brother and I both have Atari 800XL's with parallel ports. I was wondering > if I could buy a parallel-to-parallel cord to use for data transmissions, > (for a game of battleships, for example). I sent a solution to a similar problem to someone on the bit-net quite awhile ago. This time I guess I will make it public (perhaps there are others out there who are interested). Although this solution isn't exactly what you asked for (I have no info on Atari XL parallel ports [unless of course you're referring to the expansion slot on the back]) it may be useful to you. The joystick ports on the Atari 8-bits can be configured for output as well as for input. This will rule out joysticks (except on the old 400/800s) but will allow you to communicate between your computers. STEP #1 - THE HARDWARE This is the easy part. All you need are two joystick extension cords and two nine-pin joystick plugs, all available at your local Radio Shack. Cut the cords at the end in which you would normally plug your joystick (not the end which plugs into the computer) and strip the green, yellow, orange, red and grey wires enough so you will be able to solder them onto the plugs. The other wires are not needed so you might want to cut them a little shorter just to keep them out of the way. Solder both cords as shown below: PIN JACK 1 JACK 2 WIRE 1 data 0 data 4 Green 2 data 1 data 5 Yellow 3 data 2 data 6 Orange 4 data 3 data 7 Red 8 ground ground Grey To test the interface, plug it into both computers (the one in port 1 of one computer should also be in port 1 of the other computer), turn them on and try the following test: On one computer type POKE 54018,56:POKE 54016,0: POKE 54018,60:FOR N=0 TO 0 STEP 0:? PEEK(54016):NEXT N. On the other computer type POKE 54018,56:POKE 54016,255:POKE 54018,60. Now, still on the second computer POKE 54016 with any value from 0 to 255 and the same value should appear on the screen of the first computer. If not, something has been done wrong (check your wiring). STEP #2 - THE SOFTWARE In order to make practical use of the interface, you need to write a driver. Following is one that I have written (WARNING! This is a BARE-BONES driver with ALMOST NO error checking! You will want to spruce things up a bit before you trust it with anything substantial.) The program will install the driver in memory and then change LOMEM in order to protect it. This wastes all the memory between the initial position of LOMEM and the start of the program so you will want to change things (ie. make it relocatable and automatically loading above LOMEM) to overcome this. [Note that my program was written a couple of years ago as an experiment - it was never intended to be a comprehensive driver - still, it does illustrate the basics of what is required in a driver.] Once the driver is installed properly, you can communicate between the two computers using the normal OPEN,CLOSE,PUT,GET,READ,etc. commands specifying the 'X:' device. I have tested this in BASIC but have not had a chance to do so with C or Action! (I no longer have two Ataris). It should, however, work with any program or language which sticks to Ataris standard I/O procedures. For more information see _Mapping_the_Atari_. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Using the "X:" device to ; communicate between two Ataris. ; by Steven W. Klassen ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ** Equates .OPT OBJ, NO EJECT HATABS = $031A START = $3000 ; change to suit memory. MEMLO = $02E7 ICAX1Z = $2A PACTL = $D302 PORTA = $D300 *= START TEMP *= *+2 ; ; Installation routine ; LOADIT LDX #0 ; start of table SEARCH LDA HATABS,X ; check symbol BEQ FOUNDONE ; found empty CMP #'X ; already there? BEQ ALREADYTHERE ; yes! INX ; skip 3 to point INX ; to the next INX ; entry BNE SEARCH ; keep looking! RTS ; something wrong! ; end of table--extend it FOUNDONE LDA #'X ; put in name X: STA HATABS,X LDA # DRIVER ; MSB of driver STA HATABS+2,X LDA #0 ; new table end STA HATABS+3,X ; change LOMEM CHNGLOMEM LDA # DRIVEREND ; MSB of top STA MEMLO+1 RTS ; all done! ; ; BASIC entry point ALREADYTHERE JMP CHNGLOMEM ; ; and here is the driver! ; DRIVER .WORD XOPEN-1 ; driver... .WORD XCLOSE-1 ; routine... .WORD XGET-1 ; address... .WORD XPUT-1 ; table. .WORD XSTATUS-1 .WORD XXIO-1 SUCCESS LDY #1 ; keep good status RTS ; bye! ERROR LDY #$92 ; func not allowed RTS ; bye! ; XOPEN LDA ICAX1Z ; type of open CMP #8 ; write? BEQ WRITE ; yes! CMP #4 ; not write-read? BNE ERROR ; no--something wrong! LDA #$38 ; set for read STA PACTL LDA #$A0 ; bin--1010 0000 STA PORTA LDA #$3C STA PACTL LDA #$00 ; set porta... STA PORTA ; to 0 JMP SUCCESS ; done! WRITE LDA #$38 ; set for write STA PACTL LDA #$5F ; bin--0101 1111 STA PORTA LDA #$3C STA PACTL LDA #$00 ; set porta... STA PORTA ; to 0 JMP SUCCESS ; done! ; XCLOSE LDA #$38 ; return port A STA PACTL ; to input for LDA #$00 ; the joysticks STA PORTA LDA #$3C STA PACTL JMP SUCCESS ; done! ; XGET LDA PORTA ; check for ready AND #16 ; bin-0001 0000 BEQ XGET ; not ready yet LDA PORTA ; get four bits AND #15 ; bin-0000 1111 STA TEMP ; store 4 bits LOOP1 LDA #32 ; bin-0010 0000 STA PORTA ; ask for more LDA PORTA ; check for ready AND #$40 ; bin-0100 0000 BEQ LOOP1 ; not there yet LDA PORTA ; get 4 bits AND #15 ; bin-0000 1111 ASL A ; move right 4 ASL A ; bits to the ASL A ; left 4 ASL A AND #240 ; just be sure! ORA TEMP ; put the two together! STA TEMP ; store in TEMP LDA #$80 ; bin-1000 0000 STA PORTA ; thank you! LDX #25 ; slight pause LOOP2 DEX BNE LOOP2 LDA #$00 ; clear porta STA PORTA LDA TEMP ; put num in accumulator JMP SUCCESS ; all done ; XPUT STA TEMP ; save byte AND #15 ; bin-0000 1111 ORA #16 ; bin-0001 0000 (ready) STA PORTA ; send 1st 4 bits LOOP3 LDA PORTA ; acknowledge? AND #32 ; bin-0010 0000 BEQ LOOP3 ; no! LDA TEMP ; yes-load original LSR A ; shift left 4 LSR A ; bits to the LSR A ; right LSR A AND #15 ; bin-0000 1111 (just making sure) ORA #$40 ; bin-0100 0000 (ready flag) STA PORTA ; send last 4 bits LOOP4 LDA PORTA ; acknowledge? AND #$80 ; bin-1000 0000 BEQ LOOP4 ; no-try again LDA #$00 ; yes! turn off ready flag STA PORTA ; turn off ready JMP SUCCESS ; we're done ; XSTATUS ; unimplemented options XXIO JMP ERROR ; DRIVEREND = *+$FF&$FF00 .END I hope that all this helps. > ...I would probably send in the results to a magazine like Antic or > Compute... Good luck! When I sent it to ANALOG two years ago they sent it back to me saying something about a lack of reader interest in the subject. (I guess they think we're only interested in games :-) S. W. Klassen Computer Science Major University of Waterloo