From 0cb8000e5f139c4f94dc8334449db4fd18673967 Mon Sep 17 00:00:00 2001 From: Olaf Seibert Date: Sun, 21 Feb 2016 11:03:27 +0100 Subject: [PATCH] Remove old version. --- crossassemblers/macro11.old/changes | 12 - crossassemblers/macro11.old/depends | 0 crossassemblers/macro11.old/dumpobj.c | 677 --- crossassemblers/macro11.old/dumpobj.dsp | 114 - crossassemblers/macro11.old/license | 30 - crossassemblers/macro11.old/macro11.c | 6197 ----------------------- crossassemblers/macro11.old/macro11.dsp | 180 - crossassemblers/macro11.old/macro11.dsw | 53 - crossassemblers/macro11.old/macro11.h | 39 - crossassemblers/macro11.old/makefile | 38 - crossassemblers/macro11.old/mlb.c | 319 -- crossassemblers/macro11.old/mlb.h | 62 - crossassemblers/macro11.old/object.c | 861 ---- crossassemblers/macro11.old/object.h | 210 - crossassemblers/macro11.old/rad50.c | 117 - crossassemblers/macro11.old/rad50.h | 43 - crossassemblers/macro11.old/stream2.c | 380 -- crossassemblers/macro11.old/stream2.h | 110 - crossassemblers/macro11.old/todo | 57 - crossassemblers/macro11.old/util.c | 172 - crossassemblers/macro11.old/util.h | 56 - 21 files changed, 9727 deletions(-) delete mode 100644 crossassemblers/macro11.old/changes delete mode 100644 crossassemblers/macro11.old/depends delete mode 100644 crossassemblers/macro11.old/dumpobj.c delete mode 100644 crossassemblers/macro11.old/dumpobj.dsp delete mode 100644 crossassemblers/macro11.old/license delete mode 100644 crossassemblers/macro11.old/macro11.c delete mode 100644 crossassemblers/macro11.old/macro11.dsp delete mode 100644 crossassemblers/macro11.old/macro11.dsw delete mode 100644 crossassemblers/macro11.old/macro11.h delete mode 100644 crossassemblers/macro11.old/makefile delete mode 100644 crossassemblers/macro11.old/mlb.c delete mode 100644 crossassemblers/macro11.old/mlb.h delete mode 100644 crossassemblers/macro11.old/object.c delete mode 100644 crossassemblers/macro11.old/object.h delete mode 100644 crossassemblers/macro11.old/rad50.c delete mode 100644 crossassemblers/macro11.old/rad50.h delete mode 100644 crossassemblers/macro11.old/stream2.c delete mode 100644 crossassemblers/macro11.old/stream2.h delete mode 100644 crossassemblers/macro11.old/todo delete mode 100644 crossassemblers/macro11.old/util.c delete mode 100644 crossassemblers/macro11.old/util.h diff --git a/crossassemblers/macro11.old/changes b/crossassemblers/macro11.old/changes deleted file mode 100644 index 9fa1e30..0000000 --- a/crossassemblers/macro11.old/changes +++ /dev/null @@ -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. diff --git a/crossassemblers/macro11.old/depends b/crossassemblers/macro11.old/depends deleted file mode 100644 index e69de29..0000000 diff --git a/crossassemblers/macro11.old/dumpobj.c b/crossassemblers/macro11.old/dumpobj.c deleted file mode 100644 index 4efeb5f..0000000 --- a/crossassemblers/macro11.old/dumpobj.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#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; -} diff --git a/crossassemblers/macro11.old/dumpobj.dsp b/crossassemblers/macro11.old/dumpobj.dsp deleted file mode 100644 index cbb76d1..0000000 --- a/crossassemblers/macro11.old/dumpobj.dsp +++ /dev/null @@ -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 diff --git a/crossassemblers/macro11.old/license b/crossassemblers/macro11.old/license deleted file mode 100644 index b5b4413..0000000 --- a/crossassemblers/macro11.old/license +++ /dev/null @@ -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. diff --git a/crossassemblers/macro11.old/macro11.c b/crossassemblers/macro11.old/macro11.c deleted file mode 100644 index 8283e6f..0000000 --- a/crossassemblers/macro11.old/macro11.c +++ /dev/null @@ -1,6197 +0,0 @@ -/* - Assembler compatible with MACRO-11. - -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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "macro11.h" - -#include "rad50.h" - -#include "object.h" - -#include "stream2.h" - -#include "mlb.h" - -#include "util.h" - -#define SYMMAX 6 /* I will honor this many character - symbols */ - -#define issym(c) (isalpha(c) || isdigit(c) || (c) == '.' || (c) == '$') - -/* Program sections: */ - -typedef struct section -{ - char *label; /* Section name */ - unsigned type; /* Section type */ -#define USER 1 /* user-defined */ -#define SYSTEM 2 /* A system symbol (like "."; value is an - enum) */ -#define INSTRUCTION 3 /* An instruction code (like "MOV"; value is - an enum) */ -#define PSEUDO 4 /* A pseudo-op (.PSECT, .TITLE, .MACRO, .IF; - value is an enum) */ -#define REGISTER 5 /* Symbol is a register (value 0=$0, value - 1=$1, ... $7) */ -#define USERMACRO 6 /* Symbol is a user macro */ - - unsigned flags; /* Flags, defined in object.h */ - unsigned pc; /* Current offset in the section */ - unsigned size; /* Current section size */ - unsigned sector; /* Used for complex relocation, and naught else */ -} SECTION; - -/* Symbol table entries */ - -typedef struct symbol -{ - char *label; /* Symbol name */ - unsigned value; /* Symbol value */ - int stmtno; /* Statement number of symbol's definition */ - unsigned flags; /* Symbol flags */ -#define PERMANENT 1 /* Symbol may not be redefined */ -#define GLOBAL 2 /* Symbol is global */ -#define WEAK 4 /* Symbol definition is weak */ -#define DEFINITION 8 /* Symbol is a global definition, not - reference */ -#define UNDEFINED 16 /* Symbol is a phony, undefined */ -#define LOCAL 32 /* Set if this is a local label (i.e. 10$) */ - - SECTION *section; /* Section in which this symbol is defined */ - struct symbol *next; /* Next symbol with the same hash value */ -} SYMBOL; - -/* Arguments given to macros or .IRP/.IRPC blocks */ - -typedef struct arg -{ - struct arg *next; /* Pointer in arg list */ - int locsym; /* Whether arg represents an optional - local symbol */ - char *label; /* Argument name */ - char *value; /* Default or active substitution */ -} ARG; - -/* A MACRO is a superstructure surrounding a SYMBOL. */ - -typedef struct macro -{ - SYMBOL sym; /* Surrounds a symbol, contains the macro - name */ - ARG *args; /* The argument list */ - BUFFER *text; /* The macro text */ -} MACRO; - -typedef struct ex_tree -{ - enum ex_type - { - EX_LIT=1, /* Expression is a literal value */ - EX_SYM=2, /* Expression has a symbol reference */ - EX_UNDEFINED_SYM=3, /* Expression is undefined sym reference */ - EX_TEMP_SYM=4, /* Expression is temp sym reference */ - - EX_COM=5, /* One's complement */ - EX_NEG=6, /* Negate */ - EX_ERR=7, /* Expression with an error */ - - EX_ADD=8, /* Add */ - EX_SUB=9, /* Subtract */ - EX_MUL=10, /* Multiply */ - EX_DIV=11, /* Divide */ - EX_AND=12, /* bitwise and */ - EX_OR=13 /* bitwise or */ - } type; - - char *cp; /* points to end of parsed expression */ - - union - { - struct - { - struct ex_tree *left, *right; /* Left, right children */ - } child; - unsigned lit; /* Literal value */ - SYMBOL *symbol; /* Symbol reference */ - } data; - -} EX_TREE; - -typedef struct addr_mode -{ - unsigned type; /* The bits that represent the addressing mode */ - /* bits 0:2 are register number */ - /* bit 3 is indirect */ - /* bits 4:6 are mode, where 0=Rn, 1=(Rn)+, - 2=-(Rn), 3=offset(Rn) */ - int rel; /* the addressing mode is PC-relative */ - EX_TREE *offset; /* Expression giving the offset */ -} ADDR_MODE; - -#define FALSE 0 /* Everybody needs FALSE and TRUE */ -#define TRUE 1 - -enum pseudo_ops -{ - P_ASCII, P_ASCIZ, P_ASECT, P_BLKB, P_BLKW, P_BYTE, P_CSECT, P_DSABL, - P_ENABL, P_END, P_ENDC, P_ENDM, P_ENDR, P_EOT, P_ERROR, P_EVEN, - P_FLT2, P_FLT4, P_GLOBL, P_IDENT, P_IF, P_IFF, P_IFT, P_IFTF, P_IIF, - P_IRP, P_IRPC, P_LIMIT, P_LIST, P_MCALL, P_MEXIT, P_NARG, P_NCHR, - P_NLIST, P_NTYPE, P_ODD, P_PACKED, P_PAGE, P_PRINT, P_PSECT, P_RADIX, - P_RAD50, P_REM, P_REPT, P_RESTORE, P_SAVE, P_SBTTL, P_TITLE, - P_WORD, P_MACRO, P_INCLU, P_WEAK, P_IFDF -}; - -enum instruction_ops -{ - I_ADC = 0005500, I_ADCB = 0105500, I_ADD = 0060000, I_ASH = 0072000, - I_ASHC = 0073000, I_ASL = 0006300, I_ASLB = 0106300, I_ASR = 0006200, - I_ASRB = 0106200, I_BCC = 0103000, I_BCS = 0103400, I_BEQ = 0001400, - I_BGE = 0002000, I_BGT = 0003000, I_BHI = 0101000, I_BHIS = 0103000, - I_BIC = 0040000, I_BICB = 0140000, I_BIS = 0050000, I_BISB = 0150000, - I_BIT = 0030000, I_BITB = 0130000, I_BLE = 0003400, I_BLO = 0103400, - I_BLOS = 0101400, I_BLT = 0002400, I_BMI = 0100400, I_BNE = 0001000, - I_BPL = 0100000, I_BPT = 0000003, I_BR = 0000400, I_BVC = 0102000, - I_BVS = 0102400, I_CALL = 0004700, I_CALLR = 0000100, I_CCC = 0000257, - I_CLC = 0000241, I_CLN = 0000250, I_CLR = 0005000, I_CLRB = 0105000, - I_CLV = 0000242, I_CLZ = 0000244, I_CMP = 0020000, I_CMPB = 0120000, - I_COM = 0005100, I_COMB = 0105100, I_DEC = 0005300, I_DECB = 0105300, - I_DIV = 0071000, I_EMT = 0104000, I_FADD = 0075000, I_FDIV = 0075030, - I_FMUL = 0075020, I_FSUB = 0075010, I_HALT = 0000000, I_INC = 0005200, - I_INCB = 0105200, I_IOT = 0000004, I_JMP = 0000100, I_JSR = 0004000, - I_MARK = 0006400, I_MED6X = 0076600, I_MED74C= 0076601, I_MFPD = 0106500, - I_MFPI = 0006500, I_MFPS = 0106700, I_MOV = 0010000, I_MOVB = 0110000, - I_MTPD = 0106600, I_MTPI = 0006600, I_MTPS = 0106400, I_MUL = 0070000, - I_NEG = 0005400, I_NEGB = 0105400, I_NOP = 0000240, I_RESET = 0000005, - I_RETURN= 0000207, I_ROL = 0006100, I_ROLB = 0106100, I_ROR = 0006000, - I_RORB = 0106000, I_RTI = 0000002, I_RTS = 0000200, I_RTT = 0000006, - I_SBC = 0005600, I_SBCB = 0105600, I_SCC = 0000277, I_SEC = 0000261, - I_SEN = 0000270, I_SEV = 0000262, I_SEZ = 0000264, I_SOB = 0077000, - I_SPL = 0000230, I_SUB = 0160000, I_SWAB = 0000300, I_SXT = 0006700, - I_TRAP = 0104400, I_TST = 0005700, I_TSTB = 0105700, I_WAIT = 0000001, - I_XFC = 0076700, I_XOR = 0074000, I_MFPT = 0000007, - /* CIS not implemented - maybe later */ - /* FPU */ - I_ABSD = 0170600, I_ABSF = 0170600, I_ADDD = 0172000, I_ADDF = 0172000, - I_CFCC = 0170000, I_CLRD = 0170400, I_CLRF = 0170400, I_CMPD = 0173400, - I_CMPF = 0173400, I_DIVD = 0174400, I_DIVF = 0174400, I_LDCDF = 0177400, - I_LDCFD = 0177400, I_LDCID = 0177000, I_LDCIF = 0177000, I_LDCLD = 0177000, - I_LDCLF = 0177000, I_LDD = 0172400, I_LDEXP = 0176400, I_LDF = 0172400, - I_LDFPS = 0170100, I_MODD = 0171400, I_MODF = 0171400, I_MULD = 0171000, - I_MULF = 0171000, I_NEGD = 0170700, I_NEGF = 0170700, I_SETD = 0170011, - I_SETF = 0170001, I_SETI = 0170002, I_SETL = 0170012, I_STA0 = 0170005, - I_STB0 = 0170006, I_STCDF = 0176000, I_STCDI = 0175400, I_STCDL = 0175400, - I_STCFD = 0176000, I_STCFI = 0175400, I_STCFL = 0175400, I_STD = 0174000, - I_STEXP = 0175000, I_STF = 0174000, I_STFPS = 0170200, I_STST = 0170300, - I_SUBD = 0173000, I_SUBF = 0173000, I_TSTD = 0170500, I_TSTF = 0170500 -}; - -enum operand_codes -{ - OC_MASK = 0xff00, /* mask over flags for operand types */ - OC_NONE = 0x0000, /* No operands */ - OC_1GEN = 0x0100, /* One general operand (CLR, TST, etc.) */ - OC_2GEN = 0x0200, /* Two general operand (MOV, CMP, etc.) */ - OC_BR = 0x0300, /* Branch */ - OC_ASH = 0x0400, /* ASH and ASHC (one gen, one reg) */ - OC_MARK = 0x0500, /* MARK instruction operand */ - OC_JSR = 0x0600, /* JSR, XOR (one reg, one gen) */ - OC_1REG = 0x0700, /* FADD, FSUB, FMUL, FDIV, RTS */ - OC_SOB = 0x0800, /* SOB */ - OC_1FIS = 0x0900, /* FIS (reg, gen) */ - OC_2FIS = 0x0a00, /* FIS (gen, reg) */ - OC__LAST = 0xff00 }; - -/* - format of a listing line - Interestingly, no instances of this struct are ever created. - It lives to be a way to layout the format of a list line. - I wonder if I should have bothered. -*/ - -typedef struct lstformat -{ - char flag[2]; /* Error flags */ - char line_number[6]; /* Line number */ - char pc[8]; /* Location */ - char words[8][3]; /* three instruction words */ - char source[1]; /* source line */ -} LSTFORMAT; - -#define SIZEOF_MEMBER(s, m) (sizeof((s *)0)->m) - -/* GLOBAL VARIABLES */ - -int pass = 0; /* The current assembly pass. 0 = first - pass. */ - -int stmtno = 0; /* The current source line number */ -int radix = 8; /* The current input conversion radix */ -int lsb = 0; /* The current local symbol section identifier */ -int last_lsb = 0; /* The last block in which a macro - automatic label was created */ -int last_locsym = 32768; /* The last local symbol number generated */ - -int enabl_debug = 0; /* Whether assembler debugging is enabled */ - -int enabl_ama = 0; /* When set, chooses absolute (037) versus - PC-relative */ - /* (067) addressing mode */ -int enabl_lsb = 0; /* When set, stops non-local symbol - definitions from delimiting local - symbol sections. */ - -int enabl_gbl = 1; /* Implicit definition of global symbols */ - -int list_md = 1; /* option to list macro/rept definition = yes */ - -int list_me = 1; /* option to list macro/rept expansion = yes */ - -int list_bex = 1; /* option to show binary */ - -int list_level = 1; /* Listing control level. .LIST - increments; .NLIST decrements */ - -char *listline; /* Source lines */ - -char *binline; /* for octal expansion */ - -FILE *lstfile = NULL; - -int suppressed = 0; /* Assembly suppressed by failed conditional */ - -#define MAX_MLBS 32 -MLB *mlbs[MAX_MLBS]; /* macro libraries specified on the - command line */ -int nr_mlbs = 0; /* Number of macro libraries */ - -typedef struct cond -{ - int ok; /* What the condition evaluated to */ - char *file; /* What file and line it occurred */ - int line; -} COND; - -#define MAX_CONDS 256 -COND conds[MAX_CONDS]; /* Stack of recent conditions */ -int last_cond; /* 0 means no stacked cond. */ - -SECTION *sect_stack[32]; /* 32 saved sections */ -int sect_sp; /* Stack pointer */ - -char *module_name = NULL; /* The module name (taken from the 'TITLE'); */ - -char *ident = NULL; /* .IDENT name */ - -EX_TREE *xfer_address = NULL; /* The transfer address */ - -SYMBOL *current_pc; /* The current program counter */ - -unsigned last_dot_addr; /* Last coded PC... */ -SECTION *last_dot_section; /* ...and it's program section */ - -#define DOT (current_pc->value) /* Handy reference to the current location */ - -/* The following are dummy psects for symbols which have meaning to - the assembler: */ - -SECTION register_section = -{ "", REGISTER, 0, 0 }; /* the section containing the registers */ - -SECTION pseudo_section = -{ "", PSEUDO, 0, 0 }; /* the section containing the - pseudo-operations */ - -SECTION instruction_section = -{ ". ABS.", INSTRUCTION, 0, 0 }; /* the section containing instructions */ - -SECTION macro_section = -{ "", SYSTEM, 0, 0, 0 }; /* Section for macros */ - -/* These are real psects that get written out to the object file */ - -SECTION absolute_section = -{ ". ABS.", SYSTEM, PSECT_GBL|PSECT_COM, 0, 0, 0}; /* The default - absolute section */ - -SECTION blank_section = -{ "", SYSTEM, PSECT_REL, 0, 0, 1}; /* The default relocatable section */ - -SECTION *sections[256] = { /* Array of sections in the order they were - defined */ - &absolute_section, &blank_section, }; - -int sector = 2; /* number of such sections */ - -SYMBOL *reg_sym[8]; /* Keep the register symbols in a handy array */ - -/* symbol tables */ - -#define HASH_SIZE 1023 - -typedef struct symbol_table -{ - SYMBOL *hash[HASH_SIZE]; -} SYMBOL_TABLE; - -SYMBOL_TABLE system_st; /* System symbols (Instructions, - pseudo-ops, registers) */ - -SYMBOL_TABLE section_st; /* Program sections */ - -SYMBOL_TABLE symbol_st; /* User symbols */ - -SYMBOL_TABLE macro_st; /* Macros */ - -SYMBOL_TABLE implicit_st; /* The symbols which may be implicit globals */ - -/* SYMBOL_ITER is used for iterating thru a symbol table. */ - -typedef struct symbol_iter -{ - int subscript; /* Current hash subscript */ - SYMBOL *current; /* Current symbol */ -} SYMBOL_ITER; - -/* EOL says whether a char* is pointing at the end of a line */ -#define EOL(c) (!(c) || (c) == '\n' || (c) == ';') - -/* reports errors */ -static void report(STREAM *str, char *fmt, ...) -{ - va_list ap; - char *name = "**"; - int line = 0; - - if(!pass) - return; /* Don't report now. */ - - if(str) - { - name = str->name; - line = str->line; - } - - fprintf(stderr, "%s:%d: ***ERROR ", name, line); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if(lstfile) - { - fprintf(lstfile, "%s:%d: ***ERROR ", name, line); - va_start(ap, fmt); - vfprintf(lstfile, fmt, ap); - va_end(ap); - } -} - -/* memcheck - crash out if a pointer (returned from malloc) is NULL. */ - -void *memcheck(void *ptr) -{ - if(ptr == NULL) - { - fprintf(stderr, "Out of memory.\n"); - exit(EXIT_FAILURE); - } - - return ptr; -} - -/* upcase turns a string to upper case */ - -static void upcase(char *str) -{ - while(*str) - { - *str = toupper(*str); - str++; - } -} - -/* hash_name hashes a name into a value from 0-HASH_SIZE */ - -static int hash_name(char *label) -{ - unsigned accum = 0; - - while(*label) - accum = (accum << 1) ^ *label++; - - accum %= HASH_SIZE; - - return accum; -} - -/* Allocate a new symbol. Does not add it to any symbol table. */ - -static SYMBOL *new_sym(char *label) -{ - SYMBOL *sym = memcheck(malloc(sizeof(SYMBOL))); - sym->label = memcheck(strdup(label)); - sym->section = NULL; - sym->value = 0; - sym->flags = 0; - return sym; -} - -/* Free a symbol. Does not remove it from any symbol table. */ - -static void free_sym(SYMBOL *sym) -{ - if(sym->label) - { - free(sym->label); - sym->label = NULL; - } - free(sym); -} - -/* remove_sym removes a symbol from it's symbol table. */ - -static void remove_sym(SYMBOL *sym, SYMBOL_TABLE *table) -{ - SYMBOL **prevp, *symp; - int hash; - - hash = hash_name(sym->label); - prevp = &table->hash[hash]; - while(symp = *prevp, symp != NULL && symp != sym) - prevp = &symp->next; - - if(symp) - *prevp = sym->next; -} - -/* lookup_sym finds a symbol in a table */ - -static SYMBOL *lookup_sym(char *label, SYMBOL_TABLE *table) -{ - unsigned hash; - SYMBOL *sym; - - hash = hash_name(label); - - sym = table->hash[hash]; - while(sym && strcmp(sym->label, label) != 0) - sym = sym->next; - - return sym; -} - -/* next_sym - returns the next symbol from a symbol table. Must be - preceeded by first_sym. Returns NULL after the last symbol. */ - -static SYMBOL *next_sym(SYMBOL_TABLE *table, SYMBOL_ITER *iter) -{ - if(iter->current) - iter->current = iter->current->next; - - while(iter->current == NULL) - { - if(iter->subscript >= HASH_SIZE) - return NULL; /* No more symbols. */ - iter->current = table->hash[iter->subscript]; - iter->subscript++; - } - - return iter->current; /* Got a symbol. */ -} - -/* first_sym - returns the first symbol from a symbol table. Symbols - are stored in random order. */ - -static SYMBOL *first_sym(SYMBOL_TABLE *table, SYMBOL_ITER *iter) -{ - iter->subscript = 0; - iter->current = NULL; - return next_sym(table, iter); -} - -/* add_table - add a symbol to a symbol table. */ - -static void add_table(SYMBOL *sym, SYMBOL_TABLE *table) -{ - int hash = hash_name(sym->label); - sym->next = table->hash[hash]; - table->hash[hash] = sym; -} - -/* add_sym - used throughout to add or update symbols in a symbol - table. */ - -static SYMBOL *add_sym(char *label, unsigned value, unsigned flags, - SECTION *section, SYMBOL_TABLE *table) -{ - SYMBOL *sym; - - sym = lookup_sym(label, table); - if(sym != NULL) - { - // A symbol registered as "undefined" can be changed. - - if((sym->flags & UNDEFINED) && - !(flags & UNDEFINED)) - { - sym->flags &= ~(PERMANENT|UNDEFINED); - } - - /* Check for compatible definition */ - else if(sym->section == section && - sym->value == value) - { - sym->flags |= flags; /* Merge flags quietly */ - return sym; /* 's okay */ - } - - if(!(sym->flags & PERMANENT)) - { - /* permit redefinition */ - sym->value = value; - sym->flags |= flags; - sym->section = section; - return sym; - } - - return NULL; /* Bad symbol redefinition */ - } - - sym = new_sym(label); - sym->flags = flags; - sym->stmtno = stmtno; - sym->section = section; - sym->value = value; - - add_table(sym, table); - - return sym; -} - -/* Allocate a new section */ - -static SECTION *new_section(void) -{ - SECTION *sect = memcheck(malloc(sizeof(SECTION))); - sect->flags = 0; - sect->size = 0; - sect->pc = 0; - sect->type = 0; - sect->sector = 0; - sect->label = NULL; - return sect; -} - -/* Allocate a new ARG */ - -static ARG *new_arg(void) -{ - ARG *arg = memcheck(malloc(sizeof(ARG))); - arg->locsym = 0; - arg->value = NULL; - arg->next = NULL; - arg->label = NULL; - return arg; -} - -/* Allocate a new macro */ - -static MACRO *new_macro(char *label) -{ - MACRO *mac = memcheck(malloc(sizeof(MACRO))); - - mac->sym.flags = 0; - mac->sym.label = label; - mac->sym.stmtno = stmtno; - mac->sym.next = NULL; - mac->sym.section = ¯o_section; - mac->sym.value = 0; - mac->args = NULL; - mac->text = NULL; - - return mac; -} - -/* Free a list of args (as for a macro, or a macro expansion) */ - -static void free_args(ARG *arg) -{ - ARG *next; - - while(arg) - { - next = arg->next; - if(arg->label) - { - free(arg->label); - arg->label = NULL; - } - if(arg->value) - { - free(arg->value); - arg->value = NULL; - } - free(arg); - arg = next; - } -} - -/* free a macro, it's args, it's text, etc. */ - -static void free_macro(MACRO *mac) -{ - if(mac->text) - { - free(mac->text); - } - free_args(mac->args); - free_sym(&mac->sym); -} - -/* do_list returns TRUE if listing is enabled. */ - -static int dolist(void) -{ - int ok = lstfile != NULL && pass > 0 && list_level > 0; - return ok; -} - -/* list_source saves a text line for later listing by list_flush */ - -static void list_source(STREAM *str, char *cp) -{ - if(dolist()) - { - int len = strcspn(cp, "\n"); - /* Save the line text away for later... */ - if(listline) - free(listline); - listline = memcheck(malloc(len + 1)); - memcpy(listline, cp, len); - listline[len] = 0; - - if(!binline) - binline = memcheck(malloc(sizeof(LSTFORMAT) + 16)); - - sprintf(binline, "%*s%*d", - SIZEOF_MEMBER(LSTFORMAT, flag), "", - SIZEOF_MEMBER(LSTFORMAT, line_number), str->line); - } -} - -/* padto adds blanks to the end of a string until it's the given - length. */ - -static void padto(char *str, int to) -{ - int needspace = to - strlen(str); - str += strlen(str); - while(needspace > 0) - *str++ = ' ', needspace--; - *str = 0; -} - -/* list_flush produces a buffered list line. */ - -static void list_flush(void) -{ - if(dolist()) - { - padto(binline, offsetof(LSTFORMAT, source)); - fputs(binline, lstfile); - fputs(listline, lstfile); - fputc('\n', lstfile); - listline[0] = 0; - binline[0] = 0; - } -} - -/* list_fit checks to see if a word will fit in the current listing - line. If not, it flushes and prepares another line. */ - -static void list_fit(STREAM *str, unsigned addr) -{ - int len = strlen(binline); - size_t col1 = offsetof(LSTFORMAT, source); - size_t col2 = offsetof(LSTFORMAT, pc); - - if(strlen(binline) >= col1) - { - int offset = offsetof(LSTFORMAT, pc); - list_flush(); - listline[0] = 0; - binline[0] = 0; - sprintf(binline, "%*s %6.6o", - offsetof(LSTFORMAT, pc), "", - addr); - padto(binline, offsetof(LSTFORMAT, words)); - } - else if(strlen(binline) <= col2) - { - sprintf(binline, "%*s%*d %6.6o", - SIZEOF_MEMBER(LSTFORMAT, flag), "", - SIZEOF_MEMBER(LSTFORMAT, line_number), str->line, - addr); - padto(binline, offsetof(LSTFORMAT, words)); - } -} - -/* list_value is used to show a computed value */ - -static void list_value(STREAM *str, unsigned word) -{ - if(dolist()) - { - /* Print the value and go */ - binline[0] = 0; - sprintf(binline, "%*s%*d %6.6o", - SIZEOF_MEMBER(LSTFORMAT, flag), "", - SIZEOF_MEMBER(LSTFORMAT, line_number), str->line, - word & 0177777); - } -} - -/* Print a word to the listing file */ - -void list_word(STREAM *str, unsigned addr, unsigned value, int size, - char *flags) -{ - if(dolist()) - { - list_fit(str, addr); - if(size == 1) - sprintf(binline + strlen(binline), " %3.3o%1.1s ", - value & 0377, flags); - else - sprintf(binline + strlen(binline), "%6.6o%1.1s ", - value & 0177777, flags); - } -} - -/* This is called by places that are about to store some code, or - which want to manually update DOT. */ - -static void change_dot(TEXT_RLD *tr, int size) -{ - if(size > 0) - { - if(last_dot_section != current_pc->section) - { - text_define_location(tr, current_pc->section->label, - ¤t_pc->value); - last_dot_section = current_pc->section; - last_dot_addr = current_pc->value; - } - if(last_dot_addr != current_pc->value) - { - text_modify_location(tr, ¤t_pc->value); - last_dot_addr = current_pc->value; - } - - /* Update for next time */ - last_dot_addr += size; - } - - if(DOT+size > current_pc->section->size) - current_pc->section->size = DOT+size; -} - -/* store_word stores a word to the object file and lists it to the - listing file */ - -static int store_word(STREAM *str, TEXT_RLD *tr, int size, - unsigned word) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, ""); - return text_word(tr, &DOT, size, word); -} - -/* store_word stores a word to the object file and lists it to the - listing file */ - -static int store_displaced_word(STREAM *str, TEXT_RLD *tr, - int size, unsigned word) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, "'"); - return text_displaced_word(tr, &DOT, size, word); -} - -static int store_global_displaced_offset_word(STREAM *str, TEXT_RLD *tr, - int size, - unsigned word, char *global) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, "G"); - return text_global_displaced_offset_word(tr, &DOT, size, - word, global); -} - -static int store_global_offset_word(STREAM *str, TEXT_RLD *tr, - int size, - unsigned word, char *global) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, "G"); - return text_global_offset_word(tr, &DOT, size, word, global); -} - -static int store_internal_word(STREAM *str, TEXT_RLD *tr, - int size, unsigned word) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, ""); - return text_internal_word(tr, &DOT, size, word); -} - -static int store_psect_displaced_offset_word(STREAM *str, TEXT_RLD *tr, - int size, - unsigned word, char *name) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, ""); - return text_psect_displaced_offset_word(tr, &DOT, size, word, name); -} - -static int store_psect_offset_word(STREAM *str, TEXT_RLD *tr, - int size, - unsigned word, char *name) -{ - change_dot(tr, size); - list_word(str, DOT, word, size, ""); - return text_psect_offset_word(tr, &DOT, size, word, name); -} - -static int store_limits(STREAM *str, TEXT_RLD *tr) -{ - change_dot(tr, 4); - list_word(str, DOT, 0, 2, ""); - list_word(str, DOT+2, 0, 2, ""); - return text_limits(tr, &DOT); -} - -/* skipwhite - used everywhere to advance a char pointer past spaces */ - -static char *skipwhite(char *cp) -{ - while(*cp == ' ' || *cp == '\t') - cp++; - return cp; -} - -/* skipdelim - used everywhere to advance between tokens. Whitespace - and one comma are allowed delims. */ - -static char *skipdelim(char *cp) -{ - cp = skipwhite(cp); - if(*cp == ',') - cp = skipwhite(cp+1); - return cp; -} - -/* Parse PDP-11 64-bit floating point format. */ -/* Give a pointer to "size" words to receive the result. */ -/* Note: there are probably degenerate cases that store incorrect - results. For example, I think rounding up a FLT2 might cause - exponent overflow. Sorry. */ -/* Note also that the full 49 bits of precision probably aren't - available on the source platform, given the widespread application - of IEEE floating point formats, so expect some differences. Sorry - again. */ - -int parse_float(char *cp, char **endp, int size, unsigned *flt) -{ - double d; /* value */ - double frac; /* fractional value */ - ulong64 ufrac; /* fraction converted to 49 bit - unsigned integer */ - int i; /* Number of fields converted by sscanf */ - int n; /* Number of characters converted by sscanf */ - int sexp; /* Signed exponent */ - unsigned exp; /* Unsigned excess-128 exponent */ - unsigned sign = 0; /* Sign mask */ - - i = sscanf(cp, "%lf%n", &d, &n); - if(i == 0) - return 0; /* Wasn't able to convert */ - - cp += n; - if(endp) - *endp = cp; - - if(d == 0.0) - { - flt[0] = flt[1] = flt[2] = flt[3] = 0; /* All-bits-zero equals zero */ - return 1; /* Good job. */ - } - - frac = frexp(d, &sexp); /* Separate into exponent and mantissa */ - if(sexp < -128 || sexp > 127) - return 0; /* Exponent out of range. */ - - exp = sexp + 128; /* Make excess-128 mode */ - exp &= 0xff; /* express in 8 bits */ - - if(frac < 0) - { - sign = 0100000; /* Negative sign */ - frac = -frac; /* fix the mantissa */ - } - - /* The following big literal is 2 to the 49th power: */ - ufrac = (ulong64) (frac * 72057594037927936.0); /* Align fraction bits */ - - /* Round from FLT4 to FLT2 */ - if(size < 4) - { - ufrac += 0x80000000; /* Round to nearest 32-bit - representation */ - - if(ufrac > 0x200000000000) /* Overflow? */ - { - ufrac >>= 1; /* Normalize */ - exp--; - } - } - - flt[0] = (unsigned) (sign | (exp << 7) | (ufrac >> 48) & 0x7F); - if(size > 1) - { - flt[1] = (unsigned) ((ufrac >> 32) & 0xffff); - if(size > 2) - { - flt[2] = (unsigned) ((ufrac >> 16) & 0xffff); - flt[3] = (unsigned) ((ufrac >> 0) & 0xffff); - } - } - - return 1; -} - -/* Allocate an EX_TREE */ - -static EX_TREE *new_ex_tree(void) -{ - EX_TREE *tr = memcheck(malloc(sizeof(EX_TREE))); - return tr; -} - - -/* Create an EX_TREE representing a parse error */ - -static EX_TREE *ex_err(EX_TREE *tp, char *cp) -{ - EX_TREE *errtp; - - errtp = new_ex_tree(); - errtp->cp = cp; - errtp->type = EX_ERR; - errtp->data.child.left = tp; - - return errtp; -} - -/* Create an EX_TREE representing a literal value */ - -static EX_TREE *new_ex_lit(unsigned value) -{ - EX_TREE *tp; - - tp = new_ex_tree(); - tp->type = EX_LIT; - tp->data.lit = value; - - return tp; -} - -/* The recursive-descent expression parser parse_expr. */ - -/* This parser was designed for expressions with operator precedence. - However, MACRO-11 doesn't observe any sort of operator precedence. - If you feel your source deserves better, give the operators - appropriate precedence values right here. */ - -#define ADD_PREC 1 -#define MUL_PREC 1 -#define AND_PREC 1 -#define OR_PREC 1 - -EX_TREE *parse_unary(char *cp); /* Prototype for forward calls */ - -EX_TREE *parse_binary(char *cp, char term, int depth) -{ - EX_TREE *leftp, *rightp, *tp; - - leftp = parse_unary(cp); - - while(leftp->type != EX_ERR) - { - cp = skipwhite(leftp->cp); - - if(*cp == term) - return leftp; - - switch(*cp) - { - case '+': - if(depth >= ADD_PREC) - return leftp; - - rightp = parse_binary(cp+1, term, ADD_PREC); - tp = new_ex_tree(); - tp->type = EX_ADD; - tp->data.child.left = leftp; - tp->data.child.right = rightp; - tp->cp = rightp->cp; - leftp = tp; - break; - - case '-': - if(depth >= ADD_PREC) - return leftp; - - rightp = parse_binary(cp+1, term, ADD_PREC); - tp = new_ex_tree(); - tp->type = EX_SUB; - tp->data.child.left = leftp; - tp->data.child.right = rightp; - tp->cp = rightp->cp; - leftp = tp; - break; - - case '*': - if(depth >= MUL_PREC) - return leftp; - - rightp = parse_binary(cp+1, term, MUL_PREC); - tp = new_ex_tree(); - tp->type = EX_MUL; - tp->data.child.left = leftp; - tp->data.child.right = rightp; - tp->cp = rightp->cp; - leftp = tp; - break; - - case '/': - if(depth >= MUL_PREC) - return leftp; - - rightp = parse_binary(cp+1, term, MUL_PREC); - tp = new_ex_tree(); - tp->type = EX_DIV; - tp->data.child.left = leftp; - tp->data.child.right = rightp; - tp->cp = rightp->cp; - leftp = tp; - break; - - case '!': - if(depth >= OR_PREC) - return leftp; - - rightp = parse_binary(cp+1, term, 2); - tp = new_ex_tree(); - tp->type = EX_OR; - tp->data.child.left = leftp; - tp->data.child.right = rightp; - tp->cp = rightp->cp; - leftp = tp; - break; - - case '&': - if(depth >= AND_PREC) - return leftp; - - rightp = parse_binary(cp+1, term, AND_PREC); - tp = new_ex_tree(); - tp->type = EX_AND; - tp->data.child.left = leftp; - tp->data.child.right = rightp; - tp->cp = rightp->cp; - leftp = tp; - break; - - default: - /* Some unknown character. Let caller decide if it's okay. */ - - return leftp; - - } /* end switch */ - } /* end while */ - - /* Can't be reached except by error. */ - return leftp; -} - -/* get_symbol is used all over the place to pull a symbol out of the - text. */ - -static char *get_symbol(char *cp, char **endp, int *islocal) -{ - int len; - char *symcp; - int digits = 0; - - cp = skipwhite(cp); /* Skip leading whitespace */ - - if(!issym(*cp)) - return NULL; - - digits = 0; - if(isdigit(*cp)) - digits = 2; /* Think about digit count */ - - for(symcp = cp + 1; issym(*symcp); symcp++) - { - if(!isdigit(*symcp)) /* Not a digit? */ - digits--; /* Make a note. */ - } - - if(digits == 2) - return NULL; /* Not a symbol, it's a digit string */ - - if(endp) - *endp = symcp; - - len = symcp - cp; - - /* Now limit length */ - if(len > SYMMAX) - len = SYMMAX; - - symcp = memcheck(malloc(len + 1)); - - memcpy(symcp, cp, len); - symcp[len] = 0; - upcase(symcp); - - if(islocal) - { - *islocal = 0; - - /* Turn to local label format */ - if(digits == 1) - { - if(symcp[len-1] == '$') - { - char *newsym = memcheck(malloc(32)); /* Overkill */ - sprintf(newsym, "%d$%d", strtol(symcp, NULL, 10), lsb); - free(symcp); - symcp = newsym; - if(islocal) - *islocal = LOCAL; - } - else - { - free(symcp); - return NULL; - } - } - } - else - { - /* disallow local label format */ - if(isdigit(*symcp)) - { - free(symcp); - return NULL; - } - } - - return symcp; -} - -/* - brackrange is used to find a range of text which may or may not be - bracketed. - - If the brackets are <>, then nested brackets are detected. - If the brackets are of the form ^/.../ no detection of nesting is - attempted. - - Using brackets ^<...< will mess this routine up. What in the world - are you thinking? -*/ - -int brackrange(char *cp, int *start, int *length, char **endp) -{ - char endstr[6]; - int endlen; - int nest; - int len; - - switch(*cp) - { - case '^': - endstr[0] = cp[1]; - strcpy(endstr+1, "\n"); - *start = 2; - endlen = 1; - break; - case '<': - strcpy(endstr, "<>\n"); - endlen = 1; - *start = 1; - break; - default: - return FALSE; - } - - cp += *start; - - len = 0; - nest = 1; - while(nest) - { - int sublen; - sublen = strcspn(cp+len, endstr); - if(cp[len+sublen] == '<') - nest++; - else - nest--; - len += sublen; - } - - *length = len; - if(endp) - *endp = cp + len + endlen; - - return 1; -} - -/* parse_unary parses out a unary operator or leaf expression. */ - -EX_TREE *parse_unary(char *cp) -{ - EX_TREE *tp; - - /* Skip leading whitespace */ - cp = skipwhite(cp); - - if(*cp == '%') /* Register notation */ - { - unsigned reg; - cp++; - reg = strtoul(cp, &cp, 8); - if(reg > 7) - return ex_err(NULL, cp); - - /* This returns references to the built-in register symbols */ - tp = new_ex_tree(); - tp->type = EX_SYM; - tp->data.symbol = reg_sym[reg]; - tp->cp = cp; - return tp; - } - - /* Unary negate */ - if(*cp == '-') - { - tp = new_ex_tree(); - tp->type = EX_NEG; - tp->data.child.left = parse_unary(cp+1); - tp->cp = tp->data.child.left->cp; - return tp; - } - - /* Unary + I can ignore. */ - if(*cp == '+') - return parse_unary(cp+1); - - if(*cp == '^') - { - int save_radix; - switch(tolower(cp[1])) - { - case 'c': - /* ^C, ones complement */ - tp = new_ex_tree(); - tp->type = EX_COM; - tp->data.child.left = parse_unary(cp+2); - tp->cp = tp->data.child.left->cp; - return tp; - case 'b': - /* ^B, binary radix modifier */ - save_radix = radix; - radix = 2; - tp = parse_unary(cp+2); - radix = save_radix; - return tp; - case 'o': - /* ^O, octal radix modifier */ - save_radix = radix; - radix = 8; - tp = parse_unary(cp+2); - radix = save_radix; - return tp; - case 'd': - /* ^D, decimal radix modifier */ - save_radix = radix; - radix = 10; - tp = parse_unary(cp+2); - radix = save_radix; - return tp; - case 'x': - /* An enhancement! ^X, hexadecimal radix modifier */ - save_radix = radix; - radix = 16; - tp = parse_unary(cp+2); - radix = save_radix; - return tp; - case 'r': - /* ^R, RAD50 literal */ - { - int start, len; - char *endcp; - unsigned value; - cp += 2; - if(brackrange(cp, &start, &len, &endcp)) - value = rad50(cp+start, NULL); - else - value = rad50(cp, &endcp); - tp = new_ex_lit(value); - tp->cp = endcp; - return tp; - } - case 'f': - /* ^F, single-word floating point literal indicator */ - { - unsigned flt[1]; - char *endcp; - if(!parse_float(cp+2, &endcp, 1, flt)) - { - tp = ex_err(NULL, cp+2); - } - else - { - tp = new_ex_lit(flt[0]); - tp->cp = endcp; - } - return tp; - } - } - - if(ispunct(cp[1])) - { - char *ecp; - /* oddly-bracketed expression like this: ^/expression/ */ - tp = parse_binary(cp+2, cp[1], 0); - ecp = skipwhite(tp->cp); - - if(*ecp != cp[1]) - return ex_err(tp, ecp); - - tp->cp = ecp + 1; - return tp; - } - } - - /* Bracketed subexpression */ - if(*cp == '<') - { - char *ecp; - tp = parse_binary(cp+1, '>', 0); - ecp = skipwhite(tp->cp); - if(*ecp != '>') - return ex_err(tp, ecp); - - tp->cp = ecp + 1; - return tp; - } - - /* Check for ASCII constants */ - - if(*cp == '\'') - { - /* 'x single ASCII character */ - cp++; - tp = new_ex_tree(); - tp->type = EX_LIT; - tp->data.lit = *cp & 0xff; - tp->cp = ++cp; - return tp; - } - - if(*cp == '\"') - { - /* "xx ASCII character pair */ - cp++; - tp = new_ex_tree(); - tp->type = EX_LIT; - tp->data.lit = (cp[0] & 0xff) | ((cp[1] & 0xff) << 8); - tp->cp = cp + 2; - return tp; - } - - /* Numeric constants are trickier than they need to be, */ - /* since local labels start with a digit too. */ - if(isdigit(*cp)) - { - char *label; - int local; - - if((label = get_symbol(cp, NULL, &local)) == NULL) - { - char *endcp; - unsigned long value; - int rad = radix; - - /* get_symbol returning NULL assures me that it's not a - local label. */ - - /* Look for a trailing period, to indicate decimal... */ - for(endcp = cp; isdigit(*endcp); endcp++) - ; - if(*endcp == '.') - rad = 10; - - value = strtoul(cp, &endcp, rad); - if(*endcp == '.') - endcp++; - - tp = new_ex_tree(); - tp->type = EX_LIT; - tp->data.lit = value; - tp->cp = endcp; - - return tp; - } - - free(label); - } - - /* Now check for a symbol */ - - { - char *label; - int local; - SYMBOL *sym; - - /* Optimization opportunity: I don't really need to call - get_symbol a second time. */ - - if(!(label = get_symbol(cp, &cp, &local))) - { - tp = ex_err(NULL, cp); /* Not a valid label. */ - return tp; - } - - sym = lookup_sym(label, &symbol_st); - if(sym == NULL) - { - /* A symbol from the "PST", which means an instruction - code. */ - sym = lookup_sym(label, &system_st); - } - - if(sym != NULL) - { - tp = new_ex_tree(); - tp->cp = cp; - tp->type = EX_SYM; - tp->data.symbol = sym; - - free(label); - return tp; - } - - /* The symbol was not found. Create an "undefined symbol" - reference. */ - sym = memcheck(malloc(sizeof(SYMBOL))); - sym->label = label; - sym->flags = UNDEFINED | local; - sym->stmtno = stmtno; - sym->next = NULL; - sym->section = &absolute_section; - sym->value = 0; - - tp = new_ex_tree(); - tp->cp = cp; - tp->type = EX_UNDEFINED_SYM; - tp->data.symbol = sym; - - return tp; - } -} - -/* Diagnostic: symflags returns a char* which gives flags I can use to - show the context of a symbol. */ - -static char *symflags(SYMBOL *sym) -{ - static char temp[8]; - char *fp = temp; - if(sym->flags & GLOBAL) - *fp++ = 'G'; - if(sym->flags & PERMANENT) - *fp++ = 'P'; - if(sym->flags & DEFINITION) - *fp++ = 'D'; - *fp = 0; - return fp; -} - -/* Diagnostic: print an expression tree. I used this in various - places to help me diagnose parse problems, by putting in calls to - print_tree when I didn't understand why something wasn't working. - This is currently dead code, nothing calls it; but I don't want it - to go away. Hopefully the compiler will realize when it's dead, and - eliminate it. */ - -static void print_tree(FILE *printfile, EX_TREE *tp, int depth) -{ - SYMBOL *sym; - - switch(tp->type) - { - case EX_LIT: - fprintf(printfile, "%o", tp->data.lit & 0177777); - break; - - case EX_SYM: - case EX_TEMP_SYM: - sym = tp->data.symbol; - fprintf(printfile, "%s{%s%o:%s}", tp->data.symbol->label, - symflags(sym), sym->value, sym->section->label); - break; - - case EX_UNDEFINED_SYM: - fprintf(printfile, "%s{%o:undefined}", tp->data.symbol->label, - tp->data.symbol->value); - break; - - case EX_COM: - fprintf(printfile, "^C<"); - print_tree(printfile, tp->data.child.left, depth+4); - fprintf(printfile, ">"); - break; - - case EX_NEG: - fprintf(printfile, "-<"); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('>', printfile); - break; - - case EX_ERR: - fprintf(printfile, "{expression error}"); - if(tp->data.child.left) - { - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('>', printfile); - } - break; - - case EX_ADD: - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('+', printfile); - print_tree(printfile, tp->data.child.right, depth+4); - fputc('>', printfile); - break; - - case EX_SUB: - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('-', printfile); - print_tree(printfile, tp->data.child.right, depth+4); - fputc('>', printfile); - break; - - case EX_MUL: - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('*', printfile); - print_tree(printfile, tp->data.child.right, depth+4); - fputc('>', printfile); - break; - - case EX_DIV: - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('/', printfile); - print_tree(printfile, tp->data.child.right, depth+4); - fputc('>', printfile); - break; - - case EX_AND: - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('&', printfile); - print_tree(printfile, tp->data.child.right, depth+4); - fputc('>', printfile); - break; - - case EX_OR: - fputc('<', printfile); - print_tree(printfile, tp->data.child.left, depth+4); - fputc('!', printfile); - print_tree(printfile, tp->data.child.right, depth+4); - fputc('>', printfile); - break; - } - - if(depth == 0) - fputc('\n', printfile); -} - -/* free_tree frees an expression tree. */ - -static void free_tree(EX_TREE *tp) -{ - switch(tp->type) - { - case EX_UNDEFINED_SYM: - case EX_TEMP_SYM: - free(tp->data.symbol->label); - free(tp->data.symbol); - case EX_LIT: - case EX_SYM: - free(tp); - break; - - case EX_COM: - case EX_NEG: - free_tree(tp->data.child.left); - free(tp); - break; - - case EX_ERR: - if(tp->data.child.left) - free_tree(tp->data.child.left); - free(tp); - break; - - case EX_ADD: - case EX_SUB: - case EX_MUL: - case EX_DIV: - case EX_AND: - case EX_OR: - free_tree(tp->data.child.left); - free_tree(tp->data.child.right); - free(tp); - break; - } -} - -/* new_temp_sym allocates a new EX_TREE entry of type "TEMPORARY - SYMBOL" (slight semantic difference from "UNDEFINED"). */ - -static EX_TREE *new_temp_sym(char *label, SECTION *section, unsigned value) -{ - SYMBOL *sym; - EX_TREE *tp; - - sym = memcheck(malloc(sizeof(SYMBOL))); - sym->label = memcheck(strdup(label)); - sym->flags = 0; - sym->stmtno = stmtno; - sym->next = NULL; - sym->section = section; - sym->value = value; - - tp = new_ex_tree(); - tp->type = EX_TEMP_SYM; - tp->data.symbol = sym; - - return tp; -} - -#define RELTYPE(tp) (((tp)->type == EX_SYM || (tp)->type == EX_TEMP_SYM) && \ - (tp)->data.symbol->section->flags & PSECT_REL) - -/* evaluate "evaluates" an EX_TREE, ideally trying to produce a - constant value, else a symbol plus an offset. */ - -static EX_TREE *evaluate(EX_TREE *tp, int undef) -{ - EX_TREE *res; - char *cp = tp->cp; - - switch(tp->type) - { - case EX_SYM: - { - SYMBOL *sym = tp->data.symbol; - - /* Change some symbols to "undefined" */ - - if(undef) - { - int change = 0; - -#if 0 /* I'd prefer this behavior, but - MACRO.SAV is a bit too - primitive. */ - /* A temporary symbol defined later is "undefined." */ - if(!(sym->flags & PERMANENT) && sym->stmtno > stmtno) - change = 1; -#endif - - /* A global symbol with no assignment is "undefined." */ - /* Go figure. */ - if((sym->flags & (GLOBAL|DEFINITION)) == GLOBAL) - change = 1; - - if(change) - { - res = new_temp_sym(tp->data.symbol->label, - tp->data.symbol->section, tp->data.symbol->value); - res->type = EX_UNDEFINED_SYM; - break; - } - } - - /* Turn defined absolute symbol to a literal */ - if(!(sym->section->flags & PSECT_REL) && - (sym->flags & (GLOBAL|DEFINITION)) != GLOBAL && - sym->section->type != REGISTER) - { - res = new_ex_lit(sym->value); - break; - } - - /* Make a temp copy of any reference to "." since it might - change as complex relocatable expressions are written out - */ - if(strcmp(sym->label, ".") == 0) - { - res = new_temp_sym(".", sym->section, sym->value); - break; - } - - /* Copy other symbol reference verbatim. */ - res = new_ex_tree(); - res->type = EX_SYM; - res->data.symbol = tp->data.symbol; - res->cp = tp->cp; - break; - } - - case EX_LIT: - res = new_ex_tree(); - *res = *tp; - break; - - case EX_TEMP_SYM: - case EX_UNDEFINED_SYM: - /* Copy temp and undefined symbols */ - res = new_temp_sym(tp->data.symbol->label, - tp->data.symbol->section, - tp->data.symbol->value); - res->type = tp->type; - break; - - case EX_COM: - /* Complement */ - tp = evaluate(tp->data.child.left, undef); - if(tp->type == EX_LIT) - { - /* Complement the literal */ - res = new_ex_lit(~tp->data.lit); - free_tree(tp); - } - else - { - /* Copy verbatim. */ - res = new_ex_tree(); - res->type = EX_NEG; - res->cp = tp->cp; - res->data.child.left = tp; - } - - break; - - case EX_NEG: - tp = evaluate(tp->data.child.left, undef); - if(tp->type == EX_LIT) - { - /* negate literal */ - res = new_ex_lit((unsigned)-(int)tp->data.lit); - free_tree(tp); - } - else if(tp->type == EX_SYM || tp->type == EX_TEMP_SYM) - { - /* Make a temp sym with the negative value of the given - sym (this works for symbols within relocatable sections - too) */ - res = new_temp_sym("*TEMP", tp->data.symbol->section, - (unsigned)-(int)tp->data.symbol->value); - res->cp = tp->cp; - free_tree(tp); - } - else - { - /* Copy verbatim. */ - res = new_ex_tree(); - res->type = EX_NEG; - res->cp = tp->cp; - res->data.child.left = tp; - } - break; - - case EX_ERR: - /* Copy */ - res = ex_err(tp->data.child.left, tp->cp); - break; - - case EX_ADD: - { - EX_TREE *left, *right; - - left = evaluate(tp->data.child.left, undef); - right = evaluate(tp->data.child.right, undef); - - /* Both literals? Sum them and return result. */ - if(left->type == EX_LIT && right->type == EX_LIT) - { - res = new_ex_lit(left->data.lit + right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - /* Commutative: A+x == x+A. - Simplify by putting the literal on the right */ - if(left->type == EX_LIT) - { - EX_TREE *temp = left; - left = right; - right = temp; - } - - if(right->type == EX_LIT && /* Anything plus 0 == itself */ - right->data.lit == 0) - { - res = left; - free_tree(right); - break; - } - - /* Relative symbol plus lit is replaced with a temp sym - holding the sum */ - if(RELTYPE(left) && right->type == EX_LIT) - { - SYMBOL *sym = left->data.symbol; - res = new_temp_sym("*ADD", sym->section, sym->value + - right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - /* Associative: +y == A+ */ - /* and if x+y is constant, I can do that math. */ - if(left->type == EX_ADD && right->type == EX_LIT) - { - EX_TREE *leftright = left->data.child.right; - if(leftright->type == EX_LIT) - { - /* Do the shuffle */ - res = left; - leftright->data.lit += right->data.lit; - free_tree(right); - break; - } - } - - /* Associative: +y == A+ */ - /* and if y-x is constant, I can do that math. */ - if(left->type == EX_SUB && right->type == EX_LIT) - { - EX_TREE *leftright = left->data.child.right; - if(leftright->type == EX_LIT) - { - /* Do the shuffle */ - res = left; - leftright->data.lit = right->data.lit - leftright->data.lit; - free_tree(right); - break; - } - } - - /* Anything else returns verbatim */ - res = new_ex_tree(); - res->type = EX_ADD; - res->data.child.left = left; - res->data.child.right = right; - } - break; - - case EX_SUB: - { - EX_TREE *left, *right; - - left = evaluate(tp->data.child.left, undef); - right = evaluate(tp->data.child.right, undef); - - /* Both literals? Subtract them and return a lit. */ - if(left->type == EX_LIT && right->type == EX_LIT) - { - res = new_ex_lit(left->data.lit - right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - if(right->type == EX_LIT && /* Symbol minus 0 == symbol */ - right->data.lit == 0) - { - res = left; - free_tree(right); - break; - } - - /* A relocatable minus an absolute - make a new temp sym - to represent that. */ - if(RELTYPE(left) && - right->type == EX_LIT) - { - SYMBOL *sym = left->data.symbol; - res = new_temp_sym("*SUB", sym->section, - sym->value - right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - if(RELTYPE(left) && - RELTYPE(right) && - left->data.symbol->section == right->data.symbol->section) - { - /* Two defined symbols in the same psect. Resolve - their difference as a literal. */ - res = new_ex_lit(left->data.symbol->value - - right->data.symbol->value); - free_tree(left); - free_tree(right); - break; - } - - /* Associative: -y == A+ */ - /* and if x-y is constant, I can do that math. */ - if(left->type == EX_ADD && right->type == EX_LIT) - { - EX_TREE *leftright = left->data.child.right; - if(leftright->type == EX_LIT) - { - /* Do the shuffle */ - res = left; - leftright->data.lit -= right->data.lit; - free_tree(right); - break; - } - } - - /* Associative: -y == A- */ - /* and if x+y is constant, I can do that math. */ - if(left->type == EX_SUB && right->type == EX_LIT) - { - EX_TREE *leftright = left->data.child.right; - if(leftright->type == EX_LIT) - { - /* Do the shuffle */ - res = left; - leftright->data.lit += right->data.lit; - free_tree(right); - break; - } - } - - /* Anything else returns verbatim */ - res = new_ex_tree(); - res->type = EX_SUB; - res->data.child.left = left; - res->data.child.right = right; - } - break; - - case EX_MUL: - { - EX_TREE *left, *right; - - left = evaluate(tp->data.child.left, undef); - right = evaluate(tp->data.child.right, undef); - - /* Can only multiply if both are literals */ - if(left->type == EX_LIT && right->type == EX_LIT) - { - res = new_ex_lit(left->data.lit * right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - /* Commutative: A*x == x*A. - Simplify by putting the literal on the right */ - if(left->type == EX_LIT) - { - EX_TREE *temp = left; - left = right; - right = temp; - } - - if(right->type == EX_LIT && /* Symbol times 1 == symbol */ - right->data.lit == 1) - { - res = left; - free_tree(right); - break; - } - - if(right->type == EX_LIT && /* Symbol times 0 == 0 */ - right->data.lit == 0) - { - res = right; - free_tree(left); - break; - } - - /* Associative: *y == A* */ - /* If x*y is constant, I can do this math. */ - /* Is this safe? I will potentially be doing it */ - /* with greater accuracy than the target platform. */ - /* Hmmm. */ - - if(left->type == EX_MUL && right->type == EX_LIT) - { - EX_TREE *leftright = left->data.child.right; - if(leftright->type == EX_LIT) - { - /* Do the shuffle */ - res = left; - leftright->data.lit *= right->data.lit; - free_tree(right); - break; - } - } - - /* Anything else returns verbatim */ - res = new_ex_tree(); - res->type = EX_MUL; - res->data.child.left = left; - res->data.child.right = right; - } - break; - - case EX_DIV: - { - EX_TREE *left, *right; - - left = evaluate(tp->data.child.left, undef); - right = evaluate(tp->data.child.right, undef); - - /* Can only divide if both are literals */ - if(left->type == EX_LIT && right->type == EX_LIT) - { - res = new_ex_lit(left->data.lit / right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - if(right->type == EX_LIT && /* Symbol divided by 1 == symbol */ - right->data.lit == 1) - { - res = left; - free_tree(right); - break; - } - - /* Anything else returns verbatim */ - res = new_ex_tree(); - res->type = EX_DIV; - res->data.child.left = left; - res->data.child.right = right; - } - break; - - case EX_AND: - { - EX_TREE *left, *right; - - left = evaluate(tp->data.child.left, undef); - right = evaluate(tp->data.child.right, undef); - - /* Operate if both are literals */ - if(left->type == EX_LIT && right->type == EX_LIT) - { - res = new_ex_lit(left->data.lit & right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - /* Commutative: A&x == x&A. - Simplify by putting the literal on the right */ - if(left->type == EX_LIT) - { - EX_TREE *temp = left; - left = right; - right = temp; - } - - if(right->type == EX_LIT && /* Symbol AND 0 == 0 */ - right->data.lit == 0) - { - res = new_ex_lit(0); - free_tree(left); - free_tree(right); - break; - } - - if(right->type == EX_LIT && /* Symbol AND 0177777 == symbol */ - right->data.lit == 0177777) - { - res = left; - free_tree(right); - break; - } - - /* Anything else returns verbatim */ - res = new_ex_tree(); - res->type = EX_AND; - res->data.child.left = left; - res->data.child.right = right; - } - break; - - case EX_OR: - { - EX_TREE *left, *right; - - left = evaluate(tp->data.child.left, undef); - right = evaluate(tp->data.child.right, undef); - - /* Operate if both are literals */ - if(left->type == EX_LIT && right->type == EX_LIT) - { - res = new_ex_lit(left->data.lit | right->data.lit); - free_tree(left); - free_tree(right); - break; - } - - /* Commutative: A!x == x!A. - Simplify by putting the literal on the right */ - if(left->type == EX_LIT) - { - EX_TREE *temp = left; - left = right; - right = temp; - } - - if(right->type == EX_LIT && /* Symbol OR 0 == symbol */ - right->data.lit == 0) - { - res = left; - free_tree(right); - break; - } - - if(right->type == EX_LIT && /* Symbol OR 0177777 == 0177777 */ - right->data.lit == 0177777) - { - res = new_ex_lit(0177777); - free_tree(left); - free_tree(right); - break; - } - - /* Anything else returns verbatim */ - res = new_ex_tree(); - res->type = EX_OR; - res->data.child.left = left; - res->data.child.right = right; - } - break; - } - - res->cp = cp; - return res; -} - -/* - parse_expr - this gets called everywhere. It parses and evaluates - an arithmetic expression. -*/ - -EX_TREE *parse_expr(char *cp, int undef) -{ - EX_TREE *expr; - EX_TREE *value; - - expr = parse_binary(cp, 0, 0); /* Parse into a tree */ - value = evaluate(expr, undef); /* Perform the arithmetic */ - value->cp = expr->cp; /* Pointer to end of text is part of - the rootmost node */ - free_tree(expr); /* Discard parse in favor of - evaluation */ - - return value; -} - -/* free_addr_mode frees the storage consumed by an addr_mode */ - -static void free_addr_mode(ADDR_MODE *mode) -{ - if(mode->offset) - free_tree(mode->offset); - mode->offset = NULL; -} - -/* Get the register indicated by the expression */ - -#define NO_REG 0777 - -static unsigned get_register(EX_TREE *expr) -{ - unsigned reg; - - if(expr->type == EX_LIT && - expr->data.lit <= 7) - { - reg = expr->data.lit; - return reg; - } - - if(expr->type == EX_SYM && - expr->data.symbol->section->type == REGISTER) - { - reg = expr->data.symbol->value; - return reg; - } - - return NO_REG; -} - -/* get_mode - parse a general addressing mode. */ - -int get_mode(char *cp, char **endp, ADDR_MODE *mode) -{ - EX_TREE *value; - - mode->offset = NULL; - mode->rel = 0; - mode->type = 0; - - cp = skipwhite(cp); - - /* @ means "indirect," sets bit 3 */ - if(*cp == '@') - { - cp++; - mode->type |= 010; - } - - /* Immediate modes #imm and @#imm */ - if(*cp == '#') - { - cp++; - mode->type |= 027; - mode->offset = parse_expr(cp, 0); - if(endp) - *endp = mode->offset->cp; - return TRUE; - } - - /* Check for -(Rn) */ - - if(*cp == '-') - { - char *tcp = skipwhite(cp + 1); - if(*tcp++ == '(') - { - unsigned reg; - /* It's -(Rn) */ - value = parse_expr(tcp, 0); - reg = get_register(value); - if(reg == NO_REG || - (tcp = skipwhite(value->cp), *tcp++ != ')')) - { - free_tree(value); - return FALSE; - } - mode->type |= 040 | reg; - if(endp) - *endp = tcp; - free_tree(value); - return TRUE; - } - } - - /* Check for (Rn) */ - if(*cp == '(') - { - char *tcp; - unsigned reg; - value = parse_expr(cp + 1, 0); - reg = get_register(value); - - if(reg == NO_REG || - (tcp = skipwhite(value->cp), *tcp++ != ')')) - { - free_tree(value); - return FALSE; - } - - tcp = skipwhite(tcp); - if(*tcp == '+') - { - tcp++; /* It's (Rn)+ */ - if(endp) - *endp = tcp; - mode->type |= 020 | reg; - free_tree(value); - return TRUE; - } - - if(mode->type == 010) /* For @(Rn) there's an implied 0 offset */ - { - mode->offset = new_ex_lit(0); - mode->type |= 060 | reg; - free_tree(value); - if(endp) - *endp = tcp; - return TRUE; - } - - mode->type |= 010 | reg; /* Mode 10 is register indirect as - in (Rn) */ - free_tree(value); - if(endp) - *endp = tcp; - return TRUE; - } - - /* Modes with an offset */ - - mode->offset = parse_expr(cp, 0); - - cp = skipwhite(mode->offset->cp); - - if(*cp == '(') - { - unsigned reg; - /* indirect register plus offset */ - value = parse_expr(cp+1, 0); - reg = get_register(value); - if(reg == NO_REG || - (cp = skipwhite(value->cp), *cp++ != ')')) - { - free_tree(value); - return FALSE; /* Syntax error in addressing mode */ - } - - mode->type |= 060 | reg; - - free_tree(value); - - if(endp) - *endp = cp; - return TRUE; - } - - /* Plain old expression. */ - - if(endp) - *endp = cp; - - /* It might be a register, though. */ - if(mode->offset->type == EX_SYM) - { - SYMBOL *sym = mode->offset->data.symbol; - if(sym->section->type == REGISTER) - { - free_tree(mode->offset); - mode->offset = NULL; - mode->type |= sym->value; - return TRUE; - } - } - - /* It's either 067 (PC-relative) or 037 (absolute) mode, depending */ - /* on user option. */ - - if(mode->type & 010) /* Have already noted indirection? */ - { - mode->type |= 067; /* If so, then PC-relative is the only - option */ - mode->rel = 1; /* Note PC-relative */ - } - else if(enabl_ama) /* User asked for absolute adressing? */ - { - mode->type |= 037; /* Give it to him. */ - } - else - { - mode->type |= 067; /* PC-relative */ - mode->rel = 1; /* Note PC-relative */ - } - - return TRUE; -} - -/* - implicit_gbl is a self-recursive routine that adds undefined symbols - to the "implicit globals" symbol table. -*/ - -void implicit_gbl(EX_TREE *value) -{ - if(pass) - return; /* Only do this in first pass */ - - if(!enabl_gbl) - return; /* Option not enabled, don't do it. */ - - switch(value->type) - { - case EX_UNDEFINED_SYM: - { - SYMBOL *sym; - if(!(value->data.symbol->flags & LOCAL)) /* Unless it's a - local symbol, */ - { - sym = add_sym(value->data.symbol->label, - 0, GLOBAL, &absolute_section, &implicit_st); - } - } - break; - case EX_LIT: - case EX_SYM: - return; - case EX_ADD: - case EX_SUB: - case EX_MUL: - case EX_DIV: - case EX_AND: - case EX_OR: - implicit_gbl(value->data.child.right); - /* falls into... */ - case EX_COM: - case EX_NEG: - implicit_gbl(value->data.child.left); - break; - case EX_ERR: - if(value->data.child.left) - implicit_gbl(value->data.child.left); - break; - } -} - -/* Done between the first and second passes */ -/* Migrates the symbols from the "implicit" table into the main table. */ - -static void migrate_implicit(void) -{ - SYMBOL_ITER iter; - SYMBOL *isym, *sym; - - for(isym = first_sym(&implicit_st, &iter); - isym != NULL; - isym = next_sym(&implicit_st, &iter)) - { - sym = lookup_sym(isym->label, &symbol_st); - if(sym) - continue; // It's already in there. Great. - sym = add_sym(isym->label, isym->value, isym->flags, - isym->section, &symbol_st); - // Just one other thing - migrate the stmtno - sym->stmtno = isym->stmtno; - } -} - -static int express_sym_offset(EX_TREE *value, SYMBOL **sym, unsigned *offset) -{ - implicit_gbl(value); /* Translate tree's undefined syms - into global syms */ - - /* Internally relocatable symbols will have been summed down into - EX_TEMP_SYM's. */ - - if(value->type == EX_SYM || - value->type == EX_TEMP_SYM) - { - *sym = value->data.symbol; - *offset = 0; - return 1; - } - - /* What remains is external symbols. */ - - if(value->type == EX_ADD) - { - EX_TREE *left = value->data.child.left; - EX_TREE *right = value->data.child.right; - if((left->type != EX_SYM && - left->type != EX_UNDEFINED_SYM) || - right->type != EX_LIT) - return 0; /* Failed. */ - *sym = left->data.symbol; - *offset = right->data.lit; - return 1; - } - - if(value->type == EX_SUB) - { - EX_TREE *left = value->data.child.left; - EX_TREE *right = value->data.child.right; - if((left->type != EX_SYM && - left->type != EX_UNDEFINED_SYM) || - right->type != EX_LIT) - return 0; /* Failed. */ - *sym = left->data.symbol; - *offset = (unsigned)-(int)(right->data.lit); - return 1; - } - - return 0; -} - -/* - Translate an EX_TREE into a TEXT_COMPLEX suitable for encoding - into the object file. */ - -int complex_tree(TEXT_COMPLEX *tx, EX_TREE *tree) -{ - switch(tree->type) - { - case EX_LIT: - text_complex_lit(tx, tree->data.lit); - return 1; - - case EX_TEMP_SYM: - case EX_SYM: - { - SYMBOL *sym = tree->data.symbol; - if((sym->flags & (GLOBAL|DEFINITION)) == GLOBAL) - { - text_complex_global(tx, sym->label); - } - else - { - text_complex_psect(tx, sym->section->sector, sym->value); - } - } - return 1; - - case EX_COM: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - text_complex_com(tx); - return 1; - - case EX_NEG: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - text_complex_neg(tx); - return 1; - - case EX_ADD: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - if(!complex_tree(tx, tree->data.child.right)) - return 0; - text_complex_add(tx); - return 1; - - case EX_SUB: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - if(!complex_tree(tx, tree->data.child.right)) - return 0; - text_complex_sub(tx); - return 1; - - case EX_MUL: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - if(!complex_tree(tx, tree->data.child.right)) - return 0; - text_complex_mul(tx); - return 1; - - case EX_DIV: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - if(!complex_tree(tx, tree->data.child.right)) - return 0; - text_complex_div(tx); - return 1; - - case EX_AND: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - if(!complex_tree(tx, tree->data.child.right)) - return 0; - text_complex_and(tx); - return 1; - - case EX_OR: - if(!complex_tree(tx, tree->data.child.left)) - return 0; - if(!complex_tree(tx, tree->data.child.right)) - return 0; - text_complex_or(tx); - return 1; - - default: - return 0; - } -} - -/* store a word which is represented by a complex expression. */ - -static void store_complex(STREAM *refstr, TEXT_RLD *tr, - int size, EX_TREE *value) -{ - TEXT_COMPLEX tx; - - change_dot(tr, size); /* About to store - update DOT */ - - implicit_gbl(value); /* Turn undefined symbols into globals */ - - text_complex_begin(&tx); /* Open complex expression */ - - if(!complex_tree(&tx, value)) /* Translate */ - { - report(refstr, "Invalid expression\n"); - store_word(refstr, tr, size, 0); - } - else - { - list_word(refstr, DOT, 0, size, "C"); - text_complex_commit(tr, &DOT, size, &tx, 0); - } -} - -/* store_complex_displaced is the same as store_complex but uses the - "displaced" RLD code */ - -static void store_complex_displaced(STREAM *refstr, TEXT_RLD *tr, - int size, - EX_TREE *value) -{ - TEXT_COMPLEX tx; - - change_dot(tr, size); - - implicit_gbl(value); /* Turn undefined symbols into globals */ - - text_complex_begin(&tx); - - if(!complex_tree(&tx, value)) - { - report(refstr, "Invalid expression\n"); - store_word(refstr, tr, size, 0); - } - else - { - list_word(refstr, DOT, 0, size, "C"); - text_complex_commit_displaced(tr, &DOT, size, &tx, 0); - } -} - -/* - mode_extension - writes the extension word required by an addressing - mode */ - -static void mode_extension(TEXT_RLD *tr, ADDR_MODE *mode, - STREAM *str) -{ - EX_TREE *value = mode->offset; - SYMBOL *sym; - unsigned offset; - - /* Also frees the mode. */ - - if(value == NULL) - { - free_addr_mode(mode); - return; - } - - if(value->type == EX_LIT) - { - if(mode->rel) /* PC-relative? */ - store_displaced_word(str, tr, 2, value->data.lit); - else - store_word(str, tr, 2, value->data.lit); /* Just a - known - value. */ - } - else if(express_sym_offset(value, &sym, &offset)) - { - if((sym->flags & (GLOBAL|DEFINITION)) == GLOBAL) - { - /* Reference to a global symbol. */ - /* Global symbol plus offset */ - if(mode->rel) - store_global_displaced_offset_word(str, tr, - 2, offset, sym->label); - else - store_global_offset_word(str, tr, 2, offset, - sym->label); - } - else - { - /* Relative to non-external symbol. */ - if(current_pc->section == sym->section) - { - /* In the same section */ - if(mode->rel) - { - /* I can compute this myself. */ - store_word(str, tr, 2, - sym->value + offset - DOT - 2); - } - else - store_internal_word(str, tr, 2, sym->value+offset); - } - else - { - /* In a different section */ - if(mode->rel) - store_psect_displaced_offset_word(str, tr, 2, - sym->value+offset, sym->section->label); - else - store_psect_offset_word(str, tr, 2, - sym->value+offset, sym->section->label); - } - } - } - else - { - /* Complex relocation */ - - if(mode->rel) - store_complex_displaced(str, tr, 2, mode->offset); - else - store_complex(str, tr, 2, mode->offset); - } - - free_addr_mode(mode); -} - -/* eval_defined - take an EX_TREE and returns TRUE if the tree - represents "defined" symbols. */ - -int eval_defined(EX_TREE *value) -{ - switch(value->type) - { - case EX_LIT: - return 1; - case EX_SYM: - return 1; - case EX_UNDEFINED_SYM: - return 0; - case EX_AND: - return eval_defined(value->data.child.left) && - eval_defined(value->data.child.right); - case EX_OR: - return eval_defined(value->data.child.left) || - eval_defined(value->data.child.right); - default: - return 0; - } -} - -/* eval_undefined - take an EX_TREE and returns TRUE if it represents - "undefined" symbols. */ - -int eval_undefined(EX_TREE *value) -{ - switch(value->type) - { - case EX_UNDEFINED_SYM: - return 1; - case EX_SYM: - return 0; - case EX_AND: - return eval_undefined(value->data.child.left) && - eval_undefined(value->data.child.right); - case EX_OR: - return eval_undefined(value->data.child.left) || - eval_undefined(value->data.child.right); - default: - return 0; - } -} - -/* push_cond - a new conditional (.IF) block has been activated. Push - it's context. */ - -void push_cond(int ok, STREAM *str) -{ - last_cond++; - assert(last_cond < MAX_CONDS); - conds[last_cond].ok = ok; - conds[last_cond].file = memcheck(strdup(str->name)); - conds[last_cond].line = str->line; -} - -/* - pop_cond - pop stacked conditionals. */ - -void pop_cond(int to) -{ - while(last_cond > to) - { - free(conds[last_cond].file); - last_cond--; - } -} - -/* Parses a string from the input stream. */ -/* If not bracketed by <...> or ^/.../, then */ -/* the string is delimited by trailing comma or whitespace. */ -/* Allows nested <>'s */ - -char *getstring(char *cp, char **endp) -{ - int len; - int start; - char *str; - - if(!brackrange(cp, &start, &len, endp)) - { - start = 0; - len = strcspn(cp, " \t\n,;"); - if(endp) - *endp = cp + len; - } - - str = memcheck(malloc(len + 1)); - memcpy(str, cp + start, len); - str[len] = 0; - - return str; -} - -/* Get what would be the operation code from the line. */ -/* Used to find the ends of streams without evaluating them, like - finding the closing .ENDM on a macro definition */ - -SYMBOL *get_op(char *cp, char **endp) -{ - int local; - char *label; - SYMBOL *op; - - cp = skipwhite(cp); - if(EOL(*cp)) - return NULL; - - label = get_symbol(cp, &cp, &local); - if(label == NULL) - return NULL; /* No operation code. */ - - cp = skipwhite(cp); - if(*cp == ':') /* A label definition? */ - { - cp++; - if(*cp == ':') - cp++; /* Skip it */ - free(label); - label = get_symbol(cp, &cp, NULL); - if(label == NULL) - return NULL; - } - - op = lookup_sym(label, &system_st); - free(label); - - if(endp) - *endp = cp; - - return op; -} - -/* Here's where I pretend I'm a C++ compiler. :-/ */ - -/* *** derive a MACRO_STREAM from a BUFFER_STREAM with a few other args */ - -typedef struct macro_stream -{ - BUFFER_STREAM bstr; /* Base class: buffer stream */ - int nargs; /* Add number-of-macro-arguments */ - int cond; /* Add saved conditional stack */ -} MACRO_STREAM; - -/* macro_stream_delete is called when a macro expansion is - exhausted. The unique behavior is to unwind any stacked - conditionals. This allows a nested .MEXIT to work. */ - -void macro_stream_delete(STREAM *str) -{ - MACRO_STREAM *mstr = (MACRO_STREAM *)str; - pop_cond(mstr->cond); - buffer_stream_delete(str); -} - -STREAM_VTBL macro_stream_vtbl = { macro_stream_delete, - buffer_stream_gets, - buffer_stream_rewind }; - -STREAM *new_macro_stream(STREAM *refstr, BUFFER *buf, MACRO *mac, - ARG *args) -{ - MACRO_STREAM *mstr = memcheck(malloc(sizeof(MACRO_STREAM))); - - { - char *name = memcheck(malloc(strlen(refstr->name) + 32)); - sprintf(name, "%s:%d->%s", refstr->name, refstr->line, - mac->sym.label); - buffer_stream_construct(&mstr->bstr, buf, name); - free(name); - } - - mstr->bstr.stream.vtbl = ¯o_stream_vtbl; - /* Count the args and save their number */ - for(mstr->nargs = 0; args; args = args->next, mstr->nargs++) - ; - mstr->cond = last_cond; - return &mstr->bstr.stream; -} - -/* read_body fetches the body of .MACRO, .REPT, .IRP, or .IRPC into a - BUFFER. */ - -void read_body(STACK *stack, BUFFER *gb, char *name, - int called) -{ - int nest; - - /* Read the stream in until the end marker is hit */ - - /* Note: "called" says that this body is being pulled from a macro - library, and so under no circumstance should it be listed. */ - - nest = 1; - for(;;) - { - SYMBOL *op; - char *nextline; - char *cp; - - nextline = stack_gets(stack); /* Now read the line */ - if(nextline == NULL) /* End of file. */ - { - report(stack->top, "Macro body not closed\n"); - break; - } - - if(!called && (list_level - 1 + list_md) > 0) - { - list_flush(); - list_source(stack->top, nextline); - } - - op = get_op(nextline, &cp); - - if(op == NULL) /* Not a pseudo-op */ - { - buffer_append_line(gb, nextline); - continue; - } - if(op->section->type == PSEUDO) - { - if(op->value == P_MACRO || - op->value == P_REPT || - op->value == P_IRP || - op->value == P_IRPC) - nest++; - - if(op->value == P_ENDM || - op->value == P_ENDR) - { - nest--; - /* If there's a name on the .ENDM, then */ - /* close the body early if it matches the definition */ - if(name && op->value == P_ENDM) - { - cp = skipwhite(cp); - if(!EOL(*cp)) - { - char *label = get_symbol(cp, &cp, NULL); - if(label) - { - if(strcmp(label, name) == 0) - nest = 0; /* End of macro body. */ - free(label); - } - } - } - } - - if(nest == 0) - return; /* All done. */ - } - - buffer_append_line(gb, nextline); - } -} - -/* Diagnostic: dumpmacro dumps a macro definition to stdout. - I used this for debugging; it's not called at all right now, but - I hate to delete good code. */ - -void dumpmacro(MACRO *mac, FILE *fp) -{ - ARG *arg; - - fprintf(fp, ".MACRO %s ", mac->sym.label); - - for(arg = mac->args; arg != NULL; arg = arg->next) - { - fputs(arg->label, fp); - if(arg->value) - { - fputc('=', fp); - fputs(arg->value, fp); - } - fputc(' ', fp); - } - fputc('\n', fp); - - fputs(mac->text->buffer, fp); - - fputs(".ENDM\n", fp); -} - -/* defmacro - define a macro. */ -/* Also used by .MCALL to pull macro definitions from macro libraries */ - -MACRO *defmacro(char *cp, STACK *stack, int called) -{ - MACRO *mac; - ARG *arg, **argtail; - char *label; - - cp = skipwhite(cp); - label = get_symbol(cp, &cp, NULL); - if(label == NULL) - { - report(stack->top, "Invalid macro definition\n"); - return NULL; - } - - /* Allow redefinition of a macro; new definition replaces the old. */ - mac = (MACRO *)lookup_sym(label, ¯o_st); - if(mac) - { - /* Remove from the symbol table... */ - remove_sym(&mac->sym, ¯o_st); - free_macro(mac); - } - - mac = new_macro(label); - - add_table(&mac->sym, ¯o_st); - - argtail = &mac->args; - cp = skipdelim(cp); - - while(!EOL(*cp)) - { - arg = new_arg(); - if(arg->locsym = (*cp == '?')) /* special argument flag? */ - cp++; - arg->label = get_symbol(cp, &cp, NULL); - if(arg->label == NULL) - { - /* It turns out that I have code which is badly formatted - but which MACRO.SAV assembles. Sigh. */ - /* So, just quit defining arguments. */ - break; -#if 0 - report(str, "Illegal macro argument\n"); - remove_sym(&mac->sym, ¯o_st); - free_macro(mac); - return NULL; -#endif - } - - cp = skipwhite(cp); - if(*cp == '=') - { - /* Default substitution given */ - arg->value = getstring(cp+1, &cp); - if(arg->value == NULL) - { - report(stack->top, "Illegal macro argument\n"); - remove_sym(&mac->sym, ¯o_st); - free_macro(mac); - return NULL; - } - } - - /* Append to list of arguments */ - arg->next = NULL; - *argtail = arg; - argtail = &arg->next; - - cp = skipdelim(cp); - } - - /* Read the stream in until the end marker is hit */ - { - BUFFER *gb; - int levelmod = 0; - - gb = new_buffer(); - - if(!called && !list_md) - { - list_level--; - levelmod = 1; - } - - read_body(stack, gb, mac->sym.label, called); - - list_level += levelmod; - - if(mac->text != NULL) /* Discard old macro body */ - buffer_free(mac->text); - - mac->text = gb; - } - - return mac; -} - -/* find_arg - looks for an arg with the given name in the given - argument list */ - -static ARG *find_arg(ARG *arg, char *name) -{ - for(; arg != NULL; arg = arg->next) - { - if(strcmp(arg->label, name) == 0) - return arg; - } - - return NULL; -} - -/* subst_args - given a BUFFER and a list of args, generate a new - BUFFER with argument replacement having taken place. */ - -BUFFER *subst_args(BUFFER *text, ARG *args) -{ - char *in; - char *begin; - BUFFER *gb; - char *label; - ARG *arg; - - gb = new_buffer(); - - /* Blindly look for argument symbols in the input. */ - /* Don't worry about quotes or comments. */ - - for(begin = in = text->buffer; in < text->buffer + text->length;) - { - char *next; - - if(issym(*in)) - { - label = get_symbol(in, &next, NULL); - if(label) - { - if(arg = find_arg(args, label)) - { - /* An apostrophy may appear before or after the symbol. */ - /* In either case, remove it from the expansion. */ - - if(in > begin && in[-1] == '\'') - in --; /* Don't copy it. */ - if(*next == '\'') - next++; - - /* Copy prior characters */ - buffer_appendn(gb, begin, in-begin); - /* Copy replacement string */ - buffer_append_line(gb, arg->value); - in = begin = next; - --in; /* prepare for subsequent increment */ - } - free(label); - in = next; - } - else - in++; - } - else - in++; - } - - /* Append the rest of the text */ - buffer_appendn(gb, begin, in - begin); - - return gb; /* Done. */ -} - -/* eval_arg - the language allows an argument expression to be given - as "\expression" which means, evaluate the expression and - substitute the numeric value in the current radix. */ - -void eval_arg(STREAM *refstr, ARG *arg) -{ - /* Check for value substitution */ - - if(arg->value[0] == '\\') - { - EX_TREE *value = parse_expr(arg->value+1, 0); - unsigned word = 0; - char temp[10]; - if(value->type != EX_LIT) - { - report(refstr, "Constant value required\n"); - } - else - word = value->data.lit; - - free_tree(value); - - /* printf can't do base 2. */ - my_ultoa(word & 0177777, temp, radix); - free(arg->value); - arg->value = memcheck(strdup(temp)); - } - -} - -/* expandmacro - return a STREAM containing the expansion of a macro */ - -STREAM *expandmacro(STREAM *refstr, MACRO *mac, char *cp) -{ - ARG *arg, *args, *macarg; - char *label; - STREAM *str; - BUFFER *buf; - - args = NULL; - arg = NULL; - - /* Parse the arguments */ - - while(!EOL(*cp)) - { - char *nextcp; - /* Check for named argument */ - label = get_symbol(cp, &nextcp, NULL); - if(label && - (nextcp = skipwhite(nextcp), *nextcp == '=') && - (macarg = find_arg(mac->args, label))) - { - /* Check if I've already got a value for it */ - if(find_arg(args, label) != NULL) - { - report(refstr, "Duplicate submission of keyword " - "argument %s\n", label); - free(label); - free_args(args); - return NULL; - } - - arg = new_arg(); - arg->label = label; - nextcp = skipwhite(nextcp+1); - arg->value = getstring(nextcp, &nextcp); - } - else - { - if(label) - free(label); - - /* Find correct positional argument */ - - for(macarg = mac->args; macarg != NULL; macarg = macarg->next) - { - if(find_arg(args, macarg->label) == NULL) - break; /* This is the next positional arg */ - } - - if(macarg == NULL) - break; /* Don't pick up any more arguments. */ - - arg = new_arg(); - arg->label = memcheck(strdup(macarg->label)); /* Copy the name */ - arg->value = getstring(cp, &nextcp); - } - - arg->next = args; - args = arg; - - eval_arg(refstr, arg); /* Check for expression evaluation */ - - cp = skipdelim(nextcp); - } - - /* Now go back and fill in defaults */ - - { - int locsym; - if(last_lsb != lsb) - locsym = last_locsym = 32768; - else - locsym = last_locsym; - last_lsb = lsb; - - for(macarg = mac->args; macarg != NULL; macarg = macarg->next) - { - arg = find_arg(args, macarg->label); - if(arg == NULL) - { - arg = new_arg(); - arg->label = memcheck(strdup(macarg->label)); - if(macarg->locsym) - { - char temp[32]; - /* Here's where we generate local labels */ - sprintf(temp, "%d$", locsym++); - arg->value = memcheck(strdup(temp)); - } - else if(macarg->value) - { - arg->value = memcheck(strdup(macarg->value)); - } - else - arg->value = memcheck(strdup("")); - - arg->next = args; - args = arg; - } - } - - last_locsym = locsym; - } - - buf = subst_args(mac->text, args); - - str = new_macro_stream(refstr, buf, mac, args); - - free_args(args); - buffer_free(buf); - - return str; -} - -/* *** implement REPT_STREAM */ - -typedef struct rept_stream -{ - BUFFER_STREAM bstr; - int count; /* The current repeat countdown */ - int savecond; /* conditional stack level at time of - expansion */ -} REPT_STREAM; - -/* rept_stream_gets gets a line from a repeat stream. At the end of - each count, the coutdown is decreated and the stream is reset to - it's beginning. */ - -char *rept_stream_gets(STREAM *str) -{ - REPT_STREAM *rstr = (REPT_STREAM *)str; - char *cp; - - for(;;) - { - if((cp = buffer_stream_gets(str)) != NULL) - return cp; - - if(--rstr->count <= 0) - return NULL; - - buffer_stream_rewind(str); - } -} - -/* rept_stream_delete unwinds nested conditionals like .MEXIT does. */ - -void rept_stream_delete(STREAM *str) -{ - REPT_STREAM *rstr = (REPT_STREAM *)str; - pop_cond(rstr->savecond); /* complete unterminated - conditionals */ - buffer_stream_delete(&rstr->bstr.stream); -} - -/* The VTBL */ - -STREAM_VTBL rept_stream_vtbl = { rept_stream_delete, - rept_stream_gets, - buffer_stream_rewind }; - -/* expand_rept is called when a .REPT is encountered in the input. */ - -STREAM *expand_rept(STACK *stack, char *cp) -{ - EX_TREE *value; - BUFFER *gb; - REPT_STREAM *rstr; - int levelmod; - - value = parse_expr(cp, 0); - if(value->type != EX_LIT) - { - report(stack->top, ".REPT value must be constant\n"); - free_tree(value); - return NULL; - } - - gb = new_buffer(); - - levelmod = 0; - if(!list_md) - { - list_level--; - levelmod = 1; - } - - read_body(stack, gb, NULL, FALSE); - - list_level += levelmod; - - rstr = memcheck(malloc(sizeof(REPT_STREAM))); - { - char *name = memcheck(malloc(strlen(stack->top->name) + 32)); - sprintf(name, "%s:%d->.REPT", stack->top->name, stack->top->line); - buffer_stream_construct(&rstr->bstr, gb, name); - free(name); - } - - rstr->count = value->data.lit; - rstr->bstr.stream.vtbl = &rept_stream_vtbl; - rstr->savecond = last_cond; - - buffer_free(gb); - free_tree(value); - - return &rstr->bstr.stream; -} - -/* *** implement IRP_STREAM */ - -typedef struct irp_stream -{ - BUFFER_STREAM bstr; - char *label; /* The substitution label */ - char *items; /* The substitution items (in source code - format) */ - int offset; /* Current offset into "items" */ - BUFFER *body; /* Original body */ - int savecond; /* Saved conditional level */ -} IRP_STREAM; - -/* irp_stream_gets expands the IRP as the stream is read. */ -/* Each time an iteration is exhausted, the next iteration is - generated. */ - -char *irp_stream_gets(STREAM *str) -{ - IRP_STREAM *istr = (IRP_STREAM *)str; - char *cp; - BUFFER *buf; - ARG *arg; - - for(;;) - { - if((cp = buffer_stream_gets(str)) != NULL) - return cp; - - cp = istr->items + istr->offset; - - if(!*cp) - return NULL; /* No more items. EOF. */ - - arg = new_arg(); - arg->next = NULL; - arg->locsym = 0; - arg->label = istr->label; - arg->value = getstring(cp, &cp); - cp = skipdelim(cp); - istr->offset = cp - istr->items; - - eval_arg(str, arg); - buf = subst_args(istr->body, arg); - - free(arg->value); - free(arg); - buffer_stream_set_buffer(&istr->bstr, buf); - buffer_free(buf); - } -} - -/* irp_stream_delete - also pops the conditional stack */ - -void irp_stream_delete(STREAM *str) -{ - IRP_STREAM *istr = (IRP_STREAM *)str; - - pop_cond(istr->savecond); /* complete unterminated - conditionals */ - - buffer_free(istr->body); - free(istr->items); - free(istr->label); - buffer_stream_delete(str); -} - -STREAM_VTBL irp_stream_vtbl = { irp_stream_delete, irp_stream_gets, - buffer_stream_rewind }; - -/* expand_irp is called when a .IRP is encountered in the input. */ - -STREAM *expand_irp(STACK *stack, char *cp) -{ - char *label, *items; - BUFFER *gb; - int levelmod = 0; - IRP_STREAM *str; - - label = get_symbol(cp, &cp, NULL); - if(!label) - { - report(stack->top, "Illegal .IRP syntax\n"); - return NULL; - } - - cp = skipdelim(cp); - - items = getstring(cp, &cp); - if(!items) - { - report(stack->top, "Illegal .IRP syntax\n"); - free(label); - return NULL; - } - - gb = new_buffer(); - - levelmod = 0; - if(!list_md) - { - list_level--; - levelmod++; - } - - read_body(stack, gb, NULL, FALSE); - - list_level += levelmod; - - str = memcheck(malloc(sizeof(IRP_STREAM))); - { - char *name = memcheck(malloc(strlen(stack->top->name) + 32)); - sprintf(name, "%s:%d->.IRP", stack->top->name, stack->top->line); - buffer_stream_construct(&str->bstr, NULL, name); - free(name); - } - - str->bstr.stream.vtbl = &irp_stream_vtbl; - - str->body = gb; - str->items = items; - str->offset = 0; - str->label = label; - str->savecond = last_cond; - - return &str->bstr.stream; -} - -/* *** implement IRPC_STREAM */ - -typedef struct irpc_stream -{ - BUFFER_STREAM bstr; - char *label; /* The substitution label */ - char *items; /* The substitution items (in source code - format) */ - int offset; /* Current offset in "items" */ - BUFFER *body; /* Original body */ - int savecond; /* conditional stack at invocation */ -} IRPC_STREAM; - -/* irpc_stream_gets - same comments apply as with irp_stream_gets, but - the substitution is character-by-character */ - -char *irpc_stream_gets(STREAM *str) -{ - IRPC_STREAM *istr = (IRPC_STREAM *)str; - char *cp; - BUFFER *buf; - ARG *arg; - - for(;;) - { - if((cp = buffer_stream_gets(str)) != NULL) - return cp; - - cp = istr->items + istr->offset; - - if(!*cp) - return NULL; /* No more items. EOF. */ - - arg = new_arg(); - arg->next = NULL; - arg->locsym = 0; - arg->label = istr->label; - arg->value = memcheck(malloc(2)); - arg->value[0] = *cp++; - arg->value[1] = 0; - istr->offset = cp - istr->items; - - buf = subst_args(istr->body, arg); - - free(arg->value); - free(arg); - buffer_stream_set_buffer(&istr->bstr, buf); - buffer_free(buf); - } -} - -/* irpc_stream_delete - also pops contidionals */ - -void irpc_stream_delete(STREAM *str) -{ - IRPC_STREAM *istr = (IRPC_STREAM *)str; - pop_cond(istr->savecond); /* complete unterminated - conditionals */ - buffer_free(istr->body); - free(istr->items); - free(istr->label); - buffer_stream_delete(str); -} - -STREAM_VTBL irpc_stream_vtbl = { irpc_stream_delete, - irpc_stream_gets, - buffer_stream_rewind }; - -/* expand_irpc - called when .IRPC is encountered in the input */ - -STREAM *expand_irpc(STACK *stack, char *cp) -{ - char *label, *items; - BUFFER *gb; - int levelmod = 0; - IRPC_STREAM *str; - - label = get_symbol(cp, &cp, NULL); - if(!label) - { - report(stack->top, "Illegal .IRPC syntax\n"); - return NULL; - } - - cp = skipdelim(cp); - - items = getstring(cp, &cp); - if(!items) - { - report(stack->top, "Illegal .IRPC syntax\n"); - free(label); - return NULL; - } - - gb = new_buffer(); - - levelmod = 0; - if(!list_md) - { - list_level--; - levelmod++; - } - - read_body(stack, gb, NULL, FALSE); - - list_level += levelmod; - - str = memcheck(malloc(sizeof(IRPC_STREAM))); - { - char *name = memcheck(malloc(strlen(stack->top->name) + 32)); - sprintf(name, "%s:%d->.IRPC", stack->top->name, stack->top->line); - buffer_stream_construct(&str->bstr, NULL, name); - free(name); - } - - str->bstr.stream.vtbl = &irpc_stream_vtbl; - str->body = gb; - str->items = items; - str->offset = 0; - str->label = label; - str->savecond = last_cond; - - return &str->bstr.stream; -} - -/* go_section - sets current_pc to a new program section */ - -void go_section(TEXT_RLD *tr, SECTION *sect) -{ - if(current_pc->section == sect) - return; /* This is too easy */ - - /* save current PC value for old section */ - current_pc->section->pc = DOT; - - /* Set current section and PC value */ - current_pc->section = sect; - DOT = sect->pc; -} - -/* - store_value - used to store a value represented by an expression - tree into the object file. Used by do_word and .ASCII/.ASCIZ. -*/ - -static void store_value(STACK *stack, TEXT_RLD *tr, - int size, EX_TREE *value) -{ - SYMBOL *sym; - unsigned offset; - - implicit_gbl(value); /* turn undefined symbols into globals */ - - if(value->type == EX_LIT) - { - store_word(stack->top, tr, size, value->data.lit); - } - else if(!express_sym_offset(value, &sym, &offset)) - { - store_complex(stack->top, tr, size, value); - } - else - { - if((sym->flags & (GLOBAL|DEFINITION)) == GLOBAL) - { - store_global_offset_word(stack->top, tr, size, - sym->value+offset, - sym->label); - } - else if(sym->section != current_pc->section) - { - store_psect_offset_word(stack->top, tr, size, - sym->value+offset, - sym->section->label); - } - else - { - store_internal_word(stack->top, tr, size, - sym->value+offset); - } - } -} - -/* do_word - used by .WORD, .BYTE, and implied .WORD. */ - -static int do_word(STACK *stack, TEXT_RLD *tr, char *cp, int size) -{ - - if(size == 2 && (DOT & 1)) - { - report(stack->top, ".WORD on odd boundary\n"); - store_word(stack->top, tr, 1, 0); /* Align it */ - } - - do - { - EX_TREE *value = parse_expr(cp, 0); - - store_value(stack, tr, size, value); - - cp = skipdelim(value->cp); - - free_tree(value); - - } while(cp = skipdelim(cp), !EOL(*cp)); - - return 1; -} - -/* - check_branch - check branch distance. -*/ - -static int check_branch(STACK *stack, unsigned offset, int min, int max) -{ - int s_offset; - /* Sign-extend */ - if(offset & 0100000) - s_offset = offset | ~0177777; - else - s_offset = offset & 077777; - if(s_offset > max || s_offset < min) - { - char temp[16]; - /* printf can't do signed octal. */ - my_ltoa(s_offset, temp, 8); - report(stack->top, - "Branch target out of range (distance=%s)\n", - temp); - return 0; - } - return 1; -} - -/* assemble - read a line from the input stack, assemble it. */ - -/* This function is way way too large, because I just coded most of - the operation code and pseudo-op handling right in line. */ - -int assemble(STACK *stack, TEXT_RLD *tr) -{ - char *cp; /* Parse character pointer */ - char *opcp; /* Points to operation mnemonic text */ - char *ncp; /* "next" cp */ - char *label; /* A label */ - char *line; /* The whole line */ - SYMBOL *op; /* The operation SYMBOL */ - int local; /* Whether a label is a local label or - not */ - - line = stack_gets(stack); - if(line == NULL) - return -1; /* Return code for EOF. */ - - cp = line; - - /* Frankly, I don't need to keep "line." But I found it quite - handy during debugging, to see what the whole operation was, - when I'm down to parsing the second operand and things aren't - going right. */ - - stmtno++; /* Increment statement number */ - - list_source(stack->top, line); /* List source */ - - if(suppressed) - { - /* Assembly is suppressed by unsatisfoed conditional. Look - for ending and enabling statements. */ - - op = get_op(cp, &cp); /* Look at operation code */ - - /* FIXME: this code will blindly look into .REM commentary and - find operation codes. Incidentally, so will read_body. */ - - if(op == NULL) - return 1; /* Not found. Don't care. */ - if(op->section->type != PSEUDO) - return 1; /* Not a pseudo-op. */ - switch(op->value) - { - case P_IF: - case P_IFDF: - suppressed++; /* Nested. Suppressed. */ - break; - case P_IFTF: - if(suppressed == 1) /* Reduce suppression from 1 to 0. */ - suppressed = 0; - break; - case P_IFF: - if(suppressed == 1) /* Can reduce suppression from 1 to 0. */ - { - if(!conds[last_cond].ok) - suppressed = 0; - } - break; - case P_IFT: - if(suppressed == 1) /* Can reduce suppression from 1 to 0. */ - { - if(conds[last_cond].ok) - suppressed = 0; - } - break; - case P_ENDC: - suppressed--; /* Un-nested. */ - if(suppressed == 0) - pop_cond(last_cond-1); /* Re-enabled. */ - break; - } - return 1; - } - - /* The line may begin with "label:[:]" */ - - opcp = cp; - if((label = get_symbol(cp, &ncp, &local)) != NULL) - { - int flag = PERMANENT|DEFINITION|local; - SYMBOL *sym; - - ncp = skipwhite(ncp); - if(*ncp == ':') /* Colon, for symbol definition? */ - { - ncp++; - /* maybe it's a global definition */ - if(*ncp == ':') - { - flag |= GLOBAL; /* Yes, include global flag */ - ncp++; - } - - sym = add_sym(label, DOT, flag, current_pc->section, &symbol_st); - cp = ncp; - - if(sym == NULL) - report(stack->top, "Illegal symbol definition %s\n", label); - - free(label); - - /* See if local symbol block should be incremented */ - if(!enabl_lsb && !local) - lsb++; - - cp = skipwhite(ncp); - opcp = cp; - label = get_symbol(cp, &ncp, NULL); /* Now, get what follows */ - } - } - - /* PSEUDO P_IIF jumps here. */ -reassemble: - cp = skipwhite(cp); - - if(EOL(*cp)) - return 1; /* It's commentary. All done. */ - - if(label) /* Something looks like a label. */ - { - /* detect assignment */ - - ncp = skipwhite(ncp); /* The pointer to the text that - follows the symbol */ - - if(*ncp == '=') - { - unsigned flags; - EX_TREE *value; - SYMBOL *sym; - - cp = ncp; - - /* Symbol assignment. */ - - flags = DEFINITION|local; - cp++; - if(*cp == '=') - { - flags |= GLOBAL; /* Global definition */ - cp++; - } - if(*cp == ':') - { - flags |= PERMANENT; - cp++; - } - - cp = skipwhite(cp); - - value = parse_expr(cp, 0); - - /* Special code: if the symbol is the program counter, - this is harder. */ - - if(strcmp(label, ".") == 0) - { - if(current_pc->section->flags & PSECT_REL) - { - SYMBOL *sym; - unsigned offset; - - /* Express the given expression as a symbol and an - offset. The symbol must not be global, the - section must = current. */ - - if(!express_sym_offset(value, &sym, &offset)) - { - report(stack->top, "Illegal ORG\n"); - } - else if((sym->flags & (GLOBAL|DEFINITION)) == GLOBAL) - { - report(stack->top, - "Can't ORG to external location\n"); - } - else if(sym->flags & UNDEFINED) - { - report(stack->top, "Can't ORG to undefined sym\n"); - } - else if(sym->section != current_pc->section) - { - report(stack->top, - "Can't ORG to alternate section " - "(use PSECT)\n"); - } - else - { - DOT = sym->value + offset; - list_value(stack->top, DOT); - change_dot(tr, 0); - } - } - else - { - /* If the current section is absolute, the value - must be a literal */ - if(value->type != EX_LIT) - { - report(stack->top, - "Can't ORG to non-absolute location\n"); - free_tree(value); - free(label); - return 0; - } - DOT = value->data.lit; - list_value(stack->top, DOT); - change_dot(tr, 0); - } - free_tree(value); - free(label); - return 1; - } - - /* regular symbols */ - if(value->type == EX_LIT) - { - sym = add_sym(label, value->data.lit, - flags, &absolute_section, &symbol_st); - } - else if(value->type == EX_SYM || - value->type == EX_TEMP_SYM) - { - sym = add_sym(label, value->data.symbol->value, - flags, value->data.symbol->section, &symbol_st); - } - else - { - report(stack->top, "Complex expression cannot be assigned " - "to a symbol\n"); - - if(!pass) - { - /* This may work better in pass 2 - something in - RT-11 monitor needs the symbol to apear to be - defined even if I can't resolve it's value. */ - sym = add_sym(label, 0, UNDEFINED, - &absolute_section, &symbol_st); - } - else - sym = NULL; - } - - if(sym != NULL) - list_value(stack->top, sym->value); - - free_tree(value); - free(label); - - return sym != NULL; - } - - /* Try to resolve macro */ - - op = lookup_sym(label, ¯o_st); - if(op && - op->stmtno < stmtno) - { - STREAM *macstr; - - free(label); - - macstr = expandmacro(stack->top, (MACRO *)op, ncp); - - stack_push(stack, macstr); /* Push macro expansion - onto input stream */ - - return 1; - } - - /* Try to resolve instruction or pseudo */ - op = lookup_sym(label, &system_st); - if(op) - { - cp = ncp; - - free(label); /* Don't need this hanging around anymore */ - - switch(op->section->type) - { - case PSEUDO: - switch(op->value) - { - case P_ENDR: - case P_ENDM: - case P_SBTTL: - case P_LIST: - case P_NLIST: - case P_PRINT: - return 1; /* Accepted, ignored. (An obvious - need: get assembly listing - controls working. ) */ - - case P_IDENT: - { - char endc[6]; - int len; - - cp = skipwhite(cp); - endc[0] = *cp++; - endc[1] = '\n'; - endc[2] = 0; - len = strcspn(cp, endc); - if(len > 6) - len = 6; - - if(ident) /* An existing ident? */ - free(ident); /* Discard it. */ - - ident = memcheck(malloc(len + 1)); - memcpy(ident, cp, len); - ident[len] = 0; - upcase(ident); - - return 1; - } - - case P_RADIX: - { - int old_radix = radix; - radix = strtoul(cp, &cp, 10); - if(radix != 8 && radix != 10 && radix != 16 && - radix != 2) - { - radix = old_radix; - report(stack->top, "Illegal radix\n"); - return 0; - } - return 1; - } - - case P_FLT4: - case P_FLT2: - { - int ok = 1; - - while(!EOL(*cp)) - { - unsigned flt[4]; - if(parse_float(cp, &cp, - (op->value == P_FLT4 ? 4 : 2), - flt)) - { - /* Store the word values */ - store_word(stack->top, tr, 2, flt[0]); - store_word(stack->top, tr, 2, flt[1]); - if(op->value == P_FLT4) - { - store_word(stack->top, tr, - 2, flt[2]); - store_word(stack->top, tr, - 2, flt[3]); - } - } - else - { - report(stack->top, - "Bad floating point format\n"); - ok = 0; - } - cp = skipdelim(cp); - } - return ok; - } - - case P_ERROR: - report(stack->top, "%.*s\n", strcspn(cp, "\n"), cp); - return 0; - - case P_SAVE: - sect_sp++; - sect_stack[sect_sp] = current_pc->section; - return 1; - - case P_RESTORE: - if(sect_sp < 0) - { - report(stack->top, "No saved section for .RESTORE\n"); - return 0; - } - else - { - go_section(tr, sect_stack[sect_sp]); - sect_sp++; - } - return 1; - - case P_NARG: - { - STREAM *str; - MACRO_STREAM *mstr; - int local; - - label = get_symbol(cp, &cp, &local); - - if(label == NULL) - { - report(stack->top, "Bad .NARG syntax\n"); - return 0; - } - - /* Walk up the stream stack to find the - topmost macro stream */ - for(str = stack->top; - str != NULL && - str->vtbl != ¯o_stream_vtbl; - str = str->next) - ; - - if(!str) - { - report(str, ".NARG not within macro expansion\n"); - free(label); - return 0; - } - - mstr = (MACRO_STREAM *)str; - - add_sym(label, mstr->nargs, DEFINITION|local, - &absolute_section, &symbol_st); - free(label); - return 1; - } - - case P_NCHR: - { - char *string; - int local; - label = get_symbol(cp, &cp, &local); - - if(label == NULL) - { - report(stack->top, "Bad .NCHR syntax\n"); - return 0; - } - - cp = skipdelim(cp); - - string = getstring(cp, &cp); - - add_sym(label, strlen(string), - DEFINITION|local, - &absolute_section, &symbol_st); - free(label); - free(string); - return 1; - } - - case P_NTYPE: - { - ADDR_MODE mode; - int local; - - label = get_symbol(cp, &cp, &local); - if(label == NULL) - { - report(stack->top, "Bad .NTYPE syntax\n"); - return 0; - } - - cp = skipdelim(cp); - - if(!get_mode(cp, &cp, &mode)) - { - report(stack->top, - "Bad .NTYPE addressing mode\n"); - free(label); - return 0; - } - - add_sym(label, mode.type, DEFINITION|local, - &absolute_section, &symbol_st); - free_addr_mode(&mode); - free(label); - - return 1; - } - - case P_INCLU: - { - char *name = getstring(cp, &cp); - STREAM *incl; - - if(name == NULL) - { - report(stack->top, "Bad .INCLUDE file name\n"); - return 0; - } - - incl = new_file_stream(name); - if(incl == NULL) - { - report(stack->top, - "Unable to open .INCLUDE file %s\n", name); - free(name); - return 0; - } - - free(name); - - stack_push(stack, incl); - - return 1; - } - - case P_REM: - { - char quote[4]; - /* Read and discard lines until one with a - closing quote */ - - cp = skipwhite(cp); - quote[0] = *cp++; - quote[1] = '\n'; - quote[2] = 0; - - for(;;) - { - cp += strcspn(cp, quote); - if(*cp == quote[0]) - break; /* Found closing quote */ - cp = stack_gets(stack); /* Read next input line */ - if(cp == NULL) - break; /* EOF */ - } - } - return 1; - - case P_IRP: - { - STREAM *str = expand_irp(stack, cp); - if(str) - stack_push(stack, str); - return str != NULL; - } - - case P_IRPC: - { - STREAM *str = expand_irpc(stack, cp); - if(str) - stack_push(stack, str); - return str != NULL; - } - - case P_MCALL: - { - STREAM *macstr; - BUFFER *macbuf; - char *maccp; - int saveline; - MACRO *mac; - int i; - char macfile[FILENAME_MAX]; - char hitfile[FILENAME_MAX]; - - for(;;) - { - cp = skipdelim(cp); - - if(EOL(*cp)) - return 1; - - label = get_symbol(cp, &cp, NULL); - if(!label) - { - report(stack->top, "Illegal .MCALL format\n"); - return 0; - } - - /* See if that macro's already defined */ - if(lookup_sym(label, ¯o_st)) - { - free(label); /* Macro already - registered. No - prob. */ - cp = skipdelim(cp); - continue; - } - - /* Find the macro in the list of included - macro libraries */ - macbuf = NULL; - for(i = 0; i < nr_mlbs; i++) - { - if((macbuf = mlb_entry(mlbs[i], - label)) != NULL) - break; - } - if(macbuf != NULL) - { - macstr = new_buffer_stream(macbuf, label); - buffer_free(macbuf); - } - else - { - strncpy(macfile, label, sizeof(macfile)); - strncat(macfile, ".MAC", sizeof(macfile) - strlen(macfile)); - my_searchenv(macfile, "MCALL", hitfile, sizeof(hitfile)); - if(hitfile[0]) - macstr = new_file_stream(hitfile); - } - - if(macstr != NULL) - { - for(;;) - { - char *mlabel; - maccp = macstr->vtbl->gets(macstr); - if(maccp == NULL) - break; - mlabel = get_symbol(maccp, &maccp, NULL); - if(mlabel == NULL) - continue; - op = lookup_sym(mlabel, &system_st); - free(mlabel); - if(op == NULL) - continue; - if(op->value == P_MACRO) - break; - } - - if(maccp != NULL) - { - STACK macstack = { macstr }; - int savelist = list_level; - saveline = stmtno; - list_level = -1; - mac = defmacro(maccp, &macstack, TRUE); - if(mac == NULL) - { - report(stack->top, - "Failed to define macro " - "called %s\n", - label); - } - - stmtno = saveline; - list_level = savelist; - } - - macstr->vtbl->delete(macstr); - } - else - report(stack->top, - "MACRO %s not found\n", label); - - free(label); - } - } - return 1; - - case P_MACRO: - { - MACRO *mac = defmacro(cp, stack, FALSE); - return mac != NULL; - } - - case P_MEXIT: - { - STREAM *macstr; - - /* Pop a stream from the input. */ - /* It must be the first stream, and it must be */ - /* a macro, rept, irp, or irpc. */ - macstr = stack->top; - if(macstr->vtbl != ¯o_stream_vtbl && - macstr->vtbl != &rept_stream_vtbl && - macstr->vtbl != &irp_stream_vtbl && - macstr->vtbl != &irpc_stream_vtbl) - { - report(stack->top, ".MEXIT not within a macro\n"); - return 0; - } - - /* and finally, pop the macro */ - stack_pop(stack); - - return 1; - } - - case P_REPT: - { - STREAM *reptstr = expand_rept(stack, cp); - if(reptstr) - stack_push(stack, reptstr); - return reptstr != NULL; - } - - case P_ENABL: - - /* FIXME - add all the rest of the options. */ - while(!EOL(*cp)) - { - label = get_symbol(cp, &cp, NULL); - if(strcmp(label, "AMA") == 0) - enabl_ama = 1; - else if(strcmp(label, "LSB") == 0) - { - enabl_lsb = 1; - lsb++; - } - else if(strcmp(label, "GBL") == 0) - enabl_gbl = 1; - free(label); - cp = skipdelim(cp); - } - return 1; - - case P_DSABL: - - /* FIXME Ditto as for .ENABL */ - while(!EOL(*cp)) - { - label = get_symbol(cp, &cp, NULL); - if(strcmp(label, "AMA") == 0) - enabl_ama = 0; - else if(strcmp(label, "LSB") == 0) - enabl_lsb = 0; - else if(strcmp(label, "GBL") == 0) - enabl_gbl = 0; - free(label); - cp = skipdelim(cp); - } - return 1; - - case P_LIMIT: - store_limits(stack->top, tr); - return 1; - - case P_TITLE: - /* accquire module name */ - if(module_name != NULL) - { - free(module_name); - } - module_name = get_symbol(cp, &cp, NULL); - return 1; - - case P_END: - /* Accquire transfer address */ - cp = skipwhite(cp); - if(!EOL(*cp)) - { - if(xfer_address) - free_tree(xfer_address); - xfer_address = parse_expr(cp, 0); - } - return 1; - - case P_IFDF: - opcp = skipwhite(opcp); - cp = opcp + 3; /* Point cp at the "DF" or - "NDF" part */ - /* Falls into... */ - case P_IIF: - case P_IF: - { - EX_TREE *value; - int ok; - - label = get_symbol(cp, &cp, NULL); /* Get condition */ - cp = skipdelim(cp); - - if(strcmp(label, "DF") == 0) - { - value = parse_expr(cp, 1); - cp = value->cp; - ok = eval_defined(value); - free_tree(value); - } - else if(strcmp(label, "NDF") == 0) - { - value = parse_expr(cp, 1); - cp = value->cp; - ok = eval_undefined(value); - free_tree(value); - } - else if(strcmp(label, "B") == 0) - { - char *thing; - cp = skipwhite(cp); - if(!EOL(*cp)) - thing = getstring(cp, &cp); - else - thing = memcheck(strdup("")); - ok = (*thing == 0); - free(thing); - } - else if(strcmp(label, "NB") == 0) - { - char *thing; - cp = skipwhite(cp); - if(!EOL(*cp)) - thing = getstring(cp, &cp); - else - thing = memcheck(strdup("")); - ok = (*thing != 0); - free(thing); - } - else if(strcmp(label, "IDN") == 0) - { - char *thing1, *thing2; - thing1 = getstring(cp, &cp); - cp = skipdelim(cp); - if(!EOL(*cp)) - thing2 = getstring(cp, &cp); - else - thing2 = memcheck(strdup("")); - ok = (strcmp(thing1, thing2) == 0); - free(thing1); - free(thing2); - } - else if(strcmp(label, "DIF") == 0) - { - char *thing1, *thing2; - thing1 = getstring(cp, &cp); - cp = skipdelim(cp); - if(!EOL(*cp)) - thing2 = getstring(cp, &cp); - else - thing2 = memcheck(strdup("")); - ok = (strcmp(thing1, thing2) != 0); - free(thing1); - free(thing2); - } - else - { - int sword; - unsigned uword; - EX_TREE *value = parse_expr(cp, 0); - - cp = value->cp; - - if(value->type != EX_LIT) - { - report(stack->top, "Bad .IF expression\n"); - list_value(stack->top, 0); - free_tree(value); - ok = FALSE; /* Pick something. */ - } - else - { - unsigned word; - /* Convert to signed and unsigned words */ - sword = value->data.lit & 0x7fff; - - /* FIXME I don't know if the following - is portable enough. */ - if(value->data.lit & 0x8000) - sword |= ~0xFFFF; /* Render negative */ - - /* Reduce unsigned value to 16 bits */ - uword = value->data.lit & 0xffff; - - if(strcmp(label, "EQ") == 0 || - strcmp(label, "Z") == 0) - ok = (uword == 0), word = uword; - else if(strcmp(label, "NE") == 0 || - strcmp(label, "NZ") == 0) - ok = (uword != 0), word = uword; - else if(strcmp(label, "GT") == 0 || - strcmp(label, "G") == 0) - ok = (sword > 0), word = sword; - else if(strcmp(label, "GE") == 0) - ok = (sword >= 0), word = sword; - else if(strcmp(label, "LT") == 0 || - strcmp(label, "L") == 0) - ok = (sword < 0), word = sword; - else if(strcmp(label, "LE") == 0) - ok = (sword <= 0), word = sword; - - list_value(stack->top, word); - - free_tree(value); - } - } - - free(label); - - if(op->value == P_IIF) - { - stmtno++; /* the second half is a - separate statement */ - if(ok) - { - /* The "immediate if" */ - /* Only slightly tricky. */ - cp = skipdelim(cp); - label = get_symbol(cp, &ncp, &local); - goto reassemble; - } - return 1; - } - - push_cond(ok, stack->top); - - if(!ok) - suppressed++; /* Assembly - suppressed - until .ENDC */ - } - return 1; - - case P_IFF: - if(last_cond < 0) - { - report(stack->top, "No conditional block active\n"); - return 0; - } - if(conds[last_cond].ok) /* Suppress if last cond - is true */ - suppressed++; - return 1; - - case P_IFT: - if(last_cond < 0) - { - report(stack->top, "No conditional block active\n"); - return 0; - } - if(!conds[last_cond].ok) /* Suppress if last cond - is false */ - suppressed++; - return 1; - - case P_IFTF: - if(last_cond < 0) - { - report(stack->top, "No conditional block active\n"); - return 0; - } - return 1; /* Don't suppress. */ - - case P_ENDC: - if(last_cond < 0) - { - report(stack->top, "No conditional block active\n"); - return 0; - } - - pop_cond(last_cond-1); - return 1; - - case P_EVEN: - if(DOT & 1) - { - list_word(stack->top, DOT, 0, 1, ""); - DOT++; - } - return 1; - - case P_ODD: - if(!(DOT & 1)) - { - list_word(stack->top, DOT, 0, 1, ""); - DOT++; - } - return 1; - - case P_ASECT: - go_section(tr, &absolute_section); - return 1; - - case P_CSECT: - case P_PSECT: - { - SYMBOL *sectsym; - SECTION *sect; - - label = get_symbol(cp, &cp, NULL); - if(label == NULL) - label = memcheck(strdup("")); /* Allow blank */ - - sectsym = lookup_sym(label, §ion_st); - if(sectsym) - { - sect = sectsym->section; - free(label); - } - else - { - sect = new_section(); - sect->label = label; - sect->flags = 0; - sect->pc = 0; - sect->size = 0; - sect->type = USER; - sections[sector++] = sect; - sectsym = add_sym(label, 0, 0, sect, §ion_st); - } - - if(op->value == P_PSECT) - sect->flags |= PSECT_REL; - else if(op->value == P_CSECT) - sect->flags |= PSECT_REL|PSECT_COM|PSECT_GBL; - - while(cp = skipdelim(cp), !EOL(*cp)) - { - /* Parse section options */ - label = get_symbol(cp, &cp, NULL); - if(strcmp(label, "ABS") == 0) - { - sect->flags &= ~PSECT_REL; /* Not relative */ - sect->flags |= PSECT_COM; /* implies common */ - } - else if(strcmp(label, "REL") == 0) - { - sect->flags |= PSECT_REL; /* Is relative */ - } - else if(strcmp(label, "SAV") == 0) - { - sect->flags |= PSECT_SAV; /* Is root */ - } - else if(strcmp(label, "OVR") == 0) - { - sect->flags |= PSECT_COM; /* Is common */ - } - else if(strcmp(label, "RW") == 0) - { - sect->flags &= ~PSECT_RO; /* Not read-only */ - } - else if(strcmp(label, "RO") == 0) - { - sect->flags |= PSECT_RO; /* Is read-only */ - } - else if(strcmp(label, "I") == 0) - { - sect->flags &= ~PSECT_DATA; /* Not data */ - } - else if(strcmp(label, "D") == 0) - { - sect->flags |= PSECT_DATA; /* data */ - } - else if(strcmp(label, "GBL") == 0) - { - sect->flags |= PSECT_GBL; /* Global */ - } - else if(strcmp(label, "LCL") == 0) - { - sect->flags &= ~PSECT_GBL; /* Local */ - } - else - { - report(stack->top, - "Unknown flag %s given to " - ".PSECT directive\n", label); - free(label); - return 0; - } - - free(label); - } - - go_section(tr, sect); - - return 1; - } /* end PSECT code */ - break; - - case P_WEAK: - case P_GLOBL: - { - SYMBOL *sym; - while(!EOL(*cp)) - { - /* Loop and make definitions for - comma-separated symbols */ - label = get_symbol(cp, &ncp, NULL); - if(label == NULL) - { - report(stack->top, - "Illegal .GLOBL/.WEAK " - "syntax\n"); - return 0; - } - - sym = lookup_sym(label, &symbol_st); - if(sym) - { - sym->flags |= - GLOBAL| - (op->value == P_WEAK ? WEAK : 0); - } - else - sym = add_sym(label, 0, - GLOBAL| - (op->value == P_WEAK ? WEAK : 0), - &absolute_section, &symbol_st); - - free(label); - cp = skipdelim(ncp); - } - } - return 1; - - case P_WORD: - { - /* .WORD might be followed by nothing, which - is an implicit .WORD 0 */ - if(EOL(*cp)) - { - if(DOT & 1) - { - report(stack->top, ".WORD on odd " - "boundary\n"); - DOT++; /* Fix it, too */ - } - store_word(stack->top, tr, 2, 0); - return 1; - } - else - return do_word(stack, tr, cp, 2); - } - - case P_BYTE: - if(EOL(*cp)) - { - /* Blank .BYTE. Same as .BYTE 0 */ - store_word(stack->top, tr, 1, 0); - return 1; - } - else - return do_word(stack, tr, cp, 1); - - case P_BLKW: - case P_BLKB: - { - EX_TREE *value = parse_expr(cp, 0); - int ok = 1; - if(value->type != EX_LIT) - { - report(stack->top, - "Argument to .BLKB/.BLKW " - "must be constant\n"); - ok = 0; - } - else - { - list_value(stack->top, DOT); - DOT += value->data.lit * - (op->value == P_BLKW ? 2 : 1); - change_dot(tr, 0); - } - free_tree(value); - return ok; - } - - case P_ASCIZ: - case P_ASCII: - { - EX_TREE *value; - - do - { - cp = skipwhite(cp); - if(*cp == '<' || *cp == '^') - { - /* A byte value */ - value = parse_expr(cp, 0); - cp = value->cp; - store_value(stack, tr, 1, value); - free_tree(value); - } - else - { - char quote = *cp++; - while(*cp && *cp != '\n' && *cp != quote) - { - store_word(stack->top, tr, 1, *cp++); - } - cp++; /* Skip closing quote */ - } - - cp = skipwhite(cp); - } while(!EOL(*cp)); - - if(op->value == P_ASCIZ) - { - store_word(stack->top, tr, 1, 0); - } - - return 1; - } - - case P_RAD50: - - if(DOT & 1) - { - report(stack->top, ".RAD50 on odd " - "boundary\n"); - DOT++; /* Fix it */ - } - - while(!EOL(*cp)) - { - char endstr[6]; - int len; - char *radstr; - char *radp; - - endstr[0] = *cp++; - endstr[1] = '\n'; - endstr[2] = 0; - - len = strcspn(cp, endstr); - radstr = memcheck(malloc(len + 1)); - memcpy(radstr, cp, len); - radstr[len] = 0; - cp += len; - if(*cp && *cp != '\n') - cp++; - for(radp = radstr; *radp;) - { - unsigned rad; - rad = rad50(radp, &radp); - store_word(stack->top, tr, 2, rad); - } - free(radstr); - - cp = skipwhite(cp); - } - return 1; - - default: - report(stack->top, "Unimplemented directive %s\n", - op->label); - return 0; - - } /* end switch (PSEUDO operation) */ - - case INSTRUCTION: - { - /* The PC must always be even. */ - if(DOT & 1) - { - report(stack->top, - "Instruction on odd address\n"); - DOT++; /* ...and fix it... */ - } - - switch(op->flags & OC_MASK) - { - case OC_NONE: - /* No operands. */ - store_word(stack->top, tr, 2, op->value); - return 1; - - case OC_MARK: - /* MARK, EMT, TRAP */ - { - EX_TREE *value; - unsigned word; - - cp = skipwhite(cp); - if(*cp == '#') - cp++; /* Allow the hash, but - don't require it */ - value = parse_expr(cp, 0); - if(value->type != EX_LIT) - { - report(stack->top, - "Instruction requires " - "simple literal operand\n"); - word = op->value; - } - else - { - word = op->value | value->data.lit; - } - - store_word(stack->top, tr, 2, word); - free_tree(value); - } - return 1; - - case OC_1GEN: - /* One general addressing mode */ - { - ADDR_MODE mode; - unsigned word; - - if(!get_mode(cp, &cp, &mode)) - { - report(stack->top, - "Illegal addressing mode\n"); - return 0; - } - - if(op->value == 0100 && - (mode.type & 07) == 0) - { - report(stack->top, - "JMP Rn is illegal\n"); - /* But encode it anyway... */ - } - - /* Build instruction word */ - word = op->value | mode.type; - store_word(stack->top, tr, 2, word); - mode_extension(tr, &mode, stack->top); - } - return 1; - - case OC_2GEN: - /* Two general addressing modes */ - { - ADDR_MODE left, right; - unsigned word; - - if(!get_mode(cp, &cp, &left)) - { - report(stack->top, - "Illegal addressing mode\n"); - return 0; - } - - if(*cp++ != ',') - { - report(stack->top, "Illegal syntax\n"); - free_addr_mode(&left); - return 0; - } - - if(!get_mode(cp, &cp, &right)) - { - report(stack->top, - "Illegal addressing mode\n"); - free_addr_mode(&left); - return 0; - } - - /* Build instruction word */ - word = op->value | left.type << 6 | right.type; - store_word(stack->top, tr, 2, word); - mode_extension(tr, &left, stack->top); - mode_extension(tr, &right, stack->top); - } - return 1; - - case OC_BR: - /* branches */ - { - EX_TREE *value; - unsigned offset; - - value = parse_expr(cp, 0); - cp = value->cp; - - /* Relative PSECT or absolute? */ - if(current_pc->section->flags & PSECT_REL) - { - SYMBOL *sym; - - /* Can't branch unless I can - calculate the offset. */ - - /* You know, I *could* branch - between sections if I feed the - linker a complex relocation - expression to calculate the - offset. But I won't. */ - - if(!express_sym_offset(value, - &sym, - &offset) || - sym->section != current_pc->section) - { - report(stack->top, - "Bad branch target\n"); - store_word(stack->top, tr, - 2, op->value); - free_tree(value); - return 0; - } - - /* Compute the branch offset and - check for addressability */ - offset += sym->value; - offset -= DOT + 2; - } - else - { - if(value->type != EX_LIT) - { - report(stack->top, - "Bad branch target\n"); - store_word(stack->top, tr, - 2, op->value); - free_tree(value); - return 0; - } - - offset = value->data.lit - - (DOT + 2); - } - - if(!check_branch(stack, offset, -256, - 255)) - offset = 0; - - /* Emit the branch code */ - offset &= 0777;/* Reduce to 9 bits */ - offset >>= 1; /* Shift to become - word offset */ - - store_word(stack->top, tr, - 2, op->value | offset); - - free_tree(value); - } - return 1; - - case OC_SOB: - { - EX_TREE *value; - unsigned reg; - unsigned offset; - - value = parse_expr(cp, 0); - cp = value->cp; - - reg = get_register(value); - free_tree(value); - if(reg == NO_REG) - { - report(stack->top, - "Illegal addressing mode\n"); - return 0; - } - - cp = skipwhite(cp); - if(*cp++ != ',') - { - report(stack->top, "Illegal syntax\n"); - return 0; - } - - value = parse_expr(cp, 0); - cp = value->cp; - - /* Relative PSECT or absolute? */ - if(current_pc->section->flags & PSECT_REL) - { - SYMBOL *sym; - - if(!express_sym_offset(value, - &sym, &offset)) - { - report(stack->top, - "Bad branch target\n"); - free_tree(value); - return 0; - } - /* Must be same section */ - if(sym->section != current_pc->section) - { - report(stack->top, - "Bad branch target\n"); - free_tree(value); - offset = 0; - } - else - { - /* Calculate byte offset */ - offset += DOT + 2; - offset -= sym->value; - } - } - else - { - if(value->type != EX_LIT) - { - report(stack->top, "Bad branch " - "target\n"); - offset = 0; - } - else - { - offset = DOT + 2 - - value->data.lit; - } - } - - if(!check_branch(stack, offset, 0, 126)) - offset = 0; - - offset &= 0177; /* Reduce to 7 bits */ - offset >>= 1; /* Shift to become word offset */ - store_word(stack->top, tr, 2, - op->value | offset | (reg << 6)); - - free_tree(value); - } - return 1; - - case OC_ASH: - /* First op is gen, second is register. */ - { - ADDR_MODE mode; - EX_TREE *value; - unsigned reg; - unsigned word; - - if(!get_mode(cp, &cp, &mode)) - { - report(stack->top, "Illegal addressing mode\n"); - return 0; - } - - cp = skipwhite(cp); - if(*cp++ != ',') - { - report(stack->top, "Illegal addressing mode\n"); - free_addr_mode(&mode); - return 0; - } - value = parse_expr(cp, 0); - cp = value->cp; - - reg = get_register(value); - if(reg == NO_REG) - { - report(stack->top, - "Illegal addressing mode\n"); - free_tree(value); - free_addr_mode(&mode); - return 0; - } - - /* Instruction word */ - word = op->value | mode.type | (reg << 6); - store_word(stack->top, tr, 2, word); - mode_extension(tr, &mode, stack->top); - free_tree(value); - } - return 1; - - case OC_JSR: - /* First op is register, second is gen. */ - { - ADDR_MODE mode; - EX_TREE *value; - unsigned reg; - unsigned word; - - value = parse_expr(cp, 0); - cp = value->cp; - - reg = get_register(value); - if(reg == NO_REG) - { - report(stack->top, - "Illegal addressing mode\n"); - free_tree(value); - return 0; - } - - cp = skipwhite(cp); - if(*cp++ != ',') - { - report(stack->top, - "Illegal addressing mode\n"); - return 0; - } - - if(!get_mode(cp, &cp, &mode)) - { - report(stack->top, - "Illegal addressing mode\n"); - free_tree(value); - return 0; - } - word = op->value | mode.type | (reg << 6); - store_word(stack->top, tr, 2, word); - mode_extension(tr, &mode, stack->top); - free_tree(value); - } - return 1; - - case OC_1REG: - /* One register (RTS) */ - { - EX_TREE *value; - unsigned reg; - - value = parse_expr(cp, 0); - cp = value->cp; - reg = get_register(value); - if(reg == NO_REG) - { - report(stack->top, - "Illegal addressing mode\n"); - free_tree(value); - reg = 0; - } - - store_word(stack->top, tr, - 2, op->value | reg); - free_tree(value); - } - return 1; - - case OC_1FIS: - /* One one gen and one reg 0-3 */ - { - ADDR_MODE mode; - EX_TREE *value; - unsigned reg; - unsigned word; - - if(!get_mode(cp, &cp, &mode)) - { - report(stack->top, - "Illegal addressing mode\n"); - return 0; - } - - cp = skipwhite(cp); - if(*cp++ != ',') - { - report(stack->top, - "Illegal addressing mode\n"); - free_addr_mode(&mode); - return 0; - } - - value = parse_expr(cp, 0); - cp = value->cp; - - reg = get_register(value); - if(reg == NO_REG || reg > 4) - { - report(stack->top, - "Invalid destination register\n"); - reg = 0; - } - - word = op->value | mode.type | (reg << 6); - store_word(stack->top, tr, 2, word); - mode_extension(tr, &mode, stack->top); - free_tree(value); - } - return 1; - - case OC_2FIS: - /* One reg 0-3 and one gen */ - { - ADDR_MODE mode; - EX_TREE *value; - unsigned reg; - unsigned word; - int ok = 1; - - value = parse_expr(cp, 0); - cp = value->cp; - - reg = get_register(value); - if(reg == NO_REG || reg > 4) - { - report(stack->top, - "Illegal source register\n"); - reg = 0; - ok = 0; - } - - cp = skipwhite(cp); - if(*cp++ != ',') - { - report(stack->top, - "Illegal addressing mode\n"); - free_tree(value); - return 0; - } - - if(!get_mode(cp, &cp, &mode)) - { - report(stack->top, - "Illegal addressing mode\n"); - free_tree(value); - return 0; - } - - word = op->value | mode.type | (reg << 6); - store_word(stack->top, tr, 2, word); - mode_extension(tr, &mode, stack->top); - free_tree(value); - } - return 1; - - default: - report(stack->top, - "Unimplemented instruction format\n"); - return 0; - } /* end(handle an instruction) */ - } - break; - } /* end switch(section type) */ - } /* end if (op is a symbol) */ - } - - /* Only thing left is an implied .WORD directive */ - - free(label); - - return do_word(stack, tr, cp, 2); -} - -/* assemble_stack assembles the input stack. It returns the error - count. */ - -static int assemble_stack(STACK *stack, TEXT_RLD *tr) -{ - int res; - int count = 0; - - while((res = assemble(stack, tr)) >= 0) - { - list_flush(); - if(res == 0) - count++; /* Count an error */ - } - - return count; -} - -/* write_globals writes out the GSD prior to the second assembly pass */ - -static void write_globals(FILE *obj) -{ - GSD gsd; - SYMBOL *sym; - SECTION *psect; - SYMBOL_ITER sym_iter; - int isect; - - if(obj == NULL) - return; /* Nothing to do if no OBJ file. */ - - gsd_init(&gsd, obj); - - gsd_mod(&gsd, module_name); - - if(ident) - gsd_ident(&gsd, ident); - - /* write out each PSECT with it's global stuff */ - /* Sections must be written out in the order that they - appear in the assembly file. */ - for(isect = 0; isect < sector; isect++) - { - psect = sections[isect]; - - gsd_psect(&gsd, psect->label, psect->flags, psect->size); - psect->sector = isect; /* Assign it a sector */ - psect->pc = 0; /* Reset it's PC for second pass */ - - sym = first_sym(&symbol_st, &sym_iter); - while(sym) - { - if((sym->flags & GLOBAL) && - sym->section == psect) - { - gsd_global(&gsd, sym->label, - (sym->flags & DEFINITION ? GLOBAL_DEF : 0) | - ((sym->flags & WEAK) ? GLOBAL_WEAK : 0) | - ((sym->section->flags & PSECT_REL) ? GLOBAL_REL : 0) | - 0100, /* Looks undefined, but add it in anyway */ - sym->value); - } - sym = next_sym(&symbol_st, &sym_iter); - } - } - - /* Now write out the transfer address */ - if(xfer_address->type == EX_LIT) - { - gsd_xfer(&gsd, ". ABS.", xfer_address->data.lit); - } - else - { - SYMBOL *sym; - unsigned offset; - if(!express_sym_offset(xfer_address, &sym, &offset)) - { - report(NULL, "Illegal program transfer address\n"); - } - else - { - gsd_xfer(&gsd, sym->section->label, sym->value + offset); - } - } - - gsd_flush(&gsd); - - gsd_end(&gsd); -} - -/* add_symbols adds all the internal symbols. */ - -static void add_symbols(SECTION *current_section) -{ - current_pc = add_sym(".", 0, 0, current_section, &symbol_st); - - reg_sym[0] = add_sym("R0", 0, 0, ®ister_section, &system_st); - reg_sym[1] = add_sym("R1", 1, 0, ®ister_section, &system_st); - reg_sym[2] = add_sym("R2", 2, 0, ®ister_section, &system_st); - reg_sym[3] = add_sym("R3", 3, 0, ®ister_section, &system_st); - reg_sym[4] = add_sym("R4", 4, 0, ®ister_section, &system_st); - reg_sym[5] = add_sym("R5", 5, 0, ®ister_section, &system_st); - reg_sym[6] = add_sym("SP", 6, 0, ®ister_section, &system_st); - reg_sym[7] = add_sym("PC", 7, 0, ®ister_section, &system_st); - - add_sym(".ASCII", P_ASCII, 0, &pseudo_section, &system_st); - add_sym(".ASCIZ", P_ASCIZ, 0, &pseudo_section, &system_st); - add_sym(".ASECT", P_ASECT, 0, &pseudo_section, &system_st); - add_sym(".BLKB", P_BLKB, 0, &pseudo_section, &system_st); - add_sym(".BLKW", P_BLKW, 0, &pseudo_section, &system_st); - add_sym(".BYTE", P_BYTE, 0, &pseudo_section, &system_st); - add_sym(".CSECT", P_CSECT, 0, &pseudo_section, &system_st); - add_sym(".DSABL", P_DSABL, 0, &pseudo_section, &system_st); - add_sym(".ENABL", P_ENABL, 0, &pseudo_section, &system_st); - add_sym(".END", P_END, 0, &pseudo_section, &system_st); - add_sym(".ENDC", P_ENDC, 0, &pseudo_section, &system_st); - add_sym(".ENDM", P_ENDM, 0, &pseudo_section, &system_st); - add_sym(".ENDR", P_ENDR, 0, &pseudo_section, &system_st); - add_sym(".EOT", P_EOT, 0, &pseudo_section, &system_st); - add_sym(".ERROR", P_ERROR, 0, &pseudo_section, &system_st); - add_sym(".EVEN", P_EVEN, 0, &pseudo_section, &system_st); - add_sym(".FLT2", P_FLT2, 0, &pseudo_section, &system_st); - add_sym(".FLT4", P_FLT4, 0, &pseudo_section, &system_st); - add_sym(".GLOBL", P_GLOBL, 0, &pseudo_section, &system_st); - add_sym(".IDENT", P_IDENT, 0, &pseudo_section, &system_st); - add_sym(".IF", P_IF, 0, &pseudo_section, &system_st); - add_sym(".IFDF", P_IFDF, 0, &pseudo_section, &system_st); - add_sym(".IFNDF", P_IFDF, 0, &pseudo_section, &system_st); - add_sym(".IFF", P_IFF, 0, &pseudo_section, &system_st); - add_sym(".IFT", P_IFT, 0, &pseudo_section, &system_st); - add_sym(".IFTF", P_IFTF, 0, &pseudo_section, &system_st); - add_sym(".IIF", P_IIF, 0, &pseudo_section, &system_st); - add_sym(".IRP", P_IRP, 0, &pseudo_section, &system_st); - add_sym(".IRPC", P_IRPC, 0, &pseudo_section, &system_st); - add_sym(".LIMIT", P_LIMIT, 0, &pseudo_section, &system_st); - add_sym(".LIST", P_LIST, 0, &pseudo_section, &system_st); - add_sym(".MCALL", P_MCALL, 0, &pseudo_section, &system_st); - add_sym(".MEXIT", P_MEXIT, 0, &pseudo_section, &system_st); - add_sym(".NARG", P_NARG, 0, &pseudo_section, &system_st); - add_sym(".NCHR", P_NCHR, 0, &pseudo_section, &system_st); - add_sym(".NLIST", P_NLIST, 0, &pseudo_section, &system_st); - add_sym(".NTYPE", P_NTYPE, 0, &pseudo_section, &system_st); - add_sym(".ODD", P_ODD, 0, &pseudo_section, &system_st); - add_sym(".PACKE", P_PACKED, 0, &pseudo_section, &system_st); - add_sym(".PAGE", P_PAGE, 0, &pseudo_section, &system_st); - add_sym(".PRINT", P_PRINT, 0, &pseudo_section, &system_st); - add_sym(".PSECT", P_PSECT, 0, &pseudo_section, &system_st); - add_sym(".RADIX", P_RADIX, 0, &pseudo_section, &system_st); - add_sym(".RAD50", P_RAD50, 0, &pseudo_section, &system_st); - add_sym(".REM", P_REM, 0, &pseudo_section, &system_st); - add_sym(".REPT", P_REPT, 0, &pseudo_section, &system_st); - add_sym(".RESTO", P_RESTORE, 0, &pseudo_section, &system_st); - add_sym(".SAVE", P_SAVE, 0, &pseudo_section, &system_st); - add_sym(".SBTTL", P_SBTTL, 0, &pseudo_section, &system_st); - add_sym(".TITLE", P_TITLE, 0, &pseudo_section, &system_st); - add_sym(".WORD", P_WORD, 0, &pseudo_section, &system_st); - add_sym(".MACRO", P_MACRO, 0, &pseudo_section, &system_st); - add_sym(".WEAK", P_WEAK, 0, &pseudo_section, &system_st); - - add_sym("ADC", I_ADC, OC_1GEN, &instruction_section, &system_st); - add_sym("ADCB", I_ADCB, OC_1GEN, &instruction_section, &system_st); - add_sym("ADD", I_ADD, OC_2GEN, &instruction_section, &system_st); - add_sym("ASH", I_ASH, OC_ASH, &instruction_section, &system_st); - add_sym("ASHC", I_ASHC, OC_ASH, &instruction_section, &system_st); - add_sym("ASL", I_ASL, OC_1GEN, &instruction_section, &system_st); - add_sym("ASLB", I_ASLB, OC_1GEN, &instruction_section, &system_st); - add_sym("ASR", I_ASR, OC_1GEN, &instruction_section, &system_st); - add_sym("ASRB", I_ASRB, OC_1GEN, &instruction_section, &system_st); - add_sym("BCC", I_BCC, OC_BR, &instruction_section, &system_st); - add_sym("BCS", I_BCS, OC_BR, &instruction_section, &system_st); - add_sym("BEQ", I_BEQ, OC_BR, &instruction_section, &system_st); - add_sym("BGE", I_BGE, OC_BR, &instruction_section, &system_st); - add_sym("BGT", I_BGT, OC_BR, &instruction_section, &system_st); - add_sym("BHI", I_BHI, OC_BR, &instruction_section, &system_st); - add_sym("BHIS", I_BHIS, OC_BR, &instruction_section, &system_st); - add_sym("BIC", I_BIC, OC_2GEN, &instruction_section, &system_st); - add_sym("BICB", I_BICB, OC_2GEN, &instruction_section, &system_st); - add_sym("BIS", I_BIS, OC_2GEN, &instruction_section, &system_st); - add_sym("BISB", I_BISB, OC_2GEN, &instruction_section, &system_st); - add_sym("BIT", I_BIT, OC_2GEN, &instruction_section, &system_st); - add_sym("BITB", I_BITB, OC_2GEN, &instruction_section, &system_st); - add_sym("BLE", I_BLE, OC_BR, &instruction_section, &system_st); - add_sym("BLO", I_BLO, OC_BR, &instruction_section, &system_st); - add_sym("BLOS", I_BLOS, OC_BR, &instruction_section, &system_st); - add_sym("BLT", I_BLT, OC_BR, &instruction_section, &system_st); - add_sym("BMI", I_BMI, OC_BR, &instruction_section, &system_st); - add_sym("BNE", I_BNE, OC_BR, &instruction_section, &system_st); - add_sym("BPL", I_BPL, OC_BR, &instruction_section, &system_st); - add_sym("BPT", I_BPT, OC_NONE, &instruction_section, &system_st); - add_sym("BR", I_BR, OC_BR, &instruction_section, &system_st); - add_sym("BVC", I_BVC, OC_BR, &instruction_section, &system_st); - add_sym("BVS", I_BVS, OC_BR, &instruction_section, &system_st); - add_sym("CALL", I_CALL, OC_1GEN, &instruction_section, &system_st); - add_sym("CALLR", I_CALLR, OC_1GEN, &instruction_section, &system_st); - add_sym("CCC", I_CCC, OC_NONE, &instruction_section, &system_st); - add_sym("CLC", I_CLC, OC_NONE, &instruction_section, &system_st); - add_sym("CLN", I_CLN, OC_NONE, &instruction_section, &system_st); - add_sym("CLR", I_CLR, OC_1GEN, &instruction_section, &system_st); - add_sym("CLRB", I_CLRB, OC_1GEN, &instruction_section, &system_st); - add_sym("CLV", I_CLV, OC_NONE, &instruction_section, &system_st); - add_sym("CLZ", I_CLZ, OC_NONE, &instruction_section, &system_st); - add_sym("CMP", I_CMP, OC_2GEN, &instruction_section, &system_st); - add_sym("CMPB", I_CMPB, OC_2GEN, &instruction_section, &system_st); - add_sym("COM", I_COM, OC_1GEN, &instruction_section, &system_st); - add_sym("COMB", I_COMB, OC_1GEN, &instruction_section, &system_st); - add_sym("DEC", I_DEC, OC_1GEN, &instruction_section, &system_st); - add_sym("DECB", I_DECB, OC_1GEN, &instruction_section, &system_st); - add_sym("DIV", I_DIV, OC_ASH, &instruction_section, &system_st); - add_sym("EMT", I_EMT, OC_MARK, &instruction_section, &system_st); - add_sym("FADD", I_FADD, OC_1REG, &instruction_section, &system_st); - add_sym("FDIV", I_FDIV, OC_1REG, &instruction_section, &system_st); - add_sym("FMUL", I_FMUL, OC_1REG, &instruction_section, &system_st); - add_sym("FSUB", I_FSUB, OC_1REG, &instruction_section, &system_st); - add_sym("HALT", I_HALT, OC_NONE, &instruction_section, &system_st); - add_sym("INC", I_INC, OC_1GEN, &instruction_section, &system_st); - add_sym("INCB", I_INCB, OC_1GEN, &instruction_section, &system_st); - add_sym("IOT", I_IOT, OC_NONE, &instruction_section, &system_st); - add_sym("JMP", I_JMP, OC_1GEN, &instruction_section, &system_st); - add_sym("JSR", I_JSR, OC_JSR, &instruction_section, &system_st); - add_sym("MARK", I_MARK, OC_MARK, &instruction_section, &system_st); - add_sym("MED6X", I_MED6X, OC_NONE, &instruction_section, &system_st); - add_sym("MED74C", I_MED74C, OC_NONE, &instruction_section, &system_st); - add_sym("MFPD", I_MFPD, OC_1GEN, &instruction_section, &system_st); - add_sym("MFPI", I_MFPI, OC_1GEN, &instruction_section, &system_st); - add_sym("MFPS", I_MFPS, OC_1GEN, &instruction_section, &system_st); - add_sym("MOV", I_MOV, OC_2GEN, &instruction_section, &system_st); - add_sym("MOVB", I_MOVB, OC_2GEN, &instruction_section, &system_st); - add_sym("MTPD", I_MTPD, OC_1GEN, &instruction_section, &system_st); - add_sym("MTPI", I_MTPI, OC_1GEN, &instruction_section, &system_st); - add_sym("MTPS", I_MTPS, OC_1GEN, &instruction_section, &system_st); - add_sym("MUL", I_MUL, OC_ASH, &instruction_section, &system_st); - add_sym("NEG", I_NEG, OC_1GEN, &instruction_section, &system_st); - add_sym("NEGB", I_NEGB, OC_1GEN, &instruction_section, &system_st); - add_sym("NOP", I_NOP, OC_NONE, &instruction_section, &system_st); - add_sym("RESET", I_RESET, OC_NONE, &instruction_section, &system_st); - add_sym("RETURN", I_RETURN, OC_NONE, &instruction_section, &system_st); - add_sym("ROL", I_ROL, OC_1GEN, &instruction_section, &system_st); - add_sym("ROLB", I_ROLB, OC_1GEN, &instruction_section, &system_st); - add_sym("ROR", I_ROR, OC_1GEN, &instruction_section, &system_st); - add_sym("RORB", I_RORB, OC_1GEN, &instruction_section, &system_st); - add_sym("RTI", I_RTI, OC_NONE, &instruction_section, &system_st); - add_sym("RTS", I_RTS, OC_1REG, &instruction_section, &system_st); - add_sym("RTT", I_RTT, OC_NONE, &instruction_section, &system_st); - add_sym("SBC", I_SBC, OC_1GEN, &instruction_section, &system_st); - add_sym("SBCB", I_SBCB, OC_1GEN, &instruction_section, &system_st); - add_sym("SCC", I_SCC, OC_NONE, &instruction_section, &system_st); - add_sym("SEC", I_SEC, OC_NONE, &instruction_section, &system_st); - add_sym("SEN", I_SEN, OC_NONE, &instruction_section, &system_st); - add_sym("SEV", I_SEV, OC_NONE, &instruction_section, &system_st); - add_sym("SEZ", I_SEZ, OC_NONE, &instruction_section, &system_st); - add_sym("SOB", I_SOB, OC_SOB, &instruction_section, &system_st); - add_sym("SPL", I_SPL, OC_1REG, &instruction_section, &system_st); - add_sym("SUB", I_SUB, OC_2GEN, &instruction_section, &system_st); - add_sym("SWAB", I_SWAB, OC_1GEN, &instruction_section, &system_st); - add_sym("SXT", I_SXT, OC_1GEN, &instruction_section, &system_st); - add_sym("TRAP", I_TRAP, OC_MARK, &instruction_section, &system_st); - add_sym("TST", I_TST, OC_1GEN, &instruction_section, &system_st); - add_sym("TSTB", I_TSTB, OC_1GEN, &instruction_section, &system_st); - add_sym("WAIT", I_WAIT, OC_NONE, &instruction_section, &system_st); - add_sym("XFC", I_XFC, OC_NONE, &instruction_section, &system_st); - add_sym("XOR", I_XOR, OC_JSR, &instruction_section, &system_st); - add_sym("MFPT", I_MFPT, OC_NONE, &instruction_section, &system_st); - - add_sym("ABSD", I_ABSD, OC_1GEN, &instruction_section, &system_st); - add_sym("ABSF", I_ABSF, OC_1GEN, &instruction_section, &system_st); - add_sym("ADDD", I_ADDD, OC_1FIS, &instruction_section, &system_st); - add_sym("ADDF", I_ADDF, OC_1FIS, &instruction_section, &system_st); - add_sym("CFCC", I_CFCC, OC_NONE, &instruction_section, &system_st); - add_sym("CLRD", I_CLRD, OC_1GEN, &instruction_section, &system_st); - add_sym("CLRF", I_CLRF, OC_1GEN, &instruction_section, &system_st); - add_sym("CMPD", I_CMPD, OC_1FIS, &instruction_section, &system_st); - add_sym("CMPF", I_CMPF, OC_1FIS, &instruction_section, &system_st); - add_sym("DIVD", I_DIVD, OC_1FIS, &instruction_section, &system_st); - add_sym("DIVF", I_DIVF, OC_1FIS, &instruction_section, &system_st); - add_sym("LDCDF", I_LDCDF, OC_1FIS, &instruction_section, &system_st); - add_sym("LDCID", I_LDCID, OC_1FIS, &instruction_section, &system_st); - add_sym("LDCIF", I_LDCIF, OC_1FIS, &instruction_section, &system_st); - add_sym("LDCLD", I_LDCLD, OC_1FIS, &instruction_section, &system_st); - add_sym("LDCLF", I_LDCLF, OC_1FIS, &instruction_section, &system_st); - add_sym("LDD", I_LDD, OC_1FIS, &instruction_section, &system_st); - add_sym("LDEXP", I_LDEXP, OC_1FIS, &instruction_section, &system_st); - add_sym("LDF", I_LDF, OC_1FIS, &instruction_section, &system_st); - add_sym("LDFPS", I_LDFPS, OC_1GEN, &instruction_section, &system_st); - add_sym("MODD", I_MODD, OC_1FIS, &instruction_section, &system_st); - add_sym("MODF", I_MODF, OC_1FIS, &instruction_section, &system_st); - add_sym("MULD", I_MULD, OC_1FIS, &instruction_section, &system_st); - add_sym("MULF", I_MULF, OC_1FIS, &instruction_section, &system_st); - add_sym("NEGD", I_NEGD, OC_1GEN, &instruction_section, &system_st); - add_sym("NEGF", I_NEGF, OC_1GEN, &instruction_section, &system_st); - add_sym("SETD", I_SETD, OC_NONE, &instruction_section, &system_st); - add_sym("SETF", I_SETF, OC_NONE, &instruction_section, &system_st); - add_sym("SETI", I_SETI, OC_NONE, &instruction_section, &system_st); - add_sym("SETL", I_SETL, OC_NONE, &instruction_section, &system_st); - add_sym("STA0", I_STA0, OC_NONE, &instruction_section, &system_st); - add_sym("STB0", I_STB0, OC_NONE, &instruction_section, &system_st); - add_sym("STCDF", I_STCDF, OC_2FIS, &instruction_section, &system_st); - add_sym("STCDI", I_STCDI, OC_2FIS, &instruction_section, &system_st); - add_sym("STCDL", I_STCDL, OC_2FIS, &instruction_section, &system_st); - add_sym("STCFD", I_STCFD, OC_2FIS, &instruction_section, &system_st); - add_sym("STCFI", I_STCFI, OC_2FIS, &instruction_section, &system_st); - add_sym("STCFL", I_STCFL, OC_2FIS, &instruction_section, &system_st); - add_sym("STD", I_STD, OC_2FIS, &instruction_section, &system_st); - add_sym("STEXP", I_STEXP, OC_2FIS, &instruction_section, &system_st); - add_sym("STF", I_STF, OC_2FIS, &instruction_section, &system_st); - add_sym("STFPS", I_STFPS, OC_1GEN, &instruction_section, &system_st); - add_sym("STST", I_STST, OC_1GEN, &instruction_section, &system_st); - add_sym("SUBD", I_SUBD, OC_1FIS, &instruction_section, &system_st); - add_sym("SUBF", I_SUBF, OC_1FIS, &instruction_section, &system_st); - add_sym("TSTD", I_TSTD, OC_1GEN, &instruction_section, &system_st); - add_sym("TSTF", I_TSTF, OC_1GEN, &instruction_section, &system_st); - - /* FIXME: The CIS instructions are missing! */ - - add_sym(current_section->label, 0, 0, current_section, §ion_st); -} - -/* dump_all_macros is a diagnostic function that's currently not - used. I used it while debugging, and I haven't removed it. */ - -static void dump_all_macros(void) -{ - MACRO *mac; - SYMBOL_ITER iter; - - for(mac = (MACRO *)first_sym(¯o_st, &iter); - mac != NULL; mac = (MACRO *)next_sym(¯o_st, &iter)) - { - dumpmacro(mac, lstfile); - - printf("\n\n"); - } -} - -/* sym_hist is a diagnostic function that prints a histogram of the - hash table useage of a symbol table. I used this to try to tune - the hash function for better spread. It's not used now. */ - -static void sym_hist(SYMBOL_TABLE *st, char *name) -{ - int i; - SYMBOL *sym; - fprintf(lstfile, "Histogram for symbol table %s\n", name); - for(i = 0; i < 1023; i++) - { - fprintf(lstfile, "%4d: ", i); - for(sym = st->hash[i]; sym != NULL; sym = sym->next) - fputc('#', lstfile); - fputc('\n', lstfile); - } -} - -/* enable_tf is called by command argument parsing to enable and - disable named options. */ - -static void enable_tf(char *opt, int tf) -{ - if(strcmp(opt, "AMA") == 0) - enabl_ama = tf; - else if(strcmp(opt, "GBL") == 0) - enabl_gbl = tf; - else if(strcmp(opt, "ME") == 0) - list_me = tf; - else if(strcmp(opt, "BEX") == 0) - list_bex = tf; - else if(strcmp(opt, "MD") == 0) - list_md = tf; -} - -int main(int argc, char *argv[]) -{ - char *fnames[32]; - int nr_files = 0; - FILE *obj = NULL; - static char line[1024]; - TEXT_RLD tr; - char *macname = NULL; - char *objname = NULL; - char *lstname = NULL; - int arg; - int i; - STACK stack; - int count; - - for(arg = 1; arg < argc; arg++) - { - if(*argv[arg] == '-') - { - char *cp; - cp = argv[arg] + 1; - switch(tolower(*cp)) - { - case 'v': - fprintf(stderr, - "macro11 Copyright 2001 Richard Krehbiel\n" - "Version 0.2 July 15, 2001\n"); - break; - - case 'e': - /* Followed by options to enable */ - /* Since /SHOW and /ENABL option names don't overlap, - I consolidate. */ - upcase(argv[++arg]); - enable_tf(argv[arg], 1); - break; - - case 'd': - /* Followed by an option to disable */ - upcase(argv[++arg]); - enable_tf(argv[arg], 0); - break; - - case 'm': - /* Macro library */ - /* This option gives the name of an RT-11 compatible - macro library from which .MCALLed macros can be - found. */ - arg++; - mlbs[nr_mlbs] = mlb_open(argv[arg]); - if(mlbs[nr_mlbs] == NULL) - { - fprintf(stderr, - "Unable to register macro library %s\n", - argv[arg]); - exit(EXIT_FAILURE); - } - nr_mlbs++; - break; - - case 'p': /* P for search path */ - /* The -p option gives the name of a directory in - which .MCALLed macros may be found. */ - { - char *env = getenv("MCALL"); - char *temp; - - if(env == NULL) - env = ""; - - temp = memcheck(malloc(strlen(env) + - strlen(argv[arg+1]) + 8)); - strcpy(temp, "MCALL="); - strcat(temp, env); - strcat(temp, PATHSEP); - strcat(temp, argv[arg+1]); - putenv(temp); - arg++; - } - break; - - case 'o': - /* The -o option gives the object file name (.OBJ) */ - ++arg; - objname = argv[arg]; - break; - - case 'l': - /* The option -l gives the listing file name (.LST) */ - /* -l - enables listing to stdout. */ - lstname = argv[++arg]; - if(strcmp(lstname, "-") == 0) - lstfile = stdout; - else - lstfile = fopen(lstname, "w"); - break; - - case 'x': - /* The -x option invokes macro11 to expand the - contents of the registered macro libraries (see -m) - into individual .MAC files in the current - directory. No assembly of input is done. This - must be the last command line option. */ - { - int i; - for(i = 0; i < nr_mlbs; i++) - mlb_extract(mlbs[i]); - return EXIT_SUCCESS; - } - - default: - fprintf(stderr, "Unknown argument %s\n", argv[arg]); - exit(EXIT_FAILURE); - } - } - else - { - fnames[nr_files++] = argv[arg]; - } - } - - if(objname) - { - obj = fopen(objname, "wb"); - if(obj == NULL) - return EXIT_FAILURE; - } - - add_symbols(&blank_section); - - text_init(&tr, NULL, 0); - - module_name = memcheck(strdup("")); - - xfer_address = new_ex_lit(1); /* The undefined transfer address */ - - stack_init(&stack); - /* Push the files onto the input stream in reverse order */ - for(i = nr_files-1; i >= 0; --i) - { - STREAM *str = new_file_stream(fnames[i]); - if(str == NULL) - { - report(NULL, "Unable to open file %s\n", fnames[i]); - exit(EXIT_FAILURE); - } - stack_push(&stack, str); - } - - DOT = 0; - current_pc->section = &blank_section; - last_dot_section = NULL; - pass = 0; - stmtno = 0; - lsb = 0; - last_lsb = -1; - last_locsym = 32767; - last_cond = -1; - sect_sp = -1; - suppressed = 0; - - assemble_stack(&stack, &tr); - -#if 0 - if(enabl_debug) - dump_all_macros(); -#endif - - assert(stack.top == NULL); - - migrate_implicit(); /* Migrate the implicit globals */ - write_globals(obj); /* Write the global symbol dictionary */ - -#if 0 - sym_hist(&symbol_st, "symbol_st"); /* Draw a symbol table histogram */ -#endif - - - text_init(&tr, obj, 0); - - stack_init(&stack); /* Superfluous... */ - /* Re-push the files onto the input stream in reverse order */ - for(i = nr_files-1; i >= 0; --i) - { - STREAM *str = new_file_stream(fnames[i]); - if(str == NULL) - { - report(NULL, "Unable to open file %s\n", fnames[i]); - exit(EXIT_FAILURE); - } - stack_push(&stack, str); - } - - DOT = 0; - current_pc->section = &blank_section; - last_dot_section = NULL; - - pass = 1; - stmtno = 0; - lsb = 0; - last_lsb = -1; - last_locsym = 32767; - pop_cond(-1); - sect_sp = -1; - suppressed = 0; - - count = assemble_stack(&stack, &tr); - - text_flush(&tr); - - while(last_cond >= 0) - { - report(NULL, "%s:%d: Unterminated conditional\n", - conds[last_cond].file, conds[last_cond].line); - pop_cond(last_cond - 1); - count++; - } - - for(i = 0; i < nr_mlbs; i++) - mlb_close(mlbs[i]); - - write_endmod(obj); - - if(obj != NULL) - fclose(obj); - - if(count > 0) - fprintf(stderr, "%d Errors\n", count); - - if(lstfile && strcmp(lstname, "-") != 0) - fclose(lstfile); - - return count > 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/crossassemblers/macro11.old/macro11.dsp b/crossassemblers/macro11.old/macro11.dsp deleted file mode 100644 index 0a4ddfd..0000000 --- a/crossassemblers/macro11.old/macro11.dsp +++ /dev/null @@ -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 diff --git a/crossassemblers/macro11.old/macro11.dsw b/crossassemblers/macro11.old/macro11.dsw deleted file mode 100644 index 09378a5..0000000 --- a/crossassemblers/macro11.old/macro11.dsw +++ /dev/null @@ -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> -{{{ -}}} - -############################################################################### - diff --git a/crossassemblers/macro11.old/macro11.h b/crossassemblers/macro11.old/macro11.h deleted file mode 100644 index fd8d8f4..0000000 --- a/crossassemblers/macro11.old/macro11.h +++ /dev/null @@ -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 diff --git a/crossassemblers/macro11.old/makefile b/crossassemblers/macro11.old/makefile deleted file mode 100644 index 6e9d81c..0000000 --- a/crossassemblers/macro11.old/makefile +++ /dev/null @@ -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 diff --git a/crossassemblers/macro11.old/mlb.c b/crossassemblers/macro11.old/mlb.c deleted file mode 100644 index 32b5cb7..0000000 --- a/crossassemblers/macro11.old/mlb.c +++ /dev/null @@ -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 -#include -#include -#include - -#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); - } -} diff --git a/crossassemblers/macro11.old/mlb.h b/crossassemblers/macro11.old/mlb.h deleted file mode 100644 index 9ec4b68..0000000 --- a/crossassemblers/macro11.old/mlb.h +++ /dev/null @@ -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 */ diff --git a/crossassemblers/macro11.old/object.c b/crossassemblers/macro11.old/object.c deleted file mode 100644 index 2d97bbb..0000000 --- a/crossassemblers/macro11.old/object.c +++ /dev/null @@ -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 -#include -#include -#include - -#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); -} diff --git a/crossassemblers/macro11.old/object.h b/crossassemblers/macro11.old/object.h deleted file mode 100644 index 9411a03..0000000 --- a/crossassemblers/macro11.old/object.h +++ /dev/null @@ -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 */ diff --git a/crossassemblers/macro11.old/rad50.c b/crossassemblers/macro11.old/rad50.c deleted file mode 100644 index 6d6f2c5..0000000 --- a/crossassemblers/macro11.old/rad50.c +++ /dev/null @@ -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 -#include -#include - -#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] = ' '; -} diff --git a/crossassemblers/macro11.old/rad50.h b/crossassemblers/macro11.old/rad50.h deleted file mode 100644 index 9a60a01..0000000 --- a/crossassemblers/macro11.old/rad50.h +++ /dev/null @@ -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 */ diff --git a/crossassemblers/macro11.old/stream2.c b/crossassemblers/macro11.old/stream2.c deleted file mode 100644 index edfbcf2..0000000 --- a/crossassemblers/macro11.old/stream2.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#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; -} diff --git a/crossassemblers/macro11.old/stream2.h b/crossassemblers/macro11.old/stream2.h deleted file mode 100644 index 0c28440..0000000 --- a/crossassemblers/macro11.old/stream2.h +++ /dev/null @@ -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 */ diff --git a/crossassemblers/macro11.old/todo b/crossassemblers/macro11.old/todo deleted file mode 100644 index d922637..0000000 --- a/crossassemblers/macro11.old/todo +++ /dev/null @@ -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. - diff --git a/crossassemblers/macro11.old/util.c b/crossassemblers/macro11.old/util.c deleted file mode 100644 index 6d8320d..0000000 --- a/crossassemblers/macro11.old/util.c +++ /dev/null @@ -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 -#include -#include - -#include "util.h" - -#ifdef WIN32 -#include -#include -#define stat _stat -#else -#include -#include -#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. */ -} diff --git a/crossassemblers/macro11.old/util.h b/crossassemblers/macro11.old/util.h deleted file mode 100644 index d6e7790..0000000 --- a/crossassemblers/macro11.old/util.h +++ /dev/null @@ -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 */