diff --git a/docs/rgbasm.5.html b/docs/rgbasm.5.html
index 89f0a898..f8c5a4dd 100644
--- a/docs/rgbasm.5.html
+++ b/docs/rgbasm.5.html
@@ -1346,6 +1346,9 @@ INCBIN "sprites/hero.bin"
INCBIN "data.bin",78,256
+
The length arugment is optional. If only the start position is
+ specified, the bytes from the start position until the end of the file will
+ be included.
diff --git a/include/asm/section.h b/include/asm/section.h
index 8fe16ca7..41bb4425 100644
--- a/include/asm/section.h
+++ b/include/asm/section.h
@@ -57,7 +57,7 @@ void out_RelBytes(struct Expression *expr, uint32_t n);
void out_RelWord(struct Expression *expr);
void out_RelLong(struct Expression *expr);
void out_PCRelByte(struct Expression *expr);
-void out_BinaryFile(char const *s);
+void out_BinaryFile(char const *s, int32_t startPos);
void out_BinaryFileSlice(char const *s, int32_t start_pos, int32_t length);
void out_PushSection(void);
diff --git a/src/asm/asmy.y b/src/asm/asmy.y
index c5f7082d..4b687f38 100644
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -1073,7 +1073,12 @@ include : T_POP_INCLUDE string {
;
incbin : T_POP_INCBIN string {
- out_BinaryFile($2);
+ out_BinaryFile($2, 0);
+ if (oFailedOnMissingInclude)
+ YYACCEPT;
+ }
+ | T_POP_INCBIN string ',' const {
+ out_BinaryFile($2, $4);
if (oFailedOnMissingInclude)
YYACCEPT;
}
diff --git a/src/asm/rgbasm.5 b/src/asm/rgbasm.5
index 7c44f35c..7df0e3ab 100644
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -1080,6 +1080,8 @@ The example below includes 256 bytes from data.bin, starting from byte 78.
.Bd -literal -offset indent
INCBIN "data.bin",78,256
.Ed
+.Pp
+The length arugment is optional. If only the start position is specified, the bytes from the start position until the end of the file will be included.
.Ss Unions
.Pp
Unions allow multiple memory allocations to overlap, like unions in C.
diff --git a/src/asm/section.c b/src/asm/section.c
index 39aede99..2f2969db 100644
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -583,8 +583,14 @@ void out_PCRelByte(struct Expression *expr)
/*
* Output a binary file
*/
-void out_BinaryFile(char const *s)
+void out_BinaryFile(char const *s, int32_t startPos)
{
+ if (startPos < 0) {
+ yyerror("Start position cannot be negative (%" PRId32 ")",
+ startPos);
+ startPos = 0;
+ }
+
FILE *f = fstk_FindFile(s, NULL);
if (!f) {
@@ -602,12 +608,21 @@ void out_BinaryFile(char const *s)
checkcodesection();
if (fseek(f, 0, SEEK_END) != -1) {
fsize = ftell(f);
- rewind(f);
- reserveSpace(fsize);
- } else if (errno != ESPIPE) {
- yyerror("Error determining size of INCBIN file '%s': %s", s,
- strerror(errno));
+ if (startPos >= fsize) {
+ yyerror("Specified start position is greater than length of file");
+ return;
+ }
+
+ fseek(f, startPos, SEEK_SET);
+ reserveSpace(fsize - startPos);
+ } else {
+ if (errno != ESPIPE)
+ yyerror("Error determining size of INCBIN file '%s': %s",
+ s, strerror(errno));
+ /* The file isn't seekable, so we'll just skip bytes */
+ while (startPos--)
+ (void)fgetc(f);
}
while ((byte = fgetc(f)) != EOF) {