[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: String storage



In article <3fksjk$3k1@lastactionhero.rs.itd.umich.edu> mcafee@umich.edu
(Sean Michael McAfee) writes:
>Last week, I wrote a quick Applesoft program to make entry of hex listings
>from Nibble magazine a bit easier.  No, I'm not behind the times, why do
>you ask?  Anyway, the program lets me use my GS's numeric keypad to enter
>hex numbers--"clear" corresponds to A, "=" to B, etc.
>
>A problem arose after I had BSAVEd one short program, and found that the
>majority of the binary file was composed of the same characters as on the
>keypad.  Only the final part of the file had the correct values.  I
>surmised that the file I was trying to create occupied the same space
>that ProDOS uses for string storage--it began at $4080.
>
>Is my conclusion correct?  If so, is there a way to avoid this problem?
>I think that LOMEM or HIMEM could be useful, but I've never had more than
>a vague idea as to how these commands work.

That could indeed be the cause of your symptoms, especially if the more
recent strings occur near the front of the file.  You'd have to use quite a
lot of strings, though, before they could get as far down as $4080.

The LOMEM: and HIMEM: statements set the lower and upper bounds,
respectively, of the memory area available for BASIC variables.  LOMEM
normally starts out immediately above the top of the tokenized BASIC
program.  Simple variables start at LOMEM and grow upward, and arrays start
out where the simple variables end, and also grow upward.

HIMEM normally starts out immediately below DOS or ProDOS.  Strings start
at HIMEM and grow downward.  When the strings and the variables meet in the
middle, ?OUT OF MEMORY ERROR occurs.  This can often be prevented by
frequent use of X=FRE(0) or (under ProDOS) PRINT CHR$(4)"FRE", which
compacts the string space by removing the corpses of old discarded
strings and moving the active strings as far up in memory as they can go.

There are two ways to protect machine-language data from BASIC variables.
One is to move LOMEM upward and store the data below it, and the other is
to move HIMEM downward and store the data above it.  (Actually, there are
other ways too, such as storing the data at $300, but most such methods
are only useful for small amounts of data.)

If you're using DOS 3.3, both methods are about equally easy.  Just move
the appropriate pointer (preferably at the beginning of your program,
before defining any variables), and stuff your data in the resulting free
space.

If you're using ProDOS, I recommend hiding your data under LOMEM.  Hiding
data above HIMEM is possible, but not as easy--ProDOS requires that HIMEM
be an exact multiple of 256, and you need to set HIMEM at least 1024 bytes
lower than the beginning of your data, because ProDOS uses the first 1024
bytes above HIMEM as a general-purpose buffer.

The following pointers contain information that may be useful:

    PEEK(103)+256*PEEK(104) returns the starting address of the Applesoft
                            program.  The usual value is 2049.
    PEEK(175)+256*PEEK(176) returns the ending address of the Applesoft
                            program.
    PEEK(105)+256*PEEK(106) returns the current value of LOMEM.
    PEEK(109)+256*PEEK(110) returns the highest memory location currently
                            used by simple variables and arrays.
    PEEK(111)+256*PEEK(112) returns the lowest memory location currently
                            used by strings.
    PEEK(115)+256*PEEK(116) returns the current value of HIMEM.

     |          |
     |   DOS    |
     +----------+  <--- HIMEM (usually 38400)
     |  strings |
     |  |       |
     |  |       |
     |  v       |
     +----------+  <--- PEEK(111)+256*PEEK(112)
     |  usused  |
     |  space   |
     |          |
     +----------+  <--- PEEK(109)+256*PEEK(110)
     | ^        |
     | |        |
     | |        |
     | vars and |
     | arrays   |
     +----------+  <--- LOMEM
     | tokenized|  <--- PEEK(175)+256*PEEK(176)
     | program  |
     +----------+  <--- PEEK(103)+256*PEEK(104) (usually 2049)

There are a few more points to beware of.

     * Moving HIMEM wipes out your strings.
     * Moving LOMEM can wipe out some of your variables.
     * The LOMEM: command can only move LOMEM upward--if you try to move it
       downward, you get an ?OUT OF MEMORY ERROR.  If you need to move LOMEM
       downward, you'll have to POKE the new value directly into locations 105
       and 106.
     * LOMEM must always be less than HIMEM.

               - Neil Parker
--
Neil Parker                 No cute ASCII art...no cute quote...no cute
nparker@cie-2.uoregon.edu   disclaimer...no deposit, no return...
nparker@cie.uoregon.edu     (This space intentionally left blank:           )