Path: news1.icaen!news.uiowa.edu!news1.chicago.iagnet.net!iagnet.net!128.223.220.30!logbridge.uoregon.edu!news.uoregon.edu!!nparker From: nparker@inferno.uoregon.edu (Neil Parker) Newsgroups: comp.sys.apple2.programmer Subject: Re: BASIC from assembly? Date: 10 Jan 1998 08:25:31 GMT Organization: Me? Organized? Surely you jest. Lines: 77 Message-ID: <697b9r$m3c$1@pith.uoregon.edu> References: <68uojr$l6p$13@news.vanderbilt.edu> NNTP-Posting-Host: ssil.uoregon.edu X-Trace: pith.uoregon.edu 884420731 22636 nparker 128.223.108.115 X-Complaints-To: usenet@news.uoregon.edu Originator: nparker@ Xref: news1.icaen comp.sys.apple2.programmer:9624 In article <68uojr$l6p$13@news.vanderbilt.edu>, Tilghman Lesher wrote: >Is there a way from assembly to invoke the BASIC interpreter? > >For example, if you used an assembly wrapper to mask that the >code which you're using is *actually* BASIC, could you use >assembly to move a BASIC program into position, then execute >it with a JMP? > >This would enable people to write BASIC code which would be >unmodifiable by the end user (like a teacher programming >for students). Hence, you would get the ease of programming >BASIC, but the (relatively) better security of assembly >language. Yes, you can start up a BASIC program from machine language. Step #1: If you're running under DOS 3.3 or BASIC.SYSTEM, skip this step and go to step 2. Otherwise, you're probably a standalone ProDOS SYS program...you need to initialize the BASIC interpreter. Point the KSW vector (at $38, 39) at your main (machine language) code, and JMP $E000. BASIC will initialize itself, and your code regains control when it's done and ready to ask for keyboard input. (This is how DOS 3.3 initializes BASIC when it's first booted.) Step #2: Set up BASIC's program and variable space pointers. Here are the ones you need to worry about: $67,68 (TXTTAB) Points to the first byte of the BASIC program. $AF,B0 (PRGEND) Points to the end of the BASIC program. $69,6A (VARTAB) Points to the first byte of free memory for BASIC's variables. Should normally point to the first byte after the end of the BASIC program, unless you're reserving memory between the program and its variables. (This is the LOMEM pointer.) $73,74 (MEMSIZ) Points to the first byte after the end of BASIC's variable space. Should normally be pointed at the first byte used by DOS, unless you're reserving memory between DOS and your variables. (This is the HIMEM pointer.) Setting MEMSIZ correctly is especially vital if you initialized BASIC in step 1, because the default value of MEMSIZ is $C000, which allows your strings to trample all over DOS or the ProDOS global page. Setting it to $BF00 protects the global page, and setting it to $9600 protects a normal DOS 3.3 or BASIC.SYSTEM. The byte immediately prior to the first byte of the BASIC program should contain 0. The last three bytes of the BASIC program should be 0...make sure you set VARTAB high enough to protect these three bytes. Step #3: Start the BASIC program with JMP $D566. (This routine does not return. If you want your machine language to regain control at some point, you'll have to CALL it from BASIC.) There may be other steps necessary if you want to use DOS commands under BASIC.SYSTEM. In this case you may need to write a BASIC stub to BLOAD and CALL your machine-language-wrapped code. Methods like this make it harder to list or modify a BASIC program, but they don't make it impossible. You can increase the security by using ONERR GOTO to catch control-C, and modifying the RESET vector to catch or reboot on RESET, and by using the run flag (POKE 214,255...this causes BASIC to ignore commands typed at the ] prompt, and re-run the current program instead). Of course anybody who's sufficiently determined to get at your original source code will be able to circumvent all of these measures. - Neil Parker -- Neil Parker, nparker@inferno.uoregon.edu, nparker@axis.llx.com, http://axis.llx.com/~nparker/ (Note new addresses and home page!) Unsolicited commerical e-mail is not welcome, and will be discarded unread.