Paint Relocatable Code
Andy S (2979) 504 posts |
Another obscure question about Paint’s source, I’m afraid. static const unsigned int hardmode_defpal [] = /* default palette for 256 colour modes */ { 0, /* 0000 */ 0x10101000, /* 0001 */ 0x20202000, /* 0010 */ 0x30303000, /* 0011 */ 0x00004000, /* 0100 */ 0x10105000, /* 0101 */ 0x20206000, /* 0110 */ 0x30307000, /* 0111 */ 0x40000000, /* 1000 */ 0x50101000, /* 1001 */ 0x60202000, /* 1010 */ 0x70303000, /* 1011 */ 0x40004000, /* 1100 */ 0x50105000, /* 1101 */ 0x60206000, /* 1110 */ 0x70307000 /* 1111 */ }; static const unsigned int black_and_white [] = { 0, /* black */ 0xFFFFFF00 /* white */ }; static const unsigned int fourcolourpal [] = { 0, /* black */ 0xFF00, /* red */ 0xFFFF00, /* yellow */ 0xFFFFFF00 /* white */ }; int *psprite_std_palettes [2] [4]; static void init_palettes (void) { /* Required to generate relocatable code */ ftracef0 ("init_palettes\n"); psprite_std_palettes [0] [0] = twowimp_colours; psprite_std_palettes [0] [1] = fourwimp_colours; psprite_std_palettes [0] [2] = wimp_colours; psprite_std_palettes [0] [3] = (int *)hardmode_defpal; psprite_std_palettes [1] [0] = (int *)black_and_white; psprite_std_palettes [1] [1] = (int *)fourcolourpal; psprite_std_palettes [1] [2] = (int *)modesixteen; psprite_std_palettes [1] [3] = (int *)hardmode_defpal; } In the function init_palettes(), why does the comment say it is “required to generate relocatable code”? The requirements for relocatable code are sadly outside my area of expertise. Presumably hard-coded memory addresses are forbidden and I wonder about self-modifying code. I started reading some of the RISC OS docs on writing relocatable modules but am still none the wiser. What precisely is special about the way those palette lookup tables are being initialised to make it necessary for relocatable code? I ask because I’m about to write the artist friendly palette stuff and I don’t want to inadvertently write illicit code for it! |
Jeffrey Lee (213) 6048 posts |
As far as I know it should be fine to statically initialise psprite_std_palettes. The compiler should generate the necessary relocation code to fix up the pointers prior to the main code starting. Paint and the other ROM apps are a bit special, in that they use ModuleWrap rather than CMHG. I’m not an expert on ModuleWrap, but I don’t think it does anything that a standard CMHG module couldn’t also do. So it wouldn’t surprise me if the ROM apps were created before CMHG was, and the early version of ModuleWrap they used (or the compiler in general?) might not have supported position-independent code to a sufficient enough degree to allow static initialisation to be used. |
Andy S (2979) 504 posts |
That’s reassuring, thanks. If they were doing it to avoid static initialisation, surely the arrays they’re copying in (hardmode_defpal, black_and_white,..) are statically initialised. Is the difference that they’re declared const but the psprite_std_palettes array is writable? |
Jeffrey Lee (213) 6048 posts |
I think it’s down to the fact that psprite_std_palettes contains pointers (which will need relocating), while the others do not. init_palettes has the luxury of being code, so it can calculate the addresses of twowimp_colours, fourwimp_colours, etc. however the compiler sees fit (e.g. it could use ADR if the data is near enough, or it could combine a compile-time address offset with a runtime relocation offset – essentially the same way that assembler modules typically access their workspace relative to R12). For psprite_init_palettes to be statically initialised, the compiler relies on a |