• Embed binary code in Applesoft program lines

    From mmphosis@21:1/5 to All on Thu Jul 15 00:19:57 2021
    For those that might be interested, here is an example of this method. My program is "listable" and definitely "fragile." You can use different line numbers, so long as you GOSUB to the single line with the : just before the line with the CALL and the embedded binary.

    10 HOME : GOSUB 62910: PRINT PEEK (78), PEEK (79):X = RND ( - 1 * ( PEEK
    (78) + 256 * PEEK (79))): PRINT X

    62900 END
    62910 :
    62920 CALL PEEK (121) + PEEK (122) * 256 + 37: RETURN : VTAB P CLEAR
    TAB( NEW L HCOLOR= INT ONERR L IF LL IF LL IF LL VTAB @ CLEAR TAB( NEW
    0 ASC ASC N = MID$ ASC O8 GOSUB VAL

    https://www.applefritter.com/comment/93931#comment-93931

    -----

    From Slammer! "other methods" ...

    * Embed binary code in program lines

    Speedy, but difficult to manage and access, can make programs unlistable,
    and also fragile if any lines are changed.

    http://www.ivanx.com/appleii/slammer/othermethods.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From I am Rob@21:1/5 to All on Wed Jul 14 23:40:33 2021
    The idea of where to place a binary program so that it is protected and can not be tromped on by variables, strings and expanding programs is a subject that has been discussed many times, and is still difficult to give a good answer to.

    I played with the idea of putting binary code between the end of the program and the start of variable space (also known as LOMEM:, which usually follows the end of the program in memory).

    * EP = end of program address
    * BS = binary program start address
    * BL = binary program length
    * binary program can be loaded or poked to the address at EP + 15
    * The +15 is needed to skip past the two variables EP & BL, which are temporarily preserved after the end of the program until the new LOMEM: command is encountered, then the variables are reloaded to the new LOMEM: address.
    * The binary program length is from Prodos, change to 43634 & 43635 for DOS


    1 GOTO 63998 : REM Must be done before any variables are assigned
    2 CALL BS : END

    63998 GOSUB 63999: PRINT CHR$ (4)"BLOAD BIN.PGRM,A"EP + 15: LOMEM: EP + BL + 15: GOSUB 63999:BS = EP +15: GOTO 2

    63999 EP = PEEK (105) + 256 * PEEK (106):BL = PEEK (48859) + 256 * PEEK (48860): RETURN

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike Spangler@21:1/5 to All on Thu Jul 15 13:05:09 2021
    The documentation of the Wizard's Toolbox has a detailed description of what is going on with that method (putting binary code between the end of the program and the start of variable space) as did some issue of Open Apple back before it became A2-
    Central.

    It sort of fell out of favor when Prodos came out as you could just ask Prodos for a buffer. But that trick still works under Prodos too.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Erik Struiksma@21:1/5 to All on Fri Jul 16 03:25:57 2021
    I actually prefer to keep my ML saved in a separate file to BLOAD from. This way I can pull this for multiple BASIC programs without duplicating the ML each time. But... if I really wanted to have it all in 1 file without restricting my ML or binary data
    in any way, I would try doing something like this:

    * ML to set BASIC program start pointer, fix any broken BRUN hooks, and JMP to somewhere to start BASIC program execution.
    * Your ML routines & binary data
    * Your BASIC program
    * BSAVE everything (L$ something like: BASIC end - BASIC start + ML/data length)

    This does restrict you from being able to RUN/LOAD/SAVE filename, but you'll at least be able to BRUN it, and you won't have to worry about BASIC messing up your ML when you edit, nor will it need to be relocatable. Once the BASIC program start pointer
    is set, you can RUN, LIST, and edit all you want. Of course you would have the inconvenience of having to BSAVE each time you want to save your work. You could have a BASIC line to do this for you. Just keep that line number out of reach of normal
    program execution, and you would RUN Ln# from the command prompt to save. Either that or go though the trouble of making an ampersand routine if you don't want to see or store a dedicated line for saving in your BASIC program.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Erik Struiksma@21:1/5 to mspa...@ifiber.tv on Fri Jul 16 03:24:30 2021
    On Thursday, July 15, 2021 at 3:05:10 PM UTC-5, mspa...@ifiber.tv wrote:
    The documentation of the Wizard's Toolbox has a detailed description of what is going on with that method (putting binary code between the end of the program and the start of variable space) as did some issue of Open Apple back before it became A2-
    Central.

    It sort of fell out of favor when Prodos came out as you could just ask Prodos for a buffer. But that trick still works under Prodos too.

    I actually prefer to keep my ML saved in a separate file to BLOAD from. This way I can pull this for multiple BASIC programs without duplicating the ML each time. But... if I really wanted to have it all in 1 file without restricting my ML or binary
    data in any way, I would try doing something like this:

    * ML to set BASIC program start pointer, fix any broken BRUN hooks, and JMP to somewhere to start BASIC program execution.
    * Your ML routines & binary data
    * Your BASIC program
    * BSAVE everything (L$ something like: BASIC end - BASIC start + ML/data length)

    This does restrict you from being able to RUN/LOAD/SAVE filename, but you'll at least be able to BRUN it, and you won't have to worry about BASIC messing up your ML when you edit, nor will it need to be relocatable. Once the BASIC program start pointer
    is set, you can RUN, LIST, and edit all you want. Of course you would have the inconvenience of having to BSAVE each time you want to save your work. You could have a BASIC line to do this for you. Just keep that line number out of reach of normal
    program execution, and you would RUN Ln# from the command prompt to save. Either that or go though the trouble of making an ampersand routine if you don't want to see or store a dedicated line for saving in your BASIC program.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Nickolas@21:1/5 to All on Fri Jul 16 09:09:48 2021
    I'd offer another option: move up LOMEM and end-of-program, and shove the machine code in the hole. Lets you LOAD the data with the code, while
    avoiding having to shove it *into* the code.

    I think this is what HOPALONG CASSIDY did.

    -uso.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From fadden@21:1/5 to All on Fri Jul 16 07:55:07 2021
    Take a look at RENUMBER from the DOS 3.3 System Master disk.

    [...]
    1200 HOME : PRINT TAB( 4)"RENUMBER IS INSTALLED AND READY"
    1210 VTAB 8: PRINT "IF YOU USE 'FP', 'HIMEM', OR 'MAXFILES'"
    1220 PRINT : PRINT " YOU WILL HAVE TO RE-RUN RENUMBER"
    10000 REM DO NOT CHANGE 10010
    10010 CALL PEEK (121) + PEEK (122) * 256 + 31

    It's looking at $79-7a (OLDTEXT), which holds a pointer to the end of the previous line. The machine-language code follows the last line, so really the comment should be, "do not change 10010, or add anything after this line". So long as you follow
    that rule, you can add or remove lines, and everything just gets moved around.

    The code it calls relocates itself below DOS and sets up the ampersand vector.

    One reason to use this sort of approach is for programs on cassette tape. Binary programs must be loaded with an explicit start and length, but BASIC programs can just use LOAD/SAVE.

    (For Integer BASIC, see https://retrocomputing.stackexchange.com/q/494/56 .)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Erik Struiksma@21:1/5 to All on Fri Jul 16 19:05:49 2021
    I guess the complexity of how you handle this depends on what the needs of your code is. You would have to weigh the pros and cons of each method and decide for yourself what's best for each case.

    If your code is completely relocatable and doesn't need direct access to parts of itself (or data), then sure, sticking it between your program end and LOMEM would make sense. But if your code does need direct access to itself or it's data, then you can'
    t have that just floating up and down in memory... at least, not without some overhead code. So if were sticking to wanting to use SAVE/LOAD/RUN filename, here's a couple more ideas I could think of.

    You could have some additional code that's relocatable for initialization that would recalculate and rewrite each place with any kind of absolute addressing reference by using indirect ZP addressing.

    Here's my other idea. For program execution, you would have your ML code and data located above HIMEM. Before you SAVE, you would need to temporally adjust LOMEM and copy of your code/data down to the end of your BASIC program. Once you SAVE, then you
    can restore LOMEM back. After you LOAD your program, you would need to copy the code/data at the end of your program back up and adjust LOMEM and HIMEM accordingly.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mmphosis@21:1/5 to All on Wed Jul 28 21:09:37 2021
    Here is another one with a slightly different approach.

    0 GOTO 1: ONERR AI READ LY RND
    1 LET X = 256 * PEEK (104)
    2 LET X = X + PEEK (103) + 7
    3 LET E = 61588:M = - 1
    4 FOR I = E + 9 TO E STEP M
    5 POKE 65, PEEK (I): CALL X
    6 NEXT

    https://rosettacode.org/mw/index.php?title=Show_ASCII_table&oldid=339063#Applesoft_BASIC

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)