10 REM TIN PAN ALLEY 20 REM Mike Bostock 30 REM (c) CET 1983 Published by BBC Publications 40 REM version 2.0 50 : 60 ?&FE62 = 15 : REM 00001111 0-3 output 4-7 input 70 port = &FE60 : REM user port location 80 PROCmotors_on 90 : 100 ON ERROR IF ERR=17 PROCcomplete :PROCend: END ELSE REPORT:PRINT" at line ";ERL:PROCend:END 110 : 120 MODE7 : PROCoff 130 PROCsetup 140 PROCdouble (CHR$ 130 +program_name$,-1,4) 150 IF NOT FNbuggy_connected THEN PROCnogo : PROCend : END 160 : 170 PROCcharacters 180 PRINT TAB(2,20) "Do you need instructions ? (Y/N) "; 190 answer$ = FNinput (1,"YyNn") 200 IF answer$="Y" OR answer$="y" THEN PROCinstructions 210 : 220 ON ERROR IF ERR=17 MODE7:PROCescape ELSE REPORT:PRINT" at line ";ERL:PROCend:END 230 REM continues here after PROCerror 240 IF end THEN CLS : PROCcomplete :PROCend: END 250 : 260 MODE4 : PROCoff :VDU19,1,4,0,0,0:VDU19,0,7,0,0,0:REM blue on white 270 REPEAT 280 REPEAT 290 REPEAT 300 IF answer$ = "1" OR answer$ = "3" THEN PROCclean1: ELSE CLS : PROCscreen2 310 PROCcard 320 PRINT TAB(9,30) "Press ESCAPE to halt." 330 : 340 PROCchoice1:answer$=FNinput (1,"1234") 350 IF answer$="2" AND card>1 THEN PROCreplay:PROCspace1 (28) : CLS 360 IF answer$="3" THEN PROCmanual 370 IF answer$="4" THEN PROCtunes 380 UNTIL answer$ = "1" AND card<100 390 : 400 PROCscan 410 IF fault THEN PROCfault 420 PROCerase 430 IF fault = 0 THEN PROCspace1 (27) 440 UNTIL card=100 450 fault=3 : PROCfault 460 UNTIL FALSE 470 END 480 : 490 : 500 : 510 DEF PROCbar_check (direction,colour) 520 LOCAL pulse,edge 530 pulse = (direction OR 2) 540 pulsecount = 0 : edge = 0 550 REPEAT 560 ?port = direction : PROCdelay(speedcontrol) 570 ?port = pulse : PROCdelay(2) 580 IF FNsensor = colour THEN edge = 1 590 pulsecount = pulsecount + 1 600 IF pulsecount > maxwidth THEN fault = 1 610 UNTIL edge OR fault 620 ENDPROC 630 : 640 DEF FNbuggy_connected = NOT (?port AND 32) 650 : 660 DEF PROCcalculate 670 PROCcard 680 number = INT((14*scantime(1)/(scantime(1)+scantime(2)))+0.5) 690 notetype = INT((7*((duration-adjustment)/(scantime(1)+scantime(2))))+1) 700 IF notetype < 1 THEN notetype = 1 710 ENDPROC 720 : 730 DEF PROCcard 740 PRINT TAB(7,1) card 750 ENDPROC 760 : 770 DEF PROCcharacters 780 REM box 790 VDU 23,239,255,129,129,129,129,129,129,255 800 REM block 810 VDU 23,240,255,255,255,255,255,255,255,255 820 REM # 830 VDU 23,241,0,0,10,31,10,31,10,255 840 REM # /no ledger 850 VDU 23,238,0,0,10,31,10,31,10,0 860 REM crotchet in space 870 VDU 23,242,0,28,62,126,124,120,0,255 880 REM crotchet on line 890 VDU 23,243,0,0,0,0,0,28,62,255 900 VDU 23,244,124,120,0,0,0,0,0,255 910 REM minim on line 920 VDU 23,247,0,0,0,0,0,28,34,255 930 VDU 23,248,68,56,0,0,0,0,0,255 940 REM minim in space 950 VDU 23,246,0,28,34,66,68,120,0,255 960 REM dot 970 VDU 23,245,0,0,0,0,48,48,0,255 980 REM dot/no ledger 990 VDU 23,237,0,0,0,0,48,48,0,0 1000 REM blank 1010 VDU 23,249,0,0,0,0,0,0,0,0 1020 REM crotchet/no ledger 1030 VDU 23,250,0,28,62,126,124,120,0,0 1040 REM minim/no ledger 1050 VDU 23,251,0,28,34,66,68,120,0,0 1060 REM bottom half crotchet/no ledger 1070 VDU 23,252,124,120,0,0,0,0,0,0 1080 REM bottom half minim/no ledger 1090 VDU 23,253,68,120,0,0,0,0,0,0 1100 ENDPROC 1110 : 1120 DEF PROCchoice1 1130 PRINT TAB(4,25) "1 scan"; TAB(4,26) "2 replay" 1140 PRINT TAB(4,27) "3 manual drive"; TAB(4,28) "4 examples" 1150 PRINT TAB(24,27) "Your choice: "; 1160 ENDPROC 1170 : 1180 DEF PROCchoice2 1190 PROCerase 1200 PRINT TAB(4,25) "1 test run" 1210 PRINT TAB(4,26) "2 tune 1" 1220 PRINT TAB(4,27) "3 tune 2" 1230 PRINT TAB(4,28) "4 menu" 1240 PRINT TAB(24,27) "Your choice: "; 1250 ENDPROC 1260 : 1270 DEF PROCclean1 1280 LOCAL I% 1290 FOR I% = 6 TO 12 : PRINT TAB(12,I%) SPC(15) : NEXT 1300 PROCstaves 1310 PROCrectangle (380,639,864,892) 1320 PRINT TAB(13,22) SPC(13) 1330 PROCline (380,830,860,830) 1340 PROCerase 1350 ENDPROC 1360 : 1370 DEF PROCclef (x,y,N) 1380 REM Draws a musical treble clef, starting at the co-ordinates x & y, the size being given by the third parameter, N 1390 MOVE x,y 1400 PLOT 1, -N, N:PLOT 1, 0, N 1410 PLOT 1, N, N:PLOT 1, 2*N, 0 1420 PLOT 1, 2*N,2*-N:PLOT 1, 0,2*-N 1430 PLOT 1,2*-N,2*-N:PLOT 1,3*-N, 0 1440 PLOT 1,3*-N, 3*N:PLOT 1, 0, 2*N 1450 PLOT 1, 7*N,16*N:PLOT 1, 0, N 1460 PLOT 1, -N, 2*N:PLOT 1, -N, -N 1470 PLOT 1, 0,28*-N:PLOT 1, -N, -N 1480 PLOT 1, -N, N:PLOT 1, N, N 1490 ENDPROC 1500 : 1510 DEF PROCdelay (count) 1520 LOCAL delay 1530 FOR delay = 1 TO count: NEXT delay 1540 ENDPROC 1550 : 1560 DEF PROCdraw_card1 1570 LOCAL line,K% 1580 line = 1 1590 IF N>13 THEN N=N-12 1600 REPEAT 1610 PRINT TAB(12,5+line) CHR$240 1620 K%=1 1630 REPEAT 1640 IF K%=N THEN PRINT TAB(12+K%,5+line) " " ELSE PRINT TAB(12+K%,5+line) CHR$ 240 1650 K%=K%+1 1660 UNTIL K%=14 1670 PRINT TAB(26,5+line) CHR$240 1680 line=line+1 1690 UNTIL line>6 1700 ENDPROC 1710 : 1720 DEF PROCerase 1730 LOCAL I% 1740 FOR I% =25 TO 28 : PRINT TAB(1,I%) SPC(38); : NEXT 1750 ENDPROC 1760 : 1770 DEF PROCescape 1780 PROCmotors_on 1790 PRINT TAB(0,1) CHR$(130) "BBC Buggy" 1800 PROCdouble (CHR$ 130 +program_name$,-1,5) 1810 PRINT TAB(7,10) "1. continue" 1820 PRINT TAB(7,12) "2. delete last entry" 1830 PRINT TAB(7,14) "3. start again" 1840 PRINT TAB(7,16) "4. end program" 1850 PRINT TAB(3,20) CHR$(134) "Your choice: "; 1860 answer$ = FNinput (1,"1234") 1870 IF answer$ = "2" AND card >1 THEN card = card - 1 : store = store - 1 1880 IF answer$ = "3" THEN RUN 1890 IF answer$ = "4" THEN end = 1 1900 answer$ = "" 1910 ENDPROC 1920 : 1930 DEF PROCfault 1940 LOCAL count 1950 count=0 1960 IF fault = 1 THEN message$ = "READ FAULT" 1970 IF fault = 2 THEN message$ = "This card cant be an octave card" : card = card -1 1980 IF fault = 3 THEN message$ = "Two octave cards in a row":flag=0:card=card+1 1990 IF fault = 4 THEN message$ = "No record of this card" : card = card - 1 2000 PRINT TAB(1,30);SPC(38) 2010 REPEAT 2020 count = count + 1 2030 PROCcentre (message$,30) 2040 PROCdelay(600) 2050 PRINT TAB(1,30);SPC(38) 2060 SOUND 2,-15,197,1 2070 PROCdelay(200) 2080 UNTIL count=6 2090 IF card<1 THEN card=1 2100 ENDPROC 2110 : 2120 DEF PROCgreensleeves 2130 LOCAL I 2140 RESTORE 4950 2150 FOR I = 1 TO 19 : READ N(I),T(I) : NEXT 2160 store = 20 2170 ENDPROC 2180 : 2190 DEF PROCinstructions 2200 CLS : PROCdouble (CHR$ 130 +program_name$,-1,2) 2210 PROCcentre ("In this program the Buggy will pick",5) 2220 PROCcentre ("up musical information as it runs",7) 2230 PROCcentre ("over a line of cards.",9) 2240 PROCspace1 (23) 2250 PROCcentre ("Select the first few cards which",12) 2260 PROCcentre ("represent the first notes of a tune.",14) 2270 PROCcentre ("The gap before the card represents",16) 2280 PROCcentre ("the duration of the note on the card.",18) 2290 PROCspace1 (23) 2300 CLS 2310 PROCdouble (CHR$ 130 +program_name$,-1,2) 2320 PROCcentre ("After the buggy has scanned these,",5) 2330 PROCcentre ("continue to lay the cards until",7) 2340 PROCcentre ("the end of the tune is reached.",9) 2350 PROCcentre ("(maximum " + STR$ size + " notes)",12) 2360 PROCcentre ("Place an octave card after the note",15) 2370 PROCcentre ("card if an octave is required.",17) 2380 PROCspace1 (23) 2390 ENDPROC 2400 : 2410 DEF PROClook_up1 2420 RESTORE 2430 LOCAL C% 2440 C% = 1 2450 flag = 0 2460 REPEAT 2470 READ note$,sharp,N,F,space,position 2480 IF N = number THEN flag = 1 2490 C% = C% + 1 2500 UNTIL C% = 26 OR flag 2510 IF flag = 0 THEN fault = 3 2520 flag = 0 2530 ENDPROC 2540 : 2550 DEF PROCmanual 2560 REM Flush buffers 2570 *FX 15,0 2580 PROCerase 2590 PROCcentre ("MANUAL DRIVE",26) 2600 PROCcentre ("Use arrow keys to drive Buggy",27) 2610 G$=FNwait 2620 PROCcentre ("Press SPACE to continue",27) 2630 REPEAT 2640 G$=FNwait 2650 *FX 4,1 2660 IF INKEY (uparrow) THEN PROCmove (forward,uparrow) 2670 IF INKEY (downarrow) THEN PROCmove (backward,downarrow) 2680 IF INKEY (leftarrow) THEN PROCmove (left,leftarrow) 2690 IF INKEY (rightarrow)THEN PROCmove (right,rightarrow) 2700 UNTIL GET$=" " 2710 PROCerase 2720 ENDPROC 2730 : 2740 DEF PROCmotors_off 2750 ?port = 8 2760 ENDPROC 2770 : 2780 DEF PROCmotors_on 2790 ?port = 0 2800 ENDPROC 2810 : 2820 DEF PROCmove (direction,key) 2830 pulse = (direction OR 2) 2840 REPEAT 2850 ?port = direction : PROCdelay(4) 2860 IF FNsensor = black THEN PRINT TAB(37,1) CHR$(240) ELSE PRINT TAB(37,1) CHR$(239) 2870 ?port = pulse : PROCdelay(2) 2880 UNTIL INKEY(key) = FALSE 2890 ?port = 0 2900 ENDPROC 2910 : 2920 DEF PROCnogo 2930 PROCcentre ("Buggy not connected, END OF PROGRAM.",21) 2940 PRINT 2950 ENDPROC 2960 : 2970 DEF PROCnotetype 2980 IF notetype<2 THEN N$="semiquaver" 2990 IF notetype=2 THEN N$=" quaver " 3000 IF notetype=3 THEN N$=" quaver* " 3010 IF notetype=4 THEN N$=" crotchet " 3020 IF notetype>4 AND notetype<7 THEN N$=" crotchet*" 3030 IF notetype>6 THEN N$=" minim " 3040 ENDPROC 3050 : 3060 DEF PROCoctave_check 3070 factor = ((scantime(1)+scantime(2))/strip) 3080 IF factor<5 AND factor>1.4 AND octave=0 THEN octave = 1 : card = card - 1 : number = number + 12 3090 ENDPROC 3100 : 3110 DEF PROCprint 3120 IF notetype>6 THEN A%=246:B%=247:C%=248:D%=249 ELSE A%=242:B%=243:C%=244 3130 IF position>1 AND position<7 THEN D%=245 : E%=241 ELSE D%=237 : E%=238 3140 IF notetype<>3 AND notetype<>5 AND notetype<>6 AND notetype<12 THEN D%=0 3150 IF position=1 THEN A%=250:IF notetype>6 THEN A%=251 3160 IF position<3 AND space=0 THEN C%=252:IF notetype>6 THEN C%=253 3170 IF sharp=1 THEN PRINT TAB(X%,Y%-position) CHR$(E%) :X%=X%+1 3180 IF space=1 THEN PRINT TAB(X%,Y%-position) CHR$(A%);CHR$(D%) ELSE PRINT TAB(X%,Y%-position) CHR$(B%);CHR$(D%);TAB(X%,((Y%+1)-position)) CHR$(C%) 3190 IF notetype<16 THEN PROCstalk(X%,Y%,position) 3200 ENDPROC 3210 : 3220 DEF PROCprocess1 3230 IF octave = 1 THEN octaveflag = 1 3240 octave = 0 3250 PROCoctave_check 3260 IF octave = 0 THEN PROCcalculate 3270 IF card = 0 AND octave = 1 THEN fault = 2 : ENDPROC 3280 IF octaveflag = 1 AND octave = 1 THEN fault = 3 : ENDPROC 3290 IF octave = 0 THEN octaveflag = 0 3300 PROClook_up1 3310 N(card) = number : T(card) = notetype 3320 PROCcard 3330 ENDPROC 3340 : 3350 DEF PROCreplay 3360 CLS 3370 PROCcentre (program_name$,1) 3380 PROCscore : card = 1 3390 X%=5: Y%=11 3400 PRINT TAB(8,30) "number= note length= ";TAB(2,1) "card" 3410 REPEAT 3420 number = N(card) : notetype = T(card) 3430 PRINT TAB(16,30) number;" " TAB(32,30) notetype;" " TAB(7,1) card 3440 PROClook_up1 3450 type = notetype*5.5-2.5 3460 SOUND 1,-volume,F,type 3470 PROCprint 3480 time = (60*type-(10*(number-1))) 3490 PROCdelay(time) 3500 X%=X%+notetype:IF X%>38 THEN X%=5 : Y%=Y%+8:IF Y%>34 THEN CLS:PROCscore:PRINT TAB(8,30);"number= notetype= ";TAB(2,1);"card":X%=5 :Y%=11 3510 card = card + 1 3520 UNTIL card = store 3530 ENDPROC 3540 : 3550 DEF FNsensor = ADVAL(2) DIV 33000 3560 : 3570 DEF PROCsetup 3580 *FX 4,1 3590 size = 90 3600 DIM N(size) , T(size) 3610 DIM scantime(2) 3620 program_name$ = "TIN PAN ALLEY" 3630 REM keyboard INKEY values 3640 uparrow = -58 : forward = 0 3650 downarrow = -42 : backward = 5 3660 leftarrow = -26 : left = 4 3670 rightarrow = -122: right = 1 3680 space = -99 : escape =-113 3690 nokey = -129 3700 REM other variables 3710 pulselength= 100 : volume = 15 3720 speedcontrol= 15 : adjustment = 9.6 3730 card = 1 : octave = 0 3740 end = 0 : fault = 0 3750 black = 1 : white = 0 3760 octaveflag = 0 : maxwidth = 100 3770 bumpers = 192 3780 @%=02 3790 answer$="" 3800 ENDPROC 3810 : 3820 DEF PROCscan 3830 fault = 0 3840 PROCsensor1 3850 IF fault =1 THEN ENDPROC 3860 PROCprocess1 3870 IF fault =2 OR fault =3 THEN ENDPROC 3880 PROClook_up1 3890 IF fault =4 THEN ENDPROC 3900 PROCdraw_card1 3910 X%=19:Y%=21 3920 PROCprint 3930 PROCnotetype 3940 PRINT TAB(14,22) N$ 3950 SOUND 1,-volume,F,10 3960 card = card + 1 : store = card 3970 ENDPROC 3980 : 3990 DEF PROCscore 4000 REM Draws three musical staves 4010 LOCAL I,J,S 4020 FOR I=834 TO 322 STEP -256 4030 FOR J=0 TO 4 4040 S = I-J*32 4050 PROCline (20,S,1260,S) 4060 NEXT J 4070 PROCclef (80,S+32,8) 4080 NEXT I 4090 PROCrectangle (6,6,1274,1018) 4100 ENDPROC 4110 : 4120 DEF PROCscreen2 4130 PROCcentre (program_name$,1) 4140 PRINT TAB(33,1) "bar ";CHR$ 239 4150 PROCstaves 4160 PRINT TAB(13,5) "CCDDEFFGGAABC" 4170 PRINT TAB(14,4) CHR$238 " " CHR$238 " " CHR$238 " " CHR$238 " " CHR$238 4180 PROCrectangle (6,6,1274,1018) 4190 PROCrectangle (380,639,864,892) 4200 PROCline (380,830,860,830) 4210 PROCline (6,930,1274,930) 4220 PROCline (6,80,1274,80) 4230 PROCline (6,240,1274,240) 4240 PRINT TAB(2,1) "card " 4250 ENDPROC 4260 : 4270 DEF PROCsensor1 4280 bars = 0 4290 REPEAT 4300 fault = 0 4310 bars = bars + 1 4320 PRINT TAB(37,1) CHR$239 4330 PROCbar_check (forward,1) 4340 IF fault THEN UNTIL fault : ENDPROC 4350 PRINT TAB(37,1) CHR$240 4360 IF bars = 1 THEN duration = pulsecount ELSE strip = pulsecount 4370 PROCbar_check (forward,0) 4380 IF fault THEN UNTIL fault : ENDPROC 4390 scantime(bars) = pulsecount 4400 PRINT TAB(37,1) CHR$239 4410 UNTIL bars=2 OR fault 4420 ENDPROC 4430 : 4440 DEF PROCstalk(X,Y,P) 4450 X = X*32+24 4460 Y = 1068-(Y-P)*32 4470 PROCline (X,Y-70+space*16,X,Y+space*16) 4480 IF notetype<4 THEN DRAW X+16,Y-20+space*16 4490 IF notetype=1 THEN MOVE X,Y-10+space*16:DRAW X+16,Y-30+space*16 4500 VDU 4 4510 ENDPROC 4520 : 4530 DEF PROCstaves 4540 FOR K%=15 TO 19 : PRINT TAB(17,K%) "_____" : NEXT 4550 PRINT TAB(17,20) " ";TAB(17,21) " ";TAB(17,13) " ";TAB(17,14) " " 4560 ENDPROC 4570 : 4580 DEF PROCtest 4590 LOCAL I% 4600 FOR I =1 TO 24 :N(I)=I :T(I)=2 :NEXT 4610 N(25) = 25 :T(25) = 4 4620 store=26 4630 ENDPROC 4640 : 4650 DEF PROCtunes 4660 IF card<>1 THEN PROCcentre(" *Sample tunes will over-write yours*",30) 4670 PROCchoice2 : answer$ = FNinput (1,"1234") 4680 IF answer$="1" THEN PROCtest : PROCreplay : PROCspace1 (28) 4690 IF answer$="2" THEN PROCweasel : PROCreplay : PROCspace1 (28) 4700 IF answer$="3" THEN PROCgreensleeves : PROCreplay : PROCspace1 (28) 4710 IF answer$ <> "4" THEN card = 1 4720 CLS 4730 answer$ = "" 4740 ENDPROC 4750 : 4760 DEF PROCweasel 4770 LOCAL I 4780 RESTORE 4890 :FOR I = 1 TO 25 : READ N(I),T(I) : NEXT 4790 store = 26 4800 ENDPROC 4810 : 4820 REM note information 4830 DATA C,0,1,53,0,1,C#,1,2,57,0,1,D,0,3,61,1,1,D#,1,4,65,1,1,E,0,5,69,0,2,F,0,6,73,1,2,F#,1,7,77,1,2,G,0,8,81,0,3,G#,1,9,85,0,3 4840 DATA A,0,10,89,1,3,A#,1,11,93,1,3,B,0,12,97,0,4,C,0,13,101,1,4 4850 DATA C#,1,14,105,1,4,D,0,15,109,0,5,D#,1,16,113,0,5,E,0,17,117,1,5,F,0,18,121,0,6,F#,1,19,125,0,6,G,0,20,129,1,6,G#,1,21,133,1,6 4860 DATA A,0,22,137,0,7,A#,1,23,141,0,7,B,0,24,145,1,7,C,0,25,149,0,8 4870 : 4880 REM Pop Goes the Weasel 4890 DATA 1,2,5,1,3,2,6,1,5,2,8,1,1,3 4900 DATA 1,2,5,1,3,2,6,1,5,3,1,3 4910 DATA 1,2,5,1,3,2,6,1,5,2,8,1,1,3 4920 DATA 10,3,3,2,6,1,5,3,1,3 4930 : 4940 REM Greensleeves 4950 DATA 12,2,15,4,17,2,19,3,21,1,19,2,17,4,14,2,10,3 4960 DATA 12,1,14,2,15,4,12,2,12,3,11,1,12,2,14,4,11,2,7,5 4970 : 4980 : 4990 REM Utilities 5000 DEF PROCcomplete 5010 CLS 5020 PROCdouble (CHR$ 131 +"Mission completed.",-1,10) 5030 ENDPROC 5040 : 5050 DEF PROCdouble (text$,X,Y) 5060 IF X<0 THEN X = FNcentre (text$) 5070 PRINT TAB(X-1,Y ) CHR$ 141; text$ 5080 PRINT TAB(X-1,Y+1) CHR$ 141; text$ 5090 ENDPROC 5100 : 5110 DEF FNinput (length,allowed$) 5120 LOCAL input$,ascii 5130 PRINT STRING$(length,".");STRING$(length,CHR$ 8); 5140 PROCon:*FX 15 5150 REPEAT ascii = ASC FNwait 5160 IF ascii=127 AND LEN(input$)>0 THEN input$ = LEFT$(input$,LEN(input$)-1):VDU ascii 5170 IF INSTR(allowed$,CHR$ ascii) AND LEN(input$)13 AND ascii<>127 THEN ascii = 7 5180 IF ascii = 13 AND LEN(input$)<1 THEN ascii = 7 5190 IF ascii = 127 THEN VDU 46,8 ELSE VDU ascii 5200 UNTIL ascii = 13 : PRINT : PROCoff 5210 =input$ 5220 : 5230 DEF PROCspace1 (line) 5240 LOCAL I$ 5250 PROCcentre ("Press SPACE to continue",line) 5260 *FX 15 5270 REPEAT I$=FNwait : UNTIL INKEY(space) 5280 REPEAT UNTIL INKEY(nokey) 5290 ENDPROC 5300 : 5310 DEF PROCend 5320 REM Switches motors off, resets cursor, EDIT & ESCAPE keys, buffers, and PRINT format 5330 PROCmotors_off 5340 PROCon 5350 *FX 4 5360 *FX 229 5370 *FX 15 5380 @% = 10 5390 ENDPROC 5400 : 5410 DEF PROCoff VDU 23;11,0;0;0;0 : ENDPROC 5420 DEF PROCon VDU 23;11,255;0;0;0 : ENDPROC 5430 : 5440 DEF PROCrectangle (X1,Y1,X2,Y2) 5450 MOVE X1,Y1 5460 DRAW X1,Y2 5470 DRAW X2,Y2 5480 DRAW X2,Y1 5490 DRAW X1,Y1 5500 ENDPROC 5510 : 5520 DEF PROCline (X1,Y1,X2,Y2) 5530 MOVE X1,Y1 5540 DRAW X2,Y2 5550 ENDPROC 5560 : 5570 DEF FNcentre (text$) = 19-LEN(text$) DIV 2 5580 : 5590 DEF PROCcentre (text$,line) 5600 PRINT TAB(1,line) SPC 38 5610 PRINT TAB(FNcentre(text$),line) text$ 5620 ENDPROC 5630 : 5640 DEF FNwait 5650 LOCAL I$ 5660 *FX 4,1 5670 REPEAT 5680 I$=INKEY$(10000) 5690 IF I$="" THEN PROCmotors_off ELSE PROCmotors_on 5700 UNTIL I$<>"" 5710 *FX 4 5720 =I$ 5730 :