Program notes
LASTC.UB (The console program)
5 'DOS Beowulf V 2.0 October 7, 2002, Bill Weller
10 cls:console 0,*:color 3
20 Id=16 'sets this machine as console
30 '
40 'initialize port
50 Base%=956 'base% address for lpt1 on a Thinkpad Most
machines use 888 for LPT1. Use FINDPORT.EXE in the ZIP package to determine the
address on your machine.
60 out Base%+2,4
70 out Base%,0 'clear port
80 goto 370
90 '
100 '
110 beep 1:for T=1 to 100000:next:beep 0:return I
though it would be nice to have each node beep as it was polled, but it messed
up the timing. I left it in so you can have a BEEP when the machine has finished
your app.
120 '
130 '
140 *Newbyte UBASIC looks for the *. For speed, make
sure your GOTOs and GOSUBs point to a line with "*" rather than the
line below it.
150 Nflag=0
160 gosub 240
170 B=Inbyte%
180 gosub 240
190 if Inbyte%<>B then 160 'make sure it is stable Allows
time for the inverted bits to switch and slow machines to be mixed with fast
ones.
200 if Inbyte%<>Outbyte then Newbyte%=Inbyte%:Nflag%=1
210 if Newbyte%>127 then Newbyte%=Newbyte%-128
220 return
230 '
240 *Inbyte
250 if inkey<>"" then out Base%,0:end Eliminating
this line will speed things greatly, but you need CONTROL / BREAK to exit. I
left it in to help when troubleshooting.
260 Inbyte%=bitor(bitand(inp(Base%+1),240),bitand(inp(Base%+2),15)) Takes
care of those darn inverted bits.
270 Inbyte%=bitxor(Inbyte%,139)
280 return
290 '
300 *Outbyte
310 Lastbyte%=Outbyte%+Flag%
320 out Base%,Lastbyte%
330 if Flag%=0 then Flag%=128:return This is
where bit 8 is turned on and off.
340 if Flag%=128 then Flag%=0
350 return
360 '
370 *Ringtest
380 cls:N=0
390 print " Testing ring";
400 for I=1 to 6:N=2^I Tests each line
individually, looking for wiring errors.
410 clr time
420 Outbyte%=N:gosub 300
430 gosub 140:print ".";
440 if time1000<15 then 430 Time is
necessary, in case you skipped a node when you numbered them. It does not,
however check to see if a node number was used twice. A number greater than 15
might be needed if there are a lot of nodes. Nodes on the ring do not have to be
in any sequence.
450 if Inbyte%<>Lastbyte% then Test=1
460 if Test=1 and I=1 then goto 520
470 next I
480 if Test=1 then color 4:print " FAIL Check wiring.":color 3:end
490 print:print " Ring continuity and wiring bit test OK.":out Base%,0
500 print:print " Press any key to continue."
510 if inkey="" then 510 else goto 550
520 color 4:print:print " FAIL.. make sure nodes are on.":color 3:end
530 '
540 '
550 *RollCall Checks to see which node numbers
are used, and makes sure they are all running.
560 cls
570 Nn=0:print
580 print " Roll call.":print:color 2
590 for Node=17 to 20
600 Outbyte%=Node:gosub 300
610 for T=1 to 15000:next Allow plenty of time to look
for slow nodes.
620 gosub 140
630 if Inbyte%=Lastbyte% then 680
640 if Inbyte%<>6 then 620
650 print " Node";Node-16;" is online":inc Nn
660 out Base%,4 Four is End Of Transmission (EOT)
670 for T=1 to 10000:next
680 next
690 Outbyte%=4:gosub 300
700 if Nn=0 then color 4 else color 3
710 print:print " There are";Nn;" nodes online."
720 if Nn=0 then then color 3:end
730 print:print " Press any key to process.":print
740 if inkey<>"" then out Base%,3:goto 890 else 740 Commands
the nodes to run you application.
750 '
760 *Get_String This is the heart of the data
transmission. All data communication is ASCII bytes, 32 to 127. This way there
is no confusion over what is data, and which are command bytes.
770 In$="":Lastbyte%=0
780 gosub 140
790 if B=3 then 780 In the nodes, a "3"
tells it to run you application. This line tells the console to ignore it.
800 if B=Lastbyte% then 780
810 Lastbyte%=B:out Base%,Inbyte%
820 if B>127 then B=B-128
830 In$=In$+chr(B)
840 for T=1 to 100:next
850 if B<>4 then 780
860 In=val(mid(In$,3,len(In$))) It seems that UBASIC
does not like null strings, and inserts a few non-ASCII bytes.
870 return
880 '
890 *StartOfYourProgram
900 X=2+2
910 print " From console: 2+2=";X
920 for T=1 to 10000:next May not be needed on your
cluster.
930 out Base%,17 ' poll node 1 Tells
node to start sending data
940 gosub 760 Get the string. The
computational results from the node are contained in IN$ as ASCII.
950 print " From node 1: ";val(In$) At this point
something would be done with the data, added to what was calculated in the
console, sent to floppy, forwarded to another node, etc. before getting more
data.
960 '
970 for T=1 to 10000:next
980 out Base%,18 'poll node 2
990 for T=1 to 10000:next Wait for the
"18" to get to the node, and allow time for it to set up transmitting
before looking for the first byte..
1000 gosub 760
1010 print " From node 2: ";val(In$)
1020 gosub 110
1030 '
1040 *EndOfYourProgram
1050 'out base%,0:end
This is the absolute bare program. Much could be added, such as multiple apps, chaining, shared data, transfer or modification of formulas. I need more feedback from users before I can make this more sophisticated.