ref: 157fda2bc85b54a608bdb0cf5149c8a01046c51a
dir: /src/link/output.c/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "link/mylink.h"
#include "link/mapfile.h"
#include "link/main.h"
#include "link/assign.h"
char tzOutname[_MAX_PATH];
BBOOL oOutput = 0;
void
writehome(FILE * f)
{
struct sSection *pSect;
UBYTE *mem;
mem = malloc(MaxAvail[BANK_HOME]);
if (!mem)
return;
if (fillchar != -1) {
memset(mem, fillchar, MaxAvail[BANK_HOME]);
}
MapfileInitBank(0);
pSect = pSections;
while (pSect) {
if (pSect->Type == SECT_HOME) {
memcpy(mem + pSect->nOrg, pSect->pData,
pSect->nByteSize);
MapfileWriteSection(pSect);
}
pSect = pSect->pNext;
}
MapfileCloseBank(area_Avail(0));
fwrite(mem, 1, MaxAvail[BANK_HOME], f);
free(mem);
}
void
writebank(FILE * f, SLONG bank)
{
struct sSection *pSect;
UBYTE *mem;
mem = malloc(MaxAvail[bank]);
if (!mem)
return;
if (fillchar != -1) {
memset(mem, fillchar, MaxAvail[bank]);
}
MapfileInitBank(bank);
pSect = pSections;
while (pSect) {
if (pSect->Type == SECT_CODE && 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)
{
strcpy(tzOutname, tzOutputfile);
oOutput = 1;
}
void
GBROM_Output(void)
{
SLONG i;
FILE *f;
if ((f = fopen(tzOutname, "wb"))) {
writehome(f);
for (i = 1; i <= MaxBankUsed; i += 1)
writebank(f, i);
fclose(f);
}
for (i = 256; i < MAXBANKS; i += 1) {
struct sSection *pSect;
MapfileInitBank(i);
pSect = pSections;
while (pSect) {
if (pSect->nBank == i) {
MapfileWriteSection(pSect);
}
pSect = pSect->pNext;
}
MapfileCloseBank(area_Avail(i));
}
}
void
PSION2_Output(void)
{
FILE *f;
if ((f = fopen(tzOutname, "wb"))) {
struct sSection *pSect;
UBYTE *mem;
ULONG size = MaxAvail[0] - area_Avail(0);
ULONG relocpatches;
fputc(size >> 24, f);
fputc(size >> 16, f);
fputc(size >> 8, f);
fputc(size, f);
if ((mem = malloc(MaxAvail[0] - area_Avail(0)))) {
MapfileInitBank(0);
pSect = pSections;
while (pSect) {
if (pSect->Type == SECT_CODE) {
memcpy(mem + pSect->nOrg, pSect->pData,
pSect->nByteSize);
MapfileWriteSection(pSect);
} else {
memset(mem + pSect->nOrg, 0,
pSect->nByteSize);
}
pSect = pSect->pNext;
}
MapfileCloseBank(area_Avail(0));
fwrite(mem, 1, MaxAvail[0] - area_Avail(0), f);
free(mem);
}
relocpatches = 0;
pSect = pSections;
while (pSect) {
struct sPatch *pPatch;
pPatch = pSect->pPatches;
while (pPatch) {
if (pPatch->oRelocPatch) {
relocpatches += 1;
}
pPatch = pPatch->pNext;
}
pSect = pSect->pNext;
}
fputc(relocpatches >> 24, f);
fputc(relocpatches >> 16, f);
fputc(relocpatches >> 8, f);
fputc(relocpatches, f);
pSect = pSections;
while (pSect) {
struct sPatch *pPatch;
pPatch = pSect->pPatches;
while (pPatch) {
if (pPatch->oRelocPatch) {
ULONG address;
address = pPatch->nOffset + pSect->nOrg;
fputc(address >> 24, f);
fputc(address >> 16, f);
fputc(address >> 8, f);
fputc(address, f);
}
pPatch = pPatch->pNext;
}
pSect = pSect->pNext;
}
fclose(f);
}
}
void
Output(void)
{
if (oOutput) {
switch (outputtype) {
case OUTPUT_GBROM:
GBROM_Output();
break;
case OUTPUT_PSION2:
PSION2_Output();
break;
}
}
}