Example on using EXEC
Posted: Thu Oct 10, 2024 5:56 am
The EXEC keyword is typically used as way to bring plain-text BASIC into the system, since the KERNAL ROM V2 BASIC expects to load BASIC in a tokenized form. BASLOAD can handle plain-text (ASCII) as input files, but the LOAD command does not. So EXEC exists as a utility to work around that (for when using the physical hardware; within the emulator you can just paste in the plain text).
But there are some limited ways that EXEC can be used to perform "self modifying" BASIC code. Because of the way the system works, you generally have to use the RUN command to then run the loaded program. And one of the first things RUN does is CLR (clear out BASIC variables from memory). We've been pondering/experimenting with other exotic ways to make use of EXEC. So, this example is doing a couple things: after 90 jiffies (~1.5 seconds) it makes a decision on whether to draw white solid character, or else draw a random color (for a random duration across the screen). Then EXEC is used to self-modify the code to alternate which side of the screen this "simulated cave growth" is drawn on (top vs bottom, the ol'e stalagmite vs stalactite). Can try running this with WARP mode in the emulator.
I've yet to find a way to hide/disable screen output of the EXEC call (which streams the designated plain-text). I suppose you could temporarily do COLOR 6,6 or something (same foreground on background, to effectively make it non-visible). But maybe this concept has uses in graphical modes, which would mask the text output? Just exploring ideas on ways to take advantage of the constantly-interpreted nature of BASIC.
My understanding is that BASIC is essentially dividing into a <code><data> arrangement. The <code> is your tokenized code stored in memory, done as you are typing your lines of BASIC. Then when you RUN, any variables you declare (assign values to) are appended at the end past your tokenized <code> region during your runtime. This keeps everything in LORAM, but makes "true" self-modifying code impractical - as adding any new line (or significantly expanding an existing line) is stomp over the <data> portion. So in this example, it has to go out of its way to modify the code to initialize variables to the values left-off during the previous runtime (two main variables being the OS "output state" and the TL "time last" to maintain the jiffies-based decision tempo). Variables like this could also be stored in other BANKs. Code is also applied to avoid re-clearing the screen during the next "re-RUN".
NOTE: It may be possible to also just block-copy the entire BASIC <data> space to another BANK, since it is possible to programmatically "find" the end of the <code> region (and then just block-copy a prior <data> state back in early on during the "re-RUN"). As I get time, I'll try to prepare an example on how to do that (offhand I've forgotten how to find that <code> region, IIRC the BASIC ROM code maintains a RAM pointer to that?).
You can press ESCAPE to stop the runtime of this example, where the code is then modified again to return it back into a freshly re-runnable state (so you can RUN, press ESCAPE, and RUN again).
But there are some limited ways that EXEC can be used to perform "self modifying" BASIC code. Because of the way the system works, you generally have to use the RUN command to then run the loaded program. And one of the first things RUN does is CLR (clear out BASIC variables from memory). We've been pondering/experimenting with other exotic ways to make use of EXEC. So, this example is doing a couple things: after 90 jiffies (~1.5 seconds) it makes a decision on whether to draw white solid character, or else draw a random color (for a random duration across the screen). Then EXEC is used to self-modify the code to alternate which side of the screen this "simulated cave growth" is drawn on (top vs bottom, the ol'e stalagmite vs stalactite). Can try running this with WARP mode in the emulator.
I've yet to find a way to hide/disable screen output of the EXEC call (which streams the designated plain-text). I suppose you could temporarily do COLOR 6,6 or something (same foreground on background, to effectively make it non-visible). But maybe this concept has uses in graphical modes, which would mask the text output? Just exploring ideas on ways to take advantage of the constantly-interpreted nature of BASIC.
My understanding is that BASIC is essentially dividing into a <code><data> arrangement. The <code> is your tokenized code stored in memory, done as you are typing your lines of BASIC. Then when you RUN, any variables you declare (assign values to) are appended at the end past your tokenized <code> region during your runtime. This keeps everything in LORAM, but makes "true" self-modifying code impractical - as adding any new line (or significantly expanding an existing line) is stomp over the <data> portion. So in this example, it has to go out of its way to modify the code to initialize variables to the values left-off during the previous runtime (two main variables being the OS "output state" and the TL "time last" to maintain the jiffies-based decision tempo). Variables like this could also be stored in other BANKs. Code is also applied to avoid re-clearing the screen during the next "re-RUN".
NOTE: It may be possible to also just block-copy the entire BASIC <data> space to another BANK, since it is possible to programmatically "find" the end of the <code> region (and then just block-copy a prior <data> state back in early on during the "re-RUN"). As I get time, I'll try to prepare an example on how to do that (offhand I've forgotten how to find that <code> region, IIRC the BASIC ROM code maintains a RAM pointer to that?).
You can press ESCAPE to stop the runtime of this example, where the code is then modified again to return it back into a freshly re-runnable state (so you can RUN, press ESCAPE, and RUN again).