shithub: rgbds

Download patch

ref: 4f86a1253940f8f866413a2095ae3b21598d6b6f
parent: 7b8d4de35c2dc284501218982fb1a05f6a1a8321
parent: 7e2457c9bee44041dbb9ace4d67158711be6352d
author: AntonioND <[email protected]>
date: Thu Mar 2 04:17:46 EST 2017

Merge pull request #125 from Ben10do/section-alignment

Implement byte alignment for data

--- a/include/asm/output.h
+++ b/include/asm/output.h
@@ -10,6 +10,7 @@
 	ULONG nPC;
 	ULONG nOrg;
 	ULONG nBank;
+	ULONG nAlign;
 	struct Section *pNext;
 	struct Patch *pPatches;
 	struct Charmap *charmap;
@@ -20,6 +21,7 @@
 void out_SetFileName(char *s);
 void out_NewSection(char *pzName, ULONG secttype);
 void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank);
+void out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank);
 void out_AbsByte(int b);
 void out_AbsByteGroup(char *s, int length);
 void out_RelByte(struct Expression * expr);
--- a/include/link/mylink.h
+++ b/include/link/mylink.h
@@ -63,8 +63,10 @@
 struct sSection {
 	SLONG nBank;
 	SLONG nOrg;
+	SLONG nAlign;
 	BBOOL oAssigned;
 
+	char *pzName;
 	SLONG nByteSize;
 	enum eSectionType Type;
 	UBYTE *pData;
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -460,7 +460,7 @@
 %left	T_OP_MUL T_OP_DIV T_OP_MOD
 %left	T_OP_NOT
 %left	T_OP_DEF
-%left	T_OP_BANK
+%left	T_OP_BANK T_OP_ALIGN
 %left	T_OP_SIN
 %left	T_OP_COS
 %left	T_OP_TAN
@@ -1113,6 +1113,10 @@
 			else
 				yyerror("Address $%x not 16-bit", $6);
 		}
+	|	T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']'
+		{
+			out_NewAlignedSection($2, $4, $8, -1);
+		}
 	|	T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']'
 		{
 			bankrangecheck($2, $4, -1, $8);
@@ -1123,6 +1127,14 @@
 				yyerror("Address $%x not 16-bit", $6);
 			}
 			bankrangecheck($2, $4, $6, $11);
+		}
+	|	T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']' ',' T_OP_BANK '[' const ']'
+		{
+			out_NewAlignedSection($2, $4, $8, $13);
+		}
+	|	T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' ',' T_OP_ALIGN '[' const ']'
+		{
+			out_NewAlignedSection($2, $4, $13, $8);
 		}
 ;
 
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -267,6 +267,7 @@
 	{"def", T_OP_DEF},
 
 	{"bank", T_OP_BANK},
+	{"align", T_OP_ALIGN},
 
 	{"round", T_OP_ROUND},
 	{"ceil", T_OP_CEIL},
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -201,17 +201,18 @@
 void 
 writesection(struct Section * pSect, FILE * f)
 {
-	//printf("SECTION: %s, ID: %d\n", pSect->pzName, getsectid(pSect));
-
+	fputstring(pSect->pzName, f); // RGB3 addition
 	fputlong(pSect->nPC, f);
 	fputc(pSect->nType, f);
 	fputlong(pSect->nOrg, f);
 	//RGB1 addition
 
-	    fputlong(pSect->nBank, f);
+	fputlong(pSect->nBank, f);
 	//RGB1 addition
+		
+	fputlong(pSect->nAlign, f); // RGB3 addition
 
-	    if ((pSect->nType == SECT_ROM0)
+	if ((pSect->nType == SECT_ROM0)
 	    || (pSect->nType == SECT_ROMX)) {
 		struct Patch *pPatch;
 
@@ -490,7 +491,7 @@
 		struct PatchSymbol *pSym;
 		struct Section *pSect;
 
-		fwrite("RGB2", 1, 4, f);
+		fwrite("RGB3", 1, 4, f);
 		fputlong(countsymbols(), f);
 		fputlong(countsections(), f);
 
@@ -546,7 +547,7 @@
  * Find a section by name and type.  If it doesn't exist, create it
  */
 struct Section *
-out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
+out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank, SLONG alignment)
 {
 	struct Section *pSect, **ppSect;
 
@@ -557,7 +558,8 @@
 		if (strcmp(pzName, pSect->pzName) == 0) {
 			if (secttype == pSect->nType
 			    && ((ULONG) org) == pSect->nOrg
-			    && ((ULONG) bank) == pSect->nBank) {
+			    && ((ULONG) bank) == pSect->nBank
+			    && ((ULONG) alignment == pSect->nAlign)) {
 				return (pSect);
 			} else
 				fatalerror
@@ -574,6 +576,7 @@
 			pSect->nPC = 0;
 			pSect->nOrg = org;
 			pSect->nBank = bank;
+			pSect->nAlign = alignment;
 			pSect->pNext = NULL;
 			pSect->pPatches = NULL;
 			pSect->charmap = NULL;
@@ -610,7 +613,7 @@
 void 
 out_NewSection(char *pzName, ULONG secttype)
 {
-	out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1));
+	out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1, 1));
 }
 
 /*
@@ -619,7 +622,19 @@
 void 
 out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
 {
-	out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank));
+	out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank, 1));
+}
+
+/*
+ * Set the current section by name and type, using a given byte alignment
+ */
+void 
+out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank)
+{
+	if (alignment < 0 || alignment > 16) {
+		yyerror("Alignment must be between 0-16 bits.");
+	}
+	out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment));
 }
 
 /*
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -46,7 +46,7 @@
 	case SECT_WRAMX: DOMAXWBANK(y); break; \
 	case SECT_SRAM: DOMAXSBANK(y); break; \
 	case SECT_VRAM: DOMAXVBANK(y); break; \
-	default: errx(1, "DOMAXBANK used with invalid parameters"); break; }}
+	default: break; }}
 #define DOMAXRBANK(x)	{if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
 #define DOMAXWBANK(x)	{if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
 #define DOMAXSBANK(x)	{if( (x)>MaxSBankUsed ) MaxSBankUsed=(x);}
@@ -78,45 +78,51 @@
 }
 
 SLONG
-area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
+area_doAlloc(struct sFreeArea *pArea, SLONG org, SLONG size)
 {
-	struct sFreeArea *pArea;
-
-	pArea = *ppArea;
-	while (pArea) {
-		if (org >= pArea->nOrg
-		    && (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) {
-			if (org == pArea->nOrg) {
-				pArea->nOrg += size;
+	if (org >= pArea->nOrg && (org + size) <= (pArea->nOrg + pArea->nSize)) {
+		if (org == pArea->nOrg) {
+			pArea->nOrg += size;
+			pArea->nSize -= size;
+			return org;
+		} else {
+			if ((org + size) == (pArea->nOrg + pArea->nSize)) {
 				pArea->nSize -= size;
-				return 0;
+				return org;
 			} else {
-				if ((org + size - 1) ==
-				    (pArea->nOrg + pArea->nSize - 1)) {
-					pArea->nSize -= size;
-					return 0;
-				} else {
-					struct sFreeArea *pNewArea;
+				struct sFreeArea *pNewArea;
 
-					if ((pNewArea =
-						malloc(sizeof(struct sFreeArea)))
-					    != NULL) {
-						*pNewArea = *pArea;
-						pNewArea->pPrev = pArea;
-						pArea->pNext = pNewArea;
-						pArea->nSize =
-						    org - pArea->nOrg;
-						pNewArea->nOrg = org + size;
-						pNewArea->nSize -=
-						    size + pArea->nSize;
-
-						return 0;
-					} else {
-						err(1, NULL);
-					}
+				if ((pNewArea = malloc(sizeof(struct sFreeArea))) != NULL) {
+					*pNewArea = *pArea;
+					pNewArea->pPrev = pArea;
+					pArea->pNext = pNewArea;
+					pArea->nSize = org - pArea->nOrg;
+					pNewArea->nOrg = org + size;
+					pNewArea->nSize -= size + pArea->nSize;
+					return org;
+					
+				} else {
+					err(1, NULL);
 				}
 			}
 		}
+	}
+	
+	return -1;
+}
+
+SLONG
+area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
+{
+	struct sFreeArea *pArea;
+
+	pArea = *ppArea;
+	while (pArea) {
+		SLONG result = area_doAlloc(pArea, org, size);
+		if (result != -1) {
+			return result;
+		}
+		
 		ppArea = &(pArea->pNext);
 		pArea = *ppArea;
 	}
@@ -141,31 +147,35 @@
 	return -1;
 }
 
-SLONG 
-area_Alloc(struct sFreeArea ** ppArea, SLONG size)
-{
+SLONG
+area_Alloc(struct sFreeArea ** ppArea, SLONG size, SLONG alignment) {
 	struct sFreeArea *pArea;
-
+	if (alignment < 1) {
+		alignment = 1;
+	}
+	
 	pArea = *ppArea;
 	while (pArea) {
-		if (size <= pArea->nSize) {
-			SLONG r;
-
-			r = pArea->nOrg;
-			pArea->nOrg += size;
-			pArea->nSize -= size;
-
-			return (r);
+		SLONG org = pArea->nOrg;	
+		if (org % alignment) {
+			org += alignment;
 		}
+		org -= org % alignment;
+		
+		SLONG result = area_doAlloc(pArea, org, size);
+		if (result != -1) {
+			return result;
+		}
+		
 		ppArea = &(pArea->pNext);
 		pArea = *ppArea;
 	}
 
-	return (-1);
+	return -1;
 }
 
 SLONG
-area_AllocAnyBank(SLONG size, enum eSectionType type) {
+area_AllocAnyBank(SLONG size, SLONG alignment, enum eSectionType type) {
 	ensureSectionTypeIsValid(type);
 
 	SLONG startBank = SECT_ATTRIBUTES[type].bank;
@@ -172,7 +182,7 @@
 	SLONG bankCount = SECT_ATTRIBUTES[type].bankCount;
 	
 	for (int i = 0; i < bankCount; i++) {
-		SLONG org = area_Alloc(&BankFree[startBank + i], size);
+		SLONG org = area_Alloc(&BankFree[startBank + i], size, alignment);
 		if (org != -1) {
 			return ((startBank + i) << 16) | org;
 		}
@@ -182,35 +192,73 @@
 }
 
 struct sSection *
-FindLargestSection(enum eSectionType type)
+FindLargestSection(enum eSectionType type, bool bankFixed)
 {
 	struct sSection *pSection, *r = NULL;
 	SLONG nLargest = 0;
+	SLONG nLargestAlignment = 0;
 
 	pSection = pSections;
 	while (pSection) {
-		if (pSection->oAssigned == 0 && pSection->Type == type) {
-			if (pSection->nByteSize > nLargest) {
+		if (pSection->oAssigned == 0 && pSection->Type == type && (bankFixed ^ (pSection->nBank == -1))) {
+			if (pSection->nAlign > nLargestAlignment || (pSection->nAlign == nLargestAlignment && pSection->nByteSize > nLargest)) {
 				nLargest = pSection->nByteSize;
+				nLargestAlignment = pSection->nAlign;
 				r = pSection;
 			}
 		}
 		pSection = pSection->pNext;
 	}
+	
 	return r;
 }
 
+
+bool
+VerifyAndSetBank(struct sSection *pSection)
+{
+	ensureSectionTypeIsValid(pSection->Type);
+
+	if (pSection->nBank >= SECT_ATTRIBUTES[pSection->Type].minBank
+		&& pSection->nBank < SECT_ATTRIBUTES[pSection->Type].minBank + SECT_ATTRIBUTES[pSection->Type].bankCount) {
+		pSection->nBank += SECT_ATTRIBUTES[pSection->Type].bank + SECT_ATTRIBUTES[pSection->Type].offset;
+		return true;
+		
+	} else {
+		return false;
+	}
+}
+
 void
-AssignBankedSections(enum eSectionType type)
+AssignFixedBankSections(enum eSectionType type)
 {
 	ensureSectionTypeIsValid(type);
 
 	struct sSection *pSection;
 
-	while ((pSection = FindLargestSection(type))) {
+	while ((pSection = FindLargestSection(type, true))) {
+		if (VerifyAndSetBank(pSection) &&
+			(pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize, pSection->nAlign)) != -1) {
+			pSection->oAssigned = 1;
+			DOMAXBANK(pSection->Type, pSection->nBank);
+		} else {
+			errx(1, "Unable to load fixed %s section into bank $%02lX",
+				SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank);
+		}
+	}
+}
+
+void
+AssignFloatingBankSections(enum eSectionType type)
+{
+	ensureSectionTypeIsValid(type);
+
+	struct sSection *pSection;
+
+	while ((pSection = FindLargestSection(type, false))) {
 		SLONG org;
 
-		if ((org = area_AllocAnyBank(pSection->nByteSize, type)) != -1) {
+		if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) {
 			pSection->nOrg = org & 0xFFFF;
 			pSection->nBank = org >> 16;
 			pSection->oAssigned = 1;
@@ -219,24 +267,9 @@
 			errx(1, "Unable to place %s section anywhere",
 				 SECT_ATTRIBUTES[type].name);
 		}
-	}
+	}	
 }
 
-bool
-VerifyAndSetBank(struct sSection *pSection)
-{
-	ensureSectionTypeIsValid(pSection->Type);
-
-	if (pSection->nBank >= SECT_ATTRIBUTES[pSection->Type].minBank
-		&& pSection->nBank < SECT_ATTRIBUTES[pSection->Type].minBank + SECT_ATTRIBUTES[pSection->Type].bankCount) {
-		pSection->nBank += SECT_ATTRIBUTES[pSection->Type].bank + SECT_ATTRIBUTES[pSection->Type].offset;
-		return true;
-		
-	} else {
-		return false;
-	}
-}
-
 void
 AssignSections(void)
 {
@@ -353,35 +386,11 @@
 	}
 
 	/*
-	 * Next, let's assign all the bankfixed ONLY ROMX sections...
+	 * Next, let's assign all the bankfixed ONLY sections...
 	 *
 	 */
-
-	pSection = pSections;
-	while (pSection) {
-		if (pSection->oAssigned == 0
-			&& pSection->nOrg == -1 && pSection->nBank != -1) {
-			switch (pSection->Type) {
-			case SECT_ROMX:
-			case SECT_SRAM:
-			case SECT_VRAM:
-			case SECT_WRAMX:
-				if (VerifyAndSetBank(pSection) &&
-					(pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) != -1) {
-					pSection->oAssigned = 1;
-					DOMAXBANK(pSection->Type, pSection->nBank);
-				} else {
-					errx(1, "Unable to load fixed %s section into bank $%02lX",
-						 SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank);
-				}
-				break;
-
-			default: // Handle other sections later
-				break;
-			}
-		}
-
-		pSection = pSection->pNext;
+	for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) {
+		AssignFixedBankSections(i);
 	}
 
 	/*
@@ -421,41 +430,9 @@
 	 * sections
 	 *
 	 */
-
-	pSection = pSections;
-	while (pSection) {
-		if (pSection->oAssigned == 0) {
-			switch (pSection->Type) {
-			case SECT_WRAM0:
-			case SECT_HRAM:
-			case SECT_ROM0:
-				pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank;
-				if ((pSection->nOrg =
-					area_Alloc(&BankFree[pSection->nBank],
-					    pSection->nByteSize)) == -1) {
-					errx(1, "%s section too large", SECT_ATTRIBUTES[pSection->Type].name);
-				}
-				pSection->oAssigned = 1;
-				break;
-
-			case SECT_SRAM:
-			case SECT_VRAM:
-			case SECT_WRAMX:
-			case SECT_ROMX:
-				break;
-
-			default:
-				errx(1, "(INTERNAL) Unknown section type!");
-				break;
-			}
-		}
-		pSection = pSection->pNext;
+	for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) {
+		AssignFloatingBankSections(i);
 	}
-
-	AssignBankedSections(SECT_ROMX);
-	AssignBankedSections(SECT_VRAM);
-	AssignBankedSections(SECT_WRAMX);
-	AssignBankedSections(SECT_SRAM);
 }
 
 void 
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -18,6 +18,11 @@
 UBYTE dummymem;
 BBOOL oReadLib = 0;
 
+enum ObjectFileContents {
+	CONTAINS_SECTION_NAME = 1 << 0,
+	CONTAINS_SECTION_ALIGNMENT = 1 << 1
+};
+
 /*
  * The usual byte order stuff
  *
@@ -46,21 +51,41 @@
 
 	return (r);
 }
+
 /*
  * Read a NULL terminated string from a file
  *
  */
-
-SLONG 
-readasciiz(char *s, FILE * f)
+SLONG
+readasciiz(char **dest, FILE *f)
 {
 	SLONG r = 0;
-
-	while (((*s++) = fgetc(f)) != 0)
+	
+	size_t bufferLength = 16;
+	char *start = malloc(bufferLength);
+	char *s = start;
+	
+	if (!s) {
+		err(1, NULL);
+	}
+		
+	while (((*s++) = fgetc(f)) != 0) {
 		r += 1;
-
+		
+		if (r >= bufferLength) {
+			bufferLength *= 2;
+			start = realloc(start, bufferLength);
+			if (!start) {
+				err(1, NULL);
+			}
+			s = start + r;
+		}
+	}
+	
+	*dest = start;
 	return (r + 1);
 }
+
 /*
  * Allocate a new section and link it into the list
  *
@@ -97,7 +122,6 @@
 struct sSymbol *
 obj_ReadSymbol(FILE * f)
 {
-	char s[256];
 	struct sSymbol *pSym;
 
 	pSym = malloc(sizeof *pSym);
@@ -105,13 +129,7 @@
 		err(1, NULL);
 	}
 
-	readasciiz(s, f);
-	pSym->pzName = malloc(strlen(s) + 1);
-	if (!pSym->pzName) {
-		err(1, NULL);
-	}
-
-	strcpy(pSym->pzName, s);
+	readasciiz(&pSym->pzName, f);
 	if ((pSym->Type = (enum eSymbolType) fgetc(f)) != SYM_IMPORT) {
 		pSym->nSectionID = readlong(f);
 		pSym->nOffset = readlong(f);
@@ -130,10 +148,12 @@
 
 	pSection = AllocSection();
 
+	pSection->pzName = "";
 	pSection->nByteSize = readlong(f);
 	pSection->Type = (enum eSectionType) fgetc(f);
 	pSection->nOrg = -1;
 	pSection->nBank = -1;
+	pSection->nAlign = 1;
 
 	/* does the user want the -s mode? */
 
@@ -153,7 +173,6 @@
 
 			SLONG nNumberOfPatches;
 			struct sPatch **ppPatch, *pPatch;
-			char s[256];
 
 			fread(pSection->pData, sizeof(UBYTE),
 			    pSection->nByteSize, f);
@@ -171,15 +190,8 @@
 				}
 
 				*ppPatch = pPatch;
-				readasciiz(s, f);
+				readasciiz(&pPatch->pzFilename, f);
 
-				pPatch->pzFilename = malloc(strlen(s) + 1);
-				if (!pPatch->pzFilename) {
-					err(1, NULL);
-				}
-
-				strcpy(pPatch->pzFilename, s);
-
 				pPatch->nLineNo =
 				    readlong(f);
 				pPatch->nOffset =
@@ -272,21 +284,28 @@
  */
 
 struct sSection *
-obj_ReadRGB1Section(FILE * f)
+obj_ReadRGBSection(FILE * f, enum ObjectFileContents contents)
 {
 	struct sSection *pSection;
 
 	pSection = AllocSection();
 
+	if (contents & CONTAINS_SECTION_NAME) {
+		readasciiz(&pSection->pzName, f);
+	} else {
+		pSection->pzName = "";
+	}
+
 	pSection->nByteSize = readlong(f);
 	pSection->Type = (enum eSectionType) fgetc(f);
-	/*
-	 * And because of THIS new feature I'll have to rewrite loads and
-	 * loads of stuff... oh well it needed to be done anyway
-	 *
-	 */
 	pSection->nOrg = readlong(f);
 	pSection->nBank = readlong(f);
+	
+	if (contents & CONTAINS_SECTION_ALIGNMENT) {
+		pSection->nAlign = readlong(f);
+	} else {
+		pSection->nAlign = 1;
+	}
 
 	/* does the user want the -s mode? */
 
@@ -306,7 +325,6 @@
 
 			SLONG nNumberOfPatches;
 			struct sPatch **ppPatch, *pPatch;
-			char s[256];
 
 			fread(pSection->pData, sizeof(UBYTE),
 			    pSection->nByteSize, f);
@@ -324,13 +342,7 @@
 				}
 
 				*ppPatch = pPatch;
-				readasciiz(s, f);
-				pPatch->pzFilename = malloc(strlen(s) + 1);
-				if (!pPatch->pzFilename) {
-					err(1, NULL);
-				}
-
-				strcpy(pPatch->pzFilename, s);
+				readasciiz(&pPatch->pzFilename, f);
 				pPatch->nLineNo = readlong(f);
 				pPatch->nOffset = readlong(f);
 				pPatch->Type = (enum ePatchType) fgetc(f);
@@ -358,7 +370,7 @@
 }
 
 void 
-obj_ReadRGB1(FILE * pObjfile)
+obj_ReadRGB(FILE * pObjfile, enum ObjectFileContents contents)
 {
 	struct sSection *pFirstSection;
 	SLONG nNumberOfSymbols, nNumberOfSections, i;
@@ -385,7 +397,7 @@
 	while (nNumberOfSections--) {
 		struct sSection *pNewSection;
 
-		pNewSection = obj_ReadRGB1Section(pObjfile);
+		pNewSection = obj_ReadRGBSection(pObjfile, contents);
 		pNewSection->nNumberOfSymbols = nNumberOfSymbols;
 		if (pFirstSection == NULL)
 			pFirstSection = pNewSection;
@@ -432,8 +444,12 @@
 		case '1':
 		case '2':
 			//V2 is really the same but the are new patch types
-			    obj_ReadRGB1(pObjfile);
+			obj_ReadRGB(pObjfile, 0);
 			break;
+		case '3':
+			// V3 is very similiar, but contains section names and byte alignment
+			obj_ReadRGB(pObjfile, CONTAINS_SECTION_NAME | CONTAINS_SECTION_ALIGNMENT);
+			break;
 		default:
 			errx(1, "'%s' is an unsupported version", tzObjectfile);
 		}
@@ -482,9 +498,9 @@
 
 	size = file_Length(f) - 4;
 	while (size) {
-		char name[256];
+		char *name;
 
-		size -= readasciiz(name, f);
+		size -= readasciiz(&name, f);
 		readword(f);
 		size -= 2;
 		readword(f);
@@ -492,5 +508,6 @@
 		size -= readlong(f);
 		size -= 4;
 		obj_ReadOpenFile(f, name);
+		free(name);
 	}
 }