// EarsTransmit.Sr // Last modified November 30, 1979 10:19 AM by Taft get "altofilesys.d" structure SB: [ cch byte ch^0,255 byte ] structure SL: [ cch word ch^0,10000 byte ] structure FUNFA: [ fun byte; fa byte; ] structure FDA: [ track bit 13; sector bit 3; ] structure OF: [ macfp word; version word = fileid word = dests word; sn1 word; sn2 word; wmode word; wf word; macpos word; pos word; bphint word; macbi word = macbp word; formatted word = clearance word; fda @FDA; rgda word = rvrgbp word; last word; ] structure BS: [ dirty bit 1 falloced bit 1 blank bit 14 ] get "ho.df" //get "q.df" structure Q: [ head word tail word ] manifest [ lQ = (size Q)/16 ] get "ears.df" get "dir.df" get "vm.df" get "PupEftp.Decl" get "rn1.df" get "font.df" //get "st.df" //incoming procedures external [ InitPupLevel1 array array1 OpenEFTPSoc Enqueue InitializeContext AllocVm CallContextList DestroyInterrupt StartIO SetRegionSys SetRegionW updatedisplay Block macfe chknilfunfa lfm min move movec makecfa makefp ScanPages Dequeue ugt Dismiss SendEFTPBlock endofkeystream getchar CloseEFTPSoc SendEFTPEnd relvm GetPartner; ] //outgoing procedure external EarsTransmit //incoming statics external [ // vSDD freee lvUserFinishProc DefaultArgs DefaultArgs1 macfsn mpfsnfs macbp rgvpa rgbs rglastused vrlwsys ] //outgoing statics external [ Call0 Call1 Call2 Call3 ] //local statics static [ Call0 Call1 Call2 Call3 FDBuf EFTPSocket qBufRead qBufFree qBufFree2 qBufEther c2bufs pagessent sbr fUpDisp massagedone putetherdone vho cpages fp ridHostName ] //local manifest manifest [ blocktimeout= 500 endtimeout= 500 risysstate= 1 risyspast= 3 dummyzone= 0 numEFTPBufs= 4 numQbufs= 5 numQ2bufs= 3 Ears= 3 lshift 8 + 3 Szonesize= #500 Pzonesize= #700 Mzonesize= #400 eBLoc= #601 fmPassword=#20200 cNonFmWords= 64 + 1024 + 512 lFDE= 4 ] //-=-=-=-=-=-=-=-=-=- let EarsTransmit(fptr, pgnMac, ho) = valof //-=-=-=-=-=-=-=-=-=- [ vho = ho cpages=pgnMac //number of pages(counting 0) fp= fptr if ho>> HO.fEars eq false then macfsn = 0; let FontDir= nil let savefreee = freee let savedUFP = @lvUserFinishProc let EFTPCtxq = nil let poolBuf= nil // netAddress!0 = GetNetAddress(lv (vho>>HO.aslNetAddress)); // netAddress!1 = 0; // netAddress!2 = #20; // well known port for EFTP servers DefaultArgs = DefaultArgs1 Call0= table [ #55001 // sta 3 1 2 #115000 // mov 0 3 #35400 // lda 3 0 3 #1401 // jmp 1 3 ] Call1= table [ #55001 // sta 3 1 2 #115000 // mov 0 3 #35401 // lda 3 1 3 #1401 // jmp 1 3 ] Call2= table [ #55001 // sta 3 1 2 #115000 // mov 0 3 #35402 // lda 3 2 3 #1401 // jmp 1 3 ] Call3= table [ #55001 // sta 3 1 2 #115000 // mov 0 3 #35403 // lda 3 3 3 #1401 // jmp 1 3 ] [ //start repeat loop FDBuf= array(lBuf) if macfsn>0 then FontDir= array1(256,0) unless CreateFontDir(FontDir) do resultis false EFTPCtxq = array1(2,0) //init context queue InitPupLevel1(dummyzone,EFTPCtxq,numEFTPBufs) Enqueue(EFTPCtxq,InitializeContext(array(Szonesize), Szonesize,callscan)) Enqueue(EFTPCtxq,InitializeContext(array(Mzonesize), Mzonesize,massage)) Enqueue(EFTPCtxq,InitializeContext(array(Pzonesize), Pzonesize,PutEther)) qBufRead= array1(lQ,0) //scanpages puts data here qBufEther= array1(lQ,0) //massage puts it here and putether sends it qBufFree= array1(lQ,0) //available to scanpages poolBuf= array(numQbufs * lBuf) AllocVm(qBufFree,poolBuf, numQbufs, true) qBufFree2= array1(lQ,0) //available to scanpages poolBuf= array(numQ2bufs * lBuf) AllocVm(qBufFree2,poolBuf, numQ2bufs, true) c2bufs= numQ2bufs pagessent = 0 massagedone= false putetherdone= false SetRegionW(vrlwsys, 0, lv vho>>HO.asbNetAddress) ridHostName = rinil ridHostName<>SL.ch^0 -$0 // let host = 0 // for ich = 2 to sl>>SL.cch-1 do // [ dig = sl>>SL.ch^ich - $0 // if dig ls 0 % dig gr 9 then break // host = host lshift 3 + dig // ] // netAddress = net lshift 8 + host // resultis netAddress // ] //-=-=-=-=-==-===-=-== and getbuf(q) = valof //-=-=-=-=-==-===-=-== //waits for an item from the queue, Blocks meanwhile //result is the item from the queue [ let item = 0 while item eq 0 do [ item = Dequeue(q); Block() ] resultis item ] //-=-=-=-=-=-=-=-=-=-=- and tcBlock(x,y) = valof //-=-=-=-=-=-=-=-=-=-=-=- [ Block(); resultis tcToYou ] //-=-==--=-=-=-=-==-=- and updateFS(scwfm,fsoffset) be //-=-=-=-=-=-=--=-=-=-= //updates and sends the FS //unless fsoffset=0, shift to even page boundaries //SCWFM= number to add to address field //FSOFFSET= word in page where FS starts [ test fsoffset eq 0 ifso for t=1 to 2 do [ let tbuf= getbuf(qBufRead) for i=tbuf>>BUF.ca + 3 to tbuf>>BUF.ca + 255 by 4 do rv(i) = rv(i) + scwfm Enqueue(qBufEther, tbuf) ] ifnot [ let tbuf1=getbuf(qBufRead) let tbuf2=getbuf(qBufRead) let tbuf3=getbuf(qBufRead) let ca1=tbuf1>>BUF.ca let ca2=tbuf2>>BUF.ca let ca3=tbuf3>>BUF.ca move(ca1+fsoffset,ca1,256-fsoffset) move(ca2,ca1+256-fsoffset,fsoffset) move(ca2+fsoffset,ca2,256-fsoffset) move(ca3,ca2+256-fsoffset,fsoffset) for i=ca1+3 to ca1+255 by 4 do rv(i)=rv(i)+scwfm for i=ca2+3 to ca2+255 by 4 do rv(i)=rv(i)+scwfm Enqueue(qBufEther,tbuf1) Enqueue(qBufEther,tbuf2) Enqueue(qBufFree,tbuf3) ] ] // //-=-=-=-=-==-===-=-== // and updateDD(DDBuf) be // //-=-=-=-==-=-=-==--=-= // // only called for Ears files // [ // Block() // let cafd = FDBuf>>BUF.ca // let cadd = DDBuf>>BUF.ca // movec(cadd+#20,cadd+#23,0) //reserved for PUB, zero otherwise // // if macfsn eq 0 then return // // rv(cadd+#11)=1 //length of FD // let FDElast = lFDE*(macfsn-2) //0th FS doesn't count // // let strecfm = rv(cafd + FDElast) // let crecfm = rv(cafd + FDElast + 1) // let crecfs = rv(cafd + FDElast + 2) // // let crecfonts= strecfm + crecfm + crecfs // let crecfontdir = 1 // rv(cadd+1)= rv(cadd+1) + crecfonts + crecfontdir // // move((lv vho>>HO.aslPrintBy) + 1,cadd+#232,#20); // //fake cadd+#231 as an SL and add EOL character // let cch = (lv (vho>>HO.aslPrintBy))>>SL.cch // if cch>#37 then cch = #37 // (cadd+#231)>>SL.ch^cch = #376 // ] //-=-=-=-=-=-=-=-=-=-=-=-=-=-- and CreateFontDir(FontDir) = valof //-=-=-=-=-=-=-=-=-=-=-=-=-=--= //4-word entry for each FS // 0: Starting record (page) of FM (rel 1st FM) = strecfm // 1: Number of records in FM = crecfm // 2: Number of records in FS = crecfs // 3: ttytab=0 //Creates 256-word array FontDir and buffer FDBuf //Each set FM starts with extra word #20200, so 1 extra word is // included in word count //0th FM doesn't count, so FS^i goes in fontdir^(i-1) [ let strecfm = 0 let tfs = nil let crecfs = nil let crecfm = nil let cwfm= nil let tfunfa=nil let fd=nil let fdh=nil for fsn = 1 to macfsn - 1 do //0th FS doesn't count [ tfs = mpfsnfs!fsn cwfm=0 crecfm=0 crecfs = 0 for fe = 0 to macfe(tfs) -1 do [ if chknilfunfa(tfs,fe) then [ crecfs = crecfs + 2; loop ] cwfm= cwfm + lfm(tfs,fe) crecfm= (1 + cwfm + 255) rshift 8 //div 256 crecfs = crecfs + 2 if ugt(crecfm, 128) then [ SetRegionSys(risyspast,169,50) SetRegionSys(risysstate,215) resultis false ] ] FontDir>>FONTDIR.strecfm^(fsn-1) = strecfm FontDir>>FONTDIR.crecfm^(fsn-1) = crecfm FontDir>>FONTDIR.crecfs^(fsn-1) = crecfs FontDir>>FONTDIR.ttytab^(fsn-1) = 0 strecfm = strecfm + crecfm + crecfs ] //now create a buffer FDBuf>>BUF.ca = FontDir resultis true ] //-=-=-=-=-=-=-=-=-=- and massage() be //-=-=-=-=-=-=-=-=-== //takes data off qBufRead and enqueues it on qBufEther //Send pages 3 - (DD - 1) of main file //For each FS, // --Send all font FM's // --Filler to round out page // --Update font FS's - add start of font FM (words) to each // character address entry // --Send all font FS's (these are round already) //Update Document Directory //Send Document Directory // //Set done flag //ears file has 2 garbage pages at start, press file does not //for press file, macfsn must be 0, vho.fEars must be false [ let tfs=nil let scwfm=0 let cwfmleft=0 let fsoffset=0 let tbuf=0 let DDBuf=0 let tfunfa=nil let tbuf1=nil let tbuf2=nil let ca1=0; let ca2=0; let c1l=0; let c2f=0; let c2l=0 //cai= core address of tbufi //cil= buffer relative address of first unoccupied word //cif= buffer relative address of first occupied word //1st 2 pages are garbage for ears //last is Doc Dir //test vho>>HO.fEars // ifso for t=1 to 2 do Enqueue(qBufFree,getbuf(qBufRead)) // ifnot for t=1 to 2 do Enqueue(qBufEther,getbuf(qBufRead)) for t=3 to cpages-2 do Enqueue(qBufEther,getbuf(qBufRead)) DDBuf=getbuf(qBufRead) //cpages-1 page is DD //if vho>>HO.fEars then updateDD(DDBuf) Block() if macfsn eq 0 then [ Enqueue(qBufEther,DDBuf) massagedone=true Block() repeat ] Enqueue(qBufEther,FDBuf) for fsn= 0 to macfsn-1 do [ Block() tfs=mpfsnfs!fsn if macfe(tfs) eq 0 then loop tbuf1=getbuf(qBufFree2) c2bufs=c2bufs-1 ca1=tbuf1>>BUF.ca rv(ca1)=fmPassword c1l=1 for fe=0 to macfe(tfs) - 1 do [ Block() if chknilfunfa(tfs,fe) then loop cwfmleft= lfm(tfs,fe) c2f=64 //FM starts on word 64 of page 5 while cwfmleft ne 0 do [ tbuf2=getbuf(qBufRead) ca2=tbuf2>>BUF.ca c2l= min(256,cwfmleft + c2f) cwfmleft=cwfmleft - min(cwfmleft,256-c2f) test (c2l-c2f+c1l) ge 256 ifso [ move(ca2+c2f,ca1+c1l,256-c1l) Enqueue(qBufEther,tbuf1) move(ca2+c2f+256-c1l,ca2,256) //overkill tbuf1=tbuf2 ca1=tbuf1>>BUF.ca c1l=c2l-c2f+c1l-256 ] ifnot [ move(ca2+c2f,ca1+c1l,c2l-c2f) c1l=c1l+c2l-c2f Enqueue(qBufFree,tbuf2) ] c2f=0 ] ] if c1l ne 0 then Enqueue(qBufEther,tbuf1) //now do fs's //keep track of scwfm to update the FS scwfm = 1 //fmPassword for fe= 0 to macfe(tfs) -1 do [ Block() if chknilfunfa(tfs,fe) then [ //send 512 words for nil FS- any words will do Enqueue(qBufEther,getbuf(qBufFree2)) Enqueue(qBufEther,getbuf(qBufFree2)) c2bufs=c2bufs-2 loop ] fsoffset= (lfm(tfs,fe) + cNonFmWords) rem 256 updateFS(scwfm,fsoffset) //update and SEND FS scwfm= scwfm + lfm(tfs,fe) ] ] Enqueue(qBufEther,DDBuf) massagedone = true Block() repeat ] //-=-=-=-=-==-===-=-== and callscan() be //-=-=-=-==-=-=-==--=-= [ let cfa= vec lCFA let tfs=0 let cpfs=0 let cpfsfirst=0 let cpfm = 0; let tfunfa=0 let tfp= vec 5 makecfa(cfa,fp) ScanPages(cfa,qBufFree,tcBlock,0,cpages,qBufRead) for fsn= 0 to macfsn-1 do [ tfs= mpfsnfs!fsn for fe = 0 to macfe(tfs) -1 do [ Block() if chknilfunfa(tfs,fe) then loop cpfm= (lfm(tfs,fe)+ cNonFmWords +255)/256 -6 makefp(tfp,tfs,fe) makecfa(cfa,tfp,5,(lv(tfs>>FS.rvmpfedafm))!fe) ScanPages(cfa,qBufFree,tcBlock,0,cpfm,qBufRead) ] for fe = 0 to macfe(tfs) -1 do [ Block() if chknilfunfa(tfs,fe) then loop test (lfm(tfs,fe)+cNonFmWords) rem 256 eq 0 ifso cpfs=2 ifnot cpfs=3 cpfsfirst=(lfm(tfs,fe)+cNonFmWords)/256 -1 makefp(tfp,tfs,fe) makecfa(cfa,tfp,cpfsfirst,(lv(tfs>>FS.rvmpfedafs))!fe) ScanPages(cfa,qBufFree,tcBlock,0,cpfs,qBufRead) ] ] Block() repeat ] //-=-=-=-=-=-========- and PutEther() be //-=-=-==-=-=-==-=-==-= //takes buffers off qBufEther, sends them via EFTP, and returns the // buffers to qBufFree //if qBufEther is empty (buf=0) check massagedone- if massage is // done, so is PutEther [ let message=0 let buf=0 // netAddress!0 = GetNetAddress(lv (vho>>HO.aslNetAddress)) // netAddress!1 = 0 // netAddress!2 = #20 // well-known socket number for EFTP let netAddress = vec 3; unless GetPartner(lv (vho>>HO.asbNetAddress), 0, netAddress, 0, #20) then [ putetherdone = true; sbr = -10 Block(); ]; EFTPSocket = array(lenEFTPSoc) OpenEFTPSoc(EFTPSocket,0,netAddress) Dismiss(100) [ fUpDisp= false buf= Dequeue(qBufEther) test buf eq 0 ifso test massagedone ifso PutEtherEnd() ifnot Block() ifnot [ L6: sbr =SendEFTPBlock(EFTPSocket,buf>>BUF.ca,512,blocktimeout) unless endofkeystream() do if getchar() eq $*177 then [ sbr= -5 CloseEFTPSoc(EFTPSocket) putetherdone= true Block() ] if sbr ls 0 then //error from sendblock [ if pagessent ne 0 then [ sbr= -4; PutEtherEnd() ] message = selecton sbr into [ case -1: 170; case -2: 171; default: 172 ] SetRegionSys(risyspast,ridHostName,message,180) SetRegionSys(risysstate,178) fUpDisp= true CloseEFTPSoc(EFTPSocket) OpenEFTPSoc(EFTPSocket,0,netAddress) Dismiss(200) goto L6 ] //transmission proceeding if pagessent eq 0 then [ SetRegionSys(risyspast, 179, ridHostName, 249) SetRegionSys(risysstate, 178) fUpDisp= true Block() ] pagessent = pagessent + 1 test c2bufs ls 2 ifso [ Enqueue(qBufFree2,buf); c2bufs=c2bufs+1 ] ifnot Enqueue(qBufFree,buf) ] ] repeat ] //-=-=-=-=-==-=-===-==- and PutEtherEnd() be //-=-=-=-==-=-=-==-=-=- [ SendEFTPEnd(EFTPSocket,endtimeout) CloseEFTPSoc(EFTPSocket) putetherdone = true Block() ]