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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/* bug-2567.c
A bug resulting in overlapping spill locations in temporary variables.
*/
#include <testfwk.h>
#ifdef __SDCC
#pragma std_c99
#pragma disable_warning 85
#endif
#include <stdint.h>
#include <stdbool.h>
typedef uint16_t cv_vmemp;
#define TILE_SITE0 224
enum tools
{
TOOL_PATH_LR,
TOOL_PATH_UD,
TOOL_PATH_LU,
TOOL_PATH_UR,
TOOL_PATH_RD,
TOOL_PATH_DL,
TOOL_RAIL_LR,
TOOL_RAIL_UD,
TOOL_RAIL_LU,
TOOL_RAIL_UR,
TOOL_RAIL_RD,
TOOL_RAIL_DL,
TOOL_NODE,
TOOL_UPGRADE,
TOOL_DESTROY,
TOOL_INVALID
};
struct site
{
uint_fast8_t pos[2];
uint_fast8_t built;
enum tools tool;
};
struct site sites[1];
inline cv_vmemp tile_at(uint_fast8_t x, uint_fast8_t y)
{
return(x + y * 32);
}
uint_fast8_t free_workers;
uint_fast8_t workers;
void cvu_voutb(const uint8_t value, const cv_vmemp dest)
{
(void)value;
ASSERT(dest == tile_at(0, 1) || dest == tile_at(1, 1) || dest == tile_at(0, 2) || dest == tile_at(1, 2));
}
void build(void)
{
free_workers = workers;
for(struct site *s = sites; s < sites + 1; s++)
{
uint_fast8_t x;
uint_fast8_t y;
if(!free_workers)
return;
if(s->tool == UINT8_MAX)
continue;
x = s->pos[0];
y = s->pos[1];
free_workers--;
{
uint_fast8_t progress = s->built / 32;
bool big = (s->tool >= TOOL_RAIL_LU);
cvu_voutb(TILE_SITE0 + progress, tile_at(x, y));
if(big)
{
cvu_voutb(TILE_SITE0 + progress, tile_at(x + 1, y));
cvu_voutb(TILE_SITE0 + progress, tile_at(x, y + 1));
cvu_voutb(TILE_SITE0 + progress, tile_at(x + 1, y + 1));
}
}
}
}
void testBug(void)
{
workers = 1;
sites[0].pos[0] = 0;
sites[0].pos[1] = 1;
sites[0].tool = TOOL_NODE;
sites[0].built = 0;
build();
}
extern cv_vmemp tile_at(uint_fast8_t x, uint_fast8_t y);
|