yetanothertroll Posted November 4, 2023 Share Posted November 4, 2023 (edited) Hey all, what's the best way to post code here for everyone to easily import it into your emulator or Fujinet or whatever? Keep on posting it as text in the Code widget, attach it as a CR/LF formatted text file, an Atari formatted file straight from the .ATR, what? Some of my little projects are getting to be over 4KB, like the bouncing turtles and an incremental Sieve of Eratosthenes using a min heap of the next multiple of the primes. In Altirra 4.10 it can find the primes up to about 1600 in under an hour and a half before running out of nodes. (That 4KB RAM soaked up by DOS is beginning to hurt!) I'm sure the code would be cumbersome to copy if pasted into a post. EDIT: Launching LOGO with no DOS and that extra 4K of free RAM makes a huge difference. The sieve now finds the primes under 1600 in about 2600 seconds and up to 2333 in 4500 seconds, with Altirra in Warp Speed and using the system jiffies counter to time it. That node churn is a killer! I guess it's back to LOAD "C: for me 🙃 Edited November 5, 2023 by yetanothertroll 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted November 19, 2023 Share Posted November 19, 2023 Another rainy weekend, time to launch LOGO it seems MAKE is every bit as dangerous as I thought, but it can also make code like QSORT back on page 3 much easier to read, especially on a 40 character wide display. But first, madness: FOREVER is cribbed from pg. 261 of the Apple Logo II Reference Manual. Similar shenanigans can be done with MAP, WHILE, or most anywhere else you see a call to RUN Maybe code like QSORT is clearer if done with mutable local variables, maybe not. Opinions? TO QSORT :LIST IF EMPTYP :LIST [OUTPUT :LIST] OP QSORT.1 FIRST :LIST "NIL "NIL BUTFIRST :LIST [] [] END TO QSORT.1 :PIVOT :FIRST :ISLESS :RESTOFLIST :TOLEFT :TORIGHT IF EMPTYP :RESTOFLIST [OUTPUT SE ( QSORT :TOLEFT ) FPUT :PIVOT ( QSORT :TORIGHT )] MAKE "FIRST FIRST :RESTOFLIST MAKE "ISLESS :FIRST < :PIVOT MAKE "RESTOFLIST BUTFIRST :RESTOFLIST IF :ISLESS [MAKE "TOLEFT FPUT :FIRST :TOLEFT] IF NOT :ISLESS [MAKE "TORIGHT FPUT :FIRST :TORIGHT] OP QSORT.1 :PIVOT "NIL "NIL :RESTOFLIST :TOLEFT :TORIGHT END TO RANDUMB :N :MAX IF :N < 1 [OUTPUT []] OP FPUT RANDOM :MAX RANDUMB :N - 1 :MAX END Here's an example run using a random list generated with RANDUMB 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted January 2 Share Posted January 2 (edited) On 10/28/2023 at 12:08 PM, ascrnet said: Hi @yetanothertroll I recommend a good logo book rather than making geometric figures, this one contains several games. 😉 greetings I do have a couple of projects kicking around that could be turned into a game or two if I didn't keep running out of nodes. BOUNCE.LG (launched by BOUNCE) has the turtles bouncing off the walls and each other. Except when an automatic garbage collection happens at the wrong time. GRAVITY.LG (launched by DRIVER) is halfway to the 60s SPACEWAR / 70s Computer Space game. I can't get much further with either one without falling back to using the cassette instead of disk, and I'm running into situations in which a project can be edited, run, and saved but is then too big to reload, even after a cold reset. .CAS files are easy enough to attach to posts here, but what about folks using real hardware instead of Altirra or maybe a800? I think I can come up with a Logo program that does its own buffering to copy files from disk to cassette without corrupting the tape, maybe even very large files. If weekends here get very rainy and I get very ambitious, maybe even something that can catenate a list of disk or cassette files to a single file? It might be possible to catenate multiple tape files to a single disk file but probably not tape to tape. Unless. Hmm. A multiple pass project sorter that could handle ridiculously large projects that 8-bit Logo couldn't possibly actually load and run? There's no engineering like absurd overengineering! 😄 GRAVITY.LG BOUNCE.LG Edited January 2 by yetanothertroll There's always room for one more quip Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted January 26 Share Posted January 26 I guess I just can't get enough of those geometric figures. This time it's a fractal that maybe Logo isn't so well suited for, the Mandelbrot Set! I adapted it from a screenshot of BASIC code found here: https://hackaday.com/2020/06/23/boot-to-basic-box-packs-a-killer-graphics-engine/ The turtles did come in handy for sidestepping having to convert between the languages' differing coordinate systems. I just sort of used them like carriages on old school typewriters. Maybe I should add some typewriter sound effects when I advance them one y coordinate and back them up to the left 😄 Let's see if a deeplink to the screenshot of the BASIC code I stole ripped off plagiarized 'adapted' will load: https://hackaday.com/wp-content/uploads/2020/06/cmax800d.png I guess not? Anyway, here's a frame grab from Altirra running the Logo code and the code. The lines on the far left and right are to make sure the turtles aren't drifting due to an off-by-one error in the program or maybe some sort of cumulative error in XCOR like what happens in the fractal trees. And be patient. Each pixel can take up to around eight seconds or so to calculate even after my attempts to optimize it in MANDEL.ITER and MANDEL.ITER.1. TO MANDEL CS MANDEL.1 77 158 * 2 1 + ( 119 * 2 ) END TO MANDEL.1 :MAXX :W :H MANDEL.2 1 + ( :H / 2 ) END TO MANDEL.2 :HH TELL [0 1] PU ASK 1 [RT 180] FORWARD :HH + 1 ASK 0 [RIGHT 90] ASK 1 [LEFT 90] FORWARD :W / 2 MANDEL.PY 0 END TO MANDEL.PY :PY IF :HH < :PY [STOP] PD SETPN 2 FORWARD 1 BACK 1 PU BACK :W ASK 0 [RIGHT 90] ASK 1 [LEFT 90] FORWARD 1 ASK 0 [LEFT 90] ASK 1 [RIGHT 90] PD SETPN 1 BACK 1 FORWARD 1 MANDEL.PY.1 1.042 * ( ( ( :PY / :H ) * 2 ) - 1 END TO MANDEL.PY.1 :SCALEY ( PR :PY :SCALEY MANDEL.PX 0 MANDEL.PY :PY + 1 END TO MANDEL.PX :PX IF NOT ( :PX < :W ) [STOP] MANDEL.PX.1 ( ( :PX / :W ) * 2.5 ) - 2 END TO MANDEL.PX.1 :SCALEX MANDEL.PLOT MANDEL.ITER 0 0 0 MANDEL.PX :PX + 1 END TO MANDEL.PLOT :I ( PR :PY :PX :SCALEY :SCALEX :I SETPN IF :I < 15 [2] [IF :I < :MAXX [0] [1]] IF :I < 10 [PU] [PD] FORWARD 1 END TO BETWEEN :I :MIN :MAX IF :I < :MIN [OUTPUT FALSE] IF :I > :MAX [OUTPUT FALSE] OUTPUT TRUE END TO MANDEL.ITER :I :X :Y IF :I = :MAXX [OUTPUT :I] OP MANDEL.ITER.1 :X * :X :Y * :Y END TO MANDEL.ITER.1 :X2 :Y2 IF 4 < :X2 + :Y2 [OUTPUT :I] OP MANDEL.ITER :I + 1 :X2 - :Y2 + :SCALEX ( 2 * :X * :Y ) + :SCALEY END MANDEL.LG 1 Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 14 Share Posted February 14 (edited) Well this is inconvenient: It appears that at least in both Altirra/x64 4.20 and in Colleen, the apparently "official" port of Atari800 to Android, booting Logo from diskette or cassette will cause TOOT to reject frequencies under 62, while launching Logo from ROM causes TOOT to accept frequencies down to 14, even with Atari DOS loaded. Colleen only appears to like the .CAR version of the Logo ROM dump. This is impacting my 1930 Model 15 Teletype sound effects for the Mandelbrot program 😄 Edited February 14 by yetanothertroll Added a link to a second video with the tty bells Quote Link to comment Share on other sites More sharing options...
yetanothertroll Posted February 15 Share Posted February 15 Happy Valentine's Day everyone! How many big fibs have you had to tell today? This program started off as simply printing the Fibonacci sequence using bignums, stored as lists of integers between [0 .. 999999999], but it kind of got away from me. There are now functions to compare them, multiply, check if they're odd or even, and convert ordinary numbers like 9.87654321e+97. There's no need to use TOBIG on 0, 1, 2, ..., 9, but 12 will be interpreted as 2000000001 and 1.2 will throw an error. Exponentiation, tetration, debugging cruft cleanup, adding even more ridiculous checks to DOUBLEDOWN, etc., are left as exercises for the student TO BIGFIB BIGFIB.1 BIGTEE 0 BIGTEE 1 END TO BIGADD :B1 :B2 OUTPUT REVERSE BIGADD.1 :B1 :B2 0 [] END TO BIGADD.1 :B1 :B2 :CARRY :RESULT IF ( AND EMPTYP :B1 EMPTYP :B2 0 = :CARRY ) [OUTPUT :RESULT] OP BIGADD.2 SAFEBF :B1 SAFEBF :B2 ( SUM SAFEF :B1 SAFEF :B2 :CARRY ) END TO BIGADD.2 :B1 :B2 :NEW OP BIGADD.1 :B1 :B2 ( INT ( :NEW / 1000000000 ) ) FPUT ( REMAINDER :NEW 1000000000 ) :RESULT END TO BIGEQ :B1 :B2 IF AND EMPTYP :B1 EMPTYP :B2 [OUTPUT TRUE] IF NOT ( ( SAFEF :B1 ) = ( SAFEF :B2 ) ) [OUTPUT FALSE] OUTPUT BIGEQ SAFEBF :B1 SAFEBF :B2 END TO BIGEVEN :B1 IF EMPTYP :B1 [OUTPUT TRUE] OUTPUT 0 = REMAINDER FIRST :B1 2 END TO BIGFIB.1 :B1 :B2 BIGFIB.1 :B2 BIGTEE BIGADD :B1 :B2 END TO BIGHALF :B1 OUTPUT BIGHALF.1 REVERSE :B1 0 [] END TO BIGHALF.1 :B1 :CARRY :RESULT IF EMPTYP :B1 [OUTPUT :RESULT] OP BIGHALF.1 BUTFIRST :B1 ( REMAINDER FIRST :B1 2 ) FPUT ( :CARRY * 500000000 ) + INT 0.5 * FIRST :B1 :RESULT END TO BIGMUL :B1 :B2 OUTPUT BIGMUL.1 :B1 :B2 0 END TO BIGMUL.1 :B1 :B2 :RESULT BIGTYPE :B1 TYPE [*] BIGTYPE :B2 TYPE [+] BIGTYPE :RESULT PRINT [] IF OR BIGZERO :B1 BIGZERO :B2 [OP :RESULT] OP BIGMUL.1 ( BIGADD :B1 :B1 ) ( BIGHALF :B2 ) IF BIGEVEN :B2 [:RESULT] [BIGADD :B1 :RESULT] END TO BIGODD :B1 IF EMPTYP :B1 [OUTPUT FALSE] OUTPUT 0 < REMAINDER FIRST :B1 2 END TO BIGTEE :B1 BIGTYPE :B1 TYPE CHAR 32 SHOW :B1 OUTPUT :B1 END TO BIGTYPE :B1 BIGTYPE.1 REVERSE :B1 TRUE END TO BIGTYPE.1 :B1 :FIRST IF AND :FIRST EMPTYP :B1 [TYPE 0 STOP] IF EMPTYP :B1 [STOP] IF NOT :FIRST [BIGTYPE.2 FIRST :B1 100000000] IF AND :FIRST 0 < FIRST :B1 [TYPE FIRST :B1] BIGTYPE.1 BUTFIRST :B1 AND :FIRST 0 = FIRST :B1 END TO BIGTYPE.2 :N :D IF :D = 1 [TYPE :N STOP] TYPE INT :N / :D BIGTYPE.2 REMAINDER :N :D INT :D / 10 END TO BIGZERO :B1 IF EMPTYP :B1 [OUTPUT TRUE] IF 0 < FIRST :B1 [OUTPUT FALSE] OUTPUT BIGZERO BUTFIRST :B1 END TO DOUBLEDOWN :N DOUBLEDOWN.1 BIGTEE TOBIG :N END TO DOUBLEDOWN.1 :B1 DOUBLEDOWN.1 BIGTEE BIGMUL 2 BIGHALF BIGADD :B1 :B1 BIGHALF BIGADD :B1 :B1 END TO REVERSE :LIST OUTPUT REVERSE.1 :LIST [] END TO REVERSE.1 :LIST :RESULT IF EMPTYP :LIST [OUTPUT :RESULT] OP REVERSE.1 BUTFIRST :LIST FPUT FIRST :LIST :RESULT END TO SAFEBF :B1 OP IF EMPTYP :B1 [:B1] [BUTFIRST :B1] END TO SAFEF :B1 OUTPUT IF EMPTYP :B1 [0] [FIRST :B1] END TO TOBIG :N IF :N = 0 [OUTPUT []] IF :N < 0 [OUTPUT TOBIG - :N] OUTPUT FPUT REMAINDER INT :N 1000000000 TOBIG INT :N / 1000000000 END BIGFIB.LG 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.