10 REM > FindServer
   20 REM Use FindServer protocol to find a server
   30 :
   40 DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256
   50 DIM rxBuf% 31,txBuf% 15:rx%=0:tx%=0
   60 :
   70 ON ERROR REPORT:PROCNet_RxKill(rx%):PRINT:END
   80 :
   90 rx%=FNNet_RxOpen(0,&B1,rxBuf%,&20)
  100 $txBuf%="DESPOOL "              :REM Look for a DESPOOL server
  110 $txBuf%="MUGINS  "              :REM Look for a MUGINS server
  120 $txBuf%="RISCOS  "              :REM Look for a RISCOS server
  130 $txBuf%="TELETEXT"              :REM Look for a TELETEXT server
  140 $txBuf%="UNIX    "              :REM Look for a UNIX server
  150 $txBuf%="        "              :REM Look for all server types
  160 try%=10
  170 REPEAT
  180     tx%=FNNet_TxCount(&FFFF,&80,&B0,txBuf%,8,0,0,0)
  190     IF tx% THEN PRINT FNNet_Err(tx%):END
  200     rxok%=FNNet_Rx(rx%)
  210     IF NOT rxok%:A%=TIME+50:REPEATUNTILTIME>A%:try%=try%-1
  220 UNTIL rxok% OR try%<1
  230 IF NOT rxok% THEN PROCNet_RxKill(rx%):PRINT "No server found":END
  240 rxnum%=FNNet_RxRead(rx%):stn%=X%!3
  250 PRINT "Server found on station ";FNNet_Stn(stn%)
  260 IF ?rxBuf% THEN PRINT "Server error: ";$(rxBuf%+1):END
  270 rxBuf%?(12+rxBuf%?11)=13:name$=$(rxBuf%+12)
  280 rxBuf%?11=13:server$=$(rxBuf%+3)
  290 vers%=rxBuf%?2
  300 portBase%=rxBuf%?1
  310 PRINT "Type: ";server$;"   Name: ";name$
  320 PRINT "Base port: &";FNh0(portBase%,2);"   Version: ";vers%DIV16;".";(vers%AND15)*10
  330 END
  340 :
  350 :
  360 :
  370 :
  380 :
  390 :
  400 DEFFNNet_TxCount(Stn%,Ctrl%,Port%,Addr%,Len%,RAddr%,Try%,Delay%):LOCAL TxErr%
  410 DEFFNNet_Tx(Stn%,Ctrl%,Port%,Addr%,Len%,RAddr%):LOCAL TxErr%,Try%,Delay%:Try%=10:Delay%=50
  420 X%?1=Port%:X%!2=Stn%:X%!4=Addr%:X%!8=Addr%+Len%:X%!12=RAddr%
  430 IFStn%=&FFFF:X%!4=Addr%!0:X%!8=Addr%!4
  440 REPEAT:REPEAT:X%?0=Ctrl%:A%=&10:CALL &FFF1:UNTILX%?0
  450   REPEAT:TxErr%=FNbyte(&32,0,0):UNTILTxErr%<&80
  460   IFTxErr%=&41 OR TxErr%=&42:IFTry%:A%=TIME+Delay%:REPEATUNTILTIME>A%:Try%=Try%-1
  470 UNTILNOT(TxErr%=&41 OR TxErr%=&42) OR Try%<1:=TxErr%
  480 :
  490 DEFFNNet_RxOpen(Stn%,Port%,Addr%,Len%)
  500 X%?0=0:X%?1=&7F:X%?2=Port%:X%!3=Stn%:X%!5=Addr%:X%!9=Addr%+Len%
  510 A%=&11:CALL &FFF1:=X%?0
  520 :
  530 DEFFNNet_Rx(RxNum%):=(FNbyte(&33,RxNum%,0)AND&80)<>0
  540 :
  550 DEFFNNet_RxRead(RxNum%)
  560 X%?0=RxNum%:A%=&11:CALL &FFF1:A%=X%!9-X%!5:X%!5=0:=A%
  570 :
  580 DEFPROCNet_RxKill(RxNum%):A%=FNbyte(&34,RxNum%,0):ENDPROC
  590 :
  600 DEFFNNet_Err(A%):IFA%=0:=""
  610 =MID$("Line jammedNet errorNot listeningNo clockBad Tx blockNo reply",VALMID$("011221344254",(A%-&40)*2+1,2),VALMID$("110913081208",(A%-&40)*2+1,2))
  620 :
  630 DEFFNNet_Stn(A%):=LEFT$(FNd0(A%DIV256,3)+".",(A%DIV256)<>0)+FNd0(A%AND255,3)
  640 DEFFNNet_StnFixed(A%):=FNd0(A%DIV256,3)+"."+FNd0(A%AND255,3)
  650 :
  660 DEFFNbyte(A%,X%,Y%)=((USR&FFF4)AND&FF00)DIV256
  670 DEFFNd0(A%,N%)=RIGHT$("00000000"+STR$A%,N%)
  680 DEFFNh0(A%,N%)=RIGHT$("0000000"+STR$~A%,N%)