MSX-DOS TPA Question

Page 1/2
| 2

By ericb59

Paladin (797)

ericb59's picture

19-12-2018, 15:08

I don't understand this sentence from grauw.nl

"A transient program will be loaded at address 0100h, the start of the TPA (Transient Program Area), and is CALLed by MSX-DOS with the stack pointer set to the end of the TPA. If the stack pointer points to that location, as much RAM as possible can be used as the stack."

Is the Stack inside the TPA zone ? Or is the stack outside the TPA zone ?
And what is the length of the stack ?


Thanks ... for your lights ...

Login or register to post comments

By konamiman

Paladin (995)

konamiman's picture

19-12-2018, 17:34

Quote:

Is the Stack inside the TPA zone ? Or is the stack outside the TPA zone ?

Let's experiment to find out!

First, let's create this little evil program named HANG.COM:

     org 100h
     di
lol: jr lol

Let's boot MSX-DOS in an emulator, let's run that program and... oh noes, the computer got hung! Who would have imagined??

But, let's now open the emulator's debugger and take a look at a couple of things:

- Address stored at 0006h (end of TPA): D606h
- Value of SP (stack pointer): D5D1h

So, the veredict is: the stack is inside the TPA. In fact, it's at the end of the TPA minus 35 bytes (because you need to be able to end your program with a simple RET, and this will give control back to COMMAND.COM, which in turn must have pushed a few things in the stack). And this makes perfect sense as soon as we look at the following point:

Quote:

And what is the length of the stack ?

What's the length of a stack of cards? Depends on how many cards you put on it, right?

It's the same with the Z80 stack. It doesn't have any predefined size, it just has the items you have pushed (via direct PUSH instruction or CALL) minus the items you have popped (via direct POP instruction or RET). The stack pointer is decreased by two every time you push and increased by two every time you pop, in a neverending magical dance.

(Well... neverending in theory. If you push too many things, your stack pointer will go too low, the stack will overwrite your program or your data, and probably your MSX won't be very happy about that)

Now, see why the stack must be inside the TPA? There's no way for MSX-DOS to know how much stack space you will need, and so it can't allocate such space. So the only option is to put the stack pointer in TPA, as close as possible to its end, and hope that your code will be wise enough to not allow it to grow too much.

Does that make sense?

By RetroTechie

Paragon (1475)

RetroTechie's picture

19-12-2018, 18:05

Transient program = .COM file containing executable Z80 code (and probably some data, graphics or whatever).

This is loaded at 0100h, so it occupies 0100h...0100h + size of your .COM file (-1).
So on entry, Z80's SP register register points to [occupied space beyond what you can use]. When CALLing or PUSHing things, the stack grows downward from there in 2-byte increments. Free space (that you could use as stack space) is everything between there and where the binary of your .COM file ends. So [SP on entry] minus 0100h minus [size of your .COM binary].

So in that context, there isn't a fixed size limit to the stack. It's only limited by how much MSX-DOS itself occupies in the top of memory, how big your .COM file is, and what else you use empty space in between for. And how many nested CALLs & PUSHes you do... Wink

By Grauw

Enlighted (7840)

Grauw's picture

19-12-2018, 18:38

Note thar the exact amount of TPA space is not fixed. It may depend on DOS version and nr. of drives and whether you run from a batchfile.

In my code I do a check on start-up if the stack is more than a certain amount past the end of the memory my program uses. If it's less than 100H apart, I deem it "not enough" and terminate with an error.

By ericb59

Paladin (797)

ericb59's picture

19-12-2018, 20:45

Ok I understood very well.

Just two questions, where can I read SP (Stack Pointer adress ?)

Second :
In context of C programing, what is the best solution to store data and variable ?
- Let the compiler and system do its job

     unsigned char map2[27][32];
 

or

- take the control and set variable at specific adresses ?

    unsigned char __at(0x8000) map2[27][32];
 

(I'm afraid of stack growing to much !)

By Pencioner

Paladin (842)

Pencioner's picture

19-12-2018, 20:58

Generally speaking it is always good idea to let the compiler do the job. But, if you want f.e. switch pages via memory mapper to copy some stuff to device in different slot or vice versa, then you might need to have the control over exact location address. I think then you have to make some assertion code which checks if the stack is not too close to that area (say, SP minus some margin, f.e. 0x200 >= 0x8000 + 27 * 32) and exit if the assertion fails (same as @Grauw do in his code btw)

By ericb59

Paladin (797)

ericb59's picture

19-12-2018, 21:05

@pencloner OK it make sense. Where can read the SP ?

By Pencioner

Paladin (842)

Pencioner's picture

19-12-2018, 21:15

it is possible only with asm:

LD HL, SP
LD (some_var_addr), HL

By Grauw

Enlighted (7840)

Grauw's picture

19-12-2018, 23:11

The assertion is not very important though unless your program is large and close to the TPA limit. In C I really just wouldn’t bother with it.

By ericb59

Paladin (797)

ericb59's picture

20-12-2018, 06:42

Grauw wrote:

The assertion is not very important though unless your program is large and close to the TPA limit. In C I really just wouldn’t bother with it.

Sure, but his is the case... I have a large program, and more I add things inside, more there are bugs. thus i think the code is overlapped by the stack.

By ARTRAG

Enlighted (6083)

ARTRAG's picture

20-12-2018, 08:19

In order to reduce the amount of ram used you could try to use unions to reuse the same ram in different functions
https://www.tutorialspoint.com/cprogramming/c_unions.htm

Page 1/2
| 2
My MSX profile