mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-13 23:36:03 +00:00
Remove old version.
This commit is contained in:
parent
404a7e726d
commit
0cb8000e5f
@ -1,12 +0,0 @@
|
||||
15-July-2001
|
||||
version 0.2
|
||||
removed references to snprintf from dumpobj.c and
|
||||
mlb.c for portability
|
||||
fixed a type cast warning in dumpobj.c compare_gsdlines
|
||||
Removed strcasecmp from macro11.c for portability
|
||||
Removed references to wnewmem.c from makefile (isn't needed)
|
||||
makefile more compatible with non-gnu make and compiler
|
||||
main prints version 0.2
|
||||
|
||||
14-July-2001
|
||||
First release, version 0.1.
|
||||
@ -1,677 +0,0 @@
|
||||
/* Dump and interpret an object file. */
|
||||
|
||||
/*
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rad50.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define WORD(cp) ((*(cp) & 0xff) + ((*((cp)+1) & 0xff) << 8))
|
||||
|
||||
int psectid = 0;
|
||||
char *psects[256];
|
||||
FILE *bin = NULL;
|
||||
int badbin = 0;
|
||||
int xferad = 1;
|
||||
|
||||
char *readrec(FILE *fp, int *len)
|
||||
{
|
||||
int c, i;
|
||||
int chksum;
|
||||
char *buf;
|
||||
|
||||
chksum = 0;
|
||||
|
||||
while(c = fgetc(fp), c != EOF && c == 0)
|
||||
;
|
||||
|
||||
if(c == EOF)
|
||||
return NULL;
|
||||
|
||||
if(c != 1)
|
||||
{
|
||||
fprintf(stderr, "Improperly formatted OBJ file (1)\n");
|
||||
return NULL; // Not a properly formatted file.
|
||||
}
|
||||
|
||||
chksum -= c;
|
||||
|
||||
c = fgetc(fp);
|
||||
if(c != 0)
|
||||
{
|
||||
fprintf(stderr, "Improperly formatted OBJ file (2)\n");
|
||||
return NULL; // Not properly formatted
|
||||
}
|
||||
|
||||
chksum -= c; // even though for 0 the checksum isn't changed...
|
||||
|
||||
c = fgetc(fp);
|
||||
if(c == EOF)
|
||||
{
|
||||
fprintf(stderr, "Improperly formatted OBJ file (3)\n");
|
||||
return NULL;
|
||||
}
|
||||
*len = c;
|
||||
|
||||
chksum -= c;
|
||||
|
||||
c = fgetc(fp);
|
||||
if(c == EOF)
|
||||
{
|
||||
fprintf(stderr, "Improperly formatted OBJ file (4)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*len += (c << 8);
|
||||
|
||||
chksum -= c;
|
||||
|
||||
*len -= 4; // Subtract header and length bytes from length
|
||||
if(*len < 0)
|
||||
{
|
||||
fprintf(stderr, "Improperly formatted OBJ file (5)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = malloc(*len);
|
||||
if(buf == NULL)
|
||||
{
|
||||
fprintf(stderr, "Out of memory allocating %d bytes\n", *len);
|
||||
return NULL; // Bad alloc
|
||||
}
|
||||
|
||||
i = fread(buf, 1, *len, fp);
|
||||
if(i < *len)
|
||||
{
|
||||
free(buf);
|
||||
fprintf(stderr, "Improperly formatted OBJ file (6)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < *len; i++)
|
||||
{
|
||||
chksum -= (buf[i] & 0xff);
|
||||
}
|
||||
|
||||
c = fgetc(fp);
|
||||
c &= 0xff;
|
||||
chksum &= 0xff;
|
||||
|
||||
if(c != chksum)
|
||||
{
|
||||
free(buf);
|
||||
fprintf(stderr, "Bad record checksum, "
|
||||
"calculated=%d, recorded=%d\n", chksum, c);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void dump_bytes(char *buf, int len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < len; i += 8)
|
||||
{
|
||||
printf("\t%3.3o: ", i);
|
||||
for(j = i; j < len && j < i+8; j++)
|
||||
{
|
||||
printf("%3.3o ", buf[j] & 0xff);
|
||||
}
|
||||
|
||||
printf("%*s", (i+8 - j) * 4, "");
|
||||
|
||||
for(j = i; j < len && j < i+8; j++)
|
||||
{
|
||||
int c = buf[j] & 0xff;
|
||||
if(!isprint(c))
|
||||
c = '.';
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
void dump_words(unsigned addr, char *buf, int len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for(i = 0; i < len; i += 8)
|
||||
{
|
||||
printf("\t%6.6o: ", addr);
|
||||
|
||||
for(j = i; j < len && j < i+8; j += 2)
|
||||
{
|
||||
if(len - j >= 2)
|
||||
{
|
||||
unsigned word = WORD(buf + j);
|
||||
printf("%6.6o ", word);
|
||||
}
|
||||
else
|
||||
printf("%3.3o ", buf[j] & 0xff);
|
||||
}
|
||||
|
||||
printf("%*s", (i+8 - j) * 7 / 2, "");
|
||||
|
||||
for(j = i; j < len && j < i+8; j++)
|
||||
{
|
||||
int c = buf[j] & 0xff;
|
||||
if(!isprint(c))
|
||||
c = '.';
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
addr += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void dump_bin(unsigned addr, char *buf, int len)
|
||||
{
|
||||
int chksum; /* Checksum is negative sum of all
|
||||
bytes including header and length */
|
||||
int FBR_LEAD1 = 1, FBR_LEAD2 = 0;
|
||||
int i;
|
||||
unsigned hdrlen = len + 6;
|
||||
|
||||
for(i = 0; i < 8; i++) fputc (0, bin);
|
||||
chksum = 0;
|
||||
if(fputc(FBR_LEAD1, bin) == EOF) return; /* All recs begin with 1,0 */
|
||||
chksum -= FBR_LEAD1;
|
||||
if(fputc(FBR_LEAD2, bin) == EOF) return;
|
||||
chksum -= FBR_LEAD2;
|
||||
|
||||
i = hdrlen & 0xff; /* length, lsb */
|
||||
chksum -= i;
|
||||
if(fputc(i, bin) == EOF) return;
|
||||
|
||||
i = (hdrlen >> 8) & 0xff; /* length, msb */
|
||||
chksum -= i;
|
||||
if(fputc(i, bin) == EOF) return;
|
||||
|
||||
i = addr & 0xff; /* origin, msb */
|
||||
chksum -= i;
|
||||
if(fputc(i, bin) == EOF) return;
|
||||
|
||||
i = (addr >> 8) & 0xff; /* origin, lsb */
|
||||
chksum -= i;
|
||||
if(fputc(i, bin) == EOF) return;
|
||||
|
||||
if ((len == 0) || (buf == NULL)) return; /* end of tape block */
|
||||
|
||||
i = fwrite(buf, 1, len, bin);
|
||||
if(i < len) return;
|
||||
|
||||
while(len > 0) /* All the data bytes */
|
||||
{
|
||||
chksum -= *buf++ & 0xff;
|
||||
len--;
|
||||
}
|
||||
|
||||
chksum &= 0xff;
|
||||
|
||||
fputc(chksum, bin); /* Followed by the checksum byte */
|
||||
|
||||
return; /* Worked okay. */
|
||||
}
|
||||
|
||||
void trim(char *buf)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
for(cp = buf + strlen(buf); cp > buf; cp--)
|
||||
{
|
||||
if(cp[-1] != ' ')
|
||||
break;
|
||||
}
|
||||
*cp = 0;
|
||||
}
|
||||
|
||||
char **all_gsds = NULL;
|
||||
int nr_gsds = 0;
|
||||
int gsdsize = 0;
|
||||
|
||||
void add_gsdline(char *line)
|
||||
{
|
||||
if(nr_gsds >= gsdsize || all_gsds == NULL)
|
||||
{
|
||||
gsdsize += 128;
|
||||
all_gsds = realloc(all_gsds, gsdsize * sizeof(char *));
|
||||
if(all_gsds == NULL)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
all_gsds[nr_gsds++] = line;
|
||||
}
|
||||
|
||||
void got_gsd(char *cp, int len)
|
||||
{
|
||||
int i;
|
||||
char *gsdline;
|
||||
|
||||
for(i = 2; i < len; i += 8)
|
||||
{
|
||||
char name[8];
|
||||
unsigned value;
|
||||
unsigned flags;
|
||||
|
||||
gsdline = malloc(256);
|
||||
if(gsdline == NULL)
|
||||
{
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
unrad50(WORD(cp+i), name);
|
||||
unrad50(WORD(cp+i+2), name+3);
|
||||
name[6] = 0;
|
||||
|
||||
value = WORD(cp+i+6);
|
||||
flags = cp[i+4] & 0xff;
|
||||
|
||||
switch(cp[i+5] & 0xff)
|
||||
{
|
||||
case 0:
|
||||
sprintf(gsdline,
|
||||
"\tMODNAME %s=%o flags=%o\n", name, value, flags);
|
||||
break;
|
||||
case 1:
|
||||
sprintf(gsdline,
|
||||
"\tCSECT %s=%o flags=%o\n", name, value, flags);
|
||||
break;
|
||||
case 2:
|
||||
sprintf(gsdline,
|
||||
"\tISD %s=%o flags=%o\n", name, value, flags);
|
||||
break;
|
||||
case 3:
|
||||
sprintf(gsdline,
|
||||
"\tXFER %s=%o flags=%o\n", name, value, flags);
|
||||
xferad = value;
|
||||
break;
|
||||
case 4:
|
||||
sprintf(gsdline,
|
||||
"\tGLOBAL %s=%o %s flags=%o\n",
|
||||
name, value, cp[i+4] & 8 ? "DEF" : "REF", flags);
|
||||
break;
|
||||
case 5:
|
||||
sprintf(gsdline,
|
||||
"\tPSECT %s=%o flags=%o\n", name, value, flags);
|
||||
psects[psectid] = strdup(name);
|
||||
trim(psects[psectid++]);
|
||||
break;
|
||||
case 6:
|
||||
sprintf(gsdline,
|
||||
"\tIDENT %s=%o flags=%o\n", name, value, flags);
|
||||
break;
|
||||
case 7:
|
||||
sprintf(gsdline,
|
||||
"\tVSECT %s=%o flags=%o\n", name, value, flags);
|
||||
break;
|
||||
default:
|
||||
sprintf(gsdline,
|
||||
"\t***Unknown GSD entry type %d flags=%o\n",
|
||||
cp[i+5] & 0xff, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
gsdline = realloc(gsdline, strlen(gsdline)+1);
|
||||
add_gsdline(gsdline);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int compare_gsdlines(const void *p1, const void *p2)
|
||||
{
|
||||
const char * const *l1 = p1, * const *l2 = p2;
|
||||
|
||||
return strcmp(*l1, *l2);
|
||||
}
|
||||
|
||||
void got_endgsd(char *cp, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
qsort(all_gsds, nr_gsds, sizeof(char *), compare_gsdlines);
|
||||
|
||||
printf("GSD:\n");
|
||||
|
||||
for(i = 0; i < nr_gsds; i++)
|
||||
{
|
||||
fputs(all_gsds[i], stdout);
|
||||
free(all_gsds[i]);
|
||||
}
|
||||
|
||||
printf("ENDGSD\n");
|
||||
|
||||
free(all_gsds);
|
||||
}
|
||||
|
||||
unsigned last_text_addr = 0;
|
||||
|
||||
void got_text(char *cp, int len)
|
||||
{
|
||||
unsigned addr = WORD(cp+2);
|
||||
|
||||
last_text_addr = addr;
|
||||
|
||||
printf("TEXT ADDR=%o LEN=%o\n", last_text_addr, len-4);
|
||||
|
||||
dump_words(last_text_addr, cp+4, len-4);
|
||||
|
||||
if (bin) dump_bin(last_text_addr, cp+4, len-4);
|
||||
}
|
||||
|
||||
void rad50name(char *cp, char *name)
|
||||
{
|
||||
unrad50(WORD(cp), name);
|
||||
unrad50(WORD(cp+2), name+3);
|
||||
name[6] = 0;
|
||||
trim(name);
|
||||
}
|
||||
|
||||
void got_rld(char *cp, int len)
|
||||
{
|
||||
int i;
|
||||
printf("RLD\n");
|
||||
|
||||
for(i = 2; i < len;)
|
||||
{
|
||||
unsigned addr;
|
||||
unsigned word;
|
||||
unsigned disp = cp[i+1] & 0xff;
|
||||
char name[8];
|
||||
char *byte;
|
||||
|
||||
addr = last_text_addr + disp - 4;
|
||||
|
||||
byte = "";
|
||||
if(cp[i] & 0200)
|
||||
byte = " byte";
|
||||
|
||||
switch(cp[i] & 0x7f)
|
||||
{
|
||||
case 01:
|
||||
printf("\tInternal%s %o=%o\n", byte, addr, WORD(cp+i+2));
|
||||
i += 4;
|
||||
break;
|
||||
case 02:
|
||||
rad50name(cp+i+2, name);
|
||||
printf("\tGlobal%s %o=%s\n", byte, addr, name);
|
||||
i += 6;
|
||||
break;
|
||||
case 03:
|
||||
printf("\tInternal displaced%s %o=%o\n", byte, addr, WORD(cp+i+2));
|
||||
i += 4;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 04:
|
||||
rad50name(cp+i+2, name);
|
||||
printf("\tGlobal displaced%s %o=%s\n", byte, addr, name);
|
||||
i += 6;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 05:
|
||||
rad50name(cp+i+2, name);
|
||||
word = WORD(cp+i+6);
|
||||
printf("\tGlobal plus offset%s %o=%s+%o\n",
|
||||
byte, addr, name, word);
|
||||
i += 8;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 06:
|
||||
rad50name(cp+i+2, name);
|
||||
word = WORD(cp+i+6);
|
||||
printf("\tGlobal plus offset displaced%s %o=%s+%o\n",
|
||||
byte, addr, name, word);
|
||||
i += 8;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 07:
|
||||
rad50name(cp+i+2, name);
|
||||
word = WORD(cp+i+6);
|
||||
printf("\tLocation counter definition %s+%o\n",
|
||||
name, word);
|
||||
i += 8;
|
||||
|
||||
last_text_addr = word;
|
||||
break;
|
||||
case 010:
|
||||
word = WORD(cp+i+2);
|
||||
printf("\tLocation counter modification %o\n", word);
|
||||
i += 4;
|
||||
|
||||
last_text_addr = word;
|
||||
break;
|
||||
case 011:
|
||||
printf("\t.LIMIT %o\n", addr);
|
||||
i += 2;
|
||||
break;
|
||||
|
||||
case 012:
|
||||
rad50name(cp+i+2, name);
|
||||
printf("\tPSECT%s %o=%s\n", byte, addr, name);
|
||||
i += 6;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 014:
|
||||
rad50name(cp+i+2, name);
|
||||
|
||||
printf("\tPSECT displaced%s %o=%s+%o\n", byte, addr, name, word);
|
||||
i += 6;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 015:
|
||||
rad50name(cp+i+2, name);
|
||||
word = WORD(cp+i+6);
|
||||
printf("\tPSECT plus offset%s %o=%s+%o\n",
|
||||
byte, addr, name, word);
|
||||
i += 8;
|
||||
badbin = 1;
|
||||
break;
|
||||
case 016:
|
||||
rad50name(cp+i+2, name);
|
||||
word = WORD(cp+i+6);
|
||||
printf("\tPSECT plus offset displaced%s %o=%s+%o\n",
|
||||
byte, addr, name, word);
|
||||
i += 8;
|
||||
badbin = 1;
|
||||
break;
|
||||
|
||||
case 017:
|
||||
badbin = 1;
|
||||
printf("\tComplex%s %o=", byte, addr);
|
||||
i += 2;
|
||||
{
|
||||
char *xp = cp + i;
|
||||
int size;
|
||||
for(;;)
|
||||
{
|
||||
size = 1;
|
||||
switch(*xp)
|
||||
{
|
||||
case 000:
|
||||
fputs("nop ", stdout); break;
|
||||
case 001:
|
||||
fputs("+ ", stdout); break;
|
||||
case 002:
|
||||
fputs("- ", stdout); break;
|
||||
case 003:
|
||||
fputs("* ", stdout); break;
|
||||
case 004:
|
||||
fputs("/ ", stdout); break;
|
||||
case 005:
|
||||
fputs("& ", stdout); break;
|
||||
case 006:
|
||||
fputs("! ", stdout); break;
|
||||
case 010:
|
||||
fputs("neg ", stdout); break;
|
||||
case 011:
|
||||
fputs("^C ", stdout); break;
|
||||
case 012:
|
||||
fputs("store ", stdout); break;
|
||||
case 013:
|
||||
fputs("store{disp} ", stdout); break;
|
||||
|
||||
case 016:
|
||||
rad50name(xp+1, name);
|
||||
printf("%s ", name);
|
||||
size = 5;
|
||||
break;
|
||||
|
||||
case 017:
|
||||
assert((xp[1] & 0377) < psectid);
|
||||
printf("%s:%o ",
|
||||
psects[xp[1] & 0377],
|
||||
WORD(xp+2));
|
||||
size = 4;
|
||||
break;
|
||||
|
||||
case 020:
|
||||
printf("%o ", WORD(xp+1));
|
||||
size = 3;
|
||||
break;
|
||||
default:
|
||||
printf("**UNKNOWN COMPLEX CODE** %o\n", *xp & 0377);
|
||||
return;
|
||||
}
|
||||
i += size;
|
||||
if(*xp == 012 || *xp == 013)
|
||||
break;
|
||||
xp += size;
|
||||
}
|
||||
fputc('\n', stdout);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("\t***Unknown RLD code %o\n", cp[i] & 0xff);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void got_isd(char *cp, int len)
|
||||
{
|
||||
printf("ISD len=%o\n");
|
||||
}
|
||||
|
||||
void got_endmod(char *cp, int len)
|
||||
{
|
||||
printf("ENDMOD\n");
|
||||
}
|
||||
|
||||
void got_libhdr(char *cp, int len)
|
||||
{
|
||||
printf("LIBHDR\n");
|
||||
}
|
||||
|
||||
void got_libend(char *cp, int len)
|
||||
{
|
||||
printf("LIBEND\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int len;
|
||||
FILE *fp;
|
||||
char *cp;
|
||||
|
||||
fp = fopen(argv[1], "rb");
|
||||
if(fp == NULL)
|
||||
return EXIT_FAILURE;
|
||||
if(argv[2])
|
||||
{
|
||||
bin = fopen(argv[2], "wb");
|
||||
if(bin == NULL) return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while((cp = readrec(fp, &len)) != NULL)
|
||||
{
|
||||
switch(cp[0] & 0xff)
|
||||
{
|
||||
case 1:
|
||||
got_gsd(cp, len);
|
||||
break;
|
||||
case 2:
|
||||
got_endgsd(cp, len);
|
||||
break;
|
||||
case 3:
|
||||
got_text(cp, len);
|
||||
break;
|
||||
case 4:
|
||||
got_rld(cp, len);
|
||||
break;
|
||||
case 5:
|
||||
got_isd(cp, len);
|
||||
break;
|
||||
case 6:
|
||||
got_endmod(cp, len);
|
||||
break;
|
||||
case 7:
|
||||
got_libhdr(cp, len);
|
||||
break;
|
||||
case 8:
|
||||
got_libend(cp, len);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown record type %d\n", cp[0] & 0xff);
|
||||
break;
|
||||
}
|
||||
|
||||
free(cp);
|
||||
}
|
||||
|
||||
if (bin)
|
||||
{ dump_bin (xferad, NULL, 0);
|
||||
fclose (bin);
|
||||
if (badbin) fprintf (stderr, "Probable errors in binary file\n");
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@ -1,114 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="dumpobj" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=dumpobj - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "dumpobj.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "dumpobj.mak" CFG="dumpobj - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "dumpobj - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "dumpobj - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/macro11", BAAAAAAA"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "dumpobj - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "dumpobj___Release"
|
||||
# PROP Intermediate_Dir "dumpobj___Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "dumpobj - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "dumpobj___Debug"
|
||||
# PROP Intermediate_Dir "dumpobj___Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "dumpobj - Win32 Release"
|
||||
# Name "dumpobj - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dumpobj.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rad50.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rad50.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@ -1,30 +0,0 @@
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,180 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="macro11" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=macro11 - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "macro11.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "macro11.mak" CFG="macro11 - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "macro11 - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "macro11 - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""$/macro11", BAAAAAAA"
|
||||
# PROP Scc_LocalPath "."
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "macro11 - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# SUBTRACT LINK32 /profile
|
||||
# Begin Special Build Tool
|
||||
TargetPath=.\Release\macro11.exe
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Cmds=copy $(TargetPath) c:\bin
|
||||
# End Special Build Tool
|
||||
|
||||
!ELSEIF "$(CFG)" == "macro11 - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "MEM_DEBUG" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# SUBTRACT LINK32 /profile
|
||||
# Begin Special Build Tool
|
||||
TargetPath=.\Debug\macro11.exe
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Cmds=copy $(TargetPath) c:\bin
|
||||
# End Special Build Tool
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "macro11 - Win32 Release"
|
||||
# Name "macro11 - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\macro11.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mlb.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\object.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\rad50.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stream2.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\macro11.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\mlb.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\object.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Rad50.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\stream2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Changes
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\License
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Makefile
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Readme
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Todo
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
@ -1,53 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "dumpobj"=.\dumpobj.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
"$/macro11", BAAAAAAA
|
||||
.
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "macro11"=.\macro11.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
"$/macro11", BAAAAAAA
|
||||
.
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
begin source code control
|
||||
"$/macro11", BAAAAAAA
|
||||
.
|
||||
end source code control
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
#ifndef MACRO11_H
|
||||
#define MACRO11_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
*/
|
||||
|
||||
extern void *memcheck(void *p);
|
||||
|
||||
#endif
|
||||
@ -1,38 +0,0 @@
|
||||
CFLAGS = -O -g
|
||||
|
||||
MACRO11_SRCS = macro11.c mlb.c object.c stream2.c util.c rad50.c
|
||||
|
||||
MACRO11_OBJS = $(MACRO11_SRCS:.c=.o)
|
||||
|
||||
DUMPOBJ_SRCS = dumpobj.c rad50.c
|
||||
|
||||
DUMPOBJ_OBJS = $(DUMPOBJ_SRCS:.c=.o)
|
||||
|
||||
ALL_SRCS = $(MACRO11_SRCS) $(DUMPOBJ_SRCS)
|
||||
|
||||
all: macro11 dumpobj
|
||||
|
||||
tags: macro11 dumpobj
|
||||
ctags *.c *.h
|
||||
|
||||
macro11: $(MACRO11_OBJS) makefile
|
||||
$(CC) $(CFLAGS) -o macro11 $(MACRO11_OBJS) -lm
|
||||
|
||||
dumpobj: $(DUMPOBJ_OBJS) makefile
|
||||
$(CC) $(CFLAGS) -o dumpobj $(DUMPOBJ_OBJS)
|
||||
|
||||
MACRO11_OBJS: makefile
|
||||
DUMPOBJ_OBJS: makefile
|
||||
|
||||
clean:
|
||||
-rm -f $(MACRO11_OBJS) $(DUMPOBJ_OBJS) macro11 dumpobj
|
||||
|
||||
macro11.o: macro11.c macro11.h rad50.h object.h stream2.h \
|
||||
mlb.h util.h
|
||||
mlb.o: mlb.c rad50.h stream2.h mlb.h macro11.h util.h
|
||||
object.o: object.c rad50.h object.h
|
||||
stream2.o: stream2.c macro11.h stream2.h
|
||||
util.o: util.c util.h
|
||||
rad50.o: rad50.c rad50.h
|
||||
dumpobj.o: dumpobj.c rad50.h util.h
|
||||
rad50.o: rad50.c rad50.h
|
||||
@ -1,319 +0,0 @@
|
||||
/* Routines for reading from an RT-11 macro library (like SYSMAC.SML) */
|
||||
|
||||
/*
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rad50.h"
|
||||
|
||||
#include "stream2.h"
|
||||
|
||||
#include "mlb.h"
|
||||
|
||||
#include "macro11.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define WORD(cp) ((*(cp) & 0xff) + ((*((cp)+1) & 0xff) << 8))
|
||||
|
||||
/* BYTEPOS calculates the byte position within the macro libray file.
|
||||
I use this to sort the entries by their start position, in order to
|
||||
be able to calculate the entries' sizes, which isn't actually
|
||||
stored in the directory. */
|
||||
|
||||
#define BYTEPOS(rec) ((WORD((rec)+4) & 32767) * 512 + (WORD((rec)+6) & 511))
|
||||
|
||||
extern FILE *lstfile;
|
||||
|
||||
/* compare_position is the qsort callback function that compares byte
|
||||
locations within the macro library */
|
||||
static int compare_position(const void *arg1, const void *arg2)
|
||||
{
|
||||
const char *c1 = arg1, *c2 = arg2;
|
||||
|
||||
if(BYTEPOS(c1) < BYTEPOS(c2))
|
||||
return -1;
|
||||
if(BYTEPOS(c1) > BYTEPOS(c2))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* trim removes trailing blanks from a string. */
|
||||
static void trim(char *buf)
|
||||
{
|
||||
char *cp = buf + strlen(buf);
|
||||
while(--cp >= buf && *cp == ' ')
|
||||
*cp = 0;
|
||||
}
|
||||
|
||||
/* mlb_open opens a file which is given to be a macro library. */
|
||||
/* Returns NULL on failure. */
|
||||
|
||||
MLB *mlb_open(char *name)
|
||||
{
|
||||
MLB *mlb = memcheck(malloc(sizeof(MLB)));
|
||||
char *buff;
|
||||
unsigned entsize;
|
||||
unsigned nr_entries;
|
||||
unsigned start_block;
|
||||
int i;
|
||||
|
||||
mlb->directory = NULL;
|
||||
|
||||
mlb->fp = fopen(name, "rb");
|
||||
if(mlb->fp == NULL)
|
||||
{
|
||||
mlb_close(mlb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buff = memcheck(malloc(044)); /* Size of MLB library header */
|
||||
|
||||
if(fread(buff, 1, 044, mlb->fp) < 044)
|
||||
{
|
||||
mlb_close(mlb);
|
||||
free(buff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(WORD(buff) != 01001) /* Is this really a macro library? */
|
||||
{
|
||||
mlb_close(mlb); /* Nope. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entsize = WORD(buff + 032); /* The size of each macro directory
|
||||
entry */
|
||||
nr_entries = WORD(buff + 036); /* The number of directory entries */
|
||||
start_block = WORD(buff + 034); /* The start RT-11 block of the
|
||||
directory */
|
||||
|
||||
free(buff); /* Done with that header. */
|
||||
|
||||
/* Allocate a buffer for the disk directory */
|
||||
buff = memcheck(malloc(nr_entries * entsize));
|
||||
fseek(mlb->fp, start_block * 512, SEEK_SET); /* Go to the directory */
|
||||
|
||||
/* Read the disk directory */
|
||||
if(fread(buff, entsize, nr_entries, mlb->fp) < nr_entries)
|
||||
{
|
||||
mlb_close(mlb); /* Sorry, read error. */
|
||||
free(buff);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Shift occupied directory entries to the front of the array
|
||||
before sorting */
|
||||
|
||||
{
|
||||
int j;
|
||||
for(i = 0, j = nr_entries; i < j; i++)
|
||||
{
|
||||
char *ent1, *ent2;
|
||||
ent1 = buff + (i * entsize);
|
||||
/* Unused entries have 0177777 0177777 for the RAD50 name,
|
||||
which is not legal RAD50. */
|
||||
if(WORD(ent1) == 0177777 &&
|
||||
WORD(ent1 + 2) == 0177777)
|
||||
{
|
||||
while(--j > i &&
|
||||
(ent2 = buff + (j * entsize),
|
||||
WORD(ent2) == 0177777 &&
|
||||
WORD(ent2+2) == 0177777))
|
||||
;
|
||||
if(j <= i)
|
||||
break; /* All done. */
|
||||
memcpy(ent1, ent2, entsize); /* Move used entry
|
||||
into unused entry's
|
||||
space */
|
||||
memset(ent2, 0377, entsize); /* Mark entry unused */
|
||||
}
|
||||
}
|
||||
|
||||
/* Now i contains the actual number of entries. */
|
||||
|
||||
mlb->nentries = i;
|
||||
|
||||
/* Sort the array by file position */
|
||||
|
||||
qsort(buff, i, entsize, compare_position);
|
||||
|
||||
/* Now, allocate my in-memory directory */
|
||||
mlb->directory = memcheck(malloc(sizeof(MLBENT) * mlb->nentries));
|
||||
memset(mlb->directory, 0, sizeof(MLBENT) * mlb->nentries);
|
||||
|
||||
/* Build in-memory directory */
|
||||
for(j = 0; j < i; j++)
|
||||
{
|
||||
char radname[16];
|
||||
char *ent;
|
||||
|
||||
ent = buff + (j * entsize);
|
||||
|
||||
unrad50(WORD(ent), radname);
|
||||
unrad50(WORD(ent+2), radname+3);
|
||||
radname[6] = 0;
|
||||
|
||||
trim(radname);
|
||||
|
||||
mlb->directory[j].label = memcheck(strdup(radname));
|
||||
mlb->directory[j].position = BYTEPOS(ent);
|
||||
if(j < i-1)
|
||||
{
|
||||
mlb->directory[j].length =
|
||||
BYTEPOS(ent + entsize) - BYTEPOS(ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long max;
|
||||
char c;
|
||||
fseek(mlb->fp, 0, SEEK_END);
|
||||
max = ftell(mlb->fp);
|
||||
/* Look for last non-zero */
|
||||
do
|
||||
{
|
||||
max--;
|
||||
fseek(mlb->fp, max, SEEK_SET);
|
||||
c = fgetc(mlb->fp);
|
||||
} while(max > 0 && c == 0);
|
||||
max++;
|
||||
mlb->directory[j].length = max - BYTEPOS(ent);
|
||||
}
|
||||
}
|
||||
|
||||
free(buff);
|
||||
|
||||
}
|
||||
|
||||
/* Done. Return the struct that represents the opened MLB. */
|
||||
return mlb;
|
||||
}
|
||||
|
||||
/* mlb_close discards MLB and closes the file. */
|
||||
void mlb_close(MLB *mlb)
|
||||
{
|
||||
if(mlb)
|
||||
{
|
||||
int i;
|
||||
if(mlb->directory)
|
||||
{
|
||||
for(i = 0; i < mlb->nentries; i++)
|
||||
{
|
||||
if(mlb->directory[i].label)
|
||||
free(mlb->directory[i].label);
|
||||
}
|
||||
free(mlb->directory);
|
||||
}
|
||||
if(mlb->fp)
|
||||
fclose(mlb->fp);
|
||||
|
||||
free(mlb);
|
||||
}
|
||||
}
|
||||
|
||||
/* mlb_entry returns a BUFFER containing the specified entry from the
|
||||
macro library, or NULL if not found. */
|
||||
|
||||
BUFFER *mlb_entry(MLB *mlb, char *name)
|
||||
{
|
||||
int i;
|
||||
MLBENT *ent;
|
||||
BUFFER *buf;
|
||||
char *bp;
|
||||
int c;
|
||||
|
||||
for(i = 0; i < mlb->nentries; i++)
|
||||
{
|
||||
ent = &mlb->directory[i];
|
||||
if(strcmp(mlb->directory[i].label, name) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if(i >= mlb->nentries)
|
||||
return NULL;
|
||||
|
||||
/* Allocate a buffer to hold the text */
|
||||
buf = new_buffer();
|
||||
buffer_resize(buf, ent->length+1); /* Make it large enough */
|
||||
bp = buf->buffer;
|
||||
|
||||
fseek(mlb->fp, ent->position, SEEK_SET);
|
||||
|
||||
for(i = 0; i < ent->length; i++)
|
||||
{
|
||||
c = fgetc(mlb->fp); /* Get macro byte */
|
||||
if(c == '\r' || c == 0) /* If it's a carriage return or 0,
|
||||
discard it. */
|
||||
continue;
|
||||
*bp++ = c;
|
||||
}
|
||||
*bp++ = 0; /* Store trailing 0 delim */
|
||||
|
||||
/* Now resize that buffer to the length actually read. */
|
||||
buffer_resize(buf, bp - buf->buffer);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* mlb_extract - walk thru a macro library and store it's contents
|
||||
into files in the current directory.
|
||||
|
||||
See, I had decided not to bother writing macro library maintenance
|
||||
tools, since the user can call macros directly from the file
|
||||
system. But if you've already got a macro library without the
|
||||
sources, you can use this to extract the entries and maintain them
|
||||
in the file system from thence forward.
|
||||
*/
|
||||
|
||||
void mlb_extract(MLB *mlb)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
BUFFER *buf;
|
||||
|
||||
for(i = 0; i < mlb->nentries; i++)
|
||||
{
|
||||
char name[32];
|
||||
buf = mlb_entry(mlb, mlb->directory[i].label);
|
||||
sprintf(name, "%s.MAC", mlb->directory[i].label);
|
||||
fp = fopen(name, "w");
|
||||
fwrite(buf->buffer, 1, buf->length, fp);
|
||||
fclose(fp);
|
||||
buffer_free(buf);
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
#ifndef MLB_H
|
||||
#define MLB_H
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "stream2.h"
|
||||
|
||||
/* Routines to open and read entries from a macro library */
|
||||
|
||||
typedef struct mlbent
|
||||
{
|
||||
char *label;
|
||||
unsigned long position;
|
||||
int length;
|
||||
} MLBENT;
|
||||
|
||||
typedef struct mlb
|
||||
{
|
||||
FILE *fp;
|
||||
MLBENT *directory;
|
||||
int nentries;
|
||||
} MLB;
|
||||
|
||||
extern MLB *mlb_open(char *name);
|
||||
extern BUFFER *mlb_entry(MLB *mlb, char *name);
|
||||
extern void mlb_close(MLB *mlb);
|
||||
extern void mlb_extract(MLB *mlb);
|
||||
|
||||
#endif /* MLB_H */
|
||||
@ -1,861 +0,0 @@
|
||||
/*
|
||||
object.c - writes RT-11 compatible .OBJ files.
|
||||
|
||||
Ref: RT-11 Software Support Manual, File Formats.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rad50.h"
|
||||
|
||||
#include "object.h"
|
||||
|
||||
#include "macro11.h"
|
||||
|
||||
/*
|
||||
writerec writes "formatted binary records."
|
||||
Each is preceeded by any number of 0 bytes, begins with a 1,0 pair,
|
||||
followed by 2 byte length, followed by data, followed by 1 byte
|
||||
negative checksum.
|
||||
*/
|
||||
|
||||
static int writerec(FILE *fp, char *data, int len)
|
||||
{
|
||||
int chksum; /* Checksum is negative sum of all
|
||||
bytes including header and length */
|
||||
int i;
|
||||
unsigned hdrlen = len + 4;
|
||||
|
||||
if(fp == NULL)
|
||||
return 1; /* Silently ignore this attempt to write. */
|
||||
|
||||
chksum = 0;
|
||||
if(fputc(FBR_LEAD1, fp) == EOF) /* All recs begin with 1,0 */
|
||||
return 0;
|
||||
chksum -= FBR_LEAD1;
|
||||
if(fputc(FBR_LEAD2, fp) == EOF)
|
||||
return 0;
|
||||
chksum -= FBR_LEAD2;
|
||||
|
||||
i = hdrlen & 0xff; /* length, lsb */
|
||||
chksum -= i;
|
||||
if(fputc(i, fp) == EOF)
|
||||
return 0;
|
||||
|
||||
i = (hdrlen >> 8) & 0xff; /* length, msb */
|
||||
chksum -= i;
|
||||
if(fputc(i, fp) == EOF)
|
||||
return 0;
|
||||
|
||||
i = fwrite(data, 1, len, fp);
|
||||
if(i < len)
|
||||
return 0;
|
||||
|
||||
while(len > 0) /* All the data bytes */
|
||||
{
|
||||
chksum -= *data++ & 0xff;
|
||||
len--;
|
||||
}
|
||||
|
||||
chksum &= 0xff;
|
||||
|
||||
fputc(chksum, fp); /* Followed by the checksum byte */
|
||||
|
||||
return 1; /* Worked okay. */
|
||||
}
|
||||
|
||||
/* gsd_init - prepare a GSD prior to writing GSD records */
|
||||
|
||||
void gsd_init(GSD *gsd, FILE *fp)
|
||||
{
|
||||
gsd->fp = fp;
|
||||
gsd->buf[0] = OBJ_GSD; /* GSD records start with 1,0 */
|
||||
gsd->buf[1] = 0;
|
||||
gsd->offset = 2; /* Offset for further additions */
|
||||
}
|
||||
|
||||
/* gsd_flush - write buffered GSD records */
|
||||
|
||||
int gsd_flush(GSD *gsd)
|
||||
{
|
||||
if(gsd->offset > 2)
|
||||
{
|
||||
if(!writerec(gsd->fp, gsd->buf, gsd->offset))
|
||||
return 0;
|
||||
gsd_init(gsd, gsd->fp);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* gsd_write - buffers a GSD record */
|
||||
|
||||
/* All GSD entries have the following 8 byte format: */
|
||||
/* 4 bytes RAD50 name */
|
||||
/* 1 byte flags */
|
||||
/* 1 byte type */
|
||||
/* 2 bytes value */
|
||||
|
||||
static int gsd_write(GSD *gsd, char *name, int flags,
|
||||
int type, int value)
|
||||
{
|
||||
char *cp;
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(gsd->offset > sizeof(gsd->buf) - 8)
|
||||
{
|
||||
if(!gsd_flush(gsd))
|
||||
return 0;
|
||||
}
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
|
||||
cp = gsd->buf + gsd->offset;
|
||||
*cp++ = radtbl[0] & 0xff;
|
||||
*cp++ = (radtbl[0] >> 8) & 0xff;
|
||||
*cp++ = radtbl[1] & 0xff;
|
||||
*cp++ = (radtbl[1] >> 8) & 0xff;
|
||||
|
||||
*cp++ = flags;
|
||||
*cp++ = type;
|
||||
|
||||
*cp++ = value & 0xff;
|
||||
*cp = (value >> 8) & 0xff;
|
||||
|
||||
gsd->offset += 8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* gsd_mod - Write module name to GSD */
|
||||
|
||||
int gsd_mod(GSD *gsd, char *modname)
|
||||
{
|
||||
return gsd_write(gsd, modname, 0, GSD_MODNAME, 0);
|
||||
}
|
||||
|
||||
/* gsd_csect - Write a control section name & size to the GSD */
|
||||
int gsd_csect(GSD *gsd, char *sectname, int size)
|
||||
{
|
||||
return gsd_write(gsd, sectname, 0, GSD_CSECT, size);
|
||||
}
|
||||
|
||||
/* gsd_intname - Write an internal symbol (ignored by RT-11 linker) */
|
||||
int gsd_intname(GSD *gsd, char *name, unsigned value)
|
||||
{
|
||||
return gsd_write(gsd, name, 0, GSD_ISN, value);
|
||||
}
|
||||
|
||||
/* gsd_xfer - Write a program transfer address to GSD */
|
||||
int gsd_xfer(GSD *gsd, char *name, unsigned value)
|
||||
{
|
||||
return gsd_write(gsd, name, 010, GSD_XFER, value);
|
||||
}
|
||||
|
||||
/* gsd_global - Write a global definition or reference to GSD */
|
||||
/* Caller must be aware of the proper flags. */
|
||||
int gsd_global(GSD *gsd, char *name, int flags, unsigned value)
|
||||
{
|
||||
return gsd_write(gsd, name, flags, GSD_GLOBAL, value);
|
||||
}
|
||||
|
||||
/* Write a program section to the GSD */
|
||||
/* Caller must be aware of the proper flags. */
|
||||
int gsd_psect(GSD *gsd, char *name, int flags, int size)
|
||||
{
|
||||
return gsd_write(gsd, name, flags, GSD_PSECT, size);
|
||||
}
|
||||
|
||||
/* Write program ident to GSD */
|
||||
int gsd_ident(GSD *gsd, char *name)
|
||||
{
|
||||
return gsd_write(gsd, name, 0, GSD_IDENT, 0);
|
||||
}
|
||||
|
||||
/* Write virtual array declaration to GSD */
|
||||
int gsd_virt(GSD *gsd, char *name, int size)
|
||||
{
|
||||
return gsd_write(gsd, name, 0, GSD_VSECT, size);
|
||||
}
|
||||
|
||||
/* Write ENDGSD record */
|
||||
|
||||
int gsd_end(GSD *gsd)
|
||||
{
|
||||
gsd->buf[0] = OBJ_ENDGSD;
|
||||
gsd->buf[1] = 0;
|
||||
return writerec(gsd->fp, gsd->buf, 2);
|
||||
}
|
||||
|
||||
/* TEXT and RLD record handling */
|
||||
|
||||
/* TEXT records contain the plain binary of the program. An RLD
|
||||
record refers to the prior TEXT record, giving relocation
|
||||
information. */
|
||||
|
||||
/* text_init prepares a TEXT_RLD prior to writing */
|
||||
|
||||
void text_init(TEXT_RLD *tr, FILE *fp, unsigned addr)
|
||||
{
|
||||
tr->fp = fp;
|
||||
|
||||
tr->text[0] = OBJ_TEXT; /* text records begin with 3, 0 */
|
||||
tr->text[1] = 0;
|
||||
tr->text[2] = addr & 0xff; /* and are followed by load address */
|
||||
tr->text[3] = (addr >> 8) & 0xff;
|
||||
tr->txt_offset = 4; /* Here's where recording new text will begin */
|
||||
|
||||
tr->rld[0] = OBJ_RLD; /* RLD records begin with 4, 0 */
|
||||
tr->rld[1] = 0;
|
||||
|
||||
tr->txt_addr = addr;
|
||||
tr->rld_offset = 2; /* And are followed by RLD entries */
|
||||
}
|
||||
|
||||
/* text_flush - flushes buffer TEXT and RLD records. */
|
||||
|
||||
int text_flush(TEXT_RLD *tr)
|
||||
{
|
||||
|
||||
if(tr->txt_offset > 4)
|
||||
{
|
||||
if(!writerec(tr->fp, tr->text, tr->txt_offset))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tr->rld_offset > 2)
|
||||
{
|
||||
if(!writerec(tr->fp, tr->rld, tr->rld_offset))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Used to ensure that TEXT and RLD information will be in adjacent
|
||||
records. If not enough space exists in either buffer, both are
|
||||
flushed. */
|
||||
|
||||
static int text_fit(TEXT_RLD *tr, unsigned addr,
|
||||
int txtsize, int rldsize)
|
||||
{
|
||||
if(tr->txt_offset + txtsize <= sizeof(tr->text) &&
|
||||
tr->rld_offset + rldsize <= sizeof(tr->rld) &&
|
||||
(txtsize == 0 || tr->txt_addr + tr->txt_offset - 4 == addr))
|
||||
return 1; /* All's well. */
|
||||
|
||||
if(!text_flush(tr))
|
||||
return 0;
|
||||
text_init(tr, tr->fp, addr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* text_word_i - internal text_word. Used when buffer space is
|
||||
already assured. */
|
||||
|
||||
static void text_word_i(TEXT_RLD *tr, unsigned w, int size)
|
||||
{
|
||||
tr->text[tr->txt_offset++] = w & 0xff;
|
||||
if(size > 1)
|
||||
tr->text[tr->txt_offset++] = (w >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* text_word - write constant word to text */
|
||||
|
||||
int text_word(TEXT_RLD *tr, unsigned *addr, int size, unsigned word)
|
||||
{
|
||||
if(!text_fit(tr, *addr, size, 0))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
*addr += size; /* Update the caller's DOT */
|
||||
return 1; /* say "ok". */
|
||||
}
|
||||
|
||||
/* rld_word - adds a word to the RLD information. */
|
||||
|
||||
static void rld_word(TEXT_RLD *tr, unsigned wd)
|
||||
{
|
||||
tr->rld[tr->rld_offset++] = wd & 0xff;
|
||||
tr->rld[tr->rld_offset++] = (wd >> 8) & 0xff;
|
||||
}
|
||||
|
||||
/* rld_byte - adds a byte to rld information. */
|
||||
|
||||
static void rld_byte(TEXT_RLD *tr, unsigned byte)
|
||||
{
|
||||
tr->rld[tr->rld_offset++] = byte & 0xff;
|
||||
}
|
||||
|
||||
/* rld_code - write the typical RLD first-word code. Encodes the
|
||||
given address as the offset into the prior TEXT record. */
|
||||
|
||||
static void rld_code(TEXT_RLD *tr, unsigned code, unsigned addr, int size)
|
||||
{
|
||||
unsigned offset = addr - tr->txt_addr + 4;
|
||||
rld_word(tr, code | offset << 8 | (size == 1 ? 0200 : 0));
|
||||
}
|
||||
|
||||
/* rld_code_naddr - typical RLD entries refer to a text address. This
|
||||
one is used when the RLD code does not. */
|
||||
|
||||
static void rld_code_naddr(TEXT_RLD *tr, unsigned code, int size)
|
||||
{
|
||||
rld_word(tr, code | (size == 1 ? 0200 : 0));
|
||||
}
|
||||
|
||||
/* write a word with a psect-relative value */
|
||||
|
||||
int text_internal_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word)
|
||||
{
|
||||
if(!text_fit(tr, *addr, size, 4))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
rld_code(tr, RLD_INT, *addr, size);
|
||||
rld_word(tr, word);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is an absolute reference to a global symbol */
|
||||
|
||||
int text_global_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word, char *global)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(!text_fit(tr, *addr, size, 6))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
rld_code(tr, RLD_GLOBAL, *addr, size);
|
||||
|
||||
rad50x2(global, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write a word which is a PC-relative reference to an absolute address */
|
||||
|
||||
int text_displaced_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size, unsigned word)
|
||||
{
|
||||
if(!text_fit(tr, *addr, size, 4))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
rld_code(tr, RLD_INT_DISP, *addr, size);
|
||||
rld_word(tr, word);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is a PC-relative reference to a global symbol */
|
||||
|
||||
int text_global_displaced_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
unsigned word, char *global)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(!text_fit(tr, *addr, size, 6))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
rld_code(tr, RLD_GLOBAL_DISP, *addr, size);
|
||||
|
||||
rad50x2(global, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is an absolute reference to a global symbol plus
|
||||
an offset */
|
||||
|
||||
/* Optimizes to text_global_word when the offset is zero. */
|
||||
|
||||
int text_global_offset_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
unsigned word, char *global)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(word == 0)
|
||||
return text_global_word(tr, addr, size, word, global);
|
||||
|
||||
if(!text_fit(tr, *addr, size, 8))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
rld_code(tr, RLD_GLOBAL_OFFSET, *addr, size);
|
||||
|
||||
rad50x2(global, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
rld_word(tr, word);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is a PC-relative reference to a global symbol
|
||||
plus an offset */
|
||||
|
||||
/* Optimizes to text_global_displaced_word when the offset is zero. */
|
||||
|
||||
int text_global_displaced_offset_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
unsigned word, char *global)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(word == 0)
|
||||
return text_global_displaced_word(tr, addr, size, word, global);
|
||||
|
||||
if(!text_fit(tr, *addr, size, 8))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
rld_code(tr, RLD_GLOBAL_OFFSET_DISP, *addr, size);
|
||||
|
||||
rad50x2(global, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
rld_word(tr, word);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Define current program counter, plus PSECT */
|
||||
/* Different because it must be the last RLD entry in a block. That's
|
||||
because TEXT records themselves contain the current text
|
||||
address. */
|
||||
|
||||
int text_define_location(TEXT_RLD *tr, char *name, unsigned *addr)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(!text_fit(tr, *addr, 0, 8)) /* No text space used */
|
||||
return 0;
|
||||
|
||||
rld_code_naddr(tr, RLD_LOCDEF, 2); /* RLD code for "location
|
||||
counter def" with no offset */
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
rld_word(tr, radtbl[0]); /* Set current section name */
|
||||
rld_word(tr, radtbl[1]);
|
||||
rld_word(tr, *addr); /* Set current location addr */
|
||||
|
||||
if(!text_flush(tr)) /* Flush that block out. */
|
||||
return 0;
|
||||
|
||||
text_init(tr, tr->fp, *addr); /* Set new text address */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Modify current program counter, assuming current PSECT */
|
||||
/* Location counter modification is similarly weird */
|
||||
/* (I wonder - why is this RLD code even here? TEXT records contain
|
||||
thair own start address.) */
|
||||
|
||||
int text_modify_location(TEXT_RLD *tr, unsigned *addr)
|
||||
{
|
||||
if(!text_fit(tr, *addr, 0, 4)) /* No text space used */
|
||||
return 0;
|
||||
|
||||
rld_code_naddr(tr, RLD_LOCMOD, 2); /* RLD code for "location
|
||||
counter mod" with no offset */
|
||||
rld_word(tr, *addr); /* Set current location addr */
|
||||
|
||||
if(!text_flush(tr)) /* Flush that block out. */
|
||||
return 0;
|
||||
text_init(tr, tr->fp, *addr); /* Set new text address */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write two words containing program limits (the .LIMIT directive) */
|
||||
|
||||
int text_limits(TEXT_RLD *tr, unsigned *addr)
|
||||
{
|
||||
if(!text_fit(tr, *addr, 4, 2))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, 0, 2);
|
||||
text_word_i(tr, 0, 2);
|
||||
rld_code(tr, RLD_LIMITS, *addr, 2);
|
||||
|
||||
*addr += 4;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is the start address of a different PSECT */
|
||||
|
||||
int text_psect_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
unsigned word, char *name)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(!text_fit(tr, *addr, size, 6))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
rld_code(tr, RLD_PSECT, *addr, size);
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is an offset from the start of a different PSECT */
|
||||
|
||||
/* Optimizes to text_psect_word when offset is zero */
|
||||
|
||||
int text_psect_offset_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
unsigned word, char *name)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(word == 0)
|
||||
return text_psect_word(tr, addr, size, word, name);
|
||||
|
||||
if(!text_fit(tr, *addr, size, 8))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
rld_code(tr, RLD_PSECT_OFFSET, *addr, size);
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
rld_word(tr, word);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is the address of a different PSECT, PC-relative */
|
||||
|
||||
int text_psect_displaced_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word, char *name)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(!text_fit(tr, *addr, size, 6))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
rld_code(tr, RLD_PSECT_DISP, *addr, size);
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write a word which is an offset from the address of a different
|
||||
PSECT, PC-relative */
|
||||
|
||||
/* Optimizes to text_psect_displaced_word when offset is zero */
|
||||
|
||||
int text_psect_displaced_offset_word(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
unsigned word, char *name)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
|
||||
if(word == 0)
|
||||
return text_psect_displaced_word(tr, addr, size, word, name);
|
||||
|
||||
if(!text_fit(tr, *addr, size, 8))
|
||||
return 0;
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
rld_code(tr, RLD_PSECT_OFFSET_DISP, *addr, size);
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
rld_word(tr, radtbl[0]);
|
||||
rld_word(tr, radtbl[1]);
|
||||
rld_word(tr, word);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* complex relocation! */
|
||||
|
||||
/* A complex relocation expression is where a piece of code is fed to
|
||||
the linker asking it to do some math for you, and store the result
|
||||
in a program word. The code is a stack-based language. */
|
||||
|
||||
/* complex_begin initializes a TEXT_COMPLEX */
|
||||
|
||||
void text_complex_begin(TEXT_COMPLEX *tx)
|
||||
{
|
||||
tx->len = 0;
|
||||
}
|
||||
|
||||
/* text_complex_fit checks if a complex expression will fit and
|
||||
returns a pointer to it's location */
|
||||
|
||||
static char *text_complex_fit(TEXT_COMPLEX *tx, int size)
|
||||
{
|
||||
int len;
|
||||
|
||||
if(tx->len + size > sizeof(tx->accum))
|
||||
return NULL; /* Expression has grown too complex. */
|
||||
|
||||
len = tx->len;
|
||||
|
||||
tx->len += size;
|
||||
|
||||
return tx->accum + len;
|
||||
}
|
||||
|
||||
/* text_complex_byte stores a single byte. */
|
||||
|
||||
static int text_complex_byte(TEXT_COMPLEX *tx, unsigned byte)
|
||||
{
|
||||
char *cp = text_complex_fit(tx, 1);
|
||||
if(!cp)
|
||||
return 0;
|
||||
*cp = byte;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* text_complex_add - add top two stack elements */
|
||||
|
||||
int text_complex_add(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_ADD);
|
||||
}
|
||||
|
||||
/* text_complex_sub - subtract top two stack elements. */
|
||||
/* You know, I think these function labels are self-explanatory... */
|
||||
|
||||
int text_complex_sub(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_SUB);
|
||||
}
|
||||
|
||||
int text_complex_mul(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_MUL);
|
||||
}
|
||||
|
||||
int text_complex_div(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_DIV);
|
||||
}
|
||||
|
||||
int text_complex_and(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_AND);
|
||||
}
|
||||
|
||||
int text_complex_or(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_OR);
|
||||
}
|
||||
|
||||
int text_complex_xor(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_XOR);
|
||||
}
|
||||
|
||||
int text_complex_com(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_COM);
|
||||
}
|
||||
|
||||
int text_complex_neg(TEXT_COMPLEX *tx)
|
||||
{
|
||||
return text_complex_byte(tx, CPLX_NEG);
|
||||
}
|
||||
|
||||
/* text_complex_lit pushes a literal value to the stack. */
|
||||
|
||||
int text_complex_lit(TEXT_COMPLEX *tx, unsigned word)
|
||||
{
|
||||
char *cp = text_complex_fit(tx, 3);
|
||||
if(!cp)
|
||||
return 0;
|
||||
*cp++ = CPLX_CONST;
|
||||
*cp++ = word & 0xff;
|
||||
*cp = (word >> 8) & 0xff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* text_complex_global pushes the value of a global variable to the
|
||||
stack */
|
||||
|
||||
int text_complex_global(TEXT_COMPLEX *tx, char *name)
|
||||
{
|
||||
unsigned radtbl[2];
|
||||
char *cp = text_complex_fit(tx, 5);
|
||||
if(!cp)
|
||||
return 0;
|
||||
|
||||
rad50x2(name, radtbl);
|
||||
*cp++ = CPLX_GLOBAL;
|
||||
*cp++ = radtbl[0] & 0xff;
|
||||
*cp++ = (radtbl[0] >> 8) & 0xff;
|
||||
*cp++ = radtbl[1] & 0xff;
|
||||
*cp = (radtbl[1] >> 8) & 0xff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* text_complex_psect pushes the value of an offset into a PSECT to
|
||||
the stack. */
|
||||
|
||||
/* What was not documented in the Software Support manual is that
|
||||
PSECT "sect" numbers are assigned in the order they appear in the
|
||||
source program, and the order they appear in the GSD. i.e. the
|
||||
first PSECT GSD is assigned sector 0 (which is always the default
|
||||
absolute section so that's a bad example), the next sector 1,
|
||||
etc. */
|
||||
|
||||
int text_complex_psect(TEXT_COMPLEX *tx, unsigned sect, unsigned offset)
|
||||
{
|
||||
char *cp = text_complex_fit(tx, 4);
|
||||
if(!cp)
|
||||
return 0;
|
||||
*cp++ = CPLX_REL;
|
||||
*cp++ = sect & 0xff;
|
||||
*cp++ = offset & 0xff;
|
||||
*cp = (offset >> 8) & 0xff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* text_complex_commit - store the result of the complex expression
|
||||
and end the RLD code. */
|
||||
|
||||
int text_complex_commit(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, TEXT_COMPLEX *tx, unsigned word)
|
||||
{
|
||||
int i;
|
||||
|
||||
text_complex_byte(tx, CPLX_STORE);
|
||||
|
||||
if(!text_fit(tr, *addr, size, tx->len + 2))
|
||||
return 0;
|
||||
|
||||
rld_code(tr, RLD_COMPLEX, *addr, size);
|
||||
|
||||
for(i = 0; i < tx->len; i++)
|
||||
rld_byte(tr, tx->accum[i]);
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* text_complex_commit_displaced - store the result of the complex
|
||||
expression, relative to the current PC, and end the RLD code */
|
||||
|
||||
int text_complex_commit_displaced(TEXT_RLD *tr,
|
||||
unsigned *addr, int size,
|
||||
TEXT_COMPLEX *tx, unsigned word)
|
||||
{
|
||||
int i;
|
||||
|
||||
text_complex_byte(tx, CPLX_STORE_DISP);
|
||||
|
||||
if(!text_fit(tr, *addr, size, tx->len + 2))
|
||||
return 0;
|
||||
|
||||
rld_code(tr, RLD_COMPLEX, *addr, size);
|
||||
|
||||
for(i = 0; i < tx->len; i++)
|
||||
rld_byte(tr, tx->accum[i]);
|
||||
|
||||
text_word_i(tr, word, size);
|
||||
|
||||
*addr += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Write end-of-object-module to file. */
|
||||
|
||||
int write_endmod(FILE *fp)
|
||||
{
|
||||
char endmod[2] = { OBJ_ENDMOD, 0 };
|
||||
return writerec(fp, endmod, 2);
|
||||
}
|
||||
@ -1,210 +0,0 @@
|
||||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
/* Object file constant definitions */
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#define FBR_LEAD1 1 /* The byte value that defines the
|
||||
beginning of a formatted binary
|
||||
record */
|
||||
#define FBR_LEAD2 0 /* Followed by a 0 */
|
||||
/* Followed by two bytes length */
|
||||
/* Followed by (length-4) bytes data */
|
||||
/* Followed by a 1 byte checksum */
|
||||
/* which is the negative sum of all
|
||||
preceeding bytes */
|
||||
|
||||
#define OBJ_GSD 01 /* GSD (Global symbol directory) */
|
||||
#define OBJ_ENDGSD 02 /* ENDGSD */
|
||||
#define OBJ_TEXT 03 /* TEXT */
|
||||
#define OBJ_RLD 04 /* RLD (Relocation directory) */
|
||||
#define OBJ_ISD 05 /* ISD (Internal symbol directory,
|
||||
currently unused) */
|
||||
#define OBJ_ENDMOD 06 /* ENDMOD (End of object module) */
|
||||
#define OBJ_LIBHDR 07 /* LIBHDR (Object Library header) */
|
||||
#define OBJ_LIBEND 010 /* LIBEND (Object Library header end) */
|
||||
|
||||
#define GSD_MODNAME 00 /* Module name */
|
||||
#define GSD_CSECT 01 /* Control section name */
|
||||
#define GSD_ISN 02 /* Internal symbol name */
|
||||
#define GSD_XFER 03 /* Transfer address */
|
||||
#define GSD_GLOBAL 04 /* Global symbol definition/reference */
|
||||
#define GSD_PSECT 05 /* PSECT name */
|
||||
#define GSD_IDENT 06 /* IDENT */
|
||||
#define GSD_VSECT 07 /* VSECT (Virtual array declaration) */
|
||||
|
||||
#define GLOBAL_WEAK 01 /* GLOBAL is weak, else strong */
|
||||
#define GLOBAL_DEF 010 /* GLOBAL is definition, else reference */
|
||||
#define GLOBAL_REL 040 /* GLOBAL is relative, else absolute */
|
||||
|
||||
#define PSECT_SAV 001 /* PSECT is a root section, else overlay */
|
||||
#define PSECT_COM 004 /* PSECT is merged common area, else
|
||||
contatenated */
|
||||
#define PSECT_RO 020 /* PSECT is read-only, else R/W */
|
||||
#define PSECT_REL 040 /* PSECT is relative, else absolute
|
||||
(absolute implies PSECT_COM) */
|
||||
#define PSECT_GBL 0100 /* PSECT is overlay-global, else
|
||||
overlay-local */
|
||||
#define PSECT_DATA 0200 /* PSECT contains data, else instructions */
|
||||
|
||||
#define RLD_INT 01 /* "Internal relocation" */
|
||||
#define RLD_GLOBAL 02 /* "Global relocation" */
|
||||
#define RLD_INT_DISP 03 /* "Internal displaced" */
|
||||
#define RLD_GLOBAL_DISP 04 /* "Global displaced" */
|
||||
#define RLD_GLOBAL_OFFSET 05 /* "Global additive" */
|
||||
#define RLD_GLOBAL_OFFSET_DISP 06 /* "Global additive displaced" */
|
||||
#define RLD_LOCDEF 07 /* "Location counter definition" */
|
||||
#define RLD_LOCMOD 010 /* "Location counter modification" */
|
||||
#define RLD_LIMITS 011 /* ".LIMIT" */
|
||||
#define RLD_PSECT 012 /* "P-sect" */
|
||||
#define RLD_PSECT_DISP 014 /* "P-sect displaced" */
|
||||
#define RLD_PSECT_OFFSET 015 /* "P-sect additive" */
|
||||
#define RLD_PSECT_OFFSET_DISP 016 /* "P-sect additive displaced" */
|
||||
#define RLD_COMPLEX 017 /* "Complex" */
|
||||
|
||||
#define RLD_BYTE 0200 /* RLD modifies a byte, else a word */
|
||||
|
||||
/* Note: complex relocation is not well documented (in particular, no effort
|
||||
is made to define a section's "sector number"), but I'll just guess
|
||||
it's a stack language. */
|
||||
|
||||
#define CPLX_NOP 00 /* NOP - used for padding */
|
||||
#define CPLX_ADD 01
|
||||
#define CPLX_SUB 02
|
||||
#define CPLX_MUL 03
|
||||
#define CPLX_DIV 04
|
||||
#define CPLX_AND 05
|
||||
#define CPLX_OR 06
|
||||
#define CPLX_XOR 07
|
||||
#define CPLX_NEG 010
|
||||
#define CPLX_COM 011
|
||||
#define CPLX_STORE 012 /* Store result, terminate complex string. */
|
||||
#define CPLX_STORE_DISP 013 /* Store result PC-relative, terminate */
|
||||
#define CPLX_GLOBAL 016 /* Followed by four bytes RAD50 global name */
|
||||
#define CPLX_REL 017 /* Followed by one byte "sector
|
||||
number" and two bytes offset */
|
||||
#define CPLX_CONST 020 /* Followed by two bytes constant value */
|
||||
|
||||
typedef struct gsd
|
||||
{
|
||||
FILE *fp; /* The file assigned for output */
|
||||
char buf[122]; /* space for 15 GSD entries */
|
||||
int offset; /* Current buffer for GSD entries */
|
||||
} GSD;
|
||||
|
||||
void gsd_init(GSD *gsd, FILE *fp);
|
||||
int gsd_flush(GSD *gsd);
|
||||
int gsd_mod(GSD *gsd, char *modname);
|
||||
int gsd_csect(GSD *gsd, char *sectname, int size);
|
||||
int gsd_intname(GSD *gsd, char *name, unsigned value);
|
||||
int gsd_xfer(GSD *gsd, char *name, unsigned value);
|
||||
int gsd_global(GSD *gsd, char *name, int flags, unsigned value);
|
||||
int gsd_psect(GSD *gsd, char *name, int flags, int size);
|
||||
int gsd_ident(GSD *gsd, char *name);
|
||||
int gsd_virt(GSD *gsd, char *name, int size);
|
||||
int gsd_end(GSD *gsd);
|
||||
|
||||
typedef struct text_rld
|
||||
{
|
||||
FILE *fp; /* The object file, or NULL */
|
||||
char text[128]; /* text buffer */
|
||||
unsigned txt_addr; /* The base text address */
|
||||
int txt_offset; /* Current text offset */
|
||||
char rld[128]; /* RLD buffer */
|
||||
int rld_offset; /* Current RLD offset */
|
||||
} TEXT_RLD;
|
||||
|
||||
void text_init(TEXT_RLD *tr, FILE *fp, unsigned addr);
|
||||
int text_flush(TEXT_RLD *tr);
|
||||
int text_word(TEXT_RLD *tr, unsigned *addr, int size, unsigned word);
|
||||
int text_internal_word(TEXT_RLD *tr, unsigned *addr, int size,
|
||||
unsigned word);
|
||||
int text_global_word(TEXT_RLD *tr, unsigned *addr, int size,
|
||||
unsigned word, char *global);
|
||||
int text_displaced_word(TEXT_RLD *tr, unsigned *addr, int size,
|
||||
unsigned word);
|
||||
int text_global_displaced_word(TEXT_RLD *tr, unsigned *addr, int size,
|
||||
unsigned word, char *global);
|
||||
int text_global_offset_word(TEXT_RLD *tr, unsigned *addr, int size,
|
||||
unsigned word, char *global);
|
||||
int text_global_displaced_offset_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word,
|
||||
char *global);
|
||||
int text_define_location(TEXT_RLD *tr, char *name,
|
||||
unsigned *addr);
|
||||
int text_modify_location(TEXT_RLD *tr, unsigned *addr);
|
||||
int text_limits(TEXT_RLD *tr, unsigned *addr);
|
||||
int text_psect_word(TEXT_RLD *tr, unsigned *addr, int size,
|
||||
unsigned word, char *name);
|
||||
int text_psect_offset_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word, char *name);
|
||||
int text_psect_displaced_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word, char *name);
|
||||
int text_psect_displaced_offset_word(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, unsigned word,
|
||||
char *name);
|
||||
|
||||
typedef struct text_complex
|
||||
{
|
||||
char accum[126];
|
||||
int len;
|
||||
} TEXT_COMPLEX;
|
||||
|
||||
void text_complex_begin(TEXT_COMPLEX *tx);
|
||||
int text_complex_add(TEXT_COMPLEX *tx);
|
||||
int text_complex_sub(TEXT_COMPLEX *tx);
|
||||
int text_complex_mul(TEXT_COMPLEX *tx);
|
||||
int text_complex_div(TEXT_COMPLEX *tx);
|
||||
int text_complex_and(TEXT_COMPLEX *tx);
|
||||
int text_complex_or(TEXT_COMPLEX *tx);
|
||||
int text_complex_xor(TEXT_COMPLEX *tx);
|
||||
int text_complex_com(TEXT_COMPLEX *tx);
|
||||
int text_complex_neg(TEXT_COMPLEX *tx);
|
||||
int text_complex_lit(TEXT_COMPLEX *tx, unsigned word);
|
||||
int text_complex_global(TEXT_COMPLEX *tx, char *name);
|
||||
int text_complex_psect(TEXT_COMPLEX *tx, unsigned sect,
|
||||
unsigned offset);
|
||||
int text_complex_commit(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, TEXT_COMPLEX *tx,
|
||||
unsigned word);
|
||||
int text_complex_commit_displaced(TEXT_RLD *tr, unsigned *addr,
|
||||
int size, TEXT_COMPLEX *tx,
|
||||
unsigned word);
|
||||
|
||||
int write_endmod(FILE *fp);
|
||||
|
||||
#endif /* OBJECT_J */
|
||||
@ -1,117 +0,0 @@
|
||||
/* Functions to convert RAD50 to or from ASCII. */
|
||||
|
||||
/*
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rad50.h"
|
||||
|
||||
static char radtbl[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ$. 0123456789";
|
||||
|
||||
/* rad50 converts from 0 to 3 ASCII (or EBCDIC, if your compiler is so
|
||||
inclined) characters into a RAD50 word. */
|
||||
|
||||
unsigned rad50(char *cp, char **endp)
|
||||
{
|
||||
unsigned long acc = 0;
|
||||
char *rp;
|
||||
|
||||
if(endp)
|
||||
*endp = cp;
|
||||
|
||||
if(!*cp) /* Got to check for end-of-string
|
||||
manually, because strchr will call
|
||||
it a hit. :-/ */
|
||||
return acc;
|
||||
|
||||
rp = strchr(radtbl, toupper(*cp));
|
||||
if(rp == NULL) /* Not a RAD50 character */
|
||||
return acc;
|
||||
acc = (rp - radtbl) * 03100; /* Convert */
|
||||
cp++;
|
||||
|
||||
/* Now, do the same thing two more times... */
|
||||
|
||||
if(endp)
|
||||
*endp = cp;
|
||||
if(!*cp)
|
||||
return acc;
|
||||
rp = strchr(radtbl, toupper(*cp));
|
||||
if(rp == NULL)
|
||||
return acc;
|
||||
acc += (rp - radtbl) * 050;
|
||||
|
||||
cp++;
|
||||
if(endp)
|
||||
*endp = cp;
|
||||
if(!*cp)
|
||||
return acc;
|
||||
rp = strchr(radtbl, toupper(*cp));
|
||||
if(rp == NULL)
|
||||
return acc;
|
||||
acc += (rp - radtbl);
|
||||
|
||||
cp++;
|
||||
if(endp)
|
||||
*endp = cp;
|
||||
|
||||
return acc; /* Done. */
|
||||
}
|
||||
|
||||
/* rad50x2 - converts from 0 to 6 characters into two words of RAD50. */
|
||||
|
||||
void rad50x2(char *cp, unsigned *rp)
|
||||
{
|
||||
*rp++ = rad50(cp, &cp);
|
||||
*rp = 0;
|
||||
if(*cp)
|
||||
*rp = rad50(cp, &cp);
|
||||
}
|
||||
|
||||
/* unrad50 - converts a RAD50 word to three characters of ASCII. */
|
||||
|
||||
void unrad50(unsigned word, char *cp)
|
||||
{
|
||||
if(word < 0175000) /* Is it legal RAD50? */
|
||||
{
|
||||
cp[0] = radtbl[word / 03100];
|
||||
cp[1] = radtbl[(word / 050) % 050];
|
||||
cp[2] = radtbl[word % 050];
|
||||
}
|
||||
else
|
||||
cp[0] = cp[1] = cp[2] = ' ';
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
#ifndef RAD50_H
|
||||
#define RAD50_H
|
||||
|
||||
/*
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
*/
|
||||
|
||||
extern unsigned rad50(char *cp, char **endp);
|
||||
|
||||
extern void rad50x2(char *cp, unsigned *rp);
|
||||
|
||||
extern void unrad50(unsigned word, char *cp);
|
||||
|
||||
#endif /* RAD50_H */
|
||||
@ -1,380 +0,0 @@
|
||||
/* functions for managing a stack of file and buffer input streams. */
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "macro11.h"
|
||||
|
||||
#include "stream2.h"
|
||||
|
||||
/* BUFFER functions */
|
||||
|
||||
/* new_buffer allocates a new buffer */
|
||||
|
||||
BUFFER *new_buffer(void)
|
||||
{
|
||||
BUFFER *buf = memcheck(malloc(sizeof(BUFFER)));
|
||||
buf->length = 0;
|
||||
buf->size = 0;
|
||||
buf->use = 1;
|
||||
buf->buffer = NULL;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* buffer_resize makes the buffer at least the requested size. */
|
||||
/* If the buffer is already larger, then it will attempt */
|
||||
/* to shrink it. */
|
||||
|
||||
void buffer_resize(BUFFER *buff, int size)
|
||||
{
|
||||
buff->size = size;
|
||||
buff->length = size;
|
||||
|
||||
if(size == 0)
|
||||
{
|
||||
free(buff->buffer);
|
||||
buff->buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(buff->buffer == NULL)
|
||||
buff->buffer = memcheck(malloc(buff->size));
|
||||
else
|
||||
buff->buffer = memcheck(realloc(buff->buffer, buff->size));
|
||||
}
|
||||
}
|
||||
|
||||
/* buffer_clone makes a copy of a buffer */
|
||||
/* Basically it increases the use count */
|
||||
|
||||
BUFFER *buffer_clone(BUFFER *from)
|
||||
{
|
||||
if(from)
|
||||
from->use++;
|
||||
return from;
|
||||
}
|
||||
|
||||
/* buffer_free frees a buffer */
|
||||
/* It decreases the use count, and if zero, */
|
||||
/* frees the memory. */
|
||||
|
||||
void buffer_free(BUFFER *buf)
|
||||
{
|
||||
if(buf)
|
||||
{
|
||||
if(--(buf->use) == 0)
|
||||
{
|
||||
free(buf->buffer);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Append characters to the buffer. */
|
||||
|
||||
void buffer_appendn(BUFFER *buf, char *str, int len)
|
||||
{
|
||||
int needed = buf->length + len + 1;
|
||||
|
||||
if(needed >= buf->size)
|
||||
{
|
||||
buf->size = needed + GROWBUF_INCR;
|
||||
|
||||
if(buf->buffer == NULL)
|
||||
buf->buffer = memcheck(malloc(buf->size));
|
||||
else
|
||||
buf->buffer = memcheck(realloc(buf->buffer, buf->size));
|
||||
}
|
||||
|
||||
memcpy(buf->buffer + buf->length, str, len);
|
||||
buf->length += len;
|
||||
buf->buffer[buf->length] = 0;
|
||||
}
|
||||
|
||||
/* append a text line (zero or newline-delimited) */
|
||||
|
||||
void buffer_append_line(BUFFER *buf, char *str)
|
||||
{
|
||||
char *nl;
|
||||
if((nl = strchr(str, '\n')) != NULL)
|
||||
buffer_appendn(buf, str, nl - str + 1);
|
||||
else
|
||||
buffer_appendn(buf, str, strlen(str));
|
||||
}
|
||||
|
||||
/* Base STREAM class methods */
|
||||
|
||||
/* stream_construct initializes a newly allocated STREAM */
|
||||
|
||||
void stream_construct(STREAM *str, char *name)
|
||||
{
|
||||
str->line = 0;
|
||||
str->name = memcheck(strdup(name));
|
||||
str->next = NULL;
|
||||
str->vtbl = NULL;
|
||||
}
|
||||
|
||||
/* stream_delete destroys and deletes (frees) a STREAM */
|
||||
|
||||
void stream_delete(STREAM *str)
|
||||
{
|
||||
free(str->name);
|
||||
free(str);
|
||||
}
|
||||
|
||||
/* *** class BUFFER_STREAM implementation */
|
||||
|
||||
/* STREAM::gets for a buffer stream */
|
||||
|
||||
char *buffer_stream_gets(STREAM *str)
|
||||
{
|
||||
char *nl;
|
||||
char *cp;
|
||||
BUFFER_STREAM *bstr = (BUFFER_STREAM *)str;
|
||||
BUFFER *buf = bstr->buffer;
|
||||
|
||||
if(buf == NULL)
|
||||
return NULL; /* No buffer */
|
||||
|
||||
if(bstr->offset >= buf->length)
|
||||
return NULL;
|
||||
|
||||
cp = buf->buffer + bstr->offset;
|
||||
|
||||
/* Find the next line in preparation for the next call */
|
||||
|
||||
nl = memchr(cp, '\n', buf->length - bstr->offset);
|
||||
|
||||
if(nl)
|
||||
nl++;
|
||||
|
||||
bstr->offset = nl - buf->buffer;
|
||||
str->line++;
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
/* STREAM::close for a buffer stream */
|
||||
|
||||
void buffer_stream_delete(STREAM *str)
|
||||
{
|
||||
BUFFER_STREAM *bstr = (BUFFER_STREAM *)str;
|
||||
buffer_free(bstr->buffer);
|
||||
stream_delete(str);
|
||||
}
|
||||
|
||||
/* STREAM::rewind for a buffer stream */
|
||||
|
||||
void buffer_stream_rewind(STREAM *str)
|
||||
{
|
||||
BUFFER_STREAM *bstr = (BUFFER_STREAM *)str;
|
||||
bstr->offset = 0;
|
||||
str->line = 0;
|
||||
}
|
||||
|
||||
/* BUFFER_STREAM vtbl */
|
||||
|
||||
STREAM_VTBL buffer_stream_vtbl = { buffer_stream_delete,
|
||||
buffer_stream_gets,
|
||||
buffer_stream_rewind };
|
||||
|
||||
void buffer_stream_construct(BUFFER_STREAM *bstr, BUFFER *buf, char *name)
|
||||
{
|
||||
bstr->stream.vtbl = &buffer_stream_vtbl;
|
||||
|
||||
bstr->stream.name = memcheck(strdup(name));
|
||||
|
||||
bstr->buffer = buffer_clone(buf);
|
||||
bstr->offset = 0;
|
||||
bstr->stream.line = 0;
|
||||
}
|
||||
|
||||
void buffer_stream_set_buffer(BUFFER_STREAM *bstr, BUFFER *buf)
|
||||
{
|
||||
if(bstr->buffer)
|
||||
buffer_free(bstr->buffer);
|
||||
bstr->buffer = buffer_clone(buf);
|
||||
bstr->offset = 0;
|
||||
}
|
||||
|
||||
/* new_buffer_stream clones the given buffer, gives it the name, */
|
||||
/* and creates a BUFFER_STREAM to reference it */
|
||||
|
||||
STREAM *new_buffer_stream(BUFFER *buf, char *name)
|
||||
{
|
||||
BUFFER_STREAM *bstr = memcheck(malloc(sizeof(BUFFER_STREAM)));
|
||||
|
||||
buffer_stream_construct(bstr, buf, name);
|
||||
return &bstr->stream;
|
||||
}
|
||||
|
||||
/* *** FILE_STREAM implementation */
|
||||
|
||||
/* Implement STREAM::gets for a file stream */
|
||||
|
||||
static char *file_gets(STREAM *str)
|
||||
{
|
||||
int i, c;
|
||||
FILE_STREAM *fstr = (FILE_STREAM *)str;
|
||||
|
||||
if(fstr->fp == NULL)
|
||||
return NULL;
|
||||
|
||||
if(feof(fstr->fp))
|
||||
return NULL;
|
||||
|
||||
/* Read single characters, end of line when '\n' or '\f' hit */
|
||||
|
||||
i = 0;
|
||||
while(c = fgetc(fstr->fp),
|
||||
c != '\n' && c != '\f' && c != EOF)
|
||||
{
|
||||
if(c == 0)
|
||||
continue; /* Don't buffer zeros */
|
||||
if(c == '\r')
|
||||
continue; /* Don't buffer carriage returns either */
|
||||
if(i < STREAM_BUFFER_SIZE - 2)
|
||||
fstr->buffer[i++] = c;
|
||||
}
|
||||
|
||||
fstr->buffer[i++] = '\n'; /* Silently transform formfeeds
|
||||
into newlines */
|
||||
fstr->buffer[i] = 0;
|
||||
|
||||
if(c == '\n')
|
||||
fstr->stream.line++; /* Count a line */
|
||||
|
||||
return fstr->buffer;
|
||||
}
|
||||
|
||||
/* Implement STREAM::destroy for a file stream */
|
||||
|
||||
void file_destroy(STREAM *str)
|
||||
{
|
||||
FILE_STREAM *fstr = (FILE_STREAM *)str;
|
||||
fclose(fstr->fp);
|
||||
free(fstr->buffer);
|
||||
stream_delete(str);
|
||||
}
|
||||
|
||||
/* Implement STREAM::rewind for a file stream */
|
||||
|
||||
void file_rewind(STREAM *str)
|
||||
{
|
||||
FILE_STREAM *fstr = (FILE_STREAM *)str;
|
||||
rewind(fstr->fp);
|
||||
str->line = 0;
|
||||
}
|
||||
|
||||
static STREAM_VTBL file_stream_vtbl = { file_destroy, file_gets,
|
||||
file_rewind };
|
||||
|
||||
/* Prepare and open a stream from a file. */
|
||||
|
||||
STREAM *new_file_stream(char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
FILE_STREAM *str;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if(fp == NULL)
|
||||
return NULL;
|
||||
|
||||
str = memcheck(malloc(sizeof(FILE_STREAM)));
|
||||
|
||||
str->stream.vtbl = &file_stream_vtbl;
|
||||
str->stream.name = memcheck(strdup(filename));
|
||||
str->buffer = memcheck(malloc(STREAM_BUFFER_SIZE));
|
||||
str->fp = fp;
|
||||
str->stream.line = 0;
|
||||
|
||||
return &str->stream;
|
||||
}
|
||||
|
||||
/* STACK functions */
|
||||
|
||||
/* stack_init prepares a stack */
|
||||
|
||||
void stack_init(STACK *stack)
|
||||
{
|
||||
stack->top = NULL; /* Too simple */
|
||||
}
|
||||
|
||||
/* stack_pop removes and deletes the topmost STRAM on the stack */
|
||||
|
||||
void stack_pop(STACK *stack)
|
||||
{
|
||||
STREAM *top = stack->top;
|
||||
STREAM *next = top->next;
|
||||
|
||||
top->vtbl->delete(top);
|
||||
stack->top = next;
|
||||
}
|
||||
|
||||
/* stack_push pushes a STREAM onto the top of the stack */
|
||||
|
||||
void stack_push(STACK *stack, STREAM *str)
|
||||
{
|
||||
str->next = stack->top;
|
||||
stack->top = str;
|
||||
}
|
||||
|
||||
/* stack_gets calls vtbl->gets for the topmost stack entry. When
|
||||
topmost streams indicate they're exhausted, they are popped and
|
||||
deleted, until the stack is exhausted. */
|
||||
|
||||
char *stack_gets(STACK *stack)
|
||||
{
|
||||
char *line;
|
||||
|
||||
if(stack->top == NULL)
|
||||
return NULL;
|
||||
|
||||
while((line = stack->top->vtbl->gets(stack->top)) == NULL)
|
||||
{
|
||||
stack_pop(stack);
|
||||
if(stack->top == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
@ -1,110 +0,0 @@
|
||||
#ifndef STREAM2_H
|
||||
#define STREAM2_H
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
struct stream;
|
||||
|
||||
typedef struct stream_vtbl
|
||||
{
|
||||
void (*delete)(struct stream *stream); // Destructor
|
||||
char *(*gets)(struct stream *stream); // "gets" function
|
||||
void (*rewind)(struct stream *stream); // "rewind" function
|
||||
} STREAM_VTBL;
|
||||
|
||||
typedef struct stream
|
||||
{
|
||||
STREAM_VTBL *vtbl; // Pointer to dispatch table
|
||||
char *name; // Stream name
|
||||
int line; // Current line number in stream
|
||||
struct stream *next; // Next stream in stack
|
||||
} STREAM;
|
||||
|
||||
typedef struct file_stream
|
||||
{
|
||||
STREAM stream; // Base class
|
||||
FILE *fp; // File pointer
|
||||
char *buffer; // Line buffer
|
||||
} FILE_STREAM;
|
||||
|
||||
typedef struct buffer
|
||||
{
|
||||
char *buffer; // Pointer to text
|
||||
int size; // Size of buffer
|
||||
int length; // Occupied size of buffer
|
||||
int use; // Number of users of buffer
|
||||
} BUFFER;
|
||||
|
||||
#define GROWBUF_INCR 1024 // Buffers grow by leaps and bounds
|
||||
|
||||
typedef struct buffer_stream
|
||||
{
|
||||
STREAM stream; // Base class
|
||||
BUFFER *buffer; // text buffer
|
||||
int offset; // Current read offset
|
||||
} BUFFER_STREAM;
|
||||
|
||||
typedef struct stack
|
||||
{
|
||||
STREAM *top; // Top of stacked stream pieces
|
||||
} STACK;
|
||||
|
||||
#define STREAM_BUFFER_SIZE 1024 // This limits the max size of an input line.
|
||||
BUFFER *new_buffer(void);
|
||||
BUFFER *buffer_clone(BUFFER *from);
|
||||
void buffer_resize(BUFFER *buff, int size);
|
||||
void buffer_free(BUFFER *buf);
|
||||
void buffer_appendn(BUFFER *buf, char *str, int len);
|
||||
void buffer_append_line(BUFFER *buf, char *str);
|
||||
|
||||
STREAM *new_buffer_stream(BUFFER *buf, char *name);
|
||||
void buffer_stream_set_buffer(BUFFER_STREAM *bstr, BUFFER *buf);
|
||||
|
||||
/* Provide these so that macro11 can derive from a BUFFER_STREAM */
|
||||
extern STREAM_VTBL buffer_stream_vtbl;
|
||||
void buffer_stream_construct(BUFFER_STREAM *bstr, BUFFER *buf, char *name);
|
||||
char *buffer_stream_gets(STREAM *str);
|
||||
void buffer_stream_delete(STREAM *str);
|
||||
void buffer_stream_rewind(STREAM *str);
|
||||
|
||||
STREAM *new_file_stream(char *filename);
|
||||
|
||||
void stack_init(STACK *stack);
|
||||
void stack_push(STACK *stack, STREAM *str);
|
||||
void stack_pop(STACK *stack);
|
||||
char *stack_gets(STACK *stack);
|
||||
|
||||
#endif /* STREAM2_H */
|
||||
@ -1,57 +0,0 @@
|
||||
I was not able to locate a Macro-11 language reference manual any more
|
||||
recent than for RT11 version *3*, so I used that plus my recollection
|
||||
of more modern features. It was enough to get the RT11 V5.4 kernel
|
||||
built, plus a significant chunk of our own code.
|
||||
|
||||
The biggest missing feature is full featured listings. The .LIST and
|
||||
.NLIST directives are ignored, as is .SBTTL. No table of contents is
|
||||
accumulated or printed. No symbol cross referencing is done (most
|
||||
likely I'll just write a CTAGS file, not a cross reference listing).
|
||||
|
||||
Many errors still go unchecked. Off the top of my head, I recall that
|
||||
object and listing file output errors are ignored.
|
||||
|
||||
.FLT4 format may be inaccurate in the low bits. This is because IEEE
|
||||
64 bit format has two fewer mantissa bits than 64 bit PDP-11 format.
|
||||
Without writing soft-float routines, there's not much I can do abbout
|
||||
it.
|
||||
|
||||
Expression math is done in native width, almost certainly 32 bits.
|
||||
Truncation to 16 bits is done only for listing and output. This may
|
||||
make some output differ in the presence of 16-bit overflows and
|
||||
underflows. I don't think this needs fixing.
|
||||
|
||||
.REM blocks containing code can screw up .MACRO, .REPT, .IRP, .IRPC.
|
||||
read_body in macro11.c would need to be able to parse and ignore .REM
|
||||
blocks.
|
||||
|
||||
Need to search a path for the .INCLUDE directive. Right now it only
|
||||
takes a complete file name. And most likely, existing code will have
|
||||
RT-11 style file names; I don't know what to do about that, except put
|
||||
in a device name parser.
|
||||
|
||||
Possible enhancements:
|
||||
|
||||
It would be very simple to make macro11 resolve internal symbols with
|
||||
more that 6 significant characters. Even so, only the first 6 would
|
||||
be used for external symbols, and you have to be wary of existing code
|
||||
that used (for example) .LOOKU rather than .LOOKUP, since these two
|
||||
would become distinct.
|
||||
|
||||
SYM = 0
|
||||
MOV SYM(R0),R0 ; macro11 could optimize SYM(R0) into just (R0)
|
||||
|
||||
I dream of automatically fixing branches out of range. Easy when the
|
||||
destination is backwards, difficult when it's forwards. I have this
|
||||
idea: during the first assembly pass, all branches generate a long
|
||||
branch if the target symbol is undefined, otherwise an "optimized"
|
||||
branch (short or long) if the target is defined. Then keep a
|
||||
128-instruction FIFO of generated instructions. Each FIFO entry is
|
||||
tagged with context and symbol definition as they are pushed to the
|
||||
FIFO. When an instruction gets pulled from the FIFO because it's more
|
||||
than 128 words away, the FIFO is searched for long branches that point
|
||||
to this location; any such are shortened, and any symbols defined
|
||||
following their location in the stream are adjusted. In the second
|
||||
assembly pass, the FIFOs aren't used because all jump distances are
|
||||
known, and the right sized branch (JMP or Bcc) can be generated.
|
||||
|
||||
@ -1,172 +0,0 @@
|
||||
/* Some generally useful routines */
|
||||
/* The majority of the non-portable code is in here. */
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#define stat _stat
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* Sure, the library typically provides some kind of
|
||||
ultoa or _ultoa function. But since it's merely typical
|
||||
and not standard, and since the function is so simple,
|
||||
I'll write my own.
|
||||
|
||||
It's significant feature is that it'll produce representations in
|
||||
any number base from 2 to 36.
|
||||
*/
|
||||
|
||||
char *my_ultoa(unsigned long val, char *buf, unsigned int base)
|
||||
{
|
||||
static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
char *strt = buf, *end;
|
||||
|
||||
do
|
||||
{
|
||||
*buf++ = digits[val % base];
|
||||
val /= base;
|
||||
} while(val != 0);
|
||||
|
||||
*buf = 0; /* delimit */
|
||||
end = buf+1;
|
||||
|
||||
/* Now reverse the bytes */
|
||||
|
||||
while(buf > strt)
|
||||
{
|
||||
char temp;
|
||||
temp = *--buf;
|
||||
*buf = *strt;
|
||||
*strt++ = temp;
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
/* Ditto my_ultoa. This actually emits
|
||||
a signed representation in other number bases. */
|
||||
|
||||
char *my_ltoa(long val, char *buf, unsigned int base)
|
||||
{
|
||||
unsigned long uval;
|
||||
|
||||
if(val < 0)
|
||||
uval = -val, *buf++ = '-';
|
||||
else
|
||||
uval = val;
|
||||
|
||||
return my_ultoa(uval, buf, base);
|
||||
}
|
||||
|
||||
/*
|
||||
_searchenv is a function provided by the MSVC library that finds
|
||||
files which may be anywhere along a path which appears in an
|
||||
environment variable. I duplicate that function for portability.
|
||||
Note also that mine avoids destination buffer overruns.
|
||||
|
||||
Note: uses strtok. This means it'll screw you up if you
|
||||
expect your strtok context to remain intact when you use
|
||||
this function.
|
||||
*/
|
||||
|
||||
void my_searchenv(char *name, char *envname, char *hitfile, int hitlen)
|
||||
{
|
||||
char *env;
|
||||
char *envcopy;
|
||||
char *cp;
|
||||
|
||||
*hitfile = 0; /* Default failure indication */
|
||||
|
||||
/* Note: If the given name is absolute, then don't search the
|
||||
path, but use it as is. */
|
||||
|
||||
if(
|
||||
#ifdef WIN32
|
||||
strchr(name, ':') != NULL || /* Contain a drive spec? */
|
||||
name[0] == '\\' || /* Start with absolute ref? */
|
||||
#endif
|
||||
name[0] == '/') /* Start with absolute ref? */
|
||||
{
|
||||
strncpy(hitfile, name, hitlen); /* Copy to target */
|
||||
return;
|
||||
}
|
||||
|
||||
env = getenv(envname);
|
||||
if(env == NULL)
|
||||
return; /* Variable not defined, no search. */
|
||||
|
||||
envcopy = strdup(env); /* strtok destroys it's text
|
||||
argument. I don't want the return
|
||||
value from getenv destroyed. */
|
||||
|
||||
while((cp = strtok(envcopy, PATHSEP)) != NULL)
|
||||
{
|
||||
struct stat info;
|
||||
char *concat = malloc(strlen(cp) + strlen(name) + 2);
|
||||
if(concat == NULL)
|
||||
{
|
||||
free(envcopy);
|
||||
return;
|
||||
}
|
||||
strcpy(concat, cp);
|
||||
if(concat[strlen(concat)-1] != '/')
|
||||
strcat(concat, "/");
|
||||
strcat(concat, name);
|
||||
if(!stat(concat, &info))
|
||||
{
|
||||
/* Copy the file name to hitfile. Assure that it's really
|
||||
zero-delimited. */
|
||||
strncpy(hitfile, concat, hitlen-1);
|
||||
hitfile[hitlen-1] = 0;
|
||||
free(envcopy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If I fall out of that loop, then hitfile indicates no match,
|
||||
and return. */
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2001, Richard Krehbiel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
o Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
o Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
o Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
char *my_ultoa(unsigned long val, char *buf, unsigned int base);
|
||||
char *my_ltoa(long val, char *buf, unsigned int base);
|
||||
void my_searchenv(char *name, char *envname,
|
||||
char *hitfile, int hitlen);
|
||||
|
||||
/* Cover a few platform-dependencies */
|
||||
|
||||
#ifdef WIN32
|
||||
typedef unsigned __int64 ulong64;
|
||||
#define strdup _strdup
|
||||
#define putenv _putenv
|
||||
#define PATHSEP ";"
|
||||
#else
|
||||
typedef unsigned long long ulong64;
|
||||
#define PATHSEP ":"
|
||||
#endif
|
||||
|
||||
#endif /* UTIL_H */
|
||||
Loading…
x
Reference in New Issue
Block a user