[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Himem with prodos basic?
Jm wrote:
> I made an assembly language program that I need to interface with my
> prodos basic program. The problem is what addresses should it go in?
> Right now I'm loading it into the first hires graphics page. It seems
> to work there but will prodos basic start scribbling all over it if I
> make my program too long? I tried doing himem:(whatever hex 3500 is in
> decimal) but then I got a "no buffers available" message when I tried
> to load files. My apple 2c has 128K of RAM I think. Also, when I use &
> to call the program, how would I type paramaters for it? Would it be
> "& 3 2" or "&3,2,3" or what? And how does the program get them, are
> they pushed onto the stack or something?
Aha, another //c hacker! Having bumped my head many times against the
problem of combining assembly/machine language routines with BASIC
programs on the //c, I can give you some first-hand advice on the
subject.
Your suspicions about memory conflicts between your assembly code and
ProDOS BASIC are correct: if your BASIC program is rather large, it may
directly overwrite whatever is stored in Hi-Res Graphics Page 1 or
indirectly stomp on the same memory area with variable storage.
Fortunately, there are ways of protecting your assembly code from being
destroyed.
It is of great value to understand how Applesoft BASIC organizes memory
for storing program code and variable data. BASIC uses a group of
pointers to define a sort of "workspace" in memory, which is then
divided into different sections. The following chart describes these
pointers in detail.
Pointer Addresses Points to...
------- --------- ------------
TXTTAB $67 (103) and Start of BASIC program (usually
$68 (104) $801)
PRGEND $AF (175) and End of BASIC program + 1 or 2
$B0 (176)
VARTAB $69 (105) and Start of simple variable storage
$6A (106) space (usually PRGEND + 1)
ARYTAB $6B (107) and Start of array variable storage
$6C (108) space
STREND $6D (109) and End of variable storage space
$6E (110)
FRETOP $6F (111) and Start of string storage space
$70 (112)
MEMSIZ $73 (115) and End of string storage space
$74 (116) (usually $9600 under ProDOS)
Armed with this information, we can use any of the following techniques
to create a "safehouse" for our assembly language routine(s):
1.) Move TXTTAB up to a higher address
The start-of-program pointer is normally set to $801 (right after
page 1 of text video memory) but can be changed to a higher address.
Since page 2 of text video memory is not supported by Apple firmware,
addresses $800 (2048) through $BFF (3071) will be unused by anything
except our own assembly code; all we have to do is obey these guidelines
for adjusting TXTTAB: (a) the location immediately before the address
pointed to by TXTTAB must *always* contain a zero, and (b) you must not
modify TXTTAB from within a BASIC program unless you immediately
terminate said program or promptly load another BASIC program. This
means that you must preceed your main BASIC program with a special
"loader" program that "paves the way," like this....
10 POKE 103,1 : POKE 104,12 : REM Change TXTTAB
20 POKE 3072,0 : REM Store zero at TXTTAB - 1
30 PRINT CHR$(4);"RUN MY.PROGRAM" : REM Load and execute the main
BASIC code
The above example reserves the entire page 2 area of text video memory
for our use, then loads the BASIC file "MY.PROGRAM" from disk.
2.) Move VARTAB up to a higher address
The start-of-variables pointer is normally set to the address
immediately after the end of the BASIC program (pointed to by PRGEND).
However, VARTAB can be adjusted upwards *as long as it is done before
any variables have been defined by the program*. The advantage to this
method is that, if we know ahead of time how many bytes our assembly
code will require, we can set aside *exactly* as much memory as we need.
All we have to do is add the number of required bytes to the current
value of PRGEND and assign the sum to VARTAB, like so....
10 LOMEM: PEEK(175) + PEEK(176)*256 + 42 : REM Assuming that we
need 42 bytes
20 REM Rest of program continues from here....
Another nice thing is that, as long as the number of required bytes
remains the same, we can go ahead and make the BASIC program larger or
smaller -- because each time that we run the program, line 10 will
automatically recalculate VARTAB (using the LOMEM: statement) according
to the value of PRGEND no matter how it has changed. Of course, this is
assuming that you are reloading your assembly code at VARTAB - n (where
n = number of bytes needed) every time as well.
3.) Move MEMSIZ to a lower address
In a sense, this is the most problematic technique because of the
way that ProDOS modifies MEMSIZ on the fly. When opening a disk file,
ProDOS will automatically lower MEMSIZ by $400 (1024) bytes to create a
temporary disk buffer. Because strings are stored in reverse order
(starting at MEMSIZ, then moving down to lower and lower addresses)
ProDOS has to perform extra work to prevent strings from being
overwritten by the $400-byte disk buffer. When the disk file is closed,
ProDOS moves MEMSIZ back up to its original value. Also, ProDOS only
allows *multiples of $100 (256)* for values of MEMSIZ.
If we take all this into account, we can then safely adjust MEMSIZ
by following these guidelines:
(a) Close all disk files (by using the universal CLOSE command
under ProDOS)
(b) Lower the value of MEMSIZ high (hex $74, dec 116) by the
number of pages required, *plus* the four pages needed for the temporary
ProDOS disk buffer (so if your assembly code uses three pages, you
should lower MEMSIZ by seven)
(c) If you are changing MEMSIZ by using the HIMEM: command from
within a BASIC program, you must do so before defining any strings
(otherwise you may overwrite them!)
(d) Don't set MEMSIZ too low, or you'll bump into the simple/array
variable storage area of memory (this is probably what caused the "NO
BUFFERS AVAILABLE" error in your case: ProDOS didn't have enough room to
create its temporary disk buffer)
4.) Stick your code in page 3
It's an old Apple II programmer's trick, but sometimes the old ways
work best. Since the memory section from addresses $300 (768) through
$3CF (975) is not used by the Apple firmware and lies completely out of
the way of the Applesoft BASIC memory workspace, it makes an ideal
refuge for small assembly/machine language routines. Of course, this
makes it prime real estate for all sorts of neat little binary programs
and machine language utilities, so you may already be using page 3 for
something else.
BTW, that 128K in your //c is not one contiguous block of memory.
Instead, it is divided into two sections of 64K called the "main" and
"auxiliary" memory banks -- this is due to the fact that the 65C02
processor (the CPU in your //c) can only address up to 64K at a time. In
fact, the topic of //c memory management deserves an entire discussion
of its own, but suffice to say that having 128K does not usually mean
that you have twice as much room to play in.
Furthermore, the art of passing parameters from a BASIC program to a
machine language routine is so involved that I'll have to postpone
describing it until later. Hopefully I've given you enough information
to get off on a promising start. Until next time, happy hacking!
--
Peace, Love, and Apple II Forever!
Chad Choi Lin
chadlin@nyetcom.com
*********************************
New and improved .sig file -- now
with munged address AND spambait!
To send e-mail, remove the "y"
from the domain name of address.
*********************************
Hey MLM scam artists -- send your spam to the Federal Trade Commission:
pyramid@ftc.gov
The IRS wants to know how much money you REALLY make:
net-abuse@nocs.insp.irs.gov
These guys love sending spam -- let's see how much they like GETTING it:
shadowcomm.com
2hootersup.com
newpower.com
wildsnatch.com
2-girls.com
cumshower.com
cumsuckingsluts.com
pornotheater.com
fabulousfacials.com
knobgobblers.com
cherrypit.com
sexxxlinks.com
********************************
Okay, I lied -- I'm not a NETCOM
accountholder. You can e-mail me
at "dirtlink" (fnord) dot "net"
********************************