Fixes#1054.
Previously, bit-fields followed by another field were aligned
to two bytes. Bit-fields ending the struct were (and continue
to be) aligned only to a single byte.
```
struct s {
unsigned int x : 4;
};
struct t {
unsigned int x : 4;
unsigned int y;
};
```
Before: `sizeof(struct s) == 1`, sizeof(struct t) == 4`
After: `sizeof(struct s) == 1` sizeof(struct t) == 3`
The driver requires a special linker configuration: "vic20-tgi.cfg".
The VIC-20 computer needs at least 8K of expansion RAM!
"tgidemo.c" needed to be adjusted because the VIC-20's vertical (y) range is greater than its horizontal (x) range -- the opposite of most other platforms. Also, the circle demo would jam on the VIC-20.
Use different .out files for different options / targets.
This allows make -j N to work.
Previously all test.*.*.prgs would use the same test.out file.
Now test.*.*.out is also used.
This prepares for #1058, which will pad bit-fields only to
the next byte, instead of the next sizeof(int) (two bytes).
OutputBitFieldData now outputs chars instead of ints, and
calls to this function loop until there is less than one byte
to output. A final partial byte is written out with zero padding
as a final partial int was previously.
* Allow overlap of bit-field storage units
Previously,
struct s {
unsigned int x : 10;
unsigned int y : 10;
};
had sizeof(struct s) == 4.
With this change, allow the storage units of x and y to overlap,
so sizeof(struct s) == 3, with y stored immediately after x,
with no padding between them.
An int bit-field (the only type currently supported) will still
never occupy more than two bytes.
* ParseStructInit: Fix typo and expand comment
Explain why there are at most 30, not 32 bits.
* ParseStructDecl: Rewrite AddBitFieldCall
No behavior change.
Co-authored-by: Jesse Rosenstock <jmr@users.noreply.github.com>
Explicitly use `signed char` or `unsigned char`, rather than
```
signed char k;
char k;
signed char k;
char k;
```
This should have resulted in the same thing; however, note that
`REFCC` was never defined, and `common.h` was not included, so
the old code in fact tested `char` then `unsigned char`,
which are the same.
The only difference is that a switch using plain `char` is not
tested, but since this is the same as either `signed char` or
`unsigned char`, the lack of test coverage seems relatively safe.
The implementation is a bit tricky as it requires to take different code paths for the //e, the //c and the IIgs. Additionally the //c only provides a VBL IRQ flag supposed to be used by an IRQ handler to determine what triggered the IRQ. However, masking IRQs on the CPU, activating the VBL IRQ, clearing any pending VBL IRQs and then polling for the IRQ flag does the trick.