Magic GOTO lets any ordinary Applesoft program GOTO, GOSUB, or ONERR GOTO to a text label, instead of a line number. This makes programming in Applesoft BASIC much easier. For example, you can have code that looks like this:
REM "MAIN_MENU" (the GOSUB @ preps for the GOTO)
GOSUB @ : GOTO "MAIN_MENU"
IF OK THEN GOSUB @ : GOTO "DO_STUFF"
It doesn't matter what the line numbers are, and if you change them, no biggie -- you don't have to go back and fix all your GOTOs and GOSUBs. In fact, you can write your whole program without line numbers, in an editor such as TextWrangler, and then use its line numbering feature to automatically add line numbers when you're done.
You can contain Magic Goto in your Applesoft program by using special REM statements, or you can load it from a separate file on disk.
Choose your download flavor:
Copy-Pasteable text for emulators: Magic Goto Magic Goto with NuInput
disk image: 140K DOS 3.3
Everything else you might want to know:
If you wish, you can view the Magic Goto assembly source code, or download it with its assembler (non Apple II friendly)
- you can define a label in a REM statement in any of these three equivalent ways:
REM "DoSomething" REM ^DoSomething REM SUB^DoSomething
- the label definition ends with space, colon, or quote, and everything after one of those is ignored
(so you can add comments, e.g.
REM "MyLabel":my comment)
- label names are case sensitive, and most characters besides space, colon, and quote can be used
- the GOTO/GOSUB target label needs to be in quotes, e.g.
- You can control the direction and start line of the label search. The following symbols are recognized as prefixes to a label target:
"label": search forward from top of program
%"label": search forward from current line
#"label": search backward from current line
!"label": search backward from end of program
This allows you to reuse labels, e.g. in an if-then-else stucture:
GOSUB @ : ON (condition) GOTO %"THEN" : GOSUB @ : GOTO %"ELSE_IF"
GOSUB @ : GOTO "END_IF"
GOSUB @ : ON (condition) GOTO %"THEN" : GOSUB @ : GOTO %"ELSE"
GOSUB @ : GOTO "END_IF"
Or, in a while structure:
GOSUB @ : ON (condition) GOTO %"DO" : GOSUB @ : GOTO %"DONE"
GOSUB @ : GOTO #"WHILE"
Because Magic Goto searches linearly, if you have linearly nested structures, you'll need to give them different labels, e.g. "IF-2", "THEN-2", etc.
GOSUB @"label" can be used instead of
GOSUB @ : GOTO "label" (this can also be used with the label prefixes above, e.g.
GOTO "label" must always be preceded by
GOSUB @ (unpredictable results may happen otherwise), and
GOSUB @ should always be followed by
GOSUB @ and its corresponding
GOTO "label", GOSUB will produce ?UNDEF'D STATEMENT ERROR; GOSUB @ will replace the previous GOSUB @;
GOSUB @@ will cancel the GOTO prep;
GOSUB @"label" will cancel the previous GOSUB @, and then GOTO to the label (per the following note)
- the first GOTO found after
GOSUB @ will be the one followed, regardless of which GOTO "label" actually was executed
- You can initialize Magic Goto with a CALL to wherever it is in memory, or with
GOSUB $. In a large program this can take a few moments as every line is scanned for labels. Initializing destroys all variables, and LOMEM should not be changed after initializing. If you don't initialize, it will happen upon encountering the first GOSUB "label". Initializing is also required after using the Applesoft CLEAR command.
ONERR GOTO "label" will cancel
GOSUB @ if an error is caught
- Don't set
ONERR GOTO "label" until Magic Goto is initialized
- The loadable version is 713 bytes long and can be run from any memory location (default is $6000). To use it, start your program with this line. If you wish, you can specify a different BLOAD address and change 24576 in the CALL to the address you specified.
0 IF PEEK(248) < 248 THEN CALL 24576
1 PRINT CHR$(4);"BLOAD MAGIC.GOTO" : GOSUB $
- If you want NuInput in addition to Magic Goto, then copy-paste from here, or you can
EXEC MG.NUINPUT.EXEC on the Magic Goto disk. Start your code from line 40 or higher.
Magic Goto works on any Apple II with Applesoft BASIC. Applesoft itself is not modified in any way.
Thanks to Stavros and Martin for suggestions and comments.
How Magic Gosub came to be (optional reading): One day, a few years ago, I wanted to program in Applesoft BASIC after a very long hiatus, during which I became accustomed to more structured programming languages. So I decided that I would create rules for writing Structured Applesoft. As part of that, I realized that I really wanted named GOSUB targets instead of having to use line numbers, so I began experimenting, and discovered that Applesoft uses line 0 as a target if it doesn't understand what comes after a GOSUB or GOTO.
So I figured that if line 0 called a machine language routine that could search for the name, it could be done. But then I'd need distribute a file to BLOAD along with any Applesoft program I wrote: yuck. I looked into methods to deliver a routine within a program itself, and was dissatisfied with the options, so I instead came up with Slammer, and while writing its utility, I decided that Applesoft's INPUT statement sucked and there should be a better one, so I developed NuInput, and then got distracted with other stuff and never actually got around to the labeled GOSUB routine which was the reason I made those other things in the first place.
And then there I was at KansasFest 2012, and I decided to create Magic Gosub as my HackFest entry. I then polished it and released it. A couple of years later, I sat down to write some Applesoft, and even with Magic Gosub I found I still needed line numbers for this and that, like being able to GOTO backwards for a while structure. I wanted to code completely without line numbers, because they're awful, and even though it required many more bytes (and hours), we have Magic Goto. Hope ya enjoy it.
2.0, Nov 2014: Supports GOTO, ONERR GOTO, search direction and start position.
1.0, Fall 2012: First release
Got a question about Magic Gosub?
Apple II Extravaganza Home Page