int d_opt(void);
int d_dsp(void);
int d_objproc(void);
+int d_align(void);
void SetLargestAlignment(int);
// Directive handler table
d_opt, // 66 .opt
d_objproc, // 67 .objproc
(void *)d_dsm, // 68 .dsm
+ d_align // 69 .align
};
tok += 2;
+ size = lseek(fd, 0L, SEEK_END);
+ pos = lseek(fd, 0L, SEEK_SET);
+
if (*tok != EOL)
{
- // Check size parameter (can be omitted)
- if (*tok++ == ',')
+ // Parse size and position parameters
+ uint64_t requested_size = -1; // -1 means "not set" for these two
+
+ if (*tok++ != ',')
+ {
+ close(fd);
+ return error("expected comma after incbin filename");
+ }
+
+ if (tok != EOL)
{
if (*tok != ',')
{
- if (abs_expr(&size) != OK)
+ if (abs_expr(&requested_size) != OK)
{
close(fd);
return ERROR;
}
- if ((int64_t)size <= 0)
+
+ if ((int64_t)requested_size <= 0 || requested_size > size)
{
+ close(fd);
return error("invalid incbin size requested");
}
}
- else
- size = lseek(fd, 0L, SEEK_END);
- }
- // Check offset parameter (can be omitted)
- if (*tok != EOL)
- {
- if (*tok++ == ',')
+ if (*tok != EOL)
{
+ if (*tok++ != ',')
+ {
+ close(fd);
+ return error("expected comma after size parameter");
+ }
+
if (*tok != EOL)
{
if (abs_expr(&pos) != OK)
return ERROR;
}
- lseek(fd, pos, SEEK_SET);
- if ((int64_t)(size - pos) < 0)
+ if ((int64_t)pos <= 0 || pos > size)
{
- return error("requested incbin size out of range");
+ close(fd);
+ return error("invalid incbin position requested");
}
}
- else
- {
- // offset parameter omitted, so it's 0
- pos = lseek(fd, 0L, SEEK_SET);
- }
}
- else
- return error(comma_error);
+
+ if (*tok != EOL)
+ {
+ close(fd);
+ return error("extra characters following incbin");
+ }
}
- else
- pos = lseek(fd, 0L, SEEK_SET);
- }
- else
- {
- // size & pos not given, so assume offset of 0 and all of the binary
- size = lseek(fd, 0L, SEEK_END);
- pos = lseek(fd, 0L, SEEK_SET);
+
+ // Adjust size if the user didn't specify it via the parameter
+ if (requested_size == -1)
+ {
+ requested_size = size - pos;
+ }
+
+ // Are we going to read past the end of the file?
+ if (pos + requested_size > size)
+ {
+ close(fd);
+ return error("invalid combination of incbin position and size");
+ }
+ size = requested_size;
+
+ // All checks passed, let's seek to where the user requested, otherwise at file start
+ lseek(fd, pos, SEEK_SET);
}
chcheck(size);
}
+//
+// Adjust location to <alignment> bytes
+//
+int d_align(void)
+{
+ unsigned bytesToSkip;
+ uint64_t eval;
+
+ if (abs_expr(&eval) != OK)
+ return 0;
+
+ if (eval < 2)
+ {
+ return error("Invalid .align value specified");
+ }
+
+ if (dsp56001)
+ {
+ bytesToSkip = eval - sloc % eval;
+ D_ZEROFILL(bytesToSkip*3);
+ return 0;
+ }
+
+ bytesToSkip = eval - (rgpu || rdsp ? orgaddr : sloc) % eval;
+ if ( bytesToSkip != eval )
+ {
+ if ((scattr & SBSS) == 0)
+ {
+ D_ZEROFILL(bytesToSkip);
+ }
+ else
+ {
+ sloc += bytesToSkip;
+
+ if (orgactive)
+ orgaddr += bytesToSkip;
+ }
+ }
+ return 0;
+}
+
+
//
// Do auto-even. This must be called ONLY if 'sloc' is odd.
//
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
return ERROR;
-
+
// Check to see if the value being passed in is negative (who the hell does
// that?--nobody does; it's the code gremlins, or rum, what does it)
// N.B.: Since 'eval' is of type uint64_t, if it goes negative, it will
regtab = reg56tab;
regcheck = reg56check;
regaccept = reg56accept;
+ used_architectures |= M56001P | M56001X | M56001Y | M56001L;
return 0;
}
regtab = regrisctab;
regcheck = regrisccheck;
regaccept = regriscaccept;
+ //used_architectures |= MGPU; // TODO: Should GPU/DSP have their own dedicated sections in the long run?
return 0;
}
regtab = regrisctab;
regcheck = regrisccheck;
regaccept = regriscaccept;
+ //used_architectures |= MDSP; // TODO: Should GPU/DSP have their own dedicated sections in the long run?
return 0;
}
rgpu = 0; // Unset GPU assembly
rdsp = 0; // Unset DSP assembly
dsp56001 = 0; // Unset 56001 assembly
+ //used_architectures |= MOP; // TODO: Should OP have its own dedicated section in the long run?
return OK;
}