[comp.sys.atari.st] Problem doing screen dump

braner@batcomputer.tn.cornell.edu (braner) (01/18/87)

[]

I'm trying to write a RAM-resident program, activated by the screen-dump
vector at $502, to dump the screen in DEGAS format to a prepared space
in RAM.  Here is the basic code:

	LEA	space(PC),A1
	MOVE.B	0xFF8260,D0	/* video resolution		*/
	ANDI.W	#3,D0
	MOVE.W	D0,(A1)+
	MOVE.L	#0xFF8240,A0	/* palette			*/
	MOVE.W	#15,D0
dopal:	MOVE.W	(A0)+,(A1)+
	DBF	D0,dopal
	CLR.L	D0
	MOVE.B	0xFF8201,D0	/* video address		*/
	LSL.W	#8,D0
	MOVE.B	0xFF8203,D0
	LSL.L	#8,D0
	MOVE.L	D0,A0
	MOVE.W	#15999,D0
domap:	MOVE.W	(A0)+,(A1)+	/* <<<<<<<<<< BIG PROBLEM!!!!!	*/
	DBF	D0,domap

After installing the program, and then pressing Alt-Help (from the desktop),
everything looks OK, until I try to click on something on the desktop:
  BOOM! - fiery crash!

Checks I've done:  The address calculated for A0 IS the screen address,
there IS enough space at 'space', and there is no problem if the 15999
is reduced to, say, 100.

HELP!

- Moshe Braner

braner@batcomputer.tn.cornell.edu (braner) (01/18/87)

[]

WARNING: BUCKET is flawed.  Don't use it until you read what follows.

As usual, mysterious problems are caused by undocumented features of TOS.
(The following IS known to many, but I couldn't find it in the Megamax
nor the 'ST Internals' documentation for Ptermres()!)

The Ptermres() function (GEMDOS $31) cannot leave your program with more
memory than it already has.  When executed, a program is given all of free
RAM (the TPA, Transient Program Area, roughly the RAM area which is bounded
below by the resident programs and above by the default screen RAM area.)
If your program does a Setblock() call (GEMDOS $4A), releasing most of the
TPA back to TOS (as programs are supposed to do), an later exit via
Ptermres() asking more than what's left is ineffective.  You will not notice
any problem for a while, whether because your resident code doesn't yet
write over all that RAM, or because no other program is executed.  But it's
a time bomb.

The solution is to keep, in Setblock(), all the RAM you might want to keep
resident later.  Alternatively, if your program is not a GEM program (i.e.
no desk accessories will be invoked until the Ptermres()) you can skip
Setblock() altogether.  But what can you do if you're writing the program
using a compiler that includes the Setblock() call automatically?

To fix BUCKET you have to use a debugger.   Look, near the beginning of the
executable BUCKET.TOS, for the code fragment:

	move	#$4A,-(sp)
	trap	#1

and overwrite the 'trap #1' with a 'nop'.  That will avoid the Setblock()
altogether.  (Alternatively, look a few lines above that for the calculation
of the amount to keep, and change it.  In a program compiled with Megamax C,
for example, look for 'add.l #$2100,d0'.  That's Megamax adding space for an
8K stack.  Increase that amount by as much as you need.)

I am now working on an improved version of BUCKET (to be called BARREL),
avoiding that problem and adding features such as screen-dumps to RAM and
built-in SCODE-ing.  (If you were wondering why BUCKET doesn't capture
Alt-Help screen dumps, it's because the ROM screen-dump code manipulates
the printer port directly, not via the BIOS trap.)  Suggestions on what
should be done in BUCKET (or on how to solve the Setblock() problem without
resorting to post-compilation patching) are welcome.

- Moshe Braner

apratt@atari.UUCP (Allan Pratt) (01/20/87)

> As usual, mysterious problems are caused by undocumented features of TOS.
> (The following IS known to many, but I couldn't find it in the Megamax
> nor the 'ST Internals' documentation for Ptermres()!)
> 
> The Ptermres() function (GEMDOS $31) cannot leave your program with more
> memory than it already has.

Please don't blast Atari for not belaboring the obvious: when you
don't own memory (i.e. when you gave it up with a Mshrink (Setblock?)
call), it's not yours to "keep" with a Ptermres() call.  It belongs to
the system, not to you.

If your compiler provides only one startup module, and doesn't provide
source to it, it is an incomplete compiler.  The Atari compiler comes
with source to the startup (GEMSTART), and (now) it is trivial to
choose a memory model for a given application.  Desk accessories need
to do no Mshrink call at all (they don't get all of memory to begin
with), GEM programs need to return only about 8K to the OS, and TSR
programs should do their shrinking at Ptermres() time, not startup
time.  Furthermore, programs which Pexec() other programs should
shrink down to only as much as they need (possbly half or 1/4 of
available memory), to leave room for their children.  All these
options are easily available in the configurable GEMDOS which I
wrote when I came to Atari last July.

/----------------------------------------------\
| Opinions expressed above do not necessarily  |  -- Allan Pratt, Atari Corp.
| reflect those of Atari Corp. or anyone else. |     ...lll-lcc!atari!apratt
\----------------------------------------------/