yetanothertroll Posted February 27 Share Posted February 27 35 minutes ago, bent_pin said: ... 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. I have written binary trees, hash tables, min-heaps, tries, Quicksorts, etc., in various Basics, not so much in assembly. 😄 I mostly use X11 Basic for my own projects, which started off as a clone of GFA Basic for the Atari ST / Frost Basic for 8-bit, so mentioning it here hopefully isn't completely off topic. No line numbers, plus decent looping constructs and various other structured goodies to make you forget all about GOTO. In the binary tree code, I got the idea to rotate the currently accessed node up one level towards the root of the tree. It played havoc with attempts to keep the tree as a whole relatively balanced, but frequently accessed nodes were kept handy without constantly rearranging the entire thing Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 2 hours ago, yetanothertroll said: I have written binary trees, hash tables, min-heaps, tries, Quicksorts, etc., in various Basics, not so much in assembly. In assembly, the only thing that you have to add is a heap in memory, as far from the stack as possible, and when you've done it a few times, you can eliminate stack usage for everything but subroutines and achieve objectivity. Doing so on a 6502 with 64k is going to be a new and interesting challenge for me, but the mountain is there, therefore we must climb it. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 2 hours ago, yetanothertroll said: In the binary tree code, I got the idea to rotate the currently accessed node up one level towards the root of the tree. It played havoc with attempts to keep the tree as a whole relatively balanced, but frequently accessed nodes were kept handy without constantly rearranging the entire thing Try making a dequeue with an indexable pop. Enqueue the lines, in order. Then, push nodes when finished. Keeps most used in front in order of last used. I got the idea from how I kept my filing cabinet when I ran a construction company. Only works with a language with line numbers, and only if you collapse the line numbers and their references and you enqueue them. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 3 hours ago, yetanothertroll said: 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/ I did, discovered by a happy little accident. 3 hours ago, yetanothertroll said: Also, another really sketchy way to exit FOR loops: That's not too sketchy, you just gave it a ceiling. It's a fakakta while loop. And condition could be used as a rip cord. Not sure my dyspepsia would allow me to use it, but we'll see what we see. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 Really great stuff, everyone. Thank you Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted February 27 Share Posted February 27 Much easier way to exit GOSUB's and FOR loops using TRAP and POP Have a look at this 1 TRAP 199:REM CATCH REURN ERROR 10 X=20 20 X=X-1 30 IF X=5 THEN GOSUB 90 40 GOTO 20 90 PRINT "X=";X 100 X=X-1 110 IF X=0 THEN POP :RETURN 120 GOTO 100 199 TRAP 230:? "ERROR GOT US HERE" 200 FOR I=1 TO 10 205 ? I 210 IF I=5 THEN POP 220 NEXT I 230 ? "FINISHED, I=";I 240 TRAP 40000:REM TURN OFF TRAP 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted February 27 Share Posted February 27 I don't think you'd want POP then execute the NEXT, that would generate an error. An easier method can be to just set the loop counter to it's terminal value. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted February 27 Share Posted February 27 3 hours ago, Rybags said: I don't think you'd want POP then execute the NEXT, that would generate an error. That's why there's a TRAP, I posted this just as an example, I appreciate there are many solutions. Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 41 minutes ago, TGB1718 said: That's why there's a TRAP 2 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 27 Share Posted February 27 6 hours ago, bent_pin said: I did, discovered by a happy little accident. That's not too sketchy, you just gave it a ceiling. It's a fakakta while loop. And condition could be used as a rip cord. Not sure my dyspepsia would allow me to use it, but we'll see what we see. What ceiling lol Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 27 Author Share Posted February 27 @yetanothertroll Z>900 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 27 Share Posted February 27 (edited) 3 hours ago, bent_pin said: @yetanothertroll Z>900 Oh I see what you meant now. Maybe instead of 1e97 I should have used something actually reachable as a failsafe "ceiling," but then again, I guess the 1e97 makes it pretty obvious it's a FOR EVER AND EVER AND EVER UNTIL THE HEAT DEATH OF THE UNIVERSE loop If you're ever interested in an Atari emulator for Android to go along with the excellent Altirra emulator for Windows, check out Colleen. It hasn't been updated in forever, but it still works just fine for most purposes. Apparently legally downloadable copies of the OS and BASIC ROMs can be found here https://atari800.github.io/download.html Some carts, including Atari Logo, don't like being loaded from dumps on diskette, so track down ROMs in .CAR format if you can, or since you're using real hardware, dump yours to .CAR if you want to use them with Colleen. Edited February 27 by yetanothertroll Colleen and Logo quirks Quote Link to comment Share on other sites More sharing options...
thank you Posted February 28 Share Posted February 28 Hello I don't think anybody mentioned you can do like this: 90 GOTO 2*(GUESS<LOW)+4*(GUESS>HIGH)+6*(GUESS<SECRET AND GUESS>=LOW)+9*(GUESS>SECRET AND GUESS<=HIGH) I remember learning this idea from a joystick reading routine. 1 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 28 Share Posted February 28 1 hour ago, thank you said: Hello I don't think anybody mentioned you can do like this: 90 GOTO 2*(GUESS<LOW)+4*(GUESS>HIGH)+6*(GUESS<SECRET AND GUESS>=LOW)+9*(GUESS>SECRET AND GUESS<=HIGH) I remember learning this idea from a joystick reading routine. That's right, "Booleans" are just integers, not a distinct data type, either 0 or 1 in Atari BASIC. Other Basics usually set "True" to -1 That GOTO expression looks too scary and nasty to debug or modify for me. What happens if you renumber your lines? It looks like it should be at least converted to an ON GOTO, buuuuut there'd probably be a speed hit. Anyone know for sure? 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 28 Author Share Posted February 28 1 hour ago, yetanothertroll said: That's right, "Booleans" are just integers, not a distinct data type, either 0 or 1 in Atari BASIC. Other Basics usually set "True" to -1 That GOTO expression looks too scary and nasty to debug or modify for me. What happens if you renumber your lines? It looks like it should be at least converted to an ON GOTO, buuuuut there'd probably be a speed hit. Anyone know for sure? Any time you have compound statements on a single line in an interpreted language, they must be unrolled by order of operations, that's a series of stack operations and extra memory usage, then evaluated with more stack operations. The fastest processing in all conventional interpreted languages is to limit compound statements or avoid them if possible. It is possible that multiple line saves to a single variable can be a touch slower than a compound statement, but not usually. Even though I wouldn't use it as presented, I still value the comment's addition to the discussion as it makes me aware of the capability. 1 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted February 28 Share Posted February 28 7 hours ago, thank you said: I don't think anybody mentioned you can do like this: 90 GOTO 2*(GUESS<LOW)+4*(GUESS>HIGH)+6*(GUESS<SECRET AND GUESS>=LOW)+9*(GUESS>SECRET AND GUESS<=HIGH) Beware the "neat trick" 😇 1 Quote Link to comment Share on other sites More sharing options...
+bent_pin Posted February 28 Author Share Posted February 28 1 hour ago, TGB1718 said: Beware the "neat trick" 😇 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 28 Share Posted February 28 Where to next? A Matrix-like demo? https://github.com/neilk/apple-ii-matrix A Mandelbrot set generator? https://hackaday.com/2020/06/23/boot-to-basic-box-packs-a-killer-graphics-engine/ A Mandelbrot generator that draws in columns, top-down, mostly in green, Matrix style? Quote Link to comment Share on other sites More sharing options...
Houdini Posted February 28 Share Posted February 28 (edited) On 2/26/2024 at 11:53 PM, yetanothertroll said: 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 The problem with this one is the INPUT, PRINT method. It's not precise enough to do this job. One issue that jumps out right away also is there should be a semicolon after the PRINT #2 command or it will add a Carriage Return to the destination file. A better way would be to use GET, PUT so you get down to the byte level. To copy from disk to cas would be like this: (in BASIC this would be pretty slow) 1 REM Numerical variable 'A' does not need to be DIMed 10 OPEN #1,4,0,"D2:TEMP.LG" 20 OPEN #2,8,0,"C:" 30 TRAP 100: REM EOF Will cause error if not TRAPed 40 GET #1,A:REM Read a byte from the disk file 50 PUT #2,A:REM Write the byte to the cassette 60 GOTO 40:REM Repeat until error (which hopefully is generated by the EOF. Lol) 99 REM End Of File error takes us here 100 CLOSE#1:CLOSE #2:END: REM Close all IOCBs to flush buffers. End program. Edited February 28 by Houdini 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 29 Share Posted February 29 1 hour ago, Houdini said: The problem with this one is the INPUT, PRINT method. It's not precise enough to do this job. One issue that jumps out right away also is there should be a semicolon after the PRINT #2 command or it will add a Carriage Return to the destination file. A better way would be to use GET, PUT so you get down to the byte level. To copy from disk to cas would be like this: (in BASIC this would be pretty slow) ... The files I wanted to transfer were either BASIC LISTings or Logo saves, each of which are ATASCII formatted plain text, not tokenized or binary, so line input and print should have been fine. I actually asked about the issue in one of the Altirra threads, and according to @phaeron if I understand correctly, POKEY is used for SIO by both the cassette handler and DOS, and DOS will clobber the tape if invoked before the first record is written to the cassette. Quote Link to comment Share on other sites More sharing options...
phaeron Posted February 29 Share Posted February 29 1 hour ago, yetanothertroll said: The files I wanted to transfer were either BASIC LISTings or Logo saves, each of which are ATASCII formatted plain text, not tokenized or binary, so line input and print should have been fine. I actually asked about the issue in one of the Altirra threads, and according to @phaeron if I understand correctly, POKEY is used for SIO by both the cassette handler and DOS, and DOS will clobber the tape if invoked before the first record is written to the cassette. Yes, it's a known bug/limitation in the OS: GET/PUT wouldn't be any better, unless you buffer enough data to ensure that the first cassette record is written before DOS fetches another sector. 1 Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted February 29 Share Posted February 29 (edited) If they are BASIC listings, then you can Load them, and then Save them to Disk. Is there a problem with booting DOS, going to BASIC, Loading or Entering a tape, once it's loaded stopping the tape, then saving or listing to disk? How could it clobber the tape if it's not set to record or the tape mech isn't engaged? Edited February 29 by _The Doctor__ Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 29 Share Posted February 29 1 hour ago, _The Doctor__ said: If they are BASIC listings, then you can Load them, and then Save them to Disk. Is there a problem with booting DOS, going to BASIC, Loading or Entering a tape, once it's loaded stopping the tape, then saving or listing to disk? How could it clobber the tape if it's not set to record or the tape mech isn't engaged? Unfortunately, in this particular case it wasn't a BASIC listing but a Logo project that had grown a little too big. It appears it's possible to edit, run, and save a large project but then run out of memory when reloading it later, even after a cold reset. I was hoping to copy it to tape, reboot without DOS gobbling up that precious 4KB, and trim it down to where I could save it back to tape, reboot again with DOS loaded, and reload the project. Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 29 Share Posted February 29 (edited) Well, the initial test drawing in graphics mode 11 for the Mandelbrot set generator went well. It's actually kind of hypnotic to watch, but don't worry, lines 900-980 ought to jolt you out of it 😄 100 XMIN=-2:XMAX=0.5:YMAX=1.15 110 WW=80:WH=192:HH=INT(WH/2) 120 DIM X0(WW-1),X1(WW-1),Y1(HH) 130 FOR X=0 TO WW-1 140 X0(X)=X:REM SHUFFLE IT LATER 150 X1(X)=XMIN+(X*(XMAX-XMIN)/(WW-1)) 160 NEXT X 170 FOR Y=0 TO HH 180 Y1(Y)=YMAX-((Y/HH)*YMAX) 190 NEXT Y 200 GRAPHICS 11:REM GTIA 80*192*16 300 FOR X=WW-1 TO 0 STEP -1 310 R=X*RND(0) 320 T=X0(X):X0(X)=X0(R):X0(R)=T 330 T=X1(X):X1(X)=X1(R):X1(R)=T 380 X0=X0(X) 390 XSCALE=X1(X) 400 FOR Y=0 TO HH 480 Y0=Y:REM Y0 = Y0(Y) 490 YSCALE=Y1(Y) 700 COLOR (X+Y)-(16*INT((X+Y)/16)) 710 Y1=WH-1-Y0 720 PLOT X0,Y0 730 IF Y0<Y1 THEN DRAWTO X0,Y1 800 NEXT Y 810 NEXT X 900 FOR Y=0 TO 255 910 SOUND 0,Y,10,8 920 FOR X=1 TO 3 930 SOUND X,Y,2*INT(8*RND(0)),8 940 NEXT X 950 NEXT Y 980 FOR X=0 TO 3:SOUND X,0,0,0:NEXT X 990 REM GRAPHICS 0 999 END Mandel Graphics 11 test.BAS Edited February 29 by yetanothertroll Remove a failed attachment upload Quote Link to comment Share on other sites More sharing options...
thorfdbg Posted February 29 Share Posted February 29 On 2/27/2024 at 5:53 AM, 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, 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. Yes, also NEXT and RETURN only take line numbers + line offsets from the stack, and that's even true for Turbo-Basic. It just has a smarter search strategy. Basic++ is smarter and stores an address. 1 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.