Handle "label" and "segment" attributes for assembler output.
git-svn-id: svn://svn.cc65.org/cc65/trunk@5594 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
114
src/sp65/asm.c
114
src/sp65/asm.c
@@ -38,6 +38,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "chartype.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@@ -55,19 +56,34 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void WriteAsmFile (const StrBuf* Data, const Collection* A)
|
static int ValidAsmLabel (const char* L)
|
||||||
/* Write the contents of Data to the given file in assembler (ca65) format */
|
/* Check an assembler label for validity */
|
||||||
|
{
|
||||||
|
/* Must begin with underscore or alphabetic character */
|
||||||
|
if (*L != '_' && !IsAlpha (*L)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++L;
|
||||||
|
|
||||||
|
/* Remainder must be as above plus digits */
|
||||||
|
while (*L) {
|
||||||
|
if (*L != '_' && !IsAlNum (*L)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ok */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned GetBytesPerLine (const Collection* A)
|
||||||
|
/* Return the number of bytes per line from the attribute collection A */
|
||||||
{
|
{
|
||||||
FILE* F;
|
|
||||||
const char* D;
|
|
||||||
unsigned Size;
|
|
||||||
unsigned Base = 16;
|
|
||||||
unsigned BytesPerLine = 16;
|
|
||||||
char C;
|
char C;
|
||||||
|
unsigned BytesPerLine = 16;
|
||||||
|
|
||||||
/* Get the file name */
|
|
||||||
const char* Name = NeedAttrVal (A, "name", "write");
|
|
||||||
|
|
||||||
/* Check for a bytesperline attribute */
|
/* Check for a bytesperline attribute */
|
||||||
const char* V = GetAttrVal (A, "bytesperline");
|
const char* V = GetAttrVal (A, "bytesperline");
|
||||||
@@ -75,13 +91,76 @@ void WriteAsmFile (const StrBuf* Data, const Collection* A)
|
|||||||
(BytesPerLine < 1 || BytesPerLine > 64)) {
|
(BytesPerLine < 1 || BytesPerLine > 64)) {
|
||||||
Error ("Invalid value for attribute `bytesperline'");
|
Error ("Invalid value for attribute `bytesperline'");
|
||||||
}
|
}
|
||||||
|
return BytesPerLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned GetBase (const Collection* A)
|
||||||
|
/* Return the number base from the attribute collection A */
|
||||||
|
{
|
||||||
|
char C;
|
||||||
|
unsigned Base = 16;
|
||||||
|
|
||||||
/* Check for a base attribute */
|
/* Check for a base attribute */
|
||||||
V = GetAttrVal (A, "base");
|
const char* V = GetAttrVal (A, "base");
|
||||||
if ((V && sscanf (V, "%u%c", &Base, &C) != 1) ||
|
if ((V && sscanf (V, "%u%c", &Base, &C) != 1) ||
|
||||||
(Base != 2 && Base != 10 && Base != 16)) {
|
(Base != 2 && Base != 10 && Base != 16)) {
|
||||||
Error ("Invalid value for attribute `base'");
|
Error ("Invalid value for attribute `base'");
|
||||||
}
|
}
|
||||||
|
return Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char* GetLabel (const Collection* A)
|
||||||
|
/* Return the assembler label from the attribute collection A */
|
||||||
|
{
|
||||||
|
/* Check for a label attribute */
|
||||||
|
const char* Label = GetAttrVal (A, "label");
|
||||||
|
if (Label && !ValidAsmLabel (Label)) {
|
||||||
|
Error ("Invalid value for attribute `label'");
|
||||||
|
}
|
||||||
|
return Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const char* GetSegment (const Collection* A)
|
||||||
|
/* Return the segment name from the attribute collection A */
|
||||||
|
{
|
||||||
|
/* Check for a label attribute */
|
||||||
|
const char* Seg = GetAttrVal (A, "segment");
|
||||||
|
if (Seg && !ValidAsmLabel (Seg)) {
|
||||||
|
Error ("Invalid value for attribute `segment'");
|
||||||
|
}
|
||||||
|
return Seg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void WriteAsmFile (const StrBuf* Data, const Collection* A)
|
||||||
|
/* Write the contents of Data to the given file in assembler (ca65) format */
|
||||||
|
{
|
||||||
|
FILE* F;
|
||||||
|
const char* D;
|
||||||
|
unsigned Size;
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the file name */
|
||||||
|
const char* Name = NeedAttrVal (A, "name", "write");
|
||||||
|
|
||||||
|
/* Check the number of bytes per line */
|
||||||
|
unsigned BytesPerLine = GetBytesPerLine (A);
|
||||||
|
|
||||||
|
/* Get the number base */
|
||||||
|
unsigned Base = GetBase (A);
|
||||||
|
|
||||||
|
/* Get the assembler label */
|
||||||
|
const char* Label = GetLabel (A);
|
||||||
|
|
||||||
|
/* Get the segment */
|
||||||
|
const char* Segment = GetSegment (A);
|
||||||
|
|
||||||
/* Open the output file */
|
/* Open the output file */
|
||||||
F = fopen (Name, "w");
|
F = fopen (Name, "w");
|
||||||
@@ -98,6 +177,17 @@ void WriteAsmFile (const StrBuf* Data, const Collection* A)
|
|||||||
ProgName,
|
ProgName,
|
||||||
GetVersionAsString ());
|
GetVersionAsString ());
|
||||||
|
|
||||||
|
|
||||||
|
/* If we have a segment defined, output a segment directive */
|
||||||
|
if (Segment) {
|
||||||
|
fprintf (F, ".segment \"%s\"\n\n", Segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have an assembler label, output that */
|
||||||
|
if (Label) {
|
||||||
|
fprintf (F, "%s:\n", Label);
|
||||||
|
}
|
||||||
|
|
||||||
/* Write the data */
|
/* Write the data */
|
||||||
D = SB_GetConstBuf (Data);
|
D = SB_GetConstBuf (Data);
|
||||||
Size = SB_GetLen (Data);
|
Size = SB_GetLen (Data);
|
||||||
|
|||||||
Reference in New Issue
Block a user