I want to learn MSX-C, where do I start?

Page 12/12
5 | 6 | 7 | 8 | 9 | 10 | 11 |

By Grauw

Ascended (10718)

Grauw's picture

28-08-2015, 20:18

You can use _DOSVER.

Why two executables? That seems to unnecessarily complicate things… Just do if/else in your library functions, or use a jump table if you want a bit higher performance. That’s pretty simple. The fallback implementation does not need to be fully-featured, just implementing ALL_SEG (primary mapper only) and PUT_PH should be enough in many cases.

p.s. I’ll elaborate a bit on MAP.COM… it modifies DOS2 to (illegally) attempt to read the mapper I/O ports in stead of using the internal mirrors, however it’s unreliable (on some machines and mappers bits are masked, or can’t be read at all). Also, it still does not prevent the reserved DOS2 segments from being overwritten. It’s a hack that does manage to make certain software run on certain configurations, but can’t be relied upon.

By DarkSchneider

Paladin (990)

DarkSchneider's picture

31-08-2015, 10:28

OK I see.

2 executables is because I thought than would be different ways to allocate RAM. I mean, even using DOS2, how do you know that changing a page it has no code running?. For DOS page switching, you need total control because are yourself changing the page with no asking, but in DOS2 I thought maybe with all the program made in C the program itself could handle it. In other words:
- When using DOS and direct I/O mappers: you use absolute addresses to handle where anything is placed by your own.
- When using DOS2 and its functions: I thought you could use only variables and malloc.
The code of both could be somewhat different, being the "normal" one the DOS2 and the specific one the DOS one.

I though something like, when using DOS2, "give me a 16KB block", and then using it as wanted. But, if you have code running at 4000-7fffH, and use PUT_PH into page 1, is not the code broken like when using the mappers directly?. In that case we need, like with DOS, to have total control about addresses, for both code and data.
If this is the case, then both codes are the same, simply changing how you get and put blocks/pages. For DOS we suppose that them are free, and for DOS2 we ask to DOS2 for them. A few function pointers.

Also, if I copy the range (0-100h) to another 16KB block, could I switch the page 0 to that block?

By Grauw

Ascended (10718)

Grauw's picture

31-08-2015, 16:25

DarkSchneider wrote:

If this is the case, then both codes are the same, simply changing how you get and put blocks/pages. For DOS we suppose that them are free, and for DOS2 we ask to DOS2 for them. A few function pointers.

Indeed!

The DOS2 mapper routines don’t do anything with C program placement and such. PUT_P2, for example, is just a very short routine which goes something like: PUT_P2: ld (mapper_page2_mirror),a / out (0FEH),a / ret. So, the only difference there compared to OUT-ing the value yourself is that it remembers the mapper segment number in an internal mirror variable. And the allocate keeps track of which segments are used by other programs and the system, so that you won’t use and overwrite a segment which is in use by another program.

How to make sure that C does not put program code in a certain memory region, I don’t know, maybe someone can answer that question. Otherwise, it may be better to only access the extra memory through block data copy routines, it’s slower but less hassle and safer. By the way, also consider the location of the stack.

DarkSchneider wrote:

Also, if I copy the range (0-100h) to another 16KB block, could I switch the page 0 to that block?

Think so, but I would avoid it unless necessary. Keeping interrupts disabled while switching and then enabling them after you’re done and switched it back seems a bit safer.

p.s. All the details about DOS2 mapper support routines are here.

By MicroTech

Champion (388)

MicroTech's picture

02-09-2015, 10:03

DarkSchneider wrote:

Also, if I copy the range (0-100h) to another 16KB block, could I switch the page 0 to that block?

Yes, I did and it worked (although does not seem to me a good practice).
Keep present that when you place your segment in page 0, also interrupts will use it (but you could bypass this using IM 2).

By pizzapower

Master (155)

pizzapower's picture

07-02-2023, 22:21

Grauw wrote:

How to make sure that C does not put program code in a certain memory region, I don’t know, maybe someone can answer that question. Otherwise, it may be better to only access the extra memory through block data copy routines, it’s slower but less hassle and safer. By the way, also consider the location of the stack.

If you want a more generic approach, you will probably need to write your own linker to do this kind of fine-tuning (of putting code at specific addresses), albeit a not very complex one. Unfortunately SDCC supports is limited to __banked modifiers. The __banked can be used to put code in specific pages (by defining their .area in the crt0 file), so you can put code in a page that will be swapped out. But if you'd like to run bigger executables (>54kb) to use the memory mapper properly, you will probably need some kind of overlay support (to put some of the code in separate 16k files). And the linker has to be able to create those overlay files as well. And it is the responsibility of the crt0 file to load them and put them in the right segment before main() starts.

Page 12/12
5 | 6 | 7 | 8 | 9 | 10 | 11 |