`8NNNN6$p NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNN}O`  @`! #@%`')/3@5`79;=?A C@E`GIKMO/S@U`WY]_a cogikmoq su`wy{} @`@ ` @ ` / @ ` O`  @`! #@%`')/3@5`79;=?A C@E`GIKMO/S@U`WY]_a cogikmoq su`wy{} @`@ ` @ ` / @ ` SWSWL 204MIDINET C|SERIAL NETj|d. C|.. C|ANETMCTRMODD|1ANETMCTRPRGG|dANETMIDIDFNL|*ANETMIDIH N|+/ANETMIDIID P|,;ANETMIDIID0R|-;ANETMIDIID1T|.;ANETMIDIID2V|/;ANETMIDIINTX|0 ANETMIDIMODZ|1|ANETMIDIPRGb|Q'ANETMIDIRSCe|[nANETMIDITXTg|` MODULE Control; (* by fred brooks logictek san diego ca PD software *) IMPORT GEMVDIbase, GEMAESbase, AESMenus, AESForms, AESObjects, AESEvents, AESResources ; FROM AESGraphics IMPORT GrafMouse; FROM AESObjects IMPORT ObjectDraw; FROM MYLIB IMPORT InitResource,Terminate, DeselectObject, dTree,MenuTree,x,y,w,h,InitWindow,CloseWindow; FROM SYSTEM IMPORT ADR,ADDRESS,CODE,TSIZE; FROM Strings IMPORT String, Concat; FROM XBIOS IMPORT SuperExec; FROM BIOS IMPORT DriveSet; FROM GEMDOS IMPORT ExecMode,Exec,Open,Close,Read,Write,Create; FROM Streams IMPORT StreamKinds; FROM M2Conversions IMPORT ConvertToCardinal; TYPE SequenceNr = [0..1]; control = RECORD magic : LONGCARD; USER : CARDINAL; REMOTEUSER : CARDINAL; reset : BOOLEAN; networkactive : BOOLEAN; remotedrive : CARDINAL; drivemap : DriveSet; nextframetosend : ARRAY [0..15] OF SequenceNr; frameexpected : ARRAY [0..15] OF SequenceNr; sendreset : BOOLEAN; END; consave = RECORD magic : LONGCARD; USER : CARDINAL; REMOTEUSER : CARDINAL; reset : BOOLEAN; networkactive : BOOLEAN; END; CONST resourcefilename = "ANETMIDI.RSC" ; RTS = 04E75H ; CONST ABOUT = 1 ; ABOUTOK = 1 ; MENU = 0 ; DESK = 3 ; MODE = 5 ; FILE = 4 ; USERID = 6 ; OPTIONS = 7 ; SEQ = 8 ; ABOUTNET = 11 ; QUIT = 21 ; LOAD = 20 ; INT = 23 ; MODE2 = 25 ; MODE1 = 24 ; REBOOTOK = 27 ; USERID1 = 29 ; USERID2 = 30 ; USERID3 = 31 ; USERID5 = 33 ; USERID4 = 32 ; USERID6 = 34 ; USERID7 = 35 ; USERID9 = 37 ; USERID8 = 36 ; USERID10 = 38 ; USERID11 = 39 ; USERID13 = 41 ; USERID12 = 40 ; USERID14 = 42 ; USERID15 = 43 ; USERID16 = 44 ; DRVA = 46 ; DRVB = 47 ; DRVD = 49 ; DRVC = 48 ; DRVE = 50 ; DRVF = 51 ; SEQUP = 53 ; S00 = 54 ; S10 = 55 ; S11 = 57 ; S01 = 56 ; VAR status : INTEGER; resourcename,nulls,on,off,netdrv : ARRAY [0..16] OF CHAR ; tempchar : ARRAY [0..2] OF CHAR; char : CHAR; result,handle : INTEGER ; done,OK : BOOLEAN; Cptr [0210H] : ADDRESS; Dptr [0214H] : DriveSet; Mptr [0218H] ,count : LONGCARD; C : POINTER TO control; CSAVE : POINTER TO consave; drvnr,i,usernumber,e : CARDINAL; idnumber : ARRAY [0..15] OF String; PROCEDURE DoAboutDialog ; BEGIN AESResources.ResourceGetAddr(GEMAESbase.RTree,ABOUT,dTree) ; AESForms.FormCenter(dTree,x,y,w,h) ; AESForms.FormDialogue(GEMAESbase.FormStart,0,0,0,0,x,y,w,h) ; AESForms.FormDialogue(GEMAESbase.FormGrow,0,0,0,0,x,y,w,h) ; ObjectDraw(dTree,0,10,x,y,w,h) ; result := AESForms.FormDo(dTree,-1) ; DeselectObject(ABOUT,ABOUTOK) ; AESForms.FormDialogue(GEMAESbase.FormShrink,0,0,0,0,x,y,w,h) ; AESForms.FormDialogue(GEMAESbase.FormFinish,0,0,0,0,x,y,w,h) ; END DoAboutDialog ; (* ------------------------------------------------------------------- *) PROCEDURE Events ; (* Handle resource events *) VAR pipeBuff : ARRAY [0..9] OF INTEGER ; PROCEDURE SelectMenu( Menu, Item : INTEGER ) ; BEGIN CASE Menu OF DESK : IF Item = ABOUTNET THEN DoAboutDialog ; END ; | FILE : CASE Item OF LOAD : C^.networkactive:=(NOT C^.networkactive); | QUIT : done := TRUE ; | ELSE END ; IF C^.networkactive THEN AESMenus.MenuText(MenuTree,LOAD,ADR(on)); ELSE AESMenus.MenuText(MenuTree,LOAD,ADR(off)); END; | MODE : CASE Item OF INT : Create("ANETMIDI.INT",0,handle); count:=TSIZE(consave); Write(handle,count,CSAVE); OK:=Close(handle); | REBOOTOK : CODE(03F3CH,0020H,04E41H, 042B9H,0,0420H,042B9H,0,043AH, 02079H,0,4,04ED0H) ; | ELSE END ; | USERID : CASE Item OF USERID1 : i:=0 ; | USERID2 : i:=1 ; | USERID3 : i:=2 ; | USERID4 : i:=3 ; | USERID5 : i:=4 ; | USERID6 : i:=5 ; | USERID7 : i:=6 ; | USERID8 : i:=7 ; | USERID9 : i:=8 ; | USERID10 : i:=9 ; | USERID11 : i:=10 ; | USERID12 : i:=11 ; | USERID13 : i:=12 ; | USERID14 : i:=13 ; | USERID15 : i:=14 ; | USERID16 : i:=15 ; | ELSE END ; AESMenus.MenuItemCheck(MenuTree,29+C^.REMOTEUSER,0); FOR e:=0 TO 30 DO IF (idnumber[0][e]=0C) OR (idnumber[0][e]= "=") THEN idnumber[0][e]:=0C; END; END; ConvertToCardinal(idnumber[0],OK,usernumber); IF OK THEN C^.USER := usernumber; (* set local id *) END; FOR e:=0 TO 30 DO IF (idnumber[i][e]=0C) OR (idnumber[i][e]= "=") THEN idnumber[i][e]:=0C; END; END; ConvertToCardinal(idnumber[i],OK,usernumber); IF OK THEN C^.REMOTEUSER := usernumber; (* set remote id *) END; AESMenus.MenuItemCheck(MenuTree,29+C^.REMOTEUSER,1); | SEQ : CASE Item OF SEQUP : C^.sendreset:= TRUE ; | ELSE END ; | ELSE END ; (* put header back normal*) AESMenus.MenuItemCheck(MenuTree,S00,0); AESMenus.MenuItemCheck(MenuTree,S10,0); AESMenus.MenuItemCheck(MenuTree,S01,0); AESMenus.MenuItemCheck(MenuTree,S11,0); IF (C^.nextframetosend[C^.REMOTEUSER]=0) AND (C^.frameexpected[C^.REMOTEUSER]=0) THEN AESMenus.MenuItemCheck(MenuTree,S00,1); END; IF (C^.nextframetosend[C^.REMOTEUSER]=1) AND (C^.frameexpected[C^.REMOTEUSER]=0) THEN AESMenus.MenuItemCheck(MenuTree,S10,1); END; IF (C^.nextframetosend[C^.REMOTEUSER]=0) AND (C^.frameexpected[C^.REMOTEUSER]=1) THEN AESMenus.MenuItemCheck(MenuTree,S01,1); END; IF (C^.nextframetosend[C^.REMOTEUSER]=1) AND (C^.frameexpected[C^.REMOTEUSER]=1) THEN AESMenus.MenuItemCheck(MenuTree,S11,1); END; AESMenus.MenuTitleNormal(MenuTree,Menu,1) ; END SelectMenu ; BEGIN GrafMouse(GEMAESbase.Arrow,NIL) ; (* put pointing mouse *) done := FALSE ; REPEAT AESEvents.EventMessage(ADR(pipeBuff)) ; CASE pipeBuff[0] OF (* message type *) GEMAESbase.MenuSelected : SelectMenu(pipeBuff[3],pipeBuff[4]) ; | GEMAESbase.WindowClosed : done := TRUE ; | ELSE END ; UNTIL done ; END Events ; (*$P- *) (* set vector to control record *) PROCEDURE getcontrol; BEGIN C := Cptr; CSAVE := Cptr; CODE(RTS); END getcontrol; BEGIN nulls:=" "; on :=" ON "; off:=" OFF "; SuperExec(PROC(getcontrol)); IF C^.magic#3141592653 THEN Exec(loadExecute,"ANETMIDI.PRG",nulls,nulls,result); IF result<0 THEN HALT END; SuperExec(PROC(getcontrol)); END; Open("ANETMIDI.INT",0,handle); IF handle>0 THEN (* if there is, load in init file *) count:=TSIZE(consave); Read(handle,count,CSAVE); OK:=Close(handle); END; Open("ANETMIDI.ID",0,handle); IF handle>0 THEN (* if there is, load in user file *) count:=1; FOR i:=0 TO 15 DO LOOP Read(handle,count,ADR(char)); IF (char=12C) THEN EXIT END; IF (char=12C) OR (char=15C) THEN char:=0C END; tempchar[0]:=char; Concat(idnumber[i],tempchar,idnumber[i]); END; END; OK:=Close(handle); ELSE result:=AESForms.FormAlert(1,"[3][You must have a ANETMIDI.ID|in this directory!][DARN]"); HALT; END; resourcename:=resourcefilename ; IF InitResource(resourcename,MENU) THEN FOR e:=29 TO 44 DO AESMenus.MenuText(MenuTree,e,ADR(idnumber[e-29])); END; AESMenus.MenuItemCheck(MenuTree,29+C^.REMOTEUSER,1); netdrv:=" DRV A = F"; drvnr:=2; WHILE drvnr IN C^.drivemap DO INC(drvnr); END; (* while *) INC(drvnr); netdrv[6]:="A"; netdrv[10]:=CHAR(041H+drvnr); AESMenus.MenuText(MenuTree,DRVA,ADR(netdrv)); netdrv[6]:="B"; netdrv[10]:=CHAR(041H+drvnr+1); AESMenus.MenuText(MenuTree,DRVB,ADR(netdrv)); netdrv[6]:="C"; netdrv[10]:=CHAR(041H+drvnr+2); AESMenus.MenuText(MenuTree,DRVC,ADR(netdrv)); netdrv[6]:="D"; netdrv[10]:=CHAR(041H+drvnr+3); AESMenus.MenuText(MenuTree,DRVD,ADR(netdrv)); netdrv[6]:="E"; netdrv[10]:=CHAR(041H+drvnr+4); AESMenus.MenuText(MenuTree,DRVE,ADR(netdrv)); netdrv[6]:="F"; netdrv[10]:=CHAR(041H+drvnr+5); AESMenus.MenuText(MenuTree,DRVF,ADR(netdrv)); CASE C^.remotedrive OF (* PLACE CHECK IN REMOTE MENU *) 0 : AESMenus.MenuItemCheck(MenuTree,DRVA,1); | 1 : AESMenus.MenuItemCheck(MenuTree,DRVB,1); | 2 : AESMenus.MenuItemCheck(MenuTree,DRVC,1); | 3 : AESMenus.MenuItemCheck(MenuTree,DRVD,1); | 4 : AESMenus.MenuItemCheck(MenuTree,DRVE,1); | 5 : AESMenus.MenuItemCheck(MenuTree,DRVF,1); | ELSE END; IF C^.networkactive THEN AESMenus.MenuText(MenuTree,LOAD,ADR(on)); ELSE AESMenus.MenuText(MenuTree,LOAD,ADR(off)); END; (* AESMenus.MenuItemCheck(MenuTree,S00,0); AESMenus.MenuItemCheck(MenuTree,S10,0); AESMenus.MenuItemCheck(MenuTree,S01,0); AESMenus.MenuItemCheck(MenuTree,S11,0); *) IF (C^.nextframetosend[C^.REMOTEUSER]=0) AND (C^.frameexpected[C^.REMOTEUSER]=0) THEN AESMenus.MenuItemCheck(MenuTree,S00,1); END; IF (C^.nextframetosend[C^.REMOTEUSER]=1) AND (C^.frameexpected[C^.REMOTEUSER]=0) THEN AESMenus.MenuItemCheck(MenuTree,S10,1); END; IF (C^.nextframetosend[C^.REMOTEUSER]=0) AND (C^.frameexpected[C^.REMOTEUSER]=1) THEN AESMenus.MenuItemCheck(MenuTree,S01,1); END; IF (C^.nextframetosend[C^.REMOTEUSER]=1) AND (C^.frameexpected[C^.REMOTEUSER]=1) THEN AESMenus.MenuItemCheck(MenuTree,S11,1); END; Events ; END; Terminate ; END Control.`` NX GEMXModula-2/ST (c) Copyright TDI Software Ltd. 1985, 1986. The team : Chris Hall, Paul Curtis, and Phil Camp .[3][Modula-2 Run Time Error : | | #][OK]NVN^Nu _b ШNYN"pNGNuNV*x ڄ=E*P-E@-M-VNh-H:. Eg :. Ef-n*.P-ENH:. Ef Nh-hN2:. Ef BBN:. E e Nh-PN-n I`8B,)n9n)n )n)n)n|.n 9`/@>,VNhYN`NsN^NuNVBn ncN:.EIBtP ndRn`I* -EI* -EI* -EI* -EI* -Ez-E=| Bn=|BnBn <I* "NB=|N=|=|=|Bn=|z-E <I* "NB=|4=|=|=|Bn=|(mI* -E <I* "NB=|Bn=|BnBn <I* "NBN pL?NAN^NuNV/-+NI|Gz+WBn:.IJ4PgRn`=y`:. E d:.I0PN(z0x8.  HDE:.IPRnz0x8. HDE:.IPRnIGzWBn:.I8.nGP@Rn:.IJ4Pg`N+_N^Nu OAbrpNGNurpNGF'/NNn-/=-/H"Q ,IL?/^>/^Nf,oNsF'/NNn-/=-/H"Q G*- =/^Nf,oNs/NNn-/=/-/H _"h$",HL?/^>/^Nf,oNsF'SSfWWNsSf>NsSfF NsSfNqNsSf NNsNhBBB 9`R!B*H$C! `N  <L?NAN`WNsNVH|".$. &(*HDHEHABBمCمHABBBCHBHCԃԄ-A -BL>N^NuNVHx". $.bBCh8BAHA62HC6BAHA`B6HCBAHA8<㑲eRCQ-C -ALN^NuNVH(. ,. dF<gBEVBBGVB0G|b.f ؆dRE`kgb|HDkSEjؼdREBJfBEJEnB`|mpN-D LN^Nu |oNNVH(. ,..HD:|glM||HF>|gXO||G|~mF H@HFB@H@2Ё"HAHFЁHD؀kSEؼdREJEk|m pNB` -D LN^NuNVH . $j ļfB".$j ļfBLN^NuNVH .$ļfBJLN^NuNVH .g*2<bH@|bQAU-@LN^NuNVH .j g` BA<☒|lB`|DAlpN⨰b-@LN^NuF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsNV . /2.??<NM*-E:. E b:.EI`V)PN:.E EI`)PN^NuNV/9`b?<N\/9`^?<N\/9`j?<N\/9`n?<N\/9`r?<N\/9`v?<N\/9`?<'N\/9`?<&N\/9`?<%N\N^NuNqNqNq O h*#`(y`#`N ( ШШ(y`N*,Ѕ.@//??<JNA (y`*,ڬ ڬڬ#`R/<l?<N\/<^?<N\/<z?<N\/<?<N\/<?<N\/<?<N\/<?<'N\/<?<&N\/<P?<%N\# `pNGN "NVps"9dNBN^NuNV3`3`3 `3 `3`N^NuN NVI`* #dIa* #dIb* #dIc* #dI`* #d#dd#dd#de#deId* #dN^N NVIe@89n9n 9n 9n <Ie * "NB3ele=yeN^NuNV3 eJ3eLN^NuNV3 eJ3 eL3eNN^NuNV3eJ3 eL3 eN3ePN^NuNV3eJ3eL3eN3eP3eR3 eT3 eV3eXN^NuNV(n 8en(n8epN^NuNV(n8en(n8ep(n 8er(n8etN^NuN NVIe"B BBBBIe Ge@* (Ge"* )EGeJ* )EGel* )E Ge|* )EGe* )EN^NNV3eJ# e|Bg?<?<?<?<BgN O 3eN^NuNV?. ?.N X# e|Bg?<?<?<?<BgN O 3eN^NuNV?. ?.N X# e|Bg?< ?<?<?<BgN O 3eN^NuNV?. ?.N X# e|Bg?<!?<?<?<BgN O 3eN^NuNV3 eJ#e|#eBg?<"?<?<?<BgN O 3eN^NuNV3eJ(n* #e|Bg?<#?<?<?<BgN O =_N^NuN NVN^N.NV3eJ# e|Bg?<2?<?<?<BgN O =_N^NuNV?.?.?.?.?.?.?. ?. N XO3eZBg?<3?< ?<BgBgN O 3eN^NuNV3eJ(n* #e|Bg?<4?<?<?<BgN O =_N^NuNV#e|Bg?<6Bg?<?<BgN O 3e(nHT(nHT(n HT(nHTN ON^NuNNVN^NNV?.?.?.?. N 0P3 eR3eT#e|Bg?<*?<?<?<BgN O 3eN^NuN(NVN^NNV#e|Bg?<Bg?<?<BgN O 3eN^NuNNVN^NNV(n* #e|Bg?<nBg?<?<BgN O 3eN^NuNVBg?<oBg?<BgBgN O 3eN^NuNV?.?. N XBg?<p?<?<Bg?<N O 3e(n(eN^NuNNVN^NNV?.?.?.?.?.?. ?. ?.N XOBg?<I?<?<BgBgN O 3eN^NuNV?.?.?.?.?.?. ?. ?.N XOBg?<J?<?<BgBgN O 3eN^NuNVBg?<MBg?<BgBgN O =_(nHT(nHT(n HT(nHTN O=nN^NuNV3 eJ#e|Bg?<N?<?<?<BgN O 3eN^NuNNVN^NNV?<dBg?< Bg(n ?N O Bye y eoN4:9eE(n89eDG`7P@ y elRye`N Bye y,eoN4:9eEIb89eD&n7P@ y,elRye`3-e y8eoN8:9eE-EIc89eD&n7P@ y8elRye`(n 8`N^NuNV?<eBgBgBg?.N O N N^NuNNVN^NNV3`?<Bg?<Bg?. N O N =yb N^NuNV3`?<Bg?<Bg?. N O N =yb N^NuNNVN^NNV?<r?<BgBg?. N O (n* #dN #ddN^NuNNVN^NNV?.?.?. ?. N 0P3eRBg?<d?<?<BgBgN O =_N^NuNV?.?.?. ?. N 0P3eRBg?<e?<?<BgBgN O 3eN^NuNV3eJBg?<f?<?<BgBgN O 3eN^NuNV3eJBg?<g?<?<BgBgN O 3eN^NuNV?.?.N XBg?<h?<?<BgBgN O 3e(nHT(nHT(n HT(nHTN ON^NuNV?.?.?.?. N 0P3 eR3eTBg?<i?<?<BgBgN O 3eN^NuNNVN^NNVBg?< Bg?<BgBgN O =_N^NuNVBg?<Bg?<BgBgN O 3eN^NuNNVN^NRNV# e|#eBg?<xBg?<?<BgN O 3eN^NuNNVN^N$NVB9eN^NuNVBg:. ?(nHTN\=_:.RE8.Ec :.RE=EBn:.SE?0.WoN&:.(n8.&nP@0.WlRn`T:.nb:.(nePN^NuNVBg:.?(n HTN\=_:. ndF=n :.n?0.WcN*:.n(n 8.&n P@0.WdRn`TN^NuNVBg:.?(nHTN\=_:.ndh:.n d^:.nnc:.nSE=EBn:.SE8.Eb :.n(n8.&nP@Rn`:.(nePN^NuNVBg:.?(nHTN\=_Bg:.?(nHTN\=_:.nJEf(neN:. TE8.nEd`N:. ?(nHT:.?(nHTNlO =n:.nSE?0.WcN*:.n(n8.&nP@0.WdRn`T:.n(nePN^NuNVBn:. ?0.WcN0:.(n4P9ef =nTN^Nu0.WdRn`T:. RE=EN^NuNVBg:.?(nHTN\=_Bg:.?(nHTN\=_JngJng:. nnc(n8B.N^Nu:.n=EBn:. n(n8.&n3@4PgN$Rn:.nf(n8 |N^Nu`Rn :. nc(n8B.N^Nu`NLNVN^N^N,NVBye3e/9e?.<< B':. ?(nHTN'ON^NuNVBye:.JElDE3e/9e?.<< Jnlz`z:. ?(nHTN'ON^NuNV:. nm=n N^NuN =n N^NuNV(nBB./.NXl|/.-_NB.Jnm8/./?.N-bXJfz`zE N^NuNVB?<??.(n //.N-~O (n (N^NuNVB?<@?.(n //.N-~O (n (N^NuNVB?<B/.?.z. ?N-O (n(N^NuNV(n * /(n* /(n* /z.0?pK?* #e*#e*#eNA*ye,ye.ye*(n8N^NuN-2NVN^N6CON:PRN:AUX:NV:. EdB.N^NuBn ncN2:.(n8.&n3@4PgB.N^Nu ndRn`|N^NuNVBn:.Ժnb<:.(nJ4Pg.:.(n4P ae zb_:.IPRn`:.IB4P(nBT(n9|/ B'?<)Hn?<Hy0*N0:O (_JgB,N/ B'?<)Hn?<Hy0/N0:O (_Jg |N/ B'?<)Hn?<Hy04N0:O (_Jg |N|J. fV/ ?<)HnBgHlN.O (_/ B?,<HlN/O (_/ B?,B'HnN/O (_NB/ ?<)Hn?<HlN.O (_Jll/ ?<)HnBgHlN.O (_Jll&n6B,N^NuNV(nBT(n , fB'(n ?,N/TJf(n8N^NuNV-n=|:. ?0.WcN"(n(nNTR0.WdRn`TN^NuNV nCp Qz. Nz:. -E?.Hn/.N/VO Nb/<.?. /.N2O NF/<.*?. /.N2O N*/<.j?. /.N2O NN Lh0 N^NuNV n Cp QHn?<I* /N2O N^NuNV n Cp QHn?<I* /N2O N^NuNV n Cp QHn?<I* /N2O N^NuNV-n=|:. ?0.WcN(Hn(nNX(nR0.WdRn`TN^NuNV nCp Qz. Npz:. -E?.Hn/.N/*O NJNF/<. ?. /.N4$O N*/<.L?. /.N4$O NN 4P0 N^NuNV n Cp QHn?<(n* /N4rO N^NuNV n Cp QHn?<(n* /N4rO N^NuNV n Cp QHn?<(n* /N4rO N^NuNV nCp Q. f4B?.<HnN/O *.ez`zE N^NuN B. N^NuN0NVN^N?ReadCardReadIntegerReadRealReadOctReadHexReadWordReadAdrcon:p NNV n Cp QHn.N3\N^Nup NNV nCp QHn< N6V\Hn< N6V\N^Nup NNV nCp QBn:. ?0.WcN@:.(nJ4Pf TN^NuNHn:.(n4PN6V\0.WdRn`TN^NupNNVHye:. ?(nHTN6O N^Nup NNV n Cp Q?. ?.?<dHyeN6O Hn?<dHyeN6O N^Nup NNV n Cp Q?. ?.?<dHyeNvO Hn?<dHyeN6O N^Nup NNV nCp Q/. ?. ?.?<dHyeNOHn?<dHyeN6O N^Nup NNV n Cp Q?. ?.?<dHyeN!NO Hn?<dHyeN6O N^Nup NNV n Cp Q?. ?.?<dHyeN!O Hn?<dHyeN6O N^Nup NNV nCp Q/. ?.?<dHyeN!O Hn?<dHyeN6O N^Nup NNV nCp Q/. ?.?<dHyeN!O Hn?<dHyeN6O N^Nup NNV nCp Q/. ?.?<dHyeN"*O Hn?<dHyeN6O N^Nup NNV n Cp QJ.g(nB.NnB'HnN5XJg (nBN^NuHn(nHTN5PJyef.(nJf&B'HnN5XJfHn(nHTN5P`(nTN^Nup NNV n Cp QHn(nHTN: P(n ae zb_(nN^Nup NNV nCp Q|N^Nup NNV nCp QHnHnN: P.  g`N^NupNNV nCp QBn:. ?0.WcNHnHnN: P.  fH:.(nB4PJ.fTN^NuHnHnN: P.  g HnN:XTN^NuN:.(nPJ.fTN^Nu0.WdRnNvTN^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-(nHTN"ZOJ9f-fHn?<Hy6N?O J9f-f`N^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-(nHTN#OJ9f-fHn?< Hy6N?O J9f-f`N^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-(nHTN#OJ9f-fHn?<Hy6'N?O J9f-f`N^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-(nHTN'OJ9f-fHn?<Hy60N?O J9f-f`N^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-(nHTN'VOJ9f-fHn?<Hy68N?O J9f-f`N^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-HnN#OJ9f-fHn?<Hy6@N?O J9f-f`(n8N^Nup NNV n Cp QHn?<dHyeN;^O ?<dHyeHyf-(nHTN'OJ9f-fHn?<Hy6IN?O J9f-f`N^NupNNV3eN^Nup NNV nCp QpNN^NuN6pNNVI6QGf.zWHye?<Hyf.B'HyeN0OHye?<Hyf.<HyeN0OBgN?TN^NOJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC[3][ Unable to find resource file| for this program.][GET "*.RSC" FILE]this is a testJUL286798.45[3][ No resource file for Modula-2| program. ][ Get "*.RSC" ]Copyright 1986, Fred Brooks LogicTek San Diego CA. <NNVZN^?<PHn?<#Hy@tNlO BnZ n!ZcN?<PHn?.Z?<?<PHn\NpOB':.?(nHT?<PHn\Bg(nHTNHOJg.JnZf (n 8Nz:.ZRE(n 8|N^Nu nZdVnZNvB.N^NupN <NNVZ| |B':.?(nHT?<PHn(n?(nHTNHOJg`N(n:RE=EZB':.?(nHT?<PHn?.ZHnZNHOJg`Nr:.?(nHT(n?:.Z(nT??<PHn\NpO(n8Z?<PHn\Hn(n HTN"ZOJ.g(n : Eb |N^NuB.N^NupN <NNVZ| |B':.?(nHT?<PHn(n?(nHTNHOJg`N:.?(nHT(n?Bg:.?(nHTN\:(nT??<PHn\NpO(n8Z?<PHn\Hn(n HTN"ZO(n : Elc(n : Ed(n :El(n 8J.g |N^NuB.N^NupNpNNNV?</Hyf@HyfBNOBgBgBgBgBg?9f?9f@?9fBN:O?<BgBgBgBg?9f?9f@?9fBN:OBg?<NHXBg?< NHXBg?< NHXI@GfzWBg?<?<cHyfNGO Bg?< ?<Hy@NGO Bg?< ?<Hy@NGO /9fDBg?< ?9f?9f@?9fBN:OBg/9fD?<N\3gRBg?< NIPX?<BgBgBgBg?9f?9f@?9fBN:O?<BgBgBgBg?9f?9f@?9fBN:OBg?<?<cHyfNFO N^NupNNVBg?<HyfDNJP/9fDHyfHyf@HyfBNOBgBgBgBgBg?9f?9f@?9fBN:O?<BgBgBgBg?9f?9f@?9fBN:O/9fDBg?< ?9f?9f@?9fBN:OBg/9fD??9f@?9fBN:O?<BgBgBgBg?9f?9f@?9fBN:ON^NupNNV:. H Nb:. EfNKNH:.H N(NIN(m|N N N N /9fH?. ?<N(PN^NupNNV/-+NBg/WBg?<?<cHnNP=_B.N^NuBg?.HyfHNJP/9fH?<N d\BgHyg@HygBHygDHygFNJO3fPBn n cN&:.K EIfR9P n dRn`3ffHyfRHyfPHyfhNO |N^NupNpNNV/9fHBgN d\N"?9fPNTNN^NuN?pNNVN^NONV ./p&?NNN^NuNONONONXANETMIDI.INT ON OFF ANETMIDI.PRGANETMIDI.INTANETMIDI.ID[3][You must have a ANETMIDI.ID|in this directory!][DARN]ANETMIDI.RSC DRV A = FpNNVBg?<HyfDNJP/9fDHyfHyf@HyfBNOBgBgBgBgBg?9f?9f@?9fBN:O?<BgBgBgBg?9f?9f@?9fBN:O/9fDBg?< ?9f?9f@?9fBN:OBg/9fD??9f@?9fBN:O?<BgBgBgBg?9f?9f@?9fBN:ON^NupNNV:. H Nb:. E fNPbNP:.H N<(ygJ, fz`z(ygE NgN N ,(ygJ, g"/9fH?<Igz* /NlO N /9fH?<Ig* /NlO N:.H N?< HyOBgHygN.O z #g?9gHyg/9gN/VO B'?9gN/TgN.?< NAB B: yNNN fN:.H NBygN3gN3gN3gN3gN3gN3gN3gN3gNz3 gNn3 gNb3 gNV3 gNJ3 gN>3gN23gN&N" ".:FR^jv/9fH(ygzl?BgN PByg ygcNX:9gKPIgJ4Pg:9gKPIg4P =f:9gKPIgB4P ygdRyg`?<PHygHygHygN"ZOJ9gg(yg9ygByg ygcN:9gKRIg89gIPIPJ4@g,:9gKRIg89gIPIP4@ =f&:9gKRIg89gIPIPB4@ ygd RygNt:9gKRIg?<PHtPHygHygN"ZOJ9gg(yg9yg/9fH(ygzl??<N PNF:.H N5 (yg|PNN NN b^*/9fH?<6BgN P/9fH?<7BgN P/9fH?<8BgN P/9fH?<9BgN P(yg&yg:+KEIJtPf6(yg&yg:+KEI0JtPf/9fH?<6?<N P(yg&yg:+KEI84P Df6(yg&yg:+KEI0JtPf/9fH?<7?<N P(yg&yg:+KEIJtPf:(yg&yg:+KEI084P Df/9fH?<8?<N P(yg&yg:+KEI84P Df:(yg&yg:+KEI084P Df/9fH?<9?<N P/9fH?. ?<N(PN^NupNNVBg/:$0 84$L* 2 "   (      4$$&     ,F             B .       *    (                             +MENU$DESK$FILE$MODE$OPTIONSUSERSSSEQSS ABOUTNETLOADNETQUITNETINTNETMODE1ETMODE2ETREBOOTOKDIAL1OKDIAL3OKDIAL2OK DIAL4OK!DIAL5OK#DIAL7OK"DIAL6OK$DIAL8OK%DIAL9OK'DIAL11K&DIAL10K(DIAL12K)DIAL13K+DIAL15K*DIAL14K,DIAL16K/DRVB6K.DRVA6K0DRVC6K1DRVD6K3DRVF6K2DRVE6K5SEQUPK7S10PK6S00PK8S01PK9S11PKABOUTKABOUTOKCONST MENU = 0 ; DESK = 3 ; FILE = 4 ; MODE = 5 ; OPTIONS = 7 ; USERS = 6 ; SEQ = 8 ; ABOUTNET = 11 ; LOAD = 20 ; QUIT = 21 ; INT = 23 ; MODE1 = 24 ; MODE2 = 25 ; REBOOTOK = 27 ; DIAL1 = 29 ; DIAL3 = 31 ; DIAL2 = 30 ; DIAL4 = 32 ; DIAL5 = 33 ; DIAL7 = 35 ; DIAL6 = 34 ; DIAL8 = 36 ; DIAL9 = 37 ; DIAL11 = 39 ; DIAL10 = 38 ; DIAL12 = 40 ; DIAL13 = 41 ; DIAL15 = 43 ; DIAL14 = 42 ; DIAL16 = 44 ; DRVB = 47 ; DRVA = 46 ; DRVC = 48 ; DRVD = 49 ; DRVF = 51 ; DRVE = 50 ; SEQUP = 53 ; S10 = 55 ; S00 = 54 ; S01 = 56 ; S11 = 57 ; ABOUT = 1 ; ABOUTOK = 1 ; 0 = freds 520st 1 = johns 1040st 2 = alonas 520st 0 = freds 520st 1 = johns 1040st 2 = alonas 520st 1 = johns 1040st 0 = freds 520st 2 = alonas 520st 2 = alonas 520st 0 = freds 520st 1 = johns 1040st @MMODULE NETWORK ; (* by fred brooks PD software *) (* -------------------------------------------------------------------------- NETWORK : MIDI MULTI CPU NETWORK FOR TDI Modula-2/ST --------------------------------------------------------------------------*) (*$T- *) (*$S- *) FROM SYSTEM IMPORT ADDRESS, ADR, SETREG, CODE, REGISTER ,BYTE ,TSIZE,SIZE; FROM GEMX IMPORT BasePageAddress, BasePageType ; FROM BIOS IMPORT BPB ,BConStat ,BConIn, BCosStat, BConOut, Device, MediaChange,MCState,GetBPB,RWAbs,RW,DriveSet,DriveMap; FROM XBIOS IMPORT SuperExec,SerialDevice,IORec,IORECPTR,IOREC,VSync; FROM GEMDOS IMPORT TermRes,Open,Close ; IMPORT GEMDOS; FROM ASCII IMPORT SYN,STX,SOH,BEL; CONST MaxSeq = 1; recsize = 511; MAGIC = 3141592653; USERS = 16; retry = 10; debug = FALSE; trace = FALSE; (* Because we dont know what registers the BIOS is using we must use the following opcodes to save the registers *) MOVEMDEC = 48E7H ; (* 68000 opcode for MOVEM ,-(A7) *) MOVEMINC = 4CDFH ; (* 68000 opcode for MOVEM (A7)+, *) SAVEREGS = 07FFCH ; (* Registers D1..A5 for DEC *) RESTREGS = 03FFEH ; (* Registers D1..A5 for INC *) RTS = 04E75H ; (* 68000 return from subroutine opcode *) TYPE (* Procedure types to mimic correct sequence for "C" BIOS routines *) CBPBProc = PROCEDURE ( CARDINAL ) ; CMediaChProc = PROCEDURE ( CARDINAL ) ; CRWAbsProc = PROCEDURE ( CARDINAL, CARDINAL, CARDINAL, ADDRESS, CARDINAL ); midibuffer = ARRAY [0..2000] OF CARDINAL; SequenceNr = [0..MaxSeq]; message = ARRAY [0..recsize] OF BYTE; message1 = ARRAY [0..17] OF BYTE; FrameKind = (ack,data,resetreq,resetconf,diag); DataKind = (rdmediareq,rdmediaconf,rdbpbreq,rdbpbconf, rdrwabsreq,rdrwabsconf); evtype = (framearrival,cksumerr,timeout,hostready,reset,nothing); frame = RECORD syn : CHAR; (* these are sync chars *) stx : CHAR; (* for the frames *) kind : FrameKind; seq : SequenceNr; ack : SequenceNr; cmd : DataKind; rw : CARDINAL; (* read or write data *) recno : CARDINAL; (* sector for data*) d0 : LONGCARD; (* data return variable *) info : message; user : CARDINAL; remoteuser : CARDINAL; cksum : CARDINAL; END; framecptr = POINTER TO framecmd; framecmd = RECORD syn : CHAR; (* these are sync chars *) stx : CHAR; (* for the frames *) kind : FrameKind; seq : SequenceNr; ack : SequenceNr; cmd : DataKind; rw : CARDINAL; (* read or write data *) recno : CARDINAL; (* sector for data*) d0 : LONGCARD; (* data return variable *) info : message1; user : CARDINAL; remoteuser : CARDINAL; cksum : CARDINAL; END; control = RECORD magic : LONGCARD; USER : CARDINAL; REMOTEUSER : CARDINAL; reset : BOOLEAN; networkactive : BOOLEAN; remotedrive : CARDINAL; drivemap : DriveSet; nextframetosend : ARRAY [0..15] OF SequenceNr; frameexpected : ARRAY [0..15] OF SequenceNr; sendreset : BOOLEAN; END; consave = RECORD magic : LONGCARD; USER : CARDINAL; REMOTEUSER : CARDINAL; reset : BOOLEAN; networkactive : BOOLEAN; END; vblqueueptr = POINTER TO ADDRESS; frameptr = POINTER TO ARRAY [0..1024] OF BYTE; VAR (* BIOS variables : These can only be accessed with the 68000 in supervisor mode. The Modula-2 language allows you to fix the location of variables *) HDBPB [0472H] : ADDRESS ; (* hard disk get Bios Parameter Block *) HDRWAbs [0476H] : ADDRESS ; (* hard disk read/write abs *) HDMediaCh [047EH] : ADDRESS ; (* hard disk media change *) DriveBits [04C2H] : SET OF [0..31]; (* disk drives present map *) Cptr [0210H] : ADDRESS; (* control record pointer *) Dptr [0214H] : DriveSet; (* save original drive map *) Mptr [0218H] : LONGCARD; charcount,framesize,cksum,recframesize,sndframesize, SIZEframe,SIZEframecmd : CARDINAL; vblqueue : vblqueueptr; (* set to vbl routines vector *) vblptr : vblqueueptr; networkconnect : BOOLEAN; (* DCD = 1 TRUE *) gotframe : BOOLEAN; framebufferfull : BOOLEAN; cleartosend : BOOLEAN; readytosend : BOOLEAN; requesttosend : BOOLEAN; framewaiting : BOOLEAN; timer,OK : BOOLEAN; gotmediach : ARRAY [0..5] OF BOOLEAN; gotbpb : ARRAY [0..5] OF BOOLEAN; vblactive : BOOLEAN; networkerror : BOOLEAN; shortframe : BOOLEAN; sframe,rframe,SFRAME,RFRAME, nframe1,nframe2 : frame; rframeptr,sframeptr, bpbptr,nbpbptr : frameptr; framecmdptr,framecmdptr1 : framecptr; event : evtype; C : control; recchar,timestart,timefortimeout,timeouttime : LONGCARD; timestart1,timefortimeout1,timeouttime1 : LONGCARD; i,i1,i2,i3,mediacount,handle : INTEGER; wsector,drvnr,DriveA,DriveF,devicestart,d,R, REMOTEUSER,receivedfromuser : CARDINAL; rbuffer : midibuffer; rbptr : IORECPTR; numBytes,sec,min,hour,time,count : LONGCARD ; status : LONGINT ; (* The following are saved copies of the BIOS variables so that the real hard disk routines can be called if a hard disk access is requested. *) SaveHDBPB : CBPBProc ; (* hard disk get Bios Parameter Block *) SaveHDRWAbs : CRWAbsProc ; (* hard disk read/write abs *) SaveHDMediaCh : CMediaChProc ; (* hard disk media change *) (* NETWORK control *) NetworkBPB : ARRAY [0..5] OF BPB ; (* BIOS Parameter block for NETWORK *) PROCEDURE MoveMemory ( From, To : ADDRESS ; Bytes : LONGCARD ) ; (* This routine shows how time critical portions of code can be optimised to run faster. It relys on the code generation rules of the compiler which can be checked by dis-assembling the link file with DecLnk.*) CONST MOVEB = 12D8H ; (* MOVE.B (A0)+,(A1)+ *) MOVEL = 22D8H ; (* MOVE.L (A0)+,(A1)+ *) A0 = 0+8 ; (* register A0 *) A1 = 1+8 ; (* register A1 *) BEGIN SETREG(A0,From) ; (* load From pointer into A0 *) SETREG(A1,To) ; (* load To pointer into A1 *) IF ( ODD(From) OR ODD(To) ) THEN (* must do bytes *) WHILE ( Bytes <> 0 ) DO CODE(MOVEB) ; DEC(Bytes) ; END ; ELSE (* even addresses so can do long moves *) WHILE ( Bytes > 3 ) DO CODE(MOVEL) ; DEC(Bytes,4) ; END ; WHILE ( Bytes <> 0 ) DO CODE(MOVEB) ; (* clean up remainder *) DEC(Bytes) ; END ; END ; END MoveMemory ; PROCEDURE inc(VAR k: SequenceNr); (* increment k circulary *) BEGIN IF k= DriveA) AND (device <=DriveF) THEN (* is NETWORK channel *) IF ( Flag = 0 ) OR ( Flag = 2 ) (* read *) THEN FOR wsector:=0 TO (SectorCount-1) DO C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); nframe1.recno:=RecordNum+wsector; nframe1.rw:=Flag; (* read *) resetnewdisk; IF getfromremote(rdrwabsreq,rdrwabsconf,nframe1) THEN MoveMemory(ADR(nframe1.info),Buffer+ADDRESS(wsector)*512, 512); status:=0; ELSE status:=(-11); END; (* if *) END; (* for *) IF networkerror THEN C.sendreset:=TRUE END; (* send network reset to remote cpu *) SETREG(D0,status) ; ELSIF ( Flag = 1 ) OR ( Flag = 3 ) THEN (* write *) FOR wsector:=0 TO (SectorCount-1) DO C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); nframe1.recno:=RecordNum+wsector; nframe1.rw:=Flag; (* write *) resetnewdisk; MoveMemory(Buffer+ADDRESS(wsector)*512,ADR(nframe1.info),512); IF getfromremote(rdrwabsreq,rdrwabsconf,nframe1) THEN status:=0; ELSE status:=(-10); END; END; (* for *) IF networkerror THEN C.sendreset:=TRUE END; (* send network reset to remote cpu *) SETREG(D0,status) ; ELSE SETREG(D0,LONGINT(-3)) ; END ; ELSE (* not NETWORK *) SaveHDRWAbs (device,RecordNum,SectorCount,Buffer,Flag) ; END ; CODE(MOVEMINC,RESTREGS) ; (* Restore registers from stack *) END RDRWAbs ; PROCEDURE RDMediaCh ( device : CARDINAL ) ; CONST D0 = 0 ; BEGIN CODE(MOVEMDEC,SAVEREGS) ; (* save registers on stack *) IF (device >= DriveA) AND (device <=DriveF) THEN (* is NETWORK channel *) C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); IF newdisk() THEN gotmediach[device-devicestart]:=FALSE; gotbpb[device-devicestart]:=FALSE; END; IF (NOT gotmediach[device-devicestart]) THEN IF getfromremote(rdmediareq,rdmediaconf,nframe1) THEN gotmediach[device-devicestart]:=TRUE; IF nframe1.d0=1 THEN nframe1.d0:=2 END; SETREG(D0,nframe1.d0) ; (* "C" uses D0 as return location *) ELSE SETREG(D0,Changed); END; ELSE SETREG(D0,NoChange) ; (* "C" uses D0 as return location *) END; ELSE (* not NETWORK *) SaveHDMediaCh(device) ; END; CODE(MOVEMINC,RESTREGS) ; (* Restore registers from stack *) END RDMediaCh ; PROCEDURE RDBPB ( device : CARDINAL ) ; CONST D0 = 0 ; BEGIN CODE(MOVEMDEC,SAVEREGS) ; (* save registers on stack *) IF (device >= DriveA) AND (device <=DriveF) THEN (* is NETWORK channel *) C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); IF newdisk() THEN gotbpb[device-devicestart]:=FALSE; gotmediach[device-devicestart]:=FALSE END; (* gotbpb[device-devicestart]:=FALSE; (* test *) *) IF (NOT gotbpb[device-devicestart]) THEN IF getfromremote(rdbpbreq,rdbpbconf,nframe1) THEN gotbpb[device-devicestart]:=TRUE; bpbptr:=ADR(nframe1.info); nbpbptr:=ADR(NetworkBPB[device-devicestart]); FOR i3:=0 TO TSIZE(BPB)-1 DO nbpbptr^[i3]:=bpbptr^[i3]; END; resetnewdisk; SETREG(D0,ADR(NetworkBPB[device-devicestart])); (* D0 returns address of the BPB *) ELSE SETREG(D0,0); END; ELSE SETREG(D0,ADR(NetworkBPB[device-devicestart])); (* D0 returns address of the BPB *) END; IF networkerror THEN C.sendreset:=TRUE END; (* send network reset to remote cpu *) ELSE (* not NETWORK *) SaveHDBPB(device) ; END ; CODE(MOVEMINC,RESTREGS) ; (* Restore registers from stack *) END RDBPB ; PROCEDURE resetnewdisk; BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timestart1:=LONGCARD(REGISTER(0)); timefortimeout1:=timestart1; IncTime(timefortimeout1,4); END resetnewdisk; PROCEDURE newdisk(): BOOLEAN; BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timeouttime1:=LONGCARD(REGISTER(0)); SETREG(0,timeouttime1); CODE(0280H,0,0FFFFH); timeouttime1:=LONGCARD(REGISTER(0)); IF timeouttime1>timefortimeout1 THEN resetnewdisk; RETURN TRUE; END; RETURN FALSE; END newdisk; (* ----------------------------------------------------------------------- *) PROCEDURE Initialise () : BOOLEAN ; (* returns TRUE if NETWORK is to be installed *) BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) CODE(2f00H,3f3cH,0016H,4e4eH,5c8fH); (* settime *) SuperExec(PROC(setcontrol)); (* set address of global control record *) rbptr:=IORec(MIDI); rbptr^.ibuf:=ADR(rbuffer); rbptr^.ibufsize:=4000; C.magic:=MAGIC; C.remotedrive:=0; C.USER:=1; C.REMOTEUSER:=1; framesize:=TSIZE(frame); recframesize:=framesize; sndframesize:=framesize; sframe.user:=C.USER; sframe.remoteuser:=C.REMOTEUSER; R:=0; RETURN TRUE; END Initialise ; (*$P- *) (* set vector to control record *) PROCEDURE setcontrol; BEGIN Cptr:=ADR(C); IF Mptr#MAGIC THEN C.drivemap:=DriveMap(); Dptr:=C.drivemap; END; C.drivemap:=Dptr; Mptr:=MAGIC; CODE(RTS); END setcontrol; (* this routine reads the 232 port data and sync's it into frames *) (* it runs as a background process in a vbl time slot *) (*$P- *) PROCEDURE recframe; BEGIN IF C.networkactive AND vblactive THEN CODE(02f39H,0,04a2H); (* move.l $4a2,-(sp) save BIOS pointer *) CODE(04b9H,0,02eH,0,04a2H); (* sub 46 from pointer *) nrecframe; Nwait(event); IF event#nothing THEN HandleEvents() END; CODE(023dfH,0,04a2H); (* restore BIOS pointer *) END; CODE(RTS); END recframe; PROCEDURE nrecframe; BEGIN WHILE (BConStat(HSS)) AND (NOT framebufferfull) DO recchar := BConIn(HSS); (* read midi port *) IF (CHAR(recchar)=SYN) AND (NOT gotframe) THEN gotframe:=TRUE; (* got sync char from data *) charcount:=0; END; IF (charcount=1) AND ((CHAR(recchar)#STX) AND (CHAR(recchar)#SOH)) THEN gotframe:=FALSE; (* false start try again *) charcount:=0; END; IF (charcount=1) AND (CHAR(recchar)=STX) THEN recframesize:=SIZEframe; END; IF (charcount=1) AND (CHAR(recchar)=SOH) THEN recframesize:=SIZEframecmd; END; IF gotframe THEN (* put data in buffer *) rframeptr^[charcount]:=BYTE(recchar); INC(charcount); IF charcount=recframesize THEN (* got full frame *) gotframe := FALSE; IF recframesize=SIZEframecmd THEN rframe.user:=framecmdptr^.user; rframe.remoteuser:=framecmdptr^.remoteuser; rframe.cksum:=framecmdptr^.cksum; END; IF (rframe.user=C.USER) AND C.networkactive THEN framebufferfull := TRUE; ELSE IF rframe.remoteuser#C.USER THEN REMOTEUSER:=rframe.user; sendf(rframe); (* retransmit *) END; END; END; END; END; (* WHILE *) END nrecframe; (* The following compiler directive stops the compiler from generating the normal Modula-2 entry/exit code for the next procedure. This is needed as this routine is called in supervisor mode by the BIOS function to install the BIOS vectors. *) (*$P- Stop entry/exit code for next procedure *) PROCEDURE InstallVectors ; BEGIN CODE(13FCH,3H,0FFFFH,0FC04H); (* RESET MIDI ACIA *) CODE(13FCH,95H,0FFFFH,0FC04H); (* SET NEW SPEED ON MIDI ACIA *) (* First save the current hard disk vectors *) SaveHDBPB := CBPBProc(HDBPB) ; SaveHDRWAbs := CRWAbsProc(HDRWAbs) ; SaveHDMediaCh := CMediaChProc(HDMediaCh) ; (* Now set the BIOS vectors to our routines *) HDBPB := ADDRESS(RDBPB) ; HDRWAbs := ADDRESS(RDRWAbs) ; HDMediaCh := ADDRESS(RDMediaCh) ; drvnr:=2; WHILE drvnr IN DriveBits DO INC(drvnr); END; (* while *) INC(drvnr); devicestart:=drvnr; DriveA:=drvnr; DriveF:=drvnr+5; INCL(DriveBits,drvnr) ; (* set new drive A *) INCL(DriveBits,drvnr+1) ; (* set new drive B *) INCL(DriveBits,drvnr+2) ; (* set new drive C *) INCL(DriveBits,drvnr+3) ; (* set new drive D *) INCL(DriveBits,drvnr+4) ; (* set new drive E *) INCL(DriveBits,drvnr+5) ; (* set new drive F *) networkconnect := FALSE; vblactive:=TRUE; gotframe := FALSE; framebufferfull := FALSE; charcount:=0; SIZEframe:=TSIZE(frame); SIZEframecmd:=TSIZE(framecmd); vblqueue := vblqueueptr(0456H); vblptr := vblqueue^; (* set to address of vbls *) rframeptr := ADR(rframe); framecmdptr:=ADR(rframe); sframeptr := ADR(sframe); LOOP (* set up vbl vector to make packet frame from 232 input *) IF vblptr^ = ADDRESS(0) THEN vblptr^ := ADDRESS(recframe); EXIT; ELSE (*$T-*) INC(vblptr,4) ; (*$T=*) END; END; (* LOOP *) CODE(RTS) ; (* code to return to calling BIOS function *) END InstallVectors ; (*$P+ *) PROCEDURE sendf(VAR f: frame); BEGIN sframe:=f; sframe.cksum:=0; IF ((sframe.cmd=rdrwabsconf) AND ((sframe.rw=0) OR (sframe.rw=2))) OR ((sframe.cmd=rdrwabsreq) AND ((sframe.rw=1) OR (sframe.rw=3))) THEN sndframesize:=SIZEframe; sframe.syn := SYN ; sframe.stx := STX ; sframe.remoteuser := C.USER ; sframe.user := REMOTEUSER; shortframe:=FALSE; IF trace THEN BConOut(CON,":") END; ELSE sndframesize:=SIZEframecmd; sframe.syn := SYN ; sframe.stx := SOH ; framecmdptr1:=ADR(sframe); framecmdptr1^.remoteuser := C.USER ; framecmdptr1^.user := REMOTEUSER; shortframe:=TRUE; IF trace THEN BConOut(CON,".") END; END; FOR i1:=0 TO sndframesize-5 DO (* compute checksum *) sframe.cksum:=sframe.cksum+CARDINAL(sframeptr^[i1]) END; IF shortframe THEN framecmdptr1^.cksum:=sframe.cksum END; FOR i1:=0 TO sndframesize-1 DO (* send frame *) BConOut(HSS,CHAR(sframeptr^[i1])); END; REPEAT UNTIL BCosStat(HSS); (* wait until all sent *) END sendf; PROCEDURE getf(VAR f: frame); BEGIN f:=rframe; framebufferfull:=FALSE; END getf; PROCEDURE waitcts(what: BOOLEAN); (* wait for cleartosend state *) BEGIN IF what THEN REPEAT nrecframe; Nwait(event); HandleEvents(); IF R>retry THEN networkerror:=TRUE; RETURN; (* trouble *) END; UNTIL cleartosend; RETURN; ELSE LOOP nrecframe; Nwait(event); IF (NOT cleartosend) THEN EXIT END; HandleEvents(); IF R>retry THEN networkerror:=TRUE; RETURN; (* trouble *) END; END; (* loop *) IF trace THEN BConOut(CON,"N") END; HandleEvents(); END; END waitcts; (* request for data from remote hosts disk drives and system *) (* what wanted in command, the correct reply in reply, data in f *) PROCEDURE getfromremote(command, reply: DataKind; VAR f: frame): BOOLEAN; BEGIN IF (NOT C.networkactive) THEN RETURN FALSE END; (* error *) networkerror:=FALSE; R:=0; StartTimer; vblactive:=FALSE; IF trace THEN BConOut(CON,"A") END; f.kind:=data; f.cmd:=command; waitcts(TRUE); IF networkerror THEN RETURN FALSE END; IF trace THEN BConOut(CON,"B") END; SFRAME:=f; REMOTEUSER := C.REMOTEUSER; requesttosend:=TRUE; waitcts(FALSE); IF networkerror THEN RETURN FALSE END; IF trace THEN BConOut(CON,"C") END; REPEAT nrecframe; Nwait(event); HandleEvents(); IF R>retry THEN networkerror:=TRUE END; IF networkerror THEN RETURN FALSE END; UNTIL framewaiting AND (RFRAME.cmd=reply); IF trace THEN BConOut(CON,"D") END; f:=RFRAME; f.rw:=5; framewaiting:=FALSE; REMOTEUSER := C.REMOTEUSER; sendtoremote(ack,reply,f); (* send ack for reply *) IF networkerror THEN RETURN FALSE END; IF trace THEN BConOut(CON,"Z") END; vblactive:=TRUE; VSync; RETURN TRUE; END getfromremote; PROCEDURE sendtoremote(type: FrameKind; command: DataKind;VAR f: frame); BEGIN IF trace THEN BConOut(CON,"T") END; f.kind:=type; f.cmd:=command; IF debug THEN cleartosend:=TRUE END; (* so we can send in loop *) waitcts(TRUE); IF trace THEN BConOut(CON,"1") END; SFRAME:=f; requesttosend:=TRUE; waitcts(FALSE); IF trace THEN BConOut(CON,"2") END; IF SFRAME.kind=ack THEN cleartosend:=TRUE END; END sendtoremote; PROCEDURE ToHost(VAR f: frame); BEGIN IF trace THEN BConOut(CON,"H") END; IF f.kind=diag THEN framewaiting:=FALSE; RETURN; END; IF f.kind=data THEN IF f.cmd=rdmediareq THEN IF trace THEN BConOut(CON,"M") END; framewaiting:=FALSE; nframe2.d0:=LONGCARD(MediaChange(CARDINAL(f.d0))); REMOTEUSER := receivedfromuser; sendtoremote(data,rdmediaconf,nframe2); RETURN; END; IF f.cmd=rdbpbreq THEN IF trace THEN BConOut(CON,"P") END; framewaiting:=FALSE; nframe2.d0:=LONGCARD(GetBPB(CARDINAL(f.d0))); bpbptr:=ADDRESS(nframe2.d0); nbpbptr:=ADR(nframe2.info); FOR i:=0 TO TSIZE(BPB)-1 DO nbpbptr^[i]:=bpbptr^[i]; END; REMOTEUSER := receivedfromuser; sendtoremote(data,rdbpbconf,nframe2); RETURN; END; IF f.cmd=rdrwabsreq THEN IF trace THEN BConOut(CON,"W") END; framewaiting:=FALSE; nframe2.d0:=LONGCARD(RWAbs(RW(f.rw),ADR(f.info),1,f.recno, CARDINAL(f.d0))); IF (f.rw=0) OR (f.rw=2) THEN nframe2.rw:=f.rw; nframe2.info:=f.info; (* if rec get buffer to send *) END; REMOTEUSER := receivedfromuser; sendtoremote(data,rdrwabsconf,nframe2); RETURN; END; END; END ToHost; PROCEDURE senddata; BEGIN SFRAME.seq:=C.nextframetosend[SFRAME.remoteuser]; SFRAME.ack:=1-C.frameexpected[SFRAME.remoteuser]; sendf(SFRAME); IF (SFRAME.kind#ack) AND (SFRAME.kind#resetreq) THEN StartTimer; (* set timer to wait for frame ack from remote host *) END; END senddata; PROCEDURE StartTimer; BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timestart:=LONGCARD(REGISTER(0)); timer:=TRUE; (* test *) timefortimeout:=timestart; IncTime(timefortimeout,4); END StartTimer; PROCEDURE IncTime(VAR t : LONGCARD; c: CARDINAL); BEGIN IF c<1 THEN RETURN END; time:=t; SETREG(0,time); CODE(0280H,0,001FH); sec:=LONGCARD(REGISTER(0)); time:=t; SETREG(0,time); CODE(0280H,0,07E0H); min:=LONGCARD(REGISTER(0)); min:=min DIV 32; time:=t; SETREG(0,time); CODE(0280H,0,0F800H); hour:=LONGCARD(REGISTER(0)); hour:=hour DIV 2048; WHILE c#0 DO sec:=sec+1; c:=c-1; IF sec>29 THEN sec:=sec-30; min:=min+1; END; IF min>59 THEN min:=min-60; hour:=hour+1; END; IF hour>23 THEN hour:=hour-24; END; END; (* while *) t:=0; t:=sec; t:=t+(min*32); t:=t+(hour*2048); END IncTime; PROCEDURE TimeOut(): BOOLEAN; BEGIN IF (NOT timer) THEN RETURN FALSE END; CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timeouttime:=LONGCARD(REGISTER(0)); SETREG(0,timeouttime); CODE(0280H,0,0FFFFH); timeouttime:=LONGCARD(REGISTER(0)); IF timeouttime>timefortimeout THEN StartTimer; RETURN TRUE; END; RETURN FALSE; END TimeOut; PROCEDURE Nwait(VAR e: evtype); BEGIN IF requesttosend AND cleartosend THEN e:=hostready; requesttosend:=FALSE; cleartosend:=FALSE; RETURN; END; IF C.sendreset THEN e:=reset; END; IF framebufferfull THEN cksum:=0; FOR i2:=0 TO recframesize-5 DO cksum:=cksum+CARDINAL(rframeptr^[i2]) END; IF (cksum=rframe.cksum) THEN receivedfromuser := rframe.remoteuser; e:=framearrival; INC(R); ELSE e:=cksumerr; framebufferfull:=FALSE; IF trace THEN BConOut(CON,"U") END; END; RETURN; END; nrecframe; IF TimeOut() THEN e:=timeout; INC(R); END; (* so sorry no frame ack *) END Nwait; PROCEDURE HandleEvents(); BEGIN IF event=hostready THEN event:=nothing; IF trace THEN BConOut(CON,"S") END; senddata; END; IF event=reset THEN IF trace THEN BConOut(CON,"I") END; charcount:=0; R:=0; gotframe:=FALSE; framebufferfull:=FALSE; FOR d:=0 TO 5 DO gotmediach[d]:=FALSE; gotbpb[d]:=FALSE; END; C.nextframetosend[SFRAME.remoteuser]:=0; C.frameexpected[SFRAME.remoteuser]:=0; cleartosend:=TRUE; requesttosend:=FALSE; framewaiting:=FALSE; timer:=FALSE; C.sendreset:=FALSE; event:=nothing; SFRAME.kind:=resetreq; senddata; END; IF event=framearrival THEN event:=nothing; IF (rframe.kind=ack) OR (rframe.kind=resetreq) THEN framewaiting:=FALSE END; IF trace AND (NOT framewaiting) THEN BConOut(CON,"F") END; IF (NOT framewaiting) THEN getf(RFRAME) END; framebufferfull:=FALSE; IF (RFRAME.ack=C.nextframetosend[RFRAME.remoteuser]) OR debug THEN IF trace THEN BConOut(CON,"K") END; cleartosend:=TRUE; StartTimer; R:=0; timer:=FALSE; inc(C.nextframetosend[RFRAME.remoteuser]); END; IF (RFRAME.seq=C.frameexpected[RFRAME.remoteuser]) OR debug THEN IF trace THEN BConOut(CON,"E") END; IF RFRAME.kind#ack THEN (* try to exec command *) inc(C.frameexpected[RFRAME.remoteuser]); framewaiting:=TRUE; R:=0; ToHost(RFRAME); END; END; IF RFRAME.kind=resetreq THEN IF trace THEN BConOut(CON,"*") END; charcount:=0; gotframe:=FALSE; framebufferfull:=FALSE; C.nextframetosend[RFRAME.remoteuser]:=0; C.frameexpected[RFRAME.remoteuser]:=0; FOR d:=0 TO 5 DO gotmediach[d]:=FALSE; gotbpb[d]:=FALSE; END; cleartosend:=TRUE; requesttosend:=FALSE; framewaiting:=FALSE; timer:=FALSE; C.sendreset:=FALSE; event:=nothing; END; END; SFRAME.seq:=C.nextframetosend[SFRAME.remoteuser]; SFRAME.ack:=1-C.frameexpected[SFRAME.remoteuser]; IF event=timeout THEN event:=nothing; IF trace THEN BConOut(CON,"R") END; sendf(SFRAME); framewaiting:=FALSE; END; END HandleEvents; BEGIN (* body of module *) IF Initialise() THEN charcount:=0; gotframe:=FALSE; framebufferfull:=FALSE; FOR d:=0 TO 15 DO C.nextframetosend[d]:=0; C.frameexpected[d]:=0; END; FOR d:=0 TO 5 DO gotmediach[d]:=FALSE; gotbpb[d]:=FALSE; END; cleartosend:=TRUE; requesttosend:=FALSE; framewaiting:=FALSE; timer:=FALSE; C.sendreset:=FALSE; event:=nothing; C.networkactive:=TRUE; SuperExec(PROC(InstallVectors)) ; (* install the NETWORK *) Open("ANETMIDI.INT",0,handle); IF handle>0 THEN (* if there is, load in init file *) count:=TSIZE(consave); GEMDOS.Read(handle,count,ADR(C)); OK:=Close(handle); END; WITH BasePageAddress^ DO TermRes(CodeLen+BssLen+LONGCARD(CodeBase-ADDRESS(BasePageAddress)),0); END; END ; END NETWORK. `$`N#* GEMXModula-2/ST (c) Copyright TDI Software Ltd. 1985, 1986. The team : Chris Hall, Paul Curtis, and Phil Camp .[3][Modula-2 Run Time Error : | | #][OK]NVN^Nu"pNGNuNV*x ڄ=E*P-E@-M-VNh-H:. Eg :. Ef-n*.P-ENH:. Ef Nh-hN2:. Ef BBN:. E e Nh-PN-n I$8B,)n9n)n )n)n)n|.n 9$/@>,VNhYN`NsN^NuNVBn ncN:.EIBtP ndRn`I* -EI* -EI* -EI* -EI* -Ez-E=| Bn=|BnBn <I* "NB=|N=|=|=|Bn=|z-E <I* "NB=|4=|=|=|Bn=|(mI* -E <I* "NB=|Bn=|BnBn <I* "NBNpL?NAN^NuNV/-+NI|Gz+WBn:.IJ4PgRn`=y$:. E d:.I0PN(z0x8.  HDE:.IPRnz0x8. HDE:.IPRnIGzWBn:.I8.nGP@Rn:.IJ4Pg`N+_N^Nu OAbrpNGNurpNGF'/NNn-/=-/H"Q ,IL?/^>/^Nf,oNsF'/NNn-/=-/H"Q G*- =/^Nf,oNs/NNn-/=/-/H _"h$",HL?/^>/^Nf,oNsF'SSfWWNsSf>NsSfF NsSfNqNsSf NNsNhBBB 9$!B*H$C! `N <L?NAN`WNsNVHx". $.bBCh8BAHA62HC6BAHA`B6HCBAHA8<㑲eRCQ-C -ALN^NuNVH(. ,. dF<gBEVBBGVB0G|b.f ؆dRE`kgb|HDkSEjؼdREBJfBEJEnB`|mpN-D LN^NuF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsNV . /2.??<NM*-E:. E b:.EI%)PN:.E EI%0)PN^NuNV/9% ?<N\/9%?<N\/9%?<N\/9%?<N\/9%?<N\/9% ?<N\/9%L?<'N\/9%H?<&N\/9%D?<%N\N^NuNqNqNq O h*#$(y$#$ ( ШШ(y$*,Ѕ.@//??<JNA (y$*,ڬ ڬڬ#$/<R?<N\/<D?<N\/<`?<N\/<n?<N\/<|?<N\/<?<N\/<?<'N\/<?<&N\/<2?<%N\#$pNGN NVz.0?p?NM*EE N^NuNVz.0?p?NM*EE N^NuNVz.0?p?NM*-E N^NuNV.?z. 0?p?NMN^NuNV0.?0. ?0. ? ./z.0?p?NM*-EN^NuNV0.?p?NM*-E N^NuNV0.?p ?NM*E N^NuNVp ?NM*-EN^NuNN NVz.0?p?NN*-E N^NuNVp%?NNN^NuNV ./p&?NNN^NuN N NV0.?NA*-E N^NuNV0.?0. ?NA*-E N^NuNV ./ . /0.?0.?NA*-EN^NuNV ./0. ?NA*-EN^NuNV0.? . /0.?NA*-EN^NuNV0.?0. ? . /0.?NA*-EN^NuNVB?<1/. ?.N P-_N^NuNVB?<=(n* /?. N P*(n8N^NuNVB?<>?.N 8XJfz`zE N^NuNVB?<??.(n //.N TO (n (N^NuN NVN^N pNNV.  e. ~b| N^NuN B. N^NupNpNNVJ.e . c . f| N^NuN B. N^NupNN pNNVN^N#0ANETMIDI.INTNV n"n *.f *. gJgS`N"z(.c"Y`JgS`N^NuNV(n: Ed(n:RE(n8N(nBTN^NuNVHBB:.y2e:.y2b`NJng :. Ef`NBy2:.SE?092аWcN:.y232`:.y2#.:.y23.3.NB'<<Hy. N6PJg4I.* /z:92p ڮ /HxN >O BBN z#B092аWd Ry2NRTJ9%g2 9BN:. Eg :. Ef`NBy2:.SE?092аWcN:.y232`:.y2#.:.y23.3.Nz:92p ڮ /I.* /HxN >O B'<<Hy. N6PJg BBN z#B092аWd Ry2NRTJ9%g2 9BNpN"?.?.?./. ?.(yBNO L?N^NuNVH:.y2e:.y2b`N:.y232`:.y2#.B'N Jg(:.y2I%B4P:.y2I%B4P:.y2I%J4PfTB'B'<Hy. N6PJg4:.y2I%Pz(9.fz#. 9.NpNpN?.(yBNTL?N^NuNVH:.y2e:.y2b`N~:.y232`:.y2#.B'N Jg(:.y2I%B4P:.y2I%B4P:.y2I%J4Pf`NB'<<Hy. N6PJg`N:.y2I%PI.* #2D:.y2IBIP( #2HBy2 y2oN2(y2D:92&y2H892P@ y2lRy2`N:.y2IBIP( NpN:.y2IBIP( J9%g2N?.(yBNTL?N^NuNV?<NNT*#2#22Hy2?<N\N^NuNV?<NNT*#2 92*#2*922cN|N^NuB.N^NuNV?<NNT/?<NN\*</N XB<N T#BI2* (yB((yB9|#@M2VBy2`32Z32\3%~3%~%3%~%32Z'32\'By2|N^NuI2V* !*8 @MgBN #2b!2b#2b!@MNuJ92_gDJ9%g#NuNVB'<NTJg J9%f`NtB<N T#2*92 fJ9%f%By%|:9%| Ef$*92 g*92 g B9%By%|:9%| Ef*92 f 3%%:9%| Ef*92 f 3%%J9%g`N*92(y2<89%|@Ry%|:9%|y%f`NB9%:9%y%f*(y2L3$)(y2L3&)(y2L3():9)ֺy2ZfJ92_g %N(:9)غy2Zg3)2Hy'NXNpN^Nu#rB#vB#~B*< !r*< !v*<!~32*8892 D ex` gRy2`Ry2322322:92ZE32:92p :92REp :92TEp :92VEp :92XEp :92ZEp B9%%B9%B9%By%|3%3*%#V%(y%#%I'* #2:92 E c %N^NuJ9%f`N^NuNHNHy2TN@XJ9%fN"N >:92 E c %N^Nu`N >N^NuNVJ92_fB.N^NuB9%By2NFB9%(n|(nn<NTJ9%gB.N^Nu(nG)*<&Q32\2%B'NTJ9%gB.N^NuNHy2TN@XN >:92 E c%J9%gB.N^NuJ9%g 9+. g`I+&n*<&Q(n9| B9%32\2B'. (nHTNPJ9%gB.N^Nu%N |N^NuNV(nn(nn <NT(nG)*<&Q%B'NTJ9)f%N^NuNV(n, f B9%N^Nu(n, f`N(nJ,fHB9%B'(n*,?N Tz#02322<<Hy0$NPN^Nu(n, f`NB9%B(n*,?N T#02#022DI06* #2HBy2 y2oN2(y2D:92&y2H892P@ y2lRy2`322<<Hy0$NPN^Nu(n, f`NB9%B(nz:, (nI* /?<(n?, (n*,?N LO #02(nJl g(n:, Ef"(n3 0.(nIG06z&Q322<<Hy0$NPN^NuN^NuNV:9+EI2f3P):9+EI2xtP3)Hy)NXJ9)g9) gNFN^NuNV?<NNT*#2%#22Hy2?<N\N^NuNV:. EdN^Nu(n #B 9B*#B(n #B 9B*#B*9B#B(n #B 9B*#B*9B#BJng`N*9BR#B:.SE=Ez(9Bcz(9B#B*9BR#Bz;(9Bcz<(9B#B*9BR#Bz(9Bcz(9B#BNj(n B(n (B*9B(n ڔ(n (*9Bp (n ڔ(n (N^NuNVJ9%fB.N^Nu?<NNT*#2 92*#2*922cNF|N^NuB.N^NuNVJ9%g J9%g(nB9%B9%N^NuJ92g(nJ9%g`NBy%By2:9%[E?092ȰWoN2(y2<:92x4Py%3%092ȰWlRy2`T:9%y)f3)2(nBRy2N(nB9%N^NuNB'NJg(nRy2N^NuNV92T f2TN92T f`NBy%|By2B9%B9%By2 y2cN4:92I%B4P:92I%B4P y2dRy2`:9+EI2fBtP:9+EI2BtP%B9%B9%B9%B922T)NJ92Tf`N2TJ9'g 9' fB9%J9%fHy+NzXB9%:9.EI2f89+tPf4%NFBy2B9%:9.EI2fHtPN X:9.EI289+tPf>J9+g6:9.EI2HtPN X%By2Hy+NX9+ f`NBy%|B9%B9%:9.EI2fBtP:9.EI2BtPBy2 y2cN4:92I%B4P:92I%B4P y2dRy2`%B9%B9%B9%B922T:9+EI2f3P):9+EI2xtP3)92T f2THy)NXB9%N^NuN NVB'NZJg`NpBy%|B9%B9%By2 y2cN8:92EI2fBtP:92EI2BtP y2dRy2`By2 y2cN4:92I%B4P:92I%B4P y2dRy2`%B9%B9%B9%B922T2_*<8/N X?< Hy 0BgHy2N O Jy2o>z #B?92HyBI2V* /N VO B'?92N .T%(y$/ *,$(, ج؅/BgN \(_N^NuV<N*nD "4         (          F&"2 6< $    $   $             .         "                 ,  (    6 $   "                                        `XX$X`fQn Desk NETWORK MODE USERS REMOTE DRIVES SEQUENCE ABOUT ANETMIDI-------------------- Desk Accessory 1 Desk Accessory 2 Desk Accessory 3 Desk Accessory 4 Desk Accessory 5 Desk Accessory 6 QUIT MAKE INT MIDI ------------ ------------ REBOOT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- DRIVE A DRIVE B DRIVE C DRIVE D DRIVE E DRIVE F NEW 0 0 1 0 0 1 1 1 ANETMIDI MENU COMMANDSLOCICTEK San Diego Ca 619-584-0281 1987OKNETWORK: ON-OFF TOGGLE FOR MIDI PORT.NETWORK: "QUIT" EXIT CONTROL PROGRAM.MODE : "MAKE INT" CREATE ANETMIDI.INTTO LOAD SETUP PARAMETERS FOR ANETMIDI.ON REMOTE SYSTEM.REMOTE : WHAT DRIVE IDENTIFIER IS DRIVESEQU : "NEW" SEND SYNC COMMAND TOREMOTE TO RESETMESSAGE SEQUENCE NUMBERS.FILEBy Fred BrooksDEVELOPED WITH TDI MODULA-2CVERSION 1.00USERS : NETWORK ID NUMBERS FOR NODESPD software?@ >P?$B ?@<X0f}~#&&&('N'Oab($" #I&JV  P P> $ +  5  = D" U3  4P  _ q     "/>L-,[u !"#$%&+'E (_ )y * + ,4.3$ / 0 1 2" 3/ -<  5956I7N8T9Z4 `;` "%% *' F & b  ~'  #(  , &"B-^-z( %  > This program is an attempt to try to make a very simple ST to ST link. The main objective was to make it as transparent as possible to the user and to other programs. In a multi ST MIDI loop all ST's in the loop must all be running the ANETMIDI.PRG for the NETWORK to work. LOADING AND SETUP ANET uses three user vectors starting at $210 and the drivemap located at $4C2. A reset using the reset buttom sometimes does not clear the lower system memory so if this program is resident you must use a cold start "power off and power on" or a reboot program for it to be reloaded correctly when you run the ANETMIDI.PRG or ANETMCTR.PRG after the reboot. The ANETMCTR.PRG has a reboot selection on the MENU. Double-click on the ANETMIDI.PRG to load the resident program then double-click on the ANETMCTR.PRG to load the control program. After the first load you can usually load both the resident and control programs by running ANETMCTR.PRG after a reboot. ONLY LOAD THE ANETMIDI.PRG IF YOU GET A MODULA-2 ERROR TRYING TO RUN ANETMCTR.PRG FIRST. AS IT WILL LOAD THE ANETMIDI.PRG FOR YOU. The control program lets you select the remote user, reboot the ST, reset the network message sequence count, turn the network on and off, see which ICONS to install to use the remote disks and of course to quit the control program. The NEW command on the sequence MENU is to resync the remote program if it gets out of sync due to a reboot, hang or and error condition. Click the mouse on NEW to send a resync command to the remote and try to access the ICON again. MAKE INT on the mode MENU will make a network setup file called ANETMIDI.INT that ANETMIDI.PRG reads to set the baud rate and to turn the netork on or off. ANETMCTR.PRG also reads the INT file when it is loaded and uses the parameters to set up the menu values. Clicking the pointer on MAKE INT will save the current menu values on the ANETMCTR.PRG menu to a new ANETMIDI.INT file. I have included sample user files ANETMIDI.ID ,ANETMIDI.ID0, ANETMIDI.ID1, ANETMIDI.ID2. These should be renamed to ANETMIDI.ID for the ST that you decide to be users 0 thru 2. You can of course add more users or change the user numbers as you like. A check by the user in the menu shows the current remote user selected. Click on another user to change the remote system. MAKE INT will save the new default user if you want it to save it. The first entry will be assigned to the local ST user number. USE Install the ICONS on the GEM DESKTOP for the remote system drive(s) you wish to access, then just use them just like any other disk drive. Due to the slower serial access it is usally better to copy the file a local disk if you wish to edit or run the file. Every effort has been made to make sure it is error free but I would only use it to read from the remote rather that sending files due to a crash may cause disk file links to be lost while creating new files on the remote system. 0 1 MIDI IN ----------------- MIDI OUT MIDI OUT MIDI IN \ / \ / \ / \ / \ / \ / MIDI IN MIDI OUT 2 FRED BROOKS PS Please let me know of any bugs ASAP. . k|d.. k|ANETCTRLMODl|e28ANETCTRLPRGp|tgANETWORKDFNu|"ANETWORKDILw|ANETWORKH z|ANETWORKINT||ANETWORKMOD}=zANETWORKPRG}&ANETWORKRSC }hANETWORKTXT }# MODULE Control; IMPORT GEMVDIbase, GEMAESbase, AESMenus, AESForms, AESObjects, AESEvents, AESResources ; FROM AESGraphics IMPORT GrafMouse; FROM AESObjects IMPORT ObjectDraw; FROM MYLIB IMPORT InitResource,Terminate, DeselectObject, dTree,MenuTree,x,y,w,h,InitWindow,CloseWindow; FROM SYSTEM IMPORT ADR,ADDRESS,CODE,TSIZE; FROM Strings IMPORT String, Concat; FROM XBIOS IMPORT SuperExec,SerialSpeed,ConfigureRS232,FlowFlavor; FROM BIOS IMPORT DriveSet; FROM GEMDOS IMPORT ExecMode,Exec,Open,Close,Read,Write,Create; FROM TextIO IMPORT SetDefaultIO,WriteString,WriteLn; FROM Streams IMPORT StreamKinds; TYPE SequenceNr = [0..1]; control = RECORD magic : LONGCARD; speed : SerialSpeed; reset : BOOLEAN; networkactive : BOOLEAN; remotedrive : CARDINAL; drivemap : DriveSet; nextframetosend : SequenceNr; frameexpected : SequenceNr; sendreset : BOOLEAN; END; consave = RECORD magic : LONGCARD; speed : SerialSpeed; reset : BOOLEAN; networkactive : BOOLEAN; END; CONST resourcefilename = "ANETWORK.RSC" ; RTS = 04E75H ; CONST DRVD = 58 ; DRVF = 60 ; DRVE = 59 ; SEQUP = 62 ; S10 = 64 ; S00 = 63 ; S01 = 65 ; S11 = 66 ; ABOUT = 1 ; ABOUTOK = 1 ; MENU = 0 ; FILE = 4 ; DESK = 3 ; BAUD = 5 ; MODE = 6 ; OPTIONS = 8 ; DIAL = 7 ; SEQ = 9 ; ABOUTNET = 12 ; LOAD = 21 ; QUIT = 22 ; BAUD1 = 25 ; BAUD2 = 26 ; BAUD4 = 28 ; BAUD3 = 27 ; BAUD5 = 29 ; BAUD6 = 30 ; INT = 32 ; MODE1 = 33 ; MODE2 = 34 ; REBOOTOK = 36 ; DIAL1 = 38 ; DIAL3 = 40 ; DIAL2 = 39 ; DIAL4 = 41 ; DIAL5 = 42 ; DIAL7 = 44 ; DIAL6 = 43 ; DIAL8 = 45 ; DIAL9 = 46 ; DIAL11 = 48 ; DIAL10 = 47 ; DIAL12 = 49 ; DIAL13 = 50 ; DIAL15 = 52 ; DIAL14 = 51 ; DIAL16 = 53 ; DRVB = 56 ; DRVA = 55 ; DRVC = 57 ; VAR status : INTEGER; resourcename,nulls,on,off,netdrv : ARRAY [0..16] OF CHAR ; tempchar : ARRAY [0..2] OF CHAR; char : CHAR; result,handle : INTEGER ; done,OK : BOOLEAN; Cptr [0200H] : ADDRESS; Dptr [0204H] : DriveSet; Mptr [0208H] ,count : LONGCARD; C : POINTER TO control; CSAVE : POINTER TO consave; drvnr,i : CARDINAL; phonenumber : ARRAY [0..15] OF String; PROCEDURE DoAboutDialog ; BEGIN AESResources.ResourceGetAddr(GEMAESbase.RTree,ABOUT,dTree) ; AESForms.FormCenter(dTree,x,y,w,h) ; AESForms.FormDialogue(GEMAESbase.FormStart,0,0,0,0,x,y,w,h) ; AESForms.FormDialogue(GEMAESbase.FormGrow,0,0,0,0,x,y,w,h) ; ObjectDraw(dTree,0,10,x,y,w,h) ; result := AESForms.FormDo(dTree,-1) ; DeselectObject(ABOUT,ABOUTOK) ; AESForms.FormDialogue(GEMAESbase.FormShrink,0,0,0,0,x,y,w,h) ; AESForms.FormDialogue(GEMAESbase.FormFinish,0,0,0,0,x,y,w,h) ; END DoAboutDialog ; (* ------------------------------------------------------------------- *) PROCEDURE Events ; (* Handle resource events *) VAR pipeBuff : ARRAY [0..9] OF INTEGER ; PROCEDURE SelectMenu( Menu, Item : INTEGER ) ; BEGIN CASE Menu OF DESK : IF Item = ABOUTNET THEN DoAboutDialog ; END ; | FILE : CASE Item OF LOAD : C^.networkactive:=(NOT C^.networkactive); | QUIT : done := TRUE ; | ELSE END ; IF C^.networkactive THEN AESMenus.MenuText(MenuTree,LOAD,ADR(on)); ELSE AESMenus.MenuText(MenuTree,LOAD,ADR(off)); END; | BAUD : AESMenus.MenuItemCheck(MenuTree,BAUD1,0); AESMenus.MenuItemCheck(MenuTree,BAUD2,0); AESMenus.MenuItemCheck(MenuTree,BAUD3,0); AESMenus.MenuItemCheck(MenuTree,BAUD4,0); AESMenus.MenuItemCheck(MenuTree,BAUD5,0); AESMenus.MenuItemCheck(MenuTree,BAUD6,0); CASE Item OF BAUD1 : C^.speed := BPS19200 ; AESMenus.MenuItemCheck(MenuTree,Item,1) | BAUD2 : C^.speed := BPS9600 ; AESMenus.MenuItemCheck(MenuTree,Item,1) | BAUD3 : C^.speed := BPS4800 ; AESMenus.MenuItemCheck(MenuTree,Item,1) | BAUD4 : C^.speed := BPS2400 ; AESMenus.MenuItemCheck(MenuTree,Item,1) | BAUD5 : C^.speed := BPS1200 ; AESMenus.MenuItemCheck(MenuTree,Item,1) | BAUD6 : C^.speed := BPS300 ; AESMenus.MenuItemCheck(MenuTree,Item,1) | ELSE END ; ConfigureRS232(C^.speed,NONE,136,-1,-1,-1); | MODE : CASE Item OF INT : Create("ANETWORK.INT",0,handle); count:=TSIZE(consave); Write(handle,count,CSAVE); OK:=Close(handle); | REBOOTOK : CODE(03F3CH,0020H,04E41H, 042B9H,0,0420H,042B9H,0,043AH, 02079H,0,4,04ED0H) ; | (* MODE2 : GIWrite(14,255) ; | *) ELSE END ; | DIAL : CASE Item OF DIAL1 : i:=0 ; | DIAL2 : i:=1 ; | DIAL3 : i:=2 ; | DIAL4 : i:=3 ; | DIAL5 : i:=4 ; | DIAL6 : i:=5 ; | DIAL7 : i:=6 ; | DIAL8 : i:=7 ; | DIAL9 : i:=8 ; | DIAL10 : i:=9 ; | DIAL11 : i:=10 ; | DIAL12 : i:=11 ; | DIAL13 : i:=12 ; | DIAL14 : i:=13 ; | DIAL15 : i:=14 ; | DIAL16 : i:=15 ; | ELSE END ; FOR status:=0 TO 80 DO IF phonenumber[i][status]=CHAR(32) THEN phonenumber[i][status]:=CHAR(0); END; END; SetDefaultIO("AUX:",READWRITE,status); WriteString(phonenumber[i]); WriteLn; SetDefaultIO("CON:",READWRITE,status); | SEQ : CASE Item OF SEQUP : C^.sendreset:= TRUE ; | ELSE END ; AESMenus.MenuItemCheck(MenuTree,S00,0); AESMenus.MenuItemCheck(MenuTree,S10,0); AESMenus.MenuItemCheck(MenuTree,S01,0); AESMenus.MenuItemCheck(MenuTree,S11,0); IF (C^.nextframetosend=0) AND (C^.frameexpected=0) THEN AESMenus.MenuItemCheck(MenuTree,S00,1); END; IF (C^.nextframetosend=1) AND (C^.frameexpected=0) THEN AESMenus.MenuItemCheck(MenuTree,S10,1); END; IF (C^.nextframetosend=0) AND (C^.frameexpected=1) THEN AESMenus.MenuItemCheck(MenuTree,S01,1); END; IF (C^.nextframetosend=1) AND (C^.frameexpected=1) THEN AESMenus.MenuItemCheck(MenuTree,S11,1); END; | ELSE END ; (* put header back normal*) AESMenus.MenuTitleNormal(MenuTree,Menu,1) ; END SelectMenu ; BEGIN GrafMouse(GEMAESbase.Arrow,NIL) ; (* put pointing mouse *) done := FALSE ; REPEAT AESEvents.EventMessage(ADR(pipeBuff)) ; CASE pipeBuff[0] OF (* message type *) GEMAESbase.MenuSelected : SelectMenu(pipeBuff[3],pipeBuff[4]) ; | GEMAESbase.WindowClosed : done := TRUE ; | ELSE END ; UNTIL done ; END Events ; (*$P- *) (* set vector to control record *) PROCEDURE getcontrol; BEGIN C := Cptr; CSAVE := Cptr; CODE(RTS); END getcontrol; BEGIN nulls:=" "; on :=" ON "; off:=" OFF "; SuperExec(PROC(getcontrol)); IF C^.magic#324159265 THEN Exec(loadExecute,"ANETWORK.PRG",nulls,nulls,result); IF result<0 THEN HALT END; SuperExec(PROC(getcontrol)); END; Open("ANETWORK.INT",0,handle); IF handle>0 THEN (* if there is, load in init file *) count:=TSIZE(consave); Read(handle,count,CSAVE); OK:=Close(handle); END; Open("ANETWORK.DIL",0,handle); IF handle>0 THEN (* if there is, load in dialer file *) count:=1; FOR i:=0 TO 15 DO LOOP Read(handle,count,ADR(char)); IF (char=12C) THEN EXIT END; IF (char=12C) OR (char=15C) THEN char:=0C END; tempchar[0]:=char; Concat(phonenumber[i],tempchar,phonenumber[i]); END; END; OK:=Close(handle); END; resourcename:=resourcefilename ; IF InitResource(resourcename,MENU) THEN ; AESMenus.MenuText(MenuTree,DIAL1,ADR(phonenumber[0])); AESMenus.MenuText(MenuTree,DIAL2,ADR(phonenumber[1])); AESMenus.MenuText(MenuTree,DIAL3,ADR(phonenumber[2])); AESMenus.MenuText(MenuTree,DIAL4,ADR(phonenumber[3])); AESMenus.MenuText(MenuTree,DIAL5,ADR(phonenumber[4])); AESMenus.MenuText(MenuTree,DIAL6,ADR(phonenumber[5])); AESMenus.MenuText(MenuTree,DIAL7,ADR(phonenumber[6])); AESMenus.MenuText(MenuTree,DIAL8,ADR(phonenumber[7])); AESMenus.MenuText(MenuTree,DIAL9,ADR(phonenumber[8])); AESMenus.MenuText(MenuTree,DIAL10,ADR(phonenumber[9])); AESMenus.MenuText(MenuTree,DIAL11,ADR(phonenumber[10])); AESMenus.MenuText(MenuTree,DIAL12,ADR(phonenumber[11])); AESMenus.MenuText(MenuTree,DIAL13,ADR(phonenumber[12])); AESMenus.MenuText(MenuTree,DIAL14,ADR(phonenumber[13])); AESMenus.MenuText(MenuTree,DIAL15,ADR(phonenumber[14])); AESMenus.MenuText(MenuTree,DIAL16,ADR(phonenumber[15])); CASE C^.speed OF (* PLACE CHECK IN BAUD RATE MENU *) BPS19200 : AESMenus.MenuItemCheck(MenuTree,BAUD1,1); | BPS9600 : AESMenus.MenuItemCheck(MenuTree,BAUD2,1); | BPS4800 : AESMenus.MenuItemCheck(MenuTree,BAUD3,1); | BPS2400 : AESMenus.MenuItemCheck(MenuTree,BAUD4,1); | BPS1200 : AESMenus.MenuItemCheck(MenuTree,BAUD5,1); | BPS300 : AESMenus.MenuItemCheck(MenuTree,BAUD6,1); | ELSE END; netdrv:=" DRV A = F"; drvnr:=2; WHILE drvnr IN C^.drivemap DO INC(drvnr); END; (* while *) INC(drvnr); netdrv[6]:="A"; netdrv[10]:=CHAR(041H+drvnr); AESMenus.MenuText(MenuTree,DRVA,ADR(netdrv)); netdrv[6]:="B"; netdrv[10]:=CHAR(041H+drvnr+1); AESMenus.MenuText(MenuTree,DRVB,ADR(netdrv)); netdrv[6]:="C"; netdrv[10]:=CHAR(041H+drvnr+2); AESMenus.MenuText(MenuTree,DRVC,ADR(netdrv)); netdrv[6]:="D"; netdrv[10]:=CHAR(041H+drvnr+3); AESMenus.MenuText(MenuTree,DRVD,ADR(netdrv)); netdrv[6]:="E"; netdrv[10]:=CHAR(041H+drvnr+4); AESMenus.MenuText(MenuTree,DRVE,ADR(netdrv)); netdrv[6]:="F"; netdrv[10]:=CHAR(041H+drvnr+5); AESMenus.MenuText(MenuTree,DRVF,ADR(netdrv)); CASE C^.remotedrive OF (* PLACE CHECK IN REMOTE MENU *) 0 : AESMenus.MenuItemCheck(MenuTree,DRVA,1); | 1 : AESMenus.MenuItemCheck(MenuTree,DRVB,1); | 2 : AESMenus.MenuItemCheck(MenuTree,DRVC,1); | 3 : AESMenus.MenuItemCheck(MenuTree,DRVD,1); | 4 : AESMenus.MenuItemCheck(MenuTree,DRVE,1); | 5 : AESMenus.MenuItemCheck(MenuTree,DRVF,1); | ELSE END; IF C^.networkactive THEN AESMenus.MenuText(MenuTree,LOAD,ADR(on)); ELSE AESMenus.MenuText(MenuTree,LOAD,ADR(off)); END; AESMenus.MenuItemCheck(MenuTree,S00,0); AESMenus.MenuItemCheck(MenuTree,S10,0); AESMenus.MenuItemCheck(MenuTree,S01,0); AESMenus.MenuItemCheck(MenuTree,S11,0); IF (C^.nextframetosend=0) AND (C^.frameexpected=0) THEN AESMenus.MenuItemCheck(MenuTree,S00,1); END; IF (C^.nextframetosend=1) AND (C^.frameexpected=0) THEN AESMenus.MenuItemCheck(MenuTree,S10,1); END; IF (C^.nextframetosend=0) AND (C^.frameexpected=1) THEN AESMenus.MenuItemCheck(MenuTree,S01,1); END; IF (C^.nextframetosend=1) AND (C^.frameexpected=1) THEN AESMenus.MenuItemCheck(MenuTree,S11,1); END; Events ; END; Terminate ; END Control.`b NY GEMXModula-2/ST (c) Copyright TDI Software Ltd. 1985, 1986. The team : Chris Hall, Paul Curtis, and Phil Camp .[3][Modula-2 Run Time Error : | | #][OK]NVN^Nu _b ШNYN"pNGNuNV*x ڄ=E*P-E@-M-VNh-H:. Eg :. Ef-n*.P-ENH:. Ef Nh-hN2:. Ef BBN:. E e Nh-PN-n Ib8B,)n9n)n )n)n)n|.n 9b/@>,VNhYN`NsN^NuNVBn ncN:.EIBtP ndRn`I* -EI* -EI* -EI* -EI* -Ez-E=| Bn=|BnBn <I* "NB=|N=|=|=|Bn=|z-E <I* "NB=|4=|=|=|Bn=|(mI* -E <I* "NB=|Bn=|BnBn <I* "NBN pL?NAN^NuNV/-+NI|Gz+WBn:.IJ4PgRn`=yb:. E d:.I0PN(z0x8.  HDE:.IPRnz0x8. HDE:.IPRnIGzWBn:.I8.nGP@Rn:.IJ4Pg`N+_N^Nu OAbrpNGNurpNGF'/NNn-/=-/H"Q ,IL?/^>/^Nf,oNsF'/NNn-/=-/H"Q G*- =/^Nf,oNs/NNn-/=/-/H _"h$",HL?/^>/^Nf,oNsF'SSfWWNsSf>NsSfF NsSfNqNsSf NNsNhBBB 9c!B*H$C! `N  <L?NAN`WNsNVH|".$. &(*HDHEHABBمCمHABBBCHBHCԃԄ-A -BL>N^NuNVHx". $.bBCh8BAHA62HC6BAHA`B6HCBAHA8<㑲eRCQ-C -ALN^NuNVH(. ,. dF<gBEVBBGVB0G|b.f ؆dRE`kgb|HDkSEjؼdREBJfBEJEnB`|mpN-D LN^Nu |oNNVH(. ,..HD:|glM||HF>|gXO||G|~mF H@HFB@H@2Ё"HAHFЁHD؀kSEؼdREJEk|m pNB` -D LN^NuNVH . $j ļfB".$j ļfBLN^NuNVH .$ļfBJLN^NuNVH .g*2<bH@|bQAU-@LN^NuNVH .j g` BA<☒|lB`|DAlpN⨰b-@LN^NuF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsNV . /2.??<NM*-E:. E b:.EIc)PN:.E EIc4)PN^NuNV/9c?<N\/9c ?<N\/9c?<N\/9c?<N\/9c ?<N\/9c$?<N\/9cP?<'N\/9cL?<&N\/9cH?<%N\N^NuNqNqNq O h*#b(yb#b ( ШШ(yb*,Ѕ.@//??<JNA (yb*,ڬ ڬڬ#c/<l?<N\/<^?<N\/<z?<N\/<?<N\/<?<N\/<?<N\/<?<'N\/<?<&N\/<P?<%N\# bpNGN "NVps"9gNBN^NuNV3ct3cv3 cz3 c~3cN^NuN NVIc* #gId* #gIe* #gIf* #gIct* #g#gg#gg#gg#ggIg* #gN^N NVIg89n9n 9n 9n <Ig* "NB3hh>=yh>N^NuNV3 g3gN^NuNV3 g3 g3gN^NuNV3g3 g3 g3gN^NuNV3g3g3g3g3h3 h3 h3hN^NuNV(n 8h(n8hN^NuNV(n8h(n8h(n 8h (n8h"N^NuN NVIgB BBBBIgGg* (Gg* )EGg* )EGh* )E Gh** )EGh6* )EN^NNV3g# h*Bg?<?<?<?<BgN O 3h>N^NuNV?. ?.N X# h*Bg?<?<?<?<BgN O 3h>N^NuNV?. ?.N X# h*Bg?< ?<?<?<BgN O 3h>N^NuNV?. ?.N X# h*Bg?<!?<?<?<BgN O 3h>N^NuNV3 g#h*#h.Bg?<"?<?<?<BgN O 3h>N^NuNV3g(n* #h*Bg?<#?<?<?<BgN O =_N^NuN NVN^N.NV3g# h*Bg?<2?<?<?<BgN O =_N^NuNV?.?.?.?.?.?.?. ?. N XO3hBg?<3?< ?<BgBgN O 3h>N^NuNV3g(n* #h*Bg?<4?<?<?<BgN O =_N^NuNV#h*Bg?<6Bg?<?<BgN O 3h>(nHT(nHT(n HT(nHTN ON^NuNNVN^NNV?.?.?.?. N 0P3 h3h#h*Bg?<*?<?<?<BgN O 3h>N^NuN(NVN^NNV#h*Bg?<Bg?<?<BgN O 3h>N^NuNNVN^NNV(n* #h*Bg?<nBg?<?<BgN O 3h>N^NuNVBg?<oBg?<BgBgN O 3h>N^NuNV?.?. N XBg?<p?<?<Bg?<N O 3h>(n(h6N^NuNNVN^NNV?.?.?.?.?.?. ?. ?.N XOBg?<I?<?<BgBgN O 3h>N^NuNV?.?.?.?.?.?. ?. ?.N XOBg?<J?<?<BgBgN O 3h>N^NuNVBg?<MBg?<BgBgN O =_(nHT(nHT(n HT(nHTN O=nN^NuNV3 g#h*Bg?<N?<?<?<BgN O 3h>N^NuNNVN^NNV?<dBg?< Bg(n ?N O Byh@ y h@oN4:9h@E(n89h@DGc7P@ y h@lRyh@`N Byh@ y,h@oN4:9h@EIe89h@D&n7P@ y,h@lRyh@`3-h@ y8h@oN8:9h@E-EIf89h@D&n7P@ y8h@lRyh@`(n 8cN^NuNV?<eBgBgBg?.N O N N^NuNNVN^NNV3c?<Bg?<Bg?. N O N =ye N^NuNV3c?<Bg?<Bg?. N O N =ye N^NuNNVN^NNV?<r?<BgBg?. N O (n* #gN #ggN^NuNNVN^NNV?.?.?. ?. N 0P3hBg?<d?<?<BgBgN O =_N^NuNV?.?.?. ?. N 0P3hBg?<e?<?<BgBgN O 3h>N^NuNV3gBg?<f?<?<BgBgN O 3h>N^NuNV3gBg?<g?<?<BgBgN O 3h>N^NuNV?.?.N XBg?<h?<?<BgBgN O 3h>(nHT(nHT(n HT(nHTN ON^NuNV?.?.?.?. N 0P3 h3hBg?<i?<?<BgBgN O 3h>N^NuNNVN^NNVBg?< Bg?<BgBgN O =_N^NuNVBg?<Bg?<BgBgN O 3h>N^NuNNVN^NRNV# h*#h.Bg?<xBg?<?<BgN O 3h>N^NuNNVN^N$NVB9hLN^NuNVBg:. ?(nHTN\=_:.RE8.Ec :.RE=EBn:.SE?0.WoN&:.(n8.&nP@0.WlRn`T:.nb:.(nhLPN^NuNVBg:.?(n HTN\=_:. ndF=n :.n?0.WcN*:.n(n 8.&n P@0.WdRn`TN^NuNVBg:.?(nHTN\=_:.ndh:.n d^:.nnc:.nSE=EBn:.SE8.Eb :.n(n8.&nP@Rn`:.(nhLPN^NuNVBg:.?(nHTN\=_Bg:.?(nHTN\=_:.nJEf(nhLN:. TE8.nEd`N:. ?(nHT:.?(nHTNlO =n:.nSE?0.WcN*:.n(n8.&nP@0.WdRn`T:.n(nhLPN^NuNVBn:. ?0.WcN0:.(n4P9hLf =nTN^Nu0.WdRn`T:. RE=EN^NuNVBg:.?(nHTN\=_Bg:.?(nHTN\=_JngJng:. nnc(n8B.N^Nu:.n=EBn:. n(n8.&n3@4PgN$Rn:.nf(n8 |N^Nu`Rn :. nc(n8B.N^Nu`NLNVN^N^N,NVByhN3hP/9hN?.<< B':. ?(nHTN'ON^NuNVByhN:.JElDE3hP/9hN?.<< Jnlz`z:. ?(nHTN'ON^NuNV:. nm=n N^NuN =n N^NuNV(nBB./.NXl|/.-_NB.Jnm8/./?.N-bXJfz`zE N^NuNVB?<??.(n //.N-~O (n (N^NuNVB?<@?.(n //.N-~O (n (N^NuNVB?<B/.?.z. ?N-O (n(N^NuNV(n * /(n* /(n* /z.0?pK?* #hR*#hV*#hZNA*yhR,yhV.yhZ*(n8N^NuN-2NVN^N6CON:PRN:AUX:NV:. EdB.N^NuBn ncN2:.(n8.&n3@4PgB.N^Nu ndRn`|N^NuNVBn:.Ժnb<:.(nJ4Pg.:.(n4P ae zb_:.IPRn`:.IB4P(nBT(n9|/ B'?<)Hn?<Hy0*N0:O (_JgB,N/ B'?<)Hn?<Hy0/N0:O (_Jg |N/ B'?<)Hn?<Hy04N0:O (_Jg |N|J. fV/ ?<)HnBgHlN.O (_/ B?,<HlN/O (_/ B?,B'HnN/O (_NB/ ?<)Hn?<HlN.O (_Jll/ ?<)HnBgHlN.O (_Jll&n6B,N^NuNV(nBT(n , fB'(n ?,N/TJf(n8N^NuNV-n=|:. ?0.WcN"(n(nNTR0.WdRn`TN^NuNV nCp Qz. Nz:. -E?.Hn/.N/VO Nb/<.?. /.N2O NF/<.*?. /.N2O N*/<.j?. /.N2O NN Lh0 N^NuNV n Cp QHn?<I* /N2O N^NuNV n Cp QHn?<I* /N2O N^NuNV n Cp QHn?<I* /N2O N^NuNV-n=|:. ?0.WcN(Hn(nNX(nR0.WdRn`TN^NuNV nCp Qz. Npz:. -E?.Hn/.N/*O NJNF/<. ?. /.N4$O N*/<.L?. /.N4$O NN 4P0 N^NuNV n Cp QHn?<(n* /N4rO N^NuNV n Cp QHn?<(n* /N4rO N^NuNV n Cp QHn?<(n* /N4rO N^NuNV nCp Q. f4B?.<HnN/O *.ez`zE N^NuN B. N^NuN0NVN^N@ReadCardReadIntegerReadRealReadOctReadHexReadWordReadAdrcon:p NNV n Cp QHn.N3\N^Nup NNV nCp QHn< N6V\Hn< N6V\N^NupNNVHyhhN6XN^Nup NNV nCp QBn:. ?0.WcN@:.(nJ4Pf TN^NuNHn:.(n4PN6V\0.WdRn`TN^NupNNVHyhh:. ?(nHTN6O N^Nup NNV n Cp Q?. ?.?<dHyhvN6O Hn?<dHyhvN6O N^Nup NNV n Cp Q?. ?.?<dHyhvNvO Hn?<dHyhvN6O N^Nup NNV nCp Q/. ?. ?.?<dHyhvNOHn?<dHyhvN6O N^Nup NNV n Cp Q?. ?.?<dHyhvN!NO Hn?<dHyhvN6O N^Nup NNV n Cp Q?. ?.?<dHyhvN!O Hn?<dHyhvN6O N^Nup NNV nCp Q/. ?.?<dHyhvN!O Hn?<dHyhvN6O N^Nup NNV nCp Q/. ?.?<dHyhvN!O Hn?<dHyhvN6O N^Nup NNV nCp Q/. ?.?<dHyhvN"*O Hn?<dHyhvN6O N^Nup NNV n Cp QJ.g(nB.NnB'HnN5XJg (nBN^NuHn(nHTN5PJyhtf.(nJf&B'HnN5XJfHn(nHTN5P`(nTN^Nup NNV n Cp QHn(nHTN:*P(n ae zb_(nN^Nup NNV nCp Q|N^Nup NNV nCp QHnHnN:*P.  g`N^NupNNV nCp QBn:. ?0.WcNHnHnN:*P.  fH:.(nB4PJ.fTN^NuHnHnN:*P.  g HnN;XTN^NuN:.(nPJ.fTN^Nu0.WdRnNvTN^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyh(nHTN"ZOJ9hfHn?<Hy6N@O J9hf`N^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyh(nHTN#OJ9hfHn?< Hy6N@O J9hf`N^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyh(nHTN#OJ9hfHn?<Hy6'N@O J9hf`N^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyh(nHTN'OJ9hfHn?<Hy60N@O J9hf`N^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyh(nHTN'VOJ9hfHn?<Hy68N@O J9hf`N^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyhHnN#OJ9hfHn?<Hy6@N@O J9hf`(n8N^Nup NNV n Cp QHn?<dHyhvN;|O ?<dHyhvHyh(nHTN'OJ9hfHn?<Hy6IN@O J9hf`N^NupNNV3htN^Nup NNVHn:.?(nHT. (nHTN0O(nJTmfJ. f2Hyh^(nHTN2VP(nJTmIGh^z6QN0Hyhh(nHTN2VP(nJTmIGhhz6QN^Nup NNV nCp QpNN^NuN6pNNVI6QGhzWHyh^?<HyhB'HyhrN0OHyhh?<Hyh<HyhrN0OBgN?TN^NPJJANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC[3][ Unable to find resource file| for this program.][GET "*.RSC" FILE]this is a testJUL286798.45[3][ No resource file for Modula-2| program. ][ Get "*.RSC" ]Copyright 1986, Fred Brooks LogicTek San Diego CA. <NNVZN^?<PHn?<#HyA4NlO BnZ n!ZcN?<PHn?.Z?<?<PHn\NpOB':.?(nHT?<PHn\Bg(nHTNHOJg.JnZf (n 8Nz:.ZRE(n 8|N^Nu nZdVnZNvB.N^NupN <NNVZ| |B':.?(nHT?<PHn(n?(nHTNHOJg`N(n:RE=EZB':.?(nHT?<PHn?.ZHnZNHOJg`Nr:.?(nHT(n?:.Z(nT??<PHn\NpO(n8Z?<PHn\Hn(n HTN"ZOJ.g(n : Eb |N^NuB.N^NupN <NNVZ| |B':.?(nHT?<PHn(n?(nHTNHOJg`N:.?(nHT(n?Bg:.?(nHTN\:(nT??<PHn\NpO(n8Z?<PHn\Hn(n HTN"ZO(n : Elc(n : Ed(n :El(n 8J.g |N^NuB.N^NupNpNNNV?</f4IAGz>WBg?<?<cHnNP=_B.N^NuBg?.HyhNJP/9h?<N d\BgHyiHyiHyiHyiNJO3hBn n cN&:.K EIi9P n dRn`3iHyiHyhHyiNO |N^NupNpNNV/9hBgN d\N"?9hNTNN^NuN@pNNVN^NPNV0.?0. ?0. ?0.?z.0?z.0?p?NNN^NuNV ./p&?NNN^NuNPDNPNPNYANETWORK.INTAUX:CON: ON OFF ANETWORK.PRGANETWORK.INTANETWORK.DILANETWORK.RSC DRV A = FpNNVBg?<HyhNJP/9hHyhHyhHyhHyhNOBgBgBgBgBg?9h?9h?9h?9hN:O?<BgBgBgBg?9h?9h?9h?9hN:O/9hBg?< ?9h?9h?9h?9hN:OBg/9h?:. E fNQ.N.:.H N<(yjlJ,fz`z(yjlENjfN N ,(yjlJ,g"/9h?<Ij(* /NlO N /9h?<Ij:* /NlO N/9h?<BgN P/9h?<BgN P/9h?<BgN P/9h?<BgN P/9h?<BgN P/9h?<BgN P:.H N(yjlB,/9h?.?<N PN(yjl|/9h?.?<N PN(yjl|/9h?.?<N PN(yjl|/9h?.?<N PN^(yjl|/9h?.?<N PN8(yjl| /9h?.?<N PNN 0V|(yjl,B'?<?:.H N&ByjvN3jvN3jvN3jvN3jvN3jvN3jvN3jvN3jvNz3 jvNn3 jvNb3 jvNV3 jvNJ3 jvN>3jvN23jvN&N" ".:FR^jvByj yPjoNf:9jvKRIjx89jIPIP4@  f&:9jvKRIjx89jIPIPB4@ yPjlRyj`?<HyP<HyjN?O :9jvKRIjx?<PHtPN7Z\N6?<HyP<HyjN?O N`:.H N> (yjl|NN /9h?<?BgN P/9h?<@BgN P/9h?<ABgN P/9h?<BBgN P(yjlJlf"(yjlJlf/9h?<??<N P(yjl:, Ef"(yjlJlf/9h?<@?<N P(yjlJlf&(yjl:, Ef/9h?<A?<N P(yjl:, Ef&(yjl:, Ef/9h?<B?<N PNN l:/9h?. ?<N(PN^NupNNVBg/:$0 84$L* 2 "   (      4$$&     ,F       Tr                  B .           (                  $                     2ABOUTABOUTOKMENUOKDESKOKFILEOKBAUDOKDIALOKMODEOKOPTIONS SEQONS ABOUTNETLOADNETQUITNETBAUD1ETBAUD3ETBAUD2ETBAUD4ETBAUD5ETBAUD6ET INT6ET!MODE1ET"MODE2ET$REBOOTOK'DIAL2OK&DIAL1OK(DIAL3OK)DIAL4OK+DIAL6OK*DIAL5OK,DIAL7OK-DIAL8OK/DIAL10K.DIAL9K0DIAL11K1DIAL12K3DIAL14K2DIAL13K4DIAL15K5DIAL16K7DRVA6K8DRVB6K9DRVC6K;DRVE6K:DRVD6K<DRVF6K?S006K>SEQUPK@S10PKAS01PKBS11PKATDO CONST ABOUT = 1 ; ABOUTOK = 1 ; MENU = 0 ; DESK = 3 ; FILE = 4 ; BAUD = 5 ; DIAL = 7 ; MODE = 6 ; OPTIONS = 8 ; SEQ = 9 ; ABOUTNET = 12 ; LOAD = 21 ; QUIT = 22 ; BAUD1 = 25 ; BAUD3 = 27 ; BAUD2 = 26 ; BAUD4 = 28 ; BAUD5 = 29 ; BAUD6 = 30 ; INT = 32 ; MODE1 = 33 ; MODE2 = 34 ; REBOOTOK = 36 ; DIAL2 = 39 ; DIAL1 = 38 ; DIAL3 = 40 ; DIAL4 = 41 ; DIAL6 = 43 ; DIAL5 = 42 ; DIAL7 = 44 ; DIAL8 = 45 ; DIAL10 = 47 ; DIAL9 = 46 ; DIAL11 = 48 ; DIAL12 = 49 ; DIAL14 = 51 ; DIAL13 = 50 ; DIAL15 = 52 ; DIAL16 = 53 ; DRVA = 55 ; DRVB = 56 ; DRVC = 57 ; DRVE = 59 ; DRVD = 58 ; DRVF = 60 ; S00 = 63 ; SEQUP = 62 ; S10 = 64 ; S01 = 65 ; S11 = 66 ;  MODULE NETWORK ; (* -------------------------------------------------------------------------- NETWORK : RS-232 TWO CPU NETWORK FOR TDI Modula-2/ST --------------------------------------------------------------------------*) (*$T- *) (*$S- *) FROM SYSTEM IMPORT ADDRESS, ADR, SETREG, CODE, REGISTER ,BYTE ,TSIZE,SIZE; FROM GEMX IMPORT BasePageAddress, BasePageType ; FROM BIOS IMPORT BPB ,BConStat ,BConIn, BCosStat, BConOut, Device, MediaChange,MCState,GetBPB,RWAbs,RW,DriveSet,DriveMap; FROM XBIOS IMPORT SuperExec,ConfigureRS232,SerialSpeed,FlowFlavor, SerialDevice,IORec,IORECPTR,IOREC,VSync; FROM GEMDOS IMPORT TermRes,Open,Close ; IMPORT GEMDOS; FROM ASCII IMPORT SYN,STX,SOH; CONST MaxSeq = 1; recsize = 511; USER = 324159265; retry = 5; debug = FALSE; trace = FALSE; (* Because we dont know what registers the BIOS is using we must use the following opcodes to save the registers *) MOVEMDEC = 48E7H ; (* 68000 opcode for MOVEM ,-(A7) *) MOVEMINC = 4CDFH ; (* 68000 opcode for MOVEM (A7)+, *) SAVEREGS = 07FFCH ; (* Registers D1..A5 for DEC *) RESTREGS = 03FFEH ; (* Registers D1..A5 for INC *) RTS = 04E75H ; (* 68000 return from subroutine opcode *) TYPE (* Procedure types to mimic correct sequence for "C" BIOS routines *) CBPBProc = PROCEDURE ( CARDINAL ) ; CMediaChProc = PROCEDURE ( CARDINAL ) ; CRWAbsProc = PROCEDURE ( CARDINAL, CARDINAL, CARDINAL, ADDRESS, CARDINAL ); rs232buffer = ARRAY [0..512] OF CARDINAL; SequenceNr = [0..MaxSeq]; message = ARRAY [0..recsize] OF BYTE; message1 = ARRAY [0..17] OF BYTE; FrameKind = (ack,data,callreq,callaccp,clearreq,clearconf, resetreq,resetconf,diag); DataKind = (rdmediareq,rdmediaconf,rdbpbreq,rdbpbconf, rdrwabsreq,rdrwabsconf); evtype = (framearrival,cksumerr,timeout,hostready,reset,nothing); frame = RECORD syn : CHAR; (* these are sync chars *) stx : CHAR; (* for the frames *) kind : FrameKind; seq : SequenceNr; ack : SequenceNr; cmd : DataKind; rw : CARDINAL; (* read or write data *) recno : CARDINAL; (* sector for data*) d0 : LONGCARD; (* data return variable *) info : message; user : LONGCARD; cksum : CARDINAL; END; framecptr = POINTER TO framecmd; framecmd = RECORD syn : CHAR; (* these are sync chars *) stx : CHAR; (* for the frames *) kind : FrameKind; seq : SequenceNr; ack : SequenceNr; cmd : DataKind; rw : CARDINAL; (* read or write data *) recno : CARDINAL; (* sector for data*) d0 : LONGCARD; (* data return variable *) info : message1; user : LONGCARD; cksum : CARDINAL; END; control = RECORD magic : LONGCARD; speed : SerialSpeed; reset : BOOLEAN; networkactive : BOOLEAN; remotedrive : CARDINAL; drivemap : DriveSet; nextframetosend : SequenceNr; frameexpected : SequenceNr; sendreset : BOOLEAN; END; consave = RECORD magic : LONGCARD; speed : SerialSpeed; reset : BOOLEAN; networkactive : BOOLEAN; END; vblqueueptr = POINTER TO ADDRESS; frameptr = POINTER TO ARRAY [0..1024] OF BYTE; VAR (* BIOS variables : These can only be accessed with the 68000 in supervisor mode. The Modula-2 language allows you to fix the location of variables *) HDBPB [0472H] : ADDRESS ; (* hard disk get Bios Parameter Block *) HDRWAbs [0476H] : ADDRESS ; (* hard disk read/write abs *) HDMediaCh [047EH] : ADDRESS ; (* hard disk media change *) DriveBits [04C2H] : SET OF [0..31]; (* disk drives present map *) RS232RBF [0130H] : ADDRESS ; (* 232 rec char vector *) vblsem [0452H] : CARDINAL; (* check for vbl's enable *) flock [043EH] : LONGCARD; (* disk access in progress *) Cptr [0200H] : ADDRESS; Dptr [0204H] : DriveSet; (* save original drive map *) Mptr [0208H] : LONGCARD; charcount,j,framesize,cksum,recframesize,sndframesize, SIZEframe,SIZEframecmd : CARDINAL; vblqueue : vblqueueptr; (* set to vbl routines vector *) vblptr : vblqueueptr; networkconnect : BOOLEAN; (* DCD = 1 TRUE *) gotframe : BOOLEAN; framebufferfull : BOOLEAN; cleartosend : BOOLEAN; readytosend : BOOLEAN; requesttosend : BOOLEAN; framewaiting : BOOLEAN; timer,OK : BOOLEAN; gotmediach : ARRAY [0..5] OF BOOLEAN; gotbpb : ARRAY [0..5] OF BOOLEAN; vblactive : BOOLEAN; networkerror : BOOLEAN; shortframe : BOOLEAN; sendlong : BOOLEAN; sframe,rframe,SFRAME,RFRAME, nframe1,nframe2 : frame; rframeptr,sframeptr, bpbptr,nbpbptr : frameptr; framecmdptr,framecmdptr1 : framecptr; event : evtype; C : control; recchar,timestart,timefortimeout,timeouttime : LONGCARD; timestart1,timefortimeout1,timeouttime1 : LONGCARD; result,r,i,i1,i2,i3,mediacount,handle : INTEGER; D0ptr : POINTER TO LONGCARD; wsector,drvnr,DriveA,DriveF,devicestart,d,R : CARDINAL; sbuffer,rbuffer : rs232buffer; sbptr,rbptr : IORECPTR; numBytes,sec,min,hour,time,count : LONGCARD ; status : LONGINT ; (* The following are saved copies of the BIOS variables so that the real hard disk routines can be called if a hard disk access is requested. *) SaveHDBPB : CBPBProc ; (* hard disk get Bios Parameter Block *) SaveHDRWAbs : CRWAbsProc ; (* hard disk read/write abs *) SaveHDMediaCh : CMediaChProc ; (* hard disk media change *) (* NETWORK control *) NetworkBPB : ARRAY [0..5] OF BPB ; (* BIOS Parameter block for NETWORK *) PROCEDURE MoveMemory ( From, To : ADDRESS ; Bytes : LONGCARD ) ; (* This routine shows how time critical portions of code can be optimised to run faster. It relys on the code generation rules of the compiler which can be checked by dis-assembling the link file with DecLnk.*) CONST MOVEB = 12D8H ; (* MOVE.B (A0)+,(A1)+ *) MOVEL = 22D8H ; (* MOVE.L (A0)+,(A1)+ *) A0 = 0+8 ; (* register A0 *) A1 = 1+8 ; (* register A1 *) BEGIN SETREG(A0,From) ; (* load From pointer into A0 *) SETREG(A1,To) ; (* load To pointer into A1 *) IF ( ODD(From) OR ODD(To) ) THEN (* must do bytes *) WHILE ( Bytes <> 0 ) DO CODE(MOVEB) ; DEC(Bytes) ; END ; ELSE (* even addresses so can do long moves *) WHILE ( Bytes > 3 ) DO CODE(MOVEL) ; DEC(Bytes,4) ; END ; WHILE ( Bytes <> 0 ) DO CODE(MOVEB) ; (* clean up remainder *) DEC(Bytes) ; END ; END ; END MoveMemory ; PROCEDURE inc(VAR k: SequenceNr); (* increment k circulary *) BEGIN IF k= DriveA) AND (device <=DriveF) THEN (* is NETWORK channel *) IF ( Flag = 0 ) OR ( Flag = 2 ) (* read *) THEN FOR wsector:=0 TO (SectorCount-1) DO C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); nframe1.recno:=RecordNum+wsector; nframe1.rw:=Flag; (* read *) resetnewdisk; IF getfromremote(rdrwabsreq,rdrwabsconf,nframe1) THEN MoveMemory(ADR(nframe1.info),Buffer+ADDRESS(wsector)*512, 512); status:=0; ELSE status:=(-11); END; (* if *) END; (* for *) IF networkerror THEN C.sendreset:=TRUE END; (* send network reset to remote cpu *) SETREG(D0,status) ; ELSIF ( Flag = 1 ) OR ( Flag = 3 ) THEN (* write *) FOR wsector:=0 TO (SectorCount-1) DO C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); nframe1.recno:=RecordNum+wsector; nframe1.rw:=Flag; (* write *) resetnewdisk; MoveMemory(Buffer+ADDRESS(wsector)*512,ADR(nframe1.info),512); IF getfromremote(rdrwabsreq,rdrwabsconf,nframe1) THEN status:=0; ELSE status:=(-10); END; END; (* for *) IF networkerror THEN C.sendreset:=TRUE END; (* send network reset to remote cpu *) SETREG(D0,status) ; ELSE SETREG(D0,LONGINT(-3)) ; END ; ELSE (* not NETWORK *) SaveHDRWAbs (device,RecordNum,SectorCount,Buffer,Flag) ; END ; CODE(MOVEMINC,RESTREGS) ; (* Restore registers from stack *) END RDRWAbs ; PROCEDURE RDMediaCh ( device : CARDINAL ) ; CONST D0 = 0 ; BEGIN CODE(MOVEMDEC,SAVEREGS) ; (* save registers on stack *) IF (device >= DriveA) AND (device <=DriveF) THEN (* is NETWORK channel *) C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); IF newdisk() THEN gotmediach[device-devicestart]:=FALSE; gotbpb[device-devicestart]:=FALSE; END; IF (NOT gotmediach[device-devicestart]) THEN IF getfromremote(rdmediareq,rdmediaconf,nframe1) THEN gotmediach[device-devicestart]:=TRUE; IF nframe1.d0=1 THEN nframe1.d0:=2 END; SETREG(D0,nframe1.d0) ; (* "C" uses D0 as return location *) ELSE SETREG(D0,Changed); END; ELSE SETREG(D0,NoChange) ; (* "C" uses D0 as return location *) END; ELSE (* not NETWORK *) SaveHDMediaCh(device) ; END; CODE(MOVEMINC,RESTREGS) ; (* Restore registers from stack *) END RDMediaCh ; PROCEDURE RDBPB ( device : CARDINAL ) ; CONST D0 = 0 ; BEGIN CODE(MOVEMDEC,SAVEREGS) ; (* save registers on stack *) IF (device >= DriveA) AND (device <=DriveF) THEN (* is NETWORK channel *) C.remotedrive:=device-devicestart; nframe1.d0:=LONGCARD(device-devicestart); IF newdisk() THEN gotbpb[device-devicestart]:=FALSE; gotmediach[device-devicestart]:=FALSE END; (* gotbpb[device-devicestart]:=FALSE; (* test *) *) IF (NOT gotbpb[device-devicestart]) THEN IF getfromremote(rdbpbreq,rdbpbconf,nframe1) THEN gotbpb[device-devicestart]:=TRUE; bpbptr:=ADR(nframe1.info); nbpbptr:=ADR(NetworkBPB[device-devicestart]); FOR i3:=0 TO TSIZE(BPB)-1 DO nbpbptr^[i3]:=bpbptr^[i3]; END; resetnewdisk; SETREG(D0,ADR(NetworkBPB[device-devicestart])); (* D0 returns address of the BPB *) ELSE SETREG(D0,0); END; ELSE SETREG(D0,ADR(NetworkBPB[device-devicestart])); (* D0 returns address of the BPB *) END; IF networkerror THEN C.sendreset:=TRUE END; (* send network reset to remote cpu *) ELSE (* not NETWORK *) SaveHDBPB(device) ; END ; CODE(MOVEMINC,RESTREGS) ; (* Restore registers from stack *) END RDBPB ; PROCEDURE resetnewdisk; BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timestart1:=LONGCARD(REGISTER(0)); timefortimeout1:=timestart1; IncTime(timefortimeout1,3+CARDINAL(C.speed)); END resetnewdisk; PROCEDURE newdisk(): BOOLEAN; BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timeouttime1:=LONGCARD(REGISTER(0)); SETREG(0,timeouttime1); CODE(0280H,0,0FFFFH); timeouttime1:=LONGCARD(REGISTER(0)); IF timeouttime1>timefortimeout1 THEN resetnewdisk; RETURN TRUE; END; RETURN FALSE; END newdisk; (* ----------------------------------------------------------------------- *) PROCEDURE Initialise () : BOOLEAN ; (* returns TRUE if NETWORK is to be installed *) BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) CODE(2f00H,3f3cH,0016H,4e4eH,5c8fH); (* settime *) SuperExec(PROC(setcontrol)); (* set address of global control record *) rbptr:=IORec(RS232); sbptr:=IORECPTR(LONGCARD(rbptr)+LONGCARD(14)); rbptr^.ibuf:=ADR(rbuffer); rbptr^.ibufsize:=1024; sbptr^.ibuf:=ADR(sbuffer); sbptr^.ibufsize:=1024; C.magic:=USER; C.remotedrive:=0; C.speed:=BPS1200; ConfigureRS232(C.speed,NONE,136,-1,-1,-1); framesize:=TSIZE(frame); recframesize:=framesize; sndframesize:=framesize; sframe.user:=USER; R:=0; RETURN TRUE; END Initialise ; (*$P- *) (* set vector to control record *) PROCEDURE setcontrol; BEGIN Cptr:=ADR(C); IF Mptr#USER THEN C.drivemap:=DriveMap(); Dptr:=C.drivemap; END; C.drivemap:=Dptr; Mptr:=USER; CODE(RTS); END setcontrol; (* this routine reads the 232 port data and sync's it into frames *) (* it runs as a background process in a vbl time slot *) (*$P- *) PROCEDURE recframe; BEGIN IF C.networkactive AND vblactive THEN CODE(02f39H,0,04a2H); (* move.l $4a2,-(sp) save BIOS pointer *) CODE(04b9H,0,02eH,0,04a2H); (* sub 46 from pointer *) nrecframe; Nwait(event); HandleEvents(); CODE(023dfH,0,04a2H); (* restore BIOS pointer *) END; CODE(RTS); END recframe; PROCEDURE nrecframe; BEGIN IF C.networkactive THEN WHILE (BConStat(AUX)) AND (NOT framebufferfull) DO recchar := BConIn(AUX); IF (recchar=LONGCARD(SYN)) AND (NOT gotframe) THEN gotframe:=TRUE; (* got sync char from data *) charcount:=0; END; IF (charcount=1) AND ((recchar#LONGCARD(STX)) AND (recchar#LONGCARD(SOH))) THEN gotframe:=FALSE; (* false start try again *) charcount:=0; END; IF (charcount=1) AND (recchar=LONGCARD(STX)) THEN recframesize:=SIZEframe; END; IF (charcount=1) AND (recchar=LONGCARD(SOH)) THEN recframesize:=SIZEframecmd; END; IF gotframe THEN (* put data in buffer *) rframeptr^[charcount]:=BYTE(recchar); INC(charcount); IF charcount=recframesize THEN (* got full frame *) gotframe := FALSE; IF recframesize=SIZEframecmd THEN rframe.user:=framecmdptr^.user; rframe.cksum:=framecmdptr^.cksum; END; framebufferfull := TRUE; END; END; END; (* WHILE *) END; END nrecframe; (* The following compiler directive stops the compiler from generating the normal Modula-2 entry/exit code for the next procedure. This is needed as this routine is called in supervisor mode by the BIOS function to install the BIOS vectors. *) (*$P- Stop entry/exit code for next procedure *) PROCEDURE InstallVectors ; BEGIN (* First save the current hard disk vectors *) SaveHDBPB := CBPBProc(HDBPB) ; SaveHDRWAbs := CRWAbsProc(HDRWAbs) ; SaveHDMediaCh := CMediaChProc(HDMediaCh) ; (* Now set the BIOS vectors to our routines *) HDBPB := ADDRESS(RDBPB) ; HDRWAbs := ADDRESS(RDRWAbs) ; HDMediaCh := ADDRESS(RDMediaCh) ; drvnr:=2; WHILE drvnr IN DriveBits DO INC(drvnr); END; (* while *) INC(drvnr); devicestart:=drvnr; DriveA:=drvnr; DriveF:=drvnr+5; INCL(DriveBits,drvnr) ; (* set new drive A *) INCL(DriveBits,drvnr+1) ; (* set new drive B *) INCL(DriveBits,drvnr+2) ; (* set new drive C *) INCL(DriveBits,drvnr+3) ; (* set new drive D *) INCL(DriveBits,drvnr+4) ; (* set new drive E *) INCL(DriveBits,drvnr+5) ; (* set new drive F *) networkconnect := FALSE; vblactive:=TRUE; gotframe := FALSE; framebufferfull := FALSE; charcount:=0; SIZEframe:=TSIZE(frame); SIZEframecmd:=TSIZE(framecmd); (* vblsem:=0; *) vblqueue := vblqueueptr(0456H); vblptr := vblqueue^; (* set to address of vbls *) rframeptr := ADR(rframe); framecmdptr:=ADR(rframe); sframeptr := ADR(sframe); LOOP (* set up vbl vector to make packet frame from 232 input *) IF vblptr^ = ADDRESS(0) THEN vblptr^ := ADDRESS(recframe); EXIT; ELSE (*$T-*) INC(vblptr,4) ; (*$T=*) END; END; (* LOOP *) (* vblsem:=1; *) CODE(RTS) ; (* code to return to calling BIOS function *) END InstallVectors ; (*$P+ *) PROCEDURE sendf(VAR f: frame); BEGIN sframe:=f; sframe.cksum:=0; IF ((sframe.cmd=rdrwabsconf) AND ((sframe.rw=0) OR (sframe.rw=2))) OR ((sframe.cmd=rdrwabsreq) AND ((sframe.rw=1) OR (sframe.rw=3))) THEN sndframesize:=SIZEframe; sframe.syn := SYN ; sframe.stx := STX ; sframe.user := USER ; shortframe:=FALSE; IF trace THEN BConOut(CON,":") END; ELSE sndframesize:=SIZEframecmd; sframe.syn := SYN ; sframe.stx := SOH ; framecmdptr1:=ADR(sframe); framecmdptr1^.user := USER ; shortframe:=TRUE; IF trace THEN BConOut(CON,".") END; END; FOR i1:=0 TO sndframesize-5 DO (* compute checksum *) sframe.cksum:=sframe.cksum+CARDINAL(sframeptr^[i1]) END; IF shortframe THEN framecmdptr1^.cksum:=sframe.cksum END; FOR i1:=0 TO sndframesize-1 DO (* send frame *) REPEAT nrecframe; UNTIL BCosStat(AUX); BConOut(AUX,CHAR(sframeptr^[i1])); END; REPEAT UNTIL sbptr^.ibufhd=sbptr^.ibuftl; END sendf; PROCEDURE getf(VAR f: frame); BEGIN f:=rframe; framebufferfull:=FALSE; END getf; PROCEDURE waitcts(what: BOOLEAN); (* wait for cleartosend state *) BEGIN IF what THEN REPEAT nrecframe; Nwait(event); HandleEvents(); IF R>retry THEN networkerror:=TRUE; RETURN; (* trouble *) END; UNTIL cleartosend; RETURN; ELSE LOOP nrecframe; Nwait(event); IF (NOT cleartosend) THEN EXIT END; HandleEvents(); IF R>retry THEN networkerror:=TRUE; RETURN; (* trouble *) END; END; (* loop *) IF trace THEN BConOut(CON,"N") END; HandleEvents(); END; END waitcts; (* request for data from remote hosts disk drives and system *) (* what wanted in command, the correct reply in reply, data in f *) PROCEDURE getfromremote(command, reply: DataKind; VAR f: frame): BOOLEAN; BEGIN IF (NOT C.networkactive) THEN RETURN FALSE END; (* error *) networkerror:=FALSE; R:=0; StartTimer; vblactive:=FALSE; IF trace THEN BConOut(CON,"A") END; f.kind:=data; f.cmd:=command; waitcts(TRUE); IF networkerror THEN RETURN FALSE END; IF trace THEN BConOut(CON,"B") END; SFRAME:=f; requesttosend:=TRUE; waitcts(FALSE); IF networkerror THEN RETURN FALSE END; IF trace THEN BConOut(CON,"C") END; REPEAT nrecframe; Nwait(event); HandleEvents(); IF R>retry THEN networkerror:=TRUE END; IF networkerror THEN RETURN FALSE END; UNTIL framewaiting AND (RFRAME.cmd=reply); IF trace THEN BConOut(CON,"D") END; f:=RFRAME; f.rw:=5; framewaiting:=FALSE; sendtoremote(ack,reply,f); (* send ack for reply *) IF networkerror THEN RETURN FALSE END; IF trace THEN BConOut(CON,"Z") END; vblactive:=TRUE; VSync; RETURN TRUE; END getfromremote; PROCEDURE sendtoremote(type: FrameKind; command: DataKind;VAR f: frame); BEGIN IF trace THEN BConOut(CON,"T") END; f.kind:=type; f.cmd:=command; IF debug THEN cleartosend:=TRUE END; (* so we can send in loop *) waitcts(TRUE); IF trace THEN BConOut(CON,"1") END; SFRAME:=f; requesttosend:=TRUE; waitcts(FALSE); IF trace THEN BConOut(CON,"2") END; IF SFRAME.kind=ack THEN cleartosend:=TRUE END; END sendtoremote; PROCEDURE ToHost(VAR f: frame); BEGIN IF trace THEN BConOut(CON,"H") END; IF f.kind=callreq THEN framewaiting:=FALSE; RETURN; END; IF f.kind=clearreq THEN framewaiting:=FALSE; RETURN; END; IF f.kind=diag THEN framewaiting:=FALSE; RETURN; END; IF f.kind=data THEN IF f.cmd=rdmediareq THEN IF trace THEN BConOut(CON,"M") END; framewaiting:=FALSE; nframe2.d0:=LONGCARD(MediaChange(CARDINAL(f.d0))); sendtoremote(data,rdmediaconf,nframe2); RETURN; END; IF f.cmd=rdbpbreq THEN IF trace THEN BConOut(CON,"P") END; framewaiting:=FALSE; nframe2.d0:=LONGCARD(GetBPB(CARDINAL(f.d0))); bpbptr:=ADDRESS(nframe2.d0); nbpbptr:=ADR(nframe2.info); FOR i:=0 TO TSIZE(BPB)-1 DO nbpbptr^[i]:=bpbptr^[i]; END; sendtoremote(data,rdbpbconf,nframe2); RETURN; END; IF f.cmd=rdrwabsreq THEN IF trace THEN BConOut(CON,"W") END; framewaiting:=FALSE; nframe2.d0:=LONGCARD(RWAbs(RW(f.rw),ADR(f.info),1,f.recno, CARDINAL(f.d0))); IF (f.rw=0) OR (f.rw=2) THEN nframe2.rw:=f.rw; nframe2.info:=f.info; (* if rec get buffer to send *) END; sendtoremote(data,rdrwabsconf,nframe2); RETURN; END; END; END ToHost; PROCEDURE senddata; BEGIN SFRAME.seq:=C.nextframetosend; SFRAME.ack:=1-C.frameexpected; sendf(SFRAME); IF SFRAME.kind#ack THEN StartTimer; (* set timer to wait for frame ack from remote host *) END; END senddata; PROCEDURE StartTimer; BEGIN CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timestart:=LONGCARD(REGISTER(0)); timer:=TRUE; (* test *) timefortimeout:=timestart; IncTime(timefortimeout,1+(CARDINAL(C.speed))); END StartTimer; PROCEDURE IncTime(VAR t : LONGCARD; c: CARDINAL); BEGIN IF c<1 THEN RETURN END; time:=t; SETREG(0,time); CODE(0280H,0,001FH); sec:=LONGCARD(REGISTER(0)); time:=t; SETREG(0,time); CODE(0280H,0,07E0H); min:=LONGCARD(REGISTER(0)); min:=min DIV 32; time:=t; SETREG(0,time); CODE(0280H,0,0F800H); hour:=LONGCARD(REGISTER(0)); hour:=hour DIV 2048; WHILE c#0 DO sec:=sec+1; c:=c-1; IF sec>29 THEN sec:=sec-30; min:=min+1; END; IF min>59 THEN min:=min-60; hour:=hour+1; END; IF hour>23 THEN hour:=hour-24; END; END; (* while *) t:=0; t:=sec; t:=t+(min*32); t:=t+(hour*2048); END IncTime; PROCEDURE TimeOut(): BOOLEAN; BEGIN IF (NOT timer) THEN RETURN FALSE END; CODE(3f3cH,0017H,4e4eH,548fH); (* gettime *) timeouttime:=LONGCARD(REGISTER(0)); SETREG(0,timeouttime); CODE(0280H,0,0FFFFH); timeouttime:=LONGCARD(REGISTER(0)); IF timeouttime>timefortimeout THEN StartTimer; RETURN TRUE; END; RETURN FALSE; END TimeOut; PROCEDURE Nwait(VAR e: evtype); BEGIN IF requesttosend AND cleartosend THEN e:=hostready; requesttosend:=FALSE; cleartosend:=FALSE; RETURN; END; IF C.sendreset THEN e:=reset; END; IF framebufferfull THEN cksum:=0; FOR i2:=0 TO recframesize-5 DO cksum:=cksum+CARDINAL(rframeptr^[i2]) END; IF (cksum=rframe.cksum) THEN e:=framearrival; INC(R); ELSE e:=cksumerr; framebufferfull:=FALSE; IF trace THEN BConOut(CON,"U") END; END; RETURN; END; nrecframe; IF TimeOut() THEN e:=timeout; INC(R); END; (* so sorry no frame ack *) END Nwait; PROCEDURE HandleEvents(); BEGIN IF event=hostready THEN event:=nothing; IF trace THEN BConOut(CON,"S") END; senddata; END; IF event=reset THEN IF trace THEN BConOut(CON,"I") END; SFRAME.kind:=resetreq; senddata; charcount:=0; R:=0; gotframe:=FALSE; framebufferfull:=FALSE; FOR d:=0 TO 5 DO gotmediach[d]:=FALSE; gotbpb[d]:=FALSE; END; C.nextframetosend:=0; C.frameexpected:=0; cleartosend:=TRUE; requesttosend:=FALSE; framewaiting:=FALSE; timer:=FALSE; C.sendreset:=FALSE; event:=nothing; END; IF event=framearrival THEN event:=nothing; IF (rframe.kind=ack) OR (rframe.kind=resetreq) THEN framewaiting:=FALSE END; IF trace AND (NOT framewaiting) THEN BConOut(CON,"F") END; IF (NOT framewaiting) THEN getf(RFRAME) END; framebufferfull:=FALSE; IF (RFRAME.ack=C.nextframetosend) OR debug THEN IF trace THEN BConOut(CON,"K") END; cleartosend:=TRUE; StartTimer; R:=0; timer:=FALSE; inc(C.nextframetosend); END; IF (RFRAME.seq=C.frameexpected) OR debug THEN IF trace THEN BConOut(CON,"E") END; IF RFRAME.kind#ack THEN (* try to exec command *) inc(C.frameexpected); framewaiting:=TRUE; R:=0; ToHost(RFRAME); END; END; IF RFRAME.kind=resetreq THEN charcount:=0; gotframe:=FALSE; framebufferfull:=FALSE; C.nextframetosend:=0; C.frameexpected:=0; FOR d:=0 TO 5 DO gotmediach[d]:=FALSE; gotbpb[d]:=FALSE; END; cleartosend:=TRUE; requesttosend:=FALSE; framewaiting:=FALSE; timer:=FALSE; C.sendreset:=FALSE; event:=nothing; END; END; SFRAME.seq:=C.nextframetosend; SFRAME.ack:=1-C.frameexpected; IF event=timeout THEN event:=nothing; IF trace THEN BConOut(CON,"R") END; sendf(SFRAME); framewaiting:=FALSE; END; END HandleEvents; BEGIN (* body of module *) IF Initialise() THEN charcount:=0; gotframe:=FALSE; framebufferfull:=FALSE; C.nextframetosend:=0; C.frameexpected:=0; FOR d:=0 TO 5 DO gotmediach[d]:=FALSE; gotbpb[d]:=FALSE; END; cleartosend:=TRUE; requesttosend:=FALSE; framewaiting:=FALSE; timer:=FALSE; C.sendreset:=FALSE; event:=nothing; C.networkactive:=TRUE; SuperExec(PROC(InstallVectors)) ; (* install the NETWORK *) Open("ANETWORK.INT",0,handle); IF handle>0 THEN (* if there is, load in init file *) count:=TSIZE(consave); GEMDOS.Read(handle,count,ADR(C)); OK:=Close(handle); ConfigureRS232(C.speed,NONE,136,-1,-1,-1); END; WITH BasePageAddress^ DO TermRes(CodeLen+BssLen+LONGCARD(CodeBase-ADDRESS(BasePageAddress)),0); END; END ; END NETWORK. `$N" GEMXModula-2/ST (c) Copyright TDI Software Ltd. 1985, 1986. The team : Chris Hall, Paul Curtis, and Phil Camp .[3][Modula-2 Run Time Error : | | #][OK]NVN^Nu"pNGNuNV*x ڄ=E*P-E@-M-VNh-H:. Eg :. Ef-n*.P-ENH:. Ef Nh-hN2:. Ef BBN:. E e Nh-PN-n I$"8B,)n9n)n )n)n)n|.n 9$/@>,VNhYN`NsN^NuNVBn ncN:.EIBtP ndRn`I* -EI* -EI* -EI* -EI* -Ez-E=| Bn=|BnBn <I* "NB=|N=|=|=|Bn=|z-E <I* "NB=|4=|=|=|Bn=|(mI* -E <I* "NB=|Bn=|BnBn <I* "NBNpL?NAN^NuNV/-+NI|Gz+WBn:.IJ4PgRn`=y$":. E d:.I0PN(z0x8.  HDE:.IPRnz0x8. HDE:.IPRnIGzWBn:.I8.nGP@Rn:.IJ4Pg`N+_N^Nu OAbrpNGNurpNGF'/NNn-/=-/H"Q ,IL?/^>/^Nf,oNsF'/NNn-/=-/H"Q G*- =/^Nf,oNs/NNn-/=/-/H _"h$",HL?/^>/^Nf,oNsF'SSfWWNsSf>NsSfF NsSfNqNsSf NNsNhBBB 9$Z!B*H$C! `N <L?NAN`WNsNVHx". $.bBCh8BAHA62HC6BAHA`B6HCBAHA8<㑲eRCQ-C -ALN^NuNVH(. ,. dF<gBEVBBGVB0G|b.f ؆dRE`kgb|HDkSEjؼdREBJfBEJEnB`|mpN-D LN^NuF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsF'pNNsNV . /2.??<NM*-E:. E b:.EI$^)PN:.E EI$)PN^NuNV/9$j?<N\/9$f?<N\/9$r?<N\/9$v?<N\/9$z?<N\/9$~?<N\/9$?<'N\/9$?<&N\/9$?<%N\N^NuNqNqNq O h*#$(y$#$V ( ШШ(y$V*,Ѕ.@//??<JNA (y$*,ڬ ڬڬ#$Z/<R?<N\/<D?<N\/<`?<N\/<n?<N\/<|?<N\/<?<N\/<?<'N\/<?<&N\/<2?<%N\#$pNGN NVz.0?p?NM*EE N^NuNVz.0?p?NM*EE N^NuNVz.0?p?NM*-E N^NuNV.?z. 0?p?NMN^NuNV0.?0. ?0. ? ./z.0?p?NM*-EN^NuNV0.?p?NM*-E N^NuNV0.?p ?NM*E N^NuNVp ?NM*-EN^NuNN VNVz.0?p?NN*-E N^NuNV0.?0. ?0. ?0.?z.0?z.0?p?NNN^NuNVp%?NNN^NuNV ./p&?NNN^NuN N NV0.?NA*-E N^NuNV0.?0. ?NA*-E N^NuNV ./ . /0.?0.?NA*-EN^NuNV ./0. ?NA*-EN^NuNV0.? . /0.?NA*-EN^NuNV0.?0. ? . /0.?NA*-EN^NuNVB?<1/. ?.N P-_N^NuNVB?<=(n* /?. N P*(n8N^NuNVB?<>?.N rXJfz`zE N^NuNVB?<??.(n //.N O (n (N^NuN PNVN^N VpNNV.  e. ~b| N^NuN B. N^NupNpNNVJ.e . c . f| N^NuN B. N^NupNN pNNVN^N"ANETWORK.INTNV n"n *.f *. gJgS`N"z(.c"Y`JgS`N^NuNV(n: Ed(n:RE(n8N(nBTN^NuNVHB:,:.y1e:.y2b`NJng :. Ef`NBy1:.SE?091WcN:.y231:.y2#-z:.y13-x3-vNB'<<Hy-lNPPJg4I-~* /z:91p ڮ /HxN xO B:,N z#:,091Wd Ry1NRTJ9% g1 9:,N:. Eg :. Ef`NBy1:.SE?091WcN:.y231:.y2#-z:.y13-x3-vNz:91p ڮ /I-~* /HxN xO B'<<Hy-lNPPJg B:,N z#:,091Wd Ry1NRTJ9% g1 9:,NpN"?.?.?./. ?.(y:4NO L?N^NuNVH:.y1e:.y2b`N:.y231:.y2#-zB'NNJg(:.y2I$B4P:.y2I%B4P:.y2I$J4PfTB'B'<Hy-lNPPJg4:.y2I$Pz(9-zfz#-z 9-zNpNpN?.(y:8NTL?N^NuNVH:.y1e:.y2b`N~:.y231:.y2#-zB'NNJg(:.y2I%B4P:.y2I$B4P:.y2I%J4Pf`NB'<<Hy-lNPPJg`N:.y2I%PI-~* #1:.y2I:f$N^NuNV(n, f B9$N^Nu(n, f B9$N^Nu(n, f B9$N^Nu(n, f`N(nJ,f>B9$B'(n*,?N Tz#/<<Hy/NPN^Nu(n, f`NB9$B(n*,?N T#/#/1I/* #1By1 y1oN2(y1:91&y1891P@ y1lRy1`<<Hy/NPN^Nu(n, f`NB9$B(nz:, (nI* /?<(n?, (n*,?N LO #/(nJl g(n:, Ef"(n3 /(nIG/z&Q<<Hy/NPN^NuN^NuNV31)@zy13)BHy)gN:N^NuNV?<NNT*#1$#11Hy1z91RE?N~\N^NuNV:. EdN^Nu(n #:$ 9:$*#:(n #:$ 9:$*#:*9:#:(n #:$ 9:$*#: *9: #: Jng`N*9:R#::.SE=Ez(9:cz(9:#:*9:R#:z;(9:cz<(9:#:*9: R#: z(9: cz(9: #: Nj(n B(n (:*9:(n ڔ(n (*9: p (n ڔ(n (N^NuNVJ9$fB.N^Nu?<NNT*#1 91*#1*91ֺ1cN:|N^NuB.N^NuNVJ9$g J9$g(nB9$B9$N^NuJ91g(nJ9$g`NBy$By1:9$[E?091WoN2(y1:91x4Py$3$091WlRy1`T:9$y):f(nBRy2N(nB9$N^NuNB'NJg(nRy2N^NuNV91 f1N91 f`N)>NBy$By2B9$B9$By2 y2cN4:92I$B4P:92I%B4P y2dRy2`By1By1$B9$B9$B9$B911J91f`NT1J9'&g 9'& fB9$J9$fHy+TNXB9$:9+Zy1f($N:By2B9$Hy1N X:9+Xy1f2J9+Vg*Hy1N X$By2Hy+TNX9+V f`NBy$B9$B9$By1By1By2 y2cN4:92I$B4P:92I%B4P y2dRy2`$B9$B9$B9$B91131)@zy13)B91 f1Hy)O Jy1o`z#:(?91Hy:(I1* /N O B'?91N hT$91B'?<?P?$B ?@<2i0$;<_#`hjmn(& (/'0BCk(l$ ; ",H'd%  '  &   '  #(( D `,|"-- (  P P @        "" ((  34  =P  =Ody    .=L% $!Z"h#w$6&5$'()*+ ,%-?.Y/s0 1 2 3 4 5%)=7<* 8C 9P :] ;j <w 6  >B6?@AB=    This program is an attempt to try to make a very simple ST to ST link. The main objective was to make it as transparent as possible to the user and to other programs. LOADING AND SETUP ANET uses three user vectors starting at $200 and the drivemap located at $4C2. A reset using the reset buttom sometimes does not clear the lower system memory so if this program is resident you must use a cold start "power off and power on" or a reboot program for it to be reloaded correctly when you run the ANETWORK.PRG or ANETCTRL.PRG after the reboot. The ANETCTRL.PRG has a reboot selection on the MENU. Double-click on the ANETWORK.PRG to load the resident program then double-click on the ANETCTRL.PRG to load the control program. After the first load you can usually load both the resident and control programs by running ANETCTRL.PRG after a reboot. ONLY LOAD THE ANETWORK.PRG IF YOU GET A MODULA-2 ERROR TRYING TO RUN ANETCTRL.PRG FIRST. AS IT WILL LOAD THE ANETWORK.PRG FOR YOU. The control program lets you set the baud rate, reboot the ST, reset the network message sequence count, turn the network on and off, see which ICONS to install to use the remote disks and of course to quit the control program. The NEW command on the sequence MENU is to resync the remote program if it gets out of sync due to a reboot, hang or and error condition. Click the mouse on NEW to send a resync command to the remote and try to access the ICON again. MAKE INT on the mode MENU will make a network setup file called ANETWORK.INT that ANETWORK.PRG reads to set the baud rate and to turn the netork on or off. ANETCTRL.PRG also reads the INT file when it is loaded and uses the parameters to set up the menu values. Clicking the pointer on MAKE INT will save the current menu values on the ANETCTRL.PRG menu to a new ANETWORK.INT file. To load the dial menu make a file called ANETWORK.DIL. It can have up to 16 entrys for phone numbers. Each entry must be terminated with a RETURN. If you have a HAYES modem enter the dial code, the number, a space, then the name of the service or person. Example: ATDT696-0060 genie ATDT691-7862 CIS USE Install the ICONS on the GEM DESKTOP for the remote system drive(s) you wish to access, then just use them just like any other disk drive. Due to the slower serial access it is usally better to copy the file a local disk if you wish to edit or run the file. Every effort has been made to make sure it is error free but I would only use it to read from the remote rather that sending files due to a crash may cause disk file links to be lost while creating new files on the remote system. You need a crossover cable for the ST to ST connection. like this. local remote 2------------\ /-------------3 \/ /\ 3------------/ \-------------2 7-----------------------------7 <-------- any length ---------> It is possible to use a modem using a std cable from the ST to modem. FRED BROOKS PS Please let me know of any bugs ASAP.