Citadel Forums
Home
Company Information
Information Request
Linux How-to Guides
ADSP 21xx Digital Signal
Processing Tutorials
SW Utilities
On-line Order Form
Server Support
Have you found this site useful? Did we save you time? Did we cure your head-ache? Is your hair growing back now?
Please make a donation to help with maintenance.
|
Objective Real-Time Software on the ADSP21XX
ASL21 Compatible Linker Locater
Introduction
In this chapter, we present the full ANSI C source code of a compatible
linker for the ADSP 21XX family of DSP. This linker is currently still
in Beta form. It is intended to become an alternative for the LD21 linker
and would in its final form be able to handle overlays for the 218X series.
The code is written using a 16 bit ANSI C compiler, which ensures
that it would be possible to port the linker to any platform.
Missing features
The current version still has significant features missing, although
it is useable for a small embedded system if one would create the link
and locate response file with care, to locate circular buffers and absolute
segments manually:
- Overlay handling is not supported
- Circular buffers are not located correctly
- Absolute segments are ignored
- Cannot link object library files
Structure
The linker consists of the following code modules:
- ASL21.C - Source Linker. Link source code and initializers into
two monster files target.src and target.ini. All identifiers
are listed in the target.mem file.
- ASG21.C - Garbage disposal. Filters all input files and removes
garbage characters before processing starts.
- ASE21.C - External definition resolver. Attempts to resolve
all external, global and entry definitions.
- ASO21.C - Origin locater. Locate all identifiers according to
the target memory definition in target.loc and creates a memory
map file target.map.
- ASA21.C - Anotater. Anotates the source code with the results
of the linker and locater and creates the executable file target.exe.
Module ASL21
/*********************************************************************
*
* Name: ASL21.C
* Description: ADSP linker/locater
*
* Copyright (c) Aerospace Software Ltd, 1998.
*
* Revision Date Author Remarks
* -------------------------------------------------------------------
* 1.0 July 98 Herman Oosthuysen
*
*********************************************************************/
#define ASL
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "asl21.h"
#undef ASL
/*********************************************************************
* Code
*********************************************************************/
void main(int argc, char *argv[])
{
FILE *cdefile = NULL; /* Assembled Code */
FILE *objfile = NULL; /* Destination label offsets */
FILE *intfile = NULL; /* Initialization data */
FILE *locfile = NULL; /* Link and Locate data */
FILE *memfile = NULL; /* Linker memory map */
FILE *srcfile = NULL; /* Concatenated source file */
FILE *inifile = NULL; /* Concatenated initialization file */
FILE *exefile = NULL; /* Located executable source */
FILE *mapfile = NULL; /* Locator memory map */
FILE *symfile = NULL; /* Symbols */
char filename[12];
char name[12];
char locname[12];
char line[256];
char work[256];
char token[32];
char *search;
char *tok;
int row;
int mpos;
int pos;
int cnt;
int length = 0;
int linking;
int varsize;
char err = 0;
/* show opening lines */
asl_copyright_display();
/* Argument error handler */
if(argc < 2)
{
printf("Example: asl21 targetname\n\n\r");
exit(1);
}
/* Extract the target file name */
pos = strcspn(argv[1], ".");
if(pos > 8)
pos = 8;
for(cnt = 0; cnt < pos; cnt++)
name[cnt] = argv[1][cnt];
name[pos] = 0;
/*
* open all general I/O files
*/
asl_open_files(&inifile, &srcfile, &locfile, &exefile, &mapfile, &symfile, &memfile, filename, name);
/*
* Linker
*/
printf("Linking...\n\r");
linking = TRUE;
/*
* LOC file read till the .OBJECTS keyword
*/
do
{
length = asl_rd_line(locfile, line);
if(length == EOF)
{
printf("%s.loc file error 1\n\r", name);
exit(1);
}
}while(stricmp(line, ASL_OBJ) != 0);
do
{
/* read the first file name from the list */
length = asl_rd_line(locfile, line);
if(length == EOF)
{
printf("%s.loc file error 2\n\r", name);
exit(1);
}
/*
* Exit upon .ENDOBJECTS keyword
*/
if(stricmp(line, ASL_EOBJ) != 0)
{
/*
* open all the link files
*/
asl_link_files(&cdefile, &objfile, &intfile, line, filename, locname);
/*
* Append the code and constants to the monster Source file
*/
asl_concat_src(cdefile, srcfile);
asl_concat_src(intfile, inifile);
/*
* OBJ file add object information to the Linker .mem file
*/
asl_parse_module(objfile, memfile, locname, &row);
asl_parse_label(objfile, memfile, &row);
asl_parse_modsize(objfile, memfile, &row);
asl_parse_variable(objfile, memfile, &row);
asl_parse_global(objfile, memfile, &row);
asl_parse_entry(objfile, memfile, &row);
asl_parse_external(objfile, memfile, &row);
}
else
linking = FALSE;
}while(linking);
printf("Linker Done!\n\n\r");
/*
* Resolve extern definitions
*/
fclose(memfile);
strcpy(filename, name);
strcat(filename, ".mem");
memfile = fopen(filename, "rb");
err = ase_err_check(memfile, mapfile, name);
/*
* Locate the code and create a map file of all label addresses
*/
err = aso_org(memfile, locfile, inifile, mapfile, name);
/*
* Create and Annotate the exe file from the monster src file
*/
fclose(inifile);
strcpy(filename, name);
strcat(filename, ".ini");
inifile = fopen(filename, "rb");
fclose(srcfile);
strcpy(filename, name);
strcat(filename, ".src");
srcfile = fopen(filename, "rb");
fclose(mapfile);
strcpy(filename, name);
strcat(filename, ".map");
mapfile = fopen(filename, "rb");
asa_annotate(inifile, srcfile, exefile, mapfile);
/* Close all the files */
flushall();
fcloseall();
printf("\n\rCheers, have fun!\n\r");
exit(0);
}
/*********************************************************************
* Name: asl_copyright_display
* Description: display copyright notice in files
* Constraints: none
*********************************************************************/
void asl_copyright_display(void)
{
printf("\n\r%s\n\r", ASL_NOTICE1);
printf("%s\n\r", ASL_NOTICE2);
printf("%s\n\n\r", ASL_NOTICE3);
}
/*********************************************************************
* Name: asl_copyright_file
* Description: print copyright notice in files
* Constraints: none
*********************************************************************/
void asl_copyright_files(FILE *file)
{
fprintf(file, "%s\n", ASL_NOTICE1);
fprintf(file, "%s\n", ASL_NOTICE2);
fprintf(file, "%s\n\n", ASL_NOTICE3);
}
/*********************************************************************
* Name: asl_open_files
* Description: open all the general I/O files
* Constraints: none
*********************************************************************/
void asl_open_files(FILE **inifile, FILE **srcfile, FILE **locfile, FILE **exefile,
FILE **mapfile, FILE **symfile, FILE **memfile,
char *filename, char *name)
{
/* build a concatenated initialization file name */
strcpy(filename, name);
strcat(filename, ".ini");
*inifile = fopen(filename, "wb");
if(*inifile == NULL)
{
printf("Ini file %s error 6\n\r", name);
exit(1);
}
/* build a concatenated source file name */
strcpy(filename, name);
strcat(filename, ".src");
*srcfile = fopen(filename, "wb");
if(*srcfile == NULL)
{
printf("Src file %s error 6\n\r", name);
exit(1);
}
/* build a Link and Locate data file name */
strcpy(filename, name);
strcat(filename, ".loc");
asg_filter(filename);
*locfile = fopen(filename, "rb");
if(*locfile == NULL)
{
printf("Loc file %s error 6\n\r", name);
exit(1);
}
/* build a located executable file name */
strcpy(filename, name);
strcat(filename, ".exe");
*exefile = fopen(filename, "wb");
if(*exefile == NULL)
{
printf("Exe file %s error 7\n\r", name);
exit(1);
}
/* build a locater memory map file name */
strcpy(filename, name);
strcat(filename, ".map");
*mapfile = fopen(filename, "wb");
if(*mapfile == NULL)
{
printf("Map file %s error 8\n\r", name);
exit(1);
}
asl_copyright_files(*mapfile);
/* build a locater symbol file name */
strcpy(filename, name);
strcat(filename, ".sym");
*symfile = fopen(filename, "wb");
if(*symfile == NULL)
{
printf("%s.sym file error 9\n\r", name);
exit(1);
}
asl_copyright_files(*symfile);
/* build a linker memory map file name */
strcpy(filename, name);
strcat(filename, ".mem");
*memfile = fopen(filename, "wb");
if(*memfile == NULL)
{
printf("%s.mem file error 10\n\r", name);
exit(1);
}
asl_copyright_files(*memfile);
}
/*********************************************************************
* Name: asl_link_files
* Description: open all the link files
* Constraints: none
*********************************************************************/
void asl_link_files(FILE **cdefile, FILE **objfile, FILE **intfile,
char *line, char *filename, char *name)
{
int pos;
int cnt;
/* Extract the target file name */
pos = strcspn(line, ".");
if(pos > 8)
pos = 8;
for(cnt = 0; cnt < pos; cnt++)
name[cnt] = line[cnt];
name[pos] = 0;
/* build a code file name */
strcpy(filename, name);
strcat(filename, ".cde");
asg_filter(filename);
*cdefile = fopen(filename, "rb");
if(*cdefile == NULL)
{
printf("%s.cde file error 3\n\r", name);
exit(1);
}
/* build an object file name */
strcpy(filename, name);
strcat(filename, ".obj");
asg_filter(filename);
*objfile = fopen(filename, "rb");
if(*objfile == NULL)
{
printf("%s.obj file error 4\n\r", name);
exit(1);
}
/* build an initialization file name */
strcpy(filename, name);
strcat(filename, ".int");
asg_filter(filename);
*intfile = fopen(filename, "rb");
if(*intfile == NULL)
{
printf("%s.int file error 5\n\r", name);
exit(1);
}
}
/*********************************************************************
* Name: asl_concat_src
* Description: concatenate the cde to the monster src file
* Constraints: none
*********************************************************************/
void asl_concat_src(FILE *cdefile, FILE *srcfile)
{
int data;
fprintf(srcfile, "\n\n"); /* for readability */
data = fgetc(cdefile);
while(data != EOF)
{
fputc(data, srcfile); /* copy characters */
data = fgetc(cdefile);
}
}
/*********************************************************************
* Name: asl_parse_external
* Description: parse the procedure/variable external definitions in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_external(FILE *objfile, FILE *memfile, int *row)
{
char line[256];
char work[256];
char token[32];
char *tok;
char *search;
int varsize;
int pos;
int mpos;
int length = 0;
/*
* list all externals
*/
fprintf(memfile, "\n");
rewind(objfile);
*row = 0;
do
{
do
{
*row++;
length = asl_rd_line(objfile, line);
if(length != EOF)
{
pos = asl_find_token(line, work, ASC_DNLINK, ASC_DOLLARS);
if(pos > 0)
{
pos = asl_marked_token(line, work, ASC_EXTERN, token, ASC_DOTSPACE);
if(pos > 0)
{
fprintf(memfile, "\n%s %s", ASM_EXTERNAL, token);
do
{
/* find next token */
search = NULL;
tok = strtok(search, ASC_COMMAS);
if(tok == NULL)
break;
else
fprintf(memfile, "\n%s %s", ASM_EXTERNAL, tok);
}while(tok != NULL);
}
}
}
else
pos = 0;
}while((pos == 0) && (length != EOF));
}while(length != EOF);
/*
* end the mem file neatly
*/
fprintf(memfile, "\n\r");
}
/*********************************************************************
* Name: asl_parse_entry
* Description: parse the procedure entry definitions in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_entry(FILE *objfile, FILE *memfile, int *row)
{
char line[256];
char work[256];
char token[32];
char *tok;
char *search;
int varsize;
int pos;
int mpos;
int length = 0;
/*
* list all entrypoints
*/
fprintf(memfile, "\n");
rewind(objfile);
*row = 0;
do
{
do
{
*row++;
length = asl_rd_line(objfile, line);
if(length != EOF)
{
pos = asl_find_token(line, work, ASC_DNLINK, ASC_DOLLARS);
if(pos > 0)
{
pos = asl_marked_token(line, work, ASC_ENTRY, token, ASC_DOTSPACE);
if(pos > 0)
{
fprintf(memfile, "\n%s %s", ASM_ENTRY, token);
do
{
/* find next token */
search = NULL;
tok = strtok(search, ASC_COMMAS);
if(tok == NULL)
break;
else
fprintf(memfile, "\n%s %s", ASM_ENTRY, tok);
}while(tok != NULL);
}
}
}
else
pos = 0;
}while((pos == 0) && (length != EOF));
}while(length != EOF);
}
/*********************************************************************
* Name: asl_parse_global
* Description: parse the global definitions in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_global(FILE *objfile, FILE *memfile, int *row)
{
char line[256];
char work[256];
char token[32];
char *tok;
char *search;
int varsize;
int pos;
int mpos;
int length = 0;
/*
* list all globals
*/
fprintf(memfile, "\n");
rewind(objfile);
*row = 0;
do
{
do
{
*row++;
length = asl_rd_line(objfile, line);
if(length != EOF)
{
pos = asl_find_token(line, work, ASC_DNLINK, ASC_DOLLARS);
if(pos > 0)
{
pos = asl_marked_token(line, work, ASC_GLOBAL, token, ASC_DOTSPACE);
if(pos > 0)
{
fprintf(memfile, "\n%s %s", ASM_GLOBAL, token);
do
{
/* find next token */
search = NULL;
tok = strtok(search, ASC_COMMAS);
if(tok == NULL)
break;
else
fprintf(memfile, "\n%s %s", ASM_GLOBAL, tok);
}while(tok != NULL);
}
}
}
else
pos = 0;
}while((pos == 0) && (length != EOF));
}while(length != EOF);
}
/*********************************************************************
* Name: asl_parse_variable
* Description: parse the variable lists in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_variable(FILE *objfile, FILE *memfile, int *row)
{
char line[256];
char work[256];
char token[32];
char *tok;
char *search;
int varsize;
int pos;
int mpos;
int length = 0;
/*
* find all constants/variables
*/
rewind(objfile);
row = 0;
do
{
do
{
row++;
length = asl_rd_line(objfile, line);
if(length != EOF)
{
pos = asl_find_token(line, work, ASC_DNLINK, ASC_DOLLARS);
if(pos > 0)
{
pos = asl_find_token(line, work, ASC_VAR, ASC_DOTCOMMA);
if(pos > 0)
{
fprintf(memfile, "\n\n%s", ASM_SPACE);
pos = asl_find_token(line, work, ASC_PM, ASC_DOTCOMMA);
if(pos > 0)
fprintf(memfile, " %s", ASM_PM_SEG);
pos = asl_find_token(line, work, ASC_DM, ASC_DOTCOMMA);
if(pos > 0)
fprintf(memfile, " %s", ASM_DM_SEG);
pos = asl_find_token(line, work, ASC_CIRC, ASC_COMMAS);
if(pos > 0)
fprintf(memfile, "\n%s", ASM_CIRCULAR);
pos = asl_marked_token(line, work, ASC_SEGNAME, token, ASC_DOTCOMMA);
if(pos > 0)
fprintf(memfile, "\n%s %s", ASM_SEGMENT, token);
else
fprintf(memfile, "\n%s %s", ASM_SEGMENT, ASM_DONTCARE);
/* variable and size list */
varsize = 0;
pos = asl_marked_token(line, work, ASC_NAME, token, ASC_COMMAS);
if(pos > 0)
{
fprintf(memfile, "\n%s %s", ASM_VARIABLE, token);
do
{
/* find next token */
search = NULL;
tok = strtok(search, ASC_COMMAS);
if(tok == NULL)
{
if(!varsize)
fprintf(memfile, " %s", ASM_DEF_SIZE);
break;
}
else
{
if(isdigit(tok[1]))
{
varsize = 1;
fprintf(memfile, " %s", &tok[1]);
}
else
{
varsize = 0;
fprintf(memfile, "\n%s %s", ASM_VARIABLE, tok);
}
}
}while(tok != NULL);
}
}
}
}
else
pos = 0;
}while((pos == 0) && (length != EOF));
}while(length != EOF);
}
/*********************************************************************
* Name: asl_parse_modsize
* Description: parse the module size in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_modsize(FILE *objfile, FILE *memfile, int *row)
{
char line[256];
char work[256];
char token[32];
int pos;
int mpos;
int length = 0;
/*
* find the module code size
*/
rewind(objfile);
row = 0;
do
{
row++;
length = asl_rd_line(objfile, line);
if(length != EOF)
{
mpos = asl_find_token(line, work, ASC_MODULE, ASC_DOLLARS);
if(mpos > 0)
{
pos = asl_find_token(line, work, ASC_MODOUT, ASC_DOTCOMMA);
if(pos > 0)
{
pos = asl_marked_token(line, work, ASC_MODSIZE, token, ASC_COMMAS);
if(pos > 0)
fprintf(memfile, "\n\n%s %s", ASM_MODSIZE, token);
}
}
}
}while(length != EOF);
}
/*********************************************************************
* Name: asl_parse_label
* Description: parse the label references in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_label(FILE *objfile, FILE *memfile, int *row)
{
char line[256];
char work[256];
char token[32];
int pos;
int length = 0;
/*
* find all label addresses
* labels are in PM by definition
*/
fprintf(memfile, "\n\n%s %s", ASM_SPACE, ASM_PM_SEG);
do
{
do
{
*row++;
length = asl_rd_line(objfile, line);
if(length != EOF)
{
pos = asl_find_token(line, work, ASC_DNLINK, ASC_DOLLARS);
if(pos > 0)
{
pos = asl_marked_token(line, work, ASC_LABEL, token, ASC_DOTSPACE);
if(pos > 0)
fprintf(memfile, "\n%s %s", ASM_LABEL, token);
pos = asl_marked_token(line, work, ASC_OFFSET, token, ASC_COMMAS);
if(pos > 0)
fprintf(memfile, " %s", token);
}
}
else
pos = 0;
}while((pos == 0) && (length != EOF));
}while(length != EOF);
}
/*********************************************************************
* Name: asl_parse_module
* Description: parse the module name line in the OBJ file
* Constraints: none
*********************************************************************/
void asl_parse_module(FILE *objfile, FILE *memfile, char *name, int *row)
{
char line[256];
char work[256];
char token[32];
int mpos;
int pos;
int length = 0;
/*
* find module and segment names in $m line in obj file
* the PM/DM indication in the module line is superfluous,
* so don't parse it.
*/
*row = 0;
fprintf(memfile, "\n\n%s = %s.obj", ASM_FILE, name);
do
{
*row++;
length = asl_rd_line(objfile, line);
if(length == EOF)
{
printf("%s.obj file error 11 line %u\n\r", name, row);
exit(1);
}
mpos = asl_find_token(line, work, ASC_MODULE, ASC_DOLLARS);
if(mpos > 0)
{
pos = asl_marked_token(line, work, ASC_NAME, token, ASC_COMMAS);
if(pos > 0)
fprintf(memfile, "\n%s %s", ASM_MODULE, token);
else
fprintf(memfile, "\n%s %s", ASM_MODULE, ASM_UNKNOWN);
pos = asl_marked_token(line, work, ASC_ABSOLUTE, token, ASC_COMMAS);
if(pos > 0)
fprintf(memfile, "\n%s %s", ASM_ORIGIN, token);
pos = asl_marked_token(line, work, ASC_SEGNAME, token, ASC_COMMAS);
if(pos > 0)
fprintf(memfile, "\n%s %s", ASM_SEGMENT, token);
else
fprintf(memfile, "\n%s %s", ASM_SEGMENT, ASM_DONTCARE);
}
}while((mpos == 0) && (length != EOF));
}
/*********************************************************************
* Name: asl_find_token
* Description: Find a known string token
* Constraints: return the token length in AX
* returns zero if no matching token found
*********************************************************************/
int asl_find_token(char *line, char *work, char *token, char *delimiters)
{
int len;
char *search;
char *tok;
len = strlen(token);
strcpy(work, line);
search = work;
/* read until the token matches */
do
{
tok = strtok(search, delimiters);
search = NULL;
}while(((strncmp(tok, token, len)) != 0) &&
(tok != NULL));
/* test the token */
if(tok == NULL)
len = 0;
return len;
}
/*********************************************************************
* Name: asl_marked_token
* Description: Find a string token following a marker string
* Constraints: return the token length in AX
* returns zero if no matching token found
*********************************************************************/
int asl_marked_token(char *line, char *work, char *marker, char *token, char *delimiters)
{
int len;
char *search;
char *tok;
len = strlen(marker);
strcpy(work, line);
search = work;
/* read tokens until the marker matches */
do
{
tok = strtok(search, delimiters);
search = NULL;
}while(((strncmp(tok, marker, len)) != 0) &&
(tok != NULL));
/* strip the marker from the token */
if(tok != NULL)
strcpy(token, &tok[len]);
else
len = 0;
return len;
}
/*********************************************************************
* Name: asl_rd_line
* Description: Read a line from a file, skipping empty lines
* Constraints: return the length read in AX
*********************************************************************/
int asl_rd_line(FILE *infile, char *line)
{
int cnt = 0;
do
{
line[cnt] = fgetc(infile);
}while((line[cnt] != EOF) && (iscntrl(line[cnt])));
while((line[cnt] != EOF) && (!iscntrl(line[cnt])))
{
cnt++;
line[cnt] = fgetc(infile);
}
if(line[cnt] == EOF)
cnt = EOF;
line[cnt] = 0;
return cnt;
}
/*************************** EOF - ASL21 ****************************/
|
Module ASG21
/*********************************************************************
*
* Name: asg21.c
* Description: Garbage removal
* Filter garbage characters from an input file
*
* Copyright (c) Aerospace Software Ltd, 1998.
*
* Revision Date Author Remarks
* -------------------------------------------------------------------
* 1.0 July 98 Herman Oosthuysen
*
*********************************************************************/
#define ASG
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "asl21.h"
#undef ASG
/*********************************************************************
* Code
*********************************************************************/
/*********************************************************************
* Name: asg_filter
* Description: Filter garbage characters from a file
* Constraints: none
*********************************************************************/
void asg_filter(char *filename)
{
FILE *tmpfile;
FILE *infile;
int data = 0;
int work;
/*
* Open the files for filtering
*/
infile = fopen(filename, "rb");
remove(ASG_TMPFILE);
tmpfile = fopen(ASG_TMPFILE, "wb");
if((tmpfile == NULL) || (infile == NULL))
{
printf("Garbage filter File I/O Error. Disk Full?\n\r");
exit(1);
}
/*
* Filter out all garbage characters in the source files
* and end it with a single CPM EOF marker
* to ensure that the text string parsing algorithms will
* work reliably.
*
* Allow characters from Space to Tilde, as well as
* Line Feed, Cariage Return and Tab only,
* while removing all other garbage.
*/
while(data != EOF)
{
data = fgetc(infile);
work = data;
if(((work >= ASG_SP) && (work <= ASG_TL)) ||
(work == ASG_CR) || (work == ASG_LF) || (work == ASG_HT))
fputc(work, tmpfile);
}
fprintf(tmpfile, "\n\r");
fputc(ASG_SIB, tmpfile);
/*
* Rename the files
*/
fclose(infile);
fclose(tmpfile);
remove(filename);
rename(ASG_TMPFILE, filename);
}
|
Module ASE21
/*********************************************************************
*
* Name: ASE21.C
* Description: ADSP linker/locater external definition resolver
* Verify that all external definitions can be resolved
* List unresolved externals on screen and in the map file
*
* Copyright (c) Aerospace Software Ltd, 1998.
*
* Revision Date Author Remarks
* -------------------------------------------------------------------
* 1.0 July 98 Herman Oosthuysen
*
*********************************************************************/
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "asl21.h"
/*********************************************************************
* Code
*********************************************************************/
/*********************************************************************
* Name: ase_err_check
* Description: scan MEM file and resolve entry, external and global defs
* ensure that for every external, there is either a global
* or an entry definition.
* Constraints: returns ar = err, 0 = OK, 1 = error
*********************************************************************/
int ase_err_check(FILE *memfile, FILE *mapfile, char *name)
{
FILE *tmpfile;
char filename[256];
int data;
int err = 0;
int length;
int len;
int len2;
char line[1024];
char line2[1024];
char *token;
char *extlabel;
char *glblabel;
char *search;
int found;
/*
* copy the mem file to a temporary file
* to enable execution of a comparitive search
*/
printf("Cross Checking...\n\r");
rewind(memfile);
strcpy(filename, name);
strcat(filename, ".mem");
strcpy(filename, name);
strcat(filename, ".tmp");
remove(filename);
tmpfile = fopen(filename, "wb");
if(tmpfile != NULL)
{
/*
* simple file copy
*/
data = fgetc(memfile);
while(data != EOF)
{
fputc(data, tmpfile);
data = fgetc(memfile);
}
fclose(tmpfile);
tmpfile = fopen(filename, "rb");
rewind(memfile);
/*
* Wind up the mapfile
*/
rewind(mapfile);
asl_copyright_files(mapfile);
/*
* find and test all the external definitions
* every .EXTERNAL should have either a .ENTRY or .GLOBAL
*/
do
{
/*
* find an external definition in the MEM file
*/
do
{
length = asl_rd_line(memfile, line);
token = strtok(line, ASC_SPACE);
}while(((stricmp(token, ASM_EXTERNAL)) != 0) && (length != EOF));
search = NULL;
extlabel = strtok(search, ASC_SPACE);
/*
* find a matching entry/global definition in the TMP file
*/
if(extlabel != NULL)
{
rewind(tmpfile);
err = 1;
do
{
found = FALSE;
do
{
len2 = asl_rd_line(tmpfile, line2);
token = strtok(line2, ASC_SPACE);
found = (stricmp(token, ASM_GLOBAL) == 0);
found |= (stricmp(token, ASM_ENTRY) == 0);
}while((!found) && (len2 != EOF));
if(found)
{
search = NULL;
glblabel = strtok(search, ASC_SPACE);
err = strcmp(glblabel, extlabel);
}
}while((err != 0) && (len2 != EOF));
/*
* Display and save unresolved externals
*/
if(err != 0)
{
err = 0;
printf("Unresolved external definition %s\n\r", extlabel);
fprintf(mapfile, "Unresolved external definition %s\n", extlabel);
}
}
}while(length != EOF);
}
else
{
printf("File I/O error - disk full?\n\r");
err = 1;
}
fclose(tmpfile);
remove(filename);
printf("Cross Checker done!\n\n\r");
return err;
}
/************************* EOF-ASE21.C ******************************/
|
Module ASO21
/*********************************************************************
*
* Name: ASO21.C
* Description: Origin locater
* Sort the contents of the mem file and create a located
* map file according to the information in the loc file.
*
* Copyright (c) Aerospace Software Ltd, 1998.
*
* Revision Date Author Remarks
* -------------------------------------------------------------------
* 1.0 July 98 Herman Oosthuysen
*
*********************************************************************/
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "asl21.h"
/*********************************************************************
* Code
*********************************************************************/
char aso_pmfill[ASO_MEMSIZE]; /* overlap tracking */
char aso_dmfill[ASO_MEMSIZE];
/*********************************************************************
* Name: aso_org
* Description: scan MEM file and locate the code and variables
* Constraints: returns ar = err, 0 = OK, 1 = error
* Since the addressable space of this processor is small, simply open
* large arrays for data and code space labels, to look for overlaps, while
* performing the actual locating directly to a map file.
*
* Note: Does not locate circular buffers or absolute segments
*********************************************************************/
int aso_org(FILE *memfile, FILE *locfile, FILE *inifile, FILE *mapfile, char *name)
{
int err = 0;
int loclength = 0;
int locln = 0;
int memlength = 0;
int memln = 0;
char line[1024] = "";
char segname[256] = "";
char *token;
char *search;
char modstr[32] = ASM_DONTCARE;
char spacestr[32] = ASM_PM_SEG;
char segstr[32] = ASM_DONTCARE;
char labelstr[32] = "";
char varstr[32] = "";
int space = 0;
int modstart = 0;
int modend = 0;
int modsize = 0;
int segstart = 0;
int segend = 0;
int address = 0;
int labeloffset = 0;
int varsize = 0;
int overlay = FALSE;
int cnt;
int haveseg = FALSE;
int havemod = FALSE;
/* File error check */
printf("Locating...\n\r");
if((memfile == NULL) || (locfile == NULL) ||
(inifile == NULL) || (mapfile == NULL))
{
printf("\n\rFile I/O Error!!! - Disk Full!?\n\r");
exit(1);
}
/*
* rewind the information files
* and append to the mapfile
*/
rewind(memfile);
rewind(locfile);
/*
* Flush the overlap checking arrays
*/
for(cnt = 0; cnt < ASO_MEMSIZE; cnt++)
{
aso_pmfill[cnt] = ASO_FREE;
aso_dmfill[cnt] = ASO_FREE;
}
/*
* LOC file read till the .PMSEGMENTS keyword
*/
do
{
locln++;
loclength = asl_rd_line(locfile, line);
if(loclength == EOF)
{
printf("%s.loc file error line = %u, no .PMSEGMENTS definition\n\r", name, locln);
exit(1);
}
}while((stricmp(line, ASL_PMSEG) != 0) &&
(stricmp(line, ASL_DMSEG) != 0));
/*
* Code or data space?
*/
if(stricmp(line, ASL_PMSEG) == 0)
space = ASO_CODESPACE;
else
space = ASO_DATASPACE;
/*
* run over the locfile and locate all segments
* in the memfile
*/
while (loclength != EOF)
{
/*
* find a segment definition in the locfile
* extract the start and end of the segment
*/
token = strtok(line, ASC_SPACE);
strcpy(segname, token);
/*
* Code or data space?
* put DONTCARE segments in the first available space
*/
if(stricmp(segname, ASL_PMSEG) == 0)
{
space = ASO_CODESPACE;
strcpy(segname, ASM_DONTCARE);
}
else if(stricmp(segname, ASL_DMSEG) == 0)
{
space = ASO_DATASPACE;
strcpy(segname, ASM_DONTCARE);
}
/*
* end if not a name, but a .END directive
*/
else if(stricmp(segname, ASL_END) == 0)
loclength = EOF;
else
{
/*
* find segment start and ignore comments etc
*/
search = NULL;
token = strtok(search, ASC_SPACE);
if((token != NULL) && ((stricmp(segname, ASM_DONTCARE) != 0)))
{
sscanf(token, "%04X", &segstart);
/* find segment end */
search = NULL;
token = strtok(search, ASC_SPACE);
if((token != NULL) && ((stricmp(segname, ASM_DONTCARE) != 0)))
sscanf(token, "%04X", &segend);
}
}
/*
* run through the memfile and copy everything in this segment
* to the mapfile while simultaneously locating it
* first find the absolute modules and locate them
* then locate all the named segments
* if .SEGMENT is DONTCARE then locate it in the last segment
* assume that memfile has a certain order to it
*/
/* rewind the memfile */
rewind(memfile);
memlength = 0;
address = segstart;
while(memlength != EOF)
{
memln++;
memlength = asl_rd_line(memfile, line);
if(memlength != EOF)
{
/* find the first token */
token = strtok(line, ASC_SPACE);
/*
* .MODULE directive?
*/
if(stricmp(token, ASM_MODULE) == 0)
{
/* find module name */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
havemod = TRUE;
strcpy(modstr, token);
}
}
/*
* .SPACE directive?
*/
else if(stricmp(token, ASM_SPACE) == 0)
{
/* find space type */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(spacestr, token);
}
}
/*
* .SEGMENT directive?
*/
else if(stricmp(token, ASM_SEGMENT) == 0)
{
/* find segment name */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(segstr, token);
if(stricmp(segstr, segname) == 0)
{
/* correct segment: Print info collected to map file */
if(havemod)
{
modstart = address;
fprintf(mapfile, "\n%s %s %04X", ASM_MODULE, modstr, modstart);
havemod = FALSE;
}
fprintf(mapfile, "\n\n%s %s", ASM_SPACE, spacestr);
fprintf(mapfile, "\n%s %s", ASM_SEGMENT, segstr);
overlay = FALSE;
haveseg = TRUE;
}
else
/* wrong segment, loop back */
haveseg = FALSE;
}
}
/*
* If the memfile segment is matching the locfile
* relocate it on the fly to the mapfile
*/
if(haveseg)
{
/*
* .MODSIZE directive?
*/
if(stricmp(token, ASM_MODSIZE) == 0)
{
/* find module size */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
sscanf(token, "%04X", &modsize);
modend = modstart + modsize;
address = modend + 1;
fprintf(mapfile, "\n%s %s %04X %04X %04X", ASM_MODSIZE, modstr, modstart, modend, modsize);
}
}
/*
* .LABEL directive?
*/
else if(stricmp(token, ASM_LABEL) == 0)
{
/* find label name */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(labelstr, token);
/* find label offset */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
/* locate the program label */
sscanf(token, "%04X", &labeloffset);
for(cnt = address; cnt <= (modstart + labeloffset); cnt++)
{
/* verify that address is still within limits */
if((address >= segend) && (stricmp(segstr, ASM_DONTCARE) != 0))
{
printf("Segment %s overflow at address %04X\n\r", segstr, address);
fprintf(mapfile, "\nERROR: Segment %s overflow at address %04X", segstr, address);
break;
}
/*
* mark the start of an overlay, since it
* may very well be an error!
*/
if(aso_pmfill[cnt] == ASO_INUSE)
{
if(overlay == FALSE)
fprintf(mapfile, "\n%s", ASL_OVERLAY);
overlay = TRUE;
}
aso_pmfill[cnt] = ASO_INUSE;
}
address = modstart + labeloffset;
fprintf(mapfile, "\n%s %s %04X", ASM_LABEL, labelstr, address);
/* next address */
address++;
}
}
}
/*
* .VARIABLE directive?
*/
else if(stricmp(token, ASM_VARIABLE) == 0)
{
/* find variable name */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(varstr, token);
/* find variable size */
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
/* locate the variable */
sscanf(token, "%04X", &varsize);
for(cnt = address; cnt <= (address + varsize); cnt++)
{
/* verify that address is still within limits */
if(address >= segend)
{
printf("\n\rSegment %s overflow at address %04X", segstr, address);
fprintf(mapfile, "\nERROR: Segment %s overflow at address %04X", segstr, address);
break;
}
/*
* mark the start of an overlay, since it
* may very well be an error!
*/
if(aso_dmfill[cnt] == ASO_INUSE)
{
if(overlay == FALSE)
fprintf(mapfile, "\n%s", ASL_OVERLAY);
overlay = TRUE;
}
aso_dmfill[cnt] = ASO_INUSE;
}
fprintf(mapfile, "\n%s %s %04X %04X", ASM_VARIABLE, varstr, address, varsize);
/* next address */
address += varsize + 1;
}
}
}
}
}
}
/*
* get the next locfile entry
*/
locln++;
loclength = asl_rd_line(locfile, line);
}
printf("Locater done!\n\n\r");
return err;
}
/************************* EOF-ASO21.C ******************************/
|
Module ASA21
/*********************************************************************
*
* Name: asa21.c
* Description: Annotate the source files with the information in the
* map file.
*
* Copyright (c) Aerospace Software Ltd, 1998.
*
* Revision Date Author Remarks
* -------------------------------------------------------------------
* 1.0 July 98 Herman Oosthuysen
*
*********************************************************************/
#define ANA
#include "dos.h"
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "asl21.h"
#undef ANA
/*********************************************************************
* Code
*********************************************************************/
/*********************************************************************
* Name: Basic source annotation
* Description: copy src to exe file and fix the addresses
* Constraints: Assumes there are no external definition errors since
* these should have been caught by ase21.
* First search the map file locally based on the module
* name, if not found search again globally.
*********************************************************************/
void asa_annotate(FILE *inifile, FILE *srcfile, FILE *exefile,
FILE *mapfile)
{
char line[1024];
char mline[1024];
char work[1024];
char token[32];
char label[32];
char module[32];
char pointer[32];
char space[3];
char pspace[3];
char address[4];
char offset[4];
char code[6];
char fixup[4];
unsigned int codefix;
unsigned int addrfix;
int length;
int mlength;
int spos;
int mpos;
int pos;
int mlen;
int cnt;
int value;
char *tok;
char *lbltok;
char *initok;
char *search;
char first = TRUE;
char coderr = FALSE;
char moderr = TRUE;
int found = FALSE;
/*
* put the file header in the exe file:
* esc esc i
*/
printf("Annotating...\n\r");
fprintf(exefile, "%c%ci\n", ASA_ESC, ASA_ESC);
/*
* scan and copy every line in the src file
* if it has a label then
* scan the map file for the address and fix the code
*/
length = asl_rd_line(srcfile, line);
while(length != EOF)
{
/*
* $m.i,d,rAmodule
* Find the module name and add an offset statement
* to the exe file, of the form:
* @PA
* XXXX
*/
spos = asl_find_token(line, work, ASC_MODULE, ASC_DOLLARS);
if(spos > 0)
{
moderr = TRUE;
spos = asl_marked_token(line, work, ASC_NAME, token, ASC_COMMAS);
if(spos > 0)
{
/*
* search the map file for the module offset
*/
strcpy(module, token);
found = asa_lookup(mapfile, NULL, module, offset, space);
if(found)
{
/*
* Unless this is the first module,
* put a dummy checksum in the exe file, to keep the
* ADI SPL21 utility happy:
* #123456789AB
*/
if(!first)
fprintf(exefile, "%s\n", ASA_DUMMY_SUM);
first = FALSE;
/*
* print the module offset of the form:
* @PA
* XXXX
*/
fprintf(exefile, "%s\n%s\n", ASA_CODE, offset);
moderr = FALSE;
}
}
}
/*
* find the $c24_bit_code
*/
if(!moderr)
{
spos = asl_find_token(line, work, ASC_CODE, ASC_DOLSPACE);
if(spos > 0)
{
/*
* Get the ASCII Hex instruction code string
* skipping the $c leader
*/
tok = strtok(line, ASC_DOLSPACE);
if(tok != NULL)
strcpy(code, &tok[2]);
/*
* see whether there is a label on this line
*/
spos = asl_marked_token(line, work, ASC_UPLINK, token, ASC_DOTSPACE);
if(spos > 0)
{
/*
* search the map file for the label address
* either .LABEL or .VARIABLE
*/
coderr = TRUE;
strcpy(label, token);
found = asa_lookup(mapfile, module, label, address, space);
if(!found)
found = asa_lookup(mapfile, NULL, label, address, space);
/*
* fix the code with the address
* all opcodes carry the address offset by 1 nibble
*/
if(found)
{
codefix = sscanf("%04x", &code[1]);
addrfix = sscanf("%04x", address);
codefix &= ASA_CODE_MASK;
codefix |= addrfix;
sprintf(fixup, "%04x", codefix);
for(cnt = 0; cnt < 4; cnt++)
code[cnt + 1] = fixup[cnt];
}
else
printf("\n\rCode fixup failed in module %s", module);
}
/*
* print the code to the exe file
* in the form:
* XXXXXX
*/
if(!coderr)
fprintf(exefile, "%s\n", code);
else
fprintf(exefile, "CODE FIXUP ERROR!\n");
}
}
/*
* get the next src line to work on
*/
length = asl_rd_line(srcfile, line);
}
/*
* Add the initialized variables in PM and DM
* from the ini file to the exe file.
* Initializer data statements have the following form:
* $iCBAUD_PERIOD 00B400
* Initializer pointer statements have the following form:
* $iCUART_O_PTR ,puart_tx_buffer
* and they can be mixed and/or listed as for this two dimentional
* table:
* $iME_TBL ,pme_init 000000 ,pme_do_nothing 000100 ,pme_start 000000
*/
rewind(inifile);
do
{
/*
* find a variable/constant label
* then get the initializer, which can be either a value or a pointer
*/
length = asl_rd_line(inifile, line);
spos = asl_find_token(line, work, ASC_INIT, ASC_DOLSPACE);
strcpy(work, line); /* save the line */
if(spos > 0)
{
/*
* read the variable/constant label
*/
lbltok = strtok(line, ASC_INITS);
strcpy(label, lbltok);
/*
* find the module name in the ini file
*/
mpos = asl_find_token(line, work, ASC_MODULE, ASC_DOLLARS);
if(mpos > 0)
{
pos = asl_marked_token(line, work, ASC_NAME, token, ASC_COMMAS);
if(pos > 0)
strcpy(module, token);
}
/*
* find the label
*/
if(lbltok != NULL)
{
/*
* Lookup the variable / constant address
* and write and entry in the exe file of the form
* @DA
* xxxx address
* xxxx initializer or
*
* @PA
* xxxx address
* xxxxxx initializer
*/
found = asa_lookup(mapfile, module, label, address, space);
if(!found)
found = asa_lookup(mapfile, NULL, label, address, space);
if(found)
{
if(stricmp(space, ASM_PM_SEG) == 0)
strcpy(space, ASA_CODE);
else if(stricmp(space, ASM_DM_SEG) == 0)
strcpy(space, ASA_DATA);
fprintf(exefile, "%s\n%s\n%s\n", ASA_DUMMY_SUM, space, address);
}
else
printf("Map file entry %s not found\n\r", label);
/*
* strtok gets confused by the search in the map file
* therefore cannot search with a NULL pointer
*/
lbltok = strtok(work, ASC_INITS);
search = lbltok + strlen(lbltok) + 1;
do
{
initok = strtok(search, ASC_COMMAS);
search = initok + strlen(initok) + 1;
if(initok != NULL)
{
/*
* is the string numeric or text?
*/
value = isdigit(initok[0]);
if(value)
{
/*
* numeric = initializer value
* values are always saved in the LSB
* whether PM or DM
*/
strcpy(code, initok);
}
else
{
/*
* text = pointer name
* lookup the pointer value in the map file
* copy and drop the p prefix
*/
strcpy(pointer, &initok[1]);
found = asa_lookup(mapfile, module, pointer, code, pspace);
if(!found)
found = asa_lookup(mapfile, NULL, label, address, space);
/*
* if PM then
* code = code SHL 8
*/
if(found)
{
if(stricmp(space, ASA_CODE) == 0)
strcat(code, ASA_00H);
}
else
printf("Map file pointer %s not found\n\r", pointer);
}
/*
* save the initializer
*/
fprintf(exefile, "%s\n", code);
}
}while(initok != NULL);
}
}
}while(length != EOF);
/*
* put the exe file footer:
* esc esc o
*/
fprintf(exefile, "%s\n%c%co\n", ASA_DUMMY_SUM, ASA_ESC, ASA_ESC);
printf("Annotater done!\n\n\r");
}
/*********************************************************************
* Name: asa_lookup
* Description: find the address and memory space of a token in the
* specified module
* Constraints: if the module == NULL then search global
*********************************************************************/
int asa_lookup(FILE *mapfile, char *module, char *label,
char *address, char *space)
{
char line[1024];
char mod[32];
char *token;
char *search;
int length;
int found = FALSE;
/*
* error check
*/
if(mapfile == NULL)
return found;
rewind(mapfile);
do
{
/*
* read a line
*/
length = asl_rd_line(mapfile, line);
if(length > 0)
{
token = strtok(line, ASC_SPACE);
if(token != NULL)
{
/*
* record the memory space
*/
if(stricmp(token, ASM_SPACE) == 0)
{
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(space, token);
}
}
/*
* record the module
*/
else if((stricmp(token, ASM_MODULE) == 0) &&
(module != NULL))
{
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(mod, token);
}
}
/*
* find the label/variable/module address
*/
if(((stricmp(token, ASM_VARIABLE) == 0) ||
(stricmp(token, ASM_LABEL) == 0) ||
(stricmp(token, ASM_MODULE) == 0)) &&
((stricmp(mod, module) == 0) ||
(module == NULL)))
{
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
/*
* first find the label
*/
if(stricmp(label, token) == 0)
{
/*
* then the address
*/
search = NULL;
token = strtok(search, ASC_SPACE);
if(token != NULL)
{
strcpy(address, token);
found = TRUE;
}
}
}
}
}
}
}while((length != EOF) && (!found));
return found;
}
|
Header file
/*********************************************************************
*
* Name: ASL21.H
* Description: ADSP linker/locater
*
* Copyright (c) Aerospace Software Ltd, 1998.
*
* Revision Date Author Remarks
* -------------------------------------------------------------------
* 1.0 July 98 Herman Oosthuysen
*
*********************************************************************/
#ifdef ASL
#define GLOBAL
#else
#define GLOBAL extern
#endif
/************************** Literals *******************************/
/*
* Copyright notice
*/
#define ASL_NOTICE1 "ASL21 version 1.0, ADSP 21XX Linker/Locater"
#define ASL_NOTICE2 "Copyright (c) Aerospace Software Ltd., 1998."
#define ASL_NOTICE3 "email: aerosoft@agt.net web: www.agt.net/public/aerosoft"
#define TRUE 1
#define PASS 1
#define FALSE 0
#define FAIL 0
/*
* LOC File markers
*/
#define ASL_OBJ ".OBJECTS"
#define ASL_EOBJ ".ENDOBJECTS"
#define ASL_PMSEG ".PMSEGMENTS"
#define ASL_PMEND ".ENDPMSEGMENTS"
#define ASL_DMSEG ".DMSEGMENTS"
#define ASL_DMEND ".ENDDMSEGMENTS"
#define ASL_END ".END"
#define ASL_OVERLAY ".OVERLAY"
/*
* MEM file markers
*/
#define ASM_MODULE ".MODULE"
#define ASM_UNKNOWN "UNKNOWN"
#define ASM_FILE ".FILE"
#define ASM_SPACE ".SPACE"
#define ASM_ORIGIN ".ORIGIN"
#define ASM_SEGMENT ".SEGMENT"
#define ASM_DONTCARE "DONTCARE"
#define ASM_LABEL ".LABEL"
#define ASM_MODSIZE ".MODSIZE"
#define ASM_PM_SEG "PM"
#define ASM_DM_SEG "DM"
#define ASM_CIRCULAR ".CIRCULAR"
#define ASM_VARIABLE ".VARIABLE"
#define ASM_DEF_SIZE "0001"
#define ASM_GLOBAL ".GLOBAL"
#define ASM_ENTRY ".ENTRY"
#define ASM_EXTERNAL ".EXTERNAL"
/*
* CDE file markers
*/
/* $ commands */
#define ASC_CODE "c"
#define ASC_MODULE "m"
#define ASC_INIT "i"
#define ASC_DNLINK "d"
/* dot-comma commands */
#define ASC_VAR "v"
#define ASC_MODIN "i"
#define ASC_MODOUT "o"
#define ASC_UPLINK "u"
#define ASC_PM "p"
#define ASC_DM "d"
/* dot-space commands */
#define ASC_LABEL "l"
#define ASC_ENTRY "e"
#define ASC_GLOBAL "g"
#define ASC_EXTERN "x"
/* comma commands */
#define ASC_NAME "rA"
#define ASC_FIXUP "f"
#define ASC_POINTER "p"
#define ASC_OFFSET "o"
#define ASC_MODSIZE "l"
#define ASC_SEGNAME "n"
#define ASC_ABSOLUTE "a"
#define ASC_VARSIZE "s"
#define ASC_CIRC "c"
/* Command delimiters */
#define ASC_DELIMIT " .,\n\r\x1A\x09\xFF"
#define ASC_DOLLARS "$.\n\r\x1A\x09\xFF"
#define ASC_DOLSPACE "$ \n\r\x1A\x09\xFF"
#define ASC_DOTSPACE " .\n\r\x1A\x09\xFF"
#define ASC_DOTCOMMA ".,\n\r\x1A\x09\xFF"
#define ASC_COMMAS " ,\n\r\x1A\x09\xFF"
#define ASC_SPACE " \n\r\x1A\x09\xFF"
#define ASC_INITS " $i\n\r\x1A\x09\xFF"
/* Locater constants */
#define ASO_MEMSIZE 0x4000
#define ASO_CODESPACE 0
#define ASO_DATASPACE 1
#define ASO_FREE 0
#define ASO_INUSE 1
/* Annotater constants */
#define ASA_ESC 0x1B
#define ASA_CODE_MASK 0x3FFF
#define ASA_DUMMY_SUM "#123456789AB"
#define ASA_CODE "@PA"
#define ASA_DATA "@DA"
#define ASA_00H "00"
/* Garbage filter constants */
#define ASG_TMPFILE "garbage.tmp"
#define ASG_HT 0x09
#define ASG_CR 0x0D
#define ASG_LF 0x0A
#define ASG_SP 0x20
#define ASG_TL 0x7E
#define ASG_SIB 0x1A
/************************** Variables *******************************/
/************************** Prototypes ******************************/
int asl_rd_line(FILE *infile, char *line);
int asl_marked_token(char *line, char *work, char *marker,
char *token, char *delimeters);
int asl_find_token(char *line, char *work, char *token,
char *delimiters);
void asl_concat_src(FILE *cdefile, FILE *srcfile);
void asl_parse_module(FILE *objfile, FILE *memfile, char *name,
int *row);
void asl_parse_label(FILE *objfile, FILE *memfile, int *row);
void asl_parse_modsize(FILE *objfile, FILE *memfile, int *row);
void asl_parse_variable(FILE *objfile, FILE *memfile, int *row);
void asl_parse_global(FILE *objfile, FILE *memfile, int *row);
void asl_parse_entry(FILE *objfile, FILE *memfile, int *row);
void asl_parse_external(FILE *objfile, FILE *memfile, int *row);
void asl_link_files(FILE **cdefile, FILE **objfile, FILE **intfile,
char *line, char *filename, char *name);
void asl_open_files(FILE **inifile, FILE **srcfile, FILE **locfile,
FILE **exefile, FILE **mapfile, FILE **symfile,
FILE **memfile, char *filename, char *name);
void asl_copyright_files(FILE *file);
void asl_copyright_display(void);
int ase_err_check(FILE *memfile, FILE *mapfile, char *name);
int aso_org(FILE *memfile, FILE *locfile, FILE *inifile,
FILE *mapfile, char *name);
void asa_annotate(FILE *inifile, FILE *srcfile, FILE *exefile,
FILE *mapfile);
void asg_filter(char *filename);
int asa_lookup(FILE *mapfile, char *module, char *label,
char *address, char *space);
/****************************** EOF-ASL21.H *************************/
|
Link and Locate Response File Example
UART Link and locate information
Don't put comments in between key word pairs!
List all the object files between these two key words:
.OBJECTS
645ut.obj INT_PM
.ENDOBJECTS
You can put comments here...
Note that unnamed DONTCARE segments will be put in the
first available segment of the right type.
First list the PM segments,
.PMSEGMENTS
INT_PM 0000 2FFF
INT_CONST 3000 3FFF
.ENDPMSEGMENTS
then list the DM segments and
keep the addresses in incrementing order.
.DMSEGMENTS
INT_DM 0000 2FFF
INT_INIT 3000 3FFF
.ENDDMSEGMENTS
.END
|
Operation
All linker and locater object module names and parameters should be
specified in a response file as described above.
If the response file is named target.loc, invoke the linker locater with the following command:
asl target
|
|
|