blob: fd07dc0cd3b645c9bdfcb47a16a89e9eacc4dc40 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/* bug-3255.c
For z80, a read from a pointer overwrote register a that was in use for a local variable.
*/
#include <testfwk.h>
// Based on code by "Under4Mhz" licensed under GPL 2.0 or later
#include <stdint.h>
#if !(defined(__SDCC_mcs51) && defined(__SDCC_MODEL_SMALL)) && !defined(__SDCC_pdk14) // Lack of memory
static volatile uint8_t VDPControlPort;
static volatile uint8_t VDPDataPortOut;
#define BYTE_HI(x) ((x)>>8)
#define VDU_ADDRESS_SET_MASK 0x4000
void vdu_stop() {}
#define vdu_next_set_fast(value) VDPDataPortOut = value
#define vdu_address_set_unsafe(address) { VDPControlPort=address; VDPControlPort=BYTE_HI((address) | VDU_ADDRESS_SET_MASK ); }
#define for8( var, size ) for ( unsigned char var = 0; var < size; var++ )
typedef uint8_t u8;
typedef uint16_t u16;
#define MAX_TILES 24
typedef struct {
u16 address;
u8 size;
u8 tile[2];
} GameTile;
typedef struct {
GameTile tiles[MAX_TILES];
u8 size;
} GameTileState;
GameTileState gameTiles = { .size = 2, .tiles = { { 1, 2, { 2, 3 } }, { 6, 2, { 7, 8 } } } };
int p(int i)
{
ASSERT (i == 2);
}
void GameTileCallback() {
vdu_stop();
GameTile *gameTile = gameTiles.tiles;
for8( id, gameTiles.size ) {
vdu_address_set_unsafe( gameTile->address );
u8 *ptr = gameTile->tile;
u8 size; size = gameTile->size;
do {
vdu_next_set_fast( *ptr++ ); // Pointer read here overwrote size, which was allocated to register a.
} while ( --size );
p (ptr - gameTile->tile);
gameTile++;
}
gameTiles.size = 0;
}
#endif
void
testBug(void) {
#if !(defined(__SDCC_mcs51) && defined(__SDCC_MODEL_SMALL)) && !defined(__SDCC_pdk14) // Lack of memory
GameTileCallback();
#endif
}
|