From: David Z. Maze <dmaze@donut.mit.edu>
Newsgroups: comp.sys.hp48
Subject: Re: 48gx and Ram Cards
Date: 15 Dec 1996 14:27:26 GMT
Organization: Massachvsetts Institvte of Technology

Robert McIntyre <rjmcinty@eos.ncsu.edu> wrote:
>         Why do some programs not work from a covered port?  (eg. Jazz, Java, 
> et al)  What is it that makes them not work, and will this be addressed in 
> upcoming releases?  My main reason for getting a ram card is the fact that my 
> user memory is so full of school stuff, UFL, Java, and soon Jazz, that I 
> barely have room to breathe.  So, I was HOPING to offload some of the libs 
> into port memory, and run them from there.  Any comments?

Everything in the HP runs in SysRPL, except for the parts in assembly.
Things like the stack are written entirely in SysRPL.  The problem is that
the HP's Saturn processor can only address one meganybble of memory.  In
the HP-48SX, the lower half of this consisted of the built-in ROM and the
32K internal memory; the upper half took two 128K RAM cards, so you could
execute programs from any port without a problem.

In the GX, though, the internal ROM fills up all of the lower 256K of "real"
memory (and then some...more on this later).  The next 128K consist of the
built-in memory, and the last 256K are Port 1.

      S/SX Memory Structure          G/GX Memory Structure
 00000 +----------------+             +----------------+ 0K
       |                |             |                |
       |    Built-in    |             |    Built-in    |
       |      ROM       |             |      ROM       |
       |                |             |                |
       |                |             |                |
       |                |             |                |
 70000 +----------------+ <- Built-in |                |
 80000 +----------------+     RAM     +----------------+ 256K
       |                |             |                |
       |     Port 1     |             |  Built-in RAM  |
       |                |             |                |
 C0000 +----------------+             +----------------+ 384K
       |                |             |                |
       |     Port 2     |             |     Port 1     |
       |                |             |                |
 FFFFF +----------------+             +----------------+ 512K

Okay, you say, where does port 2 go on the GX, then?  After all, it does have
two card slots.  This is where the "covered port" concept comes in.  Let's
say you try to execute a library object from Port 2 (3, 4, ...31).  The GX
ROM goes through the following steps:

-- Turn off port 1.
-- Make port 2 (or whatever) appear at C0000, where port 1 appeared before.
-- Copy the relevant object or part of a library object from port 2 to
     temporary memory.
-- Turn off port 2.
-- Turn on port 1 in the usual location.

The same procedure works for the extra parts of the G/GX ROM, such as
most of the =DoInputForm command, which runs all of the pretty pop-up
forms.  This isn't the fastest procedure in the world; if there's not
a port 1, the HP can leave other parts of the ROM semi-permanently mapped
into real memory.  This is what makes the HP-48G faster than the GX:
since there's only 32K of real memory, the G has 224K of visible memory
to store the "covered" ROM in.

This works well enough for most programs, and in particular programs
consisting of pure User/System RPL.  Problems can come up when a program
uses certain machine language constructions.  Some machine subroutines
allocate memory, such =PUSH#, which pushes a binary integer onto the stack.
If the memory allocation routines can't get enough memory, they perform a
"garbage collection," in which the HP goes through temporary memory and
throws away any objects that aren't used.  Since nothing points to our
code object, the garbage-collection routines throw it away.  When execution
returns to the machine-language code, it's not there, so the calculator
crashes.

This isn't a problem for most programs, though, because they don't live
in volatile temporary memory.  For example, programs living in user memory,
Port 0, or Port 1 can do essentially whatever they like from machine
code, since they'll never move (except in a couple of circumstances that
actually manipulate user memory; this code must be executed from port 0 or
1).  Programs in Port 2 have to worry about their future existence on
many seemingly harmless calls; many can't handle it.

I hope this answers your question...

 _____________________________
/                             \  "We can write all we know in 4 lines."
|          David Maze         |   -- Ray Ashoori, MIT Physics Professor
|         dmaze@mit.edu       |      1 + 1 = 3         6 * 9 = 42  
| http://donut.mit.edu/dmaze/ |        IHTFP         17 Yellow Pigs
\_____________________________/     ...the Institute is your friend...
