1 ' signon subsystem -- entry module 4 VERSION$="1.4 {10/14/82} " '1.01 was first release 7 ' by dick lieber 8 MODNAME$="SIGNON" 10 ' 11 'note: lines 5065 and 5070 were recent additions for use with ZCPR's 12 'drive/user restriction feature, and should be deleted or commented 13 'out if you don't use ZCPR. Line 5038 had it's RETURN commented out 14 'so that 5065 and 5070 would be executed. Jim Mills, August 1983. 15 ' 49 PWDFILE$="pwds" 50 COMMENTFILE$="COMMENTS" 52 CALLERFILE$="CALLERS" 55 USERFILE$="USERS" 56 LASTCALRFILE$="LASTCALR. "+CHR$(&HA0)+" " 57 MESSAGESUB$="CBBS" 58 EXITMODULE$="BYE" 59 SYSMGR$="POSYS" 84 DEF FNADDSEP$(DS$,DELIM$)= LEFT$(DS$,2)+DELIM$+MID$(DS$,3,2)+DELIM$+RIGHT$(DS$,2) 86 DEF FNKILLSEP$(DS$)=LEFT$(DS$,2)+MID$(DS$,4,2)+RIGHT$(DS$,2) 87 DEF FNLINES$(NLINES%)=STRING$(NLINES%,CRLF$) 88 DEF FNHOURS$(TIME)=STR$(INT(TIME/60))+":"+ RIGHT$("00"+MID$(STR$(TIME-(INT(TIME/60)*60)),2),2) 93 ' 94 ' constants 95 ' 96 CRLF$=CHR$(&HD)+CHR$(&HA) 97 BSTRING$=CHR$(8)+" "+CHR$(8) 98 DEFDRIVE$="A:": DRIVE$=DEFDRIVE$ 99 DIM ACLARRAY%(5,11) 100 DIM MARRAY%(50) 101 DIM FLAGS%(14) 112 ON ERROR GOTO 1000 115 GOTO 10000 118 ' 121 ' routines used by signon 200 %INCLUDE 200.SSB 300 ' 302 ' set user number 304 ' 306 USERMD=TESTADDRESS+9 312 CALL USERMD(SETUSERNUMBER%) 345 RETURN 400 %INCLUDE 400500.SSB 600 %INCLUDE 600.SSB 700 ' 710 ' get string into ANSWER$ then CRLF 720 ' 730 GOSUB 500: PRINT: RETURN 800 %INCLUDE 800.SSB 900 ' 905 ' log off an unwanted caller 910 ' 1.2 ## 913 PRINT 917 A$="Disconnecting - Goodbye":CR%=2:GOSUB 400 920 OUT MODEMPORT%,DISCONNECT% 925 POKE 0,&HC3 926 SETUSERNUMBER%=0: GOSUB 300 927 POKE 4,0 930 END 1000 ' 1004 ' Error handler 1008 ' 1012 A$=CRLF$+"Error Trap":CR%=2: GOSUB 400 1020 PRINT "ERR = ";ERR, "ERL = ";ERL 1024 IF ERR = 53 THEN NOFILE%=1: RESUME NEXT 1028 ON ERROR GOTO 0 1100 %INCLUDE 1100.SSB 1200 ' 1204 ' find name - get record 1208 ' 1.2 1211 SETUSERNUMBER%=USERNUMBER%: GOSUB 300 1212 NOTFOUND%=0 1216 REC%=2 1220 LAST$=SPACE$(14): FIRST$=RIGHT$(LAST$,10) 1224 LSET FIRST$=FRNAME$: LSET LAST$=LNAME$ 1228 GET #1,REC% 1232 IF EOF(1) THEN NOTFOUND%=1:RETURN 1236 IF FFNAME$=FIRST$ AND FLNAME$=LAST$ THEN GOSUB 1300: RETURN 1240 REC%=REC%+1 1244 GOTO 1228 1300 %INCLUDE 1300.SSB 1400 %INCLUDE 1400.SSB 1500 ' 1502 ' exit signon 1504 '1.10 1506 GETDAY%=1: GOSUB 1600 1508 A$= CRLF$+FNADDSEP$(TIME$,":")+" "+DAY$+" "+ FNADDSEP$(DATE$,"/"): CR%=2: GOSUB 400 1509 IF STATUSLINE%<>0 THEN GOSUB 3200 1510 GOSUB 4000 'put into CALLERFILE$ 1512 IF DENIED%<>0 THEN NOCTLK%=1:FIL$=NOACCESSFILE$:GOSUB 800: IF DENIEDCOMMENT%<>0 THEN ASKFORCOM%=0:GOSUB 2100 'changed 02/04/83 1513 PRINT "."; 1514 SETUSERNUMBER%=USERNUMBER%: GOSUB 300 1515 PRINT "."; 1516 GOSUB 200 'pack user rec 1517 PRINT "." 1518 IF DENIED%<>0 THEN CLOSE: GOTO 900 'hang up 1520 SETUSERNUMBER%=0: GOSUB 300 1522 FCBNAME$=LASTCALRFILE$ 1524 RO%=0: GOSUB 2300 1526 OPEN "O",#1, LASTCALRFILE$ 1528 PRINT #1, FRNAME$;","; LNAME$;","; ACLVL%;","; DATE$;",";TIME$;","FLAGS% 1530 CLOSE #1 1532 RO%=1: GOSUB 2300 1534 IF SYSOP%=0 THEN NOCTLK%=1:FIL$=SUCESSFILE$:GOSUB 800 1536 IF SKIPFILES%=0 AND OPTIONFILE$<>"NONE" AND ACLVL%=< PWDACL% THEN A$=CRLF$+ OPTIONMESS$+" > ": CR%=0: GOSUB 400: MAX%=0: GOSUB 700: IF LEFT$(ANSWER$,1)= "Y" THEN FIL$=OPTIONFILE$: GOSUB 800 1538 GOSUB 4900 'check bbs 1542 IF RAMPOKE%<>0 THEN POKE RAMPOKEADDRESS%,ACLVL% 1546 IF BYEPOKE%<>0 THEN GOSUB 5000 1548 IF WHEELOPTION% <> 0 THEN GOSUB 5200 1549 IF ACLVL% =< PWDACL% THEN GOSUB 2000 ELSE GOSUB 4700 'stats or menu 1550 IF SYSOP%=0 THEN NOCTLK%=1: FIL$=INSTRFILE$: GOSUB 800 1551 SETUSERNUMBER%=0: GOSUB 300 1552 POKE 4,0 1556 END 1600 %INCLUDE 1600.SSB 1700 ' 1705 ' set default values to working individual variables 1710 ' 1.2 # 1713 ERRCNT%=0: ACLVL%=0: SIGCNT=0 1725 NEWCOMER%=0: SYSOP%=0: PWD$=STRING$(13,42) 1740 LOCATION$="": LTIME$="": LDATE$="" 1755 ELAPTIME%=0: TOTALTIME=0: NOTATION$="normal" 1766 QUALIFIED%=0 1770 RETURN 1800 ' 1804 ' choose a password 1808 '1.1 1811 OLDPWD$=PWD$ 1812 PRINT 1816 A$=CRLF$+"Choose a password. It may be any":CR%=2:GOSUB 400 1820 A$="combination of characters, except RETURN and may":GOSUB 400 1824 A$="be up to 13 characters in length.":GOSUB 400 1825 A$="A few Xs will be echoed for each character typed.": GOSUB 400 1828 A$="Press RETURN after typing your password.":GOSUB 400 1832 PRINT 1836 A$=" > ":CR%=1:GOSUB 400 1840 MAX%=13 1844 GOSUB 600 1845 IF NKEY%=0 THEN PWD$=OLDPWD$: RETURN 1848 PWD$=ANSWER$ 1852 PRINT 1856 IF PWD$=STRING$(13,42) THEN A$="Sorry that password isn't allowed.": CR%=2:GOSUB 400: GOTO 1812 1860 A$="To make sure, type it again.":CR%=2:GOSUB 400 1864 A$=" > ":CR%=1:GOSUB 400 1868 GOSUB 600 1872 PRINT 1876 IF PWD$<>ANSWER$ THEN A$="They don't match.": GOSUB 400: GOTO 1812 1880 PRINT 1884 A$=" ok":CR%=2:GOSUB 400 1886 CHANGED%=1 1888 RETURN 2000 ' 2005 ' show users some stats 2010 ' 1.4 2015 IF NEWCOMER%<>0 THEN RETURN 2025 A$=CRLF$+"These records were last used on "+ FNADDSEP$(LASTDATE$,"/")+",": CR%=2 :GOSUB 400 2030 A$="at "+FNADDSEP$(LASTTIME$,":")+"." : GOSUB 400 2035 A$="You've signed on"+ STR$(SIGCNT)+" times.": GOSUB 400 2037 IF MPOINT%<>0 THEN A$="You have messages! Type MINIRBBS.": CR%=2: GOSUB 400 2040 RETURN 2100 %INCLUDE 2100.SSB 2200 ' 2204 ' get a password into epwd$ 2208 ' 1.1 2210 IF STACKED%<>0 THEN STACKED%=0: A$=CRLF$+"Can't stack password!": GOSUB 400 2212 A$=CRLF$+"Type your password > ":CR%=1: GOSUB 400 2216 MAX%=13: GOSUB 600 2220 EPWD$=STRING$(13,32): LSET EPWD$=ANSWER$ 2224 RETURN 2300 %INCLUDE 2300.SSB 2600 ' 2602 ' optional user qualification 2604 ' 1.0 2605 NTRIES%=0: STACKED%=0 2606 A$=CRLF$+QUALQUESTION$+"? > ": CR%=0: GOSUB 400 2608 MAX%=20: GOSUB 500 2610 IF ANSWER$=QUALANSWER1$ OR ANSWER$=QUALANSWER2$ GOTO 2670 2615 NTRIES%=NTRIES%+1 2620 IF NTRIES% => MAXPW% THEN DENIED%=1:DENIEDCOMMENT%=1: NOTATION$="bad qual": ACLVL%=-1: RETURN 2625 GOTO 2606 2670 A$=CRLF$+"Sorry, that test is needed to keep down the nurds!": CR%=2:GOSUB 400 2674 QUALIFIED%=1 2680 RETURN 3000 %INCLUDE 3000.SSB 3100 %INCLUDE 3100.SSB 3200 ' 3210 ' write callers name and time to local terminal status line 3215 ' 1.1 3217 A$=LEFT$(STATINIT$,LEN(STATINIT$)-1): GOSUB 3100 3220 A$=LEFT$(LNAME$+", "+FRNAME$+" "+FNADDSEP$(TIME$,":"),STATLEN%) 3225 GOSUB 3100 3227 A$=LEFT$(STATEND$, LEN(STATEND$)-1): GOSUB 3100 3230 RETURN 3300 ' 3305 ' selector 3310 ' 3315 MAX%=0:GOSUB 500 3320 IF ANSWER$="" THEN SELECTION%=0: RETURN 3322 IF ANSWER$ < "A" OR ANSWER$ > "Z" THEN SELECTION%=27: RETURN 3325 SELECTION%=ASC(ANSWER$)-64 3330 RETURN 3600 ' 3605 ' display working record 3610 ' 1.3 (different from 3600 in POSYS) 3615 CR%=2 3620 A$=FNLINES$(2):GOSUB 400 3625 A$=" First Name: "+FRNAME$: GOSUB 400 3630 A$=" Last Name: "+LNAME$: GOSUB 400 3635 A$=" Access Level: "+STR$(ACLVL%): GOSUB 400 3640 A$=" Location: "+LOCATION$: GOSUB 400 3645 A$=" Last Date On: "+FNADDSEP$(LASTDATE$,"/"): GOSUB 400 3648 A$=" Last Time On: "+FNADDSEP$(LASTTIME$,":")+" for"+ FNHOURS$(ELAPTIME%)+" hr:mn.": GOSUB 400 3652 A$=" Usage: "+STR$(SIGCNT)+" signons in"+FNHOURS$(TOTALTIME)+ " hr:mn" 3653 IF OLDUSER%<>0 THEN A$=A$+" (since SIGNON in use)" 3655 GOSUB 400 3662 A$=FNLINES$(3)+ "If any of this information is incorrect"+ CRLF$+"leave a comment with the corrections." 3664 GOSUB 400 3666 MAX%=0: GOSUB 500 3669 RETURN 4000 ' 4004 ' put user into callers file 4008 '1.1 4010 SETUSERNUMBER%=USERNUMBER%: GOSUB 300 4012 OPEN "R",2,DRIVE$+CALLERFILE$,75 4016 FIELD #2, 8 AS CLOGCNT$, 6 AS CLLDATE$, 6 AS CLLTIME$, 1 AS SIGNATURE$, 8 AS CLREC$ 4020 GET #2,1 4024 LOGCNT#= VAL(CLOGCNT$) 4028 NEXTRECORD=VAL(CLREC$) 4032 IF SIGNATURE$ <> "*" THEN LOGCNT#=1: NEXTRECORD=1: LSET SIGNATURE$="*": LSET CLLDATE$=DATE$: LSET CLLTIME$=TIME$ 4036 LLDATE$= CLLDATE$ 4040 LLTIME$= CLLTIME$ 4048 LSET CLOGCNT$= STR$(LOGCNT#+1) 4060 LSET CLREC$=STR$(NEXTRECORD+1) 4064 PUT #2,1 4072 FIELD #2, 20 AS CFNAME$, 20 AS CLNAME$, 6 AS CDATE$, 6 AS CTIME$, 6 AS CTIMEON$, 10 AS CNOTATION$, 2 AS CCRLF$ 4076 LSET CFNAME$=FRNAME$ 4080 LSET CLNAME$=LNAME$ 4084 LSET CDATE$=DATE$ 4088 LSET CTIME$=TIME$ 4090 LSET CTIMEON$=STRING$(6,"x") 4092 LSET CNOTATION$=NOTATION$ 4096 PUT #2,NEXTRECORD+1 4100 CLOSE #2 4108 PRINT FNLINES$(1); "You are caller";LOGCNT# 4112 RETURN 4200 ' 4204 ' see if caller is a user 4208 '1.3 4212 PRINT 4216 A$="Checking users file...":CR%=1:GOSUB 400 4224 GOSUB 1200 4225 IF ACLVL%=-1 THEN NOTATION$="twit": DENIED%=1:DENIEDCOMMENT%=1 '02/04/83 4226 IF DELETED%=1 THEN ACLVL%=-1: NOTATION$="deleted": DENIED%=1 4228 RETURN 4300 ' 4304 ' not a user 4308 ' 1.3 4310 DATAOK%=0 4316 NOTATION$="A new user" 4318 IF MUSTQUALIFY%<>0 THEN GOSUB 2600 4319 IF DENIED%<>0 THEN RETURN 4320 GOSUB 4360 4322 IF ONLYLOC%<>0 THEN ONLYLOC%=0: RETURN 4325 IF DATAOK%=0 THEN RETURN 4333 PRINT 4336 A$="This is only asked the first time you signon.":CR%=2:GOSUB 400 4340 NEWCOMER%=1 4343 NOCTLK%=1 4344 FIL$="NEWCOM": GOSUB 800 4350 IF DATAOK%<>0 THEN REC%=NEXTUSER: ADDREC%=1 4352 RETURN 4360 A$=CRLF$+"Where are you calling from (City, State) > ": CR%=0: GOSUB 400: MAX%=15: GOSUB 700 4363 LOCATION$=ANSWER$ 4366 A$=CRLF$+FRNAME$+" "+LNAME$+" from "+LOCATION$: CR%=2: GOSUB 400 4369 A$="Is all the information ok? > ": CR%=1: GOSUB 400: MAX%=0: GOSUB 700 4372 IF LEFT$(ANSWER$,1)<>"N" THEN DATAOK%=1 4375 RETURN 4400 ' 4405 ' signon password request 4410 ' 4415 ERRCNT%=0 4420 WHILE ERRCNT% < MAXPW% 4425 PRINT 4430 GOSUB 2200 4435 IF EPWD$=PWD$ THEN A$=" ok":CR=2:GOSUB 400: RETURN 4437 PRINT 4440 A$="Passwords don't match - try again":CR%=2:GOSUB 400 4445 ERRCNT%=ERRCNT%+1 4450 WEND 4455 PRINT "Sorry, you only get";MAXPW%;"trys." 4460 DENIED%=1 4462 NOTATION$="bad pwd" 4463 RETURN 4500 ' 4504 ' put sysop info into individual 4508 ' 4512 FRNAME$="SYSOP" 4516 LNAME$="" 4520 ACLVL%=SYSOPSLVL% 4524 RETURN 4700 ' 4702 ' Signon menu 4704 ' 1.7 4706 A$=CRLF$: CR%=2: GOSUB 400 4708 IF EXPERT% <> 0 AND MENUREQ%=0 THEN GOTO 4740 4710 MENUREQ%=0 4712 A$="Signon Options:": GOSUB 400 4714 A$=" a Alter your password.": GOSUB 400 4716 A$=" b View your signon statistics": GOSUB 400 4718 A$=" c Go to to cp/m.":GOSUB 400 4720 A$=" d Deposit a comment.":GOSUB 400 4722 A$=" e "+OPTIONMESS$+".": GOSUB 400 4724 A$=" f Go to message subsystem" 4726 IF MPOINT%<>0 THEN A$=A$+" <== messages waiting" 4728 GOSUB 400 4730 IF MODEMCTLOPT% <> 0 THEN A$=" g Change baud rate.": GOSUB 400 4732 IF ACLVL% > SPECIALEVEL% THEN A$=" h View Special users message.": GOSUB 400 4734 A$=" ":GOSUB 400 4735 IF SYSOP%<>0 THEN A$=" s SIGNON Subsystem Manager.": GOSUB 400 4736 A$=" q Sign off of the system.":GOSUB 400 4738 A$=" x Toggle expert mode.":GOSUB 400 4740 CR%=0 4742 A$="Press letter of your choice " 4744 IF EXPERT%<>0 THEN A$=A$+CRLF$+"M to see the menu" 4746 IF EXPERT%<>0 AND MPOINT%<>0 THEN A$=A$+CRLF$+" type f for Messages" 4748 A$=A$+" > ": GOSUB 400 4750 GOSUB 3300 4752 A$=CRLF$: GOSUB 400 4754 IF SELECTION%=3 OR SELECTION%=0 THEN A$=CRLF$: GOSUB 400: RETURN 4756 IF SELECTION%=8 AND ACLVL% <= SPECIALEVEL% THEN GOTO 4700 4757 IF MODEMCTLOPT%=0 AND SELECTION%=7 THEN 4700 4758 IF SELECTION%=13 THEN GOSUB 4786 4760 IF SELECTION%=17 THEN GOSUB 4778 4761 IF SELECTION%=19 AND SYSOP%<>0 THEN SETUSERNUMBER%=0:GOSUB 300:RUN MGRDRIVE$+SYSMGR$ 4762 IF SELECTION%=24 THEN GOSUB 4782 4764 ASKFORCOMMENT%=0 4766 ON SELECTION% GOSUB 1800,3600,4700,2100,4772,4776,3000,4774 4768 IF CHANGED%<>0 THEN GOSUB 1400: GOSUB 200: CHANGED%=0 4770 GOTO 4700 4772 FIL$=OPTIONFILE$: GOSUB 800: RETURN 4774 FIL$=SPECIALFILE$: GOSUB 800: RETURN 4776 SETUSERNUMBER%=0: GOSUB 300: RUN DEFDRIVE$+MESSAGESUB$: CLOSE: A$=CRLF$+"Cannot get message subsystem":GOSUB 400: RETURN 4778 SETUSERNUMBER%=0:GOSUB 300: RUN DEFDRIVE$+EXITMODULE$ 4780 CLOSE:A$= "Cannot get "+EXITMODULE$: GOSUB 400: RETURN 4782 IF EXPERT%=0 THEN EXPERT%=1 ELSE EXPERT%=0 4784 CHANGED%=1: RETURN 4786 MENUREQ%=1: RETURN 4800 ' 4805 ' no entry allowed 4810 ' 4820 NOTATION$="Denied" 4825 DENIED%=1 4830 ACLVL%=-1 4832 DATAOK%=0 4835 RETURN 4900 %INCLUDE 4900.SSB 5000 ' 5005 ' poke options into bye 5010 ' 1.3 5015 ADDRESS=PEEK(2)*256+PEEK(1)-2 5020 ADDRESS=PEEK(ADDRESS+1)*256+PEEK(ADDRESS)+6 5025 WORD$=CHR$(PEEK(ADDRESS+8))+CHR$(PEEK(ADDRESS+9))+CHR$(PEEK(ADDRESS+10)) 5038 IF WORD$<> "BYE" THEN A$=CRLF$+"BYE not found": GOSUB 400: 'RETURN 5040 FOR INDEX%=0 TO BYEPARAMS%-1 5050 POKE ADDRESS+INDEX%, ACLARRAY%(INDEX%,ACLVL%) 5060 NEXT INDEX% 5065 INDEX%=PEEK(ADDRESS)+1:POKE &H3F,INDEX% 'MAX USER 5070 INDEX%=PEEK(ADDRESS+1)-1:POKE &H3D,INDEX% 'MAX DRIVE 5090 RETURN 5200 ' 5205 ' process NZCPR WHEEL mode interlock 5210 '1.0 # 5215 ON ACLARRAY%(5,ACLVL%)+1 GOTO 5230, 5240 5220 RETURN 5230 POKE WHEEL%, UNRESTRICT% 'no user 15 dfu 5235 RETURN 5240 POKE WHEEL%, RESTRICT% ' allow user 15 dfu 5245 RETURN 8000 %INCLUDE 8000.SSB 10000 ' 10010 ' main program starts here 10020 '1.3 # 10030 GOSUB 1100 10040 A$="Signon "+VERSION$: CR%=2: GOSUB 400 10050 A$=SIGNONMESS$: CR%=2: GOSUB 400 10060 NOCTLK%=0: FIL$=BULLFILE$: GOSUB 800 10065 IF RAMPOKE%<>0 THEN POKE RAMPOKEADDRESS%,&HFF 10067 IF WHEELOPTION%<>0 THEN POKE WHEEL%,UNRESTRICT% 10070 GOSUB 1400 10080 GOSUB 1700 10090 PRINT 10100 CR%=1: MAX%=20 10110 PRINT 10120 A$="What is your first name > ":GOSUB 400: GOSUB 700:FRNAME$=ANSWER$ 10130 A$=" And your last name > ":GOSUB 400: GOSUB 700:LNAME$=ANSWER$ 10140 IF FRNAME$="" OR LNAME$="" THEN GOTO 10110 10141 I%=1 'added 02/04/83 10142 IF MID$(FRNAME$,I%,1)=" " THEN 10110 'added 02/04/83 10143 I%=I%+1:IF I% <= LEN(FRNAME$) THEN 10142 'added 02/04/83 10144 I%=1 'added 02/04/83 10145 IF MID$(LNAME$,I%,1)=" " THEN 10110 'added 02/04/83 10146 I%=I%+1:IF I% <= LEN(LNAME$) THEN 10145 'added 02/04/83 10150 PRINT 10160 IF FRNAME$ = "SYSOP" OR LNAME$="SYSOP" THEN PRINT "You know you're not the SYSOP!": GOTO 10100 10170 IF FRNAME$=PWD1$ AND LNAME$=PWD2$ THEN STACKED%=0: A$=" Enter password > ": CR%=1: GOSUB 400: GOSUB 600: ELSE GOTO 10200 10180 IF ANSWER$=PWD3$ THEN SYSOP%=1 ELSE ERRCNT%=ERRCNT%+1: IF ERRCNT% => MAXPW% THEN DENIED%=1: NOTATION$="try SYSOP": GOTO 10310 ELSE GOTO 10090 10190 IF SYSOP%<>0 THEN GOSUB 4500 10200 GOSUB 4200 10205 IF DENIED%<>0 THEN GOTO 10400 10210 IF SYSOP%<>0 THEN GOSUB 4500 10220 IF SYSOP%=0 AND NOTFOUND%=1 AND ALLOWNEW%=0 THEN GOSUB 4800 'denied test 10230 IF SYSOP%=0 AND NOTFOUND%=1 THEN GOSUB 4300: IF DATAOK%<>1 AND DENIED%=0 THEN NEEDLOC%=0: GOTO 10080 10235 IF DENIED% THEN GOTO 1500 10240 SIGCNT=SIGCNT+1 10270 IF SYSOP%<>0 THEN GOTO 10400 10280 IF ACLVL%=< PWDACL% THEN IF QUALNONPWD% <> 0 AND QUALIFIED% = 0 THEN GOSUB 2600: GOTO 10400 ELSE GOTO 10400 10290 IF PWD$= STRING$(13,42) THEN GOSUB 1800:GOTO 10400 10300 GOSUB 4400 'request password 10310 IF NEEDLOC%<>0 THEN ONLYLOC%=1: MUSTQUALIFY%=0: GOSUB 4300: IF DATAOK%=0 THEN GOTO 10310 ELSE NEEDLOC%=0 10400 GOTO 1500 20000 '