Author Topic: Available memory range in a binary loader  (Read 399 times)

0 Members and 1 Guest are viewing this topic.

Offline cpcitor

  • The user previously known as FindYWay
  • CPC6128
  • ****
  • Posts: 289
  • Country: fr
  • My heart still runs on traditional CPC.
    • My code for the CPC.
  • Liked: 142
  • Likes Given: 351
Available memory range in a binary loader
« on: 11:35, 25 May 20 »
TL;DR: in a binary program run"foo.bin, what memory range can we write without causing any trouble to the firmware?

On run"foo.bin the firmware calls MC START PROGRAM. The firmware doc Soft968 covers it in:

  • chapter 15 entries "177: MC BOOT PROGRAM" and "178: MC START PROGRAM" which describes in/out conditions
  • paragraph "13.3 Loading and Running Programs."
  • and "9.8 Store requirements"

Question: how to know the maximum address that we as a binary program can write to? (As a use case, one can imagine for example handling a pool of dynamically allocatable memory, as big as possible). How high can we write to RAM after a MC START PROGRAM of MC BOOT PROGRAM without problem?

Preferred answers use code that is exactly the same on all Amstrad versions (avoid "if 464 then, if 6128 then...").

There are some similarities with Dynamic memory allocation in an RSX but it would be best to keep things as simple as possible.
« Last Edit: 13:34, 25 May 20 by cpcitor »
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC.

Offline cpcitor

  • The user previously known as FindYWay
  • CPC6128
  • ****
  • Posts: 289
  • Country: fr
  • My heart still runs on traditional CPC.
    • My code for the CPC.
  • Liked: 142
  • Likes Given: 351
Re: Memory limit on loading programs
« Reply #1 on: 11:50, 25 May 20 »
Oops, hit "post" before it was ready. Now edited.

Soft968 section 13 read:

Quote
Before this load routine is called as much of
the firmware as is possible is reset so that the are of memory between #0040 and
the base of the firmware RAM at #B100 is available for use.

B100 seems extremely high.

Besides, this is before firmware uses the disc drive to actually load the program. That requires memory in the A67B-AF00 range.

So B100 does not seem like a plausible answer.

A program loaded which: run"foo.bin, once started, can write memory, which range without messing up the firmware?

Thanks for hints.
« Last Edit: 13:42, 25 May 20 by cpcitor »
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC.

Offline Urusergi

  • CPC6128
  • ****
  • Posts: 205
  • Country: es
  • Liked: 346
  • Likes Given: 1352
Re: Available memory range in a binary loader
« Reply #2 on: 16:17, 25 May 20 »
If you have a self-executing binary file the lower limit is &40

and to know the maximum limit:
PRINT HEX$(HIMEM)

Offline cpcitor

  • The user previously known as FindYWay
  • CPC6128
  • ****
  • Posts: 289
  • Country: fr
  • My heart still runs on traditional CPC.
    • My code for the CPC.
  • Liked: 142
  • Likes Given: 351
Re: Available memory range in a binary loader
« Reply #3 on: 20:33, 25 May 20 »
If you have a self-executing binary file the lower limit is &40

and to know the maximum limit:
PRINT HEX$(HIMEM)

I considered the BASIC variable "HIMEM", or ways to get it from ASM (sadly have to check for CPC model first). But it is only one of the many variables that is somehow related but does not seem appropriate.

Inside the self-executing binary things are different, aren't they? The firmware has already reset everything.

Also, re-enabling the AMSDOS ROM will reserve some more memory. How to get the new value?
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC.

Offline cpcitor

  • The user previously known as FindYWay
  • CPC6128
  • ****
  • Posts: 289
  • Country: fr
  • My heart still runs on traditional CPC.
    • My code for the CPC.
  • Liked: 142
  • Likes Given: 351
Re: Available memory range in a binary loader
« Reply #4 on: 20:58, 25 May 20 »
Some hints. TL;DR: it looks like it is 0x0040-0xB100 indeed.

There are some hints in firmware documentation Soft968 section "9 AMSDOS" part "9.8 Store requirements"

Quote
9.8 Store requirements

When initialized AMSDOS reserves #500 bytes of memory from the memory pool and
the kernel reserves another 4 for its external command chaining information.
When loading a machine code program from disc into store using the AMSDOS routine
CAS IN DIRECT it is important that AMSDOS's variables are not overwritten. This
presents a problem since in general it is not possible to discover where these variables
are! This is because variables for expansion ROMs are allocated dynamically. Note that
this problem does not arise when loading from the cassette since the cassette manager's
variables are in the firmware variable area.

So a problem is acknowledged.

Indeed, BASIC reports HIMEM=43903 on a CPC464 without AMSDOS, and 42619 on a CPC464 with AMSDOS (that one I remember).
0x500 + 4 = 0x504 = 1284 = 43903 - 42619.

42619 = 0xA67B
43903 = 0xAB7F

Quote
AMSDOS reserves store from the top of the memory pool so the simplest solution is to
always load machine code programs into the bottom of store. The program can then
relocate itself to a higher address if required.

Incidentally that's kind of what my program already does. It loads compressed data (well below the limit), then uncompresses them to RAM.
I only would like to know how to check what limit is safe. Else I experience strange bugs when my program grows. A clear criterion would be appreciated.

Quote
Alternatively the machine code program could be loaded in two stages: first load and
run a small loader in the bottom of store. The action of MC BOOT PROGRAM will
have shut down all RSXs and extension ROMs. The loader program should now
initialize AMSDOS using KL INIT BACK thus forcing AMSDOS variables to be
wherever you so wish.

It is interesting to know that AMSDOS firmware could have its data relocated. Indeed KL INIT BACK does that. It even returns information about the exact area actually used, which is good.

It is interesting in scenarios like enabling AMSDOS only at times, and reclaiming memory at other times. There are areas in RAM that are not always needed, e.g. secondary screen buffer.

This is nice but does not tell how to get the actual upper address limit.

Quote
The loader can now load the machine code program using the
AMSDOS routines CAS IN OPEN, CAS IN DIRECT, and CAS IN CLOSE together
with MC START PROGRAM.

This suggests that firmware has to be reinitialized after loading. Mkay.

Quote
In order to initialize AMSDOS using KL INIT BACK, AMSDOS's ROM number is
required. To determine AMSDOS's ROM number look at any of the intercepted cassette
jumpblock entries with the DISC routines selected. Each entry is a far call, the address
part of which points at a three byte far address, the third part of the far address is the
ROM number. Obviously this should be done before AMSDOS is shut done.

Ah! This is convoluted, and again forbids that the initial loader is a self-executable binary.

Quote
Existing machine code programs, developed on cassette systems without any expansion
ROMs, frequently only use store to #ABFF in order to avoid BASICs variables. These
can easily be modified to use AMSDOS. Write some machine code to initialize
AMSDOS using KL INIT BACK. AMSDOS will reserve RAM down to #ABFC,
almost the same as used by BASIC.

At last a hint. This suggests that the upper limit is above 0xABFF (44031).

If after AMSDOS eats 0x504 bytes, the remaining ceiling is 0xABFC, then the initial limit is 0xABFC + 0x504 = 0xB100 .

This seems to confirm that right after MC START PROGRAM or MC BOOT PROGRAM, upper limit is 0xB100, a number mentioned in documentation of MC BOOT PROGRAM, but as an area available during program load.

Quote
This process ensures that no memory outside
the firmware variables area is in use when loading the program.
...
The routine run to load the program is free to use any store from #0040 up to the base
of the firmware variables area (#B100).

Incidentally, this looks fine when loading through totally independent means, not for loading using disc firmware which is obviously shut off.
« Last Edit: 21:10, 25 May 20 by cpcitor »
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC.

Offline andycadley

  • Supporter
  • 6128 Plus
  • *
  • Posts: 899
  • Liked: 432
  • Likes Given: 72
Re: Available memory range in a binary loader
« Reply #5 on: 21:04, 25 May 20 »
I considered the BASIC variable "HIMEM", or ways to get it from ASM (sadly have to check for CPC model first). But it is only one of the many variables that is somehow related but does not seem appropriate.

Inside the self-executing binary things are different, aren't they? The firmware has already reset everything.

Also, re-enabling the AMSDOS ROM will reserve some more memory. How to get the new value?


It's one of the return conditions from KL INIT BACK