mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-24 12:02:08 +00:00
With permission from the main authors [1], most of the code has been relicensed under the MIT license. SPDX license identifiers are used so that the license headers in source code files aren't too large. Add CONTRIBUTORS.rst file. [1] https://github.com/rednex/rgbds/issues/128 Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
168 lines
3.2 KiB
C
168 lines
3.2 KiB
C
/*
|
|
* This file is part of RGBDS.
|
|
*
|
|
* Copyright (c) 1997-2018, Carsten Sorensen and RGBDS contributors.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "extern/err.h"
|
|
|
|
#include "link/mylink.h"
|
|
#include "link/mapfile.h"
|
|
#include "link/main.h"
|
|
#include "link/assign.h"
|
|
|
|
char *tzOutname;
|
|
char *tzOverlayname;
|
|
|
|
int32_t MaxOverlayBank;
|
|
|
|
void writehome(FILE *f, FILE *f_overlay)
|
|
{
|
|
const struct sSection *pSect;
|
|
uint8_t *mem;
|
|
|
|
mem = malloc(MaxAvail[BANK_INDEX_ROM0]);
|
|
if (!mem)
|
|
return;
|
|
|
|
if (f_overlay != NULL) {
|
|
fseek(f_overlay, 0L, SEEK_SET);
|
|
if (fread(mem, 1, MaxAvail[BANK_INDEX_ROM0], f_overlay) !=
|
|
MaxAvail[BANK_INDEX_ROM0]) {
|
|
warnx("Failed to read data from overlay file.");
|
|
}
|
|
} else {
|
|
memset(mem, fillchar, MaxAvail[BANK_INDEX_ROM0]);
|
|
}
|
|
MapfileInitBank(0);
|
|
|
|
pSect = pSections;
|
|
while (pSect) {
|
|
if (pSect->Type == SECT_ROM0) {
|
|
memcpy(mem + pSect->nOrg, pSect->pData,
|
|
pSect->nByteSize);
|
|
MapfileWriteSection(pSect);
|
|
}
|
|
pSect = pSect->pNext;
|
|
}
|
|
|
|
MapfileCloseBank(area_Avail(0));
|
|
|
|
fwrite(mem, 1, MaxAvail[BANK_INDEX_ROM0], f);
|
|
free(mem);
|
|
}
|
|
|
|
void writebank(FILE *f, FILE *f_overlay, int32_t bank)
|
|
{
|
|
const struct sSection *pSect;
|
|
uint8_t *mem;
|
|
|
|
mem = malloc(MaxAvail[bank]);
|
|
if (!mem)
|
|
return;
|
|
|
|
if (f_overlay != NULL && bank <= MaxOverlayBank) {
|
|
fseek(f_overlay, bank * 0x4000, SEEK_SET);
|
|
if (fread(mem, 1, MaxAvail[bank], f_overlay) != MaxAvail[bank])
|
|
warnx("Failed to read data from overlay file.");
|
|
} else {
|
|
memset(mem, fillchar, MaxAvail[bank]);
|
|
}
|
|
MapfileInitBank(bank);
|
|
|
|
pSect = pSections;
|
|
while (pSect) {
|
|
if (pSect->Type == SECT_ROMX && pSect->nBank == bank) {
|
|
memcpy(mem + pSect->nOrg - 0x4000, pSect->pData,
|
|
pSect->nByteSize);
|
|
MapfileWriteSection(pSect);
|
|
}
|
|
pSect = pSect->pNext;
|
|
}
|
|
|
|
MapfileCloseBank(area_Avail(bank));
|
|
|
|
fwrite(mem, 1, MaxAvail[bank], f);
|
|
free(mem);
|
|
}
|
|
|
|
void out_Setname(char *tzOutputfile)
|
|
{
|
|
tzOutname = tzOutputfile;
|
|
}
|
|
|
|
void out_SetOverlayname(char *tzOverlayfile)
|
|
{
|
|
tzOverlayname = tzOverlayfile;
|
|
}
|
|
|
|
void Output(void)
|
|
{
|
|
int32_t i;
|
|
FILE *f;
|
|
FILE *f_overlay = NULL;
|
|
|
|
/*
|
|
* Apply overlay
|
|
*/
|
|
|
|
f = fopen(tzOutname, "wb");
|
|
|
|
if (f != NULL) {
|
|
if (tzOverlayname) {
|
|
f_overlay = fopen(tzOverlayname, "rb");
|
|
|
|
if (!f_overlay) {
|
|
errx(1, "Failed to open overlay file %s\n",
|
|
tzOverlayname);
|
|
}
|
|
|
|
fseek(f_overlay, 0, SEEK_END);
|
|
|
|
if (ftell(f_overlay) % 0x4000 != 0)
|
|
errx(1, "Overlay file must be aligned to 0x4000 bytes.");
|
|
|
|
MaxOverlayBank = (ftell(f_overlay) / 0x4000) - 1;
|
|
|
|
if (MaxOverlayBank < 1)
|
|
errx(1, "Overlay file must be at least 0x8000 bytes.");
|
|
|
|
if (MaxOverlayBank > MaxBankUsed)
|
|
MaxBankUsed = MaxOverlayBank;
|
|
}
|
|
|
|
writehome(f, f_overlay);
|
|
for (i = 1; i <= MaxBankUsed; i += 1)
|
|
writebank(f, f_overlay, i);
|
|
|
|
fclose(f);
|
|
|
|
if (tzOverlayname)
|
|
fclose(f_overlay);
|
|
}
|
|
|
|
/*
|
|
* Add regular sections
|
|
*/
|
|
|
|
for (i = BANK_INDEX_WRAM0; i < BANK_INDEX_MAX; i++) {
|
|
const struct sSection *pSect;
|
|
|
|
MapfileInitBank(i);
|
|
pSect = pSections;
|
|
while (pSect) {
|
|
if (pSect->nBank == i)
|
|
MapfileWriteSection(pSect);
|
|
pSect = pSect->pNext;
|
|
}
|
|
MapfileCloseBank(area_Avail(i));
|
|
}
|
|
}
|