Reproducing below
a post by @swat
which is a treasure trove of information when it comes to memory addressing on Dreamcast.
I have a few follow up questions, but I presume many users will be uninterested by these technical details,
so it felt more appropriate in the "programmer" section.
(27.11.2020 07:42)SWAT писал(а): Loader memory usage:
params (1KB) + loader code (nKB) + buffer (32KB - params - loader). Max 32KB.
In best case, for buffer need 2KB (one sector). This buffer uses only for non-optimized images and little for CDDA (track name). So the loader should be less than 29KB.
In future this buffer I will made as *dynamic* too, but it's working not in all games yet.
Also loader uses additional memory (up to 32KB) for CDDA and/or CISO buffers.
For CDDA now supported dynamic, for CISO still not, it uses only hardcoded addresses.
And CDDA can use hardcoded addresses if dynamic disabled (not supported).
You can see here:
https://github.com/DC-SWAT/DreamShell/bl...?ts=4#L220
Application (KATANA game) memory usage:
Params: 0x8c000000 - 0x8c000100 (also here vectors for syscalls)
Syscalls: 0x8c000100 - 0x8c004000
Stack: 0x8c004000 - 0x8c00f400 (in some cases at 0x8d000000)
VBR: 0x8c00f400 - 0x8c010000 (in some cases in heap)
App binary: 0x8c010000 - ???
Heap: ??? - 0x8d000000
So we can place loader (and buffers) in the heap (carefully with stack if it's at the end) or at 0x8c000100 - 0x8c004000 because loader can emulate all syscalls.
Best choice it's a 0x8c004000, we don't touch original syscalls (just change some vectors) and don't conflict with game, because stack here is usually does not grow much and VBR code block is 3KB, so we should have ~ 32KB for free.
But some games can write in this memory area some "loaders" or stack grow so much and do damage loader code. So we should move loader at high memory (heap) and hopes we are lucky
First, thanks @swat for these details, it clarified so much.
Now, "of course", as a programmer understanding more generally means having new questions.
Many are probably well known by dreamcast programmers, and may seem basic to you, sorry in advance, they are just not obvious from a general programmer perspective with no specific knowledge of Dreamcast platform.
Цитата:b]Application (KATANA game) memory usage:[/b]
Params: 0x8c000000 - 0x8c000100 (also here vectors for syscalls)
(...)
Heap: ??? - 0x8d000000
These few lines are packed with information, much of which seems implied. So here are some questions:
- KATANA game : I presume it means games that use the KATANA game development kit from Sega. It's probably a majority of games, but it also means that games using a different toolkit and set of conventions can work quite differently when it comes to memory layout. For example, maybe Window CE games. And maybe also more modern production using KallistiOS ? Anyway, this merely helps to understand that this is not a "universal" design.
- Params: 0x8c000000 - 0x8c000100 : nit-picking here : this seems to represent 256 bytes ( < 1 KB). Still, likely large enough for parameters (I have no idea how much space "vectors for syscalls" is using, but that's probably irrelevant anyway)
- The entire memory design seems to imply an MMU-less scheme, where memory addresses are directly mapped to the physical RAM
- It seems to imply that 0x8c000000 is "address zero" ?
- The Dreamcast (normal) features 16 MB of RAM, or 0x1000000 in hexadecimal. In a direct addressing scheme, it seems it would go from 0x8c000000 to 0x8d000000. Yet, later in the list, 0x8d000000 is mentioned as a start (?) address for heap (and maybe sometimes for stack). This seems contradictory, unless heap allocation goes _down_ from 0x8d000000.
Цитата:Stack: 0x8c004000 - 0x8c00f400
This seems to represent a memory space of 64KB - 16 KB (syscalls) - 3 KB (VBR) = 45 KB .
What initially was unclear to me was "a stack space for _who_?", and I guess it means stack space for the KATANA program.
Цитата:So we can place loader (and buffers) (...)
Best choice it's a 0x8c004000, (...) because stack here is usually does not grow much and VBR code block is 3KB, so we should have ~ 32KB for free.
So the idea here is to "steal away" memory space from the stack, on the ground that it's not entirely used in most cases.
It implies that stack space growth _downward_, from 0x8c00f400 towards 0x8c004000.
I presume this is generally true : in such an environment, programmers should not "toy" with stack space limits, and keep the stack for very basic structures and variables, thus pushing any table or large structure into heap space instead. In the end, they may only need a handful for KB.
But by the very nature of this bet, it's a bit "random", meaning that some games use more stack than others, so some games will overwrite the loader during gameplay. So now it becomes a "by game" setting.
I guess it explains why 0x8c004000 is "generally fine", except in some cases.
It also explains why the loader should remain small, although I don't see any hard 32 KB limit here. It seems more like a rule of thumb : using 32 KB for the loader only leaves 13 KB for the game itself, so now it becomes more and more probable that the game will overwrite the loader during gameplay.
Is that a correct assessment ?