+bent_pin Posted February 26 Share Posted February 26 Sorry for the pictures of code but I'm running it pretty old school. I usually stick to assembly, but I thought, "Why not explore basic?" This is a standard exercise that I have my students write to explore features of a new language. Seemed only fitting to be the first. Works as expected. Where can I improve it? What do you think of it in general? Can I print a concatenation of a string and a variable? Thanks for looking. Side question, how do you delay a program for a specific period of time? 10 milliseconds resolution would be ideal. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 That's my best interpretation of a while loop as I didn't see one available in the language. Also my best solution for multiple line if..Thens Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 Feature update: Now it tracks the number of guesses and reports it at the end of the game. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 To break it down: Line 1 is my start vector Lines 2-11 are my jump table and functions combined Lines 19-31 are my initializers, run once Lines 40-120 are the main body while loop Lines 130-153 conclude the program Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 Changed it to show the optimum number of guesses and to only count guesses that are in range. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 Oops Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 26 Share Posted February 26 Atari Basic is kinda slow - if a FOR/NEXT loop is too slow for a required delay then there are alternatives. If a loop is near the start of the program it will run quicker, though there's also a delay if you GOSUB/RETURN to it. Sometimes a short delay could be had by running a dummy function, e.g. Z=SIN(9) Z=SQR(120) Z=TAN(9) Z=8*3 10 ms isn't a lot and equates to little over half an NTSC frame - so maybe a small maths operation might provide sufficient delay. 2 Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 26 Share Posted February 26 Additional - your program will generally run somewhat quicker if you stack multiple statements per line (though potentially harder to read) The speed variance thing will affect any branch. Branches occur when you have GOTO, GOSUB, NEXT, RETURN, ON/GOTO, and implied GOTO via IF/THEN. Destination line search starts at the start of the program, so the more it has to trawl through the slower it'll go. 2 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted February 26 Share Posted February 26 (edited) Best way to do a reasonably accurate delay in BASIC is to use the VB timer locations 18, 19, 20 that's (HIGH Byte, MEDUIM Byte and LOW Byte) Low is incremented every 1/60th of a second NTSC and 1/50th of a second for PAL. MEDIUM incremented when LOW reaches 255 and goes back to zero, same for HIGH byte when MEDIUM rolls through 255 to zero So for short delays something as simple as this will provide a delay, not 100% accurate, but good enough for BASIC. 10 TIMER=20 : REM VB TIMER LOW BYTE 20 POKE 20,0 : REM ZERO COUNTER 30 IF PEEK(TIMER)<60 THEN 30 : REM 1 SECOND DELAY (NTSC) Edited February 26 by TGB1718 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 2 hours ago, TGB1718 said: Best way to do a reasonably accurate delay in BASIC is to use the VB timer locations 18, 19, 20 that's (HIGH Byte, MEDUIM Byte and LOW Byte) Low is incremented every 1/60th of a second NTSC and 1/50th of a second for PAL. MEDIUM incremented when LOW reaches 255 and goes back to zero, same for HIGH byte when MEDIUM rolls through 255 to zero So for short delays something as simple as this will provide a delay, not 100% accurate, but good enough for BASIC. 10 TIMER=20 : REM VB TIMER LOW BYTE 20 POKE 20,0 : REM ZERO COUNTER 30 IF PEEK(TIMER)<60 THEN 30 : REM 1 SECOND DELAY (NTSC) That's awesome! Going to play with that tonight. Quote Link to comment Share on other sites More sharing options...
zzip Posted February 26 Share Posted February 26 using GOTO is considered to be bad form since it leads to "spaghetti code" In this case you could probably just print out the message instead of doing a GOTO to go to the line that prints the message or use GOSUBs Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 30 minutes ago, zzip said: using GOTO is considered to be bad form since it leads to "spaghetti code" In this case you could probably just print out the message instead of doing a GOTO to go to the line that prints the message or use GOSUBs Normally I agree but there is no form of open-ended iteration in basic. Even with GOSUBs I will still require an IF..THEN that uses at least one GOTO, unless I'm misunderstanding which has been know to happen. A while loop and IF..THENs with code blocks would solve the issues nicely. This form of basic unfortunately does not meet the standards required for proper structured programming. GOSUBs would slow the program down too, right? Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted February 26 Share Posted February 26 Just a few observations, in ATARI BASIC, you can substitute the PRINT with a ? it works the same also probably better to line number in 10's in case you need to insert some extra code, no renumber available Also if you put 10 ? CHR$(125) at the beginning of the program, it will clear the screen. If you print anything, putting a ';' at the end will prevent a carriage return, so the next characters printed will be on the same line. e.g. 210 ? : ? "Guess a number between ";LOW;" and ";HIGH;" "; 250 INPUT GUESS outputs on screen:- Guess a number between 1 and 50 ? No need for the '?' for the input as BASIC will put one there. 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 @TGB1718 Very useful, especially the printing info. I did start out with 10s for line numbers and had to add code. I did have to copy some lines to "renumber" them, and I figured out that a line number followed by a space deletes a line. I'm going to incorporate those and do a rewrite with wider numbered lines again. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted February 26 Share Posted February 26 You may have noticed I also did a ? : ? ""Guess a number between ";LOW;" and ";HIGH;" "; The extra ? inserts a blank line, just makes it more readable. Although it won't fix GOTO's, if I want to renumber a BASIC program, I use MAC/65 in text mode Just list the program to disk, so it's in text format, after renumber, just ENTER it back into BASIC 1 Quote Link to comment Share on other sites More sharing options...
zzip Posted February 26 Share Posted February 26 30 minutes ago, bent_pin said: Normally I agree but there is no form of open-ended iteration in basic. Even with GOSUBs I will still require an IF..THEN that uses at least one GOTO, unless I'm misunderstanding which has been know to happen. A while loop and IF..THENs with code blocks would solve the issues nicely. This form of basic unfortunately does not meet the standards required for proper structured programming. GOSUBs would slow the program down too, right? Yeah Atari BASIC doesn't make it easy for sure! 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 26 Author Share Posted February 26 15 minutes ago, zzip said: Yeah Atari BASIC doesn't make it easy for sure! I've always looked at basic as a dressed up and easier but less capable version of simple assembly. So I tend to stick to assembly rules. On the Arduino forum, I'm the first to throw stones over the use of goto in C++. Quote Link to comment Share on other sites More sharing options...
Gibstov Posted February 27 Share Posted February 27 One small thing. You don't have to use THEN GOTO...you can just use THEN. For instance: Instead of: 90 IF GUESS<LOW THEN GOTO 2 You could just: 90 IF GUESS<LOW THEN 2 1 Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted February 27 Share Posted February 27 then is only required for statements using specific labels/formula so it knows the following word in use is or isn't a command 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 1 hour ago, Gibstov said: 90 IF GUESS<LOW THEN 2 45 minutes ago, _The Doctor__ said: then is only required for statements using specific labels/formula so it knows the following word in use is or isn't a command So, is the final line by @Gibstov as simple as it gets for a conditional jump? Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted February 27 Share Posted February 27 pretty much 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 27 Share Posted February 27 12 hours ago, zzip said: using GOTO is considered to be bad form since it leads to "spaghetti code" In this case you could probably just print out the message instead of doing a GOTO to go to the line that prints the message or use GOSUBs Not much alternative, since the only built in looping construct is FOR/NEXT. Do you simulate a "forever" loop with FOR Z = 1 TO 1.0E+97 or what? Then how do you exit, use a GOTO or set up a TRAP and deliberately throw an error? Would you then need to use POP to clear the FOR/NEXT data off the stack or not? I dunno 1 hour ago, bent_pin said: So, is the final line by @Gibstov as simple as it gets for a conditional jump? You could get halfway to IF/ELSEIF/ELSE or C-ish switch using calculated ON GOTO or ON GOSUB, 10 ON X GOTO 40, 60, 80 [, ...] 20 . X isn't in {1 2 3} 40 . X is 1 60 . X is 2 80 . X is 3 etc etc etc 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 27 Share Posted February 27 23 hours ago, bent_pin said: To break it down: Line 1 is my start vector Lines 2-11 are my jump table and functions combined Lines 19-31 are my initializers, run once Lines 40-120 are the main body while loop Lines 130-153 conclude the program Interesting use of the first few lines, treating them almost like page zero. The original Atari Basic does search the entire program from the beginning each and every time for any and all jump targets, whether it's GOTO, GOSUB, IF/THEN 999, most likely for TRAP as well. Maybe even NEXT and RETURN? Later third-party Basics are smarter. Here are all the line-numbered BASIC programs I've written in the last, what, 40 years? Yup, all three The Fibonacci calculator I'm still fiddling with This one was an attempt to copy diskette files to cassette tape because some of my Logo programs were getting too big and that 4KB taken up by DOS was beginning to hurt. I abandoned it when copying from disk to tape only resulted in corrupted tapes. Maybe crazy buffering would do the trick? Hmm 10 DIM S$(16),D$(16),L$(4096) 100 OPEN #1,4,0,"D2:TEMP.LG" 110 OPEN #2,8,0,"C:" 120 REM OPEN #2 140 REM 150 INPUT #1,L$ 160 PRINT L$ 170 PRINT #2;L$ 180 GOTO 140 190 REM CLOSE 200 OPEN #1,4,0,"C:" 240 REM 250 INPUT #1,L$ 260 PRINT L$ 280 GOTO 240 290 REM CLOSE How I self-diagnosed my hearing loss 1 REM I say we take off and nuke 2 REM the entire site from orbit 3 REM It's the only way to be sure 5 D=14:REM 8 6 V=8 7 W=50:REM 50 9 DIM T$(12) 10 FOR I=255 TO 3 STEP -1 20 SOUND 0,I,D,V 30 SOUND 1,I-1,D,V 40 SOUND 2,I-2,D,V 50 SOUND 3,I-3,D,V 60 GOSUB 100 80 GOSUB 200 90 NEXT I 95 ? "TODO: Learn real graphics :-)" 99 END 100 REM GROUND CONTROL TO MAJOR TOM 110 IF (I<>255) AND (I<>240) AND (I<>225) AND (I<>210) THEN 150 115 GRAPHICS 0 120 FOR J=0 TO 18:PRINT :NEXT J 130 FOR J=0 TO 3 132 READ T$ 134 PRINT :? " "; 135 IF LEN(T$)>1 THEN PRINT T$(2); 137 PRINT " "; 139 NEXT J 140 READ T$ 150 IF (I>200) OR (INT(I/10)<>(I/10)) THEN 180 160 PRINT 180 REM FOO 190 RETURN 200 REM DELAY 210 FOR J=1 TO W:NEXT J 211 REM TODO: DO IT RIGHT 212 REM IS THERE A TIMER REGISTER? 290 RETURN 600 DATA X /---\ 610 DATA X<---------> 620 DATA X / | \ 630 DATA X / | \ 640 DATA Z 650 DATA X /---\ 660 DATA X<---------> 670 DATA X _/ | \_ 680 DATA X 690 DATA Z 700 DATA X /---\ 710 DATA X<---------> 720 DATA X -+ ' +- 730 DATA X 740 DATA Z 750 DATA X /---\ 760 DATA X<---------> 770 DATA X \_/ 780 DATA X 790 DATA Z 990 PRINT "DEAD CODE REACHED!" 999 STOP How to cram 30'000 digit Fibonacci numbers into 48KB. I prioritized ease of debugging over speed, so no PEEK/POKE or ON GOTO/GOSUB 10 REM PROGRAM BIGFIB 20 REM 30 REM ATARI/HP STRING WEIRDNESS: 40 REM DIM NEEDED TO RESERVE MEMORY 50 REM X$(I,J) IS MID$(X$,I,J-I+1) 60 REM X$(I[,J]) CAN BE ASSIGNED TO 70 REM X$(LEN(X$)+1) = Y$ APPENDS 80 REM X$(I)="" EITHER TRUNCATES X$ 90 REM OR FILLS X$ WITH GARBAGE(!) 100 DIM X$(15000),Y$(15000),ZD$(3) 110 X$=CHR$(0) 120 Y$=CHR$(1) 130 REM PRETEND Y$ WAS CALCULATED 140 Z=1 150 PRINT "HOW MANY FIBS"; 160 INPUT J 170 PRINT 0;" ";ASC(X$) 180 PRINT 1;" ";ASC(Y$) 190 REM 200 FOR I=2 TO J 210 REM SWITCH OUTPUT STRING 220 Z=1-Z 230 X1=LEN(X$):X0=ADR(X$) 240 Y1=LEN(Y$):Y0=ADR(Y$) 250 IF Z=0 THEN Z0=X0 260 IF Z=1 THEN Z0=Y0 270 IF X1<=Y1 THEN Z1=Y1 280 IF Y1<=X1 THEN Z1=X1 290 CARRY=0 300 FOR P=1 TO Z1 310 XD=0:YD=0:ZD=0 320 IF P<=X1 THEN XD=ASC(X$(P,P)) 330 IF P<=Y1 THEN YD=ASC(Y$(P,P)) 340 ZD=XD+YD+CARRY 350 CARRY=INT(ZD/100) 360 ZD=ZD-(CARRY*100) 370 IF Z=0 THEN X$(P,P)=CHR$(ZD) 380 IF Z=1 THEN Y$(P,P)=CHR$(ZD) 390 NEXT P 400 IF CARRY=0 THEN 490 410 Z1=Z1+1 420 IF Z=0 THEN X$(Z1)=CHR$(CARRY) 430 IF Z=1 THEN Y$(Z1)=CHR$(CARRY) 490 PRINT I;" "; 500 P=Z1 510 IF Z=0 THEN PRINT ASC(X$(P,P)); 520 IF Z=1 THEN PRINT ASC(Y$(P,P)); 530 IF P<2 THEN 590 540 P=P-1 550 IF Z=0 THEN ZD=ASC(X$(P,P)) 560 IF Z=1 THEN ZD=ASC(Y$(P,P)) 570 ZD$=STR$(900+ZD):PRINT ZD$(2,3); 580 GOTO 530 590 PRINT 890 NEXT I 999 END 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 47 minutes ago, yetanothertroll said: Not much alternative, since the only built in looping construct is FOR/NEXT. Do you simulate a "forever" loop with FOR Z = 1 TO 1.0E+97 or what? Then how do you exit, use a GOTO or set up a TRAP and deliberately throw an error? Would you then need to use POP to clear the FOR/NEXT data off the stack or not? I dunno You could get halfway to IF/ELSEIF/ELSE or C-ish switch using calculated ON GOTO or ON GOSUB, 10 ON X GOTO 40, 60, 80 [, ...] 20 . X isn't in {1 2 3} 40 . X is 1 60 . X is 2 80 . X is 3 etc etc etc Both comments full of useful stuff. Thank you. Looking forward to seeing what I can do with them. 19 minutes ago, yetanothertroll said: Interesting use of the first few lines, treating them almost like page zero. The original Atari Basic does search the entire program from the beginning each and every time for any and all jump targets That's what I figured. It's how I wrote my first AVR basic interpreter, before moving onto a binary trees, and eventually a recent-priority dequeue. I write my assembly code the same way. 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 27 Share Posted February 27 21 minutes ago, bent_pin said: Both comments full of useful stuff. Thank you. Looking forward to seeing what I can do with them. That's what I figured. It's how I wrote my first AVR basic interpreter, before moving onto a binary trees, and eventually a recent-priority dequeue. I write my assembly code the same way. Soitenly! Did you know you can edit program listings? Use the arrow keys to navigate up to the line, have your way with it, then while still at that line hit Enter/Return/I forget how it's labeled on real Atari hardware, and it's treated just as if you had retyped it from scratch! Also, another really sketchy way to exit FOR loops: “Dijkstra would not have liked this”, Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.