mirror of http://shamusworld.gotdns.org/git/rmac
The deed has been accomplished.
As far as I can tell, there should be no more regressions, but that's no guarantee of anything. Assuming no more are found, this should go out as version 2.0.0. :-D
This commit is contained in:
parent
bdbf34766f
commit
29fa5dcf50
33
6502.c
33
6502.c
|
@ -645,46 +645,39 @@ badmode:
|
|||
if (sloc > 0x10000L)
|
||||
fatal("6502 code pointer > 64K");
|
||||
|
||||
//Now why use this instead of at_eol()?
|
||||
if (*tok != EOL)
|
||||
error(extra_stuff);
|
||||
ErrorIfNotAtEOL();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Generate 6502 object output file.
|
||||
// ggn: Converted to COM/EXE/XEX output format
|
||||
//
|
||||
// ggn: converted into a com/exe/xex output format
|
||||
void m6502obj(int ofd)
|
||||
{
|
||||
uint16_t exeheader[3];
|
||||
int headsize = 6;
|
||||
uint16_t * headpoint = exeheader;
|
||||
uint8_t header[4];
|
||||
|
||||
CHUNK * ch = sect[M6502].scode;
|
||||
|
||||
// If no 6502 code was generated, forget it
|
||||
// If no 6502 code was generated, bail out
|
||||
if ((ch == NULL) || (ch->challoc == 0))
|
||||
return;
|
||||
|
||||
exeheader[0] = 0xFFFF; // Mandatory for first segment
|
||||
register uint8_t * p = ch->chptr;
|
||||
|
||||
// Write out mandatory $FFFF header
|
||||
header[0] = header[1] = 0xFF;
|
||||
ssize_t unused = write(ofd, header, 2);
|
||||
|
||||
for(uint16_t * l=&orgmap[0][0]; l<currentorg; l+=2)
|
||||
{
|
||||
/*
|
||||
Why are we assuming endianness here? This is retarded
|
||||
*/
|
||||
exeheader[1] = l[0];
|
||||
exeheader[2] = l[1] - 1;
|
||||
SETLE16(header, 0, l[0]);
|
||||
SETLE16(header, 2, l[1] - 1);
|
||||
|
||||
// Write header
|
||||
size_t unused = write(ofd, headpoint, headsize);
|
||||
// Write header for segment
|
||||
unused = write(ofd, header, 4);
|
||||
// Write the segment data
|
||||
unused = write(ofd, p + l[0], l[1] - l[0]);
|
||||
|
||||
// Skip the $FFFF after first segment, it's not mandatory
|
||||
headpoint = &exeheader[1];
|
||||
headsize = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
238
direct.c
238
direct.c
|
@ -9,6 +9,7 @@
|
|||
#include "direct.h"
|
||||
#include "6502.h"
|
||||
#include "amode.h"
|
||||
#include "dsp56k.h"
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
#include "fltpoint.h"
|
||||
|
@ -222,7 +223,9 @@ int d_org(void)
|
|||
return error(".org permitted only in GPU/DSP/OP, 56001 and 6502 sections");
|
||||
|
||||
// M56K can leave the expression off the org for some reason :-/
|
||||
if ((abs_expr(&address) == ERROR) && !dsp56001)
|
||||
// (It's because the expression is non-standard, and so we have to look at
|
||||
// it in isolation)
|
||||
if (!dsp56001 && (abs_expr(&address) == ERROR))
|
||||
{
|
||||
error("cannot determine org'd address");
|
||||
return ERROR;
|
||||
|
@ -255,9 +258,94 @@ int d_org(void)
|
|||
}
|
||||
else if (dsp56001)
|
||||
{
|
||||
// Only mark segments we actually wrote something
|
||||
if (chptr != dsp_currentorg->start && dsp_written_data_in_current_org)
|
||||
{
|
||||
dsp_currentorg->end = chptr;
|
||||
dsp_currentorg++;
|
||||
}
|
||||
|
||||
// Maybe we switched from a non-DSP section (TEXT, DATA, etc) and
|
||||
// scode isn't initialised yet. Not that it's going to be a valid
|
||||
// scenario, but if we try it anyhow it's going to lead to a crash. So
|
||||
// let's fudge a value of 0 and get on with it.
|
||||
orgaddr = (scode != NULL ? sloc : 0);
|
||||
SaveSection();
|
||||
|
||||
if (tok[1] != ':')
|
||||
return error(syntax_error);
|
||||
|
||||
int sectionToSwitch = 0;
|
||||
|
||||
switch (tok[0])
|
||||
{
|
||||
case KW_X:
|
||||
dsp_currentorg->memtype = ORG_X;
|
||||
sectionToSwitch = M56001X;
|
||||
break;
|
||||
|
||||
case KW_Y:
|
||||
dsp_currentorg->memtype = ORG_Y;
|
||||
sectionToSwitch = M56001Y;
|
||||
break;
|
||||
|
||||
case KW_P:
|
||||
dsp_currentorg->memtype = ORG_P;
|
||||
sectionToSwitch = M56001P;
|
||||
break;
|
||||
|
||||
case KW_L:
|
||||
dsp_currentorg->memtype = ORG_L;
|
||||
sectionToSwitch = M56001L;
|
||||
break;
|
||||
|
||||
default:
|
||||
return error("unknown type in ORG");
|
||||
}
|
||||
|
||||
if ((obj_format == LOD) || (obj_format == P56))
|
||||
SwitchSection(sectionToSwitch);
|
||||
|
||||
tok += 2;
|
||||
chcheck(3); // Ensure we got a valid address to write
|
||||
dsp_currentorg->chunk = scode; // Mark down which chunk this org starts from (will be needed when outputting)
|
||||
|
||||
if (*tok == EOL)
|
||||
{
|
||||
// Well, the user didn't specify an address at all so we'll have to
|
||||
// use the last used address of that section (or 0 if there wasn't one)
|
||||
address = orgaddr;
|
||||
dsp_currentorg->start = chptr;
|
||||
dsp_currentorg->orgadr = orgaddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (abs_expr(&address) == ERROR)
|
||||
{
|
||||
error("cannot determine org'd address");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
dsp_currentorg->start = chptr;
|
||||
dsp_currentorg->orgadr = (uint32_t)address;
|
||||
sect[cursect].orgaddr = (uint32_t)address;
|
||||
}
|
||||
|
||||
if (address > DSP_MAX_RAM)
|
||||
{
|
||||
return error(range_error);
|
||||
}
|
||||
|
||||
dsp_written_data_in_current_org = 0;
|
||||
|
||||
// Copied from 6502 above: kludge `lsloc' so the listing generator
|
||||
// doesn't try to spew out megabytes.
|
||||
lsloc = sloc = (int32_t)address;
|
||||
// N.B.: It seems that by enabling this, even though it works elsewhere, will cause symbols to royally fuck up. Will have to do some digging to figure out why.
|
||||
// orgactive = 1;
|
||||
}
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -830,7 +918,7 @@ int d_assert(void)
|
|||
break;
|
||||
}
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1011,7 +1099,7 @@ int d_ds(WORD siz)
|
|||
dep_block(eval, siz, 0, (WORD)(DEFINED | ABS), NULL);
|
||||
}
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1117,9 @@ int d_dc(WORD siz)
|
|||
return error("illegal initialization of section");
|
||||
|
||||
// Do an auto_even if it's not BYTE sized (hmm, should we be doing this???)
|
||||
if (cursect != M6502 && (siz != SIZB) && (sloc & 1))
|
||||
if ((cursect != M6502) && (cursect != M56001P) && (cursect != M56001X)
|
||||
&& (cursect != M56001Y) && (cursect != M56001L)
|
||||
&& (siz != SIZB) && (sloc & 1))
|
||||
auto_even();
|
||||
|
||||
// Check to see if we're trying to set LONGS on a non 32-bit aligned
|
||||
|
@ -1086,6 +1176,138 @@ int d_dc(WORD siz)
|
|||
uint16_t tdb = eattr & TDB;
|
||||
uint16_t defined = eattr & DEFINED;
|
||||
|
||||
// N.B.: This is awful. This needs better handling, rather than just bodging something in that, while works, is basically an ugly wart on the assembler. !!! FIX !!!
|
||||
if (dsp56001)
|
||||
{
|
||||
if (cursect != M56001L)
|
||||
{
|
||||
if (!defined)
|
||||
{
|
||||
AddFixup(FU_DSPIMM24 | FU_SEXT, sloc, exprbuf);
|
||||
D_dsp(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eattr & FLOAT)
|
||||
{
|
||||
double fval = *(double *)&eval;
|
||||
|
||||
if (fval >= 1)
|
||||
{
|
||||
warn("value clamped to +1.");
|
||||
eval = 0x7fffff;
|
||||
}
|
||||
else if (fval <= -1)
|
||||
{
|
||||
warn("value clamped to -1.");
|
||||
eval = 0x800000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert fraction to 24 bits fixed point with sign and rounding
|
||||
// Yeah, that cast to int32_t has to be there because casting
|
||||
// a float to unsigned int is "undefined" according to the C
|
||||
// standard. Which most compilers seem to do the sensible thing
|
||||
// and just cast the f**king value properly, except gcc 4.x.x
|
||||
// for arm (tested on raspbian).
|
||||
// Thanks, C and gcc! Thanks for making me waste a few hours \o/
|
||||
eval = 0;//!!! FIX !!! (uint32_t)(int32_t)round(fval*(1 << 23));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((uint32_t)eval + 0x1000000 >= 0x2000000)
|
||||
return error(range_error);
|
||||
}
|
||||
|
||||
// Deposit DSP word (24-bit)
|
||||
D_dsp(eval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In L: we deposit stuff to both X: and Y: instead
|
||||
// We will be a bit lazy and require that there is a 2nd value in the same source line.
|
||||
// (Motorola's assembler can parse 12-digit hex values, which we can't do at the moment)
|
||||
// This of course requires to parse 2 values in one pass.
|
||||
// If there isn't another value in this line, assume X: value is 0.
|
||||
int secondword = 0;
|
||||
uint32_t evaly;
|
||||
l_parse_loop:
|
||||
|
||||
if (!defined)
|
||||
{
|
||||
AddFixup(FU_DSPIMM24 | FU_SEXT, sloc, exprbuf);
|
||||
D_dsp(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eattr & FLOAT)
|
||||
{
|
||||
float fval = *(float *)&eval;
|
||||
if (fval >= 1)
|
||||
{
|
||||
warn("value clamped to +1.");
|
||||
eval = 0x7fffff;
|
||||
}
|
||||
else if (fval <= -1)
|
||||
{
|
||||
warn("value clamped to -1.");
|
||||
eval = 0x800000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert fraction to 24 bits fixed point with sign and rounding
|
||||
// Yeah, that cast to int32_t has to be there because casting
|
||||
// a float to unsigned int is "undefined" according to the C
|
||||
// standard. Which most compilers seem to do the sensible thing
|
||||
// and just cast the f**king value properly, except gcc 4.x.x
|
||||
// for arm (tested on raspbian).
|
||||
// Thanks, C and gcc! Thanks for making me waste a few hours \o/
|
||||
eval = 0;//!!! FIX !!! (uint32_t)(int32_t)round(fval*(1 << 23));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (eval + 0x1000000 >= 0x2000000)
|
||||
return error(range_error);
|
||||
}
|
||||
|
||||
// Parse 2nd value if we didn't do this yet
|
||||
if (secondword == 0)
|
||||
{
|
||||
evaly = (uint32_t)eval;
|
||||
secondword = 1;
|
||||
|
||||
if (*tok != ':')
|
||||
{
|
||||
// If we don't have a : then we're probably at EOL,
|
||||
// which means the X: value will be 0
|
||||
eval = 0;
|
||||
ErrorIfNotAtEOL();
|
||||
}
|
||||
else
|
||||
{
|
||||
tok++; // Eat the comma;
|
||||
|
||||
if (expr(exprbuf, &eval, &eattr, NULL) != OK)
|
||||
return 0;
|
||||
|
||||
defined = (WORD)(eattr & DEFINED);
|
||||
goto l_parse_loop;
|
||||
}
|
||||
}
|
||||
|
||||
// Deposit DSP words (24-bit)
|
||||
D_dsp(eval);
|
||||
D_dsp(evaly);
|
||||
sloc--; // We do write 2 DSP words but as far as L: space is concerned we actually advance our counter by one
|
||||
}
|
||||
|
||||
}
|
||||
goto comma;
|
||||
}
|
||||
|
||||
switch (siz)
|
||||
{
|
||||
case SIZB:
|
||||
|
@ -1252,7 +1474,7 @@ comma:
|
|||
break;
|
||||
}
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1480,7 +1702,7 @@ int d_comm(void)
|
|||
return 0;
|
||||
|
||||
sym->svalue = eval; // Install common symbol's size
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1612,7 +1834,7 @@ int d_56001(void)
|
|||
rgpu = rdsp = robjproc = 0;
|
||||
SaveSection();
|
||||
|
||||
if (obj_format == LOD || obj_format == P56)
|
||||
if ((obj_format == LOD) || (obj_format == P56))
|
||||
SwitchSection(M56001P);
|
||||
|
||||
return 0;
|
||||
|
|
6
dsp56k.h
6
dsp56k.h
|
@ -6,7 +6,8 @@
|
|||
// Source utilised with the kind permission of Landon Dyer
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef __DSP56K_H__
|
||||
#define __DSP56K_H__
|
||||
|
||||
#include "rmac.h"
|
||||
#include "sect.h"
|
||||
|
@ -36,7 +37,8 @@ extern DSP_ORG dsp_orgmap[1024]; // Mark all 56001 org changes
|
|||
extern DSP_ORG * dsp_currentorg;
|
||||
extern int dsp_written_data_in_current_org;
|
||||
|
||||
#define dprintf(...) p_buf += sprintf(p_buf, __VA_ARGS__)
|
||||
#define D_printf(...) chptr += sprintf(chptr, __VA_ARGS__)
|
||||
|
||||
// Exported functions
|
||||
|
||||
#endif // __DSP56K_H__
|
||||
|
|
3419
dsp56k_amode.c
3419
dsp56k_amode.c
File diff suppressed because it is too large
Load Diff
11
error.c
11
error.c
|
@ -11,18 +11,21 @@
|
|||
#include "listing.h"
|
||||
#include "token.h"
|
||||
|
||||
// Exported variables
|
||||
int errcnt; // Error count
|
||||
char * err_fname; // Name of error message file
|
||||
|
||||
// Internal variables
|
||||
static long unused; // For supressing 'write' warnings
|
||||
|
||||
|
||||
//
|
||||
// Report error if not at EOL
|
||||
//
|
||||
// N.B.: Since this should *never* happen, we can feel free to add whatever
|
||||
// diagnostics that will help in tracking down a problem to this function.
|
||||
//
|
||||
int at_eol(void)
|
||||
int ErrorIfNotAtEOL(void)
|
||||
{
|
||||
if (*tok != EOL)
|
||||
{
|
||||
|
@ -40,9 +43,9 @@ int at_eol(void)
|
|||
//
|
||||
// Cannot create a file
|
||||
//
|
||||
void cantcreat(const char * fn)
|
||||
void CantCreateFile(const char * fn)
|
||||
{
|
||||
printf("cannot create: '%s'\n", fn);
|
||||
printf("Cannot create file: '%s'\n", fn);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -66,7 +69,7 @@ void err_setup(void)
|
|||
err_fname = NULL;
|
||||
|
||||
if ((err_fd = open(fnbuf, _OPEN_FLAGS, _PERM_MODE)) < 0)
|
||||
cantcreat(fnbuf);
|
||||
CantCreateFile(fnbuf);
|
||||
|
||||
err_flag = 1;
|
||||
}
|
||||
|
|
4
error.h
4
error.h
|
@ -22,9 +22,9 @@ int error(const char *, ...);
|
|||
int warn(const char *, ...);
|
||||
int fatal(const char *);
|
||||
int interror(int);
|
||||
void cantcreat(const char *);
|
||||
void CantCreateFile(const char *);
|
||||
void err_setup(void);
|
||||
int at_eol(void);
|
||||
int ErrorIfNotAtEOL(void);
|
||||
|
||||
#endif // __ERROR_H__
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ void list_setup(void)
|
|||
list_fname = NULL;
|
||||
|
||||
if ((list_fd = open(fnbuf, _OPEN_FLAGS, _PERM_MODE)) < 0)
|
||||
cantcreat(fnbuf);
|
||||
CantCreateFile(fnbuf);
|
||||
}
|
||||
|
||||
|
||||
|
|
2
macro.c
2
macro.c
|
@ -172,7 +172,7 @@ int DefineMacro(void)
|
|||
{
|
||||
argno = 0;
|
||||
symlist(defmac2);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
}
|
||||
|
||||
// Suck in the macro definition; we're looking for an ENDM symbol on a line
|
||||
|
|
180
object.c
180
object.c
|
@ -9,11 +9,13 @@
|
|||
#include "object.h"
|
||||
#include "6502.h"
|
||||
#include "direct.h"
|
||||
#include "dsp56k.h"
|
||||
#include "error.h"
|
||||
#include "mark.h"
|
||||
#include "riscasm.h"
|
||||
#include "sect.h"
|
||||
#include "symbol.h"
|
||||
#include "version.h"
|
||||
|
||||
//#define DEBUG_ELF
|
||||
|
||||
|
@ -56,6 +58,10 @@ See left. 4 & 5 If these bits are set to 0 (PF_PRIVATE), the processes'
|
|||
- 6-15 Currently unused
|
||||
*/
|
||||
|
||||
// Internal function prototypes
|
||||
static void WriteLOD(void);
|
||||
static void WriteP56(void);
|
||||
|
||||
|
||||
//
|
||||
// Add entry to symbol table (in ALCYON mode)
|
||||
|
@ -351,6 +357,7 @@ int WriteObject(int fd)
|
|||
|
||||
if (strtable == NULL)
|
||||
{
|
||||
free(buf);
|
||||
error("cannot allocate string table memory (in BSD mode)");
|
||||
return ERROR;
|
||||
}
|
||||
|
@ -359,6 +366,8 @@ int WriteObject(int fd)
|
|||
|
||||
// Build object file header
|
||||
chptr = buf; // Base of header (for D_foo macros)
|
||||
ch_size = 0;
|
||||
challoc = 0x800000;
|
||||
D_long(0x00000107); // Magic number
|
||||
D_long(sect[TEXT].sloc); // TEXT size
|
||||
D_long(sect[DATA].sloc); // DATA size
|
||||
|
@ -440,6 +449,8 @@ int WriteObject(int fd)
|
|||
|
||||
// Build object file header just before the text+data image
|
||||
chptr = buf; // -> base of header
|
||||
ch_size = 0;
|
||||
challoc = HDRSIZE + tds + symbolMaxSize;
|
||||
D_word(0x601A); // 00 - magic number
|
||||
D_long(sect[TEXT].sloc); // 02 - TEXT size
|
||||
D_long(sect[DATA].sloc); // 06 - DATA size
|
||||
|
@ -592,6 +603,8 @@ for(int j=0; j<i; j++)
|
|||
// If you want to make any sense out of this you'd better take a look
|
||||
// at Executable and Linkable Format on Wikipedia.
|
||||
chptr = buf;
|
||||
ch_size = 0;
|
||||
challoc = 0x600000;
|
||||
D_long(0x7F454C46); // 00 - "<7F>ELF" Magic Number
|
||||
D_byte(0x01); // 04 - 32 vs 64 (1 = 32, 2 = 64)
|
||||
D_byte(0x02); // 05 - Endianness (1 = LE, 2 = BE)
|
||||
|
@ -774,7 +787,174 @@ for(int j=0; j<i; j++)
|
|||
// Just write the object file
|
||||
m6502obj(fd);
|
||||
}
|
||||
else if (obj_format == P56 || obj_format == LOD)
|
||||
{
|
||||
// Allocate 6MB object file image memory
|
||||
uint8_t * buf = malloc(0x600000);
|
||||
|
||||
if (buf == NULL)
|
||||
return error("cannot allocate object file memory (in P56/LOD mode)");
|
||||
|
||||
// objImage = buf; // Set global object image pointer
|
||||
|
||||
memset(buf, 0, 0x600000); // Clear allocated memory
|
||||
|
||||
// Iterate through DSP ram buffers
|
||||
chptr = buf; // -> base of header
|
||||
ch_size = 0;
|
||||
challoc = 0x600000;
|
||||
|
||||
if (obj_format == LOD)
|
||||
WriteLOD();
|
||||
else
|
||||
WriteP56();
|
||||
|
||||
// Write all the things |o/
|
||||
ssize_t unused = write(fd, buf, chptr - buf);
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void WriteLOD(void)
|
||||
{
|
||||
D_printf("_START %s 0000 0000 0000 RMAC %01i.%01i.%01i\n\n", firstfname, MAJOR, MINOR, PATCH);
|
||||
|
||||
for(DSP_ORG * l=&dsp_orgmap[0]; l<dsp_currentorg; l++)
|
||||
{
|
||||
if (l->end != l->start)
|
||||
{
|
||||
switch (l->memtype)
|
||||
{
|
||||
case ORG_P: D_printf("_DATA P %.4X\n", l->orgadr); break;
|
||||
case ORG_X: D_printf("_DATA X %.4X\n", l->orgadr); break;
|
||||
case ORG_Y: D_printf("_DATA Y %.4X\n", l->orgadr); break;
|
||||
case ORG_L: D_printf("_DATA L %.4X\n", l->orgadr); break;
|
||||
default:
|
||||
error("Internal error: unknown DSP56001 org'd section");
|
||||
return;
|
||||
}
|
||||
|
||||
CHUNK * cp = l->chunk;
|
||||
uint8_t * p_chunk = l->start;
|
||||
uint8_t * p_chunk_end = p_chunk;
|
||||
uint32_t j = 0;
|
||||
|
||||
while (p_chunk_end != l->end)
|
||||
{
|
||||
if (l->end < (cp->chptr + cp->ch_size) && l->end > cp->chptr)
|
||||
{
|
||||
// If the end of the section is inside the current chunk, just dump everything and stop
|
||||
p_chunk_end = l->end;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the end of the section is not inside the current chunk, just dump everything from the current chunk and move on to the next
|
||||
p_chunk_end = cp->chptr + cp->ch_size;
|
||||
}
|
||||
|
||||
uint32_t count = (uint32_t)(p_chunk_end - p_chunk);
|
||||
|
||||
for(uint32_t i=0; i<count; i+=3)
|
||||
{
|
||||
if ((j & 7) != 7)
|
||||
{
|
||||
D_printf("%.6X ", (((p_chunk[0] << 8) | p_chunk[1]) << 8) | p_chunk[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_printf("%.6X\n", (((p_chunk[0] << 8) | p_chunk[1]) << 8) | p_chunk[2]);
|
||||
}
|
||||
|
||||
p_chunk += 3;
|
||||
j++;
|
||||
}
|
||||
|
||||
cp = cp->chnext; // Advance chunk
|
||||
|
||||
if (cp != NULL)
|
||||
p_chunk = cp->chptr; // Set dump pointer to start of this chunk
|
||||
}
|
||||
|
||||
if ((j & 7) != 0)
|
||||
D_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Dump the symbol table into the buf
|
||||
DumpLODSymbols();
|
||||
|
||||
D_printf("\n_END %.4X\n", dsp_orgmap[0].orgadr);
|
||||
}
|
||||
|
||||
|
||||
static void WriteP56(void)
|
||||
{
|
||||
for(DSP_ORG * l=&dsp_orgmap[0]; l<dsp_currentorg; l++)
|
||||
{
|
||||
if (l->end == l->start)
|
||||
continue;
|
||||
|
||||
if ((l->memtype < ORG_P) || (l->memtype > ORG_L))
|
||||
{
|
||||
error("Internal error: unknown DSP56001 org'd section");
|
||||
return;
|
||||
}
|
||||
|
||||
CHUNK * cp = l->chunk;
|
||||
uint8_t * p_chunk = l->start;
|
||||
uint8_t * p_chunk_end = p_chunk;
|
||||
|
||||
// Memory type (P, X, Y or L)
|
||||
D_dsp(l->memtype);
|
||||
|
||||
// Chunk start address (in DSP words)
|
||||
D_dsp(l->orgadr);
|
||||
|
||||
// Chunk length (in DSP words)
|
||||
// We'll fill this field after we write the chunk so we can calculate
|
||||
// how long it is (so if the chunk is split into different CHUNKs we
|
||||
// can deal with this during copy)
|
||||
uint8_t * p_buf_len = chptr;
|
||||
chptr += 3;
|
||||
|
||||
// The chunk itself
|
||||
uint32_t chunk_size = 0;
|
||||
|
||||
while (p_chunk_end != l->end)
|
||||
{
|
||||
if (l->end < (cp->chptr + cp->ch_size) && l->end > cp->chptr)
|
||||
{
|
||||
// If the end of the section is inside the current chunk, just
|
||||
// dump everything and stop
|
||||
p_chunk_end = l->end;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the end of the section is not inside the current chunk,
|
||||
// just dump everything from the current chunk and move on to
|
||||
// the next
|
||||
p_chunk_end = cp->chptr + cp->ch_size;
|
||||
}
|
||||
|
||||
uint32_t current_chunk_size = p_chunk_end - p_chunk;
|
||||
chunk_size += current_chunk_size;
|
||||
memcpy(chptr, p_chunk, current_chunk_size);
|
||||
chptr += current_chunk_size;
|
||||
|
||||
cp = cp->chnext; // Advance chunk
|
||||
|
||||
if (cp != NULL)
|
||||
p_chunk = cp->chptr; // Set dump pointer to start of this chunk
|
||||
}
|
||||
|
||||
// Now we can mark the chunk's length (DSP word size is 24-bits, so
|
||||
// the byte count needs to be divided by 3)
|
||||
SETBE24(p_buf_len, chunk_size / 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
10
op.c
10
op.c
|
@ -177,7 +177,7 @@ static int HandleBitmap(void)
|
|||
}
|
||||
}
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
|
||||
uint64_t p1 = 0x00 | ((ypos * 2) << 3) | (iheight << 14) | (linkAddr << 21) | (dataAddr << 40);
|
||||
uint64_t p2 = xpos | (bpp << 12) | (pitch << 15) | (dwidth << 18) | (iwidth << 28) | (index << 38) | (flags << 45) | (firstpix << 49);
|
||||
|
@ -302,7 +302,7 @@ static int HandleScaledBitmap(void)
|
|||
}
|
||||
}
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
|
||||
uint64_t p1 = 0x01 | ((ypos * 2) << 3) | (iheight << 14) | (linkAddr << 21) | (dataAddr << 40);
|
||||
uint64_t p2 = xpos | (bpp << 12) | (pitch << 15) | (dwidth << 18) | (iwidth << 28) | (index << 38) | (flags << 45) | (firstpix << 49);
|
||||
|
@ -345,7 +345,7 @@ static int HandleGPUObject(void)
|
|||
if (!(eattr & DEFINED))
|
||||
return error("bad expression in data");
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
|
||||
uint64_t p1 = 0x02 | ((ypos * 2) << 3) | (eval << 14);
|
||||
|
||||
|
@ -410,7 +410,7 @@ static int HandleBranch(void)
|
|||
if (!(eattr & DEFINED))
|
||||
AddFixup(FU_QUAD | FU_OBJLINK, sloc, exprbuf);
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
|
||||
uint64_t p1 = 0x03 | (cc << 14) | ((ypos * 2) << 3) | ((eval & 0x3FFFF8) << 21);
|
||||
|
||||
|
@ -468,7 +468,7 @@ static int HandleJump(void)
|
|||
if (!(eattr & DEFINED))
|
||||
AddFixup(FU_QUAD | FU_OBJLINK, sloc, exprbuf);
|
||||
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
|
||||
// This is "branch if VC < 2047", which pretty much guarantees the branch.
|
||||
uint64_t p1 = 0x03 | (1 << 14) | (0x7FF << 3) | ((eval & 0x3FFFF8) << 21);
|
||||
|
|
15
procln.c
15
procln.c
|
@ -587,7 +587,7 @@ When checking to see if it's already been equated, issue a warning.
|
|||
if (list_flag) // Put value in listing
|
||||
listvalue((uint32_t)eval);
|
||||
|
||||
at_eol(); // Must be at EOL now
|
||||
ErrorIfNotAtEOL(); // Must be at EOL now
|
||||
goto loop;
|
||||
}
|
||||
|
||||
|
@ -782,11 +782,24 @@ When checking to see if it's already been equated, issue a warning.
|
|||
parcode = 0;
|
||||
}
|
||||
|
||||
#if 1
|
||||
while ((dsp_am0 & md->mn0) == 0 || (dsp_am1 & md->mn1) == 0)
|
||||
md = &dsp56k_machtab[md->mncont];
|
||||
|
||||
(*md->mnfunc)(md->mninst | (parcode << 8));
|
||||
goto loop;
|
||||
#else
|
||||
for(;;)
|
||||
{
|
||||
if ((dsp_am0 & md->mn0) != 0 && (dsp_am1 & md->mn1) != 0)
|
||||
{
|
||||
(*md->mnfunc)(md->mninst|(parcode << 8));
|
||||
goto loop;
|
||||
}
|
||||
|
||||
md = &dsp56k_machtab[md->mncont];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
20
riscasm.c
20
riscasm.c
|
@ -258,7 +258,7 @@ int GenerateRISCCode(int state)
|
|||
// UNPACK
|
||||
case RI_ONE:
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, parm >> 6, reg2);
|
||||
break;
|
||||
|
||||
|
@ -276,7 +276,7 @@ int GenerateRISCCode(int state)
|
|||
altbankok = 1; // MOVETA
|
||||
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg1, reg2);
|
||||
break;
|
||||
|
||||
|
@ -338,7 +338,7 @@ int GenerateRISCCode(int state)
|
|||
|
||||
CHECK_COMMA;
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg1, reg2);
|
||||
break;
|
||||
|
||||
|
@ -387,7 +387,7 @@ int GenerateRISCCode(int state)
|
|||
|
||||
CHECK_COMMA;
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
|
||||
DepositRISCInstructionWord(parm, 0, reg2);
|
||||
val = WORDSWAP32(eval);
|
||||
|
@ -410,7 +410,7 @@ int GenerateRISCCode(int state)
|
|||
|
||||
CHECK_COMMA;
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg1, reg2);
|
||||
break;
|
||||
|
||||
|
@ -533,7 +533,7 @@ int GenerateRISCCode(int state)
|
|||
tok++;
|
||||
CHECK_COMMA;
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg1, reg2);
|
||||
break;
|
||||
|
||||
|
@ -652,7 +652,7 @@ int GenerateRISCCode(int state)
|
|||
return MalformedOpcode(MALF_RPAREN);
|
||||
|
||||
tok++;
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg2, reg1);
|
||||
break;
|
||||
|
||||
|
@ -670,7 +670,7 @@ int GenerateRISCCode(int state)
|
|||
tok++;
|
||||
CHECK_COMMA;
|
||||
reg2 = EvaluateRegisterFromTokenStream(FU_REGTWO);
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg1, reg2);
|
||||
break;
|
||||
|
||||
|
@ -689,7 +689,7 @@ int GenerateRISCCode(int state)
|
|||
return MalformedOpcode(MALF_RPAREN);
|
||||
|
||||
tok++;
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
DepositRISCInstructionWord(parm, reg2, reg1);
|
||||
break;
|
||||
|
||||
|
@ -802,7 +802,7 @@ int GenerateRISCCode(int state)
|
|||
return MalformedOpcode(MALF_RPAREN);
|
||||
|
||||
tok++;
|
||||
at_eol();
|
||||
ErrorIfNotAtEOL();
|
||||
}
|
||||
|
||||
DepositRISCInstructionWord(parm, reg2, reg1);
|
||||
|
|
29
rmac.c
29
rmac.c
|
@ -10,6 +10,7 @@
|
|||
#include "6502.h"
|
||||
#include "debug.h"
|
||||
#include "direct.h"
|
||||
#include "dsp56k.h"
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
#include "listing.h"
|
||||
|
@ -148,6 +149,8 @@ void DisplayHelp(void)
|
|||
" a: ALCYON (use this for ST)\n"
|
||||
" b: BSD (use this for Jaguar)\n"
|
||||
" e: ELF\n"
|
||||
" p: P56 (use this for DSP56001 only)\n"
|
||||
" l: LOD (use this for DSP56001 only)\n"
|
||||
" x: com/exe/xex (Atari 800)\n"
|
||||
" -i[path] Directory to search for include files\n"
|
||||
" -l[filename] Create an output listing file\n"
|
||||
|
@ -161,6 +164,7 @@ void DisplayHelp(void)
|
|||
" 6502\n"
|
||||
" tom\n"
|
||||
" jerry\n"
|
||||
" 56001\n"
|
||||
" -n Don't do things behind your back in RISC assembler\n"
|
||||
" -o file Output file name\n"
|
||||
" +o[value] Turn a specific optimisation on\n"
|
||||
|
@ -358,6 +362,14 @@ int Process(int argc, char ** argv)
|
|||
case 'E':
|
||||
obj_format = ELF;
|
||||
break;
|
||||
case 'l': // -fl = LOD
|
||||
case 'L':
|
||||
obj_format = LOD;
|
||||
break;
|
||||
case 'p': // -fp = P56
|
||||
case 'P':
|
||||
obj_format = P56;
|
||||
break;
|
||||
case 'x': // -fx = COM/EXE/XEX
|
||||
case 'X':
|
||||
obj_format = XEX;
|
||||
|
@ -588,6 +600,7 @@ int Process(int argc, char ** argv)
|
|||
// - "foo.o" for linkable output;
|
||||
// - "foo.prg" for GEMDOS executable (-p flag).
|
||||
SaveSection();
|
||||
int temp_section = cursect;
|
||||
|
||||
for(i=TEXT; i<=BSS; i<<=1)
|
||||
{
|
||||
|
@ -613,6 +626,20 @@ int Process(int argc, char ** argv)
|
|||
currentorg += 2;
|
||||
}
|
||||
|
||||
// This looks like an awful kludge... !!! FIX !!!
|
||||
if (temp_section & (M56001P | M56001X | M56001Y))
|
||||
{
|
||||
SwitchSection(temp_section);
|
||||
|
||||
if (chptr != dsp_currentorg->start)
|
||||
{
|
||||
dsp_currentorg->end = chptr;
|
||||
dsp_currentorg++;
|
||||
}
|
||||
}
|
||||
|
||||
SwitchSection(TEXT);
|
||||
|
||||
if (objfname == NULL)
|
||||
{
|
||||
if (firstfname == NULL)
|
||||
|
@ -635,7 +662,7 @@ int Process(int argc, char ** argv)
|
|||
if (errcnt == 0)
|
||||
{
|
||||
if ((fd = open(objfname, _OPEN_FLAGS, _PERM_MODE)) < 0)
|
||||
cantcreat(objfname);
|
||||
CantCreateFile(objfname);
|
||||
|
||||
if (verb_flag)
|
||||
{
|
||||
|
|
9
rmac.h
9
rmac.h
|
@ -137,6 +137,12 @@
|
|||
{ (a)[(r + 0)] = (uint8_t)((v) & 0xFF); \
|
||||
(a)[(r + 1)] = (uint8_t)((v) >> 8); }
|
||||
|
||||
// In DSP56001 mode, this is useful:
|
||||
#define SETBE24(a, v) \
|
||||
{ (a)[0] = (uint8_t)(((v) >> 16) & 0xFF); \
|
||||
(a)[1] = (uint8_t)(((v) >> 8) & 0xFF); \
|
||||
(a)[2] = (uint8_t)((v) & 0xFF); }
|
||||
|
||||
// Byteswap crap
|
||||
#define BYTESWAP16(x) ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
|
||||
#define BYTESWAP32(x) ((((x) & 0x000000FF) << 24) | (((x) & 0x0000FF00) << 8) | (((x) & 0x00FF0000) >> 8) | (((x) & 0xFF000000) >> 24))
|
||||
|
@ -218,12 +224,13 @@ PTR
|
|||
#define TEXT 0x0001 // Relative to text
|
||||
#define DATA 0x0002 // Relative to data
|
||||
#define BSS 0x0004 // Relative to BSS
|
||||
//OK, this is bad, mmkay? These are treated as indices into an array which means that this was never meant to be defined this way--at least if it was, it was a compromise that has come home to bite us all in the ass. !!! FIX !!!
|
||||
#define M6502 0x0008 // 6502/microprocessor (absolute)
|
||||
#define M56001P 0x0010 // DSP 56001 Program RAM
|
||||
#define M56001X 0x0020 // DSP 56001 X RAM
|
||||
#define M56001Y 0x0040 // DSP 56001 Y RAM
|
||||
#define M56001L 0x0080 // DSP 56001 L RAM
|
||||
#define TDB (TEXT|DATA|BSS) // Mask for text+data+bss
|
||||
#define TDB (TEXT|DATA|BSS) // Mask for TEXT+DATA+BSS
|
||||
#define M56KPXYL (M56001P|M56001X|M56001Y|M56001L) // Mask for 56K stuff
|
||||
|
||||
// Sizes
|
||||
|
|
69
sect.c
69
sect.c
|
@ -9,6 +9,7 @@
|
|||
#include "sect.h"
|
||||
#include "6502.h"
|
||||
#include "direct.h"
|
||||
#include "dsp56k.h"
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
#include "listing.h"
|
||||
|
@ -75,11 +76,14 @@ void InitSection(void)
|
|||
MakeSection(i, 0);
|
||||
|
||||
// Construct default sections, make TEXT the current section
|
||||
MakeSection(ABS, SUSED | SABS | SBSS); // ABS
|
||||
MakeSection(TEXT, SUSED | TEXT ); // TEXT
|
||||
MakeSection(DATA, SUSED | DATA ); // DATA
|
||||
MakeSection(BSS, SUSED | BSS | SBSS); // BSS
|
||||
MakeSection(M6502, SUSED | TEXT ); // 6502 code section
|
||||
MakeSection(ABS, SUSED | SABS | SBSS); // ABS
|
||||
MakeSection(TEXT, SUSED | TEXT ); // TEXT
|
||||
MakeSection(DATA, SUSED | DATA ); // DATA
|
||||
MakeSection(BSS, SUSED | BSS | SBSS); // BSS
|
||||
MakeSection(M6502, SUSED | TEXT ); // 6502 code section
|
||||
MakeSection(M56001P, SUSED | SABS ); // DSP 56001 Program RAM
|
||||
MakeSection(M56001X, SUSED | SABS ); // DSP 56001 X RAM
|
||||
MakeSection(M56001Y, SUSED | SABS ); // DSP 56001 Y RAM
|
||||
|
||||
// Switch to TEXT for starters
|
||||
SwitchSection(TEXT);
|
||||
|
@ -128,9 +132,13 @@ void SwitchSection(int sno)
|
|||
// For 6502 mode, add the last org'd address
|
||||
// Why?
|
||||
/*
|
||||
Because the way this is set up it treats the 6502 assembly space as a single 64K space (+ 16 bytes, for some reason) and just bobbles around inside that space and uses a stack of org "pointers" to show where the data ended up.
|
||||
Because the way this is set up it treats the 6502 assembly space as a single 64K space (+ 16 bytes, for some unknown reason) and just bobbles around inside that space and uses a stack of org "pointers" to show where the data ended up.
|
||||
|
||||
This is a piss poor way to handle things, and for fucks sake, we can do better than this!
|
||||
This is a shitty way to handle things, and we can do better than this! :-P
|
||||
|
||||
Really, there's no reason to have the 6502 (or DSP56001 for that matter) have their own private sections for this kind of thing, as there's literally *no* chance that it would be mingled with 68K+ code. It should be able to use the TEXT, DATA & BSS sections just like the 68K.
|
||||
|
||||
Or should it? After looking at the code, maybe it's better to keep the 56001 sections segregated from the rest. But we can still make the 6502 stuff better.
|
||||
*/
|
||||
if (m6502)
|
||||
chptr = cp->chptr + orgaddr;
|
||||
|
@ -267,7 +275,8 @@ int AddFixup(uint32_t attr, uint32_t loc, TOKEN * fexpr)
|
|||
if (attr & FUMASKDSP)
|
||||
{
|
||||
attr |= FU_56001;
|
||||
_orgaddr = orgaddr;
|
||||
// Save the exact spot in this chunk where the fixup should go
|
||||
_orgaddr = chptr - scode->chptr;
|
||||
}
|
||||
|
||||
// Allocate space for the fixup + any expression
|
||||
|
@ -349,6 +358,9 @@ int ResolveFixups(int sno)
|
|||
// than this.
|
||||
SetFilenameForErrorReporting();
|
||||
|
||||
if ((sno == M56001P) || (sno == M56001X) || (sno == M56001Y) || (sno == M56001L))
|
||||
loc = fup->orgaddr;
|
||||
|
||||
// Search for chunk containing location to fix up; compute a
|
||||
// pointer to the location (in the chunk). Often we will find the
|
||||
// Fixup is in the "cached" chunk, so the linear-search is seldom
|
||||
|
@ -566,16 +578,7 @@ int ResolveFixups(int sno)
|
|||
case FU_WORD:
|
||||
if ((dw & FUMASKRISC) == FU_JR)
|
||||
{
|
||||
#if 0
|
||||
int reg;
|
||||
|
||||
if (fup->orgaddr)
|
||||
reg = (signed)((eval - (fup->orgaddr + 2)) / 2);
|
||||
else
|
||||
reg = (signed)((eval - (loc + 2)) / 2);
|
||||
#else
|
||||
int reg = (signed)((eval - ((fup->orgaddr ? fup->orgaddr : loc) + 2)) / 2);
|
||||
#endif
|
||||
|
||||
if ((reg < -16) || (reg > 15))
|
||||
{
|
||||
|
@ -727,8 +730,8 @@ int ResolveFixups(int sno)
|
|||
uint64_t addr = eval;
|
||||
|
||||
//Hmm, not sure how this can be set, since it's only set if it's a DSP56001 fixup or a FU_JR... :-/
|
||||
if (fup->orgaddr)
|
||||
addr = fup->orgaddr;
|
||||
// if (fup->orgaddr)
|
||||
// addr = fup->orgaddr;
|
||||
|
||||
eval = (quad & 0xFFFFFC0000FFFFFFLL) | ((addr & 0x3FFFF8) << 21);
|
||||
}
|
||||
|
@ -743,8 +746,8 @@ int ResolveFixups(int sno)
|
|||
uint64_t addr = eval;
|
||||
|
||||
//Hmm, not sure how this can be set, since it's only set if it's a DSP56001 fixup or a FU_JR... :-/
|
||||
if (fup->orgaddr)
|
||||
addr = fup->orgaddr;
|
||||
// if (fup->orgaddr)
|
||||
// addr = fup->orgaddr;
|
||||
|
||||
eval = (quad & 0x000007FFFFFFFFFFLL) | ((addr & 0xFFFFF8) << 40);
|
||||
}
|
||||
|
@ -798,7 +801,7 @@ int ResolveFixups(int sno)
|
|||
case FU_DSPADR12:
|
||||
if (eval >= 0x1000)
|
||||
{
|
||||
error("address out of range ($000-$FFF)");
|
||||
error("address out of range ($0-$FFF)");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -809,22 +812,22 @@ int ResolveFixups(int sno)
|
|||
// This is a full DSP word containing Effective Address Extension
|
||||
case FU_DSPADR24:
|
||||
case FU_DSPIMM24:
|
||||
if (eval >= 0x100000)
|
||||
if (eval >= 0x1000000)
|
||||
{
|
||||
error("value out of range ($000-$FFFFFF)");
|
||||
error("value out of range ($0-$FFFFFF)");
|
||||
break;
|
||||
}
|
||||
|
||||
*locp++ = (uint32_t)eval >> 16;
|
||||
*locp++ = ((uint32_t)eval >> 8) & 0xFF;
|
||||
*locp++ = (uint32_t)eval & 0xFF;
|
||||
locp[0] = (uint8_t)((eval >> 16) & 0xFF);
|
||||
locp[1] = (uint8_t)((eval >> 8) & 0xFF);
|
||||
locp[2] = (uint8_t)(eval & 0xFF);
|
||||
break;
|
||||
|
||||
// This is a 16bit absolute address into a 24bit field
|
||||
case FU_DSPADR16:
|
||||
if (eval >= 0x10000)
|
||||
{
|
||||
error("address out of range ($0000-$FFFF)");
|
||||
error("address out of range ($0-$FFFF)");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -838,7 +841,7 @@ int ResolveFixups(int sno)
|
|||
case FU_DSPIMM12:
|
||||
if (eval >= 0x1000)
|
||||
{
|
||||
error("immediate out of range ($000-$FFF)");
|
||||
error("immediate out of range ($0-$FFF)");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -851,7 +854,7 @@ int ResolveFixups(int sno)
|
|||
case FU_DSPIMM8:
|
||||
if (eval >= 0x100)
|
||||
{
|
||||
error("immediate out of range ($00-$FF)");
|
||||
error("immediate out of range ($0-$FF)");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -948,6 +951,12 @@ int ResolveAllFixups(void)
|
|||
ResolveFixups(DATA);
|
||||
DEBUG printf("Resolving 6502 sections...\n");
|
||||
ResolveFixups(M6502); // Fixup 6502 section (if any)
|
||||
DEBUG printf("Resolving DSP56001 P: sections...\n");
|
||||
ResolveFixups(M56001P); // Fixup 56001 P: section (if any)
|
||||
DEBUG printf("Resolving DSP56001 X: sections...\n");
|
||||
ResolveFixups(M56001X); // Fixup 56001 X: section (if any)
|
||||
DEBUG printf("Resolving DSP56001 Y: sections...\n");
|
||||
ResolveFixups(M56001Y); // Fixup 56001 Y: section (if any)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
4
sect.h
4
sect.h
|
@ -54,7 +54,9 @@
|
|||
#define D_ZEROFILL(n) {chcheck(n); memset(chptr, 0, n); chptr+=n; sloc+=n; \
|
||||
ch_size+=n; if (orgactive) orgaddr+=n;}
|
||||
|
||||
#define NSECTS 16 // Max. number of sections
|
||||
//OK, this is bad, mmkay? The constants defined in rmac.h are used as indices into an array which means that this was never meant to be defined this way--at least if it was, it was a compromise that has come home to bite us all in the ass. !!! FIX !!!
|
||||
//#define NSECTS 16 // Max. number of sections
|
||||
#define NSECTS 256 // Max. number of sections
|
||||
|
||||
// Tunable (storage) definitions
|
||||
#define CH_THRESHOLD 32 // Minimum amount of space in code chunk
|
||||
|
|
51
symbol.c
51
symbol.c
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
#include "symbol.h"
|
||||
#include "dsp56k.h"
|
||||
#include "error.h"
|
||||
#include "listing.h"
|
||||
#include "object.h"
|
||||
|
@ -35,6 +36,9 @@ static uint8_t tdb_text[8] = {
|
|||
'a', 't', 'd', '!', 'b', SPACE, SPACE, SPACE
|
||||
};
|
||||
|
||||
// Internal function prototypes
|
||||
static uint16_t WriteLODSection(int, uint16_t);
|
||||
|
||||
|
||||
//
|
||||
// Initialize symbol table
|
||||
|
@ -332,6 +336,53 @@ uint32_t sy_assign_ELF(uint8_t * buf, uint8_t *(* construct)())
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// Helper function for dsp_lod_symbols
|
||||
//
|
||||
static uint16_t WriteLODSection(int section, uint16_t symbolCount)
|
||||
{
|
||||
for(SYM * sy=sdecl; sy!=NULL; sy=sy->sdecl)
|
||||
{
|
||||
// Export vanilla labels (but don't make them global). An exception is
|
||||
// made for equates, which are not exported unless they are referenced.
|
||||
if (sy->stype == LABEL && lsym_flag
|
||||
&& (sy->sattr & (DEFINED | REFERENCED)) != 0
|
||||
&& (*sy->sname != '.')
|
||||
&& (sy->sattr & GLOBAL) == 0
|
||||
&& (sy->sattr & (section)))
|
||||
{
|
||||
sy->senv = symbolCount++;
|
||||
D_printf("%-19s I %.6" PRIX64 "\n", sy->sname, sy->svalue);
|
||||
}
|
||||
}
|
||||
|
||||
return symbolCount;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Dump LOD style symbols into the passed in buffer
|
||||
//
|
||||
void DumpLODSymbols(void)
|
||||
{
|
||||
D_printf("_SYMBOL P\n");
|
||||
uint16_t count = WriteLODSection(M56001P, 0);
|
||||
|
||||
D_printf("_SYMBOL X\n");
|
||||
count = WriteLODSection(M56001X, count);
|
||||
|
||||
D_printf("_SYMBOL Y\n");
|
||||
count = WriteLODSection(M56001Y, count);
|
||||
|
||||
D_printf("_SYMBOL L\n");
|
||||
count = WriteLODSection(M56001L, count);
|
||||
|
||||
// TODO: I've seen _SYMBOL N in there but no idea what symbols it needs...
|
||||
//D_printf("_SYMBOL N\n");
|
||||
//WriteLODSection(M56001?, count);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Convert string to uppercase
|
||||
//
|
||||
|
|
1
symbol.h
1
symbol.h
|
@ -51,6 +51,7 @@ void ForceUndefinedSymbolsGlobal(void);
|
|||
int symtable(void);
|
||||
uint32_t sy_assign(uint8_t *, uint8_t *(*)());
|
||||
uint32_t sy_assign_ELF(uint8_t *, uint8_t *(*)());
|
||||
void DumpLODSymbols(void);
|
||||
uint8_t * GetSymbolNameByUID(uint32_t);
|
||||
|
||||
#endif // __SYMBOL_H__
|
||||
|
|
2
token.c
2
token.c
|
@ -1171,7 +1171,7 @@ DEBUG { printf("TokenizeLine: Calling fpop() from SRC_IFILE...\n"); }
|
|||
}
|
||||
|
||||
// Make j = -1 if user tries to use a RISC register while in 68K mode
|
||||
if (!(rgpu || rdsp) && ((TOKEN)j >= KW_R0 && (TOKEN)j <= KW_R31))
|
||||
if (!(rgpu || rdsp || dsp56001) && ((TOKEN)j >= KW_R0 && (TOKEN)j <= KW_R31))
|
||||
{
|
||||
j = -1;
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
// Release Information
|
||||
|
||||
#define MAJOR 1 // Major version number
|
||||
#define MINOR 13 // Minor version number
|
||||
#define PATCH 5 // Patch release number
|
||||
#define MAJOR 2 // Major version number
|
||||
#define MINOR 0 // Minor version number
|
||||
#define PATCH 0 // Patch release number
|
||||
|
||||
#endif // __VERSION_H__
|
||||
|
||||
|
|
Loading…
Reference in New Issue