Jump to content
IGNORED

Critique my first basic program on my 800XL


Recommended Posts

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.

 

IMG_20240225_225833~2.jpg

IMG_20240225_225850~2.jpg

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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 by TGB1718
  • Thanks 1
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

  • Thanks 1
Link to comment
Share on other sites

@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.

 

Link to comment
Share on other sites

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

  • Thanks 1
Link to comment
Share on other sites

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!   

  • Like 1
Link to comment
Share on other sites

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++.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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

 

  • Thanks 1
Link to comment
Share on other sites

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 

 

  • Thanks 1
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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”,

 

loopy.png.41b4f52211b573bb7ece08e41a470f35.png

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...