home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
100-199
/
ff110.lzh
/
A68k
/
Adirect.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-10-28
|
19KB
|
646 lines
/*------------------------------------------------------------------*/
/* */
/* MC68000 Cross Assembler */
/* */
/* Copyright (c) 1985 by Brian R. Anderson */
/* */
/* Assembler directive processing - September 2, 1987 */
/* */
/* This program may be copied for personal, non-commercial use */
/* only, provided that the above copyright notice is included */
/* on all copies of the source code. Copying for any other use */
/* without the consent of the author is prohibited. */
/* */
/*------------------------------------------------------------------*/
/* */
/* Originally published (in Modula-2) in */
/* Dr. Dobb's Journal, April, May, and June 1986. */
/* */
/* AmigaDOS conversion copyright (c) 1987 by Charlie Gibbs. */
/* */
/*------------------------------------------------------------------*/
#include <stdio.h>
#include "a68kdef.h"
#include "a68kglb.h"
/* Functions */
extern int LineParts(), GetField(), Instructions();
extern int GetSize(), GetInstModeSize(), GetMultReg();
extern int ReadSymTab(), GetArgs(), GetAReg(), OpenIncl();
extern long AddrBndW(), AddrBndL(), GetValue(), CalcValue();
extern char *malloc();
extern FILE *fopen();
int ObjDir (f) FILE *f;
/* Generates Object Code for Assembler Directives */
{
register int i, j;
int oploc, dummy;
long newflags, templong;
char tempop[MAXLINE];
AddrAdv = 0;
if (strcmp (OpCode, "ORG") == 0) { /* ORG */
templong = GetValue (SrcOp, SrcLoc);
if (Hunk2 < 0)
Error (SrcLoc, RelErr); /* Can't ORG externally */
else if (DefLine2 > LineCount)
Error (SrcLoc, FwdRef); /* Illegal forward reference */
else {
AddrCnt = templong;
CurrHunk = Hunk2;
}
PrntAddr = TRUE;
return (Org);
}
if (strcmp (OpCode, "EQU") == 0) { /* EQU */
if (Label[0] == '\0')
Error (0, NeedLab); /* Need a label */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (DefLine2 > LineCount)
Error (SrcLoc, FwdRef); /* Illegal forward reference */
Src.Hunk = Hunk2;
PrntAddr = TRUE;
return (Equ);
}
if (strcmp (OpCode, "DC") == 0) { /* DC */
if ((Size == Word) || (Size == Long))
AddrCnt = AddrBndW (AddrCnt);
i = SrcLoc;
while ((Line[i] != ' ') && (Line[i] != '\0')) {
oploc = i;
if (Line[i] == '\'') { /* String */
i++; /* Skip over delimiter */
while (i < strlen(Line)) {
if (Line[i] == '\'') { /* End of string? */
i++; /* Check next character */
if (Line[i] != '\'')
break; /* End of string */
} /* Otherwise it's an apostrophe in string */
Src.Hunk = ABSHUNK; /* Absolute value */
ObjString[nX++] = Line[i++]; /* Current char. */
}
} else { /* Not a string constant */
i = GetField (Line, i, SrcOp);
ObjSrc = GetValue (SrcOp, oploc); /* Value */
if ((Src.Hunk = Hunk2) != ABSHUNK) { /* Hunk no. */
templong = AddrCnt + nX; /* Relocatable */
PutRel (Srec, templong, Hunk2, Size);
}
if (Size == 4) {
ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
}
if (Size >= 2)
ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
ObjString[nX++] = ObjSrc & 0x00FF;
}
if (Line[i] == ',')
i++; /* Skip over separator */
}
if ((Line[i] != '\0') && (Line[i] != ' '))
Error (i, OperErr); /* Didn't end properly */
AddrAdv = InstSize = nX;
PrntAddr = TRUE;
return (DC);
}
if (strcmp (OpCode, "DS") == 0) { /* DS */
AddrAdv = GetValue (SrcOp, SrcLoc);
if (Size == Word) { /* Words */
AddrCnt = AddrBndW (AddrCnt);
AddrAdv <<= 1;
}
if (Size == Long) { /* Long words */
AddrCnt = AddrBndW (AddrCnt);
AddrAdv <<= 2;
}
if (Pass2 && (HunkType != HunkBSS)) { /* If this isn't */
templong = AddrAdv; /* a BSS hunk, */
while (templong >= 4) { /* generate zeros */
AppendSdata (f, 0L, 4); /* to fill the area */
templong -= 4;
}
if (templong > 0) {
i = templong;
AppendSdata (f, 0L, i);
}
}
if (DestLoc != 0)
Error (DestLoc, OperErr); /* Only one operand is allowed */
PrntAddr = TRUE;
return (DS);
}
if (strcmp (OpCode, "EVEN") == 0) { /* EVEN */
AddrCnt = AddrBndW (AddrCnt);
PrntAddr = TRUE;
return (Even);
}
if (strcmp (OpCode, "END") == 0) { /* END */
PrntAddr = TRUE;
if (Pass2)
if (SrcOp[0] != '\0')
EndAddr = GetValue (SrcOp, SrcLoc);
else
EndAddr = 0;
return (End);
}
if (strcmp (OpCode, "XDEF") == 0) { /* XDEF */
if (SFormat)
Error (OpLoc, NotSFmt); /* Not in S-format */
i = SrcLoc;
while ((Line[i] != ' ') && (Line[i] != '\0')) {
oploc = i;
i = GetField (Line, i, SrcOp); /* Get a symbol */
if (ReadSymTab (SrcOp)) {
if (!Pass2) {
if ((Sym->Flags & 0x60) == 0)
Sym->Flags |= 2; /* Set XDEF flag */
} else {
AddRef (LineCount);
if (Sym->Defn == 0)
Error (oploc, Undef); /* Never got defined */
else if (Sym->Flags & 0x60)
Error (oploc, AddrErr); /* Can't XDEF a register */
}
} else if (!Pass2) { /* Not yet defined */
AddSymTab (SrcOp, 0L, CurrHunk, 0, 2);
}
if (Line[i] == ',')
i++; /* Skip over separator */
}
return (Xdef);
}
if (strcmp (OpCode, "XREF") == 0) { /* XREF */
if (SFormat)
Error (OpLoc, NotSFmt); /* Not in S-format */
i = SrcLoc;
while ((Line[i] != ' ') && (Line[i] != '\0')) {
oploc = i;
i = GetField (Line, i, SrcOp);
if (Pass2) {
if (ReadSymTab (SrcOp) && (Sym->Defn != LineCount)) {
AddRef (LineCount); /* Ignore extraneous XREF */
}
} else {
if (!ReadSymTab (SrcOp)) { /* Only if not */
templong = ~(HeapLim - Heap); /* defined */
templong &= 0x0000FFFF;
AddSymTab (SrcOp, 0L, templong, LineCount, 1);
}
}
if (Line[i] == ',')
i++; /* Skip over separator */
}
return (Xref);
}
if (strcmp (OpCode, "PAGE") == 0) { /* PAGE */
if (Pass2)
LnCnt = LnMax; /* Resume on a new page */
return (Page);
}
if (strcmp (OpCode, "LIST") == 0) { /* LIST */
ListOff = FALSE;
return (DoList);
}
if ((strcmp(OpCode,"NOLIST")==0) || (strcmp(OpCode,"NOL")==0)) {
ListOff = TRUE; /* NOLIST */
return (NoList);
}
if (strcmp (OpCode, "SPC") == 0) { /* SPC */
if (Pass2 && !ListOff && !SuppList) {
if (SrcOp[0] != '\0')
j = GetValue (SrcOp, SrcLoc); /* Amount to space */
else
j = 1; /* Default to one line */
for (i = 0; i < j; i++) {
if (LnCnt >= LnMax)
break; /* Page overflow */
fprintf (List, "\n"); /* Space one line */
}
}
return (Space);
}
if (strcmp (OpCode, "TTL") == 0) { /* TTL */
for (i = SrcLoc, j = 0; Line[i] != '\0'; i++) {
TTLstring[j++] = Line[i]; /* Get title string */
if (j >= MAXLINE - 1)
break; /* The string is full */
}
TTLstring[j] = '\0';
LnCnt = LnMax; /* Skip to a new page */
return (Title);
}
if (strcmp (OpCode, "CNOP") == 0) { /* CNOP */
i = TRUE; /* "Error-free" flag */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (DefLine2 > LineCount) {
Error (SrcLoc, FwdRef); /* Illegal forward reference */
i = FALSE;
}
if (Hunk2 != ABSHUNK) {
Error (SrcLoc, AbsReq); /* Must be absolute! */
i = FALSE;
}
ObjDest = GetValue (DestOp, DestLoc);
if (DefLine2 > LineCount) {
Error (DestLoc, FwdRef); /* Illegal forward reference */
i = FALSE;
}
if (Hunk2 != ABSHUNK) {
Error (DestLoc, AbsReq); /* Must be absolute! */
i = FALSE;
}
if ((ObjDest != 2) && (ObjDest != 4)) {
Error (DestLoc, OperErr); /* DestOp must be 2 or 4 */
i = FALSE;
}
if (((ObjSrc != 0) && (ObjSrc != 2)) || (ObjSrc >= ObjDest)) {
Error (SrcLoc, OperErr); /* SrcOp must be 0 or 2 */
i = FALSE;
}
if (i) { /* If no errors... */
AddrCnt = AddrBndW (AddrCnt);
if ((AddrCnt & 3L) != ObjSrc) { /* and not aligned */
ObjOp = NOP;
AddrAdv = InstSize = nO = 2; /* generate a NOP */
PrntAddr = TRUE;
}
}
return (Cnop);
}
if (strcmp (OpCode, "INCLUDE") == 0) { /* INCLUDE */
i = SrcLoc;
if ((Line[i]=='"') || (Line[i]=='\''))
i++; /* Ignore quotes */
j = 0;
while ((Line[i] != ' ')
&& (Line[i] != '"')
&& (Line[i] != '\'')
&& (Line[i] != '\0'))
tempop[j++] = Line[i++];
tempop[j] = '\0';
if (InF->UPtr == 0)
InF->Pos = ftell(InFile); /* Position in outer file */
if (!OpenIncl (tempop, InclList)) {
Error (SrcLoc, NoIncl); /* Couldn't open file */
if (InF->UPtr == 0) {
InFile = fopen (InF->NPtr, "r");
fseek (InFile, InF->Pos, 0);
}
return (Include); /* Return to outer file */
}
InFNum++; /* Bump nesting level */
if (--InF < LowInF)
LowInF = InF;
Heap2Space (strlen (tempop) + 1); /* Check for space */
InF->UPtr = 0; /* Not a user macro */
InF->NPtr = NextFNS; /* New stack pointer */
strcpy (NextFNS, tempop); /* File name */
NextFNS += strlen (tempop) + 1; /* Next available space */
if (NextFNS > High2)
High2 = NextFNS; /* Set high-water mark */
InF->NArg = -1; /* Flag as an INCLUDE */
InF->Line = 0; /* Clear line counter */
return (Include);
}
if (strcmp (OpCode, "SET") == 0) { /* SET */
if (Label[0] == '\0')
Error (0, NeedLab); /* Need a label */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (DefLine2 > LineCount)
Error (SrcLoc, FwdRef); /* Illegal forward reference */
Src.Hunk = Hunk2;
PrntAddr = TRUE;
if (!ReadSymTab (Label)) /* Make a new entry */
AddSymTab (Label, ObjSrc, Src.Hunk, LineCount, 4);
else if (Sym->Flags & 4) { /* Re-SET the symbol */
Sym->Val = ObjSrc; /* SET value */
Sym->Hunk = Src.Hunk; /* Hunk number */
Sym->Defn = LineCount; /* Statement number */
}
return (Set);
}
if (strcmp (OpCode, "MACRO") == 0) { /* MACRO */
Dir = Macro;
tempop[0] = ' ';
i = 0; /* Prepend name with a */
j = 1; /* blank and convert */
while (Label[i]) /* it to upper case */
tempop[j++] = toupper (Label[i++]);
tempop[j] = '\0';
if (!Pass2) { /* Pass 1 */
if (Label[0] != '\0') { /* Need a label */
templong = HeapLim - Heap; /* Offset to text */
if (!ReadSymTab (tempop)) /* Save MACRO name */
AddSymTab (tempop, 0L, templong, LineCount, 8);
AddMacLine (Line); /* Save MACRO stmt. */
while (strcmp (OpCode, "ENDM")) {
if (LineParts (dummy))
break; /* Premature EOF */
AddMacLine (Line); /* Store a line */
}
}
} else { /* Pass 2 */
if (Label[0] == '\0')
Error (0, NeedLab); /* Need a label */
else {
ReadSymTab (tempop);
if (Sym->Defn != LineCount) {
Error (0, DupMac); /* Duplicate MACRO */
AddRef (LineCount);
}
}
if (!SuppList)
WriteListLine (List); /* Echo MACRO */
while (1) {
if (LineParts (dummy)) {
Error (OpLoc, NoENDM); /* Premature EOF */
break;
} else {
if (strcmp (OpCode, "ENDM") == 0)
break;
if (!SuppList)
WriteListLine (List); /* Echo a line */
}
}
}
return (Macro);
}
if (strcmp (OpCode, "IFEQ") == 0) { /* IFEQ */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (ObjSrc != 0)
SkipNest++; /* Skip to the next ENDC */
return (If);
}
if (strcmp (OpCode, "IFNE") == 0) { /* IFNE */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (ObjSrc == 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFGT") == 0) { /* IFGT */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (ObjSrc <= 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFGE") == 0) { /* IFGE */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (ObjSrc < 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFLT") == 0) { /* IFLT */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (ObjSrc >= 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFLE") == 0) { /* IFLE */
ObjSrc = GetValue (SrcOp, SrcLoc);
if (ObjSrc > 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFC") == 0) { /* IFC */
if (strcmp (SrcOp, DestOp) != 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFNC") == 0) { /* IFNC */
if (strcmp (SrcOp, DestOp) == 0)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFD") == 0) { /* IFD */
if (ReadSymTab (SrcOp))
AddRef (LineCount);
if (DefLine2 > LineCount)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "IFND") == 0) { /* IFND */
if (ReadSymTab (SrcOp))
AddRef (LineCount);
if (DefLine2 <= LineCount)
SkipNest++;
return (If);
}
if (strcmp (OpCode, "ENDC") == 0) /* ENDC */
return (EndC); /* Just ignore it */
if ((strcmp (OpCode, "CODE") == 0) /* CODE */
|| (strcmp (OpCode, "DATA") == 0) /* DATA */
|| (strcmp (OpCode, "BSS") == 0)) { /* BSS */
strcpy (DestOp, OpCode); /* Convert to corresponding */
strcpy (OpCode, "SECTION"); /* SECTION directive */
}
if (strcmp (OpCode, "SECTION") == 0) { /* SECTION */
if (SFormat)
Error (OpLoc, NotSFmt); /* Not in S-format */
PrntAddr = TRUE;
for (i = 0; DestOp[i]; i++) /* Convert section type */
DestOp[i] = toupper (DestOp[i]); /* to upper case */
if ((DestOp[0] == '\0') || (strcmp (DestOp, "CODE") == 0))
newflags = HunkCode; /* Code section */
else if (strcmp (DestOp, "DATA") == 0)
newflags = HunkData; /* Data section */
else if (strcmp (DestOp, "BSS") == 0)
newflags = HunkBSS; /* BSS section */
else {
Error (DestLoc, OperErr); /* Invalid type */
strcpy (DestOp, "CODE");
newflags = HunkCode; /* Make it CODE */
}
newflags <<= 16; /* Shift to high-order 16 bits */
tempop[0] = '\0';
j = DestLoc + strlen (DestOp); /* Check for flags */
if (Line[j] == ',') {
j++;
GetField (Line, j, tempop); /* Get specification */
for (i = 0; tempop[i]; i++) /* Convert to */
tempop[i] = toupper (tempop[i]); /* upper case */
if (strcmp (tempop, "CHIP") == 0)
newflags |= MEMF_CHIP; /* CHIP memory */
else if (strcmp (tempop, "FAST") == 0)
newflags |= MEMF_FAST; /* FAST memory */
else
Error (j, OperErr); /* Invalid */
}
if (SrcOp[0] == '\0') { /* Unnamed section */
if ((strcmp (DestOp, "DATA") == 0)
|| (strcmp (DestOp, "BSS") == 0)) {
Error (SrcLoc, NoSecNam); /* Must be named */
return (Section);
}
}
AddrCnt = AddrBndL (AddrCnt); /* Finish on long word */
strcpy (tempop, " "); /* Two leading blanks */
strcat (tempop, SrcOp); /* Section name */
if (ReadSymTab (tempop)) { /* Scan for section name */
if ((Sym->Hunk & 0xFFFF0000L) != (newflags & 0xFFFF0000L)) {
Error (DestLoc, WrongTyp); /* Continuation in a */
return (Section); /* different type */
}
if (HunkType != HunkNone) {
if (Pass2) {
AddRef (LineCount);
DumpSdata (Srec); /* Previous hunk's data */
if (!SFormat) {
templong = HunkEnd; /* End of */
putl (Srec, templong); /* previous hunk */
}
}
Sect->Val = AddrCnt; /* End of old section */
}
Sect = Sym; /* Point to new section */
SectLine = LineCount;
AddrCnt = SectStart = Sym->Val; /* Continuation */
TempAddr = StartAddr = AddrCnt;
CurrHunk = Sym->Hunk & 0x0000FFFFL; /* Hunk no. */
HunkType = (Sym->Hunk & 0x3FFF0000L) >> 16; /* Type */
HunkFlags = Sym->Hunk & 0xC0000000L; /* Flags */
if (Pass2 && !SFormat) { /* Start a new hunk */
templong = HunkName;
putl (f, templong);
if (SrcOp[0])
DumpName (f, SrcOp, 0L); /* Hunk name */
else
DumpName (f, " ", 0L);
putl (f, HunkType); /* Hunk type */
LenPos = ftell (f); /* Hunk length goes here */
putl (f, 0L); /* For now, set it to zero */
}
return (Section);
}
if (Pass2) {
Error (OpLoc, ManySect); /* Table overflowed in pass 1 */
return (Section);
}
if (NextHunk >= ABSHUNK) /* Set up a new table entry */
return (Section); /* Section table overflow */
if (HunkType != HunkNone)
Sect->Val = AddrCnt; /* End of old section */
AddrCnt = SectStart = 0L; /* Reset location counter */
TempAddr = StartAddr = AddrCnt;
HunkType = (newflags & 0x3FFF0000L) >> 16; /* Type */
HunkFlags = newflags & 0xC0000000L; /* Flags */
SectLine = LineCount; /* Starting line number */
CurrHunk = NextHunk++; /* Bump next hunk number */
newflags |= CurrHunk; /* Add hunk number */
AddSymTab (tempop, 0L, newflags, LineCount, 16); /* New entry */
Sect = Sym; /* Pointer to new entry */
return (Section);
}
if (strcmp (OpCode, "IDNT") == 0) { /* IDNT */
i = SrcLoc;
if (Line[i] == '"')
i++; /* Ignore quotation marks */
j = 0;
while ((Line[i] != ' ') && (Line[i] != '"') && (Line[i] != '\0'))
IdntName[j++] = Line[i++];
IdntName[j] = '\0';
return (Idnt);
}
if (strcmp (OpCode, "DCB") == 0) { /* DCB */
if ((Size == Word) || (Size == Long))
AddrCnt = AddrBndW (AddrCnt);
ObjSrc = GetValue (SrcOp, SrcLoc); /* Replication factor */
if (DefLine2 > LineCount) {
Error (SrcLoc, FwdRef); /* Illegal forward reference */
ObjSrc = 0;
}
if (Hunk2 != ABSHUNK) {
Error (SrcLoc, AbsReq); /* Must be absolute! */
ObjSrc = 0;
}
ObjDest = GetValue (DestOp, DestLoc); /* Value to replicate */
Dest.Hunk = Hunk2;
for (i = 0; i < ObjSrc; i++) {
if (nX >= MAXLINE) {
Error (SrcLoc, DCOflo); /* ObjString overflowed */
break;
}
if (Dest.Hunk != ABSHUNK) {
templong = AddrCnt + nX; /* Relocatable */
PutRel (Srec, templong, Hunk2, Size);
}
if (Size == 4) {
ObjString[nX++] = (ObjDest >> 24) & 0x00FF;
ObjString[nX++] = (ObjDest >> 16) & 0x00FF;
}
if (Size >= 2)
ObjString[nX++] = (ObjDest >> 8) & 0x00FF;
ObjString[nX++] = ObjDest & 0x00FF;
}
AddrAdv = InstSize = nX;
PrntAddr = TRUE;
return (DCB);
}
if (strcmp (OpCode, "EQUR") == 0) { /* EQUR */
if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
Error (SrcLoc, AddrErr); /* Not a valid register */
if (Label[0] == '\0')
Error (0, NeedLab); /* Need a label */
else {
if (!ReadSymTab (Label)) /* Make a new entry */
AddSymTab (Label, (long) i, 0L, LineCount, 0x20);
GotEqur = TRUE; /* We have at least one EQUR */
}
return (Equr);
}
if (strcmp (OpCode, "REG") == 0) { /* REG */
if (Label[0] == '\0')
Error (0, NeedLab); /* Need a label */
else {
i = GetMultReg (SrcOp, FALSE, SrcLoc);
if (!ReadSymTab (Label)) /* Make a new entry */
AddSymTab (Label, (long) i, 0L, LineCount, 0x40);
GotEqur = TRUE; /* We have at least one EQUR */
}
return (Reg);
}
return (None); /* Not a directive */
}