Skip to content

Commit c5f77b4

Browse files
committed
Rework section merge
1 parent a6853eb commit c5f77b4

File tree

7 files changed

+85
-77
lines changed

7 files changed

+85
-77
lines changed

cli/etripator.c

+6-12
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ int main(int argc, const char **argv) {
253253
}
254254
}
255255

256+
/* Sort & merge sections */
257+
section_array_tidy(&section_arr);
258+
256259
/* Disassemble and output */
257260
Section *previous = NULL;
258261
Section *current = NULL;
@@ -264,7 +267,7 @@ int main(int argc, const char **argv) {
264267
goto error_4;
265268
}
266269

267-
if (options.cdrom || (current->offset != ((current->page << 13) | (current->logical & 0x1fff)))) {
270+
if (options.cdrom && (current->offset != ((current->page << 13) | (current->logical & 0x1fff)))) {
268271
size_t offset = current->offset;
269272
/* Copy CDROM data */
270273
ret = cd_load(options.rom_filename, current->offset, current->size, options.sector_size, current->page, current->logical, &map);
@@ -314,7 +317,7 @@ int main(int argc, const char **argv) {
314317

315318
if (current->type == SECTION_TYPE_CODE) {
316319
if(current->size <= 0) {
317-
current->size = compute_size(current, i, section_arr.count, &map);
320+
current->size = compute_size(&section_arr, i, section_arr.count, &map);
318321
}
319322

320323
/* Extract labels */
@@ -339,21 +342,12 @@ int main(int argc, const char **argv) {
339342
}
340343

341344
/* Open main asm file */
342-
main_file = fopen(options.main_filename, "w");
345+
main_file = fopen(options.main_filename, "a+"); // [todo]
343346
if (!main_file) {
344347
ERROR_MSG("Unable to open %s : %s", options.main_filename, strerror(errno));
345348
goto error_4;
346349
}
347-
348350
label_dump(main_file, &map, repository);
349-
350-
if (!options.cdrom && options.extract_irq) {
351-
fprintf(main_file, "\n\t.data\n\t.bank 0\n\t.org $FFF6\n");
352-
for (int i = 0; i < 5; ++i) {
353-
fprintf(main_file, "\t.dw $%04x\n", current->logical);
354-
}
355-
}
356-
357351
fclose(main_file);
358352

359353
/* Output labels */

decode.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ static int data_extract_jump_table(FILE *out, Section *section, MemoryMap *map,
504504
print_statement_address(out, n, line_logical, line_page);
505505
}
506506
}
507-
fputc('\n', out);
507+
508508
return 1;
509509
}
510510

@@ -817,10 +817,10 @@ int decode(FILE *out, uint16_t *logical, Section *section, MemoryMap *map, Label
817817
}
818818

819819
/* Computes section size. */
820-
int32_t compute_size(Section *sections, int index, int count, MemoryMap *map) {
820+
int32_t compute_size(SectionArray *sections, int index, int count, MemoryMap *map) {
821821
uint8_t i;
822822
uint8_t data[7];
823-
Section *current = &sections[index];
823+
Section *current = &sections->data[index];
824824
uint32_t start = current->logical;
825825
uint32_t logical = start;
826826

@@ -829,9 +829,9 @@ int32_t compute_size(Section *sections, int index, int count, MemoryMap *map) {
829829
uint32_t max_offset = 0xffffffff;
830830
for (i = 0; i < count; i++) {
831831
if (i != index) {
832-
if (current->page == sections[i].page) {
832+
if (current->page == sections->data[i].page) {
833833
uint32_t offset_current = current->offset & 0x1fff;
834-
uint32_t offset_it = sections[i].offset & 0x1fff;
834+
uint32_t offset_it = sections->data[i].offset & 0x1fff;
835835
if ((offset_current < offset_it) && (max_offset > offset_it)) {
836836
max_offset = offset_it;
837837
}

decode.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ int decode(FILE *out, uint16_t *logical, Section *section, MemoryMap *map, Label
7979
/// \param [in] count Number of sections.
8080
/// \param [in] map Memory map.
8181
/// \return Section size.
82-
int32_t compute_size(Section *sections, int index, int count, MemoryMap *map);
82+
int32_t compute_size(SectionArray *sections, int index, int count, MemoryMap *map);
8383

8484
/// Output hardware IO port and RAM labels.
8585
/// \param [out] out File output.

irq.c

+22-3
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,10 @@ static char* g_irq_names[PCE_IRQ_COUNT] = {
4747
"irq_reset"
4848
};
4949

50-
// [todo] add an extra section for the address table
5150
// Get irq code offsets from rom.
5251
bool irq_read(MemoryMap* map, SectionArray *out) {
5352
assert(map != NULL);
5453
assert(out != NULL);
55-
assert(out->data != NULL);
56-
assert((out->count + PCE_IRQ_COUNT) <= out->capacity);
5754

5855
bool ret = false;
5956
if(map->memory[PCE_MEMORY_ROM].data == NULL) {
@@ -62,7 +59,10 @@ bool irq_read(MemoryMap* map, SectionArray *out) {
6259
ERROR_MSG("ROM is abnormally small.");
6360
} else {
6461
uint16_t offset = PCE_IRQ_TABLE;
62+
map->mpr[7] = 0;
63+
6564
ret = true;
65+
6666
for(size_t i=0; ret && (i<PCE_IRQ_COUNT); i++) {
6767
// IRQ name.
6868
const char *name = g_irq_names[i];
@@ -96,6 +96,25 @@ bool irq_read(MemoryMap* map, SectionArray *out) {
9696
ret = false;
9797
}
9898
}
99+
100+
const Section irq_table = {
101+
.name = strdup("irq_table"),
102+
.page = 0x00,
103+
.type = SECTION_TYPE_DATA,
104+
.logical = PCE_IRQ_TABLE,
105+
.size = PCE_IRQ_COUNT * 2U,
106+
.mpr = { [0] = 0xFU, [1] = 0xF8 },
107+
.data = {
108+
.type = DATA_TYPE_JUMP_TABLE,
109+
.elements_per_line = 1U
110+
},
111+
.output = strdup("main.asm")
112+
};
113+
114+
if(section_array_add(out, &irq_table) < 0) {
115+
ERROR_MSG("failed to add IRQ table section");
116+
ret = false;
117+
}
99118
}
100119
return ret;
101120
}

section.c

+45-53
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ static int section_overlap(const Section *a, const Section *b) {
145145
const Section *tmp = b;
146146
b = a;
147147
a = tmp;
148-
}
149-
148+
}
150149
if(a->type != b->type) {
151150
ret = (b->logical < (a->logical + a->size)) ? -1 : 0;
152151
} else if(b->logical <= (a->logical + a->size)) {
@@ -185,60 +184,24 @@ int section_array_add(SectionArray *arr, const Section* in) {
185184
assert(in != NULL);
186185

187186
int ret = -1;
188-
size_t i;
189-
bool insert = false;
190-
191-
// Find the slot where the section will be inserted or merged
192-
for(i=0; (!insert) && (i<arr->count); ) {
193-
if(in->page > arr->data[i].page) {
194-
// ...
195-
} else if(in->page < arr->data[i].page) {
196-
insert = true;
197-
} else {
198-
int overlap = section_overlap(&arr->data[i], in);
199-
if(overlap == 1) {
200-
section_merge(&arr->data[i], in);
201-
INFO_MSG("Section %s has been merged with %s!", arr->data[i].name, in->name);
202-
ret = 1;
203-
break;
204-
} else if (overlap == -1) {
205-
WARNING_MSG("Section %s and %s overlaps!", arr->data[i].name, in->name);
206-
} else if(overlap == 0) {
207-
// ...
208-
}
209-
if(in->offset < arr->data[i].offset) {
210-
insert = true;
211-
}
212-
}
213-
if(!insert) {
214-
i++;
215-
}
216-
}
217-
218-
if((i >= arr->count) || insert) {
219-
// Check if we need to expand section array buffer
220-
if(arr->count >= arr->capacity) {
221-
size_t n = arr->capacity + 4U;
222-
Section *ptr = realloc(arr->data, n*sizeof(Section));
223-
if(ptr == NULL) {
224-
ERROR_MSG("Failed to expand section array buffer", strerror(errno));
225-
} else {
226-
arr->data = ptr;
227-
arr->capacity = n;
228-
ret = 1;
229-
}
187+
// Check if we need to expand section array buffer
188+
if(arr->count >= arr->capacity) {
189+
size_t n = arr->capacity + 4U;
190+
Section *ptr = realloc(arr->data, n*sizeof(Section));
191+
if(ptr == NULL) {
192+
ERROR_MSG("Failed to expand section array buffer", strerror(errno));
230193
} else {
194+
arr->data = ptr;
195+
arr->capacity = n;
231196
ret = 1;
232197
}
198+
} else {
199+
ret = 1;
200+
}
233201

234-
size_t ii = i;
235-
if(ret > 0) {
236-
for(size_t j=arr->count; j>i; j--) {
237-
arr->data[j] = arr->data[j-1];
238-
}
239-
arr->count++;
240-
arr->data[i] = *in;
241-
}
202+
if(ret > 0) {
203+
arr->data[arr->count] = *in;
204+
arr->count++;
242205
}
243206
return ret;
244207
}
@@ -252,4 +215,33 @@ const Section* section_array_get(SectionArray *arr, size_t i) {
252215
}
253216
}
254217
return ret;
255-
}
218+
}
219+
220+
// Merge and sort sections.
221+
void section_array_tidy(SectionArray *arr) {
222+
assert(arr != NULL);
223+
assert(arr->count != 0);
224+
225+
Section *section = calloc(arr->count, sizeof(Section));
226+
227+
qsort(arr->data, arr->count, sizeof(Section), section_compare);
228+
229+
size_t j = 0;
230+
section[0] = arr->data[0];
231+
for(size_t i=1; i<arr->count; i++) {
232+
int overlap = section_overlap(&section[j], &arr->data[i]);
233+
if(overlap == 1) {
234+
section_merge(&section[j], &arr->data[i]);
235+
INFO_MSG("Section %s has been merged with %s!", arr->data[i].name, section[j].name);
236+
section_delete(&arr->data[i]);
237+
} else {
238+
if(overlap == -1) {
239+
WARNING_MSG("Section %s and %s overlaps!", arr->data[i].name, section[j].name);
240+
}
241+
section[++j] = arr->data[i];
242+
}
243+
}
244+
free(arr->data);
245+
arr->data = section;
246+
arr->count = j+1;
247+
}

section.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,17 @@ void section_array_reset(SectionArray *arr);
113113
void section_array_delete(SectionArray *arr);
114114

115115
/// Add a new section.
116-
/// Note that if the section overlaps an already existing one, it will be merged if both sections have the
117-
/// same type.
118116
/// \param [in out] arr Section array the section will be added to.
119117
/// \param [in] in Section that will be added to the section array.
120118
/// \return 1 if the section was succesfully added.
121119
/// \return 0 if the section was merged with one from the section array.
122120
/// \return -1 if the section can not be merged or if there is not enough memory to add a new one.
123121
int section_array_add(SectionArray *arr, const Section* in);
124122

123+
/// Merge and sort sections.
124+
/// \param [in out] arr Section array the section will be added to.
125+
void section_array_tidy(SectionArray *arr);
126+
125127
/// Retrieve the ith section from the array.
126128
/// \param [in] arr Section array.
127129
/// \param [in] i Index of the section to be retrieved.

test/section.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ MunitResult section_load_test(const MunitParameter params[], void* fixture) {
7878
int i, j, k;
7979
int ret;
8080
ret = section_load(&arr, "./data/bank0_0.json");
81-
81+
section_array_tidy(&arr);
8282
munit_assert_int(ret, !=, 0);
8383
munit_assert_int(arr.count, ==, 4);
8484

@@ -96,6 +96,7 @@ MunitResult section_load_test(const MunitParameter params[], void* fixture) {
9696
}
9797

9898
ret = section_load(&arr, "./data/bank0_1.json");
99+
section_array_tidy(&arr);
99100
munit_assert_int(ret, !=, 0);
100101
munit_assert_int(arr.count, ==, 13);
101102
for(i=0, k=0; k<4; i++, k++) {

0 commit comments

Comments
 (0)