1
0
mirror of https://github.com/KarolS/millfork.git synced 2026-04-20 18:16:35 +00:00

Allow initializing writable variables on cartridge targets

This commit is contained in:
Karol Stasiak
2019-06-28 16:28:49 +02:00
parent 7f28a6b10f
commit 674f8d1983
22 changed files with 436 additions and 107 deletions
+4 -2
View File
@@ -67,8 +67,6 @@ Default: the same as `encoding`.
* `emit_z80` whether the compiler should emit Zilog Z80 instructions not covered by `emit_x80`, default is `true` on compatible processors and `false` elsewhere
* `ro_arrays` (deprecated) whether the compiler should warn upon array writes, default is `false`
* `prevent_jmp_indirect_bug` whether the compiler should try to avoid the indirect JMP bug,
default is `false` on 65C02-compatible or non-6502 processors and `true` elsewhere
@@ -132,6 +130,10 @@ Default: `default`. In all options below, `NAME` refers to a segment name.
Note that the default segment for uninitialized arrays and variables is always `default`.
Default: `default`
* `ram_init_segment` the segment storing a copy of initial values for preinitialized writable arrays and variables.
The segment cannot be `default`. See [the ROM vs RAM guide](./rom-vs-ram.md) for more information.
Default: none.
* `segment_NAME_start` the first address used for automatic allocation in the segment.
Note that on 6502-like targets, the `default` segment shouldn't start before $200, as the $0-$1FF range is reserved for the zeropage and the stack.
The `main` function will be placed as close to the beginning of its segment as possible, but not necessarily at `segment_NAME_start`
+49
View File
@@ -0,0 +1,49 @@
[< back to index](../index.md)
### ROM vs RAM targets
By default, Millfork assumes that the target platform loads the program into RAM.
Code, read-only data and preinitialized writable data are all mixed together.
The program after loading can modify its contents, including preinitialized variables,
almost immediately and without any extra preparation.
When compiling for a cartridge based target, the preinitialized data cannot be writable,
as they are not loaded into RAM, but stored in ROM.
To make working with preinitialized data easier,
Millfork can create a copy of preinitialized writable date in ROM,
which can then be loaded into RAM when the program starts.
The steps are as follows:
* Add the `ram_init_segment=SEGMENT` option to the `[allocation]` section in your platform definition file,
where `SEGMENT` is the ROM segment that will store the initial values.
* Near the beginning of your program, call the `init_rw_memory` function.
It is imported automatically, you don't need to add any import statements.
If you are targeting both RAM-based and ROM-based platforms, wrap the call in `#if INIT_RW_MEMORY`...`#endif`,
as the `init_rw_memory` function is not available for RAM-based targets. For example:
void main() {
#if INIT_RW_MEMORY
// do a bankswitch to the SEGMENT segment if applicable
init_rw_memory()
#endif
// ... rest of the code
}
If the default implementation of `init_rw_memory` is unsatisfactory for your needs,
consider implementing your own and putting it in the `init_rw_memory` module
in the same directory as your main source file, to override the standard one.
Using the `ram_init_segment` option adds the following restrictions:
* Preinitialized writable variables and arrays can be put only in the `default` segment.
* Preinitialized writable variables and arrays cannot be given a fixed address.
* On 6502-based targets, the zeropage pseudoregister has to have size of at least 4,
unless the size of the `default` segment is 256 bytes or less (out of currently supported targets, only Atari 2600 has such small RAM),
which uses a different, smaller and faster implementation of `init_rw_memory` that doesn't require a zeropage pseudoregister.
You can force the compiler to use this smaller implementation by adding a preprocessor feature `TINY_RW_MEMORY = 1`.
It works only if the total size of writable memory to initialize is 255 bytes or less.
+3 -3
View File
@@ -9,6 +9,9 @@ but it may be expanded to support other 6502-based and Z80-based platforms in th
To add a custom platform yourself, see [the custom platform adding guide](./custom-platform.md).
If you are compiling for a cartridge-based target,
you need to take special precautions; see [the ROM vs RAM guide](./rom-vs-ram.md)
## Supported platforms
The following platforms are currently supported:
@@ -92,6 +95,3 @@ The compiler emits COM files.
* `dos_com` a COM file for DOS on IBM PC. (very experimental)
The primary and most tested platform is Commodore 64.
Currently, targets that assume that the program will be loaded from disk or tape are better tested.
Cartridge targets may exhibit unexpected bugs.