Jump to content

TheBF

+AtariAge Subscriber
  • Posts

    4,475
  • Joined

  • Last visited

Everything posted by TheBF

  1. That's a monster. You spent some time on that I reckon. Do we have any idea if it would be better than say, a 32 bit integer PRNG scaled and converted to a float? I know it would be a different sequence, but does the float version have any better characteristics?
  2. That's clever. Another thing I have to try. I scratched my head for awhile trying to figure out a minimal way to context switch. I didn't like taking up memory to make vectors for each task when they would just be copied into registers which is also memory. My solution was to also play a game with RTWP for round-robin mutli-tasking by presetting R13,R14,R15 in every task so they all point back to each other in a circle. This means the vectors live in registers not data memory. Then to context switch, I just run RTWP. I think that with later CPUs in the TI universe they added an instruction that did something like this but I can't remember where I saw it or how it worked.
  3. I have had too many interruptions to my coding time over the last while so the most I can do is cleanup. The conductor of of the community orchestra I joined decided it would great for us to play the Telemann concerto for two Violas. I started playing the darned thing only a year ago! This old guy needed to do a lot of practicing. Also, the homeschool coop is doing a play version of the Greatest Showman and my daughter, who I can't refuse, ask me to be in the band. Anyway during my cleanup time I reviewed my rendition of @Reciprocating Bill 's Asm sieve converted to ASMForth. If we re-name registers, they look like variables in Forth code. This code gets much more readable IMHO. This model of "machine Forth" fits much better with 9900 than Chuck Moore's machine Forth for the same reason Chuck's machine Forth was mostly one to one with his instruction set. ASMForth is mostly one to one with 9900 except for loops, sub-routines and whatever high level Forth words you wish to create. And here is the resulting code from Classic99 Dissassembler with some comments
  4. That sounds very good. I may fool around with that. I don't use BLWP for setting VDP addresses because its a leaf and a fast BL seemed all I needed I reserve full context switching for task switching in my system. With a return stack implemented it not a big deal to save a register or two if you are short somewhere but so far I find with passing parameters on the data stack and 6 scratch registers I have never needed to push/pop registers. YMMV as they say. But if I understand you correctly I can READ VDP without worrying about using LIMI 0 ??
  5. Not a popular idea but here is what I did. @dhe I put my LIMI 0, in my address setter sub-routine. There is one entry for writing (ORing a register with >4000) WMODE and another entry for reading, RMODE. It slows it down, but it's always in the right place. At the end of each VDP routine I re-enable interrupts. This allows me to do sprites and motion interactively from the interpreter which is pretty fun. In the for what it's worth department... It's all in RPN Assembler but if you feel the need to read code while hanging from the ceiling upside down here it is. CAMEL99-ITC/Compiler/cc9900/SRC.ITC/TI99IOX.HSF at master · bfox9900/CAMEL99-ITC · GitHub
  6. Could be worse. Japanese students have four alphabets to learn. Hiragana, katakana, Kanji (sub-set Chinese characters) and "romanji". (our alphabet) I have read it can take up to twelve years of school for full fluency.
  7. "Write the game snake in Python" 🤯
  8. It's nice to have a smart person around the house. That's really neat to see that explained so clearly. Your work gives me the impression that this should be a very good PRNG. My burning question: When we dumb it all down to a >300 byte screen position or a random direction vector, is there a way to know that the BASIC or XB PRNGs would provide a material benefit versus a simpler solution? (You helped me with a simple analysis tool a few years back, but I am a humble business weanie so the amount of rigour involved was slightly less. One might say it was completely devoid of rigour.)
  9. Those eyes are making me think of this screen saver I made. eyes.mp4 EYESII EYESIJ EYESIK
  10. Wow that's important stuff. Bravo. There was a guy in the 90's in the UK who was doing railway systems in Forth. He had developed a method of proving the code was safe I believe which was a specification requirement. His name is escaping my old brain at the moment. Did some googling. It's Paul Bennet. https://wiki.forth-ev.de/lib/exe/fetch.php/en:projects:a-start-with-forth:certifyingforthsource_004_.pdf But nobody would begin to believe you can do anything well in Forth in the 21st century. I mean really, how could you, the compiler is not even 1MB.
  11. Ya that was an insight that simplified my coding of Forth conditionals. ( = < > 0= etc.) Since CLR and SETO don't play with status you can compare a register, then clear it or set it to -1 as a default result. Then you can change the register based on the previous comparison instruction. It's almost like the 9900 designers knew how to write an instruction set. Something like: ( Apology in advance. I don't use normal Assemblers often) ZEROEQ CI R4,0 * 0= compare top of stack cache to zero CLR R4 JNE $1 SETO R4 $1 NEXT * return to Forth However even though it's only four instructions you can see why a native code compiler would be more efficient on 9900. In MACHFORTH or ASMForth this is only two instructions, compare to zero and the jump.
  12. Very naughty photo. Your nerds are showing.
  13. Nice to see you back Mark. I suspect life has gotten in the way of the serious job of playing with Forth on a 40 year old machine.
  14. If you can convince a local TV station to do the story that gets people's attention. Better if it's a national network station where the story can get distributed across the country.
  15. Excellent. Why? For that time that you need it and it won't work as expected. However if that is unthinkable then you are correct. Don't write code for stuff that "might" happen.
  16. Curiosity question. Is there a way to access the screen management variables in the P-code system? Where I am going is; is there any point is seeing what mode the system thinks it is in? (Text, graphics 1, as the two most common ones) That way your gchar function could maybe know the line length so that 32 would be replaced by a variable that "knows" the current line length. Asking for a friend
  17. That's pretty amazing for an Extended BASIC program.
  18. Cool. My dad's family comes from a part of Canada with an Irish and French fiddle tradition. I played fiddle badly when I was young. I played guitar as a part-time professional for many years. I just took up Viola last June and joined a community orchestra. Good for old fingers and brains to get some exercise. But it does cut into my coding time. I am working on some Irish and Scots tunes on Viola. It's a bit harder but some of the tunes sound nice in the lower key.
  19. Sounds like the future is coming at us quickly.
  20. So does that mean that the CIA can't know what you are talking about... but Meta can?
  21. Well this is fun. We can extend the range down more than an octave using the bass trick with the noise generator driven by channel 3. \ ==================[ BASS VOICE ]================== \ Bass voice uses the TENOR oscillator and the noise channel \ It also has a lower volume so you have to reduce volume of \ the other channels if used in combination : PLAY.BASS ( fcode -- ) OSC3 OR SPLIT SND! SND! \ send frequency data on channel 3 31 ATT3 OR SND! \ but chan 3 is silent -5 OSC4 OR SND! \ select noise channel for output VOLUME @ ATT4 OR SND! \ send volume \ BASS Note is now playing... ON_TIME @ DELAY \ set the ISR timer, which auto mutes OFF_TIME @ DELAY \ time between notes ; DECIMAL : BASS: ( freq -- ) CREATE 15 * HZ>CODE , \ calibrate freq. & pre-calculate the code DOES> @ PLAY.BASS ; \ FREQ NATURAL FREQ ACCIDENTAL EN-HARMONIC 41 BASS: E1 \ Lowest note of Bass guitar 44 BASS: F1 46 BASS: F#1 : Gb0 F#1 ; 49 BASS: G1 52 BASS: G#1 : Ab G#1 ; 55 BASS: A1 58 BASS: A#1 : Bb A#1 ; 62 BASS: B1 65 BASS: C2 69 BASS: C#2 : Db1 C#2 ; 73 BASS: D2 78 BASS: D#2 : Eb1 D#2 ; 82 BASS: E2 \ Lowest Note of Guitar 87 BASS: F2 93 BASS: F#2 : Gb1 F#2 ; 98 BASS: G2 104 BASS: G#2 : Ab1 G#2 ;
  22. In the mean time... I finally got something working that I knew was possible but I just didn't get all the pieces right before now. Maybe I am still learning... Long ago I made a "language" to write music as text where notes are Forth words that know how to play themselves. I added an "expression" feature where you could set how the music was played as in legato (notes connected) staccatto (notes are separated) etc. It has dynamics to control the volume. You can set the time signature. (I don't have a key signature feature and that might just make it more complicated) And you can use ||: <music notes> :|| to cause a section to repeat which is like real music notation. The fractions select the note type. quarter-note, half-note, eighth-note etc. Here is Twinkle Twinkle Little Star in the key of A major. : TWINKLE 120 BPM SOPRANO 4/4 NORMAL forte | 1/4 A4 A4 E5 E5 | F#5 F#5 1/2 E5 | | 1/4 D5 D5 C#5 C#5 | B4 B4 1/2 A4 | mf | 1/4 E5 E5 D5 D5 | C#5 C#5 1/2 B4 | | 1/4 E5 E5 D5 D5 | C#5 C#5 1/2 B4 | ff | 1/4 A4 A4 E5 E5 | F#5 F#5 1/2 E5 | | 1/4 D5 D5 C#5 C#5 | B4 B4 1/2. A4 || ; Anyway that was the easy part. The hard part was that I could never write three parts (melody, harmony, bass for example) and have them all play via the multi-tasker. They would always run out of sync. But this week I finally got it. The secret was something I had tried before but over-complicated it a bit. The idea is to let an interrupt service routine do the timing of the notes and automagically "mute" the sound channel when its timer has expired. The 2nd helpful thing was to send all the sound bytes for each voice un-interrupted for each voice, meaning don't put a PAUSE in between which changes tasks. Then a DELAY function that waits in a loop calling PAUSE to give the other voices time. This helped keep everything synchronized. Here is the code for the four muting isr timers Here is a descant and bassline for Twinkle And here is what happens when you run the Forth words in three separate tasks. Twinkle Music script.mp4 Here is the music script player code
  23. I did a similar study a while back and saw no advantage to changing to absolute addresses and in fact if you wanted to relocate binary images of Forth code it's one less thing to worry about when you use relative branching.
  24. I love Tom Lehrer. This is one my "cold war" favourites. Might be time to resurrect it...
×
×
  • Create New...