,@Ld;  Y c$% l0$@0)$$Hȱ$ YhL `e$$%`$%`  !IZP@R1!0 #      qL I`@LL,늦% uL' u ! @@) H$H 0} h?`   `LY0- HH > ?@ > 0 h 0: < =;Ң79x 608:23 44 R 234, R 8 ,P ҥ X0ɀ7Ф`d LY# N 21 4 2 - Lc 1 - ) 000 0 1  2 4  16` L <  A CE0& 'L\䩏,,09$806LL e1i1`00) ߍ ^ ҍ ) `H) 000 ^ h `ҍ ҩ(ҩҩ` $GȘLY )L  A cL6GȘ L1L )V>Y  3 HHJH h c hyhy  -L> LL $@0JJ HJJJ$@Jh)$@0) L} $ ' U L )LOJJ[Lw!,"!c@F OL1 `QH  .h _ H^ H`dJ !0 0E | E E|7EȩE|dE/EȩE - Q  0L     H  ? 7? ( 0   `   gLLG    0  g -L * H    cE` ,9 )   gL) '0BML  LML k N 'L 'NLML Kd $@бEqEHȱE$@qEh   !GLL6GɛL g AL SECTORS  ` xL H) *Gȩ GȽG GȌ h%*J >G }E X, dE` E }8 X 8,N EiFi(0 FEh    r L 'd$@0dEE`H)h3H^ji hEEd$@0EiEȱEiE`!H!I莢!ʽEF5|I  'ȘHjmGhmL, ' Cȩ8 lI0 L4&$/@<?8к c?$@ l $ɞ% Lݱ I(`DOS SYS0I L1x ) DJJ DD)D`LLl LOL 'L Ll !GH~ h )IȌ I C 8L J x (` @  L ` xBd v"  BLV J x0L DHEhDELL H  4h`H 获xI``HH` $@0 `2 DJf2)? @3 )D*,D* CD( C22C ԠX`D1:AUTORUN.SYS n 1?  lϢsD1:RAMDISK.COM d)LkhChDCIC`8O  LD8:DUP.SYSGHLlTULlBDU?VLVD8:MEM.SAVlBJ P vB 091-DE v V0L ,0 `H h`8Hhi v V0,0 uLʆ [ 0 00   @  ULl$% CC$$%%d$% 0%$% DDLo  |[E QEEHI8 *hd$@0 ) 8EEȱEEE` 'HY`N@ !;0 YS S h l@D)DL0   H L@  ~    J)L KJ  '(( H L '() H * L '(  L}0o   * IB C?  d 1 L2L 'A! ߰")- " :$G@LL  '08`W");10 c-G$Ș YLx l 8(()($˥)N`  CIBLddddDOS SYSB"Y5L"P8GN*.COM*.EXENAVD><-+=!*?%% &%z3%$$HEL{*DIR*LOC.CLR.LOA-VER%INI+UNL.FMS.SAV,MODg%CARR*REN?,FME.HEAP)BAC_%BONo1DEL.FMD.SUM(RUNm*BOF|1COP3&FMQ.TYP.)EXE$ 1Y5P" O."8""@R'S15%0i5i5501ȊԢx5"JFJPWy"HH *5")IAY54 4> 4,0L#N #L|*J #L*J #14"4`J # 1Lk*v} 4 *%H$H`)?4 $ 4 #$0 2 4 $ y$, L$LL-19" !"H "H` $ $Ѻ Ѻ걺 2ȱ 4ɛL"ȱHH 2e滠滱 u2`> 8e滐`+"`e` y$ 2" 2Execute: W. /p O. / 1L"*ԆՎ l$ 2 \*L#L)4 % HJJJJ 3. 4h 3 3XFHSEX; 4L4"݅pq y$ 2ݹp` %ݱp 3`,5 2`N5 l$ /0 / 1 l$L$$8n" }$ 2pq y$I eppq> 4pq 3 3p,"0 ' 4 3L& 3`p8pqŠ 2ݑpȥpȄ(` /5D . 5 - #( l$ / #(莉5 2Reading: . .ii e֥iש 0( . `1,P3 1S / / 1&& 5$?♵5 -8tu E( rȥs(0 O. .Еߥ .8 ' 0( 2Writing: rȱsr* / / ,` / 1rs8 E($0 O. . .C .L'5  e . 'Lx&,5PJC`,50 2Insert ( 2sourceL' 2destination 2 & hit key ! #ڭ ҍ5L25`5օtׅu` S2tu / 1HrettIseuu(` (x / / O.L1`$0'5 / S2 1XY O.8` W.r n( (errstuvw 2LEN: vw 3u 3 2 SUM: st 3rL3 W.$0 * n( ( 4LB)N` W.ʆ n( ($0,F (!$0բ 2No COM-File !LO. (8ԨՐυلإ5 * 2# 2RUN: E* 3 2INIT: E*L^) * 3 2. ԥ 3- 4֥ 3 2 LEN:إ 3 (L)إL^) ( ( 3L3 1 y$T 4T l y$l 2l *" 4 3 * $ $ 4 2 *ݥURL4` , /$0"I" 1 n+,"0e+Di5Ei Q2 1 2 V/8," 2LV+ԩ 3: 4 4I 4L+ 2D5:1 4 2: $;0+ 2SINGLE 2 DENSITY 2 RAMDISKL* 2ENHANCEDp 2DOUBLE 2QUAD }/5,5$ 1 O.$0 `DOS.SYS8f5ȩU5ȩP5婿t"Y5L, / - l$ / /X,L. /,55 5.5 橛5L/LL$ }/ l$ 2 2刄t( 28$, 2RUN : y-ft !2INIT: y-ft 1 -$tP`$tPF$6eeȄԄՠ$0֩ /$0 q- /8ਥi S2 L15 4ɛ 2` y$ 2 " 2Load: W. /$莞 1 -5 lL"0L"2`")i"` 1 . / Q2 1'  Q2 1٠0 V/ .L.L2 BLVhihi / -i(i( -8((((.. . `1 1 - .`5  e`,#,,,"H 0hZ,!,#,$/ /$0 $0ZL/ -/L. / /L11/2/5 5 H.5h5ک5`5c/d/ 5? $08`$0`45 [2519 555 /$05455$ /5ED` *50 4`5008f [2R0/@ 2./ȱ 280@0  eiȱ/\FȢɛ  o- *  D.8;+"/+ȱ0"LL$Vȱ+F/ڊ u2 80 %? 00 0/+$0Wy`5 ` 2Sure ? 1Q`$O 2es, o or bort? 81YN 4(` 'ɛ)YN A 2AL"` * 4 `)  ӆij O.+ /  /$0Ș,J, 1B &V0`1 O.:>ݩ,".U * 2 is locked !Unlock file? 1ݐ`$ 1УԢ5 )p O. * * 2# 4 3L"IH`:;:` ,ɛ`` u2` *hihi 4eiHH` ," 4 2' 8`0:` 3` 2iԥiդ o$ԥ(`LL$ 2ԍ2Ս2Ԇՠ+22ȱ.6'`0#: AG6  &&`8`芄  (` }$ 2 2 3 2=' 38nɛL4ԥ 3 2=.݆ކ&(բuݕت 3ߊ, 3HJJJJ 3h) 0:i,  4,500 BHI V,L2,"p:ɛUR.* t4 t4^ 81 t4( $x0Nhh`S8R^`倈HH`p@BDE-HI V0)H-` O. 4L2L"ȱ 4ɛ`D1:*.*pB 50#452"/ $/38%by("arth&"ruchhaeuserc -2eitershan#omputertechnikI" $x0Nhh`S8R^`倈HH`p@BDE-HI V0"K( 1# # ?81N(K# (L 0  " V#7ɮ0 '(O(   ?O(h # g$ $=&8K#J# $0l N(K# #J# $L&N(K# #L" #'а A#L%l hh4+ %eiHH` %`) ӎjHH`D1:SETUP.BATD * - -ѩ Ѡ ه#Ȍ"`ICD@ӅJa H@ #@Ȍ"h@` #HHJ# lPhh`DE`HI``,p 6 4,"ĸ #B( #`p #BLVpM( #L(M( # ($``L(M( # ($L&J# $0O( # # ($۽D}HE}I$$L(M(L#'M#ɛɛq# M#0" M# %ɛ4-M#0TM#ɛ-E(("B( $L& # R$ #L$M#ɛ;("8?`&M# ^%L$ &H&H` #T ɛ %T  %ll)a "ASIC OS ont (B/D/C)? H&CB(DɛD %l % %`HH` #L%4."ʆ``0&YR`) i1.&&` "٠٠ϠԮ P&`%H$H`) ` &)D & & & & H  YhKӽM#ɛ ) hh`M#)`80 ``תi%%'(%%%/&4/%&X&&i& " " % ""T8K#J# $F #N(K#J# $0 .$ #8K#J# $0 R$ # #'L# "ˠ 8n  J`Jɮ " '"%x 40ө( #X` #P " # "| ϭӠР | # "`DUP.SYSD8:MEM.SAV"8K#J# $0 R$ # #'L# "ˠ 8n  J`Jɮ " '"%x 4jĭӺ ˠŠ 󠠠 82 DUP.SYSMEM.SAVԛÛźPOKE 710,0:POKE 709,0:RUN"D:MENU.FOX 󠠠 8 A3EF ##-----------------------------##----the FOX-1 P.O.Box 16----##---5160 AA Sprang-Capelle---(##-the Netherlands Oct.11th'95-2##-----------------------------<4<F@+) A`6;@,HAZAlA @~AR@@@K:PD-@@8(Using JOYSTICK PORT as OUTPUT.D6-AdZD-@@<58(Read DOC's or go BASIC ? (D/B)D6-AUdG-@@8#-*(-6-@=(-A Gn)@x"@hAP"@f A A-@(%( ۱-JNET.DOC (8-bit Network)<6((00(( ۲-PORTCNFG.TXT (Joystick Port Config)00(( ۳-IEEE.TXT (8-bit Parallel Interface),,($ ۴-README.1ST (Expl. of Textfiles))@"@'% "@I 6. D:JNET.DOC$"@P$6.D:PORTCNFG.TXT "<7@Q 6. D:IEEE.TXT""@R"6. D:README.1ST!! @I)!@RA;@ A0;@@?AA'AA-(}?-")@(>:,,"F:,"@(<8)F:,"@"%6F:,"@3 Ap@ AJ9( ( (9(' > - -- --- --- -- - <T: -@6@62@@: ^F:,"AUAPh%rH &-@6@D2@<9'@@H |"F:,"@()F:,"@"%F:,"@3$ AL AP@@)+L@@D:*.*.-@@+(報.()@(>:, A<:0&@@ @#(&*B7t@d'@@d*$ D:MENU.FOX AP@@)+L@@D:*.*.-@@+(報.()@(>:, A<h  ,gzAHAMIAL**************** ANETA.BAS*!!* the data sending routine* from JNET.ARC* by George McKinney*************** KB@@V'B@@9B@H<@`KB@@##@@K:,)@(>:," A, @0K6-P:'@d,16-P:+&$@d,'@,K6-&$@d&$@B@T:,A B@%@(TH=:,A@B@%@$T:,A`.B@@8(T:,AB$$ D:ANETA.BASd,'@,K6-&$@d&$@B@T:,A B@%@(TH  5ALAMIAH**************** ANETB.BAS*##* the data receiving routine* from JNET.ARC* by George McKinney*************** KB@@V'B@@L?9B@@`KB@@-@AT:,@ $6-F:B@,$B@#(T:,@5($6-F:B@,$B@@-T:,@E2$6-F:B@,$B@7(T:L@,@U<B@@F6-&P:'@,$@P6-&P:'@,$@Z6-&P:'@,$@d/6-%@$%@d$%(>:,/ @  D:ANETB.BAS,@E2$6-F:B@,$B@7(T:L5000 DATA 104,10,240,65,170,201,6,208,56,104,149,213,202,208,250,1345010 DATA 212,134,213,165,214,41,7,133,214,169,56,141,2,211,169,155020 DATA 141,0,211,169,60,141,2,211,165,20,105,180,168,165,214,1745030 DATA 16,208,208,20,196,20,208,247,230,212,16PB0,8,140,0,211,2085040 DATA 6,104,202,208,252,230,213,96,141,0,211,196,20,240,233,1745050 DATA 16,208,208,247,169,15,141,0,211,165,214,240,234,160,255,1325060 DATA 215,165,216,168,41,7,174,16,208,240,251,141,0,211,152,745070 DATA 74,74,168,9,8,174,16PC,208,208,251,141,0,211,152,74,745080 DATA 74,174,16,208,240,251,141,0,211,169,15,174,16,208,208,2515090 DATA 141,0,211,230,215,164,215,196,216,240,172,177,218,208,196,2405100 DATA 1945110 REM * 161 BYTES6000 DATA 216,169,0,162,4,149,212,202,16,251,PD104,240,69,201,1,2086010 DATA 59,104,133,218,104,133,217,169,56,141,2,211,169,8,141,06020 DATA 211,169,60,141,2,211,174,16,208,208,251,162,100,202,208,2536030 DATA 173,0,211,142,0,211,174,16,208,240,251,162,10,202,208,2536040 DATA 160,8,140,0,211,41PE,7,133,213,208,11,96,10,170,104,2026050 DATA 208,252,198,213,208,245,160,8,174,16,208,208,251,162,10,2026060 DATA 208,253,173,0,211,142,0,211,41,7,133,216,174,16,208,2406070 DATA 251,162,10,202,208,253,173,0,211,140,0,211,10,10,10,416080 DATA 56,5,2PF16,133,216,174,16,208,208,251,162,10,202,208,253,1736090 DATA 0,211,142,0,211,174,16,208,240,251,140,0,211,106,106,1066100 DATA 41,192,5,216,36,215,48,10,198,215,133,212,201,0,208,1666110 DATA 240,153,164,214,145,217,200,132,214,196,212,208,153,240,1PG406120 REM * 191 BYTES10000 DIM DAT$(300),RECEIVE$(191),SEND$(161),FL$(30)10005 ERRSEND=11000:ERRREC=11030:RECROUT=1105010010 RESTORE 5000:FOR I=1 TO 161:READ A:SEND$(I)=CHR$(A):NEXT I10020 RESTORE 6000:FOR I=1 TO 191:READ A:RECEIVE$(I)=CHR$(A):NEXPHT I10030 RECEIVE=ADR(RECEIVE$)10040 SEND=ADR(SEND$)10100 RETURN 11000 IF Z>255 THEN ? "Bad parameters in sending USR routine.Check parameters and re-RUN":END 11010 ? "Timeout on sending. Check other machine and input CONT to continue.":STOP PI11020 RETURN 11030 ? "Bad parameters in RECEIVE USR routine.Check program and re-RUN.":END 11040 RETURN 11050 Z=USR(RECEIVE,ADR(DAT$)):IF Z>32767 THEN GOTO ERRREC11060 CMD=INT(Z/256):LNT=Z-CMD*256:DAT$(LNT+1)=CHR$(155)11070 RETURN ontinue.":STOP P@AexDATRECEIVESENDFLERRSENERRRERECROURECEIVSENCMLNFN  ********************** BNETA.BAS fTKrom* JNET.ARC by(* George McKinney2*< * Demo programs of 8-bitF* joystick portP* networkingZ*********************d Bn/+#A %P:@$H:,,$@/"s06-F:Ad,0"A)"ATLA6-?:>212,1TQ34,213,165,214,41,7,133,214,169,56,141,2,211,169,15??141,0,211,169,60,141,2,211,165,20,105,180,168,165,214,174>>16,208,208,20,196,20,208,247,230,212,160,8,140,0,211,208??6,104,202,208,252,230,213,96,141,0,211,196,20,240,233,174AA16,208,2TR08,247,169,15,141,0,211,165,214,240,234,160,255,132>>215,165,216,168,41,7,174,16,208,240,251,141,0,211,152,74::74,74,168,9,8,174,16,208,208,251,141,0,211,152,74,74??74,174,16,208,240,251,141,0,211,169,15,174,16,208,208,251CC141,0,211,230TS,215,164,215,196,216,240,172,177,218,208,196,240 194* 161 BYTESp==216,169,0,162,4,149,212,202,16,251,104,240,69,201,1,208z==59,104,133,218,104,133,217,169,56,141,2,211,169,8,141,0AA211,169,60,141,2,211,174,16,208,208,251,162,100,202TT,208,253??173,0,211,142,0,211,174,16,208,240,251,162,10,202,208,253;;160,8,140,0,211,41,7,133,213,208,11,96,10,170,104,202AA208,252,198,213,208,245,160,8,174,16,208,208,251,162,10,202==208,253,173,0,211,142,0,211,41,7,133,216,174,16,208,TU240<<251,162,10,202,208,253,173,0,211,140,0,211,10,10,10,41@@56,5,216,133,216,174,16,208,208,251,162,10,202,208,253,173>>0,211,142,0,211,174,16,208,240,251,140,0,211,106,106,106==41,192,5,216,36,215,48,10,198,215,133,212,201,0,208,166TVAA240,153,164,214,145,217,200,132,214,196,212,208,153,240,140* 191 BYTES'11;A,;A,;Aa,;@0,''6-B6-B0'6-BP'5 #AP!-@Aa%"167,.>:,5 $'5 #A`!-@ATW%"167,.>:,5 .' 6-C:,8' 6-C:,t'$*X!AUU(ABad parameters in sending USR routine.Check parameters and re-RUNX+TQ(ITimeout on sending. Check other machine and input CONT to continue.T& +$+JG(?Bad parameters inTX RECEIVE USR routine.Check program and re-RUN.J +$*+!6-?:6-P:'AV,$6-&$AV>67%@,.>:AU,>+$ D:BNETA.BASr machine and input CONT to continue.T& +$+JG(?Bad parameters inTd1DATRECEIVESENDFLERRSENERRRERECEIVRECROUCMLNSENCHAFN  ********************** BNETB.BASXZ from* JNET.ARC by(* George McKinney2*< * Demo programs of 8-bitF* joystick portP* networkingZ*********************d BINITIALIZATIONn( INITIALIZED##@@K:(TX[:,  A F:Ad,"AUA")@(>:," A*************%%* The CMDs used are as follows:* 0->All done; OK * 4->Here's data to print66* 5->Here's search spec, give me directory inX\fo*** 6->Here's file name, give me file""* 7->(with no data) ACK; OK//* (with a data byte) I/O error number**************7"@(46-?:<<<,7$7"@(46-?:<<<X],7$"@A "@A0$(6.D1:*.* A 03#7@,4:)7@,4:)6.3 A 0 6.D1:67@,.K A!*@@K6-?:<<<@,? AX^"@56-?::F:A,,f,6-?:>212,134,213,165,214,41,7,133,214,169,56,141,2,211,169,15??141,0,211,169,60,141,2,211,165,20,105,180,168,165,214,174>>16,208,208,20,196,20,208,247,230,212,160,8,140,0,211,208??6,104,202,208,252,230,213,96,141,0,211,196,20,Xa240,233,174AA16,208,208,247,169,15,141,0,211,165,214,240,234,160,255,132>>215,165,216,168,41,7,174,16,208,240,251,141,0,211,152,74::74,74,168,9,8,174,16,208,208,251,141,0,211,152,74,74??74,174,16,208,240,251,141,0,211,169,15,174,16,208,2Xb08,251CC141,0,211,230,215,164,215,196,216,240,172,177,218,208,196,240 194* 161 BYTESp==216,169,0,162,4,149,212,202,16,251,104,240,69,201,1,208z==59,104,133,218,104,133,217,169,56,141,2,211,169,8,141,0AA211,169,60,141,2,211,174,1Xc6,208,208,251,162,100,202,208,253??173,0,211,142,0,211,174,16,208,240,251,162,10,202,208,253;;160,8,140,0,211,41,7,133,213,208,11,96,10,170,104,202AA208,252,198,213,208,245,160,8,174,16,208,208,251,162,10,202==208,253,173,0,211,142,0,211Xd,41,7,133,216,174,16,208,240<<251,162,10,202,208,253,173,0,211,140,0,211,10,10,10,41@@56,5,216,133,216,174,16,208,208,251,162,10,202,208,253,173>>0,211,142,0,211,174,16,208,240,251,140,0,211,106,106,106==41,192,5,216,36,215,48,10,198,215Xe,133,212,201,0,208,166AA240,153,164,214,145,217,200,132,214,196,212,208,153,240,140* 191 BYTES'11;A,;A,;Aa,;@0,''6-B6-B0'6-BP'5 #AP!-@Aa%"167,.>:,5 $'5 #AXf`!-@A%"167,.>:,5 .' 6-C:,8' 6-C:,t'$*X!AUU(ABad parameters in sending USR routine.Check parameters and re-RUNX+TQ(ITimeout on sending. Check other machine and input CONT to continue.T& +$Xg+JG(?Bad parameters in RECEIVE USR routine.Check program and re-RUN.J +$*+!6-?:6-P:'AV,$6-&$AV>67%@,.>:AU,>+$ D:BNETB.BASXh! 4+>6-P:'AV,$6-&$AV>67%@,.>:AU,>+$ D:BNETB.BASXl X; RECEIVEX;%X; Z=USR(ADR(RECEIVE$),ADR(DAT$))(X;2HX; a BASIC subroutine for communicating between ATARI 8-bit computers<X; using joystick port #0FX;PJX; enter with 1 parameter, the address at which to store received data.ZX;d\j@X; on exit, if Z>32767, the routine was called with the wrongnX; number of parametersxX;7X; otherwise, LSB of Z=Lenght of data stored in DAT$"X; MSB of Z=Command#X; X; EQUATES PORTAӴ PACTLӾ TRIG0 LEN\kCOMMANDCOUNTER FLAG TEMP ADRX; ;; arbitrary-;; may not be necessary"Q>,$>6INIT@ PLEN9J0T IINIT^7;; check # of paramsh FBAD.PARSrR>|HPULL.PARS7 PADR7PADR SET.DIR\lQ>8;; select DDIR PPACTLQ>PPORTA;; make bits 0-2 in,Q><;; bit 3 out PPACTLGET.COMMAND$TRIG0;; ought to be =0HGET.COMMAND $>d;; delay loop  SUBLOOP40 HSUBLOOP4QPORTA;; get command&PORTA;; send back 0& \mLOOPB0 $TRIG0: FLOOPB<$> ;;delay loop> SUBLOOP5@0B HSUBLOOP5D%>;; send back 1N 'PORTAXM>;; save commandbPCOMMAND;; if command=0lHRECEIVE;; then EOTvEXIT: PULL.PARST?>PULL.LOOP;dispose of pars.70H\nPULL.LOOP BAD.PARS"COMMAND;; make Z>32767HEXIT;; forced RECEIVE%> LOOP1  $TRIG0 HLOOP1$> ;; delay loop SUBLOOP30 HSUBLOOP3 QPORTA;; get lower 3 bits* &PORTA4M>> PTEMPH LOOP2R $TRIG0\ FLOOP2^$>\o ;; delay loop` SUBLOOP2b0d HSUBLOOP2f QPORTAp 'PORTAzT?T?T?M>8 LTEMP PTEMP LOOP3 $TRIG0 HLOOP3$> ;; delay loop SUBLOOP10 HSUBLOOP1 QPORTA &PORTA LOOP4 $TRIG0 FLOOP4 'PORTAW?W?\pW?$M>. LTEMP8*FLAG;; is this len?BGSTORE.BYTEL"FLAG;; make flag=$ffVPLEN`R>;; is len=0?jHRECEIVE;; no - get datatFEXIT;; yes - exit~STORE.BYTE %COUNTERP@ADR7;; store byte3;; increase counter 'COUNTER)LEN\q HRECEIVE FEXIT*FLAG;; is this len?BGSTORE.BYTEL"FLAG;; make flag=$ffVPLEN`R>;; is len=0?jHRECEIVE;; no - get datatFEXIT;; yes - exit~STORE.BYTE %COUNTERP@ADR7;; store byte3;; increase counter 'COUNTER)LEN\w X; SEND5X; Z=USR(ADR(SEND$),ADR(DAT$),LEN(DAT$),COMMAND)X;(%X; a BASIC subroutine to send data2%X; to another ATARI 8-bit computer<)X; through joystick port 0 (most gamesAX; call this port 1)FX;P!X; enter with 3 parametersZ(`sX; ADR(DAT$)=address to get data fromd;X; LEN(DAT$)=LEN of data to send - MUST BE 255 OR LESS!!n!X; command=0 - Sends no datax6X; >0 & <8 - the meaning of these is defined}-X; by the calling program#X; (receiver expects `t1 LEN byte#X; immediately after COMMAND andX; then LEN bytes of data)X;X; on exit Z=0 OK X; 0255 bad parametersX;X; EQUATESX;RTCLOCKLO PORTA PACTL TRIG0 `uFR0COMMAND"COUNTER, LEN6 ADR@X;J ;; arbitraryT7^T?h FBAD.PARSr>|R>;; must be 3 pars.HPULL.PARS PULL.LOOP7 PFR090HPULL.LOOP&FR0&FR0;; init Z=0 QCOMMANDM> PCOMMAND`v SET.DIRQ>8 PPACTLQ>;; make 4 bits out PPORTAQ><& PPACTL0SET.TIMEOUT:/QRTCLOCKLO;; wait 3 seconds for a response.D O>;;N?XSEND.COMMANDb QCOMMANDl LOOP1v $TRIG0 HCONT1;; If TRIG0 =1 it's OK')RTCLOCKLO;; oth`werwise see if we'veHLOOP1;; waited 3 seconds.TIMEOUT;if so, set error message and exit#FR0%> 'PORTAHEXIT;; forced PULL.PARS70HPULL.PARS BAD.PARS #FR0EXIT: CONT1  PPORTA LOOP2 )RTCLOCKLO* F`xTIMEOUT4 $TRIG0> HLOOP2\ CONT2f Q>;;send 1 to other triggerp PPORTAzQCOMMAND;; was command=0?FEXIT;; if so, exit%>'COUNTER;; init counterQLEN;; send LEN firstSEND.LOOP;enter with byte?;; to send in A"M>;; mask`y low 3 bits, bit 3=0 LOOP3$TRIG0;; make sure trig=0 FLOOP3"PPORTA;; send to other machineC;; get data byteV?;; shift bits 3-5 to 0-2V?V??;; save in Y$L>;; set bit 3. LOOP48%$TRIG0;; now we make sure trig0=1B HLOOP4L`zPPORTA;; and then send dataV)C;; recall data (already shifted once)`V?;; and shift some morejV?tV?~ LOOP5 $TRIG0 FLOOP5 PPORTAQ>;; for last cycle0LOOP6;the only thing that matters is bit3=1 $TRIG0 HLOOP6 PPORTA#`{COUNTER;; increase count %COUNTER)LEN;; exit if all sent FEXITQ@ADR7;; else get another HSEND.LOOP;; and do itFSEND.LOOP;; againQ>;; for last cycle0LOOP6;the only thing that matters is bit3=1 $TRIG0 HLOOP6 PPORTA#` _`v DATSENRECEIVESENDFLRECROUERRSENRECEIVINPORCMLNT ********************** CNETA.BAS frd}om* JNET.ARC by* George McKinney* * Demo programs of 8-bit* joystick port* networking ********************* B6-F:@ ,2&6-?:<@2>162,7,189,0,6,149,214,202,16,248,104,104,133,226,104,133z??225,104,133,224,133,228,133,222,133,212,104,32,8,6,32,147==6,133,213,201,24,144,83,32,147,6,166d,221,189,16,208,208??251,162,18,202,208,253,185,0,211,72,166,219,181,214,153,0;;211,104,166,219,240,4,10,10,144,3,74,106,106,41,192,5BB222,133,222,166,221,189,16,208,240,251,169,255,153,0,211,165??222,36,228,48,10,198,228,133,212,201,0,2d08,186,240,11,16400224,145,225,200,132,224,196,212,208,173,96* 123 BYTESX99240,15,240,8,128,0,0,0,197,221,240,20,133,221,141,7b776,168,74,133,220,141,6,6,152,41,1,133,219,141,5,6l==166,219,164,220,185,2,211,41,251,153,2,211,72,185,0,2d11v8853,214,36,222,16,2,21,215,21,217,153,0,211,104,9,499153,2,211,96,133,222,41,7,166,219,240,4,10,10,10,10??21,214,72,165,20,105,240,164,221,197,20,240,44,190,16,208@@240,247,104,166,220,157,0,211,165,222,41,56,10,166,219,208::4,74,d74,74,74,21,214,21,217,72,165,20,105,240,190,16>>208,240,8,197,20,208,247,240,3,104,96,24,104,166,220,157@@0,211,96,164,220,166,221,189,16,208,208,251,162,18,202,208>>253,185,0,211,72,166,219,181,214,153,0,211,104,224,0,240;;4,74,74,74,7d4,41,7,133,222,166,221,189,16,208,240,251@@162,18,202,208,253,190,0,211,169,255,153,0,211,138,166,21933240,3,74,16,3,10,10,10,41,56,5,222,133,222,96* 223 BYTES'11;A,;A#,;A,;@0,'6-BP6-B'5d #AP!-@A%"167,.>:,5 $'5 #A`!-@A#%"167,.>:,5 .' 6-C:,8' 6-C:,B'7 #Ap!-A"%"3A6%7 t'$*TIMEOUT ROUTINE+TQ(ITimeout on sending. Check other d machine and input CONT to continue.T& +$*+6-?:6-P:'AV,$6-&$AV>67%@,.>:AU,>+$ D:CNETA.BASA+6-?:>162,7,189,0,6,149,214,202,16,248,104,104,133,226,104,133z??225,104,133,224,133,228,133,222,133,212,104,32,8,6,32,147==6,133,213,201,24,144,83,32,147,6,166,221,189,16,208,208??251,162,18,202,208,253,185,0,211,72,166,219,181,214,153,0h;;211,104,166,219,240,4,10,10,144,3,74,106,106,41,192,5BB222,133,222,166,221,189,16,208,240,251,169,255,153,0,211,165??222,36,228,48,10,198,228,133,212,201,0,208,186,240,11,16400224,145,225,200,132,224,196,212,208,173,96* 123 BYTESXh99240,15,240,8,128,0,0,0,197,221,240,20,133,221,141,7b776,168,74,133,220,141,6,6,152,41,1,133,219,141,5,6l==166,219,164,220,185,2,211,41,251,153,2,211,72,185,0,211v8853,214,36,222,16,2,21,215,21,217,153,0,211,104,9,499153,2,211,96,133,222,h41,7,166,219,240,4,10,10,10,10??21,214,72,165,20,105,240,164,221,197,20,240,44,190,16,208@@240,247,104,166,220,157,0,211,165,222,41,56,10,166,219,208::4,74,74,74,74,21,214,21,217,72,165,20,105,240,190,16>>208,240,8,197,20,208,247,240,3,1h04,96,24,104,166,220,157@@0,211,96,164,220,166,221,189,16,208,208,251,162,18,202,208>>253,185,0,211,72,166,219,181,214,153,0,211,104,224,0,240;;4,74,74,74,74,41,7,133,222,166,221,189,16,208,240,251@@162,18,202,208,253,190,0,211,169,255,1h53,0,211,138,166,21933240,3,74,16,3,10,10,10,41,56,5,222,133,222,96* 223 BYTES'11;A,;A#,;A,;@0,'6-BP6-B'5 #AP!-@A%"167,.>:,5 $'5 #A`!-@A#%"h167,.>:,5 .' 6-C:,8' 6-C:,B'7 #Ap!-A"%"3A6%7 t'$*TIMEOUT ROUTINE+TQ(ITimeout on sending. Check other machine and input CONT to continue.T& +$*+6-?:6-P:'AV,h$6-&$AV>67%@,.>:AU,>+$ D:CNETB.BASA"%"3A6%7 t'$*TIMEOUT ROUTINE+TQ(ITimeout on sending. Check other machine and input CONT to continue.T& +$*+6-?:6-P:'AV,hCR #X; ZERO-PAGE AND GENERAL EQUATESX; FOR SENDX4 AND RECVX4 DELAY TIMEOUT.JIF( PORTA2 PACTL4STRIG0<RTCLOCKLOP FR0ZZDIRMASKdZOUTMASKnZINMASKx ZPLUGۂ ZPORT܌ZCURR.PORTݖ IOlޠ TEMPު LENߴCOUNTER ADDR CMD FLAGLONG.COMMAND.JIF( PORTA2 PACTL4STRIG0<RTCLOCKLOP FR0ZZDIRMASKdZOUTMASKnZINMASKx ZPLUGۂ ZPORT܌ZCURR.PORTݖ IOlY X;"X; NON-RELOCATABLE ROUTINES FOR X; 4-CHANNEL NETWORK SOFTWARE(X;2X; ORGed to $600 for BASIC<>D:NETWX4.EQUFPX;ZX;dDIRMASK nOUTMASK =xINMASK = PLUG  PORT CURR.PORT X;X;SET.PLUGS.pPORTS&X; enter with A=joystick port (0-3)X; and IO=0 for inputX; =$FF for outputRZCURR.PORT FSET.DIRPZCURR.PORTPCURR.PORT?V? PZPORT" PPORT,C6M>@ PZPLUGJ PPLUGT SET.DIR^ $ZPLUGh %ZPORTr QPACTL8|pM> PPACTL85 QPORTA8MZDIRMASK9*IO ISKIP1LZOUTMASK9 SKIP1 LZINMASK9 PPORTA87L> PPACTL8:X;X;&%X; SUBROUTINE TO SEND LOW SIX BITS0X;:X;DX;NX;X SEND2SEGb PTEMPlM>v $ZPLUG FNOSHIFTp1T?T?T?T? NOSHIFT1LZDIRMASK95QRTCLOCKLOO>TIMEOUT.JIF%ZCURR.PORT LOOP1RRTCLOCKLOFTIMEOUT.EXIT  $STRIG08 FLOOP1 7* $ZPORT4 PPORTA9> QTEMPHM>8RT?\ $ZPLUGf HNOSHIFT2pV?zV?V?V? NpOSHIFT2LZDIRMASK9 LZINMASK95QRTCLOCKLOO>TIMEOUT.JIF LOOP2 $STRIG08 FCONTRRTCLOCKLO HLOOP2FTIMEOUT.EXIT2TIMEOUT.EXIT7:;; LEAVES CARRY SET$CONT),+TIMEOUT.EXIT2.78 $ZPORTB PPORTA9V:`X;jX;tpX;~RECEIVE2SEG %ZPORT$ZCURR.PORT ?LOOP1 QSTRIG09 H?LOOP1 $>DELAY DELAY10 HDELAY1 QPORTA85 $ZPLUGQZDIRMASK9 PPORTA87 (>F?NOSHIFT1V?(V?2V?<V?F ?NOSHIFT1PM>Z PTEMPd$ZCURR.PpORTn ?LOOP2x QSTRIG09 F?LOOP2 $>DELAY DELAY20 HDELAY2 $PORTA8Q> PPORTA8A $ZPLUGF?NOSHIFT2V?I?SKIP;; FORCED ?NOSHIFT2T?T?T?" ?SKIP,M>86 LTEMP@ PTEMPJ:SHIFT1PM>Z PTEMPd$ZCURR.PpZ X;X;'X; The BASIC USR routine to receive(X; data through any of four2X; joystick ports.<#X; If you don't have four ports,FX; DON'T TRY TO USE 3 or 4PX;Z>D:NETWX4.EQUd@ MOVE.LOOPJ QDIRMASK9TPZDIRMASK9^0hIMOVE.LOOPr7;; ԠŠ|7 PADDR7 PADDR7;; high byte of joystickPCOUNTER;; better be 0 PFLAGPIOPFR0;; len for this routine 7;; plug# SET.PLUGtS.PORTS;; and dir. RECEIVE2SEGPFR0;; cmdR>LONG.COMMANDDEXIT1;; if less than 32 BIG.LOOP RECEIVE2SEG&$ZCURR.PORT0 LOOP3: QSTRIG09D HLOOP3N $>DELAYX DELAY3b0l HDELAY3v QPORTA8{5} $ZPLUGQZDIRMASK9 PPOtRTA87 $ZPLUG FROLLT?T?DSKIP1;; forcedROLLV?W?W? SKIP1M>  LTEMP PTEMP $ZCURR.PORT* LOOP44 QSTRIG09> FLOOP4HQ>R PPORTA8\ QTEMPf *FLAGp GSKIP2z"FLAG;; make flag=$ffPFR0;; length valuetR> HBIG.LOOP FEXIT1 SKIP2 %COUNTER P@ADDR73 'COUNTER)FR0 HBIG.LOOP EXIT1:P $ZCURR.PORT* LOOP44 QSTRIG09> FLOOP4HQ>R PPORTA8\ QTEMPf *FLAGp GSKIP2z"FLAG;; make flag=$ffPFR0;; length valuetp X;X;$X; The BASIC USR routine to send(X; data through any of four2X; joystick ports.<#X; If you don't have four ports,FX; DON'T TRY TO USE 3 or 4PX;Z>D:NETWX4.EQUd;; move data to zero page@ MOVE.LOOPJ QDIRMASK9TPZDIRMASK9^0hIMOVE.LOOPr7;; Ӡӡ|$> PULL.LOOP7 PTEMP90IPULL.LOOP7&IO0 SET.PLUGS.PORTS;; and direction of transferQCMD5 SEND2SEGx7EEXIT2;; timed outR>LONG.COMMANDDEXIT1;; a no-data CMD&QLEN0%>: 'COUNTERD BIG.LOOPN SEND2SEGX QTEMPbM>l $ZPLUGv FROLLV?V?DSKIP;; forcedROLLT?U?U?SKIPLZDIRMASK9 LOOP3 $STRIG08x FLOOP3 $ZPORT PPORTA9  LOOP4 QSTRIG08  HLOOP4*Q>4 PPORTA9> %COUNTERH)LENR FEXIT1\ Q@ADDR7f #COUNTERpHBIG.LOOP;; forcedz EXIT1, EXIT2Q>PFR0W? PFR0:SKIPLZDIRMASK9 LOOP3 $STRIG08x5000 DATA 162,7,189,0,6,149,214,202,16,248,104,162,6,104,149,2225010 DATA 202,16,250,104,134,222,32,8,6,165,227,72,32,68,6,1045020 DATA 176,63,201,24,144,58,165,223,160,0,132,224,32,68,6,1655030 DATA 222,41,192,166,219,240,4,74,74,144,3,10,42,42,21,2|145040 DATA 190,16,208,240,251,166,220,157,0,211,185,16,208,208,251,1695050 DATA 255,157,0,211,164,224,196,223,240,6,177,225,230,224,208,2045060 DATA 24,169,0,133,212,106,133,213,965070 REM * 105 BYTES6000 DATA 162,7,189,0,6,149,214,202,16,248,104,|104,133,226,104,1336010 DATA 225,104,133,224,133,228,133,222,133,212,104,32,8,6,32,1476020 DATA 6,133,213,201,24,144,83,32,147,6,166,221,189,16,208,2086030 DATA 251,162,18,202,208,253,185,0,211,72,166,219,181,214,153,06040 DATA 211,104,166,219,240,4|,10,10,144,3,74,106,106,41,192,56050 DATA 222,133,222,166,221,189,16,208,240,251,169,255,153,0,211,1656060 DATA 222,36,228,48,10,198,228,133,212,201,0,208,186,240,11,1646070 DATA 224,145,225,200,132,224,196,212,208,173,966080 REM * 123 BYTES7000 DA|TA 240,15,240,8,128,0,0,0,197,221,240,20,133,221,141,77010 DATA 6,168,74,133,220,141,6,6,152,41,1,133,219,141,5,67020 DATA 166,219,164,220,185,2,211,41,251,153,2,211,72,185,0,2117030 DATA 53,214,36,222,16,2,21,215,21,217,153,0,211,104,9,47040 DATA 1|53,2,211,96,133,222,41,7,166,219,240,4,10,10,10,107050 DATA 21,214,72,165,20,105,240,164,221,197,20,240,44,190,16,2087060 DATA 240,247,104,166,220,157,0,211,165,222,41,56,10,166,219,2087070 DATA 4,74,74,74,74,21,214,21,217,72,165,20,105,240,190,1670|80 DATA 208,240,8,197,20,208,247,240,3,104,96,24,104,166,220,1577090 DATA 0,211,96,164,220,166,221,189,16,208,208,251,162,18,202,2087100 DATA 253,185,0,211,72,166,219,181,214,153,0,211,104,224,0,2407110 DATA 4,74,74,74,74,41,7,133,222,166,221,189,16,|208,240,2517120 DATA 162,18,202,208,253,190,0,211,169,255,153,0,211,138,166,2197130 DATA 240,3,74,16,3,10,10,10,41,56,5,222,133,222,967140 REM * 223 BYTES10000 DIM DAT$(300),RECEIVE$(123),SEND$(105),FL$(30)10005 RECROUT=11050:ERRSEND=1100010010 RE|STORE 5000:FOR I=1 TO 105:READ A:SEND$(I)=CHR$(A):NEXT I10020 RESTORE 6000:FOR I=1 TO 123:READ A:RECEIVE$(I)=CHR$(A):NEXT I10030 RECEIVE=ADR(RECEIVE$)10040 SEND=ADR(SEND$)10050 RESTORE 7000:FOR I=0 TO 222:READ A:POKE 1536+I,A:NEXT I10100 RETURN 11|000 REM TIMEOUT ROUTINE11010 ? "Timeout on sending. Check other machine and input CONT to continue.":STOP 11020 RETURN 11050 Z=USR(RECEIVE,ADR(DAT$),INPORT)11060 CMD=INT(Z/256):LNT=Z-CMD*256:DAT$(LNT+1)=CHR$(155)11070 RETURN 10100 RETURN 11| 8-BIT NETWORK INTRODUCTION This is a description of and directions for the use of software and hardware used to enable two ATARI 8-bit computers to communicate with each other through joystick ports. These routines are first steps toward my goal of being able to do this through any of the two or four joystick ports to connect many machines together and to use CIO to control them. THE THEORY Each ATARI 8-bit computer includes a PIA interface chip. The PIA includes two 8-bit bi-directional I/O ports (as well as various interrupt and control lines). These ports are wired to four of the pins on each of the joystick ports. (One of the PIA ports is used to control memory bank switching on the XL and XE series computers, allowing only two joystick ports on these models.) Normally these pins are set by the Operating System as inputs, but each pin can independently be set for either Input or Output. In addition, The trigger pin is wired into a memory location (STRIG0 - 3) and is for input only. My software/hardware uses one of the PIA pins in each joystick port as a dedicated output to the other machine's trigger pin, and configures the other three pins as either input or output depending on the direction of data transfer. This implies that only three bits at a time can be transferred, so the software has the responsibility of dismantling and re-assembling each byte for transfer. The trigger lines are used to indicate the sending and receiving of each chunk of data. THE HARDWARE Is about as simple as you can get. Pin 4 (right) on one machine is conected to pin 6 (trigger) on the other, and vice versa, while pins 1-3 (forward, back, left) and pin 8 (ground) on each machine are connected. I initally took apart two joysticks and (after determining which wire went where) hooked wires together with alligator clips. It worked, so I bought some 9-pin plugs and soldered them up. They don't look elegant, but they work. THE SOFTWARE There are three sets of routines included here, A- B- and CNETxx.xxx. The files in each set are related. In order to use them, you'll need two (or more) ATARI 8-bit computers, each with a way to load BASIC programs, and one or more of the cables mentioned above. STEP 1 - ANET ANETA.BAS and ANETB.BAS are pure BASIC programs which POKE the PIA chips. They show that the idea works, but that's about all. You will need a cable between joystick page 2 port 0 on one machine and joystick port 0 on the other. Run ANETA first, then ANETB (on different computers). Any key you type (except for BREAK) on machine A will be echoed to the screen of machine B. You'll notice that it is slow due to BASIC's runing things. STEP 2 - BNET BNETSN.M65 and BNETRE.M65 are the MAC-65 source code files for BASIC USR routines used in BNETA.BAS and BNETB.BAS. BNETSN.M65 sends information through port 0, BNETRE.M65 receives it. These routines are position independent, and use a few bytes from the zero-page floating point area (which is free during USR). Both these routines assume that the length of data to be transmitted is less than 256 bytes - but they don't check for that. You may notice several delay loops in the receive routine. They may not be necessary; take them out and try. BINIT.LST is a LISTED file which includes both the routines in DATA statements as well as the code to read the DATA statements into strings, and initialization and error routines. BNETA.BAS and BNETB.BAS contain BINIT.LST. Set up as before, and run BNETB first, then BNETA. While the programs are running, anything you type on the B machine is printed to the screen while the machine watches for STRIG0=0. "A" simply sends strings taken at random from the program while watching the keyboard. As "B" receives each string, it is printed to the screen. Press CTRL-D on the "A" machine and it will prompt you for a directory search spec. That spec is sent to "B" which gets directory information from a disc drive and returns it to "A", where it is printed. CTRL-F does the same with the chosen file. -WARNING- asking for a non-text file (e.g. a BASIC SAVEd file) will cause confusion, if not serious problems. Note that the "A" and "B" designations are simply a part of the BASIC program. The USR routines are identical in each of the programs. For SENDING data the form is: Z=USR(ADR(SEND$),ADR(DAT$),LEN(DAT$),COMMAND) COMMAND can be from 0 to 7. If it is zero the routine sends only the command, not any data. Otherwise, after sending COMMAND, it sends one byte for LEN and then LEN bytes from ADR. When the routine returns Z holds the status. Z=0 indicates OK; Z>=256, you sent the wrong number of parameters; 032767 (i.e. the high bit is set) you used the wrong number of parameters. Otherwise the high byte holds the COMMAND and the low byte the number of data bytes received. There is a subroutine in BINIT.LST that sorts these out into BASIC variables CMD and LNT and sets DAT$ to LNT+1 with a RETURN after the data. COMMANDs can be interpreted any way you find useful in the program, and can be combined with a zero LEN parameter. BNET*.BAS show some possibilities. page 3 STEP 3 - CNET The C*.* files are organized like the B*.* ones. CNET allows the USR routines to specify which of the joystick ports are to be used for the operation. IF YOU AREN'T USING A 400 OR 800 DON'T TRY TO USE PORTS 2 OR 3! The routines don't check. CNETA.BAS simply waits for the user to INPUT a string, sends that out through port 0, and watches port 1 for a while. If someak arrives, it prints it out; if not, it prints NO RETURN. Then it starts over. CNETB.BAS watches port 0. When something arrives, it sends it out over port 1 and also prints it to the screen. I have used four B machines and an A machine in a ring. These are trivial BASIC programs, but they work, although for some reason, you need to run the "A" program first. Let it reach the "?" prompt before running the "B" machine. The USR routines take up most of Page 6 plus strings and use 17 bytes from the zero page floating point area. They DON'T check parameters, and the limit of 255 bytes on data length remains. To send use: Z=USR(ADR(SEND$),CMD,ADR(DAT$),LEN(DAT$),JPLUG) Note that JPLUG is 0 to 3 NOT 1 to 4. CMD can be 0 to 63 and CMDs <24 send NO data. Z=0 if OK, 32768 if timed out. To receive, use: Z=USR(ADR(RECEIVE$),ADR(DAT$),JPLUG) The MSB of Z is the command; the LSB is the length of the data. Again CINIT.LST includes a subroutine to handle this. Enter it with INPORT set to the port you want. THE NEXT STEP(s) The USR routines could be used in a number of interesting ways - multi player games, dedicated systems for parallel processing or neural network experiments - particularly with some refining and/or rewriting to work with ACTION!, but I hope to develop this system into a device driver ( the N: device ) which can be used like any other of the OS devices and which can use any of the two or four joystick ports. One of the shortcomings is that everything must be loaded from disk, which requires either a drive for each machine or a lot of cable switching. A cartridge with the driver in ROM would work, but you'd probably have to give up other carts or BASIC. More basic is the question of HOW the N: device is organized. Requiring each machine - both the originating and the answering one - to call CIO is, I think, too confining. My current plan is to use CIO for the originator and a VBI routine to watch the ports and switch to answering routines when someak comes in. There is an ACTION! routine called FORK which might be a model. I would like to include functions which would send data to a specified address, run the data as a program, and retreive data from specified addresses. In addition, forwarding data through one or more machines to a specified machine would be good. I'll try to organize my notes on the subject and upload them. I would appreciate any comments, criticisms, or suggestions you might have. Feel free to use page 4 any of these programs in your own programs. If you need to contact me, my GEnieMail address is G.MCKINNEY1, or write: GEORGE MCKINNEY 1641 Western Drive Port Coquitlam, B.C. Canada V3C 2X1 or leave a message on the VANTARI BBS, (604) 432-9557 (21 November 1992) GEORGE MCKINNEY 1641 Western Drive Joystick Port Config for Output Atari can begin to control the outside world, not just sense it through the joystick ports. To do this we need an "output port." Inside the Atari is an integrated circuit numbered 6520, also called the PIA or Peripheral Interface Adapter. The PIA contains two 8-bit input/output (I/O) ports and two control registers. Associated with the PIA are two ACs, which monitor the address bus. Whenever an address between 54016 and 54271 is called, they alert the PIA to "come on-line." When selected, the PIA monitors only the first two address lines, so that it responds to every fourth address whithin the 54016 to 54271 range. The address 00110011 has the same low two bits as 00000011, and the PIA responds identically to either, so PEEK 54020 is the same as PEEK 54016. It's really a shame that better addressing wasn't included. Had it been, 252 byes in this section could be dedicated to external devices on the new XL/XE parallel bus, instead of the complex system now necessary. Oh well, nothing like wishful Thinking. Memory address 54016 and 54017 are called "port A" and "port B" respectively. On the XL/XE computers, port B controls memory banks. POKEing here can disrupt operation of the computer so thoroughly that even a RESET won't recover it. In the 400/800 computers, port B goes to joysticks 3 and 4. What's said about port A above applies to port B on these models. the connection is straight foward: Pin 1 of plug 1 controls bit 1 of port A. Pin 2 controls bit 2, and so on. As you you can see the results of activity on these pins by PEEKing 54016. The real secret to the 6520 chip is memory location 54018, or "port A control." Each bit controls a specific function. When bit 2 (4 in decimal) is set to 0, then writing to port A can alter the port's function from input to output. In this condidition, a 0 written to a bit in port A sets it to input, but a 1 sets it to output. Examine this listing:10 P=PEEK(54018):REM SAVE SONTROL SETTINGS FOR LATER20 POKE 54018,P-4:REM SETS BIT #2 TO 030 POKE 54016,15:REM ETS ALL 8 BITS TO OUTPUT40 POKE 54018,P:REM RESTORE PORT CONTROL Now, instead or PEEKing inputs from the joysticks, we can control the voltage on the joystick pins by POKEing to 54016, A 0 puts all pins to a logic 0, a 255 sets them all to 1, while 85 turns on every other pin. Line 30 reads POKE 54016,15 (00001111), then the first four pins or port A is outputs, and the last four inputs. joystick 1 would be outs and stick 2 would be ins. Note the reverse relationship between binary numbers and joystick pins. Now a 00000001 (binary 1) POKEd into 54016 turns on pins in the 1000/0000 order, where the 1 is an on and 0 if off. Let's put this theory to test on a reusable bread board. PLUG 1   1 2 3 4 5     6 7 8 9  Connect pins 1-4 of plug 2 to the #8 pin of plug 1. Use temporary jumpers. pin 1  2 |   L 3 |  E   D 4 |  |   | |  | |  | |  | | | 8 | | |  LEDs - Radio Shack #276-1622 Now add these lines to listing 1 and run it:100 N=1:GOSUB 1000110 N=2:GOSUB 1000120 N=4:GOSUB 1000130 N=8:GOSUB 1000140 GOTO 1001000 POKE 54016,N1020 FOR DELAY=1 TO 500:NEXT DELAY:RETURN If done correctly you'll see the four Light Emitting Diodes (LEDs) blink sequentially. If not, check the wiring and try reversing the LEDs. Now add the following line:1010 HINIBBLE=INT(PEEK(54016)/16)*16:? HINIBBLE This is the same formula as that for most significant byte, except you use 16 instead of 256. While this pro gram is running, connect and disconnect the jumpers on the section attached to joystick 2 You'll see the reflection of the jumpers on-screen while the LEDs continue to blink. This simple system demonstates true simultaneous input and output, and gives a simple example of what can be done. Okay. What can we do with our newfound power? Inputs can be any switch, while outputs lines can be connected to many different kinds of devices. You can control lamps, motors, stereos, TVs, alarm bells, sirens, beepers, and so on. However, the amount of power available to run these devices is limited to about 10 milliamperes (.01 amperes) from each joystick pin. A little beeper will work just fine, but most other devices need more power. Pin 7 carries +5 volts at 50 milliamperes. If you use pin 7, the pins 1-4 will be 0 for on, and 1 for off. In other words the output is inverted. This works because a logic gate at 0 output is allmost a short circuit to ground and presents little resistance electrical current. You can extend the driving power by providing an outside power source. An easy source to find and use is a 12 volt lantern battery. Connect the negative terminal to pin 8 or ground, but never connect the positive terminal to pin 7, ONLY to the device to be controlled. Then using pins 1-4 as the signal ground to activate the device. You should limit the external voltage to 12 volts. DO NOT hook into a plug-in device or anything which has high voltage, unless your sure it's completly isolated electrically from the wall current. A good way to isolate from a high power device is to use an "opto-coupler" RS #276-134 (rated at 1 amp)- it's an LED encapsssted with a light-sensitive switch, so theres no physical, electrical connection between input an output, or use RS #275-217 10 amp relay for super high-power controller. You could use a combination opto-coupler and TRIAC for a high power driver also (600 watts). light {o | | 120 volts | |  ----> || |o | o |6 5 4|||  | Opto- | ||| | | | Coupler |1 2 3||| |12 G|Triac | ||  |  | || | | pin 1 | |   | | pin 8 ^^^^ 220 ohms Above TRIAC requires a heat sink RS #276-1363 to keep it from over heating with full loads One last precaution: devices that plug in should be built into a box, to prevent you from touching places you shouldn'tEnd.20 ohms 盛 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 IgnoreCircuit Parts List:IC1: 74LS244 Octal noninverting buffer  pin 20 Vcc (+5V), Pin 10 groundIC2: 74LS75 Quad F Flipflops Pin 5 Vcc (+5V), pin 12 ground Circuit schematic and pin connectionsJoystick 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 por t 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 a vailable at the joystick ports (pin7). 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 regul ated 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 in to 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 MS"B 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 $D%010 (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. Tha&t'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 tr'ick. (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 ;o*utsignal 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. This took a considerable amount of effort for me to go back into my notes to type this information. After an amount of time went by I forgot some stuff so had to figure it all out again. I also have some notes not yet neatly types out, of my .DTMF tone decoder/encoder, and transiever PLL chip control (added scanning functions and direct frequency access to a CB radio). I put those 2 items above with some other gadgets I thought up, and used the 4 joystick ports of My Atari 800 as a half dupl/ex Phone patch/Repeater. And I know someone else that used the 8-Bit Interface for a controller of a Voice Messaging Service and is accually making money charging people for there message box! If your really interested in this stuff I may be able t0o make it understandable but there would be alot of work on my part to make it presentable. If you have no electronics background or the equipment the I would say the other stuff is beyond the scope of your capabilities... Any questions can be dir1ected to me VIA these 2 following BBS systems:Outter Limits BBS (617)665-0977, account handle: GumbyArgus Computerized Exchange (617)674-2345, account handle: Ricky NOTES: This text was entered using TextPro so you can reformat the text for prin2ter if you desire and still be able to view with a 40 Column ATASCII viewer... PORTCNFG.TXT - Explains how to set-up port for output/input using basic examples. 8BITINTR.TXT - Almost a full-blow 8-bit interface (IEEE-488). Included is a hardware s3chematic and an Action! Prgram example Enjoy!ewer... PORTCNFG.TXT - Explains how to set-up port for output/input using basic examples. 8BITINTR.TXT - Almost a full-blow 8-bit interface (IEEE-488). Included is a hardware sG`-----------` Using the `joystick as` output `-----------bDOS SYSbDUP SYS`ح`ЮϮ``筠``b*AUTORUN SYSb1SETUP BATb3MENU FOX`ЮϮ``筠``b*AUTORUN SYSb1SETUP BATb3MENU FOX`-----------`Ԡb;ANETA BASb>ANETB BASb ABINIT LSTbJBNETA BASbYBNETB BASb iBNETRE M65`-----------`Ԡb;ANETA BASb>ANETB BASb ABINIT LSTbJBNETA BASbYBNETB BASb iBNETRE M65b rBNETSN M65b |CNETA BASb CNETB BASbCNETEQU M65bCNETNR M65bCNETRE M65bCNETSN M65b CINIT LSTb rBNETSN M65b |CNETA BASb CNETB BASbCNETEQU M65bCNETNR M65bCNETRE M65bCNETSN M65b CINIT LSTb*JNET DOC`-----------`ɠ bPORTCNFGTXTb4IEEE TXTb-README 1ST`-----------b*JNET DOC`-----------`ɠ bPORTCNFGTXTb4IEEE TXTb-README 1ST`-----------