Summary: This application note describes a small problem in the SEGA C compiler by Paul Lee, and shows an easy "work around" for it. Probably the easiest way to explain the problem is with an example. Here's a very small example program, made by stripping demo6.c. - - - - - begin showbug.c - - - - - #include "genesis.h" ulong tiledata[] = { 0x00000008, /* tile #0 = slash character */ 0x00000080, 0x00000800, 0x00008000, 0x00080000, 0x00800000, 0x08000000, 0x80000000, }; /* * Variables... */ ulong vtimer; /* VBL timer, incremented by ISR in sega.s */ /* * Main program */ void main() { } - - - - - end showbug.c - - - - - If you compile this with the SEGA C compiler, you'll get the following: - - - - - begin showbug.s - - - - - .data .globl _tiledata _tiledata: .dc.l 8 .dc.l 128 .dc.l 2048 .dc.l -32768 .dc.l 524288 .dc.l 8388608 .dc.l 134217728 .dc.l -2147483648 .bss .globl _vtimer .comm _vtimer,4 .text .globl _main _main: bra L1 L0: L2: unlk a6 rts L1: link a6,#-0 bra L0 .data - - - - - end showbug.s - - - - - If you look at the generated "tiledata" values, you'll notice that the fourth and eight values are incorrect (negative). If you tried to use values 0x8000 through 0xffff in demo6.c (demo6.c comes with the compiler) you will get an unwanted "stripe" in your tile. Instead of .......O ......O. .....O.. ....O... ...O.... ..O..... .O...... O....... you'll see .......O ......O. .....O.. OOOOO... ...O.... ..O..... .O...... O....... (I discovered this while working on tiles for my game "moonbase".) Basically, the compiler is incorrectly computing the TYPE of the constants, based upon their VALUE. While reading through the source code to the compiler (in hopes of finding a quick fix) I came up with a "work around" for the problem. The compiler isn't smart enough to use the variable type specified in the array declaration, BUT you can explicitly tell it the correct type using suffix characters. - - - - - begin showfix.c - - - - - #include "genesis.h" ulong tiledata[] = { 0x00000008UL, /* tile #0 = slash character */ 0x00000080UL, 0x00000800UL, 0x00008000UL, 0x00080000UL, 0x00800000UL, 0x08000000UL, 0x80000000UL, }; /* * Variables... */ ulong vtimer; /* VBL timer, incremented by ISR in sega.s */ /* * Main program */ void main() { } - - - - - end showfix.c - - - - - The change from the previous version is the "UL" suffix characters. - - - - - begin showfix.s - - - - - .data .globl _tiledata _tiledata: .dc.l 8 .dc.l 128 .dc.l 2048 .dc.l 32768 .dc.l 524288 .dc.l 8388608 .dc.l 134217728 .dc.l -2147483648 .bss .globl _vtimer .comm _vtimer,4 .text .globl _main _main: bra L1 L0: L2: unlk a6 rts L1: link a6,#-0 bra L0 .data - - - - - end showfix.s - - - - - As you can see, the generated code no longer has the bad value for the fourth array element. The eighth element is still negative, but that's harmless. Acknowledgements ---------------- I would like to thank Paul Lee (for releasing the SEGA C compiler in the first place), and Steven Fuller, for loaning me the source code so I could research this problem. Kevin Banks (kbanks@ro.com)