Initial commit from macross.tar.gz

MD5 (macross.tar.gz) = 4ecb4a6e015b11fef043fe78d1eedb61
This commit is contained in:
Michael Steil 2014-05-03 22:20:34 -07:00
commit 98a36557e4
143 changed files with 36916 additions and 0 deletions

1
.mark Normal file
View File

@ -0,0 +1 @@
Mon Feb 2 23:18:33 PST 1987

34
DOC Normal file
View File

@ -0,0 +1,34 @@
/u0/chip/macross:
This directory contains the source to Macross. Here's what's here:
DOC - this file
Makefile - current makefile
Makefile_6502 - makefile for 6502 version
Makefile_68000 - makefile for 68000
There are both 6502 and 68000 versions of Macross, though the 68000
version has not been very well tested. Source for both is here. Source files
which come in different flavors for the different versions are marked 6502 or
68000 in their names as appropriate. There are two different Makefiles also.
At any given time, either the 6502 version or the 68000 version is the
'working' version. The 'working' version is what the default makefile
'Makefile' will produce. Typing 'make foobar' will change the working version
by swapping the makefiles.
*.c, *.h, *.y - source for the program
doc/ - the manual and other user documentation are here
notes68/ - notes on 68000 syntax and operand structure
opt/ - working directory for 'optimized' version. When I
was developing the program, I needed to keep two separate copies of
the source and object code. This is because the C compiler can
compile with debugging or with optimization, but not both. The
version that folks use needs to be compiled with optimization, but I
need a version with debugging to fix any problems that crop up. Since
the time to recompile the whole thing is so enormous, it was easiest
to keep two copies. In the interest of saving file space, all that is
in this directory now, however, are the Makefiles for compiling with
optimization.
slinky/ - Slinky lives here

164
Makefile Normal file
View File

@ -0,0 +1,164 @@
.SUFFIXES: .o .c .h .run
# to make for another target CPU, redefine PROC to the name of the target
# processor, e.g., 68000
PROC =6502
OBJECTS = y.tab.o actions.o buildStuff1.o buildStuff2.o\
buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o\
emitBranch.o emitStuff.o encode.o errorStuff.o expressionSemantics.o fixups.o\
garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o\
malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o\
statementSemantics.o structSemantics.o tokenStrings.o
SOURCES = macross_$(PROC).y actions_$(PROC).c buildStuff1.c buildStuff2.c\
buildStuff3.c builtInFunctions.c builtInFunsSD_$(PROC).c debugPrint.c\
debugPrintSD_$(PROC).c emitBranch_$(PROC).c emitStuff.c encode.c errorStuff.c\
expressionSemantics.c fixups.c garbage.c initialize.c lexer.c listing.c\
lookups.c macrossTables_$(PROC).c main.c malloc.c object.c\
operandStuffSD_$(PROC).c parserMisc.c semanticMisc.c statementSemantics.c\
structSemantics.c tokenStrings_$(PROC).c lexerTables.h macrossGlobals.h\
macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h driver.c slinkyExpressions.h
HEADERS = macrossTypes.h macrossGlobals.h
.c.o:
cc -c -g -DTARGET_CPU=CPU_$(PROC) $*.c
.c.run:
cc -o $* $*.c
macross: $(OBJECTS)
cc -g -o macross $(OBJECTS)
driver: driver.c
cc -o driver driver.c
update: .mark
kessel "(cd /u0/chip/macross; make macross >&errorfyle)" &
install: macross
cp macross /u1/gg/bin/macross_tmp
strip /u1/gg/bin/macross_tmp
mv /u1/gg/bin/macross_$(PROC) /u1/gg/bin/macross_$(PROC).old
mv /u1/gg/bin/macross_tmp /u1/gg/bin/macross_$(PROC)
cp /u1/gg/bin/macross_$(PROC) /net/mycroft/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/shem/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/weyr/u1/gg/bin
dinstall: driver
cp driver /u1/gg/bin/driver_tmp
strip /u1/gg/bin/driver_tmp
mv /u1/gg/bin/driver_tmp /u1/gg/bin/driver/macross
cp /u1/gg/bin/driver /net/mycroft/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/shem/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/weyr/u1/gg/bin/macross
change:
rm *.o
rm *.tab.*
cp Makefile_68000 Makefile
move: .mark
.mark: $(SOURCES)
cp $? /net/kessel/u0/chip/macross
cp $? /net/kessel/u0/chip/macross/prof
cp $? opt
date >.mark
date >/net/kessel/u0/chip/macross/.mark
date >/net/kessel/u0/chip/macross/prof/.mark
date >opt/.mark
macrossTypes.h: macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h
actions.o: actions_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) actions_$(PROC).c
mv actions_$(PROC).o actions.o
buildStuff1.o: buildStuff1.c $(HEADERS)
buildStuff2.o: buildStuff2.c $(HEADERS)
buildStuff3.o: buildStuff3.c $(HEADERS)
builtInFunctions.o: builtInFunctions.c $(HEADERS)
builtInFunsSD.o: builtInFunsSD_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) builtInFunsSD_$(PROC).c
mv builtInFunsSD_$(PROC).o builtInFunsSD.o
debugPrint.o: debugPrint.c y.tab.h $(HEADERS)
debugPrintSD.o: debugPrintSD_$(PROC).c y.tab.h $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) debugPrintSD_$(PROC).c
mv debugPrintSD_$(PROC).o debugPrintSD.o
emitBranch.o: emitBranch_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) emitBranch_$(PROC).c
mv emitBranch_$(PROC).o emitBranch.o
emitStuff.o: emitStuff.c $(HEADERS)
cc -c -g -DBYTESWAPPED -DTARGET_CPU=CPU_$(PROC) emitStuff.c
encode.o: encode.c $(HEADERS)
errorStuff.o: errorStuff.c $(HEADERS)
expressionSemantics.o: expressionSemantics.c y.tab.h $(HEADERS)
fixups.o: fixups.c $(HEADERS)
garbage.o: garbage.c y.tab.h $(HEADERS)
initialize.o: initialize.c $(HEADERS)
lexer.o: lexer.c lexerTables.h y.tab.h $(HEADERS)
listing.o: listing.c $(HEADERS)
lookups.o: lookups.c $(HEADERS)
macrossTables.o: macrossTables_$(PROC).c y.tab.h macrossTypes.h
cc -c -g -DTARGET_CPU=CPU_$(PROC) macrossTables_$(PROC).c
mv macrossTables_$(PROC).o macrossTables.o
malloc.o: malloc.c
main.o: main.c $(HEADERS)
object.o: object.c $(HEADERS)
operandStuffSD.o: operandStuffSD_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) operandStuffSD_$(PROC).c
mv operandStuffSD_$(PROC).o operandStuffSD.o
parserMisc.o: parserMisc.c y.tab.h $(HEADERS)
semanticMisc.o: semanticMisc.c $(HEADERS)
statementSemantics.o: statementSemantics.c $(HEADERS)
structSemantics.o: structSemantics.c $(HEADERS)
tokenStrings.o: tokenStrings_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) tokenStrings_$(PROC).c
mv tokenStrings_$(PROC).o tokenStrings.o
y.tab.o: y.tab.c $(HEADERS)
cc -c -g -DYYDEBUG -DTARGET_CPU=CPU_$(PROC) y.tab.c
y.tab.c y.tab.h: macross_$(PROC).y
yacc -d macross_$(PROC).y
y.output: macross_$(PROC).y
yacc -vd macross_$(PROC).y
cleanup:
/bin/rm -f *.o y.output y.tab.c y.tab.h macross
love:
@echo "Not war?"

162
Makefile_6502 Normal file
View File

@ -0,0 +1,162 @@
.SUFFIXES: .o .c .h .run
# to make for another target CPU, redefine PROC to the name of the target
# processor, e.g., 68000
PROC =6502
OBJECTS = y.tab.o actions.o buildStuff1.o buildStuff2.o\
buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o\
emitBranch.o emitStuff.o errorStuff.o expressionSemantics.o fixups.o\
garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o\
malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o\
statementSemantics.o structSemantics.o tokenStrings.o
SOURCES = macross_$(PROC).y actions_$(PROC).c buildStuff1.c buildStuff2.c\
buildStuff3.c builtInFunctions.c builtInFunsSD_$(PROC).c debugPrint.c\
debugPrintSD_$(PROC).c emitBranch_$(PROC).c emitStuff.c errorStuff.c\
expressionSemantics.c fixups.c garbage.c initialize.c lexer.c listing.c\
lookups.c macrossTables_$(PROC).c main.c malloc.c object.c\
operandStuffSD_$(PROC).c parserMisc.c semanticMisc.c statementSemantics.c\
structSemantics.c tokenStrings_$(PROC).c lexerTables.h macrossGlobals.h\
macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h driver.c
HEADERS = macrossTypes.h macrossGlobals.h
.c.o:
cc -c -g -DTARGET_CPU=CPU_$(PROC) $*.c
.c.run:
cc -o $* $*.c
macross: $(OBJECTS)
cc -g -o macross $(OBJECTS)
driver: driver.c
cc -o driver driver.c
update: .mark
kessel "(cd /u0/chip/macross; make macross >&errorfyle)" &
install: macross
cp macross /u1/gg/bin/macross_tmp
strip /u1/gg/bin/macross_tmp
mv /u1/gg/bin/macross_$(PROC) /u1/gg/bin/macross_$(PROC).old
mv /u1/gg/bin/macross_tmp /u1/gg/bin/macross_$(PROC)
cp /u1/gg/bin/macross_$(PROC) /net/mycroft/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/shem/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/weyr/u1/gg/bin
dinstall: driver
cp driver /u1/gg/bin/driver_tmp
strip /u1/gg/bin/driver_tmp
mv /u1/gg/bin/driver_tmp /u1/gg/bin/driver/macross
cp /u1/gg/bin/driver /net/mycroft/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/shem/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/weyr/u1/gg/bin/macross
change:
rm *.o
rm *.tab.*
cp Makefile_68000 Makefile
move: .mark
.mark: $(SOURCES)
cp $? /net/kessel/u0/chip/macross
cp $? /net/kessel/u0/chip/macross/prof
cp $? opt
date >.mark
date >/net/kessel/u0/chip/macross/.mark
date >/net/kessel/u0/chip/macross/prof/.mark
date >opt/.mark
macrossTypes.h: macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h
actions.o: actions_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) actions_$(PROC).c
mv actions_$(PROC).o actions.o
buildStuff1.o: buildStuff1.c $(HEADERS)
buildStuff2.o: buildStuff2.c $(HEADERS)
buildStuff3.o: buildStuff3.c $(HEADERS)
builtInFunctions.o: builtInFunctions.c $(HEADERS)
builtInFunsSD.o: builtInFunsSD_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) builtInFunsSD_$(PROC).c
mv builtInFunsSD_$(PROC).o builtInFunsSD.o
debugPrint.o: debugPrint.c y.tab.h $(HEADERS)
debugPrintSD.o: debugPrintSD_$(PROC).c y.tab.h $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) debugPrintSD_$(PROC).c
mv debugPrintSD_$(PROC).o debugPrintSD.o
emitBranch.o: emitBranch_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) emitBranch_$(PROC).c
mv emitBranch_$(PROC).o emitBranch.o
emitStuff.o: emitStuff.c $(HEADERS)
cc -c -g -DBYTESWAPPED -DTARGET_CPU=CPU_$(PROC) emitStuff.c
errorStuff.o: errorStuff.c $(HEADERS)
expressionSemantics.o: expressionSemantics.c y.tab.h $(HEADERS)
fixups.o: fixups.c $(HEADERS)
garbage.o: garbage.c y.tab.h $(HEADERS)
initialize.o: initialize.c $(HEADERS)
lexer.o: lexer.c lexerTables.h y.tab.h $(HEADERS)
listing.o: listing.c $(HEADERS)
lookups.o: lookups.c $(HEADERS)
macrossTables.o: macrossTables_$(PROC).c y.tab.h macrossTypes.h
cc -c -g -DTARGET_CPU=CPU_$(PROC) macrossTables_$(PROC).c
mv macrossTables_$(PROC).o macrossTables.o
malloc.o: malloc.c
main.o: main.c $(HEADERS)
object.o: object.c $(HEADERS)
operandStuffSD.o: operandStuffSD_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) operandStuffSD_$(PROC).c
mv operandStuffSD_$(PROC).o operandStuffSD.o
parserMisc.o: parserMisc.c y.tab.h $(HEADERS)
semanticMisc.o: semanticMisc.c $(HEADERS)
statementSemantics.o: statementSemantics.c $(HEADERS)
structSemantics.o: structSemantics.c $(HEADERS)
tokenStrings.o: tokenStrings_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) tokenStrings_$(PROC).c
mv tokenStrings_$(PROC).o tokenStrings.o
y.tab.o: y.tab.c $(HEADERS)
cc -c -g -DYYDEBUG -DTARGET_CPU=CPU_$(PROC) y.tab.c
y.tab.c y.tab.h: macross_$(PROC).y
yacc -d macross_$(PROC).y
y.output: macross_$(PROC).y
yacc -vd macross_$(PROC).y
cleanup:
/bin/rm -f *.o y.output y.tab.c y.tab.h macross
love:
@echo "Not war?"

162
Makefile_68000 Normal file
View File

@ -0,0 +1,162 @@
.SUFFIXES: .o .c .h .run
# to make for another target CPU, redefine PROC to the name of the target
# processor, e.g., 68000
PROC =68000
OBJECTS = y.tab.o actions.o buildStuff1.o buildStuff2.o\
buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o\
emitBranch.o emitStuff.o errorStuff.o expressionSemantics.o fixups.o\
garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o\
malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o\
statementSemantics.o structSemantics.o tokenStrings.o
SOURCES = macross_$(PROC).y actions_$(PROC).c buildStuff1.c buildStuff2.c\
buildStuff3.c builtInFunctions.c builtInFunsSD_$(PROC).c debugPrint.c\
debugPrintSD_$(PROC).c emitBranch_$(PROC).c emitStuff.c errorStuff.c\
expressionSemantics.c fixups.c garbage.c initialize.c lexer.c listing.c\
lookups.c macrossTables_$(PROC).c main.c malloc.c object.c\
operandStuffSD_$(PROC).c parserMisc.c semanticMisc.c statementSemantics.c\
structSemantics.c tokenStrings_$(PROC).c lexerTables.h macrossGlobals.h\
macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h driver.c
HEADERS = macrossTypes.h macrossGlobals.h
.c.o:
cc -c -g -DTARGET_CPU=CPU_$(PROC) $*.c
.c.run:
cc -o $* $*.c
macross: $(OBJECTS)
cc -g -o macross $(OBJECTS)
driver: driver.c
cc -o driver driver.c
update: .mark
kessel "(cd /u0/chip/macross; make macross >&errorfyle)" &
install: macross
cp macross /u1/gg/bin/macross_tmp
strip /u1/gg/bin/macross_tmp
mv /u1/gg/bin/macross_$(PROC) /u1/gg/bin/macross_$(PROC).old
mv /u1/gg/bin/macross_tmp /u1/gg/bin/macross_$(PROC)
cp /u1/gg/bin/macross_$(PROC) /net/mycroft/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/shem/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/weyr/u1/gg/bin
dinstall: driver
cp driver /u1/gg/bin/driver_tmp
strip /u1/gg/bin/driver_tmp
mv /u1/gg/bin/driver_tmp /u1/gg/bin/driver/macross
cp /u1/gg/bin/driver /net/mycroft/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/shem/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/weyr/u1/gg/bin/macross
change:
rm *.o
rm *.tab.*
cp Makefile_6502 Makefile
move: .mark
.mark: $(SOURCES)
cp $? /net/kessel/u0/chip/macross
cp $? /net/kessel/u0/chip/macross/prof
cp $? opt
date >.mark
date >/net/kessel/u0/chip/macross/.mark
date >/net/kessel/u0/chip/macross/prof/.mark
date >opt/.mark
macrossTypes.h: macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h
actions.o: actions_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) actions_$(PROC).c
mv actions_$(PROC).o actions.o
buildStuff1.o: buildStuff1.c $(HEADERS)
buildStuff2.o: buildStuff2.c $(HEADERS)
buildStuff3.o: buildStuff3.c $(HEADERS)
builtInFunctions.o: builtInFunctions.c $(HEADERS)
builtInFunsSD.o: builtInFunsSD_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) builtInFunsSD_$(PROC).c
mv builtInFunsSD_$(PROC).o builtInFunsSD.o
debugPrint.o: debugPrint.c y.tab.h $(HEADERS)
debugPrintSD.o: debugPrintSD_$(PROC).c y.tab.h $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) debugPrintSD_$(PROC).c
mv debugPrintSD_$(PROC).o debugPrintSD.o
emitBranch.o: emitBranch_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) emitBranch_$(PROC).c
mv emitBranch_$(PROC).o emitBranch.o
emitStuff.o: emitStuff.c $(HEADERS)
cc -c -g -DBYTESWAPPED -DTARGET_CPU=CPU_$(PROC) emitStuff.c
errorStuff.o: errorStuff.c $(HEADERS)
expressionSemantics.o: expressionSemantics.c y.tab.h $(HEADERS)
fixups.o: fixups.c $(HEADERS)
garbage.o: garbage.c y.tab.h $(HEADERS)
initialize.o: initialize.c $(HEADERS)
lexer.o: lexer.c lexerTables.h y.tab.h $(HEADERS)
listing.o: listing.c $(HEADERS)
lookups.o: lookups.c $(HEADERS)
macrossTables.o: macrossTables_$(PROC).c y.tab.h macrossTypes.h
cc -c -g -DTARGET_CPU=CPU_$(PROC) macrossTables_$(PROC).c
mv macrossTables_$(PROC).o macrossTables.o
malloc.o: malloc.c
main.o: main.c $(HEADERS)
object.o: object.c $(HEADERS)
operandStuffSD.o: operandStuffSD_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) operandStuffSD_$(PROC).c
mv operandStuffSD_$(PROC).o operandStuffSD.o
parserMisc.o: parserMisc.c y.tab.h $(HEADERS)
semanticMisc.o: semanticMisc.c $(HEADERS)
statementSemantics.o: statementSemantics.c $(HEADERS)
structSemantics.o: structSemantics.c $(HEADERS)
tokenStrings.o: tokenStrings_$(PROC).c $(HEADERS)
cc -c -g -DTARGET_CPU=CPU_$(PROC) tokenStrings_$(PROC).c
mv tokenStrings_$(PROC).o tokenStrings.o
y.tab.o: y.tab.c $(HEADERS)
cc -c -g -DYYDEBUG -DTARGET_CPU=CPU_$(PROC) y.tab.c
y.tab.c y.tab.h: macross_$(PROC).y
yacc -d macross_$(PROC).y
y.output: macross_$(PROC).y
yacc -vd macross_$(PROC).y
cleanup:
/bin/rm -f *.o y.output y.tab.c y.tab.h macross
love:
@echo "Not war?"

BIN
actions.o Normal file

Binary file not shown.

511
actions_6502.c Normal file
View File

@ -0,0 +1,511 @@
/*
actions.c -- Actions associated with various machine instruction
classes (6502 version).
Chip Morningstar -- Lucasfilm Ltd.
16-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#define operand (evaluatedOperands[0])
#define address (evaluatedOperands[0])->value
#define class (evaluatedOperands[0])->addressMode
#define binary opcode->opcode
/*
These routines are vectored off of the opcode lookup table. Each
instruction is of a particular category that defines which address modes
it accepts its operands in and what size (one byte or two) the operands
are. There is one "actionsXXXX" routine for each of these categories that
grabs the operand, checks the address mode, and emits the binary opcode
and operand.
*/
void
actionsDir1(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define ZERO_PAGE_ADDRESS_BIT 0x00
#define NON_ZERO_PAGE_ADDRESS_BIT 0x08
if(class==EXPRESSION_OPND && isByteAddress(operand) &&
isDefined(operand)){
emitByte(binary | ZERO_PAGE_ADDRESS_BIT);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | NON_ZERO_PAGE_ADDRESS_BIT);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
void
actionsDir2(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
if (wordCheck(address)) {
emitByte(binary);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
void
actionsDirIndir(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define DIRECT_ADDRESS_BIT 0x00
#define INDIRECT_ADDRESS_BIT 0x20
if (wordCheck(address)) {
if (class == INDIRECT_OPND)
emitByte(binary | INDIRECT_ADDRESS_BIT);
else
emitByte(binary | DIRECT_ADDRESS_BIT);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
void
actionsDirX1(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_X1 0x04
#define A_REGISTER_BITS_X1 0x08
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_X1 0x0C
#define X_INDEXED_ZERO_PAGE_BITS_X1 0x14
#define X_INDEXED_NON_ZERO_PAGE_BITS_X1 0x1C
if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_X1);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_X1);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class==X_INDEXED_OPND || class==X_SELECTED_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | X_INDEXED_ZERO_PAGE_BITS_X1);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | X_INDEXED_NON_ZERO_PAGE_BITS_X1);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else {
emitByte(binary | A_REGISTER_BITS_X1);
}
}
void
actionsDirX2(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_X2 0x00
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_X2 0x08
#define X_INDEXED_ZERO_PAGE_BITS_X2 0x10
#define X_INDEXED_NON_ZERO_PAGE_BITS_X2 0x18
if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_X2);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_X2);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | X_INDEXED_ZERO_PAGE_BITS_X2);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | X_INDEXED_NON_ZERO_PAGE_BITS_X2);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
}
void
actionsDirX3(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_X2);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_X2);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else {
if (byteCheck(address)) {
emitByte(binary | X_INDEXED_ZERO_PAGE_BITS_X2);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
}
}
void
actionsDirY(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_Y 0x00
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_Y 0x08
#define Y_INDEXED_ZERO_PAGE_BITS_Y 0x10
if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_Y);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_Y);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else {
if (byteCheck(address)) {
emitByte(binary | Y_INDEXED_ZERO_PAGE_BITS_Y);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
}
}
void
actionsImmDir(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define IMMEDIATE_DATA_BITS_ID 0x00
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_ID 0x04
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_ID 0x0C
if (class == IMMEDIATE_OPND) {
if (byteCheck(address)) {
emitByte(binary | IMMEDIATE_DATA_BITS_ID);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
} else {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_ID);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_ID);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
}
void
actionsImmDirX(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define IMMEDIATE_DATA_BITS_IX 0x00
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_IX 0x04
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_IX 0x0C
#define X_INDEXED_ZERO_PAGE_BITS_IX 0x14
#define X_INDEXED_NON_ZERO_PAGE_BITS_IX 0x1C
if (class == IMMEDIATE_OPND) {
if (byteCheck(address)) {
emitByte(binary | IMMEDIATE_DATA_BITS_IX);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
} else if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_IX);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_IX);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | X_INDEXED_ZERO_PAGE_BITS_IX);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | X_INDEXED_NON_ZERO_PAGE_BITS_IX);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
}
void
actionsImmDirY(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define IMMEDIATE_DATA_BITS_IY 0x00
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_IY 0x04
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_IY 0x0C
#define Y_INDEXED_ZERO_PAGE_BITS_IY 0x14
#define Y_INDEXED_NON_ZERO_PAGE_BITS_IY 0x1C
if (class == IMMEDIATE_OPND) {
if (byteCheck(address)) {
emitByte(binary | IMMEDIATE_DATA_BITS_IY);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
} else if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_IY);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary|DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_IY);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | Y_INDEXED_ZERO_PAGE_BITS_IY);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | Y_INDEXED_NON_ZERO_PAGE_BITS_IY);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
}
}
void
actionsImmIndex(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
#define PRE_INDEXED_BITS_A 0x00
#define DIRECT_ADDRESS_ZERO_PAGE_BITS_A 0x04
#define IMMEDIATE_DATA_BITS_A 0x08
#define DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_A 0x0C
#define POST_INDEXED_BITS_A 0x10
#define X_INDEXED_ZERO_PAGE_BITS_A 0x14
#define Y_INDEXED_NON_ZERO_PAGE_BITS_A 0x18
#define X_INDEXED_NON_ZERO_PAGE_BITS_A 0x1C
if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_A);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary |DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_A);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class==X_INDEXED_OPND || class==X_SELECTED_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | X_INDEXED_ZERO_PAGE_BITS_A);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | X_INDEXED_NON_ZERO_PAGE_BITS_A);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class==Y_INDEXED_OPND || class==Y_SELECTED_OPND) {
if (wordCheck(address)) {
emitByte(binary | Y_INDEXED_NON_ZERO_PAGE_BITS_A);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class == IMMEDIATE_OPND) {
if (byteCheck(address)) {
emitByte(binary | IMMEDIATE_DATA_BITS_A);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
} else if (class == POST_INDEXED_Y_OPND) {
if (byteCheck(address)) {
emitByte(binary | POST_INDEXED_BITS_A);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
} else {
if (byteCheck(address)) {
emitByte(binary | PRE_INDEXED_BITS_A);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
}
}
void
actionsIndex(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
if (class == EXPRESSION_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | DIRECT_ADDRESS_ZERO_PAGE_BITS_A);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary |DIRECT_ADDRESS_NON_ZERO_PAGE_BITS_A);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class==X_INDEXED_OPND || class==X_SELECTED_OPND) {
if (isByteAddress(operand) && isDefined(operand)) {
emitByte(binary | X_INDEXED_ZERO_PAGE_BITS_A);
emitByte(address);
} else if (wordCheck(address)) {
emitByte(binary | X_INDEXED_NON_ZERO_PAGE_BITS_A);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class==Y_INDEXED_OPND || class==Y_SELECTED_OPND) {
if (wordCheck(address)) {
emitByte(binary | Y_INDEXED_NON_ZERO_PAGE_BITS_A);
putFixupsHere(WORD_FIXUP, 0);
emitWord(address);
}
} else if (class == POST_INDEXED_Y_OPND) {
if (byteCheck(address)) {
emitByte(binary | POST_INDEXED_BITS_A);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
} else {
if (byteCheck(address)) {
emitByte(binary | PRE_INDEXED_BITS_A);
putFixupsHere(BYTE_FIXUP, 0);
emitByte(address);
}
}
}
void
actionsNone(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
emitByte(binary);
}
void
actionsRelative(opcode, numberOfOperands, evaluatedOperands)
opcodeTableEntryType *opcode;
int numberOfOperands;
valueType *evaluatedOperands[];
{
int offset;
if (operand->kindOfValue == UNDEFINED_VALUE || (currentCodeMode ==
RELOCATABLE_BUFFER && targetOffset == 0))
offset = 0;
else
offset = address - (currentLocationCounter.value - targetOffset) - 1;
if (offset < 0)
offset--;
if (isByteOffset(offset)) {
emitByte(binary);
putFixupsHere(BYTE_RELATIVE_FIXUP, 0);
emitByte(offset);
} else {
error(RELATIVE_OFFSET_TOO_LARGE_ERROR);
}
}
/*
Miscellaneous helper predicates.
*/
bool
isByte(value)
int value;
{
return (-129<value && value<256);
}
bool
isByteOffset(value)
int value;
{
return (-129<value && value<128);
}
bool
isWordOffset(value)
int value;
{
return (-32769<value && value<32768);
}
bool
isByteAddress(value)
valueType *value;
{
return(value->kindOfValue==ABSOLUTE_VALUE && isByte(value->value));
}
bool
isWord(value)
int value;
{
return (-32769<value && value<65536);
}
bool
byteCheck(value)
int value;
{
if (isByte(value)) {
return(TRUE);
} else {
error(BYTE_VALUE_TOO_LARGE_ERROR, value);
return(FALSE);
}
}
bool
wordCheck(value)
int value;
{
if (isWord(value)) {
return(TRUE);
} else {
printf("word: %d\n", value);
error(WORD_VALUE_TOO_LARGE_ERROR, value);
return(FALSE);
}
}
bool
isDefined(value)
valueType *value;
{
return(value!=NULL && value->kindOfValue!=UNDEFINED_VALUE);
}

1089
actions_68000.c Normal file

File diff suppressed because it is too large Load Diff

547
buildStuff1.c Normal file
View File

@ -0,0 +1,547 @@
/*
buildStuff1.c -- Routines to build parse-tree structures for the
Macross assembler. This module is target processor
independent.
Chip Morningstar -- Lucasfilm Ltd.
1-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
symbolTableEntryType *lookupOrEnterSymbol();
char *saveString();
/* Generic routine to create statement nodes */
statementType *
newStatement(kind, body)
statementKindType kind;
statementBodyType body;
{
statementType *result;
result = typeAlloc(statementType);
result->kindOfStatement = kind;
result->labels = NULL;
result->statementBody = body;
result->nextStatement = NULL;
result->fileName = currentFileName;
result->lineNumber = currentLineNumber;
result->cumulativeLineNumber = cumulativeLineNumber;
return(result);
}
/*
These routines specifically build top-level parse-tree nodes corresponding
to the different types of Macross statements. There is one such routine of
the form "buildXxxxStatement" for each kind of Macross statement.
*/
statementType *
buildAlignStatement(expression)
expressionType *expression;
{
return(newStatement(ALIGN_STATEMENT,
(alignStatementBodyType *) expression));
}
statementType *
buildAssertStatement(condition, message)
expressionType *condition;
expressionType *message;
{
assertStatementBodyType *result;
result = typeAlloc(assertStatementBodyType);
result->condition = condition;
result->message = message;
return(newStatement(ASSERT_STATEMENT, result));
}
statementType *
buildBlockStatement(expressionList)
expressionListType *expressionList;
{
return(newStatement(BLOCK_STATEMENT,
(blockStatementBodyType *) expressionList));
}
statementType *
buildByteStatement(expressionList)
expressionListType *expressionList;
{
return(newStatement(BYTE_STATEMENT,
(byteStatementBodyType *) expressionList));
}
statementType *
buildConstrainStatement(expression, block)
expressionType *expression;
blockType *block;
{
constrainStatementBodyType *result;
result = typeAlloc(constrainStatementBodyType);
result->constraint = expression;
result->constrainedBlock = block;
return(newStatement(CONSTRAIN_STATEMENT, result));
}
statementType *
buildDbyteStatement(expressionList)
expressionListType *expressionList;
{
return(newStatement(DBYTE_STATEMENT,
(dbyteStatementBodyType *) expressionList));
}
statementType *
buildDefineStatement(name, value)
stringType *name;
expressionType *value;
{
defineStatementBodyType *result;
result = typeAlloc(defineStatementBodyType);
result->theSymbol = lookupOrEnterSymbol(name, UNKNOWN_SYMBOL);
result->theValue = value;
return(newStatement(DEFINE_STATEMENT, result));
}
statementType *
buildDoUntilStatement(body, condition)
blockType *body;
conditionType condition;
{
doUntilStatementBodyType *result;
result = typeAlloc(doUntilStatementBodyType);
result->doUntilCondition = condition;
result->doUntilLoop = body;
return(newStatement(DO_UNTIL_STATEMENT,result));
}
statementType *
buildDoWhileStatement(body, condition)
blockType *body;
conditionType condition;
{
doWhileStatementBodyType *result;
result = typeAlloc(doWhileStatementBodyType);
result->doWhileCondition = condition;
result->doWhileLoop = body;
return(newStatement(DO_WHILE_STATEMENT, result));
}
statementType *
buildDoStatement(body, end)
blockType *body;
doEndType *end;
{
statementType *result;
if (end->doEndKind == UNTIL_END)
result = buildDoUntilStatement(body, end->doEndCondition);
else if (end->doEndKind == WHILE_END)
result = buildDoWhileStatement(body, end->doEndCondition);
else
botch("bad do-end kind: %d\n", end->doEndCondition);
qfree(end);
return(result);
}
statementType *
buildExternStatement(identifierList)
identifierListType *identifierList;
{
return(newStatement(EXTERN_STATEMENT,
(externStatementBodyType *) identifierList));
}
statementType *
buildFreturnStatement(expression)
expressionType *expression;
{
return(newStatement(FRETURN_STATEMENT,
(freturnStatementBodyType *) expression));
}
statementType *
buildFunctionStatement(name, arguments, body)
stringType *name;
argumentDefinitionListType *arguments;
blockType *body;
{
functionStatementBodyType *result;
symbolTableEntryType *testSymbol;
testSymbol = lookupOrEnterSymbol(name, FUNCTION_SYMBOL);
if (testSymbol->context->usage != FUNCTION_SYMBOL && testSymbol->
context->usage != UNKNOWN_FUNCTION_SYMBOL) {
error(SYMBOL_ALREADY_THERE_ERROR, symbName(testSymbol));
return(NULL);
}
result = typeAlloc(functionStatementBodyType);
result->functionName = saveString(name);
result->theArguments = arguments;
result->theBlock = body;
return(newStatement(FUNCTION_STATEMENT, result));
}
statementType *
buildGroupStatement(block)
blockType *block;
{
return(newStatement(GROUP_STATEMENT,
(groupStatementBodyType *) block));
}
statementType *
buildIfStatement(head, continuation, continuationKind)
ifHeadType *head;
ifContinuationType continuation;
ifContinuationKindType continuationKind;
{
ifStatementBodyType *result;
result = typeAlloc(ifStatementBodyType);
result->ifCondition = head->headCondition;
result->consequence = head->headBody;
if (continuationKind == NO_CONTINUATION)
result->continuation.blockUnion = NULL;
else if (continuationKind == ELSE_CONTINUATION) {
result->continuation.continuationBodyUnion =
typeAlloc(ifContinuationBodyType);
result->continuation.continuationBodyUnion->ifCondition =
ALWAYS_COND;
result->continuation.continuationBodyUnion->consequence =
continuation.blockUnion;
result->continuation.continuationBodyUnion->
continuation.continuationBodyUnion = NULL;
} else if (continuationKind == ELSEIF_CONTINUATION)
result->continuation = continuation;
else
botch("bad continuation kind: %d\n", continuationKind);
qfree(head);
return(newStatement(IF_STATEMENT, result));
}
statementType *
buildIncludeStatement(filename)
expressionType *filename;
{
return(newStatement(INCLUDE_STATEMENT,
(includeStatementBodyType *) filename));
}
statementType *
buildInstructionStatement(opcode, operands)
opcodeTableEntryType *opcode;
operandListType *operands;
{
instructionStatementBodyType *result;
result = typeAlloc(instructionStatementBodyType);
result->kindOfInstruction = OPCODE_INSTRUCTION;
result->theInstruction.opcodeUnion = opcode;
result->theOperands = operands;
return(newStatement(INSTRUCTION_STATEMENT, result));
}
statementType *
buildLongStatement(expressionList)
expressionListType *expressionList;
{
return(newStatement(LONG_STATEMENT,
(longStatementBodyType *) expressionList));
}
statementType *
buildMacroStatement(macro, arguments, body)
macroTableEntryType *macro;
argumentDefinitionListType *arguments;
blockType *body;
{
macroStatementBodyType *result;
result = typeAlloc(macroStatementBodyType);
result->theMacro = macro;
result->theArguments = arguments;
result->theBlock = body;
return(newStatement(MACRO_STATEMENT, result));
}
statementType *
buildMacroInstructionStatement(macro, operands)
macroTableEntryType *macro;
operandListType *operands;
{
instructionStatementBodyType *result;
result = typeAlloc(instructionStatementBodyType);
result->kindOfInstruction = MACRO_INSTRUCTION;
result->theInstruction.macroUnion = macro;
result->theOperands = operands;
return(newStatement(INSTRUCTION_STATEMENT, result));
}
statementType *
buildMdefineStatement(name, value)
stringType *name;
expressionType *value;
{
mdefineStatementBodyType *result;
result = typeAlloc(mdefineStatementBodyType);
result->theSymbol = lookupOrEnterSymbol(name, DEAD_SYMBOL);
result->theValue = value;
return(newStatement(MDEFINE_STATEMENT, result));
}
statementType *
buildMdoUntilStatement(body, condition)
blockType *body;
ExpressionType *condition;
{
mdoUntilStatementBodyType *result;
result = typeAlloc(mdoUntilStatementBodyType);
result->mdoUntilCondition = condition;
result->mdoUntilLoop = body;
return(newStatement(MDO_UNTIL_STATEMENT,result));
}
statementType *
buildMdoWhileStatement(body, condition)
blockType *body;
expressionType *condition;
{
mdoWhileStatementBodyType *result;
result = typeAlloc(mdoWhileStatementBodyType);
result->mdoWhileCondition = condition;
result->mdoWhileLoop = body;
return(newStatement(MDO_WHILE_STATEMENT, result));
}
statementType *
buildMdoStatement(body, end)
blockType *body;
doEndType *end;
{
statementType *result;
if (end->doEndKind == UNTIL_END)
result = buildMdoUntilStatement(body, end->doEndCondition);
else if (end->doEndKind == WHILE_END)
result = buildMdoWhileStatement(body, end->doEndCondition);
else
botch("bad mdo-end kind: %d\n", end->doEndCondition);
qfree(end);
return(result);
}
statementType *
buildMforStatement(forExpressions, body)
forExpressionsType *forExpressions;
blockType *body;
{
mforStatementBodyType *result;
result = typeAlloc(mforStatementBodyType);
result->initExpression = forExpressions->initExpression;
result->testExpression = forExpressions->testExpression;
result->incrExpression = forExpressions->incrExpression;
result->forLoop = body;
qfree(forExpressions);
return(newStatement(MFOR_STATEMENT, result));
}
statementType *
buildMifStatement(head, continuation, continuationKind)
mifHeadType *head;
mifContinuationType continuation;
ifContinuationKindType continuationKind;
{
mifStatementBodyType *result;
result = typeAlloc(mifStatementBodyType);
result->mifCondition = head->headCondition;
result->mifConsequence = head->headBody;
if (continuationKind == NO_CONTINUATION)
result->mifContinuation.mifContinuationBodyUnion = NULL;
else if (continuationKind == ELSE_CONTINUATION) {
result->mifContinuation.mifContinuationBodyUnion =
typeAlloc(mifContinuationBodyType);
result->mifContinuation.mifContinuationBodyUnion->
mifCondition = NULL;
result->mifContinuation.mifContinuationBodyUnion->
mifConsequence = continuation.mifBlockUnion;
result->mifContinuation.mifContinuationBodyUnion->
mifContinuation.mifContinuationBodyUnion = NULL;
} else if (continuationKind == ELSEIF_CONTINUATION)
result->mifContinuation = continuation;
else
botch("bad mif continuation kind: %d\n", continuationKind);
qfree(head);
return(newStatement(MIF_STATEMENT, result));
}
statementType *
buildMswitchStatement(switchExpression, cases)
expressionType *switchExpression;
caseListType *cases;
{
mswitchStatementBodyType *result;
result = typeAlloc(mswitchStatementBodyType);
result->switchExpression = switchExpression;
result->cases = cases;
return(newStatement(MSWITCH_STATEMENT, result));
}
statementType *
buildMvariableStatement(name, value, dimension)
stringType *name;
expressionListType *value;
expressionType *dimension;
{
mvariableStatementBodyType *result;
result = typeAlloc(mvariableStatementBodyType);
result->theSymbol = lookupOrEnterSymbol(name, DEAD_SYMBOL);
result->theValue = value;
result->theDimension = dimension;
return(newStatement(MVARIABLE_STATEMENT, result));
}
statementType *
buildMwhileStatement(condition, body)
expressionType *condition;
blockType *body;
{
mwhileStatementBodyType *result;
result = typeAlloc(mwhileStatementBodyType);
result->mwhileCondition = condition;
result->mwhileLoop = body;
return(newStatement(MWHILE_STATEMENT, result));
}
statementType *
buildNullStatement()
{
return(newStatement(NULL_STATEMENT, NULL));
}
statementType *
buildOrgStatement(expression)
expressionType *expression;
{
return(newStatement(ORG_STATEMENT,
(orgStatementBodyType *) expression));
}
statementType *
buildPerformStatement(expression)
expressionType *expression;
{
return(newStatement(PERFORM_STATEMENT,
(performStatementBodyType *) expression));
}
statementType *
buildRelStatement()
{
return(newStatement(REL_STATEMENT, NULL));
}
statementType *
buildStartStatement(expression)
expressionType *expression;
{
return(newStatement(START_STATEMENT,
(startStatementBodyType *) expression));
}
statementType *
buildStringStatement(expressionList)
expressionListType *expressionList;
{
return(newStatement(STRING_STATEMENT,
(stringStatementBodyType *) expressionList));
}
statementType *
buildStructStatement(name, body)
symbolTableEntryType *name;
blockType *body;
{
structStatementBodyType *result;
result = typeAlloc(structStatementBodyType);
result->structBody = body;
result->structName = name;
return(newStatement(STRUCT_STATEMENT, result));
}
statementType *
buildTargetStatement(expression)
expressionType *expression;
{
return(newStatement(TARGET_STATEMENT,
(targetStatementBodyType *) expression));
}
statementType *
buildUndefineStatement(identifierList)
identifierListType *identifierList;
{
return(newStatement(UNDEFINE_STATEMENT,
(undefineStatementBodyType *) identifierList));
}
statementType *
buildVariableStatement(name, value, dimension)
stringType *name;
expressionListType *value;
expressionType *dimension;
{
variableStatementBodyType *result;
result = typeAlloc(variableStatementBodyType);
result->theSymbol = lookupOrEnterSymbol(name, VARIABLE_SYMBOL);
result->theValue = value;
result->theDimension = dimension;
return(newStatement(VARIABLE_STATEMENT, result));
}
statementType *
buildWhileStatement(condition, body)
conditionType condition;
blockType *body;
{
whileStatementBodyType *result;
result = typeAlloc(whileStatementBodyType);
result->whileCondition = condition;
result->whileLoop = body;
return(newStatement(WHILE_STATEMENT, result));
}
statementType *
buildWordStatement(expressionList)
expressionListType *expressionList;
{
return(newStatement(WORD_STATEMENT,
(wordStatementBodyType *) expressionList));
}

BIN
buildStuff1.o Normal file

Binary file not shown.

358
buildStuff2.c Normal file
View File

@ -0,0 +1,358 @@
/*
buildStuff2.c -- More routines to build parse-tree structures for the
Macross assembler. This module is target processor
independent.
Chip Morningstar -- Lucasfilm Ltd.
2-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/*
These are all the miscellaneous routines for building pieces of parse-tree
structures.
*/
/* Fragments of statement structures */
caseType *
buildCase(caseTags, caseBody)
expressionListType *caseTags;
blockType *caseBody;
{
caseType *result;
result = typeAlloc(caseType);
result->caseTags = caseTags;
result->caseBody = caseBody;
return(result);
}
doEndType *
buildDoEnd(condition, kindOfDoEnd)
conditionType condition;
doEndKindType kindOfDoEnd;
{
doEndType *result;
result = typeAlloc(doEndType);
result->doEndKind = kindOfDoEnd;
result->doEndCondition = condition;
return(result);
}
forExpressionsType *
buildForExpressions(initExpression, testExpression, incrExpression)
expressionType *initExpression;
expressionType *testExpression;
expressionType *incrExpression;
{
forExpressionsType *result;
result = typeAlloc(forExpressionsType);
result->initExpression = initExpression;
result->testExpression = testExpression;
result->incrExpression = incrExpression;
return(result);
}
ifHeadType *
buildIfHead(condition, block)
conditionType condition;
blockType *block;
{
ifHeadType *result;
result = typeAlloc(ifHeadType);
result->headCondition = condition;
result->headBody = block;
return(result);
}
mdoEndType *
buildMdoEnd(condition, kindOfMdoEnd)
expressionType *condition;
doEndKindType kindOfMdoEnd;
{
mdoEndType *result;
result = typeAlloc(mdoEndType);
result->mdoEndKind = kindOfMdoEnd;
result->mdoEndCondition = condition;
return(result);
}
mifHeadType *
buildMifHead(condition, block)
expressionType *condition;
blockType *block;
{
mifHeadType *result;
result = typeAlloc(mifHeadType);
result->headCondition = condition;
result->headBody = block;
return(result);
}
/* Fragments of expression structures */
arrayTermType *
buildArrayTerm(array, index)
expressionType *array;
expressionType *index;
{
arrayTermType *result;
result = typeAlloc(arrayTermType);
result->arrayName = array;
result->arrayIndex = index;
return(result);
}
binopTermType *
buildBinopTerm(binop, leftArgument, rightArgument)
binopKindType binop;
expressionType *leftArgument;
expressionType *rightArgument;
{
binopTermType *result;
result = typeAlloc(binopTermType);
result->binop = binop;
result->leftArgument = leftArgument;
result->rightArgument = rightArgument;
return(result);
}
functionCallTermType *
buildFunctionCall(functionName, arguments)
stringType *functionName;
operandListType *arguments;
{
functionCallTermType *result;
symbolTableEntryType *lookupOrEnterSymbol();
result = typeAlloc(functionCallTermType);
result->functionName = lookupOrEnterSymbol(functionName,
UNKNOWN_FUNCTION_SYMBOL);
result->parameters = arguments;
return(result);
}
postOpTermType *
buildPostOpTerm(postOp, postOpArgument)
postOpKindType postOp;
expressionType *postOpArgument;
{
postOpTermType *result;
result = typeAlloc(postOpTermType);
result->postOp = postOp;
result->postOpArgument = postOpArgument;
return(result);
}
preOpTermType *
buildPreOpTerm(preOp, preOpArgument)
preOpKindType preOp;
expressionType *preOpArgument;
{
preOpTermType *result;
result = typeAlloc(preOpTermType);
result->preOp = preOp;
result->preOpArgument = preOpArgument;
return(result);
}
unopTermType *
buildUnopTerm(unop, unopArgument)
unopKindType unop;
expressionType *unopArgument;
{
unopTermType *result;
result = typeAlloc(unopTermType);
result->unop = unop;
result->unopArgument = unopArgument;
return(result);
}
expressionTermType *
buildExpressionTerm(kindOfExpressionTerm, arg1, arg2, arg3)
expressionTermKindType kindOfExpressionTerm;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
expressionType *result;
symbolTableEntryType *lookupOrEnterSymbol();
result = typeAlloc(expressionType);
result->kindOfTerm = kindOfExpressionTerm;
switch (kindOfExpressionTerm) {
case IDENTIFIER_EXPR:
result->expressionTerm.identifierUnion =
(identifierTermType *) arg1;
break;
case ARRAY_EXPR:
result->expressionTerm.arrayUnion =
buildArrayTerm((expressionType *) arg1,
(expressionType *) arg2);
break;
case FUNCTION_CALL_EXPR:
result->expressionTerm.functionCallUnion =
(functionCallTermType *) arg1;
break;
case NUMBER_EXPR:
result->expressionTerm.numberUnion = (numberTermType) arg1;
break;
case STRING_EXPR:
result->expressionTerm.stringUnion = (stringTermType *) arg1;
break;
case SUBEXPRESSION_EXPR:
result->expressionTerm.subexpressionUnion =
(subexpressionTermType *) arg1;
break;
case UNOP_EXPR:
result->expressionTerm.unopUnion =
buildUnopTerm((unopKindType) arg1,
(expressionType *) arg2);
break;
case ASSIGN_EXPR:
case BINOP_EXPR:
result->expressionTerm.binopUnion =
buildBinopTerm((binopKindType) arg1,
(expressionType *) arg2,
(expressionType *) arg3);
break;
case PREOP_EXPR:
result->expressionTerm.preOpUnion =
buildPreOpTerm((preOpKindType) arg1,
(expressionType *) arg2);
break;
case POSTOP_EXPR:
result->expressionTerm.postOpUnion =
buildPostOpTerm((postOpKindType) arg1,
(expressionType *) arg2);
break;
case HERE_EXPR:
result->expressionTerm.hereUnion = (hereTermType *) NULL;
break;
case CONDITION_CODE_EXPR:
result->expressionTerm.conditionCodeUnion =
(conditionCodeTermType) arg1;
break;
default:
botch("invalid expression term kind: %d\n",
kindOfExpressionTerm);
break;
}
return(result);
}
/* Other stuff */
macroTableEntryType *
buildMacroTableEntry(name)
stringType *name;
{
macroTableEntryType *result;
char *saveString();
result = typeAlloc(macroTableEntryType);
result->macroName = saveString(name);
result->nextMacro = NULL;
result->arguments = NULL;
result->body = NULL;
return(result);
}
symbolTableEntryType *
buildSymbolTableEntry(name, usage)
stringType *name;
symbolUsageKindType usage;
{
symbolTableEntryType *result;
char *saveString();
result = typeAlloc(symbolTableEntryType);
result->symbolName = saveString(name);
result->nextSymbol = NULL;
result->context = typeAlloc(symbolInContextType);
result->referenceCount = 0;
dupValue(result->context->value, UndefinedValue);
result->context->attributes = 0;
result->context->referenceCount = 0;
result->context->usage = usage;
result->context->pushedContexts = NULL;
result->context->environmentNumber = GLOBAL_ENVIRONMENT_NUMBER;
return(result);
}
codeBreakType *
buildCodeBreak(kind, address, data)
codeBreakKindType kind;
addressType address;
int data;
{
codeBreakType *result;
result = typeAlloc(codeBreakType);
result->kindOfBreak = kind;
result->breakAddress = address;
result->breakData = data;
result->nextBreak = NULL;
return(result);
}
reservationListType *
buildReservation(startAddress, blockSize, nextReservation)
addressType startAddress;
int blockSize;
reservationListType *nextReservation;
{
reservationListType *result;
result = typeAlloc(reservationListType);
result->startAddress = startAddress;
result->blockSize = blockSize;
result->nextReservation = nextReservation;
return(result);
}
simpleFixupListType *
buildSimpleFixupList(locationToFixup, previousList)
valueType locationToFixup;
simpleFixupListType *previousList;
{
simpleFixupListType *result;
result = typeAlloc(simpleFixupListType);
result->locationToFixup = locationToFixup;
result->nextFixup = previousList;
return(result);
}

BIN
buildStuff2.o Normal file

Binary file not shown.

232
buildStuff3.c Normal file
View File

@ -0,0 +1,232 @@
/*
buildStuff3.c -- Still more routines to build parse-tree structures
for the Macross assembler.
Chip Morningstar -- Lucasfilm Ltd.
2-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/*
These routines all build list-type structures. Since yacc likes to build
things left-recursively but we don't want lists to be backwards (which
would then necessitate reversing them at some point -- yuck), we employ
the ruse of substituting for the first element of a list a different
struct which is identical to a normal one but contains an additional field
for a pointer to the tail element of the list. We can then add things
directly onto the tail as we like.
*/
argumentListHeadType *
buildArgumentList(new, rest, arrayTag)
stringType *new;
argumentListHeadType *rest;
bool arrayTag;
{
argumentListHeadType *newListHead;
argumentDefinitionListType *newArgument;
symbolTableEntryType *lookupOrEnterSymbol();
if (rest == NULL) {
newListHead = typeAlloc(argumentListHeadType);
newListHead->theArgument = lookupOrEnterSymbol(new,
DEAD_SYMBOL);
newListHead->nextArgument = NULL;
newListHead->tail = NULL;
newListHead->arrayTag = arrayTag;
return(newListHead);
} else {
newArgument = typeAlloc(argumentDefinitionListType);
newArgument->theArgument = lookupOrEnterSymbol(new,
DEAD_SYMBOL);
newArgument->nextArgument = NULL;
if (rest->tail != NULL)
rest->tail->nextArgument = newArgument;
else
rest->nextArgument = newArgument;
rest->tail = newArgument;
rest->arrayTag = arrayTag;
return(rest);
}
}
caseListHeadType *
buildCaseList(new, rest)
caseType *new;
caseListHeadType *rest;
{
caseListHeadType *newListHead;
caseListType *newCase;
if (rest == NULL) {
newListHead = typeAlloc(caseListHeadType);
newListHead->theCase = new;
newListHead->nextCase = NULL;
newListHead->tail = NULL;
return(newListHead);
} else {
newCase = typeAlloc(caseListType);
newCase->theCase = new;
newCase->nextCase = NULL;
if (rest->tail != NULL)
rest->tail->nextCase = newCase;
else
rest->nextCase = newCase;
rest->tail = newCase;
return(rest);
}
}
expressionListHeadType *
buildExpressionList(new, rest)
expressionType *new;
expressionListHeadType *rest;
{
expressionListHeadType *newListHead;
expressionListType *newListEntry;
if (rest == NULL) {
newListHead = typeAlloc(expressionListHeadType);
newListHead->theExpression = new;
newListHead->nextExpression = NULL;
newListHead->tail = NULL;
return(newListHead);
} else {
newListEntry = typeAlloc(expressionListType);
newListEntry->theExpression = new;
newListEntry->nextExpression = NULL;
if (rest->tail != NULL)
rest->tail->nextExpression = newListEntry;
else
rest->nextExpression = newListEntry;
rest->tail = newListEntry;
return(rest);
}
}
identifierListHeadType *
buildIdentifierList(new, rest, usage)
stringType *new;
identifierListHeadType *rest;
symbolUsageKindType usage;
{
identifierListType *newListEntry;
identifierListHeadType *newListHead;
symbolTableEntryType *lookupOrEnterSymbol();
if (rest == NULL) {
newListHead = typeAlloc(identifierListHeadType);
newListHead->theSymbol = lookupOrEnterSymbol(new, usage);
newListHead->nextIdentifier = NULL;
newListHead->tail = NULL;
return(newListHead);
} else {
newListEntry = typeAlloc(identifierListType);
newListEntry->theSymbol = lookupOrEnterSymbol(new, usage);
newListEntry->nextIdentifier = NULL;
if (rest->tail != NULL)
rest->tail->nextIdentifier = newListEntry;
else
rest->nextIdentifier = newListEntry;
rest->tail = newListEntry;
return(rest);
}
}
labelListHeadType *
buildLabelList(new, rest)
symbolTableEntryType *new;
labelListHeadType *rest;
{
labelListHeadType *newLabelHead;
labelListType *newLabel;
if (rest == NULL) {
newLabelHead = typeAlloc(labelListHeadType);
newLabelHead->theLabel = new;
newLabelHead->nextLabel = NULL;
newLabelHead->tail = NULL;
return(newLabelHead);
} else {
newLabel = typeAlloc(labelListType);
newLabel->theLabel = new;
newLabel->nextLabel = NULL;
if (rest->tail != NULL)
rest->tail->nextLabel = newLabel;
else
rest->nextLabel = newLabel;
rest->tail = newLabel;
return(rest);
}
}
operandListHeadType *
buildOperandList(new, rest)
operandType *new;
operandListHeadType *rest;
{
operandListHeadType *newListHead;
if (rest == NULL) {
newListHead = typeAlloc(operandListHeadType);
newListHead->kindOfOperand = new->kindOfOperand;
newListHead->theOperand = new->theOperand;
newListHead->nextOperand = NULL;
newListHead->tail = NULL;
qfree(new);
return(newListHead);
} else {
new->nextOperand = NULL;
if (rest->tail != NULL)
rest->tail->nextOperand = new;
else
rest->nextOperand = new;
rest->tail = new;
return(rest);
}
}
selectionListHeadType *
buildSelectionList(new, rest)
selectionListType *new;
selectionListHeadType *rest;
{
return((selectionListHeadType *) buildIdentifierList(new, rest));
}
statementListHeadType *
buildStatementList(new, rest)
statementType *new;
statementListHeadType *rest;
{
statementListHeadType *newListHead;
if (new == NULL)
return(rest);
if (rest == NULL) {
newListHead = typeAlloc(statementListHeadType);
newListHead->kindOfStatement = new->kindOfStatement;
newListHead->labels = new->labels;
newListHead->statementBody = new->statementBody;
newListHead->lineNumber = new->lineNumber;
newListHead->fileName = new->fileName;
newListHead->cumulativeLineNumber = new->cumulativeLineNumber;
newListHead->nextStatement = NULL;
newListHead->tail = NULL;
qfree(new);
return(newListHead);
} else {
new->nextStatement = NULL;
if (rest->tail != NULL)
rest->tail->nextStatement = new;
else
rest->nextStatement = new;
rest->tail = new;
return(rest);
}
}

BIN
buildStuff3.o Normal file

Binary file not shown.

1033
builtInFunctions.c Normal file

File diff suppressed because it is too large Load Diff

BIN
builtInFunctions.o Normal file

Binary file not shown.

BIN
builtInFunsSD.o Normal file

Binary file not shown.

237
builtInFunsSD_6502.c Normal file
View File

@ -0,0 +1,237 @@
/*
builtInFunsSD_6502.c -- Code for target-processor dependent
intrinsic user callable functions in the Macross assembler.
(6502 version).
Chip Morningstar -- Lucasfilm Ltd.
23-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/* Helper functions, defined in builtInFunctions.c */
valueType *makeBooleanValue();
valueType *makeFailureValue();
valueType *makeIntegerValue();
valueType *makeOperandValue();
valueType *makeStringValue();
valueType *makeUndefinedValue();
/* Check if operand is the accumulator */
valueType *
isARegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
A_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is DIRECT */
valueType *
isDirectModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
EXPRESSION_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is IMMEDIATE */
valueType *
isImmediateModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
IMMEDIATE_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is INDEXED (either X or Y) */
valueType *
isIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
X_INDEXED_OPND || evaluatedParameter->addressMode ==
Y_INDEXED_OPND || evaluatedParameter->addressMode ==
X_SELECTED_OPND || evaluatedParameter->addressMode ==
Y_SELECTED_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is INDIRECT */
valueType *
isIndirectModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
INDIRECT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is POST-INDEXED */
valueType *
isPostIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
POST_INDEXED_Y_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is PRE-INDEXED */
valueType *
isPreIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
PRE_INDEXED_X_OPND || evaluatedParameter->
addressMode == PRE_SELECTED_X_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is X-INDEXED */
valueType *
isXIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
X_INDEXED_OPND || evaluatedParameter->addressMode ==
X_SELECTED_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand is the X index register */
valueType *
isXRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
X_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is Y-INDEXED */
valueType *
isYIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
Y_INDEXED_OPND || evaluatedParameter->addressMode ==
Y_SELECTED_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand is the Y index register */
valueType *
isYRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(evaluatedParameter->addressMode ==
Y_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}

505
builtInFunsSD_68000.c Normal file
View File

@ -0,0 +1,505 @@
/*
builtInFunsSD_68000.c -- Code for target-processor dependent
intrinsic user callable functions in the Macross assembler.
(68000 version).
Chip Morningstar -- Lucasfilm Ltd.
26-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/* Helper functions, defined in builtInFunctions.c */
valueType *makeBooleanValue();
valueType *makeFailureValue();
valueType *makeIntegerValue();
valueType *makeOperandValue();
valueType *makeStringValue();
valueType *makeUndefinedValue();
/* Get address register component of operand */
valueType *
getAddressRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeIntegerValue(getAddressRegister(
evaluatedParameter->addressMode)));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Get data register component of operand */
valueType *
getDataRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeIntegerValue(getDataRegister(evaluatedParameter->
addressMode)));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Get index register component of operand */
valueType *
getIndexRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeIntegerValue(getIndexRegister(evaluatedParameter->
addressMode)));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Get register component of operand */
valueType *
getRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeIntegerValue(getRegister(evaluatedParameter->
addressMode)));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Get word/long component of operand */
valueType *
getWLBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeIntegerValue(getWL(evaluatedParameter->
addressMode)));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is absolute */
valueType *
isAbsoluteModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == ABSOLUTE_SHORT_OPND ||
operandKindField(evaluatedParameter->addressMode) ==
ABSOLUTE_LONG_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is absolute long */
valueType *
isAbsoluteLongModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == ABSOLUTE_LONG_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is absolute short */
valueType *
isAbsoluteShortModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == ABSOLUTE_SHORT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is an address register */
valueType *
isARegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == A_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is the condition code register */
valueType *
isCCRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == CC_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is a control register */
valueType *
isControlRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == CONTROL_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is a data register */
valueType *
isDRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == D_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is DFC register */
valueType *
isDFCRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == CONTROL_REGISTER_OPND &&
getRegister(evaluatedParameter->addressMode) ==
DFC_REGISTER));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is displacement */
valueType *
isDisplacementModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == DISPLACEMENT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is IMMEDIATE */
valueType *
isImmediateModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == IMMEDIATE_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is indexed */
valueType *
isIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == INDEXED_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is indirect */
valueType *
isIndirectModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == A_REGISTER_INDIRECT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is pc displacement */
valueType *
isPCDisplacementModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == PC_DISPLACEMENT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is pc indexed */
valueType *
isPCIndexedModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == PC_INDEXED_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is postincrement */
valueType *
isPostincrementModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == POSTINCREMENT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if an operand's address mode is predecrement */
valueType *
isPredecrementModeBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == PREDECREMENT_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is SFC register */
valueType *
isSFCRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == CONTROL_REGISTER_OPND &&
getRegister(evaluatedParameter->addressMode) ==
SFC_REGISTER));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is the status register */
valueType *
isStatusRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == STATUS_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is user stack pointer */
valueType *
isUSPBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == USP_REGISTER_OPND));
} else {
return(makeBooleanValue(FALSE));
}
}
/* Check if operand is VB register */
valueType *
isVBRegisterBIF(parameterList, kindOfFixup)
operandListType *parameterList;
fixupKindType kindOfFixup;
{
valueType *evaluatedParameter;
valueType *evaluateOperand();
if (parameterList != NULL) {
evaluatedParameter = evaluateOperand(parameterList, NO_FIXUP);
return(makeBooleanValue(operandKindField(evaluatedParameter->
addressMode) == CONTROL_REGISTER_OPND &&
getRegister(evaluatedParameter->addressMode) ==
VBR_REGISTER));
} else {
return(makeBooleanValue(FALSE));
}
}

19
conditionDefs_6502.h Normal file
View File

@ -0,0 +1,19 @@
/*
conditionDefs_6502.h -- Define types for 6502 branch condition codes.
Chip Morningstar -- Lucasfilm Ltd.
18-April-1985
*/
typedef enum {
CARRY_COND, ZERO_COND, NEGATIVE_COND, OVERFLOW_COND, LT_COND,
LEQ_COND, SLT_COND, SLEQ_COND,
ALWAYS_COND,
NOT_CARRY_COND, NOT_ZERO_COND, NOT_NEGATIVE_COND,
NOT_OVERFLOW_COND, GEQ_COND, GT_COND, SGEQ_COND, SGT_COND,
NEVER_COND,
NOT_FOUND_COND,
} conditionType;
#define COMPOUND_BRANCH_MAX 3

20
conditionDefs_68000.h Normal file
View File

@ -0,0 +1,20 @@
/*
conditionDefs_68000.h -- Define types for 68000 condition codes.
Chip Morningstar -- Lucasfilm Ltd.
25-April-1985
*/
typedef enum {
CARRY_COND, EQUAL_COND, OVERFLOW_COND, MINUS_COND, LT_COND,
LEQ_COND, LOW_OR_SAME_COND,
ALWAYS_COND,
NOT_CARRY_COND, NOT_EQUAL_COND, NOT_OVERFLOW_COND, PLUS_COND,
GEQ_COND, GT_COND, HIGH_COND,
NEVER_COND,
NOT_FOUND_COND,
} conditionType;
#define COMPOUND_BRANCH_MAX 1

1200
debugPrint.c Normal file

File diff suppressed because it is too large Load Diff

BIN
debugPrint.o Normal file

Binary file not shown.

BIN
debugPrintSD.o Normal file

Binary file not shown.

249
debugPrintSD_6502.c Normal file
View File

@ -0,0 +1,249 @@
/*
debugPrintSD_6502.c -- Routines to print out things for debugging
purposes (system dependent routines, 6502 version).
Chip Morningstar -- Lucasfilm Ltd.
23-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "y.tab.h"
int tablevel;
/* Fundamental nop print operation */
#define nullPrint(thing) if (thing==NULL) { tab(); printf("()\n"); return; }
void
printCondition(condition)
conditionType condition;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'conditionType'. */
static char *conditionTable[] = {
"carry",
"zero",
"negative",
"overflow",
"lt",
"leq",
"slt",
"sleq",
"always",
"!carry",
"!zero",
"!negative",
"!overflow",
"geq",
"gt",
"sgeq",
"sgt",
"never",
};
printf("%s", conditionTable[(int)condition]);
}
void
printOperandKind(kind)
operandKindType kind;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'operandKindType'. */
static char *operandKindTable[] = {
"expression opnd",
"immediate opnd",
"indirect opnd",
"a register opnd",
"x register opnd",
"y register opnd",
"post indexed y opnd",
"pre indexed x opnd",
"x indexed opnd",
"y indexed opnd",
"x selected opnd",
"y selected opnd",
"pre selected x opnd",
"string opnd",
"block opnd",
};
printf("%s", operandKindTable[(int)kind]);
}
void
printToken(token)
int token;
{
/* This table MUST be maintained congruently with the set of '#define's in
the file 'y.tab.h' as produced by yacc. */
static char *tokenTable[] = {
"A",
"ALIGN",
"ASSERT",
"BLOCK",
"BYTE",
"CONSTRAIN",
"DBYTE",
"DEFINE",
"DO",
"ELSE",
"ELSEIF",
"ENDFILE",
"EOL",
"EXTERN",
"FRETURN",
"FUNCTION",
"HERE",
"IF",
"INCLUDE",
"LONG",
"MACRO",
"MCASE",
"MDEFAULT",
"MDEFINE",
"MDO",
"MELSE",
"MELSEIF",
"MFOR",
"MIF",
"MSWITCH",
"MUNTIL",
"MVARIABLE",
"MWHILE",
"ORG",
"REL",
"START",
"STRING",
"STRUCT",
"TARGET",
"UNDEFINE",
"UNTIL",
"VARIABLE",
"WHILE",
"WORD",
"X",
"Y",
"ConditionCode",
"Identifier",
"MacroName",
"Number",
"Opcode",
"TextString",
"ASSIGN",
"LOGICAL_OR",
"LOGICAL_XOR",
"LOGICAL_AND",
"BITWISE_OR",
"BITWISE_XOR",
"BITWISE_AND",
"EQUAL_TO",
"NOT_EQUAL_TO",
"LESS_THAN",
"LESS_THAN_OR_EQUAL_TO",
"GREATER_THAN",
"GREATER_THAN_OR_EQUAL_TO",
"LEFT_SHIFT",
"RIGHT_SHIFT",
"ADD",
"SUB",
"MUL",
"DIV",
"MOD",
"UNARY_MINUS",
"LOGICAL_NOT",
"BITWISE_NOT",
"HI_BYTE",
"LO_BYTE",
"SELECT",
"INCREMENT",
"DECREMENT",
};
if (token >= A) {
printf("%s", tokenTable[token - A]);
} else {
printf("'%c'", token);
}
}
void
printOperand(operand)
operandType *operand;
{
nullPrint(operand);
tab(); printf("(operand: [");
printOperandKind(operand->kindOfOperand);
printf("]\n");
tablevel++;
switch (operand->kindOfOperand) {
case EXPRESSION_OPND:
printExpression(operand->theOperand);
break;
case IMMEDIATE_OPND:
printExpression(operand->theOperand);
break;
case INDIRECT_OPND:
printExpression(operand->theOperand);
break;
case A_REGISTER_OPND:
break;
case X_REGISTER_OPND:
break;
case Y_REGISTER_OPND:
break;
case POST_INDEXED_Y_OPND:
printExpression(operand->theOperand);
break;
case PRE_INDEXED_X_OPND:
printExpression(operand->theOperand);
break;
case X_INDEXED_OPND:
printExpression(operand->theOperand);
break;
case Y_INDEXED_OPND:
printExpression(operand->theOperand);
break;
case X_SELECTED_OPND:
printIdentifierList(operand->theOperand);
break;
case Y_SELECTED_OPND:
printIdentifierList(operand->theOperand);
break;
case PRE_SELECTED_X_OPND:
printIdentifierList(operand->theOperand);
break;
case STRING_OPND:
tab(); printf("(string: \"%s\")\n", operand->theOperand);
break;
case BLOCK_OPND:
printBlock(operand->theOperand);
break;
default:
printf("fooey: bad operand kind %d\n", operand->
kindOfOperand);
break;
}
tablevel--;
tab(); printf(")\n");
}

309
debugPrintSD_68000.c Normal file
View File

@ -0,0 +1,309 @@
/*
debugPrintSD_68000.c -- Routines to print out things for debugging
purposes (system dependent routines, 68000 version).
Chip Morningstar -- Lucasfilm Ltd.
26-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "y.tab.h"
int tablevel;
/* Fundamental nop print operation */
#define nullPrint(thing) if (thing==NULL) { tab(); printf("()\n"); return; }
void
printCondition(condition)
conditionType condition;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'conditionType'. */
static char *conditionTable[] = {
"carry",
"equal",
"overflow",
"minus",
"lt",
"leq",
"ls",
"always",
"!carry",
"!equal",
"!overflow",
"plus",
"geq",
"gt",
"high",
"never",
};
printf("%s", conditionTable[(int)condition]);
}
void
printRegister(reg)
int reg;
{
if (reg < 8)
printf(" a%d", reg);
else
printf(" d%d", reg - 8);
}
void
printControlRegister(reg)
int reg;
{
switch (reg) {
case SFC_REGISTER: printf("sfc"); break;
case DFC_REGISTER: printf("dfc"); break;
case VBR_REGISTER: printf("vbr"); break;
default: botch("Bad control register %d\n", reg); break;
}
}
void
printOperandKind(kind)
operandKindType kind;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'operandKindType'. */
static char *operandKindTable[] = {
"expression opnd",
"string opnd",
"block opnd",
"data register opnd",
"address register opnd",
"address register indirect opnd",
"postincrement opnd",
"predecrement opnd",
"displacement opnd",
"indexed opnd",
"program counter displacement opnd",
"program counter indexed opnd",
"immediate opnd",
"absolute short opnd",
"absolute long opnd",
"condition code register opnd",
"status register opnd",
"user stack pointer opnd",
"control register opnd",
};
printf("%s", operandKindTable[(int)operandKindField(kind)]);
if (isRegisterOperand(kind))
printRegister(getRegister(kind));
if (isControlRegisterOperand(kind))
printControlRegister(getRegister(kind));
if (isIndexedOperand(kind))
printRegister(getIndexRegister(kind));
}
bool
isRegisterOperand(kind)
operandKindType kind;
{
kind = operandKindField(kind);
return(kind==D_REGISTER_OPND || kind==A_REGISTER_OPND ||
kind==A_REGISTER_INDIRECT_OPND || kind==POSTINCREMENT_OPND ||
kind==PREDECREMENT_OPND || kind==DISPLACEMENT_OPND ||
kind==INDEXED_OPND || kind==SELECTED_OPND ||
kind==INDEX_SELECTED_OPND);
}
bool
isIndexedOperand(kind)
operandKindType kind;
{
kind = operandKindField(kind);
return(kind==INDEXED_OPND || kind==PC_INDEXED_OPND || kind==
INDEX_SELECTED_OPND);
}
bool
isControlRegisterOperand(kind)
operandKindType kind;
{
return(operandKindField(kind) == CONTROL_REGISTER_OPND);
}
void
printToken(token)
int token;
{
/* This table MUST be maintained congruently with the set of '#define's in
the file 'y.tab.h' as produced by yacc. */
static char *tokenTable[] = {
"A0",
"A1",
"A2",
"A3",
"A4",
"A5",
"A6",
"A7",
"ALIGN",
"ASSERT",
"BLOCK",
"BYTE",
"CCR",
"CONSTRAIN",
"D0",
"D1",
"D2",
"D3",
"D4",
"D5",
"D6",
"D7",
"DBYTE",
"DEFINE",
"DFC",
"DO",
"ELSE",
"ELSEIF",
"ENDFILE",
"EOL",
"EXTERN",
"FRETURN",
"FUNCTION",
"HERE",
"IF",
"INCLUDE",
"L",
"LONG",
"MACRO",
"MCASE",
"MDEFAULT",
"MDEFINE",
"MDO",
"MELSE",
"MELSEIF",
"MFOR",
"MIF",
"MSWITCH",
"MUNTIL",
"MVARIABLE",
"MWHILE",
"ORG",
"PC",
"REL",
"SFC",
"SR",
"START",
"STRING",
"STRUCT",
"TARGET",
"UNDEFINE",
"UNTIL",
"USP",
"VARIABLE",
"VBR",
"W",
"WHILE",
"WORD",
"X",
"Y",
"ConditionCode",
"Identifier",
"MacroName",
"Number",
"Opcode",
"TextString",
"ASSIGN",
"LOGICAL_OR",
"LOGICAL_XOR",
"LOGICAL_AND",
"BITWISE_OR",
"BITWISE_XOR",
"BITWISE_AND",
"EQUAL_TO",
"NOT_EQUAL_TO",
"LESS_THAN",
"LESS_THAN_OR_EQUAL_TO",
"GREATER_THAN",
"GREATER_THAN_OR_EQUAL_TO",
"LEFT_SHIFT",
"RIGHT_SHIFT",
"ADD",
"SUB",
"MUL",
"DIV",
"MOD",
"UNARY_MINUS",
"LOGICAL_NOT",
"BITWISE_NOT",
"HI_BYTE",
"LO_BYTE",
"SELECT",
"INCREMENT",
"DECREMENT",
};
if (token >= A0) {
printf("%s", tokenTable[token - A0]);
} else {
printf("'%c'", token);
}
}
void
printOperand(operand)
operandType *operand;
{
nullPrint(operand);
tab(); printf("(operand: [");
printOperandKind(operand->kindOfOperand);
printf("]\n");
tablevel++;
switch (operand->kindOfOperand) {
case EXPRESSION_OPND:
case DISPLACEMENT_OPND:
case INDEXED_OPND:
case PC_DISPLACEMENT_OPND:
case PC_INDEXED_OPND:
case IMMEDIATE_OPND:
case ABSOLUTE_SHORT_OPND:
case ABSOLUTE_LONG_OPND:
printExpression(operand->theOperand);
break;
case D_REGISTER_OPND:
case A_REGISTER_OPND:
case A_REGISTER_INDIRECT_OPND:
case POSTINCREMENT_OPND:
case PREDECREMENT_OPND:
case CC_REGISTER_OPND:
case STATUS_REGISTER_OPND:
case USP_REGISTER_OPND:
case CONTROL_REGISTER_OPND:
break;
case SELECTED_OPND:
case INDEX_SELECTED_OPND:
printIdentifierList(operand->theOperand);
break;
case STRING_OPND:
tab(); printf("(string: \"%s\")\n", operand->theOperand);
break;
case BLOCK_OPND:
printBlock(operand->theOperand);
break;
default:
printf("fooey: bad operand kind %d\n", operand->
kindOfOperand);
break;
}
tablevel--;
tab(); printf(")\n");
}

463
doc/genmacros.itr Normal file
View File

@ -0,0 +1,463 @@
.TL
\s+9genmacros.m\s-9
.AU
a macro library for use with the 6502 version of Macross
.AI
Lucasfilm Ltd. Games Division
\\*(DY
.ds LH genmacros.m
.ds CH \\*(DY
.ds RH Reference Manual
.ds LF Lucasfilm Ltd. Proprietary Information
.ds CF - % -
.ds RF CONFIDENTIAL
.PP
These macros have been concocted by various people for the convenience and
amusement of those programming the 6502 using \fIMacross\fR. The will be
found in the file \fB/u1/gg/lib/6502/genmacros.m\fR. To use them, insert the
following statement somewhere near the beginning of your \fIMacross\fR
program:
.nf
\fBinclude "/u1/gg/lib/6502/genmacros.m"\fR
.fi
Easy, no? What follows is a summary of the macros, grouped roughly by
category.
.sp 1
.SH
\s+2Macros to save and restore registers\s-2
.nf
\fBphr\fR
.fi
.IP
Push all registers (i.e., the accumulator and the X and Y index registers)
onto the stack.
.LP
.nf
\fBplr\fR
.fi
.IP
Pull the registers (the accumulator and the X and Y index registers) off the
stack.
.LP
.nf
\fBphx\fR
.fi
.IP
Push the X register onto the stack.
.LP
.nf
\fBplx\fR
.fi
.IP
Pull the X register off of the stack.
.LP
.nf
\fBphy\fR
.fi
.IP
Push the Y register onto the stack.
.LP
.nf
\fBply\fR
.fi
.IP
Pull the Y register off of the stack.
.LP
.nf
\fBpushaddr \fIaddress\fR
.fi
.IP
Push \fIaddress\fR onto the stack to \fBrts\fR to.
.sp 1
.SH
\s+2Macros to move data around with\s-2
.PP
These macros provide an address mode independent method of moving bytes from
one place to another. The source and destination arguments of these macros
may, generally speaking, be in any address mode you desire (except, of course,
that the destination can't be immediate mode!).
.nf
\fBmovm \fIn\fB, \fIdest\fB, \fIsrc\fR
.fi
.IP
Move multiple \(em move \fIn\fR bytes from \fIsrc\fR to \fIdest\fR. The bytes
are moved using the accumulator as an intermediary.
.LP
.nf
\fBmovmx \fIn\fB, \fIdest\fB, \fIsrc\fR
.fi
.IP
Move multiple \(em move \fIn\fR bytes from \fIsrc\fR to \fIdest\fR. The bytes
are moved using the X register as an intermediary.
.LP
.nf
\fBmovmy \fIn\fB, \fIdest\fB, \fIsrc\fR
.fi
.IP
Move multiple \(em move \fIn\fR bytes from \fIsrc\fR to \fIdest\fR. The bytes
are moved using the Y register as an intermediary.
.LP
.nf
\fBmv2m \fIn\fB, \fIdest1\fB, \fIdest2\fB, \fIsrc\fR
.fi
.IP
Move multiple to two destinations \(em move \fIn\fR bytes from \fIsrc\fR to
both \fIdest1\fR and \fIdest2\fR. The bytes are moved using the acuumulator
as an intermediary.
.LP
.nf
\fBmoveb \fIsrc\fB, \fIdest\fR
.fi
.IP
Move byte \(em move one byte from \fIsrc\fR to \fIdest\fR via the accumulator.
.LP
.nf
\fBmovew \fIsrc\fB, \fIdest\fR
.fi
.IP
Move word \(em move one word from \fIsrc\fR to \fIdest\fR via the accumulator.
.LP
.nf
\fBmovexb \fIsrc\fB, \fIdest\fR
.fi
.IP
Move byte \(em move one byte from \fIsrc\fR to \fIdest\fR via the X register.
.LP
.nf
\fBmovexw \fIsrc\fB, \fIdest\fR
.fi
.IP
Move word \(em move one word from \fIsrc\fR to \fIdest\fR via the X register.
.LP
.nf
\fBmoveyb \fIsrc\fB, \fIdest\fR
.fi
.IP
Move byte \(em move one byte from \fIsrc\fR to \fIdest\fR via the Y register.
.LP
.nf
\fBmoveyw \fIsrc\fB, \fIdest\fR
.fi
.IP
Move word \(em move one word from \fIsrc\fR to \fIdest\fR via the Y register.
.LP
.nf
\fBmovb \fIdest\fB, \fIsrc\fR
.fi
.IP
Move byte \(em move one byte from \fIsrc\fR to \fIdest\fR via the accumulator.
This is distinguished from \fBmoveb\fR in that it has the order of the
operands reversed. This confusing feature is provided for compatibility with
\fBa65\fR.
.LP
.nf
\fBmovw \fIdest\fB, \fIsrc\fR
.fi
.IP
Move word \(em move one word from \fIsrc\fR to \fIdest\fR via the accumulator.
This is distinguished from \fBmovew\fR in that it has the order of the
operands reversed. This confusing feature is provided for compatibility with
\fBa65\fR.
.LP
.nf
\fBclrm \fIn\fB, \fIdest\fR
.fi
.IP
Clear multiple \(em clears (zeros) \fIn\fR bytes starting at \fIdest\fR.
Leaves a zero in the accumulator.
.LP
.nf
\fBclrb \fIdest\fR
\fBclearb \fIdest\fR
.fi
.IP
Clear byte \(em clears (zeros) one byte at \fIdest\fR. Leaves a zero in the
accumulator.
.LP
.nf
\fBclrw \fIdest\fR
\fBclearw \fIdest\fR
.fi
.IP
Clear word \(em clears (zeros) one word at \fIdest\fR. Leaves a zero in the
accumulator.
.sp 1
.SH
\s+2Arithmetic macros\s-2
.nf
\fBaddm \fIn\fB, \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Add multiple \(em adds the \fIn\fR byte numbers found at \fIsrc1\fR and
\fIsrc2\fR and puts the result at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBaddb \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Add byte \(em adds the one byte numbers \fIsrc1\fR and \fIsrc2\fR and puts the
one byte result in \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBaddw \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Add word \(em adds the two byte numbers \fIsrc1\fR and \fIsrc2\fR and puts the
two byte result in \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBsubm \fIn\fB, \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Subtract multiple \(em subtracts the \fIn\fR byte number found at \fIsrc2\fR
from the same sized number found at \fIsrc1\fR and puts the \fIn\fR byte
result in \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBsubb \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Subtract byte \(em subtracts the one byte number \fIsrc2\fR from \fIsrc1\fR
and puts the one byte result in \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBsubw \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Subtract word \(em subtracts the two byte numbers \fIsrc2\fR from \fIsrc1\fR
and puts the two byte result in \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBcmpm \fIn\fB, \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Compare multiple \(em compares the two \fIn\fR byte numbers found at
\fIsrc1\fR and \fIsrc2\fR. Clobbers the accumulator.
.LP
.nf
\fBcmpb \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Compare byte \(em compares the one byte numbers \fIsrc1\fR and \fIsrc2\fR.
Clobbers the accumulator.
.LP
.nf
\fBcmpw \fIsrc1\fB, \fIsrc2\fR
.fi
.IP
Compare word \(em compares the two byte numbers \fIsrc1\fR and \fIsrc2\fR.
Clobbers the accumulator.
.LP
.nf
\fBnegm \fIn\fB, \fIdest\fR
.fi
.IP
Negate multiple \(em negates the \fIn\fR byte number at \fIdest\fR. Clobbers
the accumulator.
.LP
.nf
\fBnegb \fIdest\fR
.fi
.IP
Negate byte \(em negates the one byte number at \fIdest\fR. Clobbers the
accumulator.
.LP
.nf
\fBnegw \fIdest\fR
.fi
.IP
Negate word \(em negates the two byte number at \fIdest\fR. Clobbers the
accumulator.
.LP
.nf
\fBasrm \fIn\fB, \fIdest\fR
.fi
.IP
Arithmetic shift right multiple \(em performs a rightward one-bit arithmetic
shift of the \fIn\fR byte number at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBasrb \fIdest\fR
.fi
.IP
Arithmetic shift right byte \(em performs a rightward one-bit arithmetic
shift of the byte at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBasrw \fIdest\fR
.fi
.IP
Arithmetic shift right word \(em performs a rightward one-bit arithmetic
shift of the word at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBaslm \fIn\fB, \fIdest\fR
.fi
.IP
Arithmetic shift left multiple \(em performs a leftward one-bit arithmetic
shift of the \fIn\fR byte number at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBaslb \fIdest\fR
.fi
.IP
Arithmetic shift left byte \(em performs a leftward one-bit arithmetic
shift of the byte at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBaslw \fIdest\fR
.fi
.IP
Arithmetic shift left word \(em performs a leftward one-bit arithmetic
shift of the word at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBlsrm \fIn\fB, \fIdest\fR
.fi
.IP
Logical shift right multiple \(em performs a rightward one-bit logical shift
of the \fIn\fR byte number at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBlsrb \fIdest\fR
.fi
.IP
Logical shift right byte \(em performs a rightward one-bit logical shift of
the byte at \fIdest\fR. Clobbers the accumulator.
.LP
.nf
\fBlsrw \fIdest\fR
.fi
.IP
Logical shift right word \(em performs a rightward one-bit logical shift of
the word at \fIdest\fR. Clobbers the accumulator.
.SH
.sp 1
\s+2Flow-of-control macros\s-2
.nf
\fBrepeat \fIn\fB { \fIcode\fB }\fR
.fi
.IP
Replicates the block of \fIMacross\fR statements \fIcode\fR \fIn\fR times.
.LP
.nf
\fBloop \fIcounter\fB, \fIstart\fB, \fIend\fB { \fIcode\fB }\fR
.fi
.IP
Generic ``do-loop'' \(em generates 6502 code for a loop that initializes
\fIcounter\fR to \fIstart\fR, and then repeatedly executes \fIcode\fR,
incrementing \fIcounter\fR until it reaches the value \fIend\fR.
\fICounter\fR may be ``\fBx\fR'' to denote the X index register, ``\fBy\fR''
to denote the Y index register, or a memory location. \fIStart\fR and
\fIend\fR may be referenced in any 6502 address mode.
.SH
.sp 1
\s+2Miscellaneous macros\s-2
.nf
\fBmbyte \fIn\fR
.fi
.IP
Generates \fIn\fR zero data bytes.
.bp
.CD
\s+5\fBAppendix \*- Summary of the macros\fR\s-5
.DE
.LP
.nf
\fBaddb \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
\fBaddm \fIn\fB, \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
\fBaddw \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
\fBaslb \fIdest\fR
\fBaslm \fIn\fB, \fIdest\fR
\fBaslw \fIdest\fR
\fBasrb \fIdest\fR
\fBasrm \fIn\fB, \fIdest\fR
\fBasrw \fIdest\fR
\fBclearb \fIdest\fR
\fBclearw \fIdest\fR
\fBclrb \fIdest\fR
\fBclrm \fIn\fB, \fIdest\fR
\fBclrw \fIdest\fR
\fBcmpb \fIsrc1\fB, \fIsrc2\fR
\fBcmpm \fIn\fB, \fIsrc1\fB, \fIsrc2\fR
\fBcmpw \fIsrc1\fB, \fIsrc2\fR
\fBloop \fIcounter\fB, \fIstart\fB, \fIend\fB, \fIcode\fR
\fBlsrb \fIdest\fR
\fBlsrm \fIn\fB, \fIdest\fR
\fBlsrw \fIdest\fR
\fBmbyte \fIn\fR
\fBmovb \fIdest\fB, \fIsrc\fR
\fBmoveb \fIsrc\fB, \fIdest\fR
\fBmovew \fIdest\fB, \fIsrc\fR
\fBmovexb \fIsrc\fB, \fIdest\fR
\fBmovexw \fIsrc\fB, \fIdest\fR
\fBmoveyb \fIsrc\fB, \fIdest\fR
\fBmoveyw \fIsrc\fB, \fIdest\fR
\fBmovm \fIn\fB, \fIdest\fB, \fIsrc\fR
\fBmovmx \fIn\fB, \fIdest\fB, \fIsrc\fR
\fBmovmy \fIn\fB, \fIdest\fB, \fIsrc\fR
\fBmovw \fIsrc\fB, \fIdest\fR
\fBmv2m \fIn\fB, \fIdest1\fB, \fIdest2\fB, \fIsrc\fR
\fBnegb \fIdest\fR
\fBnegm \fIn\fB, \fIdest\fR
\fBnegw \fIdest\fR
\fBphr\fR
\fBphx\fR
\fBphy\fR
\fBplr\fR
\fBplx\fR
\fBply\fR
\fBpushaddr \fIaddress\fR
\fBrepeat \fIn\fB, \fIcode\fR
\fBsubb \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
\fBsubm \fIn\fB, \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
\fBsubw \fIdest\fB, \fIsrc1\fB, \fIsrc2\fR
.fi

85
doc/handyHelpfulHints.t Normal file
View File

@ -0,0 +1,85 @@
Handy Helpful Hints for using make/macross/slinky
1. You need two header files: a header and a sub-header. The sub-header
declares 'define' symbols, zero page labels (as local labels), macros,
functions, and so on. The header includes the sub-header and then
additionally contains 'extern' declarations for all program-space labels and
non-zero page variable-space labels plus 'define' declarations which refer to
externals.
Non-zero page variable-space should be laid out in one file that includes just
the sub-header. The rest of the program should be spread among files each of
which includes the header.
2. In any given Macross assembly (usually one source file plus all of the
other files that it 'include's), you can classify each symbol in two different
orthogonal ways: whether it is global or local on the one hand and whether it
is defined in this assembly or defined in some other assembly.
Being defined means that the symbol has a value which is known and can
therefore be used to generate code. If a symbol has a value when it is
encountered during assembly, then that value can be used immediately.
If not, then we must wait until linking when (presumably) the value will be
known.
Being global means that the symbol's value is known outside of the assembly in
which the symbol is defined (i.e., that the value is "published" in the object
file for use by the linker). Conversely, being local means that the value is
known only in the one assembly.
Let's look at the four possible cases when a symbol is encountered during
assembly:
LOCAL, DEFINED: this is the usual case. The value is used at assembly time.
Multiple independent assemblies can define local symbols with the same names
without conflicting with each other when they are linked.
LOCAL, UNDEFINED: this shouldn't happen. You will get a complaint from the
assembler.
GLOBAL, DEFINED: during assembly, the symbol is treated just like a defined
local symbol. However, the value is "published" in the object file for use by
the linker. The symbol value can be made global either or both of two
different ways: with an 'extern' declaration
extern foo ; makes the symbol 'foo' global
or, if the symbol is a label, by using two colons instead of one
foo:: word 123 ; 'foo' is global
bar: word 456 ; 'bar' is local
If a global symbol is defined in more than one object file, the linker will
complain.
GLOBAL, UNDEFINED: this means that the assembler assumes that the value of the
symbol will be defined at link time. You still have to tell the assembler
that the symbol is global with an 'extern' statement.
Note that all macro, function and variable (Macross variables, not 6502
storage locations used as variables) names MUST be local, as must be struct
names and struct fields. The assembler will complain if you try to declare
one of these 'extern'.
A 'define' symbol must be local if it refers to any global symbols in its
definition.
3. The fewer global symbols there are, the faster the link will run.
4. When juggling a program that consists of multiple source and object files,
only a very foolish person would not use 'make'.
5. Emacs has a very nice feature whereby you can run 'make' under emacs and
then get taken automagically to the errors:
The emacs function 'compile' (or 'new-compile' on some systems), which is
usually bound to ^X^C (also to the shift-F5 key on my Concept terminal; I
don't know about others), will run make and put the output from make (error
messages and so on) in a buffer with a new window.
After compiling with make, the emacs function 'next-error', which is usually
bound to ^X^N (also to the the F5 key on my Concept) will search in the error
message buffer for the first C-compiler-style error message (which is what
Macross outputs), read the file name and line number from the error message
and then (in another window) position the cursor at that line of that file.
Entering this command again takes you to the next error message, and then the
next, and so on. The wonderful thing about this is that if you edit your
source file, emacs keeps track of how you have shifted things around so that
it will always take you to the location of the next error, even if your
editing has invalidated the line numbers in the error messages!

224
doc/linkerReleaseNotes Normal file
View File

@ -0,0 +1,224 @@
An informal introduction to
code relocation
and
multi-file linking
using
Macross and Slinky
To use:
First, let me explain that if you don't want to use the linker and assemble
your programs in pieces, you need do nothing. Macross will continue to
operate for you just as it always has (except that it will be somewhat faster
since it no longer will be keeping track of some stuff internally that only
matters to the linker). If you're not interested stop reading this right now.
There is a new command line option for Macross, '-c'. This signals to the
assembler that, rather than generating a plain old ordinary object file, you
want it to produce a special linkable object file that contains all kinds of
information that the linker will need later. (I know it's obscure, but I'm
running out of letters and the C compiler uses this flag to signal the same
thing (maybe it should be '-m' or would that be even more obscure?)). E.g.:
macross -c -o foo foo.m
To link object files together, you use Slinky. The command is
slinky file1 file2 file3 ...
where file1, file2, etc. were generated by Macross using the '-c' option
described in the previous paragraph. By default the output will go in the
file 's.out' but the aesthetically enlightened will use the '-o' option to
slinky that will name the output file whatever you want. E.g.:
slinky -o foobar file1 file2 file3 ...
will name the output 'foobar' (just like the '-o' option to Macross). The
output file from Slinky will be a standard a65-style object file suitable for
downloading to your Atari or whatever. *Don't* try to directly download an
unlinked object that was produced by Macross using '-c'. Doing so will make
the downloader choke, puke and die (actually, I haven't tried this, but in any
case it will be wrong and the result will most likely be ugly).
Simple, no? Actually no, because...
You need to write your Macross programs in a way that can allow the various
files to be assembled separately. This requires an understanding of two
important concepts: 1. relocation and 2. external symbols.
A Macross relocatable object file consists of a bunch of little pieces of
object code (called 'segments') plus some other bookkeeping info. Each of
these little pieces of object code is either 'absolute' or 'relocatable'.
Being absolute means that a segment is given a fixed, pre-specified location
in memory. Being relocatable means that the segment can go wherever the
linker finds room to put it.
All right, you ask, how do my pieces of code get to be absolute or
relocatable? Well, at any given time, Macross is assembling in either
absolute-mode or relocatable-mode (it starts out in relocatable-mode (always
did, bet you didn't even notice!)). It gets into absolute-mode using the
'org' statement with an absolute-value as the address to org to, i.e.,
org 0x1000
This starts an absolute segment at location 0x1000. The segment continues
until the next 'org' or 'rel' statement. Macross gets into relocatable-mode
via the 'rel' statement:
rel
or by an 'org' statement with a relocatable value as the address to org to
(actually, using an org in this way is, as of the current implementation,
somewhat questionable). The relocatable segment continues until the next
'org' kicks Macross out of relocatable-mode or you use a 'constrain' or
'align' statement. Each of the latter two (in relocatable-mode but not in
absolute-mode) starts a new relocatable segment which is aligned or
constrained appropriately at link-time. Also, a new relocatable segment
starts at the end of the block that is the argument of a 'constrain'
statement (again, in relocatable mode only).
It is important for you to know where (in your source code) relocatable
segments begin and end, because each segment is relocated by the linker
independently of all the others. Thus, even though two segments might be
adjacent in your Macross source, in the eventual linked object they might not
be. Thus relative branches across segment boundaries may go out of range and
you cannot expect the flow of program execution to be continuous from one
segment to another, i.e., that the last instruction in a segment will be
followed immediately by the first instruction of the segment that follows it
in the source. For example, in the following:
...stuff...
and 123
constrain (0x100) {
sta foobar
...more stuff...
you can't assume that the 'sta' will follow the 'and'. So
RULE #1 -- Don't allow program flow of control to fall through from one
segment to the next.
RULE #2 -- Don't do relative branches across segment boundaries ('jmp's and
'jsr's are OK).
COROLLARY -- You can't put an 'align' or 'constrain' statement inside an 'if',
'while', 'do while' or 'do until' statement, and putting one inside a macro is
very likely to result in a weird program bug unless you really understand what
you are doing.
As with segments, a symbol in your Macross program is either absolute or
relocatable. The value of an absolute symbol (called an 'absolute value') is
a location in an absolute segment (or simply a fixed number like 42 or 137).
A relocatable symbol has a value (called a 'relocatable value') which is a
location in a relocatable segment. The important point to note is that the
value of a relocatable symbol is not known until the program is linked and the
relocatable segment to which it refers is given an actual location in memory.
This in turn means that Macross can't do any assembly-time arithmetic with the
symbol since it doesn't know what value to compute with. Since storing away
whole expressions in the object file would be both costly and messy we don't
even try. The only arithmetic operation that the linker knows how to do is
simple addition. Thus, the only operation you can perform with a relocatable
symbol or value is simple addition, and then only in contexts where the result
of the computation will get stored in the resultant object somewhere, such as
the argument to an instruction or a 'byte' or 'word' statement. Thus the
following are OK, for example (let's say 'foo' and 'bar' are relocatable
symbols):
and foo+3
ora bar-10 ; OK since this is just adding -10
word foo+bar
but these are not
and foo*3 ; not addition
ora 10-bar ; can't subtract 'bar'
lda (bar+10)/7 ; even though 'bar' gets added, the result of
; the addition is needed for the division
So,
RULE #3 -- No arithmetic more complicated than simple addition is allowed with
relocatable symbols or values.
Now to explain external symbols...
First of all, you need to understand about symbols being *defined*. When we
say that a symbol is 'defined' we mean that it has a value that the assembler
or linker can use. A symbol gets defined by the Macross 'define' statement or
by being used as a label. In order to actually use a symbol, e.g. as part of
the operand of an instruction, the symbol must be defined *somewhere*.
Now let's say you have a subroutine that is defined in one file (actually, the
label which is associated with the entry point to the subroutine is defined in
that file, but let's not quibble), but which is called (using a 'jsr') from a
second file. Two pieces of information need to be given to Macross when it
assembles these files. In the first file, where the subroutine label is
defined, you need to tell Macross, "Hey, this label is going to be used
outside of this file, so put something in the object file that will tell the
linker that it's here." In the second file, where the label is used (but not
defined), you need to tell Macross, "Yes, I know this symbol isn't defined
here. Don't worry about it. It's defined elsewhere and the linker will worry
about it." Both of these pieces of information are conveyed by declaring the
symbol to be external using the Macross 'extern' statement. E.g., in the
first file:
extern foo
...stuff...
foo: ...more stuff...
rts
and in the second file:
extern foo
...stuff...
jsr foo
...more stuff...
In addition to this, a shorthand form of declaring a label to be external when
it is defined is supported: you simply use two colons instead of one. In our
example above, then, the first file could be:
...stuff...
foo:: ...more stuff...
rts
and the result would be exactly the same. So,
RULE #4 -- If you want a symbol's value to be carried across multiple files,
that symbol MUST be declared external in the file where it is defined and in
all files in which it is used.
Note that, as with relocatable symbols, symbols which are defined externally
do not have a value which is known to Macross at assembly-time (though symbols
which are external but which are defined in a given file do have such a value
presuming that they are not also relocatable). This means that the same
restrictions about arithmetic on relocatable symbols apply to externally
defined symbols:
RULE #3a -- No arithmetic more complicated than simple addition is allowed
with externally defined symbols.
Not to belabor the obvious, but it is of course an error to define an external
symbol in more than one file. The linker will catch this and complain if you
try.
In summary then:
RULE #1 -- Don't allow program flow of control to fall through from one
segment to the next.
RULE #2 -- Don't do relative branches across segment boundaries ('jmp's and
'jsr's are OK).
COROLLARY -- You can't put an 'align' or 'constrain' statement inside an 'if',
'while', 'do while' or 'do until' statement, and putting one inside a macro is
very likely to result in a weird program bug unless you really understand what
you are doing.
RULE #3 -- No arithmetic more complicated than simple addition is allowed with
relocatable symbols or values or symbols which are defined externally.
RULE #4 -- If you want a symbol's value to be carried across multiple files,
that symbol MUST be declared external in the file in which it is defined and
in all files in which it is used.

315
doc/macros.itr Normal file
View File

@ -0,0 +1,315 @@
;
; potentially popular macros for the macross assembler
;
; 11-Jan-85 cbm converted for Macross from original a65
;
mif (!isDefined(_macros_)) {
define _macros_ = 1
;
; push and pop X and Y registers
;
macro phx {
txa
pha
}
macro plx {
pla
tax
}
macro phy {
tya
pha
}
macro ply {
pla
tay
}
macro call arg {
jsr arg
}
macro return {
rts
}
macro callret arg {
jmp arg ; same as jsr arg; rts
}
macro save arg {
lda arg
pha
}
macro restore arg {
pla
sta arg
}
; ================================================================
; some auxiliary functions for the macros that follow
;
; MAKE-FIRST-BYTE - access low byte for any addressing mode
function makeFirstByte(operand) {
mif (isImmediateMode(operand)) {
freturn(/operand)
} melse {
freturn(operand)
}
}
; MAKE-SECOND-BYTE - access high byte for any addr mode except (post y zzz)
function makeSecondByte(operand) {
mif (isImmediateMode(operand)) {
freturn(?operand)
} melse {
freturn(operand + 1)
}
}
; MAKE-NTH-BYTE - similarly access arbitrary byte
function makeNthByte(operand, n) {
mif (isImmediateMode(operand)) {
freturn((operand >> (8 * (n - 1))) & 0xFF)
} melse {
freturn(operand + n - 1)
}
}
; ================================================================
; MOVM, MOVEB, MOVB, MOVEW, MOVW, CLEARB, and CLEARW
; Note that the args on MOVEx are src,dst as opposed to
; MOVx, which uses dst,src.
;
; MOVM - move multiple
macro movm n, dst, src {
mvariable i
mfor (i=1, i<=n, i++) {
lda makeNthByte(src, i)
sta makeNthByte(dst, i)
}
}
; MOVEB - move byte from src to dst
macro moveb src, dst {
lda src
sta dst
}
; MOVB - for those who like their destination before their source
macro movb dst, src {
lda src
sta dst
}
; MOVEW - move word from src to dst
; works for all addressing moves EXCEPT (post y zzz)
macro movew src, dst {
lda makeFirstByte(src)
sta makeFirstByte(dst)
lda makeSecondByte(src)
sta makeSecondByte(dst)
}
; MOVW - and another with destination before source
; works for all addressing moves EXCEPT (post y zzz)
macro movw dst, src {
lda makeFirstByte(src)
sta makeFirstByte(dst)
lda makeSecondByte(src)
sta makeSecondByte(dst)
}
; CLEARB - zero byte dst
macro clearb dst {
lda #0
sta dst
}
; CLEARW - zero word dst
; works for all addressing modes EXCEPT (post y dst)
macro clearw dst {
lda #0
sta makeFirstByte(dst)
sta makeSecondByte(dst)
}
; ================================================================
; the general macros
;
; MOVWB - move byte SRC to word DST
; works for all addressing modes EXCEPT (post y zzz)
macro movwb dst, src {
lda src
sta makeFirstByte(dst)
lda #0
sta makeSecondByte(dst)
}
; ADDM - add multiple
macro addm n, dst, src, src1 {
mvariable i
clc
mfor (i=1, i<=n, i++) {
lda makeNthByte(src, i)
adc makeNthByte(src1, i)
sta makeNthByte(dst, i)
}
}
; ADDB - byte dst = byte src0 + byte src1
macro addb dst, src0, src1 {
clc
lda src0
adc src1
sta dst
}
; ADDW - word dst = word src0 + word src1
; works for all addressing modes EXCEPT (post y zzz)
macro addw dst, src0, src1 {
clc
lda makeFirstByte(src0)
adc makeFirstByte(src1)
sta makeFirstByte(dst)
lda makeSecondByte(src0)
adc makeSecondByte(src1)
sta makeSecondByte(dst)
}
; ADDWWB - word dst = word src0 + byte src1
; works for all addressing modes EXCEPT (post y zzz)
macro addwwb dst, src0, src1 {
clc
lda makeFirstByte(src0)
adc src1
sta makeFirstByte(dst)
lda makeSecondByte(src0)
adc #0
sta makeSecondByte(dst)
}
; SUBB - byte dst = byte src0 - byte src1
macro subb dst, src0, src1 {
sec
lda src0
sbc src1
sta dst
}
; SUBW - word dst = word src0 - word src1
; works for all addressing modes EXCEPT (post y zzz)
macro subw dst, src0, src1 {
sec
lda makeFirstByte(src0)
sbc makeFirstByte(src1)
sta makeFirstByte(dst)
lda makeSecondByte(src0)
sbc makeSecondByte(src1)
sta makeSecondByte(dst)
}
; SUBWWB - word dst = word src0 - byte src1
; works for all addressing modes EXCEPT (post y zzz)
macro subwwb dst, src0, src1 {
sec
lda makeFirstByte(src0)
sbc src1
sta makeFirstByte(dst)
lda makeSecondByte(src0)
sbc #0
sta makeSecondByte(dst)
}
; ================================================================
; cmpm, cmpb, cmpw
; compare two quantities (arbitrary length, byte, and word)
; set the condition flags following s0-s1
;
macro cmpm n, s0, s1 {
mvariable i
mfor (i=1, i<=n, i++) {
lda makeNthByte(s0, i)
sbc makeNthByte(s1, i)
}
}
macro cmpb s0, s1 {
sec
lda s0
sbc s1
}
macro cmpw s0, s1 {
sec
lda makeFirstByte(s0)
sbc makeFirstByte(s1)
lda makeSecondByte(s0)
sbc makeSecondByte(s1)
}
;
; ASLM - multiply all by 2
macro aslm n, s0 {
mvariable i
asl s0
mfor (i = 2, i <= n, i++) {
rol makeNthByte(s0, i)
}
}
; ================================================================
; asrm, asrb, asrw
; Arithmetic Shift Right (with sign extend).
;
macro asrm n, s0 {
mvariable i = n
lda makeNthByte(s0, i)
cmp #0x80
mwhile (i > 0) {
ror makeNthByte(s0, i--)
}
}
macro asrb s0 {
lda s0
cmp #0x80
ror s0
}
macro asrw s0 {
lda makeSecondByte(s0)
cmp #0x80
ror makeSecondByte(s0)
ror makeFirstByte(s0)
}
; ================================================================
; repeat n {code. . .}
; repeat n instances of code. e.g.,
; repeat 6 {
; lda x[foo]
; sta x[bar]
; inx
; }
; will generate inline code to move 6 bytes
;
macro repeat count, blockToRepeat {
mvariable i = count
mwhile (i-- > 0) {
blockToRepeat
}
}
macro includef fname {
printf("Including %s\n", fname)
include fname
}
} ; *** end -- mif (!isDefined(_macros_)) ***

108
doc/macross.1 Normal file
View File

@ -0,0 +1,108 @@
.TH MACROSS 1 "27 November 1985"
.UC 4
.SH NAME
macross \- Macross assembler
.SH SYNOPSIS
.B macross
[ option ] ... file ...
.SH DESCRIPTION
.I Macross
is a fancy macro cross assembler for the 6502.
.I Macross
assembles the given files in the order specified on the command line. Macross
source file names must end with ``\fB.m\fR''.
.PP
The following options are interpreted by
.IR macross .
.TP
.BI \-l " listfile"
Produce an assembler listing in the file
.IR listfile
showing the object code generated. If
.IR listfile
is ``\fB-\fR'' the listing will be printed on the standard output.
.TP
.B \-m
When listing is enabled, causes the assembler to include in the listing
synthesized lines showing the code generated by macros.
.TP
.B \-g
Suppress assembly-time garbage collection of unused dynamic storage space
(may speed up small assemblies).
.TP
.B \-d
Print esoteric debug information showing parse trees generated by the parser.
(Generally not of interest to the casual user).
.TP
.B \-D
Print even more esoteric debug information showing parser states. (Almost
certainly not of interest to the casual user).
.TP
.B \-e
Print esoteric debug information showing emitted binary as it is generated.
(Even duller than parser states).
.TP
.BI \-s " dumpfile"
Place a symbol table dump in the file
.IR dumpfile
at the end of assembly. If
.IR dumpfile
is ``\fB-\fR'', the symbol table dump will go to the standard output.
.TP
.BI \-S " dumpfile"
As \fB-s\fR, except also dump internal symbols normally not of interest.
.TP
.BI \-h " dumpfile"
As \fB-s\fR, except that the symbols are dumped in the form of Macross
\fBdefine\fR statements.
.TP
.BI \-H " dumpfile"
As \fB-h\fR, except that it only dumps defined external symbols.
.TP
.B \-a
If a symbol dump has been specified, have it include unreferenced \fBdefine\fR
symbols (these are not normally displayed in a symbol table dump listing).
.TP
.BI \-o " output"
Name the final output file
.IR output .
If this option is not used the output will be placed in the file `m.out'.
.TP
.BI \-P " processor"
Assemble for the target processor
.IR processor .
The allowed values are \fB6502\fR and \fB68000\fR. If this option is not
used \fB6502\fR will be assumed.
.TP
.B \-c
Make the object file produced be a linkable object suitable for use with the
\fIslinky\fR linker.
.TP
.B \-p
Produce position independent code for the \fBelse\fP clause of
\fBif-then-else\fP statements. This is accomplished by emitting a
\fBbcc/bcs\fP branch pair instead of a \fBjmp\fP instruction.
.TP
.B \-t
Be terse about error messages. Output no more than one error message for a
given line.
.TP
.B \-u
Don't discard the temporary intermediate files generated during the listing
process when the assemble exits (used for debugging the listing facility).
.TP
.B \-v
Print the \fImacross\fP version number on the standard output before beginning
assembly.
.TP
.B \-B
When generating branches for nested \fBif-then-else\fR constructs, generate
code like that generated by \fBa65\fR. This code will be slightly less
efficient but will be completely backwards compatible.
.SH "SEE ALSO"
slinky(1), the Macross manual
.SH DIAGNOSTICS
The diagnostics produced by Macross are \fIintended\fR to be self-explanatory.
.SH BUGS
Errors in the input may sometimes produce bizarre and unexpected results.
There are probably lots of bugs that are as yet undetected.

66
doc/slinky.1 Normal file
View File

@ -0,0 +1,66 @@
.TH SLINKY 1 "28 February 1986"
.UC 4
.SH NAME
slinky \- slinky linker
.SH SYNOPSIS
.B slinky
[ option ] ... file ...
.SH DESCRIPTION
.I Slinky
is a multi-file relocating object linker designed to be used in conjunction
with the
.I Macross
assembler.
.I Slinky
links the given
.I Macross
object files in the order specified on the command line together into one
executable object file.
.PP
The following options are interpreted by
.IR slinky .
.TP
.B \-d
Print esoteric debug information (you don't want to use this).
.TP
.B \-e
Print different esoteric debug information (you don't want to use this
either).
.TP
.B \-v
Print the \fIslinky\fP version number on the standard output before linking.
.TP
.BI \-l " hexaddress"
By default, \fIslinky\fP starts putting relocatable modules at location 0x100.
The \fB-l\fR option lets you tell it to put things anywhere. This option can
be used more than once in a single link command and can be interspersed with
the names of the object files being linked. Thus
.br
\fBslinky foo.obj -l 0x3800 bar.obj baz.obj -l 0x5000 snood.obj\fP
.br
loads `foo.obj' starting at location 0x100, `bar.obj' and `baz.obj'
consecutively starting at location 0x3800 and `snood.obj' starting at location
0x5000.
.TP
.BI \-o " output"
Name the final output file
.IR output .
If this option is not used the output will be placed in the file `s.out'.
.TP
.BI \-m " mapfile"
Generate a load map listing, showing the values of all symbols after linking
and put it in the file
.IR mapfile .
If
.IR mapfile
is ``\fB-\fR'', the load map will go to the standard output.
.TP
.B \-n
If generating a load map, suppress the printing of the names of the files that
reference each symbol.
.SH "SEE ALSO"
macross(1), the Macross manual
.SH DIAGNOSTICS
The diagnostics produced by Slinky are \fIintended\fR to be self-explanatory.
.SH BUGS
Who knows what bugs lurk there? Nobody's used it yet!

2124
doc/writeup_6502.itr Normal file

File diff suppressed because it is too large Load Diff

2262
doc/writeup_68000.itr Normal file

File diff suppressed because it is too large Load Diff

47
driver.c Normal file
View File

@ -0,0 +1,47 @@
/*
driver.c -- Top level driver program for all versions of Macross
Chip Morningstar -- Lucasfilm Ltd.
3-May-1985
*/
#include <stdio.h>
#define MACROSS_6502 "/u1/gg/bin/macross_6502"
#define MACROSS_68000 "/u1/gg/bin/macross_68000"
char *m6502 = "6502";
char *m68000 = "68000";
char **mlist;
main(argc, argv)
char **argv;
{
char *processor = m6502;
int i;
int j;
mlist = (char **)calloc(argc + 1, sizeof (char **));
for (i=1, j=1; i<argc; i++) {
if (argv[i][0] == '-' && argv[i][1]== 'P') {
processor = argv[++i];
} else {
mlist[j++] = argv[i];
}
}
mlist[0] = processor;
mlist[j] = NULL;
if (strcmp(processor, m6502) == 0) {
execv(MACROSS_6502, mlist);
fprintf(stderr, "Macross: driver can't fork to %s for some reason\n", MACROSS_6502);
} else if (strcmp(processor, m68000) == 0) {
execv(MACROSS_68000, mlist);
fprintf(stderr, "Macross: driver can't fork to %s for some reason\n", MACROSS_68000);
} else {
fprintf(stderr, "Macross: '%s' is an unknown processor\n", processor);
}
exit(1);
}

BIN
emitBranch.o Normal file

Binary file not shown.

157
emitBranch_6502.c Normal file
View File

@ -0,0 +1,157 @@
/*
emitBranch_6502.c -- Routines to deal with code generation for
branches and jumps in the Macross assembler (6502
version).
Chip Morningstar -- Lucasfilm Ltd.
23-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/* emitRelativeBranch emits a relative branch instruction for the 6502,
branching from the current location given a condition to branch upon and a
target address. */
void
emitRelativeBranch(condition, target, fixupLocation)
conditionType condition;
valueType *target;
valueType fixupLocation[COMPOUND_BRANCH_MAX];
{
int i;
#define COMPOUND 0x00
#define BPL_OPCODE 0x10
#define BMI_OPCODE 0x30
#define BVC_OPCODE 0x50
#define BVS_OPCODE 0x70
#define BCC_OPCODE 0x90
#define BCS_OPCODE 0xB0
#define BNE_OPCODE 0xD0
#define NOP_OPCODE 0xEA
#define BEQ_OPCODE 0xF0
static byte conditionalBranchOpcodes[] = {
/* CARRY_COND */ BCS_OPCODE,
/* ZERO_COND */ BEQ_OPCODE,
/* NEGATIVE_COND */ BMI_OPCODE,
/* OVERFLOW_COND */ BVS_OPCODE,
/* LT_COND */ BCC_OPCODE,
/* LEQ_COND */ COMPOUND,
/* SLT_COND */ COMPOUND,
/* SLEQ_COND */ COMPOUND,
/* ALWAYS_COND */ NOP_OPCODE,
/* NOT_CARRY_COND */ BCC_OPCODE,
/* NOT_ZERO_COND */ BNE_OPCODE,
/* NOT_NEGATIVE_COND */ BPL_OPCODE,
/* NOT_OVERFLOW_COND */ BVC_OPCODE,
/* GEQ_COND */ BCS_OPCODE,
/* GT_COND */ COMPOUND,
/* SGEQ_COND */ COMPOUND,
/* SGT_COND */ COMPOUND,
/* NEVER_COND */ NOP_OPCODE
};
#define conditionalFixup(n) if (fixupLocation != NULL) \
fixupLocation[n] = currentLocationCounter; \
emitRelativeByteOffset(target);
if (fixupLocation != NULL)
for (i=0; i<COMPOUND_BRANCH_MAX; i++)
fixupLocation[i].value = -1;
if (conditionalBranchOpcodes[(int)condition] != COMPOUND) {
emitByte(conditionalBranchOpcodes[(int)condition]);
conditionalFixup(0);
} else switch (condition) {
case GT_COND:
emitByte(BEQ_OPCODE); emitByte(2);
emitByte(BCS_OPCODE); conditionalFixup(0);
break;
case LEQ_COND:
emitByte(BCC_OPCODE); conditionalFixup(0);
emitByte(BEQ_OPCODE); conditionalFixup(1);
break;
case SGEQ_COND:
emitByte(BVS_OPCODE); emitByte(4);
emitByte(BPL_OPCODE); conditionalFixup(0);
emitByte(BMI_OPCODE); emitByte(2);
emitByte(BMI_OPCODE); conditionalFixup(1);
break;
case SGT_COND:
emitByte(BEQ_OPCODE); emitByte(8);
emitByte(BVS_OPCODE); emitByte(4);
emitByte(BPL_OPCODE); conditionalFixup(0);
emitByte(BMI_OPCODE); emitByte(2);
emitByte(BMI_OPCODE); conditionalFixup(1);
break;
case SLEQ_COND:
emitByte(BEQ_OPCODE); conditionalFixup(0);
emitByte(BVS_OPCODE); emitByte(4);
emitByte(BMI_OPCODE); conditionalFixup(1);
emitByte(BPL_OPCODE); emitByte(2);
emitByte(BPL_OPCODE); conditionalFixup(2);
break;
case SLT_COND:
emitByte(BVS_OPCODE); emitByte(4);
emitByte(BMI_OPCODE); conditionalFixup(0);
emitByte(BPL_OPCODE); emitByte(2);
emitByte(BPL_OPCODE); conditionalFixup(1);
break;
default:
botch("non-compound condition leaked thru!\n");
break;
}
}
/* emitJump emits a 6502 jump instruction given the target address */
simpleFixupListType *
emitJump(target, previousFixups)
valueType *target;
simpleFixupListType *previousFixups;
{
simpleFixupListType *result;
valueType picFixup[COMPOUND_BRANCH_MAX];
simpleFixupListType *buildSimpleFixupList();
#define JUMP_OPCODE 0x4C
result = previousFixups;
if (positionIndependentCodeMode) {
if (target == NULL) {
emitRelativeBranch(CARRY_COND, NULL, picFixup);
result = buildSimpleFixupList(picFixup[0], result);
emitRelativeBranch(NOT_CARRY_COND, NULL, picFixup);
result = buildSimpleFixupList(picFixup[0], result);
} else {
emitRelativeBranch(CARRY_COND, target, NULL);
emitRelativeBranch(NOT_CARRY_COND, target, NULL);
}
} else {
emitByte(JUMP_OPCODE);
if (target == NULL) {
result = buildSimpleFixupList(currentLocationCounter,
result);
emitWord(0);
} else {
if (target->kindOfValue != ABSOLUTE_VALUE)
noteAnonymousReference();
emitWordValue(target);
}
}
return(result);
}

116
emitBranch_68000.c Normal file
View File

@ -0,0 +1,116 @@
/*
emitBranch_68000.c -- Routines to deal with code generation for
branches and jumps in the Macross assembler (68000
version).
Chip Morningstar -- Lucasfilm Ltd.
29-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/* emitRelativeBranch emits a relative branch instruction for the 68000,
branching from the current location given a condition to branch upon and a
target address. */
void
emitRelativeBranch(condition, target, fixupLocation)
conditionType condition;
valueType *target;
valueType *fixupLocation;
{
int i;
#define BCS_OPCODE 0x65
#define BCC_OPCODE 0x64
#define BEQ_OPCODE 0x67
#define BGE_OPCODE 0x6C
#define BGT_OPCODE 0x6E
#define BHI_OPCODE 0x62
#define BLE_OPCODE 0x6F
#define BLS_OPCODE 0x63
#define BLT_OPCODE 0x6D
#define BMI_OPCODE 0x6B
#define BNE_OPCODE 0x66
#define BPL_OPCODE 0x6A
#define BVC_OPCODE 0x68
#define BVS_OPCODE 0x69
#define BRA_OPCODE 0x60
static byte conditionalBranchOpcodes[] = {
/* CARRY_COND */ BCS_OPCODE,
/* EQUAL_COND */ BEQ_OPCODE,
/* OVERFLOW_COND */ BVS_OPCODE,
/* MINUS_COND */ BMI_OPCODE,
/* LT_COND */ BLT_OPCODE,
/* LEQ_COND */ BLE_OPCODE,
/* LOW_OR_SAME */ BLS_OPCODE,
/* ALWAYS_COND */ BRA_OPCODE,
/* NOT_CARRY_COND */ BCC_OPCODE,
/* NOT_EQUAL_COND */ BNE_OPCODE,
/* NOT_OVERFLOW_COND */ BVC_OPCODE,
/* PLUS_COND */ BPL_OPCODE,
/* GEQ_COND */ BGE_OPCODE,
/* GT_COND */ BGT_OPCODE,
/* HIGH_COND */ BHI_OPCODE,
/* NEVER_COND */ 0,
};
if (fixupLocation != NULL)
fixupLocation->value = -1;
if (condition == NEVER_COND)
return;
emitByte(conditionalBranchOpcodes[(int)condition]);
if (isByteOffset(target - (currentLocationCounter.value + 1))) {
if (fixupLocation != NULL)
*fixupLocation = currentLocationCounter;
emitRelativeByteOffset(target);
} else {
emitByte(0);
if (fixupLocation != NULL)
*fixupLocation = currentLocationCounter;
emitRelativeWordOffset(target);
}
}
/* emitJump emits a 68000 jump instruction given the target address */
simpleFixupListType *
emitJump(target, previousFixups)
valueType *target;
simpleFixupListType *previousFixups;
{
simpleFixupListType *result;
simpleFixupListType *buildSimpleFixupList();
#define JUMP_OPCODE_WORD 0x4EF8
#define JUMP_OPCODE_LONG 0x4EF9
#define JUMP_OPCODE_PC_REL 0x4EFA
result = previousFixups;
if (target == NULL) {
emitWord(JUMP_OPCODE_LONG);
result = buildSimpleFixupList(currentLocationCounter, result);
emitWord(0);
} else if (target->kindOfValue != ABSOLUTE_VALUE) {
emitWord(JUMP_OPCODE_LONG);
noteAnonymousReference();
emitLongValue(target);
} else if (isWordOffset(target->value-currentLocationCounter.value)) {
emitWord(JUMP_OPCODE_PC_REL);
emitWord(target->value - currentLocationCounter.value);
} else if (isWord(target)) {
emitWord(JUMP_OPCODE_WORD);
emitWord(target);
} else {
emitWord(JUMP_OPCODE_LONG);
emitLong(target);
}
return(result);
}

560
emitStuff.c Normal file
View File

@ -0,0 +1,560 @@
/*
emitStuff.c -- Routines to actually generate binary stuff for the
Macross assembler.
Chip Morningstar -- Lucasfilm Ltd.
14-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/*
Emitted code is stored in places that are allocated dynamically as they
are needed. This saves us from having to keep umpteenK of code buffer
around ALL the time and also lets us keep track of where code has actually
been put for purposes of generating the final object module.
The structure of the code storage is: there are two code region structs
(type 'codeRegionType'), one each for absolute and relocatable code. These
are stored in the global array 'codeRegions' which is indexed by
'currentCodeMode' which in turn indicates whether we are emitting aboslute
or relocatable code. Each of these region structs contains a vector of
[currently 64] pointers to code segment structs (type 'codeSegmentType').
Each code segment represents a [currently 1Kbyte] piece of the target
processor address space; it contains the high and low addresses within
that space that have been occupied up until now and a pointer to a
[1Kbyte] buffer that actually contains the code.
Initially, the code regions are filled with vectors of null pointers and
there are no code segments allocated. As code is emitted, the space for
the code segments and their associated buffers is allocated using 'malloc'.
Only the actual buffers needed are allocated, resulting in substantial
storage savings.
A complication that can arise from Macross 'struct's. Structs are
assembled in a small scratch buffer and then transferred to the main code
buffers as needed.
*/
/* incarnateCodeBuffer causes code buffer space to actually be allocated */
void
incarnateCodeBuffer(bufferNum, bufferKind)
int bufferNum;
codeBufferKindType bufferKind;
{
codeSegmentType *newCodeSegment;
codeBufferType *newCodeBuffer;
int i;
newCodeSegment = typeAlloc(codeSegmentType);
newCodeBuffer = typeAlloc(codeBufferType);
for (i=0; i<CODE_BUFFER_SIZE; i++)
(*newCodeBuffer)[i] = 0;
newCodeSegment->codeStartAddress = 0xFFFF + 1;
newCodeSegment->codeEndAddress = -1;
newCodeSegment->codeBuffer = newCodeBuffer;
codeRegions[(int)bufferKind]->codeSegments[bufferNum] =
newCodeSegment;
}
/* putByte actually puts a byte in code storage somewhere, given the address
and the byte itself. It tracks down the appropriate code buffer, taking
care to make sure said buffer actually exists before using it. */
void
putByte(address, byteValue)
addressType address;
byte byteValue;
{
int bufferNum;
int bufferPos;
codeBufferType *theBuffer;
codeSegmentType *theSegment;
bufferNum = bufferNumber(address);
bufferPos = bufferPosition(address);
if (bufferNum >= CODE_BUFFERS_IN_ADDRESS_SPACE) {
fatalError(ADDRESS_OUTSIDE_ADDRESS_SPACE_ERROR, address);
return;
}
theSegment = codeRegions[(int)currentCodeMode]->codeSegments[
bufferNum];
if (theSegment == NULL) {
incarnateCodeBuffer(bufferNum, currentCodeMode);
theSegment = codeRegions[(int)currentCodeMode]->codeSegments[
bufferNum];
}
theBuffer = theSegment->codeBuffer;
if (currentCodeMode == RELOCATABLE_BUFFER && address >
relocatableHighWaterMark)
relocatableHighWaterMark = address;
if (address > theSegment->codeEndAddress)
theSegment->codeEndAddress = address;
if (address < theSegment->codeStartAddress)
theSegment->codeStartAddress = address;
if (address > codeRegions[(int)currentCodeMode]->regionEndAddress)
codeRegions[(int)currentCodeMode]->regionEndAddress = address;
if (address < codeRegions[(int)currentCodeMode]->regionStartAddress)
codeRegions[(int)currentCodeMode]->regionStartAddress =
address;
(*theBuffer)[bufferPos] = byteValue;
}
/* mapByte is like 'putByte', but places its values in the struct assembly
buffer */
void
mapByte(address, byteValue)
int address;
byte byteValue;
{
if (address < MAXIMUM_ALLOWED_STRUCT_SIZE)
structScratchBuffer[address] = byteValue;
}
/* emitByte outputs one byte at the current location in either the current
code buffer or the current struct assembly buffer */
void
emitByte(byteValue)
byte byteValue;
{
if (debug || emitPrint)
if (structNestingDepth == 0)
printf("emitByte(%x: %x)\n", currentLocationCounter.
value, byteValue);
else
printf("emitByte in struct (%x: %x)\n",
currentFieldOffset, byteValue);
if (structNestingDepth == 0) {
putByte(currentLocationCounter.value++, byteValue);
} else {
mapByte(currentFieldOffset++, byteValue);
}
}
/* emitWord similarly emits a word */
void
emitWord(wordValue)
wordType wordValue;
{
byteToWordType convert;
int loByte, hiByte;
/* We hack around with this, even though it's less portable, so that we can
avoid doing a division and a modulo on every word we emit (since code
emission is in the inner loop). */
#ifdef BYTESWAPPED
loByte = 1;
hiByte = 0;
#else
loByte = 0;
hiByte = 1;
#endif
convert.wordPart = wordValue;
if (debug || emitPrint)
if (structNestingDepth == 0)
printf("emitWord(%x: %x)\n", currentLocationCounter.
value, wordValue);
else
printf("emitWord in struct (%x: %x)\n",
currentFieldOffset, wordValue);
if (structNestingDepth == 0) {
#if TARGET_CPU == CPU_6502
putByte(currentLocationCounter.value++,
convert.bytePart[loByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[hiByte]);
#else if TARGET_CPU == CPU_68000
putByte(currentLocationCounter.value++,
convert.bytePart[hiByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[loByte]);
#endif
} else {
#if TARGET_CPU == CPU_6502
mapByte(currentFieldOffset++, convert.bytePart[loByte]);
mapByte(currentFieldOffset++, convert.bytePart[hiByte]);
#else if TARGET_CPU == CPU_68000
mapByte(currentFieldOffset++, convert.bytePart[hiByte]);
mapByte(currentFieldOffset++, convert.bytePart[loByte]);
#endif
}
}
/* emitLong similarly emits a long */
void
emitLong(longValue)
longType longValue;
{
byteToLongType convert;
int loByte, secondByte, thirdByte, hiByte;
/* We hack around with this, even though it's less portable, so that we can
avoid doing a division and a modulo on every long we emit (since code
emission is in the inner loop). */
#ifdef BYTESWAPPED
/* Sun workstation... */
loByte = 3;
secondByte = 2;
thirdByte = 1;
hiByte = 0;
#else
/* Vax... */
loByte = 0;
secondByte = 1;
thirdByte = 2;
hiByte = 3;
#endif
convert.longPart = longValue;
if (debug || emitPrint)
if (structNestingDepth == 0)
printf("emitLong(%x: %x)\n", currentLocationCounter.
value, longValue);
else
printf("emitLong in struct (%x: %x)\n",
currentFieldOffset, longValue);
if (structNestingDepth == 0) {
#if TARGET_CPU == CPU_6502
putByte(currentLocationCounter.value++,
convert.bytePart[loByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[secondByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[thirdByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[hiByte]);
#else if TARGET_CPU == CPU_68000
putByte(currentLocationCounter.value++,
convert.bytePart[hiByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[thirdByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[secondByte]);
putByte(currentLocationCounter.value++,
convert.bytePart[loByte]);
#endif
} else {
#if TARGET_CPU == CPU_6502
mapByte(currentFieldOffset++, convert.bytePart[loByte]);
mapByte(currentFieldOffset++, convert.bytePart[secondByte]);
mapByte(currentFieldOffset++, convert.bytePart[thirdByte]);
mapByte(currentFieldOffset++, convert.bytePart[hiByte]);
#else if TARGET_CPU == CPU_68000
mapByte(currentFieldOffset++, convert.bytePart[hiByte]);
mapByte(currentFieldOffset++, convert.bytePart[thirdByte]);
mapByte(currentFieldOffset++, convert.bytePart[secondByte]);
mapByte(currentFieldOffset++, convert.bytePart[loByte]);
#endif
}
}
/* emitByteValue takes the byte to be emitted out of a 'valueType' */
void
emitByteValue(byteValue)
valueType *byteValue;
{
if (byteValue->kindOfValue == ABSOLUTE_VALUE || byteValue->kindOfValue ==
RELOCATABLE_VALUE || byteValue->kindOfValue == UNDEFINED_VALUE) {
if (byteCheck(byteValue->value) && byteValue->kindOfValue!=FAIL) {
if (debug || emitPrint) {
if (structNestingDepth == 0)
printf("emitByteValue(%x: ",currentLocationCounter.value);
else
printf("emitByteValue in struct (%x:",currentFieldOffset);
printValue(byteValue);
printf(")\n");
}
emitByte(byteValue->value);
}
} else {
if (byteValue->kindOfValue != FAIL)
error(NON_ADDRESS_BYTE_VALUE_ERROR, valueKindString(byteValue->
kindOfValue));
}
}
/* emitString similarly spits out a string of bytes */
void
emitString(string)
stringType *string;
{
if (debug || emitPrint)
if (structNestingDepth == 0)
printf("emitString(%x: \"%s\")\n",
currentLocationCounter.value, string);
else
printf("emitString in struct(%x: \"%s\")\n",
currentFieldOffset, string);
/* Horrible terrible no good very bad cretinous ugly hack, but no graceful
way to avoid it: a 0xFF byte in the string means output a 0x00 byte in
the object. This is so we can embed nuls in strings without embedding
nuls in strings, so to speak. We assume that the character 0xFF is not
likely to be needed since ASCII (and ATASCII) is a seven bit character
code. */
while (*string != NULL)
if ((*string & 0xFF) == 0xFF) {
emitByte('\0');
string++;
} else {
emitByte(*string++);
}
}
/* emitWordValue emits a word out of a 'valueType' */
void
emitWordValue(wordValue)
valueType *wordValue;
{
if (wordValue->kindOfValue == ABSOLUTE_VALUE || wordValue->kindOfValue ==
RELOCATABLE_VALUE || wordValue->kindOfValue == UNDEFINED_VALUE) {
if (wordCheck(wordValue->value) && wordValue->kindOfValue!=FAIL) {
if (debug || emitPrint) {
if (structNestingDepth == 0)
printf("emitWordValue(%x: ",currentLocationCounter.value);
else
printf("emitWordValue in struct (%x:",currentFieldOffset);
printValue(wordValue);
printf(")\n");
}
emitWord(wordValue->value);
}
} else {
if (wordValue->kindOfValue != FAIL)
error(NON_ADDRESS_WORD_VALUE_ERROR, valueKindString(wordValue->
kindOfValue));
}
}
/* emitLongValue emits a long out of a 'valueType' */
void
emitLongValue(longValue)
valueType *longValue;
{
if (longValue->kindOfValue == ABSOLUTE_VALUE || longValue->kindOfValue ==
RELOCATABLE_VALUE || longValue->kindOfValue == UNDEFINED_VALUE) {
if (longValue->kindOfValue != FAIL) {
if (debug || emitPrint) {
if (structNestingDepth == 0)
printf("emitLongValue(%x: ",currentLocationCounter.value);
else
printf("emitLongValue in struct (%x:",currentFieldOffset);
printValue(longValue);
printf(")\n");
}
emitLong(longValue->value);
}
} else {
if (longValue->kindOfValue != FAIL)
error(NON_ADDRESS_LONG_VALUE_ERROR, valueKindString(longValue->
kindOfValue));
}
}
/* pokeByteValue is like 'emitByte' but it's random access */
void
pokeByteValue(location, value)
addressType location;
valueType *value;
{
currentLocationCounter.value = location;
emitByteValue(value);
}
/* ditto pokeWordValue */
void
pokeWordValue(location, value)
addressType location;
valueType *value;
{
currentLocationCounter.value = location;
emitWordValue(value);
}
/* ditto pokeLongValue */
void
pokeLongValue(location, value)
addressType location;
valueType *value;
{
currentLocationCounter.value = location;
emitLongValue(value);
}
/* ditto pokeRelativeByteValue. This is a special case used in fixing up
relative branches */
void
pokeRelativeByteValue(location, value)
addressType location;
valueType *value;
{
int offset;
currentLocationCounter.value = location;
offset = value->value - (location - targetOffset) - 1;
if (offset < 0)
offset--;
/* if (currentCodeMode == RELOCATABLE_BUFFER)
offset = 0;*/
if (isByteOffset(offset)) {
emitByte(offset);
} else {
error(RELATIVE_OFFSET_TOO_LARGE_ERROR);
}
}
/* ditto pokeRelativeWordValue. This is a special case used in fixing up
relative branches */
void
pokeRelativeWordValue(location, value)
addressType location;
valueType *value;
{
int offset;
currentLocationCounter.value = location;
offset = value->value - (location - targetOffset);
if (isWordOffset(offset)) {
emitWord(offset);
} else {
error(RELATIVE_OFFSET_TOO_LARGE_ERROR);
}
}
/* getByte fetches a byte back out of the labyrinth of code buffers */
byte
getByte(address)
addressType address;
{
int bufferNum;
int bufferPos;
codeBufferType *theBuffer;
codeSegmentType *theSegment;
bufferNum = bufferNumber(address);
bufferPos = bufferPosition(address);
theSegment = codeRegions[(int)currentCodeMode]->codeSegments[
bufferNum];
if (theSegment == NULL)
return(0);
else
return((*(theSegment->codeBuffer))[bufferPos]);
}
void
emitRelativeByteOffset(target)
valueType *target;
{
int saveTargetOffset;
if (target == NULL) {
emitByte(0);
} else {
(target->value)++;
saveTargetOffset = targetOffset;
targetOffset = 0;
pokeRelativeByteValue(currentLocationCounter.value, target);
targetOffset = saveTargetOffset;
(target->value)--;
}
}
void
emitRelativeWordOffset(target)
valueType *target;
{
int saveTargetOffset;
if (target == NULL) {
emitWord(0);
} else {
saveTargetOffset = targetOffset;
targetOffset = 0;
pokeRelativeWordValue(currentLocationCounter.value, target);
targetOffset = saveTargetOffset;
}
}
/* fixupBranch repairs a previously undefined branch once the branch address
has become known. */
void
fixupBranch(location, target)
valueType location[COMPOUND_BRANCH_MAX];
valueType target;
{
valueType saveCurrentLocation;
int saveTargetOffset;
int i;
saveCurrentLocation = currentLocationCounter;
saveTargetOffset = targetOffset;
targetOffset = 0;
for (i=0; i<COMPOUND_BRANCH_MAX; i++) {
if (location[i].value >= 0)
pokeRelativeByteValue(location[i].value, &target);
}
targetOffset = saveTargetOffset;
currentLocationCounter = saveCurrentLocation;
}
/* fixupJump similarly repairs a jump */
void
fixupJump(locations, target)
simpleFixupListType *locations;
valueType target;
{
valueType saveCurrentLocation;
simpleFixupListType *oldLocation;
saveCurrentLocation = currentLocationCounter;
while (locations != NULL) {
currentLocationCounter = locations->locationToFixup;
noteAnonymousReference();
target.value -= targetOffset;
if (positionIndependentCodeMode)
pokeRelativeByteValue(locations->locationToFixup.
value, &target);
else
pokeWordValue(locations->locationToFixup.value,
&target);
target.value += targetOffset;
oldLocation = locations;
locations = locations->nextFixup;
free(oldLocation);
}
currentLocationCounter = saveCurrentLocation;
}

BIN
emitStuff.o Normal file

Binary file not shown.

674
encode.c Normal file
View File

@ -0,0 +1,674 @@
/* WARNING: this file has not yet been separated into 6502 and non-6052 parts */
/*
encode.c -- Routines to encode expressions for Macross object files.
Chip Morningstar -- Lucasfilm Ltd.
8-November-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "y.tab.h"
#include "slinkyExpressions.h"
#define nullEncode(thing) if (thing==NULL) return(TRUE);
#define byteOp(op) ((op)-256)
bool encodingFunction;
bool
encodeByte(aByte)
byte aByte;
{
if (expressionBufferSize < EXPRESSION_BUFFER_LIMIT) {
expressionBuffer[expressionBufferSize++] = aByte;
return(TRUE);
} else {
error(EXPRESSION_TOO_BIG_TO_FIT_IN_OBJECT_ERROR);
return(FALSE);
}
}
bool
encodeBigword(bigword)
int bigword;
{
int i;
for (i=0; i<sizeof(int); ++i) {
if (!encodeByte(bigword & 0xFF))
return(FALSE);
bigword >>= 8;
}
return(TRUE);
}
bool
encodeAssignmentTerm(assignmentTerm, kindOfFixup)
binopTermType *assignmentTerm;
fixupKindType kindOfFixup;
{
nullEncode(assignmentTerm);
if ((assignmentKindType)assignmentTerm->binop != ASSIGN_ASSIGN) {
error(FUNNY_ASSIGNMENT_KIND_IN_OBJECT_EXPRESSION_ERROR);
return(FALSE);
}
return(
encodeByte(BINOP_TAG) &&
encodeByte(byteOp(ASSIGN)) &&
encodeIdentifier(assignmentTerm->leftArgument) &&
encodeExpression(assignmentTerm->rightArgument)
);
}
bool
encodeBinopTerm(binopTerm, isTopLevel, kindOfFixup)
binopTermType *binopTerm;
bool isTopLevel;
fixupKindType kindOfFixup;
{
bool encodeExpression();
nullEncode(binopTerm);
return (
encodeByte(BINOP_TAG) &&
encodeByte(byteOp(binopTerm->binop)) &&
encodeExpression(binopTerm->leftArgument) &&
encodeExpression(binopTerm->rightArgument)
);
}
bool
encodeCondition(condition)
conditionType condition;
{
return(
encodeByte(CONDITION_CODE_TAG) &&
encodeByte(condition)
);
}
int
functionNumber(function)
functionDefinitionType *function;
{
if (function->ordinal == -1) {
function->ordinal = externalFunctionCount++;
if (externalFunctionList == NULL) {
externalFunctionList = endOfExternalFunctionList =
function;
} else {
endOfExternalFunctionList->nextExternalFunction =
function;
endOfExternalFunctionList = function;
}
}
return(function->ordinal);
}
bool
encodeFunctionCall(functionCall)
functionCallTermType *functionCall;
{
functionDefinitionType *theFunction;
int functionOrdinal;
symbolInContextType *workingContext;
operandListType *parameterList;
symbolInContextType *getWorkingContext();
nullEncode(functionCall);
workingContext = getWorkingContext(functionCall->functionName);
if (isFunction(workingContext)) {
if (!encodeByte(FUNCTION_CALL_TAG))
return(FALSE);
theFunction = (functionDefinitionType *)workingContext->
value->value;
if (!encodeBigword(functionNumber(theFunction)))
return(FALSE);
} else if (isBuiltInFunction(workingContext)) {
functionOrdinal = workingContext->value->value;
if (builtInFunctionTable[functionOrdinal].isSpecialFunction)
return(encodeValue((*builtInFunctionTable[
functionOrdinal].functionEntry)(functionCall->
parameters, NO_FIXUP)));
if (!encodeByte(BUILTIN_FUNCTION_CALL_TAG))
return(FALSE);
if (builtInFunctionTable[functionOrdinal].ordinal < 0) {
error(BUILT_IN_FUNCTION_NOT_AVAILABLE_IN_OBJECT_ERROR,
builtInFunctionTable[functionOrdinal].
functionName);
return(FALSE);
} else if (!encodeBigword(builtInFunctionTable[
functionOrdinal].ordinal)) {
return(FALSE);
}
} else {
error(NOT_A_FUNCTION_ERROR, symbName(functionCall->
functionName));
return(FALSE);
}
parameterList = functionCall->parameters;
if (!encodeByte(countParameters(parameterList)))
return(FALSE);
while (parameterList != NULL)
if (!encodeOperand(parameterList))
return(FALSE);
else
parameterList = parameterList->nextOperand;
return(TRUE);
}
bool
encodeHere()
{
return(encodeByte(HERE_TAG));
}
bool
encodeIdentifier(identifier)
symbolTableEntryType *identifier;
{
symbolInContextType *workingContext;
environmentType *saveEnvironment;
bool result;
nullEncode(identifier);
if (symbName(identifier)[0] == '$') {
error(TEMP_SYMBOL_IN_OBJECT_ERROR, symbName(identifier));
return(FALSE);
}
if (encodingFunction) {
return(encodeByte(IDENTIFIER_TAG) &&
encodeBigword(identifier->ordinal));
}
if ((workingContext = getWorkingContext(identifier)) == NULL) {
error(UNDEFINED_SYMBOL_ERROR, symbName(identifier));
return(FALSE);
}
if (workingContext->usage == FUNCTION_SYMBOL || workingContext->usage
== BUILT_IN_FUNCTION_SYMBOL) {
error(FUNCTION_IS_NOT_A_VALUE_ERROR, symbName(identifier));
return(FALSE);
}
if (workingContext->value == NULL) {
error(UNDEFINED_SYMBOL_ERROR, symbName(identifier));
return(FALSE);
}
if (workingContext->value->kindOfValue == UNDEFINED_VALUE) {
if (workingContext->attributes & GLOBAL_ATT) {
return(encodeByte(IDENTIFIER_TAG) &&
encodeBigword(identifier->ordinal));
} else {
error(UNDEFINED_SYMBOL_ERROR, symbName(identifier));
return(FALSE);
}
}
if (workingContext->value->kindOfValue == RELOCATABLE_VALUE) {
return(encodeByte(IDENTIFIER_TAG) &&
encodeBigword(identifier->ordinal));
}
if (workingContext->value->kindOfValue == FAIL) {
error(UNASSIGNED_SYMBOL_ERROR, symbName(identifier));
return(FALSE);
}
if (workingContext->value->kindOfValue == OPERAND_VALUE) {
saveEnvironment = currentEnvironment;
if (workingContext->usage == ARGUMENT_SYMBOL) {
currentEnvironment = currentEnvironment->
previousEnvironment;
}
result = encodeOperand(workingContext->value->value);
currentEnvironment = saveEnvironment;
return(result);
}
if (workingContext->value->kindOfValue == BLOCK_VALUE) {
error(BLOCK_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
return(FALSE);
}
return(encodeValue(workingContext->value));
}
bool
encodeNumber(number)
numberTermType number;
{
return(
encodeByte(NUMBER_TAG) &&
encodeBigword(number)
);
}
bool
encodeRelocatableNumber(number)
numberTermType number;
{
return(
encodeByte(RELOCATABLE_TAG) &&
encodeBigword(number)
);
}
bool
encodeOperand(operand)
operandType *operand;
{
switch (operand->kindOfOperand) {
case EXPRESSION_OPND:
case IMMEDIATE_OPND:
case INDIRECT_OPND:
case POST_INDEXED_Y_OPND:
case PRE_INDEXED_X_OPND:
case X_INDEXED_OPND:
case Y_INDEXED_OPND:
return(encodeExpression(operand->theOperand));
case A_REGISTER_OPND:
case X_REGISTER_OPND:
case Y_REGISTER_OPND:
error(REGISTER_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
return(FALSE);
case X_SELECTED_OPND:
case Y_SELECTED_OPND:
case PRE_SELECTED_X_OPND:
error(SELECTION_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
return(FALSE);
case STRING_OPND:
return(encodeString(operand->theOperand));
case BLOCK_OPND:
error(BLOCK_OPERAND_IN_OBJECT_EXPRESSION_ERROR);
return(FALSE);
}
}
bool
encodePostopTerm(postopTerm)
postOpTermType *postopTerm;
{
nullEncode(postopTerm);
return(
encodeByte(POSTOP_TAG) &&
encodeByte(byteOp(postopTerm->postOp)) &&
encodeExpression(postopTerm->postOpArgument)
);
}
bool
encodePreopTerm(preopTerm)
preOpTermType *preopTerm;
{
nullEncode(preopTerm);
return(
encodeByte(PREOP_TAG) &&
encodeByte(byteOp(preopTerm->preOp)) &&
encodeExpression(preopTerm->preOpArgument)
);
}
bool
encodeString(string)
stringType *string;
{
if (!encodeByte(STRING_TAG))
return(FALSE);
while (*string != '\0') {
if (!encodeByte(*string++))
return(FALSE);
}
return(encodeByte('\0'));
}
bool
encodeUnopTerm(unopTerm)
unopTermType *unopTerm;
{
nullEncode(unopTerm);
return(
encodeByte(UNOP_TAG) &&
encodeByte(byteOp(unopTerm->unop)) &&
encodeExpression(unopTerm->unopArgument)
);
}
bool
encodeValue(value)
valueType *value;
{
switch (value->kindOfValue) {
case ABSOLUTE_VALUE:
return(encodeNumber(value->value));
case RELOCATABLE_VALUE:
return(encodeRelocatableNumber(value->value));
case OPERAND_VALUE:
return(encodeOperand(value->value));
case STRING_VALUE:
return(encodeString(value->value));
case CONDITION_VALUE:
return(encodeCondition(value->value));
case DATA_VALUE:
case BSS_VALUE:
case STRUCT_VALUE:
case FIELD_VALUE:
case MACRO_VALUE:
case UNDEFINED_VALUE:
case FUNCTION_VALUE:
case BLOCK_VALUE:
case BUILT_IN_FUNCTION_VALUE:
case ARRAY_VALUE:
case FAIL:
error(WRONG_KIND_OF_VALUE_IN_OBJECT_EXPRESSION_ERROR,
valueKindString(value->kindOfValue));
return(FALSE);
}
}
bool
encodeExpression(expression)
expressionType *expression;
{
nullEncode(expression);
switch (expression->kindOfTerm) {
case ARRAY_EXPR:
error(ARRAY_TERM_IN_OBJECT_EXPRESSION_ERROR);
return(FALSE);
break;
case ASSIGN_EXPR:
return(encodeAssignmentTerm(expression->expressionTerm));
break;
case BINOP_EXPR:
return(encodeBinopTerm(expression->expressionTerm));
break;
case CONDITION_CODE_EXPR:
return(encodeCondition(expression->expressionTerm));
break;
case FUNCTION_CALL_EXPR:
return(encodeFunctionCall(expression->expressionTerm));
break;
case HERE_EXPR:
return(encodeHere());
break;
case IDENTIFIER_EXPR:
return(encodeIdentifier(expression->expressionTerm));
break;
case NUMBER_EXPR:
return(encodeNumber(expression->expressionTerm));
break;
case POSTOP_EXPR:
return(encodePostopTerm(expression->expressionTerm));
break;
case PREOP_EXPR:
return(encodePreopTerm(expression->expressionTerm));
break;
case SUBEXPRESSION_EXPR:
encodeExpression(expression->expressionTerm);
break;
case STRING_EXPR:
return(encodeString(expression->expressionTerm));
break;
case UNOP_EXPR:
return(encodeUnopTerm(expression->expressionTerm));
break;
case VALUE_EXPR:
return(encodeValue(expression->expressionTerm));
break;
default:
botch("encodeExpression: funny expression kind %d\n",
expression->kindOfTerm);
break;
}
}
bool
encodeAssertStatement(assertStatement)
assertStatementBodyType *assertStatement;
{
return(
encodeByte(ASSERT_TAG) &&
encodeExpression(assertStatement->condition) &&
encodeExpression(assertStatement->message)
);
}
bool
encodeFreturnStatement(freturnStatement)
freturnStatementBodyType *freturnStatement;
{
return(
encodeByte(FRETURN_TAG) &&
encodeExpression(freturnStatement)
);
}
bool
encodeMdefineStatement(mdefineStatement)
defineStatementBodyType *mdefineStatement;
{
return(
encodeByte(MDEFINE_TAG) &&
encodeIdentifier(mdefineStatement->theSymbol) &&
encodeExpression(mdefineStatement->theValue)
);
}
bool
encodeMdoUntilStatement(mdoUntilStatement)
mdoUntilStatementBodyType *mdoUntilStatement;
{
return(
encodeByte(MDOUNTIL_TAG) &&
encodeExpression(mdoUntilStatement->mdoUntilCondition) &&
encodeBlock(mdoUntilStatement->mdoUntilLoop)
);
}
bool
encodeMdoWhileStatement(mdoWhileStatement)
mdoWhileStatementBodyType *mdoWhileStatement;
{
return(
encodeByte(MDOWHILE_TAG) &&
encodeExpression(mdoWhileStatement->mdoWhileCondition) &&
encodeBlock(mdoWhileStatement->mdoWhileLoop)
);
}
bool
encodeMforStatement(mforStatement)
mforStatementBodyType *mforStatement;
{
return(
encodeByte(MFOR_TAG) &&
encodeExpression(mforStatement->initExpression) &&
encodeExpression(mforStatement->testExpression) &&
encodeExpression(mforStatement->incrExpression) &&
encodeBlock(mforStatement->forLoop)
);
}
bool
encodeMifStatement(mifStatement)
mifStatementBodyType *mifStatement;
{
return(
encodeByte(MIF_TAG) &&
encodeExpression(mifStatement->mifCondition) &&
encodeBlock(mifStatement->mifConsequence) &&
encodeBlock(mifStatement->mifContinuation)
);
}
bool
encodeMswitchStatement(mswitchStatement)
mswitchStatementBodyType *mswitchStatement;
{
caseListType *caseList;
caseType *theCase;
expressionListType *tagExpressionList;
if (!(encodeByte(MSWITCH_TAG) && encodeExpression(mswitchStatement->
switchExpression)))
return(FALSE);
for (caseList=mswitchStatement->cases; caseList!=NULL; caseList=caseList->
nextCase) {
theCase = caseList->theCase;
for (tagExpressionList=theCase->caseTags; tagExpressionList!=NULL;
tagExpressionList=tagExpressionList->nextExpression) {
if (!encodeExpression(tagExpressionList->theExpression))
return(FALSE);
}
if (!encodeBlock(theCase->caseBody))
return(FALSE);
}
return(encodeByte(END_TAG));
}
bool
encodeMvariableStatement(mvariableStatement)
mvariableStatementBodyType *mvariableStatement;
{
int length;
if ((length=expressionListLength(mvariableStatement->theValue) > 1) ||
mvariableStatement->theDimension!=NULL) {
error(ARRAY_MVARIABLE_IN_OBJECT_FUNCTION_ERROR);
return(FALSE);
}
if (!(encodeByte(MVARIABLE_TAG) && encodeIdentifier(mvariableStatement->
theSymbol)))
return(FALSE);
if (length == 1)
return(encodeExpression(mvariableStatement->theValue->
theExpression));
else
return(encodeExpression(NULL));
}
bool
encodeMwhileStatement(mwhileStatement)
mwhileStatementBodyType *mwhileStatement;
{
return(
encodeByte(MWHILE_TAG) &&
encodeExpression(mwhileStatement->mwhileCondition) &&
encodeBlock(mwhileStatement->mwhileLoop)
);
}
bool
encodeStatement(statement)
statementType *statement;
{
switch(statement->kindOfStatement) {
case ALIGN_STATEMENT:
case BLOCK_STATEMENT:
case BYTE_STATEMENT:
case CONSTRAIN_STATEMENT:
case DBYTE_STATEMENT:
case DEFINE_STATEMENT:
case DO_UNTIL_STATEMENT:
case DO_WHILE_STATEMENT:
case EXTERN_STATEMENT:
case FUNCTION_STATEMENT:
case IF_STATEMENT:
case INCLUDE_STATEMENT:
case INSTRUCTION_STATEMENT:
case LONG_STATEMENT:
case MACRO_STATEMENT:
case ORG_STATEMENT:
case REL_STATEMENT:
case START_STATEMENT:
case STRING_STATEMENT:
case STRUCT_STATEMENT:
case TARGET_STATEMENT:
case UNDEFINE_STATEMENT:
case VARIABLE_STATEMENT:
case WHILE_STATEMENT:
case WORD_STATEMENT:
error(ILLEGAL_STATEMENT_IN_OBJECT_FILE_FUNCTION_ERROR,
statementKindString(statement->kindOfStatement));
return(FALSE);
case ASSERT_STATEMENT:
return(encodeAssertStatement(statement->statementBody));
case FRETURN_STATEMENT:
return(encodeFreturnStatement(statement->statementBody));
case GROUP_STATEMENT:
return(encodeBlock(statement->statementBody));
case MDEFINE_STATEMENT:
return(encodeMdefineStatement(statement->statementBody));
case MDO_UNTIL_STATEMENT:
return(encodeMdoUntilStatement(statement->statementBody));
case MDO_WHILE_STATEMENT:
return(encodeMdoWhileStatement(statement->statementBody));
case MFOR_STATEMENT:
return(encodeMforStatement(statement->statementBody));
case MIF_STATEMENT:
return(encodeMifStatement(statement->statementBody));
case MSWITCH_STATEMENT:
return(encodeMswitchStatement(statement->statementBody));
case MVARIABLE_STATEMENT:
return(encodeMvariableStatement(statement->statementBody));
case MWHILE_STATEMENT:
return(encodeMwhileStatement(statement->statementBody));
case NULL_STATEMENT:
return(TRUE);
case PERFORM_STATEMENT:
return(encodeExpression(statement->statementBody));
default:
botch("encodeStatementBody doesn't know kind %d\n",
statement->kindOfStatement);
return(FALSE);
}
}
bool
encodeBlock(block)
blockType *block;
{
if (!encodeByte(BLOCK_TAG))
return(FALSE);
while (block != NULL) {
if (!encodeStatement(block))
return(FALSE);
block = block->nextStatement;
}
return(encodeByte(END_TAG));
}

BIN
encode.o Normal file

Binary file not shown.

360
errorStuff.c Normal file
View File

@ -0,0 +1,360 @@
/*
errorStuff.c -- Error handling for the Macross assembler
Chip Morningstar -- Lucasfilm Ltd.
5-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
bool nullStatementFlag;
/* puntOnError handles syntax errors and the like encountered during parsing
or lexical analysis: it issues the relevent error message and scans the
input up to the end of the line, in a (probably futile) effort to recover
from the booboo. */
void
puntOnError(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
char c;
void error();
while ((c = getc(input))!='\n' && c!=EOF)
;
ungetc(c, input);
error(theError, arg1, arg2, arg3);
}
/* printErrorMessage is the general error message handler */
void
printErrorMessage(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'errorType'. */
void fatalError();
static bool dying = FALSE;
static char *errorMessageStrings[] = {
"assignment in 'define' statement is not '='",
"digit '%c' is not valid in base %d",
"closing \"'\" missing in character constant",
"closing '\"' missing in string constant",
"octal value '0%o' too large to fit in a character",
"character '%c' not allowed here",
"comment not closed at end of file",
"line comment not closed at end of file",
"fatal: unable to open temporary scratch file '%s'",
"%s cannot be a valid address for an 'org'",
"negative block size in 'block' statement",
"'%s' is %s and hence unassignable",
"left and right hand sides of assignment are incompatible for '%s' operator",
"operands of '%s' are incompatible with each other",
"postincrement operand is %s and hence un-postincrementable",
"postdecrement operand is %s and hence un-postdecrementable",
"preincrement operand is %s and hence un-preincrementable",
"predecrement operand is %s and hence un-predecrementable",
"operand of '%s' is incompatible with operator",
"value is not an address",
"value is not an integer",
"can't 'align' to zero or negative value",
"left hand operand of '%s' has no value",
"too many operands for '%s' instruction (should have %d)",
"illegal address mode for '%s' instruction",
"value %d is too large to fit in a byte",
"value %d is too large to fit in a word",
"illegal address mode for '%s' instruction",
"divide by zero",
"symbol '%s' undefined",
"relative branch offset too large",
"label '%s' previously defined",
"fatal: can't open object file '%s'",
"%s can't be made external",
"warning: more than one output file name given on command line",
"warning: '-%c' is not a recognized command line flag",
"fatal: no output file name given on command line after '-o'",
"fatal: unable to open input file '%s'",
"fatal: unable to open include file '%s'",
"%s cannot be a valid boolean value",
"symbol '%s' was previously defined",
"assignment to undeclared variable '%s'",
"redefinition of variable '%s'",
"'%s' is not a struct",
"struct is too large for all components to be addressed",
"struct field '%s' previously defined",
"struct definition inside a struct definition",
"'%s' is not a struct field",
"macro '%s' previously defined",
"macro definition inside a macro or function",
"too many arguments given to macro '%s' (expects no more than %d)",
"function definition inside a macro or function",
"function '%s' previously defined",
"too many arguments given to function '%s' (expects no more than %d)",
"'%s' is not a function",
"function '%s' did not return a value",
"operand already has an address mode",
"multiple address modes in expression",
"include file name given is not a string",
"start address previously given",
"attempt to use function name '%s' as a value",
"statement with side-effects not allowed inside a function",
"symbolName can't find symbol",
"error inside macro '%s'",
"error inside function '%s'",
"fatal: no listing file name given on command line after '-l'",
"fatal: no symbol dump file name given on command line after '-%c'",
"warning: more than one listing file name given on command line",
"warning: more than one symbol dump file name given on command line",
"fatal: can't open listing file '%s'",
"fatal: can't open symbol dump file '%s'",
"fatal: source file '%s' does not have a Macross source file name",
"fatal: output file '%s' has a Macross source file name",
"fatal: list file '%s' has a Macross source file name",
"fatal: symbol dump file '%s' has a Macross source file name",
"constraint value is not an integer",
"constrained block crosses 0x%x boundary",
"symbol '%s' has no value",
"bad start address",
"align inside constraint block -- alignment ignored",
"constrain inside constraint block -- constraint ignored",
"can't emit %s as a word",
"can't emit %s as a byte",
"too few operands for '%s' instruction (should have %d)",
"bad color argument to 'atasciiColor'",
"'printf' format argument is not a string",
"'%s' argument #%d is not a string",
"no arguments given to '%s'",
"'%s' argument is not a string",
"too few arguments to '%s'",
"'%s' argument #%d is not an absolute value",
"bad substring indices",
"invalid 'assert' condition",
"invalid 'assert' message",
"'assert' failed: %s",
"'assert' failed",
"can't use %s as a switch value",
"can't use %s as a case value",
"can't forward reference a block",
"warning: turning macro expansion listing off because listing in general is off",
"inappropriate address modes",
"can't do byte address op",
"quick data out of range",
"ccr op is byte op",
"sr op is word op",
"shift op is word op",
"cmp address is not byte op",
"usp move is long op",
"ccr move is word op",
"sr move is word op",
"cr move is long op",
"address move not byte op",
"trap data too large",
"relative offset value too large",
"can't do op from A register",
"forward reference not allowed here",
"fatal: address 0x%x is outside the available address space",
"argument '%s' to 'apply' is not a macro name",
"can't 'target' in relocatable mode",
"%s cannot be a valid address for a 'target'",
"macro '%s' is undefined",
"bad position argument to 'nthChar'",
"value argument to 'symbolDefine' is not an expression operand",
"attempt to use %s as an array",
"attempt to index an array with %s",
"array index of %d exceeds maximum of %d",
"too many initialization values for variable",
"negative array index",
"can't emit %s as a long",
"can't use ++ or -- on an element of a string",
"can't assign a non-character value into a string element",
"negative array size given to 'makeArray'",
"too many initialization values given to 'makeArray'",
"array element has no value",
"can't use prefix '%s' in an expression containing a forward reference",
"can't use postfix '%s' in an expression containing a forward reference",
"can't use assignment in an expression containing a forward reference",
"fatal: too many errors (choke, gasp, wheeze, die...)",
"expression too large for object file encoding",
"operator assignment not allowed in object file expression",
"temporary symbol '%s' in object file expression",
"block operand in object file expression",
"register operand in object file expression",
"selection operand in object file expression (not yet)",
"%s not allowed in object file expression",
"array term not allowed in object file expression",
"%s not allowed in object file function",
"array mvariable declaration in object file function",
"built-in function '%s' is not available in the linker",
"fatal: no name definition given on command line after '-D'",
"bad name definition: '%s'",
"warning: perform statement has no side effects",
};
static int errorCount = 0;
if (!terseErrorMessages || currentFileName != lastErrorFile ||
currentLineNumber != lastErrorLine) {
lastErrorFile = currentFileName;
lastErrorLine = currentLineNumber;
printf("\"%s\", line %d: ", currentFileName, currentLineNumber
-1);
printf(errorMessageStrings[(int)theError], arg1, arg2, arg3);
printf("\n");
fflush(stdout);
}
if (++errorCount > ERROR_LIMIT && !dying) {
dying = TRUE;
fatalError(TOO_MANY_ERRORS_ERROR);
}
}
void
error(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
errorFlag = TRUE;
}
void
warning(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
}
void
fatalError(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
chokePukeAndDie();
}
void
fatalSystemError(theError, arg1, arg2, arg3)
errorType theError;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printErrorMessage(theError, arg1, arg2, arg3);
perror("Unix says");
chokePukeAndDie();
}
/* yyerror is what yacc expects to call when it hits an error. Yacc passes
the error message as a string (this is almost always 'syntax error'). */
void
yyerror(s)
char *s;
{
printf("\"%s\", line %d: %s\n", currentFileName, currentLineNumber,s);
fflush(stdout);
errorFlag = TRUE;
}
/* usageString is used in reporting errors having to do with symbol usage.
It provides a translation between the internal representation and
something printable (with the printable something designed to be embedded
in a sentence). */
char *
usageString(usageKind)
symbolUsageKindType usageKind;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'symbolUsageKindType'. */
static char *usageStrings[NUM_OF_SYM_USAGES] = {
"a struct name",
"a struct field name",
"a macro name",
"an argument variable name",
"a label",
"an external symbol",
"a variable",
"a macro variable",
"a symbol of unknown type",
"a dead symbol",
"a function name",
"a built-in-function name",
"a nested symbol of unknown type",
"a define symbol",
"a macro define symbol",
"an unknown function",
"an unknown macro",
};
return(usageStrings[(int)usageKind]);
}
/* valueKindString similarly deals with the different kinds of values. */
char *
valueKindString(valueKind)
valueKindType valueKind;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'valueKindType'. */
static char *valueKindStrings[] = {
"an absolute value",
"a data value",
"a relocatable value",
"a bss value",
"a struct name",
"a field name",
"a macro name",
"an operand value",
"a string value",
"a condition code",
"an undefined value",
"a function name",
"a block of statements",
"a built in function",
"an array",
"a failed expression"
};
return (valueKindStrings[(int)valueKind]);
}
/* assignmentString similarly handles assignments */
char *
assignmentString(assignment)
assignmentKindType assignment;
{
/* This table MUST be maintained congruently with the definition of the
enumerated type 'assignmentKindType'. */
static char *assignmentStringTable[] = {
"=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=",
"<<=", ">>=", "macross botch! no assigment"
};
return(assignmentStringTable[(int)assignment]);
}

BIN
errorStuff.o Normal file

Binary file not shown.

39
errorfyle Normal file
View File

@ -0,0 +1,39 @@
make: Warning: Infinite loop: Target `macrossTypes.h' depends on itself
cc -c -g -DYYDEBUG -DTARGET_CPU=CPU_6502 y.tab.c
cc -c -g -DTARGET_CPU=CPU_6502 actions_6502.c
mv actions_6502.o actions.o
cc -c -g -DTARGET_CPU=CPU_6502 buildStuff1.c
cc -c -g -DTARGET_CPU=CPU_6502 buildStuff2.c
cc -c -g -DTARGET_CPU=CPU_6502 buildStuff3.c
cc -c -g -DTARGET_CPU=CPU_6502 builtInFunctions.c
cc -c -g -DTARGET_CPU=CPU_6502 builtInFunsSD_6502.c
mv builtInFunsSD_6502.o builtInFunsSD.o
cc -c -g -DTARGET_CPU=CPU_6502 debugPrint.c
cc -c -g -DTARGET_CPU=CPU_6502 debugPrintSD_6502.c
mv debugPrintSD_6502.o debugPrintSD.o
cc -c -g -DTARGET_CPU=CPU_6502 emitBranch_6502.c
mv emitBranch_6502.o emitBranch.o
cc -c -g -DBYTESWAPPED -DTARGET_CPU=CPU_6502 emitStuff.c
cc -c -g -DTARGET_CPU=CPU_6502 encode.c
cc -c -g -DTARGET_CPU=CPU_6502 errorStuff.c
cc -c -g -DTARGET_CPU=CPU_6502 expressionSemantics.c
cc -c -g -DTARGET_CPU=CPU_6502 fixups.c
cc -c -g -DTARGET_CPU=CPU_6502 garbage.c
cc -c -g -DTARGET_CPU=CPU_6502 initialize.c
cc -c -g -DTARGET_CPU=CPU_6502 lexer.c
cc -c -g -DTARGET_CPU=CPU_6502 listing.c
cc -c -g -DTARGET_CPU=CPU_6502 lookups.c
cc -c -g -DTARGET_CPU=CPU_6502 macrossTables_6502.c
mv macrossTables_6502.o macrossTables.o
cc -c -g -DTARGET_CPU=CPU_6502 main.c
cc -c -g -DTARGET_CPU=CPU_6502 malloc.c
cc -c -g -DTARGET_CPU=CPU_6502 object.c
cc -c -g -DTARGET_CPU=CPU_6502 operandStuffSD_6502.c
mv operandStuffSD_6502.o operandStuffSD.o
cc -c -g -DTARGET_CPU=CPU_6502 parserMisc.c
cc -c -g -DTARGET_CPU=CPU_6502 semanticMisc.c
cc -c -g -DTARGET_CPU=CPU_6502 statementSemantics.c
cc -c -g -DTARGET_CPU=CPU_6502 structSemantics.c
cc -c -g -DTARGET_CPU=CPU_6502 tokenStrings_6502.c
mv tokenStrings_6502.o tokenStrings.o
cc -g -o macross y.tab.o actions.o buildStuff1.o buildStuff2.o buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o emitBranch.o emitStuff.o encode.o errorStuff.o expressionSemantics.o fixups.o garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o statementSemantics.o structSemantics.o tokenStrings.o

1219
expressionSemantics.c Normal file

File diff suppressed because it is too large Load Diff

BIN
expressionSemantics.o Normal file

Binary file not shown.

346
fixups.c Normal file
View File

@ -0,0 +1,346 @@
/*
fixups.c -- Routines to handle expressions being saved away for fixups
in the Macross assembler.
Chip Morningstar -- Lucasfilm Ltd.
20-December-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
operandType *dbOperand; /* safe temps for dbx hacking */
expressionType *dbExpression;
symbolTableEntryType *dbSymbol;
stringType *dbString = "graphics2.m";
#define nullDup(thing) if (thing==NULL) { return (NULL); }
#define expansionOff() {saveExpansion=expandMacros; expandMacros=FALSE;}
#define expansionOn() expandMacros=saveExpansion;
/*
Whenever a value is needed as the operand of an instruction or data
statement, but one or more of the terms of the expression which define the
value are themselves undefined symbols, we have to get fancy. What we do
is use a zero value and save away a copy of the expression for later
evaluation at a time (the end of assembly) when (hopefully) the undefined
symbols will have been defined. It is necessary to save a copy of the
expression, rather that the expression itself, since some of the terms of
the expression may be variables whose value may change between now and
when the saved expression gets reevaluated. When we are making the copy
we replace any variables with their present values.
The routines below collectively duplicate expressions for later evaluation.
*/
expressionType *
generateFixupExpression(expression)
expressionType *expression;
{
expressionType *result;
expressionType *duplicateExpressionForFixup();
generatingFixup = TRUE;
result = duplicateExpressionForFixup(expression, TRUE, FALSE);
generatingFixup = FALSE;
return(result);
}
expressionType *
duplicateExpressionForFixup(expression, isTopLevel, isSpecialFunctionOperand)
expressionType *expression;
bool isTopLevel;
bool isSpecialFunctionOperand;
{
expressionType *result;
expressionType *originalResult;
valueType *value;
symbolTableEntryType *identifier;
symbolInContextType *context;
operandType *newOperand;
environmentType *saveEnvironment;
bool saveExpansion;
operandType *duplicateOperandForFixup();
symbolInContextType *getWorkingContext();
functionCallTermType *duplicateFunctionCall();
expressionType *duplicateArrayReference();
valueType *evaluateIdentifier();
valueType *evaluateHere();
valueType *newValue();
symbolTableEntryType *generateLocalLabel();
stringType *saveString();
nullDup(expression);
result = originalResult = typeAlloc(expressionType);
*result = *expression;
switch (expression->kindOfTerm) {
case STRING_EXPR:
expand(moreExpression("%s", expression->expressionTerm.stringUnion));
result->expressionTerm.stringUnion = saveString(originalResult->
expressionTerm.stringUnion);
break;
case IDENTIFIER_EXPR:
identifier = expression->expressionTerm.identifierUnion;
if (symbName(identifier)[0] == '$')
identifier = result->expressionTerm.identifierUnion =
generateLocalLabel(identifier);
context = getWorkingContext(identifier);
if (context->usage == ARGUMENT_SYMBOL && context->value->
kindOfValue == OPERAND_VALUE) {
if (isSpecialFunctionOperand) {
while (context->usage == ARGUMENT_SYMBOL && context->value->
kindOfValue == OPERAND_VALUE) {
newOperand = (operandType *)context->value->value;
if (newOperand->kindOfOperand == EXPRESSION_OPND &&
(expression = newOperand->theOperand.
expressionUnion) != NULL && expression->
kindOfTerm == IDENTIFIER_EXPR) {
identifier = expression->expressionTerm.
identifierUnion;
context = getWorkingContext(identifier);
} else {
expand(moreExpression("*fail*"));
return(NULL);
}
}
expand(moreExpression("%s", symbName(identifier)));
result->expressionTerm.identifierUnion = identifier;
} else {
saveEnvironment = currentEnvironment;
currentEnvironment = currentEnvironment->previousEnvironment;
if ((newOperand = duplicateOperandForFixup(
context->value->value,
FALSE)) == NULL) {
result = NULL;
} else {
result->kindOfTerm = VALUE_EXPR;
result->expressionTerm.valueUnion =
newValue(OPERAND_VALUE,
newOperand, newOperand->
kindOfOperand);
}
currentEnvironment = saveEnvironment;
}
} else {
expansionOff();
if(!isUndefined(value = evaluateIdentifier(identifier,
isTopLevel, NO_FIXUP_OK)) && value->kindOfValue !=
RELOCATABLE_VALUE) {
expansionOn();
result->kindOfTerm = VALUE_EXPR;
result->expressionTerm.valueUnion = value;
expand((context->usage==MVARIABLE_SYMBOL ||
context->usage==VARIABLE_SYMBOL ||
context->usage==MDEFINE_SYMBOL) ?
moreExpression("0x%x", value->value) :
moreExpression("%s", symbName(identifier)));
} else {
expansionOn();
expand(moreExpression("%s", symbName(identifier)));
}
}
break;
case FUNCTION_CALL_EXPR:
if ((result->expressionTerm.functionCallUnion =
duplicateFunctionCall(expression->
expressionTerm.functionCallUnion)) == NULL)
result = NULL;
break;
case NUMBER_EXPR:
expand(moreExpression("0x%x", result->expressionTerm.numberUnion));
/* keep unchanged */
break;
case SUBEXPRESSION_EXPR:
expand(moreExpression("("));
if ((result->expressionTerm.subexpressionUnion =
duplicateExpressionForFixup(expression->
expressionTerm.subexpressionUnion,
isTopLevel, FALSE)) == NULL)
result = NULL;
expand(moreExpression(")"));
break;
case UNOP_EXPR:
expand(moreExpression("%s", tokenString(expression->expressionTerm.
unopUnion->unop)));
result->expressionTerm.unopUnion = typeAlloc(unopTermType);
result->expressionTerm.unopUnion->unop = expression->expressionTerm.
unopUnion->unop;
if ((result->expressionTerm.unopUnion->unopArgument =
duplicateExpressionForFixup(expression->
expressionTerm.unopUnion->unopArgument,
FALSE, FALSE)) == NULL)
result = NULL;
break;
case BINOP_EXPR:
result->expressionTerm.binopUnion = typeAlloc(binopTermType);
result->expressionTerm.binopUnion->binop = expression->expressionTerm.
binopUnion->binop;
if ((result->expressionTerm.binopUnion->leftArgument =
duplicateExpressionForFixup(expression->
expressionTerm.binopUnion->leftArgument,
FALSE, FALSE)) == NULL) {
expand(moreExpression("*fail*"));
result = NULL;
} else {
expand(moreExpression("%s", tokenString(expression->
expressionTerm.binopUnion->binop)));
if ((result->expressionTerm.binopUnion->rightArgument =
duplicateExpressionForFixup(expression->
expressionTerm.binopUnion->rightArgument,
FALSE, FALSE)) == NULL) {
result = NULL;
expand(moreExpression("*fail*"));
}
}
break;
case PREOP_EXPR:
expand(moreExpression("*fail*"));
error(CANT_USE_PREOP_WITH_FORWARD_REFERENCE_ERROR, tokenString(
expression->expressionTerm.preOpUnion->preOp));
result = NULL;
break;
case POSTOP_EXPR:
expand(moreExpression("*fail*"));
error(CANT_USE_POSTOP_WITH_FORWARD_REFERENCE_ERROR, tokenString(
expression->expressionTerm.postOpUnion->postOp));
result = NULL;
break;
case HERE_EXPR:
result->kindOfTerm = VALUE_EXPR;
result->expressionTerm.valueUnion = evaluateHere();
expand(moreExpression("0x%x", result->expressionTerm.valueUnion->
value));
break;
case ASSIGN_EXPR:
expand(moreExpression("*fail*"));
error(CANT_USE_ASSIGNMENT_WITH_FORWARD_REFERENCE_ERROR);
result = NULL;
break;
case CONDITION_CODE_EXPR:
/* keep unchanged */
expand(moreExpression("%s", conditionString(expression->
expressionTerm.conditionCodeUnion)));
break;
case VALUE_EXPR:
/* keep unchanged */
expand(moreExpression("0x%x", expression->expressionTerm.valueUnion->
value));
break;
case ARRAY_EXPR:
result = duplicateArrayReference(expression->expressionTerm.
arrayUnion);
break;
default:
botch("duplicateExpression: funny expression kind %d\n",
expression->kindOfTerm);
break;
}
return(result);
}
functionCallTermType *
duplicateFunctionCall(functionCall)
functionCallTermType *functionCall;
{
functionCallTermType *result;
operandListType **argument;
operandListType *parameterList;
operandListType *duplicateOperandForFixup();
result = typeAlloc(functionCallTermType);
result->functionName = functionCall->functionName;
expand(moreExpression("%s(", symbName(functionCall->functionName)));
result->parameters = NULL;
parameterList = functionCall->parameters;
argument = &(result->parameters);
while (parameterList != NULL) {
*argument = duplicateOperandForFixup(parameterList,
(functionCall->functionName->context->attributes &
SPECIAL_FUNCTION_ATT) != 0);
(*argument)->nextOperand = NULL;
argument = &((*argument)->nextOperand);
parameterList = parameterList->nextOperand;
expand(parameterList != NULL ? moreExpression(", ") : 0);
}
expand(moreExpression(")"));
return(result);
}
expressionType *
duplicateArrayReference(arrayTerm)
arrayTermType *arrayTerm;
{
anyOldThing *resultThing;
valueKindType kindOfResult;
expressionType *result;
stringType *charPtr;
valueType **valuePtr;
environmentType *saveEnvironment;
bool saveExpansion;
operandType *newOperand;
valueType *newValue();
operandType *duplicateOperandForFixup();
anyOldThing *arrayLookup();
expansionOff();
resultThing = arrayLookup(arrayTerm, &kindOfResult);
expansionOn();
if (*(valueType **)resultThing == NULL) {
error(VALUELESS_ARRAY_ELEMENT_ERROR);
result = NULL;
} else if (kindOfResult == FAIL) {
result = NULL;
} else if (kindOfResult == STRING_VALUE) {
charPtr = (stringType *)resultThing;
result = typeAlloc(expressionType);
result->kindOfTerm = VALUE_EXPR;
result->expressionTerm.valueUnion = newValue(ABSOLUTE_VALUE,
*charPtr, EXPRESSION_OPND);
} else {
valuePtr = (valueType **) resultThing;
if ((*valuePtr)->kindOfValue == OPERAND_VALUE) {
saveEnvironment = currentEnvironment;
currentEnvironment = currentEnvironment->
previousEnvironment;
if ((newOperand = duplicateOperandForFixup((*
valuePtr)->value, FALSE)) == NULL) {
result = NULL;
} else {
result = typeAlloc(expressionType);
result->kindOfTerm = VALUE_EXPR;
result->expressionTerm.valueUnion = newValue(
OPERAND_VALUE, newOperand,
newOperand->kindOfOperand);
}
currentEnvironment = saveEnvironment;
} else {
result = typeAlloc(expressionType);
result->kindOfTerm = VALUE_EXPR;
dupValue(result->expressionTerm.valueUnion,*valuePtr);
}
}
return(result);
}

BIN
fixups.o Normal file

Binary file not shown.

829
garbage.c Normal file
View File

@ -0,0 +1,829 @@
/*
garbage.c -- Routines to eat up a parse tree and throw it away
Chip Morningstar -- Lucasfilm Ltd.
4-February-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "y.tab.h"
#define nullFree(thing) if (thing == NULL) return;
void
freeArrayTerm(arrayTerm)
arrayTermType *arrayTerm;
{
void freeExpression();
nullFree(arrayTerm);
freeExpression(arrayTerm->arrayName);
freeExpression(arrayTerm->arrayIndex);
free(arrayTerm);
}
void
freeAssignmentTerm(assignmentTerm)
binopTermType *assignmentTerm;
{
void freeExpression();
nullFree(assignmentTerm);
freeExpression(assignmentTerm->rightArgument);
free(assignmentTerm);
}
void
freeBinopTerm(binopTerm)
binopTermType *binopTerm;
{
void freeExpression();
nullFree(binopTerm);
freeExpression(binopTerm->leftArgument);
if (binopTerm->binop != SELECT)
freeExpression(binopTerm->rightArgument);
free(binopTerm);
}
void
freeFunctionCall(functionCall)
functionCallTermType *functionCall;
{
void freeOperandList();
nullFree(functionCall);
freeOperandList(functionCall->parameters);
free(functionCall);
}
void
freePostopTerm(postopTerm)
postOpTermType *postopTerm;
{
nullFree(postopTerm);
free(postopTerm);
}
void
freePreopTerm(preopTerm)
preOpTermType *preopTerm;
{
nullFree(preopTerm);
free(preopTerm);
}
void
freeString(string)
stringType *string;
{
nullFree(string);
free(string);
}
void
freeUnopTerm(unopTerm)
unopTermType *unopTerm;
{
void freeExpression();
nullFree(unopTerm);
freeExpression(unopTerm->unopArgument);
free(unopTerm);
}
void
freeExpression(expression)
expressionType *expression;
{
nullFree(expression);
switch (expression->kindOfTerm) {
case CONDITION_CODE_EXPR:
case HERE_EXPR:
case IDENTIFIER_EXPR:
case NUMBER_EXPR:
case VALUE_EXPR:
case STRING_EXPR:
break;
case ARRAY_EXPR:
freeArrayTerm(expression->expressionTerm);
break;
case ASSIGN_EXPR:
freeAssignmentTerm(expression->expressionTerm);
break;
case BINOP_EXPR:
freeBinopTerm(expression->expressionTerm);
break;
case FUNCTION_CALL_EXPR:
freeFunctionCall(expression->expressionTerm);
break;
case POSTOP_EXPR:
freePostopTerm(expression->expressionTerm);
break;
case PREOP_EXPR:
freePreopTerm(expression->expressionTerm);
break;
case SUBEXPRESSION_EXPR:
freeExpression(expression->expressionTerm);
break;
case UNOP_EXPR:
freeUnopTerm(expression->expressionTerm);
break;
default:
botch("freeExpression: funny expression kind %d\n",
expression->kindOfTerm);
break;
}
free(expression);
}
void
freeExpressionList(expressionList)
expressionListType *expressionList;
{
expressionListType *newExpressionList;
while (expressionList != NULL) {
freeExpression(expressionList->theExpression);
newExpressionList = expressionList->nextExpression;
free(expressionList);
expressionList = newExpressionList;
}
}
void
freeIdentifierList(identifierList)
identifierListType *identifierList;
{
identifierListType *newIdentifierList;
while (identifierList != NULL) {
newIdentifierList = identifierList->nextIdentifier;
free(identifierList);
identifierList = newIdentifierList;
}
}
void
freeSelectionList(selectionList)
selectionListType *selectionList;
{
freeIdentifierList(selectionList);
}
void
freeBlock(block)
blockType *block;
{
void freeStatement();
nullFree(block);
freeStatement(block);
}
void
freeCase(aCase)
caseType *aCase;
{
freeExpressionList(aCase->caseTags);
freeBlock(aCase->caseBody);
free(aCase);
}
void
freeCaseList(caseList)
caseListType *caseList;
{
caseListType *newCaseList;
while (caseList != NULL) {
freeCase(caseList->theCase);
newCaseList = caseList->nextCase;
free(caseList);
caseList = newCaseList;
}
}
void
freeOperandList(operandList)
operandListType *operandList;
{
freeOperand(operandList);
}
void
freeMacro(operands)
operandListType *operands;
{
freeOperandList(operands);
}
void
freeMachineInstruction(operands)
operandListType *operands;
{
freeOperandList(operands);
}
void
freeAlignStatement(alignStatement)
alignStatementBodyType *alignStatement;
{
nullFree(alignStatement);
freeExpression(alignStatement);
}
void
freeAssertStatement(assertStatement)
assertStatementBodyType *assertStatement;
{
nullFree(assertStatement);
freeExpression(assertStatement->condition);
freeExpression(assertStatement->message);
free(assertStatement);
}
void
freeBlockStatement(blockStatement)
blockStatementBodyType *blockStatement;
{
nullFree(blockStatement);
freeExpressionList(blockStatement);
}
void
freeByteStatement(byteStatement)
byteStatementBodyType *byteStatement;
{
byteStatementBodyType *newByteStatement;
nullFree(byteStatement);
while (byteStatement != NULL) {
freeExpression(byteStatement->theExpression);
newByteStatement = byteStatement->nextExpression;
free(byteStatement);
byteStatement = newByteStatement;
}
}
void
freeConstrainStatement(constrainStatement)
constrainStatementBodyType *constrainStatement;
{
nullFree(constrainStatement);
freeExpression(constrainStatement->constraint);
freeBlock(constrainStatement->constrainedBlock);
free(constrainStatement);
}
void
freeDbyteStatement(dbyteStatement)
dbyteStatementBodyType *dbyteStatement;
{
dbyteStatementBodyType *newDbyteStatement;
nullFree(dbyteStatement);
while (dbyteStatement != NULL) {
freeExpression(dbyteStatement->theExpression);
newDbyteStatement = dbyteStatement->nextExpression;
free(dbyteStatement);
dbyteStatement = newDbyteStatement;
}
}
void
freeDefineStatement(defineStatement)
defineStatementBodyType *defineStatement;
{
nullFree(defineStatement);
freeExpression(defineStatement->theValue);
free(defineStatement);
}
void
freeDoUntilStatement(doUntilStatement)
doUntilStatementBodyType *doUntilStatement;
{
nullFree(doUntilStatement);
freeBlock(doUntilStatement->doUntilLoop);
free(doUntilStatement);
}
void
freeDoWhileStatement(doWhileStatement)
doWhileStatementBodyType *doWhileStatement;
{
nullFree(doWhileStatement);
freeBlock(doWhileStatement->doWhileLoop);
free(doWhileStatement);
}
void
freeExternStatement(externStatement)
externStatementBodyType *externStatement;
{
freeIdentifierList(externStatement);
}
void
freeFreturnStatement(freturnStatement)
freturnStatementBodyType *freturnStatement;
{
nullFree(freturnStatement);
freeExpression(freturnStatement);
}
void
freeFunctionStatement(functionStatement)
functionStatementBodyType *functionStatement;
{
nullFree(functionStatement);
free(functionStatement->functionName);
free(functionStatement);
}
void
freeIfStatement(ifStatement)
ifStatementBodyType *ifStatement;
{
nullFree(ifStatement);
if (ifStatement->consequence != NULL)
freeBlock(ifStatement->consequence);
if (ifStatement->continuation.continuationBodyUnion != NULL) {
freeIfStatement(ifStatement->continuation);
}
free(ifStatement);
}
void
freeIncludeStatement(includeStatement)
includeStatementBodyType *includeStatement;
{
nullFree(includeStatement);
freeExpression(includeStatement);
}
void
freeInstructionStatement(instructionStatement)
instructionStatementBodyType *instructionStatement;
{
nullFree(instructionStatement);
switch(instructionStatement->kindOfInstruction) {
case OPCODE_INSTRUCTION:
freeMachineInstruction(instructionStatement->theOperands);
break;
case MACRO_INSTRUCTION:
freeMacro(instructionStatement->theOperands);
break;
default:
botch("bad instruction type=%d\n", instructionStatement->
kindOfInstruction);
break;
}
}
void
freeLongStatement(longStatement)
longStatementBodyType *longStatement;
{
longStatementBodyType *newLongStatement;
nullFree(longStatement);
while (longStatement != NULL) {
freeExpression(longStatement->theExpression);
newLongStatement = longStatement->nextExpression;
free(longStatement);
longStatement = newLongStatement;
}
}
void
freeMacroStatement(macroStatement)
macroStatementBodyType *macroStatement;
{
nullFree(macroStatement);
free(macroStatement);
}
void
freeMdefineStatement(mdefineStatement)
defineStatementBodyType *mdefineStatement;
{
valueType *freeDefineExpression();
nullFree(mdefineStatement);
freeExpression(mdefineStatement->theValue);
free(mdefineStatement);
}
void
freeMdoUntilStatement(mdoUntilStatement)
mdoUntilStatementBodyType *mdoUntilStatement;
{
nullFree(mdoUntilStatement);
freeBlock(mdoUntilStatement->mdoUntilLoop);
freeExpression(mdoUntilStatement->mdoUntilCondition);
}
void
freeMdoWhileStatement(mdoWhileStatement)
mdoWhileStatementBodyType *mdoWhileStatement;
{
nullFree(mdoWhileStatement);
freeBlock(mdoWhileStatement->mdoWhileLoop);
freeExpression(mdoWhileStatement->mdoWhileCondition);
free(mdoWhileStatement);
}
void
freeMifStatement(mifStatement)
mifStatementBodyType *mifStatement;
{
nullFree(mifStatement);
freeExpression(mifStatement->mifCondition);
freeBlock(mifStatement->mifConsequence);
freeMifStatement(mifStatement->mifContinuation.
mifContinuationBodyUnion);
free(mifStatement);
}
void
freeMswitchStatement(mswitchStatement)
mswitchStatementBodyType *mswitchStatement;
{
freeExpression(mswitchStatement->switchExpression);
freeCaseList(mswitchStatement->cases);
free(mswitchStatement);
}
void
freeMforStatement(mforStatement)
mforStatementBodyType *mforStatement;
{
nullFree(mforStatement);
freeExpression(mforStatement->initExpression);
freeExpression(mforStatement->testExpression);
freeExpression(mforStatement->incrExpression);
freeBlock(mforStatement->forLoop);
free(mforStatement);
}
void
freeMvariableStatement(mvariableStatement)
mvariableStatementBodyType *mvariableStatement;
{
nullFree(mvariableStatement);
if ((int)mvariableStatement->theDimension != -1)
freeExpression(mvariableStatement->theDimension);
freeExpressionList(mvariableStatement->theValue);
free(mvariableStatement);
}
void
freeMwhileStatement(mwhileStatement)
mwhileStatementBodyType *mwhileStatement;
{
nullFree(mwhileStatement);
freeExpression(mwhileStatement->mwhileCondition);
freeBlock(mwhileStatement->mwhileLoop);
free(mwhileStatement);
}
void
freeOrgStatement(orgStatement)
orgStatementBodyType *orgStatement;
{
nullFree(orgStatement);
freeExpression(orgStatement);
}
void
freePerformStatement(performStatement)
performStatementBodyType *performStatement;
{
nullFree(performStatement);
freeExpression(performStatement);
}
void
freeRelStatement(relStatement)
relStatementBodyType *relStatement;
{
}
void
freeStartStatement(startStatement)
startStatementBodyType *startStatement;
{
nullFree(startStatement);
freeExpression(startStatement);
}
void
freeStringStatement(stringStatement)
stringStatementBodyType *stringStatement;
{
stringStatementBodyType *newStringStatement;
nullFree(stringStatement);
while (stringStatement != NULL) {
freeExpression(stringStatement->theExpression);
newStringStatement = stringStatement->nextExpression;
free(stringStatement);
stringStatement = newStringStatement;
}
}
void
freeStructStatement(structStatement)
structStatementBodyType *structStatement;
{
nullFree(structStatement);
freeBlock(structStatement->structBody);
free(structStatement);
}
void
freeTargetStatement(targetStatement)
targetStatementBodyType *targetStatement;
{
nullFree(targetStatement);
freeExpression(targetStatement);
}
void
freeUndefineStatement(undefineStatement)
undefineStatementBodyType *undefineStatement;
{
freeIdentifierList(undefineStatement);
}
void
freeVariableStatement(variableStatement)
variableStatementBodyType *variableStatement;
{
nullFree(variableStatement);
if ((int)variableStatement->theDimension != -1)
freeExpression(variableStatement->theDimension);
freeExpressionList(variableStatement->theValue);
free(variableStatement);
}
void
freeWhileStatement(whileStatement)
whileStatementBodyType *whileStatement;
{
nullFree(whileStatement);
freeBlock(whileStatement->whileLoop);
free(whileStatement);
}
void
freeWordStatement(wordStatement)
wordStatementBodyType *wordStatement;
{
wordStatementBodyType *newWordStatement;
nullFree(wordStatement);
while (wordStatement != NULL) {
freeExpression(wordStatement->theExpression);
newWordStatement = wordStatement->nextExpression;
free(wordStatement);
wordStatement = newWordStatement;
}
}
void
freeStatementBody(kind, body)
statementKindType kind;
statementBodyType body;
{
switch (kind) {
case ALIGN_STATEMENT:
freeAlignStatement(body);
break;
case ASSERT_STATEMENT:
freeAssertStatement(body);
break;
case BLOCK_STATEMENT:
freeBlockStatement(body);
break;
case BYTE_STATEMENT:
freeByteStatement(body);
break;
case CONSTRAIN_STATEMENT:
freeConstrainStatement(body);
break;
case DBYTE_STATEMENT:
freeDbyteStatement(body);
break;
case DEFINE_STATEMENT:
freeDefineStatement(body);
break;
case DO_UNTIL_STATEMENT:
freeDoUntilStatement(body);
break;
case DO_WHILE_STATEMENT:
freeDoWhileStatement(body);
break;
case EXTERN_STATEMENT:
freeExternStatement(body);
break;
case FRETURN_STATEMENT:
freeFreturnStatement(body);
break;
case FUNCTION_STATEMENT:
freeFunctionStatement(body);
break;
case GROUP_STATEMENT:
freeBlock(body);
break;
case IF_STATEMENT:
freeIfStatement(body);
break;
case INCLUDE_STATEMENT:
freeIncludeStatement(body);
break;
case INSTRUCTION_STATEMENT:
freeInstructionStatement(body);
break;
case LONG_STATEMENT:
freeLongStatement(body);
break;
case MACRO_STATEMENT:
freeMacroStatement(body);
break;
case MDEFINE_STATEMENT:
freeMdefineStatement(body);
break;
case MDO_UNTIL_STATEMENT:
freeMdoUntilStatement(body);
break;
case MDO_WHILE_STATEMENT:
freeMdoWhileStatement(body);
break;
case MIF_STATEMENT:
freeMifStatement(body);
break;
case MSWITCH_STATEMENT:
freeMswitchStatement(body);
break;
case MFOR_STATEMENT:
freeMforStatement(body);
break;
case MVARIABLE_STATEMENT:
freeMvariableStatement(body);
break;
case MWHILE_STATEMENT:
freeMwhileStatement(body);
break;
case NULL_STATEMENT:
/* do nothing */
break;
case ORG_STATEMENT:
freeOrgStatement(body);
break;
case PERFORM_STATEMENT:
freePerformStatement(body);
break;
case REL_STATEMENT:
freeRelStatement(body);
break;
case START_STATEMENT:
freeStartStatement(body);
break;
case STRING_STATEMENT:
freeStringStatement(body);
break;
case STRUCT_STATEMENT:
freeStructStatement(body);
break;
case TARGET_STATEMENT:
freeTargetStatement(body);
break;
case UNDEFINE_STATEMENT:
freeUndefineStatement(body);
break;
case VARIABLE_STATEMENT:
freeVariableStatement(body);
break;
case WHILE_STATEMENT:
freeWhileStatement(body);
break;
case WORD_STATEMENT:
freeWordStatement(body);
break;
default:
botch("freeStatementBody doesn't know kind %d\n", kind);
break;
}
}
void
freeLabelList(labelList)
labelListType *labelList;
{
labelListType *nextLabel;
while (labelList != NULL) {
nextLabel = labelList->nextLabel;
free(labelList);
labelList = nextLabel;
}
}
void
freeStatement(statement)
statementType *statement;
{
statementType *newStatement;
while (statement != NULL) {
freeLabelList(statement->labels);
freeStatementBody(statement->kindOfStatement, statement->
statementBody);
newStatement = statement->nextStatement;
free(statement);
statement = newStatement;
}
}
void
freeArray(array)
arrayType *array;
{
int i;
void freeValue();
if (array->arraySize > 0) {
for (i=0; i<array->arraySize; i++)
freeValue((array->arrayContents)[i]);
free(array->arrayContents);
}
free(array);
}
void
freeValue(value)
valueType *value;
{
if (value->kindOfValue == STRING_VALUE)
freeString(value->value);
else if (value->kindOfValue == ARRAY_VALUE)
freeArray(value->value);
free(value);
}

BIN
garbage.o Normal file

Binary file not shown.

557
initialize.c Normal file
View File

@ -0,0 +1,557 @@
/*
initialize.c -- Routines to get things going for the Macross assembler
Chip Morningstar -- Lucasfilm Ltd.
6-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#define isAlphaNumeric(c) (alphaNumericCharacterTable[c])
extern int yydebug;
static fileNameListType *bottomOfInputFileStack;
static char *outputFileName;
void
chokePukeAndDie()
{
unlink(outputFileName);
exit(1);
}
void
initializeStuff(argc, argv)
int argc;
char *argv[];
{
int i;
int j;
char **args;
char *arg;
int outputFilesFound;
int listFilesFound;
int symbolDumpFilesFound;
char *listFileName;
char *symbolDumpFileName;
bool dontUnlinkTempFiles;
void createHashTables();
void installBuiltInFunctions();
void installPredefinedSymbols();
void installCommandLineDefineSymbols();
void openFirstInputFile();
void queueInputFile();
void noteCommandLineDefine();
for (i=0; i<128; i++) {
lowerCaseCharacterTable[i] = i;
alphabeticCharacterTable[i] = FALSE;
numericCharacterTable[i] = FALSE;
alphaNumericCharacterTable[i] = FALSE;
}
for (i='A'; i<='Z'; i++) {
lowerCaseCharacterTable[i] = i - 'A' + 'a';
alphabeticCharacterTable[i] = TRUE;
alphabeticCharacterTable[i - 'A' + 'a'] = TRUE;
alphaNumericCharacterTable[i] = TRUE;
alphaNumericCharacterTable[i - 'A' + 'a'] = TRUE;
}
alphabeticCharacterTable['_'] = TRUE;
alphaNumericCharacterTable['_'] = TRUE;
for (i='0'; i<='9'; i++) {
numericCharacterTable[i] = TRUE;
alphaNumericCharacterTable[i] = TRUE;
}
outputFilesFound = 0;
listFilesFound = 0;
symbolDumpFilesFound = 0;
outputFileName = DEFAULT_OBJECT_FILE_NAME;
dontUnlinkTempFiles = FALSE;
produceLinkableObject = FALSE;
currentFileName = "<command line>"; /* for error messages... */
currentLineNumber = 1; /* ...during startup */
cumulativeLineNumber = 1;
nextEnvironmentNumber = GLOBAL_ENVIRONMENT_NUMBER;
currentEnvironment = NULL;
pushEnvironment(globalEnvironment);
beneathFunction = FALSE;
includeNestingDepth = 0;
macroOrFunctionNestingDepth = 0;
macroCallDepth = 0;
tabCount = 1;
statementEvaluationDepth = 0;
structNestingDepth = 0;
performingFixups = FALSE;
generatingFixup = FALSE;
finishOperand = FALSE;
unknownSymbolTag = UNKNOWN_SYMBOL;
haveUserStartAddress = FALSE;
fixupStartAddress = FALSE;
currentLabelTagNumber = 0;
currentLocalVariableList = NULL;
inputFileStack = bottomOfInputFileStack = NULL;
listingControlCounter = 0;
nextLabelTagNumber = 1;
commandLineDefines = NULL;
showAllSymbolsFlag = FALSE;
backwardsCompatibleIfFlag = FALSE;
debug = FALSE;
yydebug = FALSE;
emitPrint = FALSE;
freeFlag = TRUE;
freturnExit = FALSE;
listingOn = FALSE;
expandMacros = FALSE;
standaloneExpansionFlag = FALSE;
terseErrorMessages = FALSE;
lastErrorLine = -1;
lastErrorFile = NULL;
symbolTableDumpOn = 0;
positionIndependentCodeMode = FALSE;
hackFlag = 0;
args = argv + 1;
for (i=1; i<argc; i++) {
arg = *args++;
if (*arg != '-') {
if (!isDotMName(arg)) {
fatalError(FILE_NAME_IS_NOT_MACROSS_SOURCE_ERROR,
arg);
}
queueInputFile(arg);
continue;
}
for (j=1; arg[j]!='\0'; j++) switch (arg[j]) {
case 'a':
showAllSymbolsFlag = TRUE;
continue;
case 'B':
backwardsCompatibleIfFlag = TRUE;
continue;
case 'c':
produceLinkableObject = TRUE;
continue;
case 'd':
debug = TRUE;
continue;
case 'D':
if (++i >= argc) {
fatalError(NO_DASH_D_FILE_NAME_ERROR);
} else {
noteCommandLineDefine(*args++);
}
continue;
case 'e':
emitPrint = TRUE;
continue;
case 'g':
freeFlag = FALSE;
continue;
case 'l':
if (++i >= argc) {
fatalError(NO_LIST_FILE_NAME_ERROR);
} else {
if (isDotMName(*args)) {
fatalError(LIST_FILE_NAME_IS_MACROSS_SOURCE_ERROR,
*args);
}
listFileName = *args++;
listFilesFound++;
}
listingOn = TRUE;
continue;
case 'm':
expandMacros = TRUE;
continue;
case 'o':
if (++i >= argc) {
fatalError(NO_DASH_O_FILE_NAME_ERROR);
} else {
if (isDotMName(*args)) {
fatalError(OUTPUT_FILE_NAME_IS_MACROSS_SOURCE_ERROR,
*args);
}
outputFileName = *args++;
outputFilesFound++;
}
continue;
case 'p':
positionIndependentCodeMode = TRUE;
continue;
case 's':
case 'S':
case 'h':
case 'H':
if (++i >= argc) {
fatalError(NO_SYMBOL_DUMP_FILE_NAME_ERROR, arg[j]);
} else {
if (isDotMName(*args)) {
fatalError(SYMBOL_DUMP_FILE_NAME_IS_MACROSS_SOURCE_ERROR,
*args);
}
symbolDumpFileName = *args++;
symbolDumpFilesFound++;
}
if (arg[j] == 'h') {
hackFlag = 1;
symbolTableDumpOn = 1;
} else if (arg[j] == 'H') {
hackFlag = 2;
symbolTableDumpOn = 1;
} else {
symbolTableDumpOn = arg[j]=='s' ? 1 : 2;
}
continue;
case 't':
terseErrorMessages = TRUE;
continue;
case 'u':
dontUnlinkTempFiles = TRUE;
continue;
case 'v':
printVersion();
continue;
case 'Y':
yydebug = TRUE;
continue;
default:
warning(BAD_COMMAND_LINE_FLAG_ERROR, arg[j]);
continue;
}
}
openFirstInputFile();
if (outputFilesFound > 1) {
warning(MORE_THAN_ONE_OUTPUT_FILE_ERROR);
} else if ((objectFileOutput = fopen(outputFileName, "w"))==NULL) {
fatalSystemError(CANT_OPEN_OBJECT_FILE_ERROR, outputFileName);
}
if (listFilesFound > 1) {
warning(MORE_THAN_ONE_LIST_FILE_ERROR);
} else if (listFilesFound == 1) {
if (strcmp(listFileName, "-") == 0) {
listFileOutput = stdout;
} else if ((listFileOutput = fopen(listFileName, "w"))==NULL){
fatalSystemError(CANT_OPEN_LIST_FILE_ERROR, listFileName);
}
}
if (symbolDumpFilesFound > 1) {
warning(MORE_THAN_ONE_SYMBOL_DUMP_FILE_ERROR);
} else if (symbolDumpFilesFound == 1) {
if (strcmp(symbolDumpFileName, "-") == 0) {
symbolDumpFileOutput = stdout;
} else if ((symbolDumpFileOutput = fopen(symbolDumpFileName,
"w"))==NULL) {
fatalSystemError(CANT_OPEN_SYMBOL_DUMP_FILE_ERROR, symbolDumpFileName);
}
}
expressionReferenceList[0] = expressionReferenceList[1] = NULL;
numberOfReferencesInList[0] = numberOfReferencesInList[1] = 0;
externalFunctionList = endOfExternalFunctionList = NULL;
externalFunctionCount = 0;
currentLocationCounter.kindOfValue = RELOCATABLE_VALUE;
currentLocationCounter.value = 0;
targetOffset = 0;
currentCodeMode = RELOCATABLE_BUFFER;
relocatableHighWaterMark = -1;
codeBreakList = NULL;
lastCodeBreak = NULL;
reservationList = NULL;
for (i=0; i<HASH_TABLE_SIZE; i++) {
macroTable[i] = NULL;
opcodeTable[i] = NULL;
symbolTable[i] = NULL;
keywordTable[i] = NULL;
conditionTable[i] = NULL;
}
absoluteCodeRegion.regionStartAddress = relocatableCodeRegion.
regionStartAddress = 0xFFFF + 1;
absoluteCodeRegion.regionEndAddress = relocatableCodeRegion.
regionEndAddress = -1;
for (i=0; i<CODE_BUFFERS_IN_ADDRESS_SPACE; i++) {
absoluteCodeRegion.codeSegments[i] = NULL;
relocatableCodeRegion.codeSegments[i] = NULL;
}
emptyBuffer = typeAlloc(codeBufferType);
for (i=0; i<CODE_BUFFER_SIZE; i++)
(*emptyBuffer)[i] = 0;
createHashTables();
initializeLexDispatchTable();
installBuiltInFunctions();
installPredefinedSymbols();
installCommandLineDefineSymbols();
if (listingOn) {
if ((saveFileForPass2 = fopen(mktemp(pass2SourceFileName),
"w+")) == NULL) {
fatalSystemError(UNABLE_TO_OPEN_PASS_2_FILE_ERROR,
pass2SourceFileName);
}
if (!dontUnlinkTempFiles)
unlink(pass2SourceFileName); /* will take effect on
program exit */
if ((indexFileForPass2 = fopen(mktemp(pass2IndexFileName),
"w+")) == NULL) {
fatalSystemError(UNABLE_TO_OPEN_PASS_2_FILE_ERROR,
pass2IndexFileName);
}
if (!dontUnlinkTempFiles)
unlink(pass2IndexFileName); /* will take effect on
program exit */
if (expandMacros) {
if ((macroFileForPass2 = fopen(mktemp(
pass2MacroExpansionFileName),"w+")) == NULL) {
fatalSystemError(
UNABLE_TO_OPEN_PASS_2_FILE_ERROR,
pass2MacroExpansionFileName);
}
if (!dontUnlinkTempFiles)
unlink(pass2MacroExpansionFileName); /* will
take effect on program exit */
} else {
macroFileForPass2 = fopen("/dev/null", "w+");
}
} else {
if (expandMacros) {
warning(MACRO_EXPANSION_WITHOUT_LISTING_ERROR);
expandMacros = FALSE;
}
}
}
void
installBuiltInFunctions()
{
int i;
symbolTableEntryType *newFunction;
symbolTableEntryType *lookupOrEnterSymbol();
valueType *newValue();
for (i=0; builtInFunctionTable[i].functionName!=NULL; i++) {
newFunction = lookupOrEnterSymbol(builtInFunctionTable[i].
functionName, BUILT_IN_FUNCTION_SYMBOL);
newFunction->context->value =newValue(BUILT_IN_FUNCTION_VALUE,
i, EXPRESSION_OPND);
if (builtInFunctionTable[i].isSpecialFunction)
newFunction->context->attributes |=
SPECIAL_FUNCTION_ATT;
}
}
void
installPredefinedSymbols()
{
int i;
symbolTableEntryType *newSymbol;
symbolTableEntryType *lookupOrEnterSymbol();
valueType *newValue();
for (i=0; predefinedSymbolTable[i].symbolName!=NULL; i++) {
newSymbol = lookupOrEnterSymbol(predefinedSymbolTable[i].
symbolName, DEFINE_SYMBOL);
newSymbol->context->value = newValue(ABSOLUTE_VALUE,
predefinedSymbolTable[i].symbolValue,
EXPRESSION_OPND);
newSymbol->context->attributes |= DEFINED_VARIABLE_ATT;
}
}
void
installCommandLineDefineSymbols()
{
int i;
symbolTableEntryType *newSymbol;
symbolTableEntryType *lookupOrEnterSymbol();
valueType *newValue();
while (commandLineDefines != NULL) {
newSymbol = lookupOrEnterSymbol(commandLineDefines->name,
DEFINE_SYMBOL);
newSymbol->context->value = newValue(ABSOLUTE_VALUE,
commandLineDefines->value, EXPRESSION_OPND);
newSymbol->context->attributes |= DEFINED_VARIABLE_ATT;
commandLineDefines = commandLineDefines->nextDefine;
}
}
void
createHashTables()
{
opcodeTableEntryType *newOpcodeEntry;
keywordTableEntryType *newKeywordEntry;
conditionTableEntryType *newConditionEntry;
newOpcodeEntry = theOpcodes;
while (newOpcodeEntry->mnemonic != NULL)
hashStringEnter(newOpcodeEntry++, opcodeTable);
newKeywordEntry = theKeywords;
while (newKeywordEntry->string != NULL)
hashStringEnter(newKeywordEntry++, keywordTable);
newConditionEntry = theConditions;
while (newConditionEntry->string != NULL)
hashStringEnter(newConditionEntry++, conditionTable);
}
void
queueInputFile(name)
char *name;
{
fileNameListType *newFileName;
newFileName = typeAlloc(fileNameListType);
newFileName->name = name;
newFileName->fildes = NULL;
newFileName->openFlag = FALSE;
newFileName->nextFileName = NULL;
newFileName->lineNumber = 1;
if (inputFileStack == NULL) {
inputFileStack = bottomOfInputFileStack = newFileName;
} else {
bottomOfInputFileStack->nextFileName = newFileName;
bottomOfInputFileStack = newFileName;
}
}
void
openFirstInputFile()
{
if (inputFileStack == NULL) {
inputFileStack = typeAlloc(fileNameListType);
inputFileStack->name = "<standard input>";
inputFileStack->fildes = stdin;
inputFileStack->openFlag = TRUE;
inputFileStack->lineNumber = 1;
inputFileStack->nextFileName = NULL;
} else {
if ((inputFileStack->fildes = fopen(inputFileStack->name,
"r")) == NULL) {
fatalSystemError(UNABLE_TO_OPEN_INPUT_FILE_ERROR,
inputFileStack->name);
} else {
inputFileStack->openFlag = TRUE;
}
}
input = inputFileStack->fildes;
currentLineNumber = inputFileStack->lineNumber;
currentFileName = inputFileStack->name;
currentOperandNumber = 0;
}
bool
isDotMName(fileName)
stringType *fileName;
{
int length;
length = strlen(fileName);
return(length >= 2 && fileName[length - 1] == 'm' &&
fileName[length - 2] == '.');
}
bool
parseCommandLineDefine(arg, name, value)
char *arg;
char **name;
int *value;
{
char *ptr;
char c;
int base;
int start;
ptr = arg;
while ((c = *ptr++) && (ptr-arg)<MAX_NAME_SIZE && isAlphaNumeric(c))
;
--ptr;
if (c=='\0') {
*value = 1;
} else if (c == '=') {
*ptr++ = '\0';
if (ptr[0] != '0') {
base = 10;
start = 0;
} else if (ptr[1]=='b' || ptr[1]=='B') {
base = 2;
start = 2;
} else if (ptr[1]=='q' || ptr[1]=='Q') {
base = 4;
start = 2;
} else if (ptr[1]=='x' || ptr[1]=='X') {
base = 16;
start = 2;
} else {
base = 8;
start = 1;
}
*value = fancyAtoI(&ptr[start], base);
} else {
error(BAD_COMMAND_LINE_DEFINE_ERROR, arg);
*name = NULL;
*value = 0;
return(FALSE);
}
*name = arg;
return(TRUE);
}
void
noteCommandLineDefine(arg)
char *arg;
{
char *name;
int value;
commandLineDefineType *newCommandLineDefine;
bool parseCommandLineDefine();
if (parseCommandLineDefine(arg, &name, &value)) {
newCommandLineDefine = typeAlloc(commandLineDefineType);
newCommandLineDefine->name = name;
newCommandLineDefine->value = value;
newCommandLineDefine->nextDefine = commandLineDefines;
commandLineDefines = newCommandLineDefine;
}
}

BIN
initialize.o Normal file

Binary file not shown.

542
lexer.c Normal file
View File

@ -0,0 +1,542 @@
/*
lexer.c -- Lexical scanner for the Macross assembler
Chip Morningstar -- Lucasfilm Ltd.
3-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "y.tab.h"
#include "lexerTables.h"
extern int yylval;
extern int yydebug;
static char lineBuffer[LINE_BUFFER_SIZE] = { '\0' };
static int lineBufferPtr = 0;
#define getNextChar() (lineBuffer[lineBufferPtr] ? \
lineBuffer[lineBufferPtr++] : \
readAnotherLine())
/*int getNextChar() {int c;c=xgetNextChar();printf("read '%c'\n",c);return(c);}*/
#define oopsThatWasTheWrongChar(c) { if(lineBufferPtr) \
lineBuffer[--lineBufferPtr] = c; }
/*oopsThatWasTheWrongChar(c)char c;{printf("ungetting '%c'\n", c);xoopsThatWasTheWrongChar(c);}*/
#define isAlphabetic(c) (alphabeticCharacterTable[c])
#define isNumeric(c) (numericCharacterTable[c])
#define isAlphaNumeric(c) (alphaNumericCharacterTable[c])
int
yylex()
{
int result;
result = lexer();
if (yydebug) {
printf("lexer returns ");
printToken(result);
printf(", value=%d (0x%x)\n", yylval, yylval);
}
return(result);
}
int
lexer()
{
char c;
char skipWhitespaceAndComments();
if ((c = skipWhitespaceAndComments()) == EOF)
return(lexLiteral(c));
else
return((*lexDispatchTable[c])(c));
}
void
initializeLexDispatchTable()
{
int c;
int lexIdentifier();
int lexNumber();
int lexLiteral();
int lexCharacterConstant();
int lexStringConstant();
int lexOperator();
for (c = 0; c < LEX_DISPATCH_TABLE_SIZE; c++) {
if (isAlphabetic(c) || c=='$')
lexDispatchTable[c] = lexIdentifier;
else if (isNumeric(c))
lexDispatchTable[c] = lexNumber;
else if (isMacrossLiteralCharacter(c))
lexDispatchTable[c] = lexLiteral;
else if (c == '\'')
lexDispatchTable[c] = lexCharacterConstant;
else if (c == '"')
lexDispatchTable[c] = lexStringConstant;
else
lexDispatchTable[c] = lexOperator;
}
}
bool
isMacrossLiteralCharacter(c)
char c;
{
return(c==':' || c==',' || c=='@' || c=='#' ||
c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' ||
c=='\n' || c==EOF);
}
void
snarfAlphanumericString(c, buffer)
char c;
char *buffer;
{
char *bufferPtr;
bufferPtr = buffer;
do {
if (bufferPtr < &buffer[MAX_NAME_SIZE])
*bufferPtr++ = c;
c = getNextChar();
} while (c!=EOF && isAlphaNumeric(c));
*bufferPtr = '\0';
oopsThatWasTheWrongChar(c);
}
char nameBuffer[MAX_NAME_SIZE+1];
int
lexIdentifier(c)
char c;
{
char *saveString();
int hashValue;
snarfAlphanumericString(c, nameBuffer);
hashValue = hashString(nameBuffer);
if (yylval = lookupOpcode(nameBuffer, hashValue))
return(Opcode);
else if (yylval = lookupKeyword(nameBuffer, hashValue))
return(yylval);
else if ((yylval = lookupConditionCode(nameBuffer, hashValue)) !=
(int)NOT_FOUND_COND)
return(ConditionCode);
else if (yylval = lookupMacroName(nameBuffer, hashValue))
return(MacroName);
else {
yylval = (int) saveString(nameBuffer);
return(Identifier);
}
}
char numberBuffer[MAX_NAME_SIZE+1];
int
lexNumber(c)
char c;
{
int base;
int start;
snarfAlphanumericString(c, numberBuffer);
if (numberBuffer[0] != '0') {
base = 10;
start = 0;
} else if (numberBuffer[1]=='b' || numberBuffer[1]=='B') {
base = 2;
start = 2;
} else if (numberBuffer[1]=='q' || numberBuffer[1]=='Q') {
base = 4;
start = 2;
} else if (numberBuffer[1]=='x' || numberBuffer[1]=='X') {
base = 16;
start = 2;
} else {
base = 8;
start = 1;
}
yylval = fancyAtoI(&numberBuffer[start], base);
return(Number);
}
int
fancyAtoI(buffer, base)
char *buffer;
int base;
{
int value;
int digit;
char c;
value = 0;
while (*buffer != '\0') {
if ((digit = digitValue(c = *buffer++)) >= base) {
error(DIGIT_OUT_OF_RADIX_ERROR, c, base);
return(0);
}
value = value*base + digit;
}
return(value);
}
int
digitValue(c)
char c;
{
if (isNumeric(c))
return(c - '0');
else
return(toLowerCase(c) - 'a' + 10);
}
int
lexLiteral(c)
char c;
{
static bool passedEnd = FALSE;
yylval = 0;
if (c == '\n') {
return(EOL);
} else if (c == EOF) {
if (passedEnd) {
return(0);
} else {
passedEnd = TRUE;
return(ENDFILE);
}
} else {
return(c);
}
}
int
lexCharacterConstant()
{
char c;
yylval = getStringCharacter(input);
if (getNextChar() != '\'') {
error(UNCLOSED_CHARACTER_CONSTANT_ERROR);
while ((c = getNextChar())!='\'' && c!='\n' && c!=EOF)
;
}
return(Number);
}
bool escaped; /* true if last string character read was an escape
code. */
int
getStringCharacter(input)
FILE *input;
{
char c;
char *numberPtr;
int result;
char controlCharacter();
escaped = FALSE;
c = getNextChar();
if (c == '\\') {
escaped = TRUE;
c = getNextChar();
if (c == '^')
return(controlCharacter(getNextChar()));
else if ('0'<=c && c<='7') {
numberPtr = numberBuffer;
while ('0'<=c && c<='7') {
*numberPtr++ = c;
c = getNextChar();
}
*numberPtr = '\0';
oopsThatWasTheWrongChar(c);
result = fancyAtoI(numberBuffer, 8);
if (result > 0377)
error(OCTAL_CHARACTER_TOO_BIG_ERROR, result);
return (result % 0377);
} else
return(escapeCodes[c]);
} else
return(c);
}
char stringBuffer[MAX_NAME_SIZE + 1];
int
lexStringConstant()
{
char *stringPtr;
char c;
stringPtr = stringBuffer;
while (((c = getStringCharacter(input))!='"' && c!='\n' && c!=EOF)
|| escaped)
*stringPtr++ = c;
*stringPtr = '\0';
if (c=='\n' || c==EOF)
error(UNCLOSED_STRING_CONSTANT_ERROR);
yylval = (int)saveString(stringBuffer);
return(TextString);
}
int
lexOperator(firstC)
char firstC;
{
char secondC;
char thirdC;
int op;
int oper;
secondC = getNextChar();
for (op=0; operatorTable[op].first!='\0'; op++) {
if (operatorTable[op].first==firstC &&
operatorTable[op].second==secondC)
break;
else if (operatorTable[op].first==firstC &&
operatorTable[op].second=='\0') {
oopsThatWasTheWrongChar(secondC);
break;
}
}
if (operatorTable[op].first == '\0') {
error(UNRECOGNIZED_SOMETHING_OR_OTHER_ERROR, firstC);
return(yylex());
}
/* kludge to deal with the two three-character operators: */
if ((oper=operatorTable[op].token)==RIGHT_SHIFT || oper==LEFT_SHIFT) {
thirdC = getNextChar();
if (thirdC == '=') {
yylval = (int)((oper==RIGHT_SHIFT) ?
RIGHT_SHIFT_ASSIGN : LEFT_SHIFT_ASSIGN);
return(ASSIGN);
} else
oopsThatWasTheWrongChar(thirdC);
}
yylval = (int)operatorTable[op].value;
return(operatorTable[op].token);
}
char
controlCharacter(c)
char c;
{
#define CONTROL_CHARACTER_MASK (~0100)
return(c & CONTROL_CHARACTER_MASK);
}
char
skipWhitespaceAndComments()
{
char c;
while ((c=getNextChar())==' ' || c=='\t' || c=='/') {
if (c == '/') {
if ((c = getNextChar()) == '*') {
while (TRUE) {
while ((c = getNextChar()) != '*') {
if (c == EOF) {
error(UNCLOSED_COMMENT_ERROR);
return(c);
}
}
if ((c = getNextChar()) == '/') {
break;
} else if (c == '*') {
oopsThatWasTheWrongChar(c);
}
}
} else {
oopsThatWasTheWrongChar(c);
return('/');
}
}
}
if (c == ';') {
while ((c = getNextChar()) != '\n') {
if (c == EOF) {
error(UNCLOSED_LINE_COMMENT_ERROR);
return(c);
}
}
}
return(c);
}
int
popInputFileStack()
{
fileNameListType *oldFile;
if (inputFileStack->nextFileName == NULL)
return(EOF);
oldFile = inputFileStack;
inputFileStack = inputFileStack->nextFileName;
qfree(oldFile);
currentLineNumber = inputFileStack->lineNumber;
currentFileName = inputFileStack->name;
cumulativeLineNumber--;
fclose(input);
if (!inputFileStack->openFlag) {
if ((inputFileStack->fildes = fopen(inputFileStack->name,
"r")) == NULL) {
fatalSystemError(UNABLE_TO_OPEN_INPUT_FILE_ERROR,
inputFileStack->name);
} else {
inputFileStack->openFlag = TRUE;
}
}
input = inputFileStack->fildes;
if (includeNestingDepth > 0) {
includeNestingDepth--;
currentLineNumber--;
}
return(getNextChar());
}
void
pushInputFileStack(fileName)
stringType *fileName;
{
fileNameListType *newFileName;
inputFileStack->lineNumber = currentLineNumber;
newFileName = typeAlloc(fileNameListType);
if ((input = newFileName->fildes = fopen(fileName, "r")) == NULL) {
fatalSystemError(UNABLE_TO_OPEN_INCLUDE_FILE_ERROR, fileName);
}
newFileName->openFlag = TRUE;
newFileName->nextFileName = inputFileStack;
inputFileStack = newFileName;
currentFileName = newFileName->name = fileName;
currentLineNumber = newFileName->lineNumber = 1;
includeNestingDepth++;
if (statementEvaluationDepth == 1)
oopsThatWasTheWrongChar('\n'); /* hack for line #'s */
}
void
resynchronizeInput()
{
char c;
while ((c = getNextChar())!='\n' && c!=EOF)
;
oopsThatWasTheWrongChar(c);
}
bool longLineFlag = FALSE;
static bool previousLongLineFlag = FALSE;
void
saveLineForListing(line)
stringType *line;
{
if (!previousLongLineFlag) {
putw(currentLocationCounter.value, saveFileForPass2);
putw(includeNestingDepth, saveFileForPass2);
}
previousLongLineFlag = longLineFlag;
fputs(line, saveFileForPass2);
}
void
saveEOLForListing()
{
putw(-1, saveFileForPass2);
putw(includeNestingDepth, saveFileForPass2);
fputs("\n", saveFileForPass2);
}
void
saveIndexForListing(kindOfStatement, cumulativeLineNumber)
statementKindType kindOfStatement;
int cumulativeLineNumber;
{
if (!amExpanding() || !notListable(kindOfStatement)) {
putw(kindOfStatement, indexFileForPass2);
putw(currentLocationCounter.value, indexFileForPass2);
if (amExpanding())
putw(-cumulativeLineNumber, indexFileForPass2);
else
putw( cumulativeLineNumber, indexFileForPass2);
}
}
void
saveEndMifForListing(cumulativeLineNumber)
int cumulativeLineNumber;
{
putw(MIF_STATEMENT, indexFileForPass2);
putw(-1, indexFileForPass2);
if (amExpanding())
putw(-cumulativeLineNumber, indexFileForPass2);
else
putw(cumulativeLineNumber, indexFileForPass2);
}
void
saveListingOff()
{
saveIndexForListing(-1, cumulativeLineNumber);
}
void
saveListingOn()
{
if (currentCodeMode == ABSOLUTE_BUFFER)
saveIndexForListing(-1, cumulativeLineNumber);
else
saveIndexForListing(-2, cumulativeLineNumber);
}
char *
myfgets(buffer, length, stream)
char *buffer;
int length;
FILE *stream;
{
char *result;
char c;
result = buffer;
while (length-- > 1 && (c = getc(stream)) != EOF && c != '\n')
*buffer++ = c;
if (c == EOF) {
*result = '\0';
return(NULL);
}
if (length > 0)
*buffer++ = c;
if (length == 0 && c != '\n')
longLineFlag = TRUE;
else
longLineFlag = FALSE;
*buffer = '\0';
return(result);
}
int
readAnotherLine()
{
int result;
if (myfgets(lineBuffer, LINE_BUFFER_SIZE, input)) {
if (amListing())
saveLineForListing(lineBuffer);
lineBufferPtr = 1;
result = lineBuffer[0];
} else {
result = popInputFileStack();
}
currentLineNumber++;
cumulativeLineNumber++;
return(result);
}

BIN
lexer.o Normal file

Binary file not shown.

85
lexerTables.h Normal file
View File

@ -0,0 +1,85 @@
/*
lexerTables.h -- Tables describing stuff the lexer needs to know.
Chip Morningstar -- Lucasfilm Ltd.
3-November-1984
*/
struct {
char first;
char second;
int token;
assignmentKindType value;
} operatorTable[] = {
'!', '=', NOT_EQUAL_TO, NO_ASSIGN,
'!', '\0', LOGICAL_NOT, NO_ASSIGN,
'%', '=', ASSIGN, MOD_ASSIGN,
'%', '\0', MOD, NO_ASSIGN,
'&', '&', LOGICAL_AND, NO_ASSIGN,
'&', '=', ASSIGN, AND_ASSIGN,
'&', '\0', BITWISE_AND, NO_ASSIGN,
'*', '=', ASSIGN, MUL_ASSIGN,
'*', '\0', MUL, NO_ASSIGN,
'+', '+', INCREMENT, NO_ASSIGN,
'+', '=', ASSIGN, ADD_ASSIGN,
'+', '\0', ADD, NO_ASSIGN,
'-', '-', DECREMENT, NO_ASSIGN,
'-', '=', ASSIGN, SUB_ASSIGN,
'-', '\0', SUB, NO_ASSIGN,
'.', '\0', SELECT, NO_ASSIGN,
'/', '=', ASSIGN, DIV_ASSIGN,
'/', '\0', DIV, NO_ASSIGN,
'<', '<', LEFT_SHIFT, NO_ASSIGN,
'<', '=', LESS_THAN_OR_EQUAL_TO, NO_ASSIGN,
'<', '\0', LESS_THAN, NO_ASSIGN,
'=', '=', EQUAL_TO, NO_ASSIGN,
'=', '\0', ASSIGN, ASSIGN_ASSIGN,
'>', '=', GREATER_THAN_OR_EQUAL_TO, NO_ASSIGN,
'>', '>', RIGHT_SHIFT, NO_ASSIGN,
'>', '\0', GREATER_THAN, NO_ASSIGN,
'^', '=', ASSIGN, XOR_ASSIGN,
'^', '^', LOGICAL_XOR, NO_ASSIGN,
'^', '\0', BITWISE_XOR, NO_ASSIGN,
'|', '=', ASSIGN, OR_ASSIGN,
'|', '|', LOGICAL_OR, NO_ASSIGN,
'|', '\0', BITWISE_OR, NO_ASSIGN,
'~', '\0', BITWISE_NOT, NO_ASSIGN,
'?', '\0', HI_BYTE, NO_ASSIGN,
'\0', '\0', 0, NO_ASSIGN,
};
char escapeCodes[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
' ', '!', '"', '#', '$', '%', '&', '\'',
'(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'a', '\b', 'c', 'd', '\33', '\f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', '\n', 'o',
'p', 'q', '\r', 's', '\t', 'u', 'v', 'w',
'x', 'y', 'z', '{', '|', '}', '~', '\177',
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
'\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
'\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
'\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
'\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
'\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
'\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
'\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
'\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
'\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
};

649
listing.c Normal file
View File

@ -0,0 +1,649 @@
/*
listing.c -- Routines to generate a Macross assembly listing.
Chip Morningstar -- Lucasfilm Ltd.
10-February-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
static char lineBuffer1[LINE_BUFFER_SIZE];
static char lineBuffer2[LINE_BUFFER_SIZE];
static int cumulativeLineNumber = 0;
static char macroLineBuffer[LINE_BUFFER_SIZE];
static char nextMacroLineBuffer[LINE_BUFFER_SIZE];
static int macroAddress;
static int nextMacroAddress;
static int macroDepth;
static int nextMacroDepth;
void
outputListing()
{
void generateListing();
rewind(saveFileForPass2);
rewind(indexFileForPass2);
rewind(macroFileForPass2);
generateListing();
}
void
terminateListingFiles()
{
saveLineForListing("\n");
saveIndexForListing(NULL_STATEMENT, cumulativeLineNumber);
saveLineForListing("\n");
saveIndexForListing(NULL_STATEMENT, cumulativeLineNumber);
}
#define advanceSourceFile() \
if (nextSourceAddress == -1) {\
readSourceFileLine(&sourceAddress, &sourceDepth,\
sourceText = lineBuffer1, saveFileForPass2);\
readSourceFileLine(&nextSourceAddress,\
&nextSourceDepth, nextSourceText =\
lineBuffer2, saveFileForPass2);\
sourceLineNumber++;\
} else {\
sourceAddress = nextSourceAddress;\
sourceDepth = nextSourceDepth;\
tempText = sourceText;\
sourceText = nextSourceText;\
nextSourceText = tempText;\
if (tempText == NULL)\
nextSourceText = (sourceText==lineBuffer1) ?\
lineBuffer2 : lineBuffer1;\
readSourceFileLine(&nextSourceAddress,\
&nextSourceDepth, nextSourceText,\
saveFileForPass2);\
sourceLineNumber++;\
}
#define advanceIndexFile() {\
indexAddress = nextIndexAddress;\
indexLineNumber = nextIndexLineNumber;\
indexKind = nextIndexKind;\
readIndexFileLine(&nextIndexKind, &nextIndexAddress,\
&nextIndexLineNumber);\
}
/* This is the most horrible piece of code I have ever written in my entire
life -- cbm */
void
generateListing()
{
int sourceAddress;
int sourceDepth;
char *sourceText = lineBuffer1;
int nextSourceAddress;
int nextSourceDepth;
char *nextSourceText = lineBuffer2;
int sourceLineNumber;
int indexAddress;
int indexLineNumber;
statementKindType indexKind;
int nextIndexAddress;
int nextIndexLineNumber;
statementKindType nextIndexKind;
bool firstLine;
bool alreadyListingMacroExpansion;
bool finishingListingMacroExpansion;
bool nullMacroLine;
int callLineNumber;
int targetLineNumber;
bool mifEndFlag;
int numberOfBytesToList;
int numberOfBytesListed;
char *tempText;
void readIndexFileLine();
void readSourceFileLine();
sourceLineNumber = 1;
alreadyListingMacroExpansion = FALSE;
readSourceFileLine(&sourceAddress, &sourceDepth, sourceText,
saveFileForPass2);
readSourceFileLine(&nextSourceAddress, &nextSourceDepth,
nextSourceText, saveFileForPass2);
if (expandMacros)
readSourceFileLine(&nextMacroAddress, &nextMacroDepth,
nextMacroLineBuffer, macroFileForPass2);
readIndexFileLine(&indexKind, &indexAddress, &indexLineNumber);
readIndexFileLine(&nextIndexKind, &nextIndexAddress,
&nextIndexLineNumber);
currentCodeMode = RELOCATABLE_BUFFER;
if (indexKind == ORG_STATEMENT || indexKind == ALIGN_STATEMENT ||
indexKind == REL_STATEMENT) {
if (indexKind == ORG_STATEMENT) {
currentCodeMode = ABSOLUTE_BUFFER;
}
advanceIndexFile();
}
while (!feof(saveFileForPass2) && !feof(indexFileForPass2)) {
mifEndFlag = FALSE;
if ((int)indexKind == -1) {
advanceIndexFile();
if ((int)indexKind == -1)
currentCodeMode = ABSOLUTE_BUFFER;
else
currentCodeMode = RELOCATABLE_BUFFER;
advanceIndexFile();
sourceLineNumber = indexLineNumber;
if (nextIndexKind == ORG_STATEMENT || nextIndexKind ==
ALIGN_STATEMENT || nextIndexKind ==
REL_STATEMENT) {
if (nextIndexKind == ORG_STATEMENT) {
currentCodeMode = ABSOLUTE_BUFFER;
} else if (nextIndexKind == REL_STATEMENT) {
currentCodeMode = RELOCATABLE_BUFFER;
}
advanceIndexFile();
}
}
if (indexKind == MACRO_STATEMENT || indexKind ==
FUNCTION_STATEMENT || indexKind ==
STRUCT_STATEMENT) {
while (sourceLineNumber < indexLineNumber) {
printListingLine(0, indexAddress, sourceText,
indexKind);
advanceSourceFile();
}
} else if (!alreadyListingMacroExpansion && isBlockOpener(
indexKind)) {
while (sourceLineNumber < nextIndexLineNumber) {
printListingLine(0, indexAddress, sourceText,
indexKind);
advanceSourceFile();
}
readIndexFileLine(&nextIndexKind, &nextIndexAddress,
&nextIndexLineNumber);
}
while ((indexLineNumber == nextIndexLineNumber &&
!alreadyListingMacroExpansion &&
(int)nextIndexKind != -1 && indexKind !=
ORG_STATEMENT) || (indexKind ==
NULL_STATEMENT && nextSourceAddress == -1)) {
while (nextSourceAddress == -1) {
printListingLine(0, indexAddress, sourceText,
indexKind);
advanceSourceFile();
}
readIndexFileLine(&nextIndexKind, &nextIndexAddress,
&nextIndexLineNumber);
}
if (nextIndexLineNumber >= 0) {
targetLineNumber = alreadyListingMacroExpansion ?
callLineNumber : sourceLineNumber;
while (nextIndexLineNumber < targetLineNumber &&
!isBlockOpener(indexKind)) {
readIndexFileLine(&nextIndexKind,
&nextIndexAddress,
&nextIndexLineNumber);
}
}
while (nextIndexAddress == -1 && !feof(indexFileForPass2)) {
readIndexFileLine(&nextIndexKind, &nextIndexAddress,
&nextIndexLineNumber);
mifEndFlag = TRUE;
}
numberOfBytesToList = nextIndexAddress - indexAddress;
firstLine = TRUE;
nullMacroLine = FALSE;
while (numberOfBytesToList > 0 || nextSourceAddress == -1 ||
firstLine) {
firstLine = FALSE;
if (alreadyListingMacroExpansion) {
if (nullMacroLine) {
numberOfBytesListed = printListingLine(
numberOfBytesToList, indexAddress,
NULL, indexKind);
nullMacroLine = FALSE;
} else {
numberOfBytesListed = printMacroLine(
numberOfBytesToList, indexAddress,
indexKind);
}
} else if (!feof(indexFileForPass2)) {
numberOfBytesListed = printListingLine(
numberOfBytesToList, indexAddress,
sourceText, indexKind);
}
numberOfBytesToList -= numberOfBytesListed;
indexAddress += numberOfBytesListed;
if (nextSourceAddress == -1 || (sourceLineNumber <
indexLineNumber && indexKind ==
INSTRUCTION_STATEMENT &&
!alreadyListingMacroExpansion)) {
advanceSourceFile();
firstLine = TRUE;
} else if (!alreadyListingMacroExpansion &&
nextIndexLineNumber >= 0) {
sourceText = NULL;
} else if (alreadyListingMacroExpansion &&
numberOfBytesToList > 0) {
nullMacroLine = TRUE;
}
}
while (mifEndFlag && sourceLineNumber+1<nextIndexLineNumber
&& !alreadyListingMacroExpansion) {
advanceSourceFile();
printListingLine(0, indexAddress, sourceText,
indexKind);
}
if (nextIndexKind == ORG_STATEMENT || nextIndexKind ==
ALIGN_STATEMENT || nextIndexKind ==
REL_STATEMENT) {
if (nextIndexKind == ORG_STATEMENT) {
currentCodeMode = ABSOLUTE_BUFFER;
} else if (nextIndexKind == REL_STATEMENT) {
currentCodeMode = RELOCATABLE_BUFFER;
}
advanceIndexFile();
}
advanceIndexFile();
if (!alreadyListingMacroExpansion)
advanceSourceFile();
if (indexLineNumber < 0) {
while (nextIndexAddress == -1) {
readIndexFileLine(&nextIndexKind,
&nextIndexAddress,
&nextIndexLineNumber);
}
if ((int)indexKind == -2) {
indexKind = NULL_STATEMENT;
}
if (!alreadyListingMacroExpansion) {
callLineNumber = sourceLineNumber;
sourceLineNumber = -indexLineNumber;
alreadyListingMacroExpansion = TRUE;
}
} else if (alreadyListingMacroExpansion) {
alreadyListingMacroExpansion = FALSE;
while (abs(indexLineNumber) < callLineNumber &&
!feof(indexFileForPass2)) {
advanceIndexFile();
}
sourceLineNumber = /*isBlockOpener(indexKind) ?*/
callLineNumber /*+ 1 : indexLineNumber*/;
}
}
}
bool longLineFlag; /* defined in lexer.c */
int
printMacroLine(numberOfBytes, byteAddress, kind)
int numberOfBytes;
int byteAddress;
statementKindType kind;
{
macroAddress = nextMacroAddress;
macroDepth = nextMacroDepth;
strcpy(macroLineBuffer, nextMacroLineBuffer);
readSourceFileLine(&nextMacroAddress, &nextMacroDepth,
nextMacroLineBuffer, macroFileForPass2);
return(printListingLine(numberOfBytes, byteAddress, macroLineBuffer,
kind));
}
void
readSourceFileLine(sourceAddressPtr, sourceDepthPtr, lineBuffer, file)
int *sourceAddressPtr;
int *sourceDepthPtr;
char lineBuffer[];
FILE *file;
{
char c;
*sourceAddressPtr = getw(file);
*sourceDepthPtr = getw(file);
myfgets(lineBuffer, LINE_BUFFER_SIZE, file);
if (longLineFlag) {
while ((c = getc(file)) != '\n' && c != EOF)
;
lineBuffer[LINE_BUFFER_SIZE - 2] = '\n';
}
}
void
readIndexFileLine(statementKindPtr, indexAddressPtr, indexLineNumberPtr)
statementKindType *statementKindPtr;
int *indexAddressPtr;
int *indexLineNumberPtr;
{
statementKindType statementKindRead;
int indexAddressRead;
int indexLineNumberRead;
statementKindRead = (statementKindType) getw(indexFileForPass2);
indexAddressRead = getw(indexFileForPass2);
indexLineNumberRead = getw(indexFileForPass2) - 1;
if (!feof(indexFileForPass2)) {
*statementKindPtr = statementKindRead;
*indexAddressPtr = indexAddressRead;
*indexLineNumberPtr = indexLineNumberRead;
} else {
*indexLineNumberPtr += 1;
}
}
int
printListingLine(numberOfBytes, byteAddress, text, kind)
int numberOfBytes;
int byteAddress;
char *text;
statementKindType kind;
{
int i;
void tabPrint();
if (kind != BLOCK_STATEMENT)
numberOfBytes = (numberOfBytes < 4) ? numberOfBytes : 4;
if (numberOfBytes==0 && isBlankStatement(kind))
fprintf(listFileOutput, " ");
else
#if TARGET_CPU == CPU_6502
fprintf(listFileOutput, "%04x ", byteAddress);
#else if TARGET_CPU == CPU_68000
fprintf(listFileOutput, "%06x ", byteAddress);
#endif
if (kind != BLOCK_STATEMENT) {
#if TARGET_CPU == CPU_6502
for (i=0; i<numberOfBytes; i++)
fprintf(listFileOutput, " %02x",
getByte(byteAddress++));
for (i=numberOfBytes; i<4; i++)
fprintf(listFileOutput, " ");
} else {
fprintf(listFileOutput, " ");
#else if TARGET_CPU == CPU_68000
for (i=0; i<numberOfBytes; i++) {
fprintf(listFileOutput, "%02x",
getByte(byteAddress++));
if (i==1) fprintf(listFileOutput, " ");
}
for (i=numberOfBytes; i<4; i++) {
fprintf(listFileOutput, " ");
if (i==1) fprintf(listFileOutput, " ");
}
} else {
fprintf(listFileOutput, " ");
#endif
}
if (text == NULL) {
fprintf(listFileOutput, "\n");
} else {
fprintf(listFileOutput, " ");
tabPrint(text);
}
return(numberOfBytes);
}
bool
isBlockOpener(statementKind)
statementKindType statementKind;
{
return (statementKind==IF_STATEMENT ||
statementKind==WHILE_STATEMENT ||
statementKind==DO_WHILE_STATEMENT ||
statementKind==DO_UNTIL_STATEMENT ||
statementKind==CONSTRAIN_STATEMENT ||
/* statementKind==STRUCT_STATEMENT ||*/
statementKind==MIF_STATEMENT ||
statementKind==MFOR_STATEMENT ||
statementKind==MDO_WHILE_STATEMENT ||
statementKind==MDO_UNTIL_STATEMENT ||
statementKind==MWHILE_STATEMENT ||
statementKind==INCLUDE_STATEMENT ||
statementKind==GROUP_STATEMENT
);
}
bool
isBlankStatement(statementKind)
statementKindType statementKind;
{
return( statementKind == DEFINE_STATEMENT ||
statementKind == NULL_STATEMENT ||
statementKind == VARIABLE_STATEMENT ||
statementKind == CONSTRAIN_STATEMENT ||
statementKind == MACRO_STATEMENT ||
statementKind == FUNCTION_STATEMENT ||
statementKind == UNDEFINE_STATEMENT ||
statementKind == MDEFINE_STATEMENT ||
statementKind == MVARIABLE_STATEMENT ||
statementKind == FRETURN_STATEMENT ||
statementKind == UNDEFINE_STATEMENT ||
statementKind == EXTERN_STATEMENT ||
statementKind == START_STATEMENT ||
statementKind == INCLUDE_STATEMENT ||
statementKind == MIF_STATEMENT ||
statementKind == MFOR_STATEMENT ||
statementKind == MDO_WHILE_STATEMENT ||
statementKind == MDO_UNTIL_STATEMENT ||
statementKind == MWHILE_STATEMENT ||
statementKind == PERFORM_STATEMENT
);
}
void
tabPrint(text)
stringType *text;
{
int column;
int spaces;
column = 0;
while (*text != '\0') {
if (*text == '\t') {
for (spaces = 8 - (column % 8); spaces>0; spaces--) {
putc(' ', listFileOutput);
column++;
}
} else {
putc(*text, listFileOutput);
column++;
}
text++;
}
}
void
printNTimes(aChar, times)
char aChar;
int times;
{
void moreText();
while (times-- > 0)
moreText("%c", aChar);
}
void
tabIndent()
{
printNTimes('\t', tabCount);
}
static char expressionString[LINE_BUFFER_SIZE] = { '\0' };
static char *expressionStringPtr = expressionString;
static char expansionString[LINE_BUFFER_SIZE] = { '\0' };
static char *expansionStringPtr = expansionString;
static char labelString[LINE_BUFFER_SIZE] = { '\0' };
static char *labelStringPtr = labelString;
bool
labeledLine()
{
return(labelStringPtr != labelString);
}
void
addText(buffer, bufferPtr, format, arg1, arg2, arg3)
char *buffer;
char **bufferPtr;
char *format;
int arg1;
int arg2;
int arg3;
{
sprintf(*bufferPtr, format, arg1, arg2, arg3);
*bufferPtr = buffer + strlen(buffer);
}
void
moreTextOptional(buffer, bufferPtr, format, arg1, arg2, arg3)
char *buffer;
char **bufferPtr;
char *format;
int arg1;
int arg2;
int arg3;
{
if (buffer == NULL)
addText(expansionString, &expansionStringPtr, format, arg1,
arg2, arg3);
else
addText(buffer, bufferPtr, format, arg1, arg2, arg3);
}
void
moreText(format, arg1, arg2, arg3)
char *format;
int arg1;
int arg2;
int arg3;
{
addText(expansionString, &expansionStringPtr, format, arg1,arg2,arg3);
}
void
moreLabel(format, arg1, arg2, arg3)
char *format;
int arg1;
int arg2;
int arg3;
{
sprintf(labelStringPtr, format, arg1, arg2, arg3);
labelStringPtr = labelString + strlen(labelString);
}
static addressType savedCurrentLocationCounterValue;
static int savedIncludeNestingDepth;
void
startLine()
{
printNTimes('+', macroCallDepth);
savedCurrentLocationCounterValue = currentLocationCounter.value;
savedIncludeNestingDepth = includeNestingDepth;
}
void
endLine()
{
if (amListing()) {
putw(savedCurrentLocationCounterValue, macroFileForPass2);
putw(savedIncludeNestingDepth, macroFileForPass2);
fprintf(macroFileForPass2, "%s\n", expansionString);
}
expansionStringPtr = expansionString;
*expansionStringPtr = '\0';
}
void
flushExpressionString()
{
expressionStringPtr = expressionString;
*expressionStringPtr = '\0';
}
void
expandExpression(toBuffer, toBufferPtr)
char *toBuffer;
char **toBufferPtr;
{
if (toBuffer == NULL)
moreText("%s", expressionString);
else
addText(toBuffer, toBufferPtr, "%s", expressionString);
flushExpressionString();
}
void
expandNum(buffer, bufferPtr, n)
char *buffer;
char **bufferPtr;
int n;
{
moreTextOptional(buffer, bufferPtr, "%d", n);
}
void
flushOperand(n)
int n;
{
moreText("%s", operandBuffer[n]);
operandBuffer[n][0] = '\0';
}
void
expandOperands(op)
int op;
{
int i;
if (op > 0) {
flushOperand(0);
for (i=1; i<op; i++) {
moreText(", ");
flushOperand(i);
}
}
}
void
expandLabel()
{
moreText("%s", labelString);
labelStringPtr = labelString;
*labelStringPtr = '\0';
}
void
moreExpression(format, arg1, arg2, arg3)
char *format;
int arg1;
int arg2;
int arg3;
{
sprintf(expressionStringPtr, format, arg1, arg2, arg3);
expressionStringPtr = expressionString + strlen(expressionString);
}
void
startLineMarked()
{
startLine();
if (amListing())
saveIndexForListing(-2, cumulativeLineNumber);
}
bool
notListable(statementKind)
statementKindType statementKind;
{
return(!listableStatement(statementKind) &&
statementKind != INSTRUCTION_STATEMENT &&
(int)statementKind != -2);
}

BIN
listing.o Normal file

Binary file not shown.

521
lookups.c Normal file
View File

@ -0,0 +1,521 @@
/*
lookups.c -- Routines to lookup things in tables.
Chip Morningstar -- Lucasfilm Ltd.
5-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/*
These routines all do basically the same thing. Various kinds of keywords
and so forth are stored in hash tables. The hash buckets contain linked
lists that are sorted alphabetically.
*/
conditionType
lookupConditionCode(s, hashValue)
char *s;
int hashValue;
{
conditionTableEntryType *result;
genericTableEntryType *prehashedStringLookup();
result = (conditionTableEntryType *) prehashedStringLookup(s,
conditionTable, hashValue);
if (result != NULL)
return(result->code);
else
return(NOT_FOUND_COND);
}
int
lookupKeyword(s, hashValue)
char *s;
int hashValue;
{
keywordTableEntryType *result;
genericTableEntryType *prehashedStringLookup();
result = (keywordTableEntryType *) prehashedStringLookup(s,
keywordTable, hashValue);
if (result != NULL)
return(result->token);
else
return(0);
}
macroTableEntryType *
lookupMacroName(s, hashValue)
char *s;
int hashValue;
{
genericTableEntryType *prehashedStringLookup();
return((macroTableEntryType *) prehashedStringLookup(s, macroTable,
hashValue));
}
opcodeTableEntryType *
lookupOpcode(s, hashValue)
char *s;
int hashValue;
{
genericTableEntryType *prehashedStringLookup();
return((opcodeTableEntryType *) prehashedStringLookup(s,
opcodeTable, hashValue));
}
/* lookupOrEnterSymbol -- if there is an entry in the symbol table for the
given symbol, return that entry, otherwise create a new entry for it of
the given kind and return *that* */
symbolTableEntryType *
lookupOrEnterSymbol(s, kind)
stringType *s;
symbolUsageKindType kind;
{
symbolTableEntryType *result;
genericTableEntryType *hashStringLookup();
genericTableEntryType *hashStringEnter();
symbolTableEntryType *buildSymbolTableEntry();
if (result = (symbolTableEntryType *)hashStringLookup(s,symbolTable)){
/* result->referenceCount++;*/
return(result);
} else
return((symbolTableEntryType *)
hashStringEnter(buildSymbolTableEntry(s, kind),
symbolTable));
}
void
pushSymbol(symbol)
symbolTableEntryType *symbol;
{
symbolInContextType *newContext;
newContext = typeAlloc(symbolInContextType);
newContext->pushedContexts = symbol->context;
symbol->context = newContext;
}
void
popSymbol(symbol)
symbolTableEntryType *symbol;
{
symbolInContextType *deadContext;
deadContext = symbol->context;
if (deadContext == NULL)
botch("symbol pop underflow\n");
else {
symbol->context = deadContext->pushedContexts;
if (freeFlag) {
if (deadContext->value != NULL)
freeValue(deadContext->value);
free(deadContext);
}
}
}
macroTableEntryType *
createMacro(macroName)
stringType *macroName;
{
macroTableEntryType *result;
symbolTableEntryType *testSymbol;
genericTableEntryType *hashStringLookup();
genericTableEntryType *hashStringEnter();
macroTableEntryType *buildMacroTableEntry();
symbolTableEntryType *lookupOrEnterSymbol();
testSymbol = lookupOrEnterSymbol(macroName, MACRO_SYMBOL);
if (testSymbol->context->usage != MACRO_SYMBOL) {
error(SYMBOL_ALREADY_THERE_ERROR, symbName(testSymbol));
return(NULL);
} else if (hashStringLookup(macroName, macroTable) != NULL) {
error(SYMBOL_ALREADY_THERE_ERROR, symbName(testSymbol));
return(NULL);
} else {
result = (macroTableEntryType *)
hashStringEnter(buildMacroTableEntry(macroName),
macroTable);
result->body = NULL;
return(result);
}
}
/*
Generic table lookup utility routines
*/
genericTableEntryType *
prehashedStringLookup(s, table, hashValue)
char *s;
genericTableEntryType *table[];
int hashValue;
{
genericTableEntryType *result;
int test;
result = table[hashValue];
while (result != NULL) {
if ((test = strcmplc(s, result->string)) == 0)
break;
else if (test > 0) {
result = NULL;
break;
} else {
result = result->next;
}
}
return(result);
}
genericTableEntryType *
hashStringLookup(s, table)
char *s;
genericTableEntryType *table[];
{
return(prehashedStringLookup(s, table, hashString(s)));
}
genericTableEntryType *
hashStringEnter(entry, table)
genericTableEntryType *entry;
genericTableEntryType *table[];
{
genericTableEntryType *result;
genericTableEntryType *oldResult;
int test;
int hashValue;
hashValue = hashString(entry->string);
result = table[hashValue];
if (result == NULL) {
table[hashValue] = entry;
entry->next = NULL;
return(entry);
}
oldResult = NULL;
while (result != NULL) {
if ((test = strcmplc(entry->string, result->string)) == 0) {
botch("symbol table entry %s already there\n",
entry->string);
} else if (test > 0) {
entry->next = result;
if (oldResult == NULL)
table[hashValue] = entry;
else
oldResult->next = entry;
return(entry);
} else {
oldResult = result;
result = result->next;
}
}
if (oldResult == NULL)
table[hashValue] = entry;
else
oldResult->next = entry;
entry->next = NULL;
return(entry);
}
int
hashString(s)
char *s;
{
unsigned result;
result = 0;
while (*s != '\0')
result = (result << 1) + toLowerCase(*s++);
return(result & HASH_TABLE_MASK);
}
bool
strcmplc(s1, s2) /* string compare in lower case */
char *s1; /* heavily optimized version */
char *s2;
{
char c1;
int result;
do {
c1 = toLowerCase(*s1++);
/* if result != 0, they differ */
if (result = c1 - toLowerCase(*s2++)) {
return(result); /* c1<c2==neg, c1>c2==pos */
} else if (!c1) { /* if they're null, we're done */
return(0);
}
} while (TRUE);
}
bool
strcmplct(s1, s2) /* For tables: s2 is already lower case */
char *s1; /* heavily optimized version. */
char *s2;
{
char c1;
int result;
while (TRUE) {
c1 = toLowerCase(*s1++);
if (result = c1 - (*s2++)) { /* if result != 0, they differ */
return(result); /* c1<c2==neg, c1>c2==pos */
} else if (!c1) { /* if they're null, we're done */
return(0);
}
}
}
void
purgeSymbol(symbol)
symbolTableEntryType *symbol;
{
symbolInContextType *context;
symbolInContextType *getWorkingContext();
if ((context = getWorkingContext(symbol)) != NULL)
context->usage = DEAD_SYMBOL;
}
void
reincarnateSymbol(context, newUsage)
symbolInContextType *context;
symbolUsageKindType newUsage;
{
context->attributes = 0;
dupValue(context->value, UndefinedValue);
context->usage = newUsage;
}
/*
Routines to handle assembly-time binding of symbols to contexts.
*/
void
pushBinding(symbol, newBinding, newUsage)
symbolTableEntryType *symbol;
valueType *newBinding;
symbolUsageKindType newUsage;
{
valueType *newValue();
pushSymbol(symbol);
if (newBinding == NULL)
newBinding = newValue(FAIL, 0, EXPRESSION_OPND);
symbol->context->value = newBinding;
symbol->context->usage = newUsage;
symbol->context->environmentNumber = currentEnvironment->
environmentNumber;
symbol->context->attributes = DEFINED_VARIABLE_ATT;
}
void
popBinding(symbol)
symbolTableEntryType *symbol;
{
popSymbol(symbol);
}
int /* returns number of bindings completed, negative this if failure */
bindMacroArguments(argumentList, parameterList, macroName)
argumentDefinitionListType *argumentList;
operandListType *parameterList;
stringType *macroName;
{
int numberBound;
bool arrayTag;
int arrayLength;
valueType **arrayContents;
int i;
valueType *newValue();
if (argumentList == NULL)
arrayTag = FALSE;
else
arrayTag = ((argumentListHeadType *)argumentList)->arrayTag;
numberBound = 1;
while (argumentList!=NULL && (!arrayTag || argumentList->
nextArgument!=NULL) && parameterList!=NULL) {
pushBinding(argumentList->theArgument, newValue(OPERAND_VALUE,
parameterList, EXPRESSION_OPND), ARGUMENT_SYMBOL);
argumentList = argumentList->nextArgument;
parameterList = parameterList->nextOperand;
numberBound++;
}
if (!arrayTag) {
if (parameterList != NULL) {
error(TOO_MANY_ARGUMENTS_TO_MACRO_ERROR, macroName,
numberBound-1);
return(-numberBound);
}
while (argumentList != NULL) {
pushBinding(argumentList->theArgument, newValue(FAIL,
0, EXPRESSION_OPND), ARGUMENT_SYMBOL);
argumentList = argumentList->nextArgument;
numberBound++;
}
} else {
if (parameterList == NULL) {
while (argumentList->nextArgument != NULL) {
pushBinding(argumentList->theArgument,
newValue(FAIL, 0, EXPRESSION_OPND),
ARGUMENT_SYMBOL);
argumentList = argumentList->nextArgument;
numberBound++;
}
}
arrayLength = countParameters(parameterList);
pushBinding(argumentList->theArgument, newValue(ARRAY_VALUE,
allocArray(arrayLength, &arrayContents),
EXPRESSION_OPND), ARGUMENT_SYMBOL);
for (i=0; i<arrayLength; ++i) {
arrayContents[i] = newValue(OPERAND_VALUE,
parameterList, EXPRESSION_OPND);
parameterList = parameterList->nextOperand;
}
numberBound++;
}
return(numberBound);
}
int /* returns number of bindings completed, negative this if failure */
bindFunctionArguments(argumentList, parameterList, functionName)
argumentDefinitionListType *argumentList;
operandListType *parameterList;
stringType *functionName;
{
valueType *argument;
bool arrayTag;
int arrayLength;
valueType **arrayContents;
int i;
int numberBound;
valueType *firstArgument;
environmentType *saveEnvironment;
valueType *evaluateOperand();
valueType *newValue();
if (argumentList == NULL)
arrayTag = FALSE;
else
arrayTag = ((argumentListHeadType *)argumentList)->arrayTag;
numberBound = 1;
firstArgument = NULL;
while (argumentList!=NULL && (!arrayTag || argumentList->
nextArgument!=NULL) && parameterList!=NULL) {
saveEnvironment = currentEnvironment;
currentEnvironment = currentEnvironment->previousEnvironment;
argument = evaluateOperand(parameterList, NO_FIXUP);
currentEnvironment = saveEnvironment;
if (firstArgument == NULL)
firstArgument = argument;
if (isUsable(argument)) {
pushBinding(argumentList->theArgument, argument,
ARGUMENT_SYMBOL);
argumentList = argumentList->nextArgument;
parameterList = parameterList->nextOperand;
expand((argumentList!=NULL && parameterList!=NULL) ?
moreExpression(", ") : 0);
numberBound++;
} else {
if (isUndefined(argument))
resultOfLastFunctionCall =
newValue(UNDEFINED_VALUE, 0,
firstArgument->addressMode);
return(-numberBound);
}
}
if (!arrayTag) {
if (parameterList != NULL) {
error(TOO_MANY_ARGUMENTS_TO_FUNCTION_ERROR,
functionName, numberBound - 1);
return(-numberBound);
}
while (argumentList != NULL) {
pushBinding(argumentList->theArgument, newValue(FAIL,
0, EXPRESSION_OPND), ARGUMENT_SYMBOL);
argumentList = argumentList->nextArgument;
numberBound++;
}
} else {
if (parameterList == NULL) {
while (argumentList->nextArgument != NULL) {
pushBinding(argumentList->theArgument,
newValue(FAIL, 0, EXPRESSION_OPND),
ARGUMENT_SYMBOL);
argumentList = argumentList->nextArgument;
numberBound++;
}
}
arrayLength = countParameters(parameterList);
pushBinding(argumentList->theArgument, newValue(ARRAY_VALUE,
allocArray(arrayLength, &arrayContents),
EXPRESSION_OPND), ARGUMENT_SYMBOL);
numberBound++;
for (i=0; i<arrayLength; ++i) {
saveEnvironment = currentEnvironment;
currentEnvironment = currentEnvironment->
previousEnvironment;
argument = evaluateOperand(parameterList, NO_FIXUP);
currentEnvironment = saveEnvironment;
if (firstArgument == NULL)
firstArgument = argument;
if (isUsable(argument)) {
arrayContents[i] = argument;
parameterList = parameterList->nextOperand;
} else {
if (isUndefined(argument))
resultOfLastFunctionCall =
newValue(UNDEFINED_VALUE, 0,
firstArgument->addressMode);
return(-numberBound);
}
}
}
return(numberBound);
}
void
unbindArguments(argumentList, numberToUnbind)
argumentDefinitionListType *argumentList;
int numberToUnbind;
{
while (argumentList != NULL && numberToUnbind-- > 0) {
popBinding(argumentList->theArgument);
argumentList = argumentList->nextArgument;
}
if (numberToUnbind > 0)
botch("binding count larger than number of bindings\n");
}
void
unbindLocalVariables(identifierList)
identifierListType *identifierList;
{
identifierListType *deadEntry;
while (identifierList != NULL) {
popBinding(identifierList->theSymbol);
deadEntry = identifierList;
identifierList = identifierList->nextIdentifier;
qfree(deadEntry);
}
}

BIN
lookups.o Normal file

Binary file not shown.

BIN
macross Executable file

Binary file not shown.

151
macrossGlobals.h Normal file
View File

@ -0,0 +1,151 @@
/*
macrossGlobals.h -- Global variable definitions for the Macross
assembler.
Chip Morningstar -- Lucasfilm Ltd.
1-November-1984
*/
bool backwardsCompatibleIfFlag;
bool beneathFunction;
commandLineDefineType *commandLineDefines;
int cumulativeLineNumber;
environmentType *currentEnvironment;
int currentFieldOffset;
char *currentFileName;
char *lastErrorFile;
stringType *currentFunctionName;
int currentLabelTagNumber;
int currentLineNumber;
int lastErrorLine;
identifierListType *currentLocalVariableList;
valueType currentLocationCounter;
int currentOperandNumber;
int currentReferenceDepth;
bool debug;
bool emitPrint;
bool expandMacros;
bool errorFlag;
bool expressionFailed;
bool finishOperand;
operandKindType fixupAddressMode[MAX_NUMBER_OF_OPERANDS];
operandKindType newFixupAddressMode;
fixupListType *fixupList;
bool freeFlag;
bool freturnExit;
bool generatingFixup;
environmentType globalEnvironment;
int hackFlag;
bool haveUserStartAddress;
bool fixupStartAddress;
int includeNestingDepth;
FILE *indexFileForPass2;
FILE *input;
fileNameListType *inputFileStack;
FILE *listFileOutput;
int listingControlCounter;
bool listingOn;
int macroCallDepth;
FILE *macroFileForPass2;
int macroOrFunctionNestingDepth;
structInstanceType *newStruct;
int nextEnvironmentNumber;
int nextLabelTagNumber;
FILE *objectFileOutput;
char operandBuffer[MAX_NUMBER_OF_OPERANDS][LINE_BUFFER_SIZE];
char pass2IndexFileName[];
char pass2SourceFileName[];
char pass2MacroExpansionFileName[];
expressionType *pendingFixup[MAX_NUMBER_OF_OPERANDS];
bool performingFixups;
bool positionIndependentCodeMode;
bool produceLinkableObject;
addressType relocatableHighWaterMark;
reservationListType *reservationList;
valueType *resultOfLastFunctionCall;
valueType savedRelocatableCurrentLocationCounter;
FILE *saveFileForPass2;
bool showAllSymbolsFlag;
bool sideEffectFlag;
bool standaloneExpansionFlag;
valueType *startAddress;
int statementEvaluationDepth;
int statementListNestingDepth;
int structNestingDepth;
FILE *symbolDumpFileOutput;
bool symbolTableDumpOn;
int tabCount;
addressType targetOffset;
bool terseErrorMessages;
valueType *UndefinedValue;
symbolUsageKindType unknownSymbolTag;
#define DEFAULT_OBJECT_FILE_NAME "m.out"
#define LEX_DISPATCH_TABLE_SIZE 128
int (*lexDispatchTable[128])();
#define HASH_TABLE_SIZE 512
#define HASH_TABLE_MASK 0x1FF
struct {
stringType *functionName;
valueType *(*functionEntry)();
bool isSpecialFunction;
int ordinal;
} builtInFunctionTable[];
struct {
stringType *symbolName;
int symbolValue;
} predefinedSymbolTable[];
macroTableEntryType *macroTable[HASH_TABLE_SIZE];
opcodeTableEntryType *opcodeTable[HASH_TABLE_SIZE];
opcodeTableEntryType theOpcodes[];
keywordTableEntryType *keywordTable[HASH_TABLE_SIZE];
keywordTableEntryType theKeywords[];
conditionTableEntryType *conditionTable[HASH_TABLE_SIZE];
conditionTableEntryType theConditions[];
symbolTableEntryType *symbolTable[HASH_TABLE_SIZE];
int operandClassTable[];
void (*instructionActionTable[])();
int validSymbolValues[NUM_OF_SYM_USAGES];
byte structScratchBuffer[MAXIMUM_ALLOWED_STRUCT_SIZE];
codeRegionType absoluteCodeRegion;
codeRegionType relocatableCodeRegion;
codeRegionType *codeRegions[2];
codeBufferKindType currentCodeMode;
codeBufferType *emptyBuffer; /* ??? */
codeBreakType *codeBreakList;
codeBreakType *lastCodeBreak;
expressionReferenceListType *expressionReferenceList[3];
expressionReferenceListType *referencesToNote[MAX_NUMBER_OF_OPERANDS];
int numberOfReferencesInList[3];
functionDefinitionType *externalFunctionList;
functionDefinitionType *endOfExternalFunctionList;
int externalFunctionCount;
char alphabeticCharacterTable[128];
char alphaNumericCharacterTable[128];
char lowerCaseCharacterTable[128];
char numericCharacterTable[128];
int expressionBufferSize;
#define EXPRESSION_BUFFER_LIMIT 500
byte expressionBuffer[EXPRESSION_BUFFER_LIMIT];

BIN
macrossTables.o Normal file

Binary file not shown.

405
macrossTables_6502.c Normal file
View File

@ -0,0 +1,405 @@
/*
macrossTables.c -- Define the contents of various tables and values
of various initialized global variables.
Chip Morningstar -- Lucasfilm Ltd.
5-November-1984
*/
#include "macrossTypes.h"
#include "y.tab.h"
/* All those NULLs are used to string together lists after this all gets
hashed */
conditionTableEntryType theConditions[] = {
"always", NULL, ALWAYS_COND,
"carry", NULL, CARRY_COND,
"equal", NULL, ZERO_COND,
"geq", NULL, GEQ_COND,
"greater", NULL, GT_COND,
"gt", NULL, GT_COND,
"leq", NULL, LEQ_COND,
"less", NULL, LT_COND,
"lt", NULL, LT_COND,
"minus", NULL, NEGATIVE_COND,
"negative", NULL, NEGATIVE_COND,
"neq", NULL, NOT_ZERO_COND,
"never", NULL, NEVER_COND,
"not_carry", NULL, NOT_CARRY_COND, /* for dragon */
"not_equal", NULL, NOT_ZERO_COND, /* for dragon */
"not_overflow", NULL, NOT_OVERFLOW_COND, /* for dragon */
"not_zero", NULL, NOT_ZERO_COND, /* for dragon */
"overflow", NULL, OVERFLOW_COND,
"plus", NULL, NOT_NEGATIVE_COND,
"positive", NULL, NOT_NEGATIVE_COND,
"sgeq", NULL, SGEQ_COND,
"sgt", NULL, SGT_COND,
"sleq", NULL, SLEQ_COND,
"slt", NULL, SLT_COND,
"sneq", NULL, NOT_ZERO_COND,
"zero", NULL, ZERO_COND,
NULL, NULL, NEVER_COND,
};
/* All those NULLs are used to string together lists after this all gets
hashed */
keywordTableEntryType theKeywords[] = {
"a", NULL, A,
"align", NULL, ALIGN,
"assert", NULL, ASSERT,
"block", NULL, BLOCK,
"byte", NULL, BYTE,
"constrain", NULL, CONSTRAIN,
"dbyte", NULL, DBYTE,
"define", NULL, DEFINE,
"do", NULL, DO,
"else", NULL, ELSE,
"elseif", NULL, ELSEIF,
"extern", NULL, EXTERN,
"freturn", NULL, FRETURN,
"function", NULL, FUNCTION,
"here", NULL, HERE,
"if", NULL, IF,
"include", NULL, INCLUDE,
"long", NULL, LONG,
"macro", NULL, MACRO,
"mcase", NULL, MCASE,
"mdefault", NULL, MDEFAULT,
"mdefine", NULL, MDEFINE,
"mdo", NULL, MDO,
"melse", NULL, MELSE,
"melseif", NULL, MELSEIF,
"mfor", NULL, MFOR,
"mif", NULL, MIF,
"mswitch", NULL, MSWITCH,
"muntil", NULL, MUNTIL,
"mvariable", NULL, MVARIABLE,
"mwhile", NULL, MWHILE,
"org", NULL, ORG,
"rel", NULL, REL,
"start", NULL, START,
"string", NULL, STRING,
"struct", NULL, STRUCT,
"target", NULL, TARGET,
"undefine", NULL, UNDEFINE,
"until", NULL, UNTIL,
"variable", NULL, VARIABLE,
"while", NULL, WHILE,
"word", NULL, WORD,
"x", NULL, X,
"y", NULL, Y,
NULL, NULL, 0,
};
#define HASH_TABLE_SIZE 509
macroTableEntryType *macroTable[HASH_TABLE_SIZE];
opcodeTableEntryType *opcodeTable[HASH_TABLE_SIZE];
symbolTableEntryType *symbolTable[HASH_TABLE_SIZE];
keywordTableEntryType *keywordTable[HASH_TABLE_SIZE];
conditionTableEntryType *conditionTable[HASH_TABLE_SIZE];
/* All those NULLs are used to string together lists after this all gets
hashed. */
opcodeTableEntryType theOpcodes[] = {
"adc", NULL, 0x61, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"and", NULL, 0x21, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"asl", NULL, 0x02, DIR_X_1, DIR_X_1_CLASS_BITS, 1, 1, 0,
"bcc", NULL, 0x90, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"bcs", NULL, 0xB0, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"beq", NULL, 0xF0, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"bit", NULL, 0x24, DIR_1, DIR_1_CLASS_BITS, 1, 1, 0,
"bmi", NULL, 0x30, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"bne", NULL, 0xD0, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"bpl", NULL, 0x10, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"brk", NULL, 0x00, NONE, NONE_CLASS_BITS, 0, 0, 0,
"bvc", NULL, 0x50, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"bvs", NULL, 0x70, RELATIVE, REL_CLASS_BITS, 1, 1, 0,
"clc", NULL, 0x18, NONE, NONE_CLASS_BITS, 0, 0, 0,
"cld", NULL, 0xD8, NONE, NONE_CLASS_BITS, 0, 0, 0,
"cli", NULL, 0x58, NONE, NONE_CLASS_BITS, 0, 0, 0,
"clv", NULL, 0xB8, NONE, NONE_CLASS_BITS, 0, 0, 0,
"cmp", NULL, 0xC1, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"cpx", NULL, 0xE0, IMM_DIR, IMM_DIR_CLASS_BITS, 1, 1, 0,
"cpy", NULL, 0xC0, IMM_DIR, IMM_DIR_CLASS_BITS, 1, 1, 0,
"dec", NULL, 0xC6, DIR_X_2, DIR_X_2_CLASS_BITS, 1, 1, 0,
"dex", NULL, 0xCA, NONE, NONE_CLASS_BITS, 0, 0, 0,
"dey", NULL, 0x88, NONE, NONE_CLASS_BITS, 0, 0, 0,
"eor", NULL, 0x41, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"inc", NULL, 0xE6, DIR_X_2, DIR_X_2_CLASS_BITS, 1, 1, 0,
"inx", NULL, 0xE8, NONE, NONE_CLASS_BITS, 0, 0, 0,
"iny", NULL, 0xC8, NONE, NONE_CLASS_BITS, 0, 0, 0,
"jmp", NULL, 0x4C, DIR_INDIR, DIR_INDIR_CLASS_BITS, 1, 1, 0,
"jsr", NULL, 0x20, DIR_2, DIR_2_CLASS_BITS, 1, 1, 0,
"lda", NULL, 0xA1, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"ldx", NULL, 0xA2, IMM_DIR_Y, IMM_DIR_Y_CLASS_BITS, 1, 1, 0,
"ldy", NULL, 0xA0, IMM_DIR_X, IMM_DIR_X_CLASS_BITS, 1, 1, 0,
"lsr", NULL, 0x42, DIR_X_1, DIR_X_1_CLASS_BITS, 1, 1, 0,
"nop", NULL, 0xEA, NONE, NONE_CLASS_BITS, 0, 0, 0,
"ora", NULL, 0x01, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"pha", NULL, 0x48, NONE, NONE_CLASS_BITS, 0, 0, 0,
"php", NULL, 0x08, NONE, NONE_CLASS_BITS, 0, 0, 0,
"pla", NULL, 0x68, NONE, NONE_CLASS_BITS, 0, 0, 0,
"plp", NULL, 0x28, NONE, NONE_CLASS_BITS, 0, 0, 0,
"rol", NULL, 0x22, DIR_X_1, DIR_X_1_CLASS_BITS, 1, 1, 0,
"ror", NULL, 0x62, DIR_X_1, DIR_X_1_CLASS_BITS, 1, 1, 0,
"rti", NULL, 0x40, NONE, NONE_CLASS_BITS, 0, 0, 0,
"rts", NULL, 0x60, NONE, NONE_CLASS_BITS, 0, 0, 0,
"sbc", NULL, 0xE1, IMM_INDEX, IMM_INDEX_CLASS_BITS, 1, 1, 0,
"sec", NULL, 0x38, NONE, NONE_CLASS_BITS, 0, 0, 0,
"sed", NULL, 0xF8, NONE, NONE_CLASS_BITS, 0, 0, 0,
"sei", NULL, 0x78, NONE, NONE_CLASS_BITS, 0, 0, 0,
"sta", NULL, 0x81, INDEX, INDEX_CLASS_BITS, 1, 1, 0,
"stx", NULL, 0x86, DIR_Y, DIR_Y_CLASS_BITS, 1, 1, 0,
"sty", NULL, 0x84, DIR_X_3, DIR_X_3_CLASS_BITS, 1, 1, 0,
"tax", NULL, 0xAA, NONE, NONE_CLASS_BITS, 0, 0, 0,
"tay", NULL, 0xA8, NONE, NONE_CLASS_BITS, 0, 0, 0,
"tsx", NULL, 0xBA, NONE, NONE_CLASS_BITS, 0, 0, 0,
"txa", NULL, 0x8A, NONE, NONE_CLASS_BITS, 0, 0, 0,
"txs", NULL, 0x9A, NONE, NONE_CLASS_BITS, 0, 0, 0,
"tya", NULL, 0x98, NONE, NONE_CLASS_BITS, 0, 0, 0,
NULL, NULL, 0x00, NONE, NONE_CLASS_BITS, 0, 0, 0,
};
int operandClassTable[] = { /* indexed by operandKindType */
EXPRESSION_OPND_BIT,
IMMEDIATE_OPND_BIT,
INDIRECT_OPND_BIT,
A_REGISTER_OPND_BIT,
X_REGISTER_OPND_BIT,
Y_REGISTER_OPND_BIT,
POST_INDEXED_Y_OPND_BIT,
PRE_INDEXED_X_OPND_BIT,
X_INDEXED_OPND_BIT,
Y_INDEXED_OPND_BIT,
X_SELECTED_OPND_BIT,
Y_SELECTED_OPND_BIT,
PRE_SELECTED_X_OPND_BIT,
STRING_OPND_BIT,
BLOCK_OPND_BIT,
};
int actionsRelative();
int actionsDir1();
int actionsDir2();
int actionsDirIndir();
int actionsDirX1();
int actionsDirX2();
int actionsDirX3();
int actionsDirY();
int actionsImmDir();
int actionsImmDirX();
int actionsImmDirY();
int actionsNone();
int actionsIndex();
int actionsImmIndex();
/* indexed by opcodeClass */
int (*instructionActionTable[])() = {
actionsRelative,
actionsDir1,
actionsDir2,
actionsDirIndir,
actionsDirX1,
actionsDirX2,
actionsDirX3,
actionsDirY,
actionsImmDir,
actionsImmDirX,
actionsImmDirY,
actionsNone,
actionsIndex,
actionsImmIndex,
};
/* indexed by symbolUsageKindType */
int validSymbolValues[NUM_OF_SYM_USAGES] = {
/* STRUCT_NAME_SYMBOL */ STRUCT_VALUE_BIT,
/* STRUCT_FIELD_SYMBOL */ FIELD_VALUE_BIT,
/* MACRO_SYMBOL */ MACRO_VALUE_BIT,
/* ARGUMENT_SYMBOL */ OPERAND_VALUE_BIT,
/* LABEL_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT,
/* EXTERNAL_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT |
UNDEFINED_VALUE_BIT,
/* VARIABLE_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT |
UNDEFINED_VALUE_BIT |
STRING_VALUE_BIT | OPERAND_VALUE_BIT |
CONDITION_VALUE_BIT,
/* MVARIABLE_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT |
UNDEFINED_VALUE_BIT |
STRING_VALUE_BIT | OPERAND_VALUE_BIT |
CONDITION_VALUE_BIT,
/* UNKNOWN_SYMBOL */ UNDEFINED_VALUE_BIT,
/* FUNCTION_SYMBOL */ FUNCTION_VALUE_BIT,
/* BUILT_IN_FUNCTION_SYMBOL */ BUILT_IN_FUNCTION_VALUE_BIT,
/* NESTED_UNKNOWN_SYMBOL */ UNDEFINED_VALUE_BIT,
/* DEFINE_SYMBOL */ OPERAND_VALUE_BIT,
/* MDEFINE_SYMBOL */ OPERAND_VALUE_BIT,
/* UNKNOWN_FUNCTION_SYMBOL */ UNDEFINED_VALUE_BIT,
/* UNKNOWN_MACRO_SYMBOL */ UNDEFINED_VALUE_BIT,
};
/* indexed by valueKindType */
int valueBitTable[] = {
ABSOLUTE_VALUE_BIT,
DATA_VALUE_BIT,
RELOCATABLE_VALUE_BIT,
BSS_VALUE_BIT,
STRUCT_VALUE_BIT,
FIELD_VALUE_BIT,
MACRO_VALUE_BIT,
OPERAND_VALUE_BIT,
STRING_VALUE_BIT,
CONDITION_VALUE_BIT,
UNDEFINED_VALUE_BIT,
FUNCTION_VALUE_BIT,
BLOCK_VALUE_BIT,
BUILT_IN_FUNCTION_VALUE_BIT,
ARRAY_VALUE_BIT,
FAIL_BIT,
};
codeRegionType absoluteCodeRegion;
codeRegionType relocatableCodeRegion;
codeRegionType *codeRegions[2] = {
&absoluteCodeRegion,
&relocatableCodeRegion
};
/* A predefined undefined value so we don't have to make a new one every
time we need one */
valueType undefinedValueValue = { UNDEFINED_VALUE, 0,
EXPRESSION_OPND };
valueType *UndefinedValue = &undefinedValueValue;
valueType *addressModeBIF();
valueType *applyBIF();
valueType *arrayLengthBIF();
valueType *atasciiBIF();
valueType *atasciiColorBIF();
valueType *debugModeOffBIF();
valueType *debugModeOnBIF();
valueType *emitModeOffBIF();
valueType *emitModeOnBIF();
valueType *isAbsoluteValueBIF();
valueType *isARegisterBIF();
valueType *isBlockBIF();
valueType *isBuiltInFunctionBIF();
valueType *isConditionCodeBIF();
valueType *isDefinedBIF();
valueType *isDirectModeBIF();
valueType *isExternalBIF();
valueType *isFieldBIF();
valueType *isFunctionBIF();
valueType *isImmediateModeBIF();
valueType *isIndexedModeBIF();
valueType *isIndirectModeBIF();
valueType *isPostIndexedModeBIF();
valueType *isPreIndexedModeBIF();
valueType *isRelocatableValueBIF();
valueType *isStringBIF();
valueType *isStructBIF();
valueType *isSymbolBIF();
valueType *isXIndexedModeBIF();
valueType *isXRegisterBIF();
valueType *isYIndexedModeBIF();
valueType *isYRegisterBIF();
valueType *listingOffBIF();
valueType *listingOnBIF();
valueType *makeArrayBIF();
valueType *nthCharBIF();
valueType *printfBIF();
valueType *strcatBIF();
valueType *strcmpBIF();
valueType *strcmplcBIF();
valueType *strlenBIF();
valueType *substrBIF();
valueType *symbolDefineBIF();
valueType *symbolLookupBIF();
valueType *symbolNameBIF();
valueType *symbolUsageBIF();
valueType *valueTypeBIF();
/* Used to initialize symbols representing built-in functions */
struct {
stringType *functionName;
valueType *(*functionEntry)();
bool isSpecialFunction;
int ordinal;
} builtInFunctionTable[] = {
"addressMode", addressModeBIF, FALSE, -1,
"apply", applyBIF, FALSE, -1,
"arrayLength", arrayLengthBIF, FALSE, -1,
"atascii", atasciiBIF, FALSE, 0,
"atasciiColor", atasciiColorBIF, FALSE, 1,
"debugModeOff", debugModeOffBIF, FALSE, -1,
"debugModeOn", debugModeOnBIF, FALSE, -1,
"emitModeOff", emitModeOffBIF, FALSE, -1,
"emitModeOn", emitModeOnBIF, FALSE, -1,
"isAbsoluteValue", isAbsoluteValueBIF, FALSE, 2,
"isARegister", isARegisterBIF, FALSE, -1,
"isBlock", isBlockBIF, FALSE, -1,
"isBuiltInFunction", isBuiltInFunctionBIF, FALSE, -1,
"isConditionCode", isConditionCodeBIF, FALSE, 3,
"isDefined", isDefinedBIF, TRUE, 4,
"isDirectMode", isDirectModeBIF, FALSE, -1,
"isExternal", isExternalBIF, TRUE, 5,
"isField", isFieldBIF, FALSE, -1,
"isFunction", isFunctionBIF, FALSE, -1,
"isImmediateMode", isImmediateModeBIF, FALSE, -1,
"isIndexedMode", isIndexedModeBIF, FALSE, -1,
"isIndirectMode", isIndirectModeBIF, FALSE, -1,
"isPostIndexedMode", isPostIndexedModeBIF, FALSE, -1,
"isPreIndexedMode", isPreIndexedModeBIF, FALSE, -1,
"isRelocatableValue", isRelocatableValueBIF, FALSE, -1,
"isString", isStringBIF, FALSE, -1,
"isStruct", isStructBIF, FALSE, -1,
"isSymbol", isSymbolBIF, TRUE, -1,
"isXIndexedMode", isXIndexedModeBIF, FALSE, -1,
"isXRegister", isXRegisterBIF, FALSE, -1,
"isYIndexedMode", isYIndexedModeBIF, FALSE, -1,
"isYRegister", isYRegisterBIF, FALSE, -1,
"listingOff", listingOffBIF, FALSE, -1,
"listingOn", listingOnBIF, FALSE, -1,
"makeArray", makeArrayBIF, FALSE, -1,
"nthChar", nthCharBIF, FALSE, 6,
"printf", printfBIF, FALSE, 7,
"strcat", strcatBIF, FALSE, 8,
"strcmp", strcmpBIF, FALSE, 9,
"strcmplc", strcmplcBIF, FALSE, 10,
"strlen", strlenBIF, FALSE, 11,
"substr", substrBIF, FALSE, 12,
"symbolDefine", symbolDefineBIF, FALSE, -1,
"symbolLookup", symbolLookupBIF, FALSE, 13,
"symbolName", symbolNameBIF, TRUE, 14,
"symbolUsage", symbolUsageBIF, TRUE, -1,
"valueType", valueTypeBIF, FALSE, -1,
NULL, NULL, FALSE, -1,
};
/* Used to initialize predefined symbols */
struct {
stringType *symbolName;
int symbolValue;
} predefinedSymbolTable[] = {
"FALSE", 0,
"NULL", 0,
"TRUE", 1,
NULL, 0,
};
/* These define the temporary files used to hold scratch data used in the
generation of listings. The "XXXXXX"s get blasted by 'mktemp' */
char pass2SourceFileName[] = "/tmp/zsourceXXXXXX";
char pass2IndexFileName[] = "/tmp/zindexXXXXXX";
char pass2MacroExpansionFileName[] = "/tmp/zmacroXXXXXX";

608
macrossTables_68000.c Normal file
View File

@ -0,0 +1,608 @@
/*
macrossTables.c -- Define the contents of various tables and values
of various initialized global variables.
Chip Morningstar -- Lucasfilm Ltd.
5-November-1984
*/
#include "macrossTypes.h"
#include "y.tab.h"
/* All those NULLs are used to string together lists after this all gets
hashed */
conditionTableEntryType theConditions[] = {
"always", NULL, ALWAYS_COND,
"carry", NULL, CARRY_COND,
"equal", NULL, EQUAL_COND,
"geq", NULL, GEQ_COND,
"greater", NULL, GT_COND,
"gt", NULL, GT_COND,
"high", NULL, HIGH_COND,
"high_same", NULL, NOT_CARRY_COND,
"hs", NULL, NOT_CARRY_COND,
"less", NULL, LT_COND,
"leq", NULL, LEQ_COND,
"low", NULL, CARRY_COND,
"low_same", NULL, LOW_OR_SAME_COND,
"ls", NULL, LOW_OR_SAME_COND,
"lt", NULL, LT_COND,
"minus", NULL, MINUS_COND,
"negative", NULL, MINUS_COND,
"neq", NULL, NOT_EQUAL_COND,
"never", NULL, NEVER_COND,
"not_carry", NULL, NOT_CARRY_COND, /* for dragon */
"not_equal", NULL, NOT_EQUAL_COND, /* for dragon */
"not_overflow", NULL, NOT_OVERFLOW_COND, /* for dragon */
"not_zero", NULL, NOT_EQUAL_COND, /* for dragon */
"overflow", NULL, OVERFLOW_COND,
"plus", NULL, PLUS_COND,
"positive", NULL, PLUS_COND,
"zero", NULL, EQUAL_COND,
NULL, NULL, NEVER_COND,
};
/* All those NULLs are used to string together lists after this all gets
hashed */
keywordTableEntryType theKeywords[] = {
"a0", NULL, A0,
"a1", NULL, A1,
"a2", NULL, A2,
"a3", NULL, A3,
"a4", NULL, A4,
"a5", NULL, A5,
"a6", NULL, A6,
"a7", NULL, A7,
"align", NULL, ALIGN,
"assert", NULL, ASSERT,
"block", NULL, BLOCK,
"byte", NULL, BYTE,
"cc", NULL, CCR,
"ccr", NULL, CCR,
"constrain", NULL, CONSTRAIN,
"d0", NULL, D0,
"d1", NULL, D1,
"d2", NULL, D2,
"d3", NULL, D3,
"d4", NULL, D4,
"d5", NULL, D5,
"d6", NULL, D6,
"d7", NULL, D7,
"dbyte", NULL, DBYTE,
"define", NULL, DEFINE,
"dfc", NULL, DFC,
"do", NULL, DO,
"else", NULL, ELSE,
"elseif", NULL, ELSEIF,
"extern", NULL, EXTERN,
"freturn", NULL, FRETURN,
"function", NULL, FUNCTION,
"here", NULL, HERE,
"if", NULL, IF,
"include", NULL, INCLUDE,
"l", NULL, L,
"long", NULL, LONG,
"macro", NULL, MACRO,
"mcase", NULL, MCASE,
"mdefault", NULL, MDEFAULT,
"mdefine", NULL, MDEFINE,
"mdo", NULL, MDO,
"melse", NULL, MELSE,
"melseif", NULL, MELSEIF,
"mfor", NULL, MFOR,
"mif", NULL, MIF,
"mswitch", NULL, MSWITCH,
"muntil", NULL, MUNTIL,
"mvariable", NULL, MVARIABLE,
"mwhile", NULL, MWHILE,
"org", NULL, ORG,
"pc", NULL, PC,
"rel", NULL, REL,
"sfc", NULL, SFC,
"sr", NULL, SR,
"start", NULL, START,
"string", NULL, STRING,
"struct", NULL, STRUCT,
"target", NULL, TARGET,
"undefine", NULL, UNDEFINE,
"until", NULL, UNTIL,
"usp", NULL, USP,
"variable", NULL, VARIABLE,
"vbr", NULL, VBR,
"w", NULL, W,
"while", NULL, WHILE,
"word", NULL, WORD,
NULL, NULL, 0,
};
#define HASH_TABLE_SIZE 509
macroTableEntryType *macroTable[HASH_TABLE_SIZE];
opcodeTableEntryType *opcodeTable[HASH_TABLE_SIZE];
symbolTableEntryType *symbolTable[HASH_TABLE_SIZE];
keywordTableEntryType *keywordTable[HASH_TABLE_SIZE];
conditionTableEntryType *conditionTable[HASH_TABLE_SIZE];
/* All those NULLs are used to string together lists after this all gets
hashed. */
opcodeTableEntryType theOpcodes[] = {
/* mnemonic, next, opcode, class, allowed modes, min#operands, max#operands,
subclass/alternate opcode */
"abcd", NULL, 0xC100, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"addb", NULL, 0xD000, CLASS_II, CLASS_II_BITS, 2, 2, 0x0600,
"addl", NULL, 0xD080, CLASS_II, CLASS_II_BITS, 2, 2, 0x0680,
"addqb",NULL, 0x5000, CLASS_III, CLASS_III_BITS, 2, 2, 0,
"addql",NULL, 0x5080, CLASS_III, CLASS_III_BITS, 2, 2, 0,
"addqw",NULL, 0x5040, CLASS_III, CLASS_III_BITS, 2, 2, 0,
"addw", NULL, 0xD040, CLASS_II, CLASS_II_BITS, 2, 2, 0x0640,
"addxb",NULL, 0xD100, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"addxl",NULL, 0xD180, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"addxw",NULL, 0xD140, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"andb", NULL, 0xC000, CLASS_IV, CLASS_IV_BITS, 2, 2, 0x0200,
"andl", NULL, 0xC080, CLASS_IV, CLASS_IV_BITS, 2, 2, 0x0280,
"andw", NULL, 0xC040, CLASS_IV, CLASS_IV_BITS, 2, 2, 0x0240,
"aslb", NULL, 0xE100, CLASS_V, CLASS_V_BITS, 1, 2, 00,
"asll", NULL, 0xE180, CLASS_V, CLASS_V_BITS, 1, 2, 00,
"aslw", NULL, 0xE140, CLASS_V, CLASS_V_BITS, 1, 2, 00,
"asrb", NULL, 0xE000, CLASS_V, CLASS_V_BITS, 1, 2, 00,
"asrl", NULL, 0xE080, CLASS_V, CLASS_V_BITS, 1, 2, 00,
"asrw", NULL, 0xE040, CLASS_V, CLASS_V_BITS, 1, 2, 00,
"bcc", NULL, 0x64, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bchg", NULL, 0x0040, CLASS_VII, CLASS_VII_BITS, 2, 2, 0,
"bclr", NULL, 0x0080, CLASS_VII, CLASS_VII_BITS, 2, 2, 0,
"bcs", NULL, 0x65, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"beq", NULL, 0x67, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bge", NULL, 0x6C, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bgt", NULL, 0x6E, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bhi", NULL, 0x62, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"ble", NULL, 0x6F, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bls", NULL, 0x63, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"blt", NULL, 0x6D, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bmi", NULL, 0x6B, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bne", NULL, 0x66, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bpl", NULL, 0x6A, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bra", NULL, 0x60, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bset", NULL, 0x00C0, CLASS_VII, CLASS_VII_BITS, 2, 2, 0,
"bsr", NULL, 0x61, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"btst", NULL, 0x0000, CLASS_VII, CLASS_VII_BITS, 2, 2, 0,
"bvc", NULL, 0x68, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"bvs", NULL, 0x69, CLASS_VI, CLASS_VI_BITS, 1, 1, 0,
"chk", NULL, 0x4180, CLASS_VIII, CLASS_VIII_BITS,2, 2, 0,
"clrb", NULL, 0x4200, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"clrl", NULL, 0x4280, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"clrw", NULL, 0x4240, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"cmpb", NULL, 0x0000, CLASS_X, CLASS_X_BITS, 2, 2, 0x0000,
"cmpl", NULL, 0x0080, CLASS_X, CLASS_X_BITS, 2, 2, 0xB1C0,
"cmpmb",NULL, 0xB108, CLASS_XI, CLASS_XI_BITS, 2, 2, 0,
"cmpml",NULL, 0xB188, CLASS_XI, CLASS_XI_BITS, 2, 2, 0,
"cmpmw",NULL, 0xB148, CLASS_XI, CLASS_XI_BITS, 2, 2, 0,
"cmpw", NULL, 0x0040, CLASS_X, CLASS_X_BITS, 2, 2, 0xB0C0,
"dbcc", NULL, 0x54C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbcs", NULL, 0x55C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbeq", NULL, 0x57C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbf", NULL, 0x51C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbge", NULL, 0x5CC8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbgt", NULL, 0x5EC8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbhi", NULL, 0x52C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dble", NULL, 0x5FC8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbls", NULL, 0x53C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dblt", NULL, 0x5DC8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbmi", NULL, 0x5BC8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbne", NULL, 0x56C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbpl", NULL, 0x5BC8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbra", NULL, 0x50C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbt", NULL, 0x50C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbvc", NULL, 0x58C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"dbvs", NULL, 0x59C8, CLASS_XII, CLASS_XII_BITS, 2, 2, 0,
"divs", NULL, 0x81C0, CLASS_VIII, CLASS_VIII_BITS,2, 2, 0,
"divu", NULL, 0x80C0, CLASS_VIII, CLASS_VIII_BITS,2, 2, 0,
"eorb", NULL, 0xB100, CLASS_XIII, CLASS_XIII_BITS,2, 2, 0x0A00,
"eorl", NULL, 0xB180, CLASS_XIII, CLASS_XIII_BITS,2, 2, 0x0A80,
"eorw", NULL, 0xB140, CLASS_XIII, CLASS_XIII_BITS,2, 2, 0x0A40,
"exg", NULL, 0xC100, CLASS_XIV, CLASS_XIV_BITS, 2, 2, 0,
"extl", NULL, 0x48C0, CLASS_XV, CLASS_XV_BITS, 1, 1, 0,
"extw", NULL, 0x4880, CLASS_XV, CLASS_XV_BITS, 1, 1, 0,
"illegal",NULL, 0x4AFC, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"jmp", NULL, 0x4EC0, CLASS_XVII, CLASS_XVII_BITS,1, 1, 0,
"jsr", NULL, 0x4E80, CLASS_XVII, CLASS_XVII_BITS,1, 1, 0,
"lea", NULL, 0x41C0, CLASS_XVIII, CLASS_XVIII_BITS,2, 2, 0,
"link", NULL, 0x4E50, CLASS_XIX, CLASS_XIX_BITS, 2, 2, 0,
"lslb", NULL, 0xE100, CLASS_V, CLASS_V_BITS, 1, 2, 01,
"lsll", NULL, 0xE180, CLASS_V, CLASS_V_BITS, 1, 2, 01,
"lslw", NULL, 0xE140, CLASS_V, CLASS_V_BITS, 1, 2, 01,
"lsrb", NULL, 0xE000, CLASS_V, CLASS_V_BITS, 1, 2, 01,
"lsrl", NULL, 0xE080, CLASS_V, CLASS_V_BITS, 1, 2, 01,
"lsrw", NULL, 0xE040, CLASS_V, CLASS_V_BITS, 1, 2, 01,
"movb", NULL, 0x1000, CLASS_XX, CLASS_XX_BITS, 2, 2, 0x0000,
"moveb",NULL, 0x1000, CLASS_XX, CLASS_XX_BITS, 2, 2, 0x0000,
"movel",NULL, 0x2000, CLASS_XX, CLASS_XX_BITS, 2, 2, 0x2040,
"moveml",NULL, 0x48C0, CLASS_XXI, CLASS_XXI_BITS, 2, 17, 0,
"movemw",NULL, 0x4880, CLASS_XXI, CLASS_XXI_BITS, 2, 17, 0,
"movepl",NULL, 0x0148, CLASS_XXII, CLASS_XXII_BITS,2, 2, 0,
"movepw",NULL, 0x0108, CLASS_XXII, CLASS_XXII_BITS,2, 2, 0,
"moveq",NULL, 0x70, CLASS_XXIII, CLASS_XXIII_BITS,2, 2, 0,
"movesb",NULL, 0x0E00, CLASS_XXIV, CLASS_XXIV_BITS,2, 2, 0,
"movesl",NULL, 0x0E80, CLASS_XXIV, CLASS_XXIV_BITS,2, 2, 0,
"movesw",NULL, 0x0E40, CLASS_XXIV, CLASS_XXIV_BITS,2, 2, 0,
"movew",NULL, 0x3000, CLASS_XX, CLASS_XX_BITS, 2, 2, 0x3040,
"movl", NULL, 0x2000, CLASS_XX, CLASS_XX_BITS, 2, 2, 0x2040,
"movml",NULL, 0x48C0, CLASS_XXI, CLASS_XXI_BITS, 2, 17, 0,
"movmw",NULL, 0x4880, CLASS_XXI, CLASS_XXI_BITS, 2, 17, 0,
"movpl",NULL, 0x0148, CLASS_XXII, CLASS_XXII_BITS,2, 2, 0,
"movpw",NULL, 0x0108, CLASS_XXII, CLASS_XXII_BITS,2, 2, 0,
"movq", NULL, 0x70, CLASS_XXIII, CLASS_XXIII_BITS,2, 2, 0,
"movsb",NULL, 0x0E00, CLASS_XXIV, CLASS_XXIV_BITS,2, 2, 0,
"movsl",NULL, 0x0E80, CLASS_XXIV, CLASS_XXIV_BITS,2, 2, 0,
"movsw",NULL, 0x0E40, CLASS_XXIV, CLASS_XXIV_BITS,2, 2, 0,
"movw", NULL, 0x3000, CLASS_XX, CLASS_XX_BITS, 2, 2, 0x3040,
"muls", NULL, 0xC1C0, CLASS_VIII, CLASS_VIII_BITS,2, 2, 0,
"mulu", NULL, 0xC0C0, CLASS_VIII, CLASS_VIII_BITS,2, 2, 0,
"nbcd", NULL, 0x4800, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"negb", NULL, 0x4400, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"negl", NULL, 0x4480, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"negw", NULL, 0x4440, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"negxb",NULL, 0x4000, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"negxl",NULL, 0x4080, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"negxw",NULL, 0x4040, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"nop", NULL, 0x4E71, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"notb", NULL, 0x4600, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"notl", NULL, 0x4680, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"notw", NULL, 0x4640, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"orb", NULL, 0x8000, CLASS_IV, CLASS_IV_BITS, 2, 2, 0x0000,
"orl", NULL, 0x8080, CLASS_IV, CLASS_IV_BITS, 2, 2, 0x0080,
"orw", NULL, 0x8040, CLASS_IV, CLASS_IV_BITS, 2, 2, 0x0040,
"pea", NULL, 0x4840, CLASS_XVII, CLASS_XVII_BITS,1, 1, 0,
"reset",NULL, 0x4E70, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"rolb", NULL, 0xE100, CLASS_V, CLASS_V_BITS, 1, 2, 02,
"roll", NULL, 0xE180, CLASS_V, CLASS_V_BITS, 1, 2, 02,
"rolw", NULL, 0xE140, CLASS_V, CLASS_V_BITS, 1, 2, 02,
"rorb", NULL, 0xE000, CLASS_V, CLASS_V_BITS, 1, 2, 02,
"rorl", NULL, 0xE080, CLASS_V, CLASS_V_BITS, 1, 2, 02,
"rorw", NULL, 0xE040, CLASS_V, CLASS_V_BITS, 1, 2, 02,
"roxlb",NULL, 0xE100, CLASS_V, CLASS_V_BITS, 1, 2, 03,
"roxll",NULL, 0xE180, CLASS_V, CLASS_V_BITS, 1, 2, 03,
"roxlw",NULL, 0xE140, CLASS_V, CLASS_V_BITS, 1, 2, 03,
"roxrb",NULL, 0xE000, CLASS_V, CLASS_V_BITS, 1, 2, 03,
"roxrl",NULL, 0xE080, CLASS_V, CLASS_V_BITS, 1, 2, 03,
"roxrw",NULL, 0xE040, CLASS_V, CLASS_V_BITS, 1, 2, 03,
"rtd", NULL, 0x4E74, CLASS_XXV, CLASS_XXV_BITS, 1, 1, 0,
"rte", NULL, 0x4E73, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"rtr", NULL, 0x4E77, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"rts", NULL, 0x4E75, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"sbcd", NULL, 0x8100, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"scc", NULL, 0x54C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"scs", NULL, 0x55C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"seq", NULL, 0x57C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"sf", NULL, 0x51C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"sge", NULL, 0x5CC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"sgt", NULL, 0x5EC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"shi", NULL, 0x52C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"sle", NULL, 0x5FC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"sls", NULL, 0x53C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"slt", NULL, 0x5DC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"smi", NULL, 0x5BC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"sne", NULL, 0x56C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"spl", NULL, 0x5AC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"st", NULL, 0x50C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"stop", NULL, 0x4E72, CLASS_XXVII, CLASS_XXVII_BITS,1, 1, 0,
"subb", NULL, 0x9000, CLASS_II, CLASS_II_BITS, 2, 2, 0x0400,
"subl", NULL, 0x9080, CLASS_II, CLASS_II_BITS, 2, 2, 0x0480,
"subqb",NULL, 0x5100, CLASS_III, CLASS_III_BITS, 2, 2, 0,
"subql",NULL, 0x5180, CLASS_III, CLASS_III_BITS, 2, 2, 0,
"subqw",NULL, 0x5140, CLASS_III, CLASS_III_BITS, 2, 2, 0,
"subw", NULL, 0x9040, CLASS_II, CLASS_II_BITS, 2, 2, 0x0440,
"subxb",NULL, 0x9100, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"subxl",NULL, 0x9180, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"subxw",NULL, 0x9140, CLASS_I, CLASS_I_BITS, 2, 2, 0,
"svc", NULL, 0x58C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"svs", NULL, 0x59C0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"swap", NULL, 0x4840, CLASS_XV, CLASS_XV_BITS, 1, 1, 0,
"tas", NULL, 0x4AC0, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"trap", NULL, 0x4E40, CLASS_XXVIII, CLASS_XXVIII_BITS,1,1, 0,
"trapv",NULL, 0x4E76, CLASS_XVI, CLASS_XVI_BITS, 0, 0, 0,
"tstb", NULL, 0x4A00, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"tstl", NULL, 0x4A80, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"tstw", NULL, 0x4A40, CLASS_IX, CLASS_IX_BITS, 1, 1, 0,
"unlk", NULL, 0x4E58, CLASS_XXVI, CLASS_XXVI_BITS,1, 1, 0,
NULL, NULL, 0x0000, CLASS_XVI, 0, 0, 0, 0,
};
int operandClassTable[] = { /* indexed by operandKindType */
EXPRESSION_OPND_BIT,
STRING_OPND_BIT,
BLOCK_OPND_BIT,
D_REGISTER_OPND_BIT,
A_REGISTER_OPND_BIT,
A_REGISTER_INDIRECT_OPND_BIT,
POSTINCREMENT_OPND_BIT,
PREDECREMENT_OPND_BIT,
DISPLACEMENT_OPND_BIT,
INDEXED_OPND_BIT,
PC_DISPLACEMENT_OPND_BIT,
PC_INDEXED_OPND_BIT,
IMMEDIATE_OPND_BIT,
ABSOLUTE_SHORT_OPND_BIT,
ABSOLUTE_LONG_OPND_BIT,
CC_REGISTER_OPND_BIT,
STATUS_REGISTER_OPND_BIT,
USP_REGISTER_OPND_BIT,
CONTROL_REGISTER_OPND_BIT,
SELECTED_OPND_BIT,
INDEX_SELECTED_OPND_BIT,
};
int actionsClassI();
int actionsClassII();
int actionsClassIII();
int actionsClassIV();
int actionsClassV();
int actionsClassVI();
int actionsClassVII();
int actionsClassVIII();
int actionsClassIX();
int actionsClassX();
int actionsClassXI();
int actionsClassXII();
int actionsClassXIII();
int actionsClassXIV();
int actionsClassXV();
int actionsClassXVI();
int actionsClassXVII();
int actionsClassXVIII();
int actionsClassXIX();
int actionsClassXX();
int actionsClassXXI();
int actionsClassXXII();
int actionsClassXXIII();
int actionsClassXXIV();
int actionsClassXXV();
int actionsClassXXVI();
int actionsClassXXVII();
int actionsClassXXVIII();
/* indexed by opcodeClass */
int (*instructionActionTable[])() = {
actionsClassI,
actionsClassII,
actionsClassIII,
actionsClassIV,
actionsClassV,
actionsClassVI,
actionsClassVII,
actionsClassVIII,
actionsClassIX,
actionsClassX,
actionsClassXI,
actionsClassXII,
actionsClassXIII,
actionsClassXIV,
actionsClassXV,
actionsClassXVI,
actionsClassXVII,
actionsClassXVIII,
actionsClassXIX,
actionsClassXX,
actionsClassXXI,
actionsClassXXII,
actionsClassXXIII,
actionsClassXXIV,
actionsClassXXV,
actionsClassXXVI,
actionsClassXXVII,
actionsClassXXVIII,
};
/* indexed by symbolUsageKindType */
int validSymbolValues[NUM_OF_SYM_USAGES] = {
/* STRUCT_NAME_SYMBOL */ STRUCT_VALUE_BIT,
/* STRUCT_FIELD_SYMBOL */ FIELD_VALUE_BIT,
/* MACRO_SYMBOL */ MACRO_VALUE_BIT,
/* ARGUMENT_SYMBOL */ OPERAND_VALUE_BIT,
/* LABEL_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT,
/* EXTERNAL_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT |
UNDEFINED_VALUE_BIT,
/* VARIABLE_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT |
UNDEFINED_VALUE_BIT |
STRING_VALUE_BIT | OPERAND_VALUE_BIT |
CONDITION_VALUE_BIT,
/* MVARIABLE_SYMBOL */ ABSOLUTE_VALUE_BIT | RELOCATABLE_VALUE_BIT |
DATA_VALUE_BIT | BSS_VALUE_BIT |
UNDEFINED_VALUE_BIT |
STRING_VALUE_BIT | OPERAND_VALUE_BIT |
CONDITION_VALUE_BIT,
/* UNKNOWN_SYMBOL */ UNDEFINED_VALUE_BIT,
/* FUNCTION_SYMBOL */ FUNCTION_VALUE_BIT,
/* BUILT_IN_FUNCTION_SYMBOL */ BUILT_IN_FUNCTION_VALUE_BIT,
/* NESTED_UNKNOWN_SYMBOL */ UNDEFINED_VALUE_BIT,
/* DEFINE_SYMBOL */ OPERAND_VALUE_BIT,
/* MDEFINE_SYMBOL */ OPERAND_VALUE_BIT,
/* UNKNOWN_FUNCTION_SYMBOL */ UNDEFINED_VALUE_BIT,
/* UNKNOWN_MACRO_SYMBOL */ UNDEFINED_VALUE_BIT,
};
/* indexed by valueKindType */
int valueBitTable[] = {
ABSOLUTE_VALUE_BIT,
DATA_VALUE_BIT,
RELOCATABLE_VALUE_BIT,
BSS_VALUE_BIT,
STRUCT_VALUE_BIT,
FIELD_VALUE_BIT,
MACRO_VALUE_BIT,
OPERAND_VALUE_BIT,
STRING_VALUE_BIT,
CONDITION_VALUE_BIT,
UNDEFINED_VALUE_BIT,
FUNCTION_VALUE_BIT,
BLOCK_VALUE_BIT,
BUILT_IN_FUNCTION_VALUE_BIT,
ARRAY_VALUE_BIT,
FAIL_BIT,
};
codeRegionType absoluteCodeRegion;
codeRegionType relocatableCodeRegion;
codeRegionType *codeRegions[2] = {
&absoluteCodeRegion,
&relocatableCodeRegion
};
/* A predefined undefined value so we don't have to make a new one every
time we need one */
valueType undefinedValueValue = { UNDEFINED_VALUE, 0,
EXPRESSION_OPND };
valueType *UndefinedValue = &undefinedValueValue;
valueType *addressModeBIF();
valueType *applyBIF();
valueType *atasciiBIF();
valueType *atasciiColorBIF();
valueType *debugModeOffBIF();
valueType *debugModeOnBIF();
valueType *emitModeOffBIF();
valueType *emitModeOnBIF();
valueType *getAddressRegisterBIF();
valueType *getDataRegisterBIF();
valueType *getIndexRegisterBIF();
valueType *getRegisterBIF();
valueType *getWLBIF();
valueType *isARegisterBIF();
valueType *isAbsoluteLongModeBIF();
valueType *isAbsoluteModeBIF();
valueType *isAbsoluteShortModeBIF();
valueType *isAbsoluteValueBIF();
valueType *isBlockBIF();
valueType *isBuiltInFunctionBIF();
valueType *isCCRegisterBIF();
valueType *isConditionCodeBIF();
valueType *isControlRegisterBIF();
valueType *isDFCRegisterBIF();
valueType *isDRegisterBIF();
valueType *isDefinedBIF();
valueType *isDisplacementModeBIF();
valueType *isExternalBIF();
valueType *isFieldBIF();
valueType *isFunctionBIF();
valueType *isImmediateModeBIF();
valueType *isIndexedModeBIF();
valueType *isIndirectModeBIF();
valueType *isPCDisplacementModeBIF();
valueType *isPCIndexedModeBIF();
valueType *isPostincrementModeBIF();
valueType *isPredecrementModeBIF();
valueType *isRelocatableValueBIF();
valueType *isSFCRegisterBIF();
valueType *isStatusRegisterBIF();
valueType *isStringBIF();
valueType *isStructBIF();
valueType *isSymbolBIF();
valueType *isUSPBIF();
valueType *isVBRegisterBIF();
valueType *listingOffBIF();
valueType *listingOnBIF();
valueType *nthCharBIF();
valueType *printfBIF();
valueType *strcatBIF();
valueType *strcmpBIF();
valueType *strcmplcBIF();
valueType *strlenBIF();
valueType *substrBIF();
valueType *symbolDefineBIF();
valueType *symbolLookupBIF();
valueType *symbolNameBIF();
valueType *symbolUsageBIF();
valueType *valueTypeBIF();
/* Used to initialize symbols representing built-in functions */
struct {
stringType *functionName;
valueType *(*functionEntry)();
bool isSpecialFunction;
} builtInFunctionTable[] = {
"addressMode", addressModeBIF, FALSE,
"apply", applyBIF, FALSE,
"atascii", atasciiBIF, FALSE,
"atasciiColor", atasciiColorBIF, FALSE,
"debugModeOff", debugModeOffBIF, FALSE,
"debugModeOn", debugModeOnBIF, FALSE,
"emitModeOff", emitModeOffBIF, FALSE,
"emitModeOn", emitModeOnBIF, FALSE,
"getAddressRegister", getAddressRegisterBIF, FALSE,
"getDataRegister", getDataRegisterBIF, FALSE,
"getIndexRegister", getIndexRegisterBIF, FALSE,
"getRegister", getRegisterBIF, FALSE,
"getWL", getWLBIF, FALSE,
"isARegister", isARegisterBIF, FALSE,
"isAbsoluteLongMode", isAbsoluteLongModeBIF, FALSE,
"isAbsoluteMode", isAbsoluteModeBIF, FALSE,
"isAbsoluteShortMode", isAbsoluteShortModeBIF, FALSE,
"isAbsoluteValue", isAbsoluteValueBIF, FALSE,
"isBlock", isBlockBIF, FALSE,
"isBuiltInFunction", isBuiltInFunctionBIF, FALSE,
"isCCRegister", isCCRegisterBIF, FALSE,
"isConditionCode", isConditionCodeBIF, FALSE,
"isControlRegister", isControlRegisterBIF, FALSE,
"isDFCRegister", isDFCRegisterBIF, FALSE,
"isDRegister", isDRegisterBIF, FALSE,
"isDefined", isDefinedBIF, TRUE,
"isDisplacementMode", isDisplacementModeBIF, FALSE,
"isExternal", isExternalBIF, TRUE,
"isField", isFieldBIF, FALSE,
"isFunction", isFunctionBIF, FALSE,
"isImmediateMode", isImmediateModeBIF, FALSE,
"isIndexedMode", isIndexedModeBIF, FALSE,
"isIndirectMode", isIndirectModeBIF, FALSE,
"isPCDisplacementMode", isPCDisplacementModeBIF,FALSE,
"isPCIndexedMode", isPCIndexedModeBIF, FALSE,
"isPostincrementMode", isPostincrementModeBIF, FALSE,
"isPredecrementMode", isPredecrementModeBIF, FALSE,
"isRelocatableValue", isRelocatableValueBIF, FALSE,
"isSFCRegister", isSFCRegisterBIF, FALSE,
"isStatusRegister", isStatusRegisterBIF, FALSE,
"isString", isStringBIF, FALSE,
"isStruct", isStructBIF, FALSE,
"isSymbol", isSymbolBIF, TRUE,
"isUSP", isUSPBIF, FALSE,
"isVBRegister", isVBRegisterBIF, FALSE,
"listingOff", listingOffBIF, FALSE,
"listingOn", listingOnBIF, FALSE,
"nthChar", nthCharBIF, FALSE,
"printf", printfBIF, FALSE,
"strcat", strcatBIF, FALSE,
"strcmp", strcmpBIF, FALSE,
"strcmplc", strcmplcBIF, FALSE,
"strlen", strlenBIF, FALSE,
"substr", substrBIF, FALSE,
"symbolDefine", symbolDefineBIF, FALSE,
"symbolLookup", symbolLookupBIF, FALSE,
"symbolName", symbolNameBIF, TRUE,
"symbolUsage", symbolUsageBIF, TRUE,
"valueType", valueTypeBIF, FALSE,
NULL, NULL, FALSE,
};
/* Used to initialize predefined symbols */
struct {
stringType *symbolName;
int symbolValue;
} predefinedSymbolTable[] = {
"FALSE", 0,
"NULL", 0,
"TRUE", 1,
NULL, 0,
};
/* These define the temporary files used to hold scratch data used in the
generation of listings. The "XXXXXX"s get blasted by 'mktemp' */
char pass2SourceFileName[] = "/tmp/zsourceXXXXXX";
char pass2IndexFileName[] = "/tmp/zindexXXXXXX";
char pass2MacroExpansionFileName[] = "/tmp/zmacroXXXXXX";

1070
macrossTypes.h Normal file

File diff suppressed because it is too large Load Diff

1202
macross_6502.y Normal file

File diff suppressed because it is too large Load Diff

1362
macross_68000.y Normal file

File diff suppressed because it is too large Load Diff

37
main.c Normal file
View File

@ -0,0 +1,37 @@
/*
main.c -- Top level of the Macross assembler.
Chip Morningstar -- Lucasfilm Ltd.
5-December-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
main(argc, argv)
int argc;
char *argv[];
{
extern char end;
char *sbrk();
fflush(stdout);
initializeStuff(argc, argv);
yyparse();
finishUp();
if (emitPrint)
printf("storage high water mark 0x%x == %d\n", sbrk(0) - &end,
sbrk(0) - &end);
if (errorFlag)
chokePukeAndDie();
else
exit(0);
}
void
printVersion()
{
printf("Macross %s version 4.20.\n", TARGET_CPU_STRING);
}

BIN
main.o Normal file

Binary file not shown.

331
malloc.c Normal file
View File

@ -0,0 +1,331 @@
#ifndef lint
static char sccsid[] = "@(#)malloc.c 1.2 (Lucasfilm) 84/10/17";
/* from malloc.c 4.3 (Berkeley) 9/16/83 */
#endif
/*
* malloc.c (Caltech) 2/21/82
* Chris Kingsley, kingsley@cit-20.
*
* This is a very fast storage allocator. It allocates blocks of a small
* number of different sizes, and keeps free lists of each size. Blocks that
* don't exactly fit are passed up to the next larger size. In this
* implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
* This is designed for use in a program that uses vast quantities of memory,
* but bombs when it runs out.
*/
#include <sys/types.h>
#define NULL 0
/*
* The overhead on a block is at least 4 bytes. When free, this space
* contains a pointer to the next free block, and the bottom two bits must
* be zero. When in use, the first byte is set to MAGIC, and the second
* byte is the size index. The remaining bytes are for alignment.
* If range checking is enabled and the size of the block fits
* in two bytes, then the top two bytes hold the size of the requested block
* plus the range checking words, and the header word MINUS ONE.
*/
union overhead {
union overhead *ov_next; /* when free */
struct {
u_char ovu_magic; /* magic number */
u_char ovu_index; /* bucket # */
#ifdef RCHECK
u_short ovu_size; /* actual block size */
u_int ovu_rmagic; /* range magic number */
#endif
} ovu;
#define ov_magic ovu.ovu_magic
#define ov_index ovu.ovu_index
#define ov_size ovu.ovu_size
#define ov_rmagic ovu.ovu_rmagic
};
#define MAGIC 0xff /* magic # on accounting info */
#define RMAGIC 0x55555555 /* magic # on range info */
#ifdef RCHECK
#define RSLOP sizeof (u_int)
#else
#define RSLOP 0
#endif
/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information
* precedes the data area returned to the user.
*/
#define NBUCKETS 30
static union overhead *nextf[NBUCKETS];
extern char *sbrk();
#ifdef MSTATS
/*
* nmalloc[i] is the difference between the number of mallocs and frees
* for a given block size.
*/
static u_int nmalloc[NBUCKETS];
#include <stdio.h>
#endif
#ifdef debug
#define ASSERT(p) if (!(p)) botch("p"); else
static
botch(s)
char *s;
{
printf("assertion botched: %s\n", s);
abort();
}
#else
#define ASSERT(p)
#endif
char *
malloc(nbytes)
register unsigned nbytes;
{
register union overhead *p;
register int bucket = 0;
register unsigned shiftr;
/*
* Convert amount of memory requested into
* closest block size stored in hash buckets
* which satisfies request. Account for
* space used per block for accounting.
*/
nbytes += sizeof (union overhead) + RSLOP;
nbytes = (nbytes + 3) &~ 3;
shiftr = (nbytes - 1) >> 2;
/* apart from this loop, this is O(1) */
while (shiftr >>= 1)
bucket++;
/*
* If nothing in hash bucket right now,
* request more memory from the system.
*/
if (nextf[bucket] == NULL)
morecore(bucket);
if ((p = (union overhead *)nextf[bucket]) == NULL)
return (NULL);
/* remove from linked list */
nextf[bucket] = nextf[bucket]->ov_next;
p->ov_magic = MAGIC;
p->ov_index= bucket;
#ifdef MSTATS
nmalloc[bucket]++;
#endif
#ifdef RCHECK
/*
* Record allocated size of block and
* bound space with magic numbers.
*/
if (nbytes <= 0x10000)
p->ov_size = nbytes - 1;
p->ov_rmagic = RMAGIC;
*((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC;
#endif
return ((char *)(p + 1));
}
/*
* Allocate more memory to the indicated bucket.
*/
static
morecore(bucket)
register bucket;
{
register union overhead *op;
register int rnu; /* 2^rnu bytes will be requested */
register int nblks; /* become nblks blocks of the desired size */
register int siz;
if (nextf[bucket])
return;
/*
* Insure memory is allocated
* on a page boundary. Should
* make getpageize call?
*/
op = (union overhead *)sbrk(0);
if ((int)op & 0x3ff)
sbrk(1024 - ((int)op & 0x3ff));
/* take 2k unless the block is bigger than that */
/* rnu = (bucket <= 8) ? 11 : bucket + 3; */
rnu = (bucket <= 10) ? 13 : bucket + 3; /* now grab 8k 'cbm' */
nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */
if (rnu < bucket)
rnu = bucket;
op = (union overhead *)sbrk(1 << rnu);
/* no more room! */
if ((int)op == -1)
return;
/*
* Round up to minimum allocation size boundary
* and deduct from block count to reflect.
*/
if ((int)op & 7) {
op = (union overhead *)(((int)op + 8) &~ 7);
nblks--;
}
/*
* Add new memory allocated to that on
* free list for this hash bucket.
*/
nextf[bucket] = op;
siz = 1 << (bucket + 3);
while (--nblks > 0) {
op->ov_next = (union overhead *)((caddr_t)op + siz);
op = (union overhead *)((caddr_t)op + siz);
}
}
free(cp)
char *cp;
{
register int size;
register union overhead *op;
if (cp == NULL)
return;
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
#ifdef debug
ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
#else
if (op->ov_magic != MAGIC)
return; /* sanity */
#endif
#ifdef RCHECK
ASSERT(op->ov_rmagic == RMAGIC);
if (op->ov_index <= 13)
ASSERT(*(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) == RMAGIC);
#endif
ASSERT(op->ov_index < NBUCKETS);
size = op->ov_index;
op->ov_next = nextf[size];
nextf[size] = op;
#ifdef MSTATS
nmalloc[size]--;
#endif
}
/*
* When a program attempts "storage compaction" as mentioned in the
* old malloc man page, it realloc's an already freed block. Usually
* this is the last block it freed; occasionally it might be farther
* back. We have to search all the free lists for the block in order
* to determine its bucket: 1st we make one pass thru the lists
* checking only the first block in each; if that fails we search
* ``realloc_srchlen'' blocks in each list for a match (the variable
* is extern so the caller can modify it). If that fails we just copy
* however many bytes was given to realloc() and hope it's not huge.
*/
int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
char *
realloc(cp, nbytes)
char *cp;
unsigned nbytes;
{
register u_int onb;
union overhead *op;
char *res;
register int i;
int was_alloced = 0;
if (cp == NULL)
return (malloc(nbytes));
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
if (op->ov_magic == MAGIC) {
was_alloced++;
i = op->ov_index;
} else {
/*
* Already free, doing "compaction".
*
* Search for the old block of memory on the
* free list. First, check the most common
* case (last element free'd), then (this failing)
* the last ``realloc_srchlen'' items free'd.
* If all lookups fail, then assume the size of
* the memory block being realloc'd is the
* smallest possible.
*/
if ((i = findbucket(op, 1)) < 0 &&
(i = findbucket(op, realloc_srchlen)) < 0)
i = 0;
}
onb = (1 << (i + 3)) - sizeof (*op) - RSLOP;
/* avoid the copy if same size block */
if (was_alloced &&
nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP)
return(cp);
if ((res = malloc(nbytes)) == NULL)
return (NULL);
if (cp != res) /* common optimization */
bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
if (was_alloced)
free(cp);
return (res);
}
/*
* Search ``srchlen'' elements of each free list for a block whose
* header starts at ``freep''. If srchlen is -1 search the whole list.
* Return bucket number, or -1 if not found.
*/
static
findbucket(freep, srchlen)
union overhead *freep;
int srchlen;
{
register union overhead *p;
register int i, j;
for (i = 0; i < NBUCKETS; i++) {
j = 0;
for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
if (p == freep)
return (i);
j++;
}
}
return (-1);
}
#ifdef MSTATS
/*
* mstats - print out statistics about malloc
*
* Prints two lines of numbers, one showing the length of the free list
* for each size category, the second showing the number of mallocs -
* frees for each size category.
*/
mstats(s)
char *s;
{
register int i, j;
register union overhead *p;
int totfree = 0,
totused = 0;
fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
for (i = 0; i < NBUCKETS; i++) {
for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
;
fprintf(stderr, " %d", j);
totfree += j * (1 << (i + 3));
}
fprintf(stderr, "\nused:\t");
for (i = 0; i < NBUCKETS; i++) {
fprintf(stderr, " %d", nmalloc[i]);
totused += nmalloc[i] * (1 << (i + 3));
}
fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",
totused, totfree);
}
#endif

BIN
malloc.o Normal file

Binary file not shown.

51
notes68/1.am Normal file
View File

@ -0,0 +1,51 @@
Address Modes
-------------
Notation
Number Motorola Name Motorola Sun Sun Name
------ ------------- -------- --- --------
1 Data Register Direct Dn Dn Register
2 Address Register Direct An An Register
3 Address Register Indirect (An) An@ Register
Deferred
4 Address Register Indirect w/ (An)+ An@+ Postincrement
Postincrement
5 Address Register Indirect w/ -(An) An@- Predecrement
Predecrement
6 Address Register Indirect w/ d(An) An@(d) Displacement
Displacement
7 Address Register Indirect w/ d(An,Rx.W) An@(d,Rx:W) Word Index
Index d(An,Rx.L) An@(d,Rx:L) Long Index
8 Program Counter w/ Displacement d(PC) PC@(d) PC Displacement
9 Program Counter w/ Index d(PC,Rx.W) PC@(d,Rx:W) PC Word
Index
d(PC,Rx.L) PC@(d,Rx:L) PC Long
Index
10 Immediate #xxx #xxx Immediate
11 Absolute Short xxx.W xxx:W Absolute Short
12 Absolute Long xxx.L xxx:L Absolute Long
13 -- -- xxx Normal
14 (condition code register) CCR CC --
15 (status register) SR SR --
16 Implied
17 (user stack pointer) USP USP --
18 (control register) SFC SFC --
DFC DFC
VBR VBR

45
notes68/2.amg Normal file
View File

@ -0,0 +1,45 @@
Address Mode Groups
-------------------
ID Mode set Mnemonic
-- -------- --------
A 1 DATA_REGISTER
B 2 ADDRESS_REGISTER
C 4 POSTINCREMENT
D 5 PREDECREMENT
E 6 DISPLACEMENT
F 10 IMMEDIATE
G 13 NORMAL
H 14 CONDITION_CODE_REGISTER
I 15 STATUS_REGISTER
J 16 (no operand at all!)
K 17 USER_STACK_POINTER
L { 17-18 } CONTROL_REGISTER
M { 1-2 } REGISTER
N { 1-7, 11-13 } STORABLE
O { 1-13 } FULL_EA
P { 1, 3-7, 11-13 } STORABLE_NO_A_REGISTER
Q { 1, 3-13 } FULL_EA_NO_A_REG
R { 3-4, 6-9, 11-13 } MISC_1
S { 3-7, 11-13 } STORABLE_NO_REGISTER
T { 3, 5-7, 11-13 } MISC_2
U { 3, 6-9, 11-13 } MISC_3

60
notes68/3.os Normal file
View File

@ -0,0 +1,60 @@
Operand Sets
------------
1 A
2 AA
3 AE
4 AG
5 AP
6 AS
7 B
8 BF
9 BK
10 CC
11 DD
12 EA
13 F
14 FA
15 FH
16 FI
17 FN
18 FP
19 G
20 HP
21 IP
22 J
23 KB
24 LM
25 ML
26 MM
27 MP
28 MS
29 M*T
30 OA
31 OB
32 P
33 QA
34 QH
35 QI
36 RM*
37 S
38 SM
39 U
40 UB

115
notes68/4.ic Normal file
View File

@ -0,0 +1,115 @@
Instruction Classes
-------------------
i ABCD - | AA
ADDX bwl | DD
SBCD - |
SUBX bwl |
ii ADD bwl | AS
SUB bwl | FP __I
| OA
| OB __A
iii ADDQ bwl | FN
SUBQ bwl |
iv AND bwl | AS
OR bwl | FH __CCR
| FI __SR
| FN __I
| GA
v ASL bwl | AA
ASR bwl | FA
LSL bwl | S
LSR bwl |
ROL bwl |
ROR bwl |
ROXL bwl |
ROXR bwl |
vi Bcc - | G
BRA - |
BSR - |
vii BCHG - | AP
BCLR - | FP
BSET - |
BTST - |
viii CHK - | QA
DIVS - |
DIVU - |
MULS - |
MULU - |
ix CLR bwl | P
NBCD - |
NEG bwl |
NEGX bwl |
NOT bwl |
Scc - |
TAS - |
TST bwl |
x CMP bwl | FP __I
| OA
| OB __A
xi CMPM bwl | CC
xii DBcc - | AG
xiii EOR bwl | AP
| FH __CCR
| FI __SR
| FP __I
xiv EXG - | MM
xv EXT bwl | A
SWAP - |
xvi ILLEGAL - | J
NOP - |
RESET - |
RTE - |
RTR - |
RTS - |
TRAPV - |
xvii JMP - | U
JSR - |
PEA - |
xviii LEA - | UB
xix LINK - | BF
xx MOV bwl | BK __USP
| HP CCR__
| IP SR__
| KB __USP
| LM __C
| ML __C
| OB __I
| OP
| QH __CCR
| QI __SR
xxi MOVEM wl | M*T
| RM*
xxii MOVEP wl | AE
| EA
xxiii MOVEQ - | FA
xxiv MOVS bwl | MS
| SM
xxv RTD - | F
STOP - |
TRAP - |
xxvi UNLK - | B

612
object.c Normal file
View File

@ -0,0 +1,612 @@
/*
object.c -- Routines to output object files for the Macross assembler.
Chip Morningstar -- Lucasfilm Ltd.
20-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
static int symbolTableSize;
static int symbolTableStringSize;
bool encodingFunction;
void
outputObjectFile()
{
void outputPartition();
void outputReferenceInfo();
void outputSymbolTableInfo();
void outputAbsoluteCode();
void outputRelocatableCode();
void outputReservations();
void outputExpressions();
void outputFunctions();
void dumpSymbolTable();
void enumerateAndCountSymbols();
if (debug || emitPrint)
printCodeBuffers();
outputPartition();
outputAbsoluteCode();
if (produceLinkableObject) {
outputPartition();
outputRelocatableCode();
outputPartition();
outputReservations();
outputPartition();
enumerateAndCountSymbols();
outputReferenceInfo();
outputSymbolTableInfo();
outputExpressions();
outputFunctions();
}
if (symbolTableDumpOn)
dumpSymbolTable();
fclose(objectFileOutput);
}
void
outputWord(aWord)
int aWord;
{
putc(aWord & 0xFF, objectFileOutput);
putc((aWord >> 8) & 0xFF, objectFileOutput);
}
void
outputPartition()
{
outputWord(0xFFFF);
}
void
outputBigword(bigword)
unsigned long bigword;
{
int i;
for (i=1; i<=4; i++) {
putc(bigword & 0xFF, objectFileOutput);
bigword >>= 8;
}
}
void
outputByte(aByte)
byte aByte;
{
putc(aByte, objectFileOutput);
}
void
outputString(string)
stringType *string;
{
do {
putc(*string, objectFileOutput);
} while (*string++ != '\0');
}
void
outputStartAddress(startAddress)
addressType startAddress;
{
outputWord(startAddress);
if (produceLinkableObject) {
outputWord(startAddress - 3);
outputByte(0);
} else {
outputWord(startAddress);
outputByte(0);
}
}
void
outputRelocatableCode()
{
int i;
addressType codeStartAddress;
addressType codeEndAddress;
void outputPseudoSegment();
void outputBreak();
if (haveUserStartAddress && !fixupStartAddress && startAddress->
kindOfValue == RELOCATABLE_VALUE)
outputStartAddress(startAddress->value);
else if (haveUserStartAddress && fixupStartAddress)
outputStartAddress(0xFFFE);
if (relocatableHighWaterMark < 0)
return;
codeEndAddress = -1;
do {
codeStartAddress = codeEndAddress + 1;
while (codeBreakList != NULL && codeBreakList->breakAddress
== codeStartAddress) {
outputBreak(codeBreakList);
codeBreakList = codeBreakList->nextBreak;
}
if (codeBreakList == NULL)
codeEndAddress = relocatableHighWaterMark;
else
codeEndAddress = codeBreakList->breakAddress - 1;
outputPseudoSegment(codeStartAddress, codeEndAddress);
} while (codeEndAddress < relocatableHighWaterMark);
}
void
outputBreak(codeBreak)
codeBreakType *codeBreak;
{
switch (codeBreak->kindOfBreak) {
case BREAK_BREAK:
case END_CONSTRAIN_BREAK:
/* do nothing */
break;
case ALIGN_BREAK:
outputWord(codeBreak->breakAddress);
outputWord(codeBreak->breakAddress - 2);
outputWord(codeBreak->breakData);
break;
case CONSTRAIN_BREAK:
outputWord(codeBreak->breakAddress);
outputWord(codeBreak->breakAddress - 1);
outputWord(codeBreak->breakData);
break;
}
}
void
outputAbsoluteCode()
{
int i;
int startSegment;
int endSegment;
int nextSegment;
void outputOneCodeBuffer();
if (haveUserStartAddress && !fixupStartAddress && startAddress->
kindOfValue==ABSOLUTE_VALUE)
outputStartAddress(startAddress->value);
for (startSegment=0; startSegment<CODE_BUFFERS_IN_ADDRESS_SPACE;
startSegment = endSegment + 1) {
endSegment = startSegment;
nextSegment = endSegment + 1;
while (nextSegment < CODE_BUFFERS_IN_ADDRESS_SPACE &&
absoluteCodeRegion.codeSegments[nextSegment]
!= NULL && absoluteCodeRegion.codeSegments[
endSegment] != NULL && absoluteCodeRegion.
codeSegments[endSegment]->codeEndAddress+1 ==
absoluteCodeRegion.codeSegments[nextSegment]
->codeStartAddress) {
++endSegment;
++nextSegment;
}
if (absoluteCodeRegion.codeSegments[startSegment] != NULL) {
outputWord(absoluteCodeRegion.codeSegments[
startSegment]->codeStartAddress);
outputWord(absoluteCodeRegion.codeSegments[
endSegment]->codeEndAddress);
for (i=startSegment; i<=endSegment; ++i)
outputOneCodeBuffer(absoluteCodeRegion.
codeSegments[i]);
}
}
}
void
outputOneCodeBuffer(segment)
codeSegmentType *segment;
{
int i;
if (segment != NULL) {
/* outputWord(segment->codeStartAddress);
outputWord(segment->codeEndAddress);*/
for (i=bufferPosition(segment->codeStartAddress); i<=
bufferPosition(segment->codeEndAddress); i++)
outputByte((*segment->codeBuffer)[i]);
}
}
void
outputPseudoSegment(codeStartAddress, codeEndAddress)
addressType codeStartAddress;
addressType codeEndAddress;
{
int startSegment;
int endSegment;
int startPosition;
int endPosition;
int originalStartPosition;
int ultimateEndPosition;
int position;
int segment;
codeSegmentType *segmentPtr;
void outputWord();
void outputByte();
outputWord(codeStartAddress);
outputWord(codeEndAddress);
startSegment = bufferNumber(codeStartAddress);
endSegment = bufferNumber(codeEndAddress);
originalStartPosition = bufferPosition(codeStartAddress);
ultimateEndPosition = bufferPosition(codeEndAddress);
for (segment=startSegment; segment<=endSegment; segment++) {
segmentPtr = relocatableCodeRegion.codeSegments[segment];
startPosition = (segment == startSegment) ?
originalStartPosition : 0;
endPosition = (segment == endSegment) ? ultimateEndPosition :
CODE_BUFFER_SIZE - 1;
for(position=startPosition; position<=endPosition; position++)
outputByte((*segmentPtr->codeBuffer)[position]);
}
}
bool
isObjectSymbol(symbol)
symbolTableEntryType *symbol;
{
return(symbol != NULL && symbol->context->value != NULL &&
symbol->context->value->kindOfValue != FUNCTION_VALUE &&
symbol->context->value->kindOfValue != BUILT_IN_FUNCTION_VALUE
&& symbol->context->value->kindOfValue != MACRO_VALUE &&
((isExternal(symbol) && symbol->context->value->kindOfValue
!= UNDEFINED_VALUE) || symbol->referenceCount > 0));
/* return(symbol != NULL && symbol->context->value != NULL &&
(symbol->context->value->kindOfValue == RELOCATABLE_VALUE ||
symbol->context->value->kindOfValue == ABSOLUTE_VALUE ||
isExternal(symbol)));*/
}
void
enumerateAndCountSymbols()
{
int i;
symbolTableEntryType *symb;
symbolTableSize = 0;
symbolTableStringSize = 0;
for (i=0; i<HASH_TABLE_SIZE; i++)
for (symb=symbolTable[i]; symb!=NULL; symb=symb->nextSymbol)
if (isObjectSymbol(symb)) {
symbolTableStringSize += strlen(symb->symbolName) + 1;
symb->ordinal = symbolTableSize++;
}
}
int
enumerateAndCountReferences()
{
int result;
int codeMode;
expressionReferenceListType *theReferences;
result = 0;
for (codeMode=0; codeMode<=1; codeMode++) {
theReferences = expressionReferenceList[codeMode];
while (theReferences != NULL) {
theReferences->relocation.referenceExpression = result++;
theReferences = theReferences->nextReference;
}
}
return(result);
}
void
outputReference(reference)
expressionReferenceType *reference;
{
byte funnyByte;
bigWord funnyWord;
/* This nonsense is to maintain byte-order and bit-order independence
across host machines so that Macross object files will be
portable. */
funnyByte = reference->referenceMode |
(reference->referenceRelative << 1) |
(reference->referenceExternal << 2) |
(reference->referenceKind << 3);
funnyWord = ((reference->referenceAddress) & 0xFFFFFF) |
(funnyByte << 24);
outputBigword(funnyWord);
outputBigword(reference->referenceExpression);
}
static int referenceCount;
void
outputReferenceInfo()
{
expressionReferenceListType *theReferences;
int codeMode;
outputBigword(referenceCount = enumerateAndCountReferences());
for (codeMode=0; codeMode<=1; codeMode++) {
theReferences = expressionReferenceList[codeMode];
while (theReferences != NULL) {
outputReference(&(theReferences->relocation));
theReferences = theReferences->nextReference;
}
}
}
void
outputOneSymbol(symbol)
symbolTableEntryType *symbol;
{
byte symbolClass;
valueType *symbolValue;
valueType *evaluateIdentifier();
if (symbol->context->usage == DEFINE_SYMBOL)
symbolValue = evaluateIdentifier(symbol, FALSE, NO_FIXUP_OK);
else
symbolValue = symbol->context->value;
if (symbolValue->kindOfValue == ABSOLUTE_VALUE)
symbolClass = SYMBOL_ABSOLUTE;
else if (symbolValue->kindOfValue == RELOCATABLE_VALUE)
symbolClass = SYMBOL_RELOCATABLE;
else
symbolClass = SYMBOL_UNDEFINED;
if (isExternal(symbol))
symbolClass |= SYMBOL_EXTERNAL;
else if (symbolClass == SYMBOL_UNDEFINED)
symbolClass = SYMBOL_ABSOLUTE;
outputByte(symbolClass);
outputBigword(symbolValue->value);
outputString(symbol->symbolName);
}
void
outputSymbolTableInfo()
{
int i;
symbolTableEntryType *symb;
outputBigword(symbolTableSize);
outputBigword(symbolTableStringSize);
for (i=0; i<HASH_TABLE_SIZE; i++)
for (symb=symbolTable[i]; symb!=NULL; symb=symb->nextSymbol)
if (isObjectSymbol(symb))
outputOneSymbol(symb);
}
int
symbolCompare(symbol1, symbol2)
symbolTableEntryType **symbol1;
symbolTableEntryType **symbol2;
{
return(strcmplc((*symbol1)->symbolName, (*symbol2)->symbolName));
}
bool
shouldDumpSymbol(symbol)
symbolTableEntryType *symbol;
{
return(symbolTableDumpOn == 2
|| (symbol->context->usage != BUILT_IN_FUNCTION_SYMBOL
&& (symbol->context->usage != DEFINE_SYMBOL
|| symbol->context->referenceCount != 0
|| showAllSymbolsFlag
)
&& symbol->symbolName[0] != '$'
&& symbol->symbolName[0] != '_'
)
);
}
void
dumpSymbolTable()
{
int i;
symbolTableEntryType *symb;
symbolTableEntryType **symbolVector;
int numberOfSymbols;
int symbolPtr;
valueType *value;
valueType *evaluateIdentifier();
void printValueTersely();
numberOfSymbols = 0;
for (i=0; i<HASH_TABLE_SIZE; i++)
for (symb=symbolTable[i]; symb!=NULL; symb=symb->nextSymbol) {
if (symb->context != NULL && symb->context->value != NULL &&
(symb->context->value->kindOfValue !=
UNDEFINED_VALUE || symb->context->usage ==
LABEL_SYMBOL || symb->context->usage ==
EXTERNAL_SYMBOL || symb->context->usage ==
UNKNOWN_SYMBOL || symb->context->usage ==
NESTED_UNKNOWN_SYMBOL)) {
if (shouldDumpSymbol(symb)) {
numberOfSymbols++;
}
}
}
symbolVector = (symbolTableEntryType **)malloc(
sizeof(symbolTableEntryType *) * numberOfSymbols);
symbolPtr = 0;
for (i=0; i<HASH_TABLE_SIZE; i++)
for (symb=symbolTable[i]; symb!=NULL; symb=symb->nextSymbol) {
if (symb->context != NULL && symb->context->value != NULL &&
(symb->context->value->kindOfValue !=
UNDEFINED_VALUE || symb->context->usage ==
LABEL_SYMBOL || symb->context->usage ==
EXTERNAL_SYMBOL || symb->context->usage ==
UNKNOWN_SYMBOL || symb->context->usage ==
NESTED_UNKNOWN_SYMBOL)) {
if (shouldDumpSymbol(symb)) {
symbolVector[symbolPtr++] = symb;
}
}
}
qsort(symbolVector, numberOfSymbols, sizeof(symbolTableEntryType *),
symbolCompare);
for (symbolPtr=0; symbolPtr<numberOfSymbols; symbolPtr++) {
symb = symbolVector[symbolPtr];
if (hackFlag != 0) {
if (hackableSymbol(symb) && (isExternal(symb) ||
hackFlag == 1)) {
value = evaluateIdentifier(symb, TRUE,
NO_FIXUP_OK);
fprintf(symbolDumpFileOutput,
"define %s = 0x%x\n", symb->
symbolName, value->value);
}
} else if (symb->context->usage == FUNCTION_SYMBOL) {
fprintf(symbolDumpFileOutput, "%-20s = FUNCTION\n",
symb->symbolName);
} else if (symbolTableDumpOn == 2 || symb->context->usage !=
BUILT_IN_FUNCTION_SYMBOL) {
value = evaluateIdentifier(symb, TRUE, NO_FIXUP_OK);
fprintf(symbolDumpFileOutput, "%-20s = ", symb->
symbolName);
printValueTersely(value);
fprintf(symbolDumpFileOutput, " [%d]", symb->
context->referenceCount - 1);
if (isExternal(symb))
fprintf(symbolDumpFileOutput, " ext");
fprintf(symbolDumpFileOutput, "\n");
}
}
free(symbolVector);
}
bool
hackableSymbol(symbol)
symbolTableEntryType *symbol;
{
return(symbol->context->usage == DEFINE_SYMBOL || symbol->context->
usage == LABEL_SYMBOL);
}
void
printValueTersely(value)
valueType *value;
{
static char *valueKindTable[NUM_OF_VALUE_KINDS] = {
"ABS",
"DAT",
"REL",
"BSS",
"STT",
"FLD",
"MAC",
"OPN",
"STR",
"CND",
"UND",
"FUN",
"BLK",
"BIF",
"FAL",
};
if (value != NULL)
fprintf(symbolDumpFileOutput, "%s: %#6x %d", valueKindTable[
(int)value->kindOfValue], value->value, value->value);
else
fprintf(symbolDumpFileOutput, "(no value)");
}
void
outputReservations()
{
while (reservationList != NULL) {
outputWord(reservationList->startAddress);
outputWord(reservationList->blockSize);
reservationList = reservationList->nextReservation;
}
}
void
outputExpressionBuffer()
{
int i;
outputBigword(expressionBufferSize);
if (debug || emitPrint)
printExpressionBuffer();
for (i=0; i<expressionBufferSize; ++i)
outputByte(expressionBuffer[i]);
}
void
outputOneExpression(expression)
expressionType *expression;
{
expressionType *newExpression;
expressionType *generateFixupExpression();
bool encodeExpression();
expressionBufferSize = 0;
if (expression == NULL) {
encodeRelocatableNumber(0);
outputExpressionBuffer();
} else {
newExpression = generateFixupExpression(expression);
freeExpression(expression);
if (encodeExpression(newExpression))
outputExpressionBuffer();
}
}
void
outputExpressions()
{
int codeMode;
expressionReferenceListType *theReferences;
encodingFunction = FALSE;
outputBigword(referenceCount);
for (codeMode=0; codeMode<=1; codeMode++) {
theReferences = expressionReferenceList[codeMode];
while (theReferences != NULL) {
outputOneExpression(theReferences->expressionReferenced);
theReferences = theReferences->nextReference;
}
}
if (haveUserStartAddress && fixupStartAddress)
outputOneExpression(startAddress);
}
void
outputOneFunction(function)
functionDefinitionType *function;
{
argumentDefinitionListType *argumentList;
bool encodeBlock();
int countArguments();
outputByte((byte)countArguments(function));
argumentList = function->arguments;
while (argumentList != NULL) {
outputBigword(argumentList->theArgument->ordinal);
argumentList = argumentList->nextArgument;
}
expressionBufferSize = 0;
if (encodeBlock(function->body))
outputExpressionBuffer();
}
void
outputFunctions()
{
outputBigword(externalFunctionCount);
encodingFunction = TRUE;
while (externalFunctionCount-- > 0) {
outputOneFunction(externalFunctionList);
externalFunctionList = externalFunctionList->
nextExternalFunction;
}
}

BIN
object.o Normal file

Binary file not shown.

59
operandBody_6502.h Normal file
View File

@ -0,0 +1,59 @@
/*
operandBody_6502.h -- Define parser tree types for 6502 operands.
Chip Morningstar -- Lucasfilm Ltd.
18-April-1985
*/
typedef stringType stringOperandBodyType;
typedef expressionType xIndexedOperandBodyType;
typedef expressionType yIndexedOperandBodyType;
typedef expressionType preIndexedXOperandBodyType;
typedef expressionType postIndexedYOperandBodyType;
typedef nullType yRegisterOperandBodyType;
typedef nullType xRegisterOperandBodyType;
typedef nullType aRegisterOperandBodyType;
typedef expressionType immediateOperandBodyType;
typedef expressionType indirectOperandBodyType;
typedef expressionType expressionOperandBodyType;
typedef BlockType blockOperandBodyType;
typedef selectionListType xSelectedOperandBodyType;
typedef selectionListType ySelectedOperandBodyType;
typedef selectionListType preSelectedOperandBodyType;
#define BlockOperandBodyType anyOldThing /* kludge */
/* doing above right confuses compiler as it is a forward reference inside
yon union: */
typedef union {
expressionOperandBodyType *expressionUnion;
immediateOperandBodyType *immediateUnion;
indirectOperandBodyType *indirectUnion;
aRegisterOperandBodyType *aRegisterUnion;
xRegisterOperandBodyType *xRegisterUnion;
yRegisterOperandBodyType *yRegisterUnion;
postIndexedYOperandBodyType *postIndexedYUnion;
preIndexedXOperandBodyType *preIndexedXUnion;
xIndexedOperandBodyType *xIndexedUnion;
yIndexedOperandBodyType *yIndexedUnion;
xSelectedOperandBodyType *xSelectedUnion;
ySelectedOperandBodyType *ySelectedUnion;
preSelectedOperandBodyType *preSelectedUnion;
stringOperandBodyType *stringUnion;
BlockOperandBodyType *blockUnion;
} operandBodyType;

81
operandBody_68000.h Normal file
View File

@ -0,0 +1,81 @@
/*
operandBody_68000.h -- Define parser tree types for 68000 operands.
Chip Morningstar -- Lucasfilm Ltd.
25-April-1985
*/
typedef expressionType expressionOperandBodyType;
typedef stringType stringOperandBodyType;
typedef BlockType blockOperandBodyType;
typedef nullType dRegisterOperandBodyType;
typedef nullType aRegisterOperandBodyType;
typedef nullType aRegisterIndirectOperandBodyType;
typedef nullType postincrementOperandBodyType;
typedef nullType predecrementOperandBodyType;
typedef expressionType displacementOperandBodyType;
typedef selectionListType selectedOperandBodyType;
typedef expressionType indexedOperandBodyType;
typedef selectionListType indexSelectedOperandBodyType;
typedef expressionType pcDisplacementOperandBodyType;
typedef expressionType pcIndexedOperandBodyType;
typedef expressionType immediateOperandBodyType;
typedef expressionType absoluteShortOperandBodyType;
typedef expressionType absoluteLongOperandBodyType;
typedef nullType ccRegisterOperandBodyType;
typedef nullType statusRegisterOperandBodyType;
typedef nullType uspRegisterOperandBodyType;
typedef nullType controlRegisterOperandBodyType;
#define BlockOperandBodyType anyOldThing /* kludge */
/* doing above right confuses compiler as it is a forward reference inside
yon union: */
typedef union {
expressionOperandBodyType *expressionUnion;
stringOperandBodyType *stringUnion;
BlockOperandBodyType *blockUnion;
dRegisterOperandBodyType *dRegisterUnion;
aRegisterOperandBodyType *aRegisterUnion;
aRegisterIndirectOperandBodyType *aRegisterIndirectUnion;
postincrementOperandBodyType *postincrementUnion;
predecrementOperandBodyType *predecrementUnion;
displacementOperandBodyType *displacementUnion;
selectedOperandBodyType *selectionUnion;
indexedOperandBodyType *indexedUnion;
indexSelectedOperandBodyType *indexSelectedUnion;
pcDisplacementOperandBodyType *pcDisplacementUnion;
pcIndexedOperandBodyType *pcIndexedUnion;
immediateOperandBodyType *immediateUnion;
absoluteShortOperandBodyType *absoluteShortUnion;
absoluteLongOperandBodyType *absoluteLongUnion;
ccRegisterOperandBodyType *ccRegisterUnion;
statusRegisterOperandBodyType *statusRegisterUnion;
uspRegisterOperandBodyType *uspRegisterUnion;
controlRegisterOperandBodyType *controlRegisterUnion;
} operandBodyType;
#define SFC_REGISTER 0
#define DFC_REGISTER 1
#define VBR_REGISTER 2

80
operandDefs_6502.h Normal file
View File

@ -0,0 +1,80 @@
/*
operandDefs_6502.h -- Define operand types and flag bits for 6502.
Chip Morningstar -- Lucasfilm Ltd.
18-April-1985
*/
typedef enum {
EXPRESSION_OPND, IMMEDIATE_OPND, INDIRECT_OPND,
A_REGISTER_OPND, X_REGISTER_OPND, Y_REGISTER_OPND,
POST_INDEXED_Y_OPND, PRE_INDEXED_X_OPND, X_INDEXED_OPND,
Y_INDEXED_OPND, X_SELECTED_OPND, Y_SELECTED_OPND,
PRE_SELECTED_X_OPND, STRING_OPND, BLOCK_OPND
} operandKindType;
#define operandKindField(op) op
/* Opcodes: */
/* In the opcode table we want to have information that tells which possible
address modes the corresponding instruction can utilize. The
instruction set of the 6502 breaks up into classes of instructions, such
that all of the instructions in a class accept the same address modes.
We encode the instructions by class and the classes by permissible address
modes. This helps us reduce errors in construction of the opcode table,
since getting one instruction of a given class right means getting all the
others right too. */
typedef enum {
RELATIVE, DIR_1, DIR_2, DIR_INDIR, DIR_X_1, DIR_X_2, DIR_X_3,
DIR_Y, IMM_DIR, IMM_DIR_X, IMM_DIR_Y, NONE, INDEX, IMM_INDEX
} addressClassType;
#define NO_OPND_BIT 0x0000
#define EXPRESSION_OPND_BIT 0x0001
#define IMMEDIATE_OPND_BIT 0x0002
#define INDIRECT_OPND_BIT 0x0004
#define A_REGISTER_OPND_BIT 0x0008
#define X_REGISTER_OPND_BIT 0x0010
#define Y_REGISTER_OPND_BIT 0x0020
#define POST_INDEXED_Y_OPND_BIT 0x0040
#define PRE_INDEXED_X_OPND_BIT 0x0080
#define X_INDEXED_OPND_BIT 0x0100
#define Y_INDEXED_OPND_BIT 0x0200
#define X_SELECTED_OPND_BIT 0x0400
#define Y_SELECTED_OPND_BIT 0x0800
#define PRE_SELECTED_X_OPND_BIT 0x1000
#define STRING_OPND_BIT 0x2000
#define BLOCK_OPND_BIT 0x4000
#define ANY_OPND_BITS 0xFFFF
#define REL_CLASS_BITS EXPRESSION_OPND_BIT
#define DIR_1_CLASS_BITS EXPRESSION_OPND_BIT
#define DIR_2_CLASS_BITS EXPRESSION_OPND_BIT
#define DIR_INDIR_CLASS_BITS EXPRESSION_OPND_BIT | INDIRECT_OPND_BIT
#define DIR_X_1_CLASS_BITS EXPRESSION_OPND_BIT | X_INDEXED_OPND_BIT | \
X_SELECTED_OPND_BIT | A_REGISTER_OPND_BIT
#define DIR_X_2_CLASS_BITS EXPRESSION_OPND_BIT | X_INDEXED_OPND_BIT | \
X_SELECTED_OPND_BIT
#define DIR_X_3_CLASS_BITS EXPRESSION_OPND_BIT | X_INDEXED_OPND_BIT | \
X_SELECTED_OPND_BIT
#define DIR_Y_CLASS_BITS EXPRESSION_OPND_BIT | Y_INDEXED_OPND_BIT | \
Y_SELECTED_OPND_BIT
#define IMM_DIR_CLASS_BITS EXPRESSION_OPND_BIT | IMMEDIATE_OPND_BIT
#define IMM_DIR_X_CLASS_BITS EXPRESSION_OPND_BIT | IMMEDIATE_OPND_BIT | \
X_INDEXED_OPND_BIT | X_SELECTED_OPND_BIT
#define IMM_DIR_Y_CLASS_BITS EXPRESSION_OPND_BIT | IMMEDIATE_OPND_BIT | \
Y_INDEXED_OPND_BIT | Y_SELECTED_OPND_BIT
#define NONE_CLASS_BITS NO_OPND_BIT
#define IMM_INDEX_CLASS_BITS X_INDEXED_OPND_BIT | Y_INDEXED_OPND_BIT | \
X_SELECTED_OPND_BIT | Y_SELECTED_OPND_BIT | \
IMMEDIATE_OPND_BIT | PRE_INDEXED_X_OPND_BIT |\
POST_INDEXED_Y_OPND_BIT | \
EXPRESSION_OPND_BIT | PRE_SELECTED_X_OPND_BIT
#define INDEX_CLASS_BITS X_INDEXED_OPND_BIT | Y_INDEXED_OPND_BIT | \
X_SELECTED_OPND_BIT | Y_SELECTED_OPND_BIT | \
PRE_INDEXED_X_OPND_BIT | \
POST_INDEXED_Y_OPND_BIT | \
EXPRESSION_OPND_BIT | PRE_SELECTED_X_OPND_BIT
#define MAX_NUMBER_OF_OPERANDS 1

279
operandDefs_68000.h Normal file
View File

@ -0,0 +1,279 @@
/*
operandDefs_68000.h -- Define operand types and flag bits for 68000.
Chip Morningstar -- Lucasfilm Ltd.
25-April-1985
*/
typedef enum {
EXPRESSION_OPND, STRING_OPND, BLOCK_OPND, D_REGISTER_OPND,
A_REGISTER_OPND, A_REGISTER_INDIRECT_OPND, POSTINCREMENT_OPND,
PREDECREMENT_OPND, DISPLACEMENT_OPND, INDEXED_OPND,
PC_DISPLACEMENT_OPND, PC_INDEXED_OPND, IMMEDIATE_OPND,
ABSOLUTE_SHORT_OPND, ABSOLUTE_LONG_OPND, CC_REGISTER_OPND,
STATUS_REGISTER_OPND, USP_REGISTER_OPND,
CONTROL_REGISTER_OPND, SELECTED_OPND, INDEX_SELECTED_OPND,
} operandKindType;
/*** Hack warning ***/
/* We know that enumerated types are actually just ints. Some of the address
modes require some additional information in the form of one or two
register numbers. We want to still encode this information in one int.
Therefor, we are going to OR some bits representing the register into the
higher-order bits of the type word, thus violating the principle of
enumerated types (it's just that the 'enum' syntax above is so much cleaner
than a bunch of '#define's) */
#define getRegisterField(op, n) ((((int)op)>>(8+(n-1)*4)) & 0xF)
#define setRegisterField(op, n, r) (op=((int)op | \
(((r)&0xF)<<(8+((n)-1)*4))))
#define getAddressRegister(op) (getRegisterField(op, 1) - 8)
#define getDataRegister(op) getRegisterField(op, 1)
#define getRegister(op) getRegisterField(op, 1)
#define getIndexRegister(op) getRegisterField(op, 2)
#define getWL(op) (((int)op >> 16) & 1)
#define setAddressRegister(op, r) setRegisterField(op, 1, (int)r + 8)
#define setDataRegister(op, r) setRegisterField(op, 1, (int)r)
#define setRegister(op, r) setRegisterField(op, 1, (int)r)
#define setIndexRegister(op, r) setRegisterField(op, 2, (int)r)
#define setWL(op, wl) (op = ((int)op | (((wl) & 1) << 16)))
#define operandKindField(op) (operandKindType)((int)op & 0xFF)
/* Opcodes: */
/* In the opcode table we want to have information that tells which possible
address modes the corresponding instruction can utilize. The
instruction set of the 68000 breaks up into classes of instructions, such
that all of the instructions in a class accept the same address modes.
We encode the instructions by class and the classes by permissible address
modes. This helps us reduce errors in construction of the opcode table,
since getting one instruction of a given class right means getting all the
others right too. Ordinarily we'd give each class a nice mnemonic name,
but the 68000 has 26 idiosyncratic classes and a unique name for each
would confuse more than it would help. */
typedef enum {
CLASS_I, CLASS_II, CLASS_III, CLASS_IV, CLASS_V, CLASS_VI,
CLASS_VII, CLASS_VIII, CLASS_IX, CLASS_X, CLASS_XI, CLASS_XII,
CLASS_XIII, CLASS_XIV, CLASS_XV, CLASS_XVI, CLASS_XVII,
CLASS_XVIII, CLASS_XIX, CLASS_XX, CLASS_XXI, CLASS_XXII,
CLASS_XXIII, CLASS_XXIV, CLASS_XXV, CLASS_XXVI, CLASS_XXVII,
CLASS_XXVIII,
} addressClassType;
/* The various address modes as required by the various instructions manage to
sort themselves into a number of independent groups. We will give these
groups names to facilitate operand address mode checking */
#define NO_OPND_BIT 0x000000
#define EXPRESSION_OPND_BIT 0x000001
#define STRING_OPND_BIT 0x000002
#define BLOCK_OPND_BIT 0x000004
#define D_REGISTER_OPND_BIT 0x000008
#define A_REGISTER_OPND_BIT 0x000010
#define A_REGISTER_INDIRECT_OPND_BIT 0x000020
#define POSTINCREMENT_OPND_BIT 0x000040
#define PREDECREMENT_OPND_BIT 0x000080
#define DISPLACEMENT_OPND_BIT 0x000100
#define INDEXED_OPND_BIT 0x000200
#define PC_DISPLACEMENT_OPND_BIT 0x000400
#define PC_INDEXED_OPND_BIT 0x000800
#define IMMEDIATE_OPND_BIT 0x001000
#define ABSOLUTE_SHORT_OPND_BIT 0x002000
#define ABSOLUTE_LONG_OPND_BIT 0x004000
#define CC_REGISTER_OPND_BIT 0x008000
#define STATUS_REGISTER_OPND_BIT 0x010000
#define USP_REGISTER_OPND_BIT 0x020000
#define CONTROL_REGISTER_OPND_BIT 0x040000
#define SELECTED_OPND_BIT 0x080000
#define INDEX_SELECTED_OPND_BIT 0x100000
#define ANY_OPND_BITS 0xFFFFFF
#define D_REGISTER_GROUP_BITS D_REGISTER_OPND_BIT
#define GROUP_A D_REGISTER_GROUP_BITS
#define A_REGISTER_GROUP_BITS A_REGISTER_OPND_BIT
#define GROUP_B A_REGISTER_GROUP_BITS
#define POSTINCREMENT_GROUP_BITS POSTINCREMENT_OPND_BIT
#define GROUP_C POSTINCREMENT_GROUP_BITS
#define PREDECREMENT_GROUP_BITS PREDECREMENT_OPND_BIT
#define GROUP_D PREDECREMENT_GROUP_BITS
#define DISPLACEMENT_GROUP_BITS (DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT)
#define GROUP_E DISPLACEMENT_GROUP_BITS
#define IMMEDIATE_GROUP_BITS IMMEDIATE_OPND_BIT
#define GROUP_F IMMEDIATE_GROUP_BITS
#define NORMAL_GROUP_BITS EXPRESSION_OPND_BIT
#define GROUP_G NORMAL_GROUP_BITS
#define CC_REGISTER_GROUP_BITS CC_REGISTER_OPND_BIT
#define GROUP_H CC_REGISTER_GROUP_BITS
#define STATUS_REGISTER_GROUP_BITS STATUS_REGISTER_OPND_BIT
#define GROUP_I STATUS_REGISTER_GROUP_BITS
#define IMPLIED_GROUP_BITS NO_OPND_BIT
#define GROUP_J IMPLIED_GROUP_BITS
#define USP_REGISTER_GROUP_BITS USP_REGISTER_OPND_BIT
#define GROUP_K USP_REGISTER_GROUP_BITS
#define CONTROL_REGISTER_GROUP_BITS (USP_REGISTER_OPND_BIT | \
CONTROL_REGISTER_OPND_BIT)
#define GROUP_L CONTROL_REGISTER_GROUP_BITS
#define REGISTER_GROUP_BITS (D_REGISTER_OPND_BIT | \
A_REGISTER_OPND_BIT)
#define GROUP_M REGISTER_GROUP_BITS
#define STORABLE_GROUP_BITS (D_REGISTER_OPND_BIT | \
A_REGISTER_OPND_BIT | \
A_REGISTER_INDIRECT_OPND_BIT | \
POSTINCREMENT_OPND_BIT | \
PREDECREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_N STORABLE_GROUP_BITS
#define FULL_EA_GROUP_BITS (D_REGISTER_OPND_BIT | \
A_REGISTER_OPND_BIT | \
A_REGISTER_INDIRECT_OPND_BIT | \
POSTINCREMENT_OPND_BIT | \
PREDECREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
PC_DISPLACEMENT_OPND_BIT | \
PC_INDEXED_OPND_BIT | \
IMMEDIATE_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_O FULL_EA_GROUP_BITS
#define STORABLE_NO_A_REGISTER_GROUP_BITS \
(D_REGISTER_OPND_BIT | \
A_REGISTER_INDIRECT_OPND_BIT | \
POSTINCREMENT_OPND_BIT | \
PREDECREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_P STORABLE_NO_A_REGISTER_GROUP_BITS
#define FULL_EA_NO_A_REGISTER_GROUP_BITS (D_REGISTER_OPND_BIT | \
A_REGISTER_INDIRECT_OPND_BIT | \
POSTINCREMENT_OPND_BIT | \
PREDECREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
PC_DISPLACEMENT_OPND_BIT | \
PC_INDEXED_OPND_BIT | \
IMMEDIATE_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_Q FULL_EA_NO_A_REGISTER_GROUP_BITS
#define MISC_1_GROUP_BITS (A_REGISTER_INDIRECT_OPND_BIT | \
POSTINCREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
PC_DISPLACEMENT_OPND_BIT | \
PC_INDEXED_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_R MISC_1_GROUP_BITS
#define STORABLE_NO_REGISTER_GROUP_BITS (A_REGISTER_INDIRECT_OPND_BIT | \
POSTINCREMENT_OPND_BIT | \
PREDECREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_S STORABLE_NO_REGISTER_GROUP_BITS
#define MISC_2_GROUP_BITS (A_REGISTER_INDIRECT_OPND_BIT | \
PREDECREMENT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_T MISC_2_GROUP_BITS
#define MISC_3_GROUP_BITS (A_REGISTER_INDIRECT_OPND_BIT | \
DISPLACEMENT_OPND_BIT | \
SELECTED_OPND_BIT | \
INDEXED_OPND_BIT | \
INDEX_SELECTED_OPND_BIT | \
PC_DISPLACEMENT_OPND_BIT | \
PC_INDEXED_OPND_BIT | \
ABSOLUTE_SHORT_OPND_BIT | \
ABSOLUTE_LONG_OPND_BIT | \
EXPRESSION_OPND_BIT)
#define GROUP_U MISC_3_GROUP_BITS
#define CLASS_I_BITS (GROUP_A | GROUP_D)
#define CLASS_II_BITS (GROUP_A | GROUP_B | GROUP_F | GROUP_O | \
GROUP_P | GROUP_S)
#define CLASS_III_BITS (GROUP_F | GROUP_N)
#define CLASS_IV_BITS (GROUP_A | GROUP_F | GROUP_H | GROUP_I | \
GROUP_P | GROUP_Q | GROUP_S)
#define CLASS_V_BITS (GROUP_A | GROUP_F | GROUP_S)
#define CLASS_VI_BITS GROUP_G
#define CLASS_VII_BITS (GROUP_A | GROUP_F | GROUP_P)
#define CLASS_VIII_BITS (GROUP_A | GROUP_Q)
#define CLASS_IX_BITS GROUP_P
#define CLASS_X_BITS (GROUP_A | GROUP_B | GROUP_F | GROUP_O | GROUP_P)
#define CLASS_XI_BITS GROUP_C
#define CLASS_XII_BITS (GROUP_A | GROUP_G)
#define CLASS_XIII_BITS (GROUP_A | GROUP_F | GROUP_H | GROUP_I | GROUP_P)
#define CLASS_XIV_BITS GROUP_M
#define CLASS_XV_BITS GROUP_A
#define CLASS_XVI_BITS GROUP_J
#define CLASS_XVII_BITS GROUP_U
#define CLASS_XVIII_BITS (GROUP_B | GROUP_U)
#define CLASS_XIX_BITS (GROUP_B | GROUP_F)
#define CLASS_XX_BITS (GROUP_B | GROUP_H | GROUP_I | GROUP_K | \
GROUP_L | GROUP_M | GROUP_O | GROUP_Q)
#define CLASS_XXI_BITS (GROUP_M | GROUP_R | GROUP_T)
#define CLASS_XXII_BITS (GROUP_A | GROUP_E)
#define CLASS_XXIII_BITS (GROUP_A | GROUP_F)
#define CLASS_XXIV_BITS (GROUP_M | GROUP_S)
#define CLASS_XXV_BITS GROUP_F
#define CLASS_XXVI_BITS GROUP_B
#define CLASS_XXVII_BITS GROUP_F
#define CLASS_XXVIII_BITS GROUP_F
#define MAX_NUMBER_OF_OPERANDS 17

BIN
operandStuffSD.o Normal file

Binary file not shown.

389
operandStuffSD_6502.c Normal file
View File

@ -0,0 +1,389 @@
/*
operandStuff_6502.c -- Various target processor routines to handle
operands in the Macross assembler (6502 version).
Chip Morningstar -- Lucasfilm Ltd.
23-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/* corresponds to routines in buildStuff2.c */
operandType *
buildOperand(kindOfOperand, arg)
operandKindType kindOfOperand;
anyOldThing *arg;
{
operandType *result;
result = typeAlloc(operandType);
result->kindOfOperand = kindOfOperand;
result->nextOperand = NULL;
switch (kindOfOperand) {
case EXPRESSION_OPND:
result->theOperand.expressionUnion =
(expressionOperandBodyType *) arg;
break;
case IMMEDIATE_OPND:
result->theOperand.immediateUnion =
(immediateOperandBodyType *) arg;
break;
case INDIRECT_OPND:
result->theOperand.indirectUnion =
(indirectOperandBodyType *) arg;
break;
case A_REGISTER_OPND:
result->theOperand.aRegisterUnion =
(aRegisterOperandBodyType *) NULL;
break;
case X_REGISTER_OPND:
result->theOperand.xRegisterUnion =
(xRegisterOperandBodyType *) NULL;
break;
case Y_REGISTER_OPND:
result->theOperand.yRegisterUnion =
(yRegisterOperandBodyType *) NULL;
break;
case POST_INDEXED_Y_OPND:
result->theOperand.postIndexedYUnion =
(postIndexedYOperandBodyType *) arg;
break;
case PRE_INDEXED_X_OPND:
result->theOperand.preIndexedXUnion =
(preIndexedXOperandBodyType *) arg;
break;
case X_INDEXED_OPND:
result->theOperand.xIndexedUnion =
(xIndexedOperandBodyType *) arg;
break;
case Y_INDEXED_OPND:
result->theOperand.yIndexedUnion =
(yIndexedOperandBodyType *) arg;
break;
case X_SELECTED_OPND:
result->theOperand.xSelectedUnion =
(xSelectedOperandBodyType *) arg;
break;
case Y_SELECTED_OPND:
result->theOperand.ySelectedUnion =
(ySelectedOperandBodyType *) arg;
break;
case PRE_SELECTED_X_OPND:
result->theOperand.preSelectedUnion =
(preSelectedOperandBodyType *) arg;
break;
case STRING_OPND:
result->theOperand.stringUnion =
(stringOperandBodyType *) arg;
break;
case BLOCK_OPND:
result->theOperand.blockUnion = (BlockOperandBodyType *) arg;
break;
default:
botch("unknown operand kind: %d\n", kindOfOperand);
break;
}
return(result);
}
/* corresponds to routines in fixups.c */
operandListType *
duplicateOperandForFixup(operand, isSpecialFunctionOperand)
operandListType *operand;
bool isSpecialFunctionOperand;
{
operandListType *result;
expressionType *duplicateExpressionForFixup();
result = typeAlloc(operandListType);
result->kindOfOperand = operand->kindOfOperand;
result->nextOperand = NULL;
if (operand->kindOfOperand != EXPRESSION_OPND)
newFixupAddressMode = operand->kindOfOperand;
switch (operand->kindOfOperand) {
case EXPRESSION_OPND:
case IMMEDIATE_OPND:
case INDIRECT_OPND:
case POST_INDEXED_Y_OPND:
case PRE_INDEXED_X_OPND:
case X_INDEXED_OPND:
case Y_INDEXED_OPND:
result->theOperand.expressionUnion =
duplicateExpressionForFixup(operand->theOperand,
FALSE, isSpecialFunctionOperand);
break;
case X_SELECTED_OPND:
case Y_SELECTED_OPND:
case PRE_SELECTED_X_OPND:
result->theOperand.expressionUnion =
duplicateExpressionForFixup(operand->theOperand,
FALSE, isSpecialFunctionOperand);
break;
case A_REGISTER_OPND:
case X_REGISTER_OPND:
case Y_REGISTER_OPND:
result->theOperand = operand->theOperand;
break;
case STRING_OPND:
result->theOperand = operand->theOperand;
break;
case BLOCK_OPND:
error(CANT_FORWARD_REFERENCE_BLOCK_ERROR);
result = NULL;
break;
}
return(result);
}
/* corresponds to routines in garbage.c */
#define nullFree(thing) if (thing == NULL) return;
void
freeOperand(operand)
operandType *operand;
{
nullFree(operand);
switch (operand->kindOfOperand) {
case EXPRESSION_OPND:
case IMMEDIATE_OPND:
case INDIRECT_OPND:
case POST_INDEXED_Y_OPND:
case PRE_INDEXED_X_OPND:
case X_INDEXED_OPND:
case Y_INDEXED_OPND:
freeExpression(operand->theOperand);
break;
case A_REGISTER_OPND:
case X_REGISTER_OPND:
case Y_REGISTER_OPND:
break;
case X_SELECTED_OPND:
case Y_SELECTED_OPND:
case PRE_SELECTED_X_OPND:
freeSelectionList(operand->theOperand);
break;
case STRING_OPND:
freeString(operand->theOperand);
break;
case BLOCK_OPND:
freeBlock(operand->theOperand);
break;
default:
botch("bad operand kind in freeOperand %d\n",
operand->kindOfOperand);
break;
}
freeOperand(operand->nextOperand);
free(operand);
}
/* corresponds to routines in listing.c */
void
expandOperand(addressMode)
operandKindType addressMode;
{
switch (addressMode) {
case IMMEDIATE_OPND: moreText("#"); break;
case INDIRECT_OPND: moreText("@"); break;
case POST_INDEXED_Y_OPND: moreText("y[@"); break;
case PRE_INDEXED_X_OPND: moreText("@x["); break;
case X_INDEXED_OPND: moreText("x["); break;
case Y_INDEXED_OPND: moreText("y["); break;
case A_REGISTER_OPND: moreText("a"); break;
case X_REGISTER_OPND: moreText("x"); break;
case Y_REGISTER_OPND: moreText("y"); break;
case X_SELECTED_OPND: moreText("x"); break;
case Y_SELECTED_OPND: moreText("y"); break;
case PRE_SELECTED_X_OPND: moreText("@x"); break;
default: break;
}
expandExpression(NULL);
if (addressMode == POST_INDEXED_Y_OPND ||
addressMode == PRE_INDEXED_X_OPND ||
addressMode == X_INDEXED_OPND ||
addressMode == Y_INDEXED_OPND)
moreText("]");
}
/* corresponds to routines in expressionSemantics.c */
#define nullEvaluate(thing) if (thing==NULL) return(NULL);
#define fail(err) if (!expressionFailed) {\
error(err);\
expressionFailed = TRUE;\
}
#define fail1(err,arg) if (!expressionFailed) {\
error(err,arg);\
expressionFailed = TRUE;\
}
#define fail2(err,arg1,arg2) if (!expressionFailed) {\
error(err,arg1,arg2);\
expressionFailed = TRUE;\
}
#define qfree2(a,b) if (freeFlag) { free(a); free(b); }
#define expansionOff() {saveExpansion=expandMacros; expandMacros=FALSE;}
#define forceExpansion() {saveExpansion=expandMacros; expandMacros=TRUE;}
#define expansionOn() expandMacros=saveExpansion;
valueType *
evaluateOperand(operand)
operandType *operand;
{
valueType *result;
bool saveExpansion;
expressionType *expression;
valueType *evaluateExpression();
valueType *evaluateSelectionList();
valueType *newValue();
nullEvaluate(operand);
if (operand->kindOfOperand != EXPRESSION_OPND)
newFixupAddressMode = operand->kindOfOperand;
switch (operand->kindOfOperand) {
case EXPRESSION_OPND:
case IMMEDIATE_OPND:
case INDIRECT_OPND:
case POST_INDEXED_Y_OPND:
case PRE_INDEXED_X_OPND:
case X_INDEXED_OPND:
case Y_INDEXED_OPND:
result = evaluateExpression(operand->theOperand,
performingFixups ? NO_FIXUP : OPERAND_FIXUP);
if (operand->kindOfOperand != EXPRESSION_OPND) {
if (result->addressMode != EXPRESSION_OPND) {
error(BAD_ADDRESS_MODE_ERROR);
result->kindOfValue = FAIL;
} else {
result->addressMode = operand->kindOfOperand;
}
}
break;
case A_REGISTER_OPND:
case X_REGISTER_OPND:
case Y_REGISTER_OPND:
result = newValue(UNDEFINED_VALUE, 0, operand->
kindOfOperand);
break;
case X_SELECTED_OPND:
case Y_SELECTED_OPND:
case PRE_SELECTED_X_OPND:
result = evaluateSelectionList(operand->theOperand);
if (result->addressMode != EXPRESSION_OPND) {
error(BAD_ADDRESS_MODE_ERROR);
result->kindOfValue = FAIL;
} else {
result->addressMode = operand->kindOfOperand;
}
break;
case STRING_OPND:
result = newValue(STRING_VALUE, operand->theOperand,
STRING_OPND);
break;
case BLOCK_OPND:
if (standaloneExpansionFlag)
forceExpansion();
sideEffectFlag = TRUE;
assembleBlock(operand->theOperand);
expansionOn();
result = newValue(FAIL, 0, BLOCK_OPND);
break;
default:
botch("bad operand kind in evaluateOperand %d\n",
operand->kindOfOperand);
break;
}
return(result);
}
/* from parserMisc.c */
conditionType
invertConditionCode(conditionCode)
conditionType conditionCode;
{
#define cc (int)conditionCode
if ((int)CARRY_COND<=cc && cc<=(int)ALWAYS_COND)
return((conditionType)
(cc - (int)CARRY_COND + (int)NOT_CARRY_COND));
else if ((int)NOT_CARRY_COND<=cc && cc<=(int)NEVER_COND)
return((conditionType)
(cc + (int)CARRY_COND - (int)NOT_CARRY_COND));
else
botch("invertConditionCode given %d, not a condition code\n");
}
/* from semanticMisc.c */
bool
shouldParenthesize(operand)
operandType *operand;
{
expressionTermKindType kind;
switch(operand->kindOfOperand) {
case EXPRESSION_OPND:
case IMMEDIATE_OPND:
case INDIRECT_OPND:
case POST_INDEXED_Y_OPND:
case PRE_INDEXED_X_OPND:
case X_INDEXED_OPND:
case Y_INDEXED_OPND:
kind = operand->theOperand.expressionUnion->kindOfTerm;
return (kind==UNOP_EXPR || kind==BINOP_EXPR || kind==
ASSIGN_EXPR);
break;
case X_SELECTED_OPND:
case Y_SELECTED_OPND:
case PRE_SELECTED_X_OPND:
return(TRUE);
break;
case A_REGISTER_OPND:
case X_REGISTER_OPND:
case Y_REGISTER_OPND:
case STRING_OPND:
case BLOCK_OPND:
return(FALSE);
break;
}
}

559
operandStuffSD_68000.c Normal file
View File

@ -0,0 +1,559 @@
/*
operandStuff_68000.c -- Various target processor routines to handle
operands in the Macross assembler (68000 version).
Chip Morningstar -- Lucasfilm Ltd.
26-April-1985
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
/* corresponds to routines in buildStuff2.c */
operandType *
buildOperand(kindOfOperand, arg1, arg2, arg3, arg4)
operandKindType kindOfOperand;
int arg1;
int arg2;
int arg3;
int arg4;
{
operandType *result;
result = typeAlloc(operandType);
result->kindOfOperand = kindOfOperand;
result->nextOperand = NULL;
switch (kindOfOperand) {
case EXPRESSION_OPND:
result->theOperand.expressionUnion =
(expressionOperandBodyType *) arg1;
break;
case STRING_OPND:
result->theOperand.stringUnion =
(stringOperandBodyType *) arg1;
break;
case BLOCK_OPND:
result->theOperand.blockUnion = (BlockOperandBodyType *) arg1;
break;
case D_REGISTER_OPND:
result->theOperand.dRegisterUnion =
(dRegisterOperandBodyType *) NULL;
setRegister(result->kindOfOperand, arg1);
break;
case A_REGISTER_OPND:
result->theOperand.aRegisterUnion =
(aRegisterOperandBodyType *) NULL;
setRegister(result->kindOfOperand, arg1);
break;
case A_REGISTER_INDIRECT_OPND:
result->theOperand.aRegisterIndirectUnion =
(aRegisterIndirectOperandBodyType *) NULL;
setRegister(result->kindOfOperand, arg1);
break;
case POSTINCREMENT_OPND:
result->theOperand.postincrementUnion =
(postincrementOperandBodyType *) NULL;
setRegister(result->kindOfOperand, arg1);
break;
case PREDECREMENT_OPND:
result->theOperand.predecrementUnion =
(predecrementOperandBodyType *) NULL;
setRegister(result->kindOfOperand, arg1);
break;
case DISPLACEMENT_OPND:
result->theOperand.displacementUnion =
(displacementOperandBodyType *) arg2;
setRegister(result->kindOfOperand, arg1);
break;
case SELECTED_OPND:
result->theOperand.selectionUnion =
(selectedOperandBodyType *) arg2;
setRegister(result->kindOfOperand, arg1);
break;
case INDEXED_OPND:
result->theOperand.indexedUnion =
(indexedOperandBodyType *) arg1;
setRegister(result->kindOfOperand, arg2);
setIndexRegister(result->kindOfOperand, arg3);
setWL(result->kindOfOperand, (int)arg4);
break;
case INDEX_SELECTED_OPND:
result->theOperand.indexSelectedUnion =
(indexSelectedOperandBodyType *) arg1;
setRegister(result->kindOfOperand, arg2);
setIndexRegister(result->kindOfOperand, arg3);
setWL(result->kindOfOperand, (int)arg4);
break;
case PC_DISPLACEMENT_OPND:
result->theOperand.pcDisplacementUnion =
(pcDisplacementOperandBodyType *) arg1;
break;
case PC_INDEXED_OPND:
result->theOperand.pcIndexedUnion =
(pcIndexedOperandBodyType *) arg1;
setIndexRegister(result->kindOfOperand, arg2);
setWL(result->kindOfOperand, (int)arg3);
break;
case IMMEDIATE_OPND:
result->theOperand.immediateUnion =
(immediateOperandBodyType *) arg1;
break;
case ABSOLUTE_SHORT_OPND:
result->theOperand.absoluteShortUnion =
(absoluteShortOperandBodyType *) arg1;
break;
case ABSOLUTE_LONG_OPND:
result->theOperand.absoluteLongUnion =
(absoluteLongOperandBodyType *) arg1;
break;
case CC_REGISTER_OPND:
result->theOperand.ccRegisterUnion =
(ccRegisterOperandBodyType *) NULL;
break;
case STATUS_REGISTER_OPND:
result->theOperand.statusRegisterUnion =
(statusRegisterOperandBodyType *) NULL;
break;
case USP_REGISTER_OPND:
result->theOperand.uspRegisterUnion =
(uspRegisterOperandBodyType *) NULL;
break;
case CONTROL_REGISTER_OPND:
result->theOperand.controlRegisterUnion =
(controlRegisterOperandBodyType *) NULL;
setRegister(result->kindOfOperand, arg1);
break;
default:
botch("unknown operand kind: %d\n", kindOfOperand);
break;
}
return(result);
}
/* corresponds to routines in fixups.c */
operandListType *
duplicateOperandForFixup(operand, isSpecialFunctionOperand)
operandListType *operand;
bool isSpecialFunctionOperand;
{
operandListType *result;
expressionType *duplicateExpressionForFixup();
result = typeAlloc(operandListType);
result->kindOfOperand = operand->kindOfOperand;
result->nextOperand = NULL;
if (operand->kindOfOperand != EXPRESSION_OPND)
newFixupAddressMode = operand->kindOfOperand;
switch (operandKindField(operand->kindOfOperand)) {
case EXPRESSION_OPND:
case DISPLACEMENT_OPND:
case SELECTED_OPND:
case INDEXED_OPND:
case INDEX_SELECTED_OPND:
case PC_DISPLACEMENT_OPND:
case PC_INDEXED_OPND:
case IMMEDIATE_OPND:
case ABSOLUTE_SHORT_OPND:
case ABSOLUTE_LONG_OPND:
result->theOperand.expressionUnion =
duplicateExpressionForFixup(operand->theOperand,
FALSE, isSpecialFunctionOperand);
break;
case D_REGISTER_OPND:
case A_REGISTER_OPND:
case A_REGISTER_INDIRECT_OPND:
case POSTINCREMENT_OPND:
case PREDECREMENT_OPND:
case CC_REGISTER_OPND:
case STATUS_REGISTER_OPND:
case USP_REGISTER_OPND:
case CONTROL_REGISTER_OPND:
result->theOperand = operand->theOperand;
break;
case STRING_OPND:
result->theOperand = operand->theOperand;
break;
case BLOCK_OPND:
error(CANT_FORWARD_REFERENCE_BLOCK_ERROR);
result = NULL;
break;
}
return(result);
}
/* corresponds to routines in garbage.c */
#define nullFree(thing) if (thing == NULL) return;
void
freeOperand(operand)
operandType *operand;
{
nullFree(operand);
switch (operandKindField(operand->kindOfOperand)) {
case EXPRESSION_OPND:
case DISPLACEMENT_OPND:
case INDEXED_OPND:
case PC_DISPLACEMENT_OPND:
case PC_INDEXED_OPND:
case IMMEDIATE_OPND:
case ABSOLUTE_SHORT_OPND:
case ABSOLUTE_LONG_OPND:
freeExpression(operand->theOperand);
break;
case D_REGISTER_OPND:
case A_REGISTER_OPND:
case A_REGISTER_INDIRECT_OPND:
case POSTINCREMENT_OPND:
case PREDECREMENT_OPND:
case CC_REGISTER_OPND:
case STATUS_REGISTER_OPND:
case USP_REGISTER_OPND:
case CONTROL_REGISTER_OPND:
break;
case SELECTED_OPND:
case INDEX_SELECTED_OPND:
freeSelectionList(operand->theOperand);
break;
case STRING_OPND:
freeString(operand->theOperand);
break;
case BLOCK_OPND:
freeBlock(operand->theOperand);
break;
default:
botch("bad operand kind in freeOperand %d\n",
operand->kindOfOperand);
break;
}
freeOperand(operand->nextOperand);
free(operand);
}
/* corresponds to routines in listing.c */
void
expandOperand(addressMode, buffer)
operandKindType addressMode;
char *buffer;
{
char *bufferPtr;
bufferPtr = buffer;
switch (operandKindField(addressMode)) {
case D_REGISTER_OPND:
moreTextOptional(buffer, &bufferPtr, "d");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
break;
case A_REGISTER_OPND:
moreTextOptional(buffer, &bufferPtr, "a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
break;
case A_REGISTER_INDIRECT_OPND:
moreTextOptional(buffer, &bufferPtr, "[a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
moreTextOptional(buffer, &bufferPtr, "]");
break;
case POSTINCREMENT_OPND:
moreTextOptional(buffer, &bufferPtr, "[a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
moreTextOptional(buffer, &bufferPtr, "]+");
break;
case PREDECREMENT_OPND:
moreTextOptional(buffer, &bufferPtr, "-[a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
moreTextOptional(buffer, &bufferPtr, "]");
break;
case IMMEDIATE_OPND:
moreTextOptional(buffer, &bufferPtr, "#");
break;
case CC_REGISTER_OPND:
moreTextOptional(buffer, &bufferPtr, "ccr");
break;
case STATUS_REGISTER_OPND:
moreTextOptional(buffer, &bufferPtr, "sr");
break;
case USP_REGISTER_OPND:
moreTextOptional(buffer, &bufferPtr, "usp");
break;
case CONTROL_REGISTER_OPND:
if (getRegister(addressMode) == 1)
moreTextOptional(buffer, &bufferPtr, "sfc");
else if (getRegister(addressMode) == 2)
moreTextOptional(buffer, &bufferPtr, "dfc");
else
moreTextOptional(buffer, &bufferPtr, "vbr");
break;
case SELECTED_OPND:
moreTextOptional(buffer, &bufferPtr, "a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
break;
case INDEX_SELECTED_OPND:
moreTextOptional(buffer, &bufferPtr, "a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
if (getIndexRegister(addressMode)<8) {
moreTextOptional(buffer, &bufferPtr, "[a");
expandNum(buffer, &bufferPtr,
getIndexRegister(addressMode));
} else {
moreTextOptional(buffer, &bufferPtr, "[d");
expandNum(buffer, &bufferPtr,
getIndexRegister(addressMode)-8);
}
moreTextOptional(buffer, &bufferPtr, "]");
break;
default:
break;
}
expandExpression(buffer, &bufferPtr);
switch(operandKindField(addressMode)) {
case DISPLACEMENT_OPND:
moreTextOptional(buffer, &bufferPtr, "[a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
moreTextOptional(buffer, &bufferPtr, "]");
break;
case INDEXED_OPND:
moreTextOptional(buffer, &bufferPtr, "[a");
expandNum(buffer, &bufferPtr, getRegister(addressMode));
moreTextOptional(buffer, &bufferPtr, ",");
if (getIndexRegister(addressMode)<8) {
moreTextOptional(buffer, &bufferPtr, "a");
expandNum(buffer, &bufferPtr,
getIndexRegister(addressMode));
} else {
moreTextOptional(buffer, &bufferPtr, "d");
expandNum(buffer, &bufferPtr,
getIndexRegister(addressMode)-8);
}
moreTextOptional(buffer, &bufferPtr, ".");
if (getWL(addressMode))
moreTextOptional(buffer, &bufferPtr, "l]");
else
moreTextOptional(buffer, &bufferPtr, "w]");
break;
case PC_DISPLACEMENT_OPND:
moreTextOptional(buffer, &bufferPtr, "[pc]");
break;
case PC_INDEXED_OPND:
moreTextOptional(buffer, &bufferPtr, "[pc,");
if (getIndexRegister(addressMode)<8) {
moreTextOptional(buffer, &bufferPtr, "a");
expandNum(buffer, &bufferPtr,
getIndexRegister(addressMode));
} else {
moreTextOptional(buffer, &bufferPtr, "d");
expandNum(buffer, &bufferPtr,
getIndexRegister(addressMode)-8);
}
moreTextOptional(buffer, &bufferPtr, ".");
if (getWL(addressMode))
moreTextOptional(buffer, &bufferPtr, "l]");
else
moreTextOptional(buffer, &bufferPtr, "w]");
break;
case ABSOLUTE_SHORT_OPND:
moreTextOptional(buffer, &bufferPtr, ".w");
break;
case ABSOLUTE_LONG_OPND:
moreTextOptional(buffer, &bufferPtr, ".l");
break;
default:
break;
}
}
/* corresponds to routines in expressionSemantics.c */
#define nullEvaluate(thing) if (thing==NULL) return(NULL);
#define fail(err) if (!expressionFailed) {\
error(err);\
expressionFailed = TRUE;\
}
#define fail1(err,arg) if (!expressionFailed) {\
error(err,arg);\
expressionFailed = TRUE;\
}
#define fail2(err,arg1,arg2) if (!expressionFailed) {\
error(err,arg1,arg2);\
expressionFailed = TRUE;\
}
#define qfree2(a,b) if (freeFlag) { free(a); free(b); }
#define expansionOff() {saveExpansion=expandMacros; expandMacros=FALSE;}
#define forceExpansion() {saveExpansion=expandMacros; expandMacros=TRUE;}
#define expansionOn() expandMacros=saveExpansion;
valueType *
evaluateOperand(operand)
operandType *operand;
{
valueType *result;
bool saveExpansion;
expressionType *expression;
valueType *evaluateExpression();
valueType *evaluateSelectionList();
valueType *newValue();
nullEvaluate(operand);
if (operand->kindOfOperand != EXPRESSION_OPND)
newFixupAddressMode = operand->kindOfOperand;
switch (operandKindField(operand->kindOfOperand)) {
case EXPRESSION_OPND:
case DISPLACEMENT_OPND:
case INDEXED_OPND:
case PC_DISPLACEMENT_OPND:
case PC_INDEXED_OPND:
case IMMEDIATE_OPND:
case ABSOLUTE_SHORT_OPND:
case ABSOLUTE_LONG_OPND:
result = evaluateExpression(operand->theOperand,
performingFixups ? NO_FIXUP : OPERAND_FIXUP);
if (operand->kindOfOperand != EXPRESSION_OPND) {
if (result->addressMode != EXPRESSION_OPND) {
error(BAD_ADDRESS_MODE_ERROR);
result->kindOfValue = FAIL;
} else {
result->addressMode = operand->kindOfOperand;
}
}
break;
case SELECTED_OPND:
case INDEX_SELECTED_OPND:
result = evaluateSelectionList(operand->theOperand);
if (result->addressMode != EXPRESSION_OPND) {
error(BAD_ADDRESS_MODE_ERROR);
result->kindOfValue = FAIL;
} else {
result->addressMode = operand->kindOfOperand;
}
break;
case D_REGISTER_OPND:
case A_REGISTER_OPND:
case A_REGISTER_INDIRECT_OPND:
case POSTINCREMENT_OPND:
case PREDECREMENT_OPND:
case CC_REGISTER_OPND:
case STATUS_REGISTER_OPND:
case USP_REGISTER_OPND:
case CONTROL_REGISTER_OPND:
result = newValue(ABSOLUTE_VALUE, 0, operand->
kindOfOperand);
break;
case STRING_OPND:
result = newValue(STRING_VALUE, operand->theOperand,
STRING_OPND);
break;
case BLOCK_OPND:
if (standaloneExpansionFlag)
forceExpansion();
assembleBlock(operand->theOperand);
expansionOn();
result = newValue(FAIL, 0, BLOCK_OPND);
break;
default:
botch("bad operand kind in evaluateOperand %d\n",
operand->kindOfOperand);
break;
}
return(result);
}
/* from parserMisc.c */
conditionType
invertConditionCode(conditionCode)
conditionType conditionCode;
{
#define cc (int)conditionCode
if ((int)CARRY_COND<=cc && cc<=(int)ALWAYS_COND)
return((conditionType)
(cc - (int)CARRY_COND + (int)NOT_CARRY_COND));
else if ((int)NOT_CARRY_COND<=cc && cc<=(int)NEVER_COND)
return((conditionType)
(cc + (int)CARRY_COND - (int)NOT_CARRY_COND));
else
botch("invertConditionCode given %d, not a condition code\n");
}
/* from semanticMisc.c */
bool
shouldParenthesize(operand)
operandType *operand;
{
expressionTermKindType kind;
switch(operandKindField(operand->kindOfOperand)) {
case EXPRESSION_OPND:
case DISPLACEMENT_OPND:
case INDEXED_OPND:
case PC_DISPLACEMENT_OPND:
case PC_INDEXED_OPND:
case IMMEDIATE_OPND:
case ABSOLUTE_SHORT_OPND:
case ABSOLUTE_LONG_OPND:
kind = operand->theOperand.expressionUnion->kindOfTerm;
return (kind==UNOP_EXPR || kind==BINOP_EXPR || kind==
ASSIGN_EXPR);
break;
case STRING_OPND:
case BLOCK_OPND:
case D_REGISTER_OPND:
case A_REGISTER_OPND:
case A_REGISTER_INDIRECT_OPND:
case POSTINCREMENT_OPND:
case PREDECREMENT_OPND:
case CC_REGISTER_OPND:
case STATUS_REGISTER_OPND:
case USP_REGISTER_OPND:
case CONTROL_REGISTER_OPND:
case SELECTED_OPND:
case INDEX_SELECTED_OPND:
return(FALSE);
break;
}
}

1
opt/.mark Normal file
View File

@ -0,0 +1 @@
Mon Feb 2 23:18:37 PST 1987

165
opt/Makefile Normal file
View File

@ -0,0 +1,165 @@
.SUFFIXES: .o .c .h .run
# to make for another target CPU, redefine PROC to the name of the target
# processor, e.g., 68000
PROC =6502
OBJECTS = y.tab.o actions.o buildStuff1.o buildStuff2.o\
buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o\
emitBranch.o emitStuff.o encode.o errorStuff.o expressionSemantics.o fixups.o\
garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o\
malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o\
statementSemantics.o structSemantics.o tokenStrings.o
SOURCES = macross_$(PROC).y actions_$(PROC).c buildStuff1.c buildStuff2.c\
buildStuff3.c builtInFunctions.c builtInFunsSD_$(PROC).c debugPrint.c\
debugPrintSD_$(PROC).c emitBranch_$(PROC).c emitStuff.c encode.c errorStuff.c\
expressionSemantics.c fixups.c garbage.c initialize.c lexer.c listing.c\
lookups.c macrossTables_$(PROC).c main.c malloc.c object.c\
operandStuffSD_$(PROC).c parserMisc.c semanticMisc.c statementSemantics.c\
structSemantics.c tokenStrings_$(PROC).c lexerTables.h macrossGlobals.h\
macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h driver.c
HEADERS = macrossTypes.h macrossGlobals.h
.c.o:
cc -c -O -DTARGET_CPU=CPU_$(PROC) $*.c
.c.run:
cc -o $* $*.c
macross: $(OBJECTS)
cc -O -o macross $(OBJECTS)
driver: driver.c
cc -o driver driver.c
update: .mark
kessel "(cd /u0/chip/macross; make macross >&errorfyle)" &
install: macross
cp macross macross_tmp
strip macross_tmp
cp /u1/gg/bin/macross_$(PROC) /u1/gg/bin/macross_$(PROC).old
cp macross_tmp /u1/gg/bin/macross_$(PROC)
rm macross_tmp
cp /u1/gg/bin/macross_$(PROC) /net/mycroft/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/shem/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/weyr/u1/gg/bin
dinstall: driver
cp driver /u1/gg/bin/driver_tmp
strip /u1/gg/bin/driver_tmp
mv /u1/gg/bin/driver_tmp /u1/gg/bin/driver/macross
cp /u1/gg/bin/driver /net/mycroft/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/shem/u1/gg/bin/macross
cp /u1/gg/bin/driver /net/weyr/u1/gg/bin/macross
change:
rm *.o
rm *.tab.*
cp Makefile_68000 Makefile
move: .mark
.mark: $(SOURCES)
cp $? /net/kessel/u0/chip/macross
cp $? /net/kessel/u0/chip/macross/prof
cp $? ..
date >.mark
date >/net/kessel/u0/chip/macross/.mark
date >/net/kessel/u0/chip/macross/prof/.mark
date >../.mark
macrossTypes.h: macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h
actions.o: actions_$(PROC).c $(HEADERS)
cc -c -O -DTARGET_CPU=CPU_$(PROC) actions_$(PROC).c
mv actions_$(PROC).o actions.o
buildStuff1.o: buildStuff1.c $(HEADERS)
buildStuff2.o: buildStuff2.c $(HEADERS)
buildStuff3.o: buildStuff3.c $(HEADERS)
builtInFunctions.o: builtInFunctions.c $(HEADERS)
builtInFunsSD.o: builtInFunsSD_$(PROC).c $(HEADERS)
cc -c -O -DTARGET_CPU=CPU_$(PROC) builtInFunsSD_$(PROC).c
mv builtInFunsSD_$(PROC).o builtInFunsSD.o
debugPrint.o: debugPrint.c y.tab.h $(HEADERS)
debugPrintSD.o: debugPrintSD_$(PROC).c y.tab.h $(HEADERS)
cc -c -O -DTARGET_CPU=CPU_$(PROC) debugPrintSD_$(PROC).c
mv debugPrintSD_$(PROC).o debugPrintSD.o
emitBranch.o: emitBranch_$(PROC).c $(HEADERS)
cc -c -O -DTARGET_CPU=CPU_$(PROC) emitBranch_$(PROC).c
mv emitBranch_$(PROC).o emitBranch.o
emitStuff.o: emitStuff.c $(HEADERS)
cc -c -O -DBYTESWAPPED -DTARGET_CPU=CPU_$(PROC) emitStuff.c
encode.o: encode.c $(HEADERS)
errorStuff.o: errorStuff.c $(HEADERS)
expressionSemantics.o: expressionSemantics.c y.tab.h $(HEADERS)
fixups.o: fixups.c $(HEADERS)
garbage.o: garbage.c y.tab.h $(HEADERS)
initialize.o: initialize.c $(HEADERS)
lexer.o: lexer.c lexerTables.h y.tab.h $(HEADERS)
listing.o: listing.c $(HEADERS)
lookups.o: lookups.c $(HEADERS)
macrossTables.o: macrossTables_$(PROC).c y.tab.h macrossTypes.h
cc -c -O -DTARGET_CPU=CPU_$(PROC) macrossTables_$(PROC).c
mv macrossTables_$(PROC).o macrossTables.o
malloc.o: malloc.c
main.o: main.c $(HEADERS)
object.o: object.c $(HEADERS)
operandStuffSD.o: operandStuffSD_$(PROC).c $(HEADERS)
cc -c -O -DTARGET_CPU=CPU_$(PROC) operandStuffSD_$(PROC).c
mv operandStuffSD_$(PROC).o operandStuffSD.o
parserMisc.o: parserMisc.c y.tab.h $(HEADERS)
semanticMisc.o: semanticMisc.c $(HEADERS)
statementSemantics.o: statementSemantics.c $(HEADERS)
structSemantics.o: structSemantics.c $(HEADERS)
tokenStrings.o: tokenStrings_$(PROC).c $(HEADERS)
cc -c -O -DTARGET_CPU=CPU_$(PROC) tokenStrings_$(PROC).c
mv tokenStrings_$(PROC).o tokenStrings.o
y.tab.o: y.tab.c $(HEADERS)
cc -c -O -DYYDEBUG -DTARGET_CPU=CPU_$(PROC) y.tab.c
y.tab.c y.tab.h: macross_$(PROC).y
yacc -d macross_$(PROC).y
y.output: macross_$(PROC).y
yacc -vd macross_$(PROC).y
cleanup:
/bin/rm -f *.o y.output y.tab.c y.tab.h macross
love:
@echo "Not war?"

162
opt/Makefile_6502 Normal file
View File

@ -0,0 +1,162 @@
.SUFFIXES: .o .c .h .run
# to make for another target CPU, redefine PROC to the name of the target
# processor, e.g., 68000
PROC =6502
OBJECTS = y.tab.o actions.o buildStuff1.o buildStuff2.o\
buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o\
emitBranch.o emitStuff.o errorStuff.o expressionSemantics.o fixups.o\
garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o\
malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o\
statementSemantics.o structSemantics.o tokenStrings.o
SOURCES = macross_$(PROC).y actions_$(PROC).c buildStuff1.c buildStuff2.c\
buildStuff3.c builtInFunctions.c builtInFunsSD_$(PROC).c debugPrint.c\
debugPrintSD_$(PROC).c emitBranch_$(PROC).c emitStuff.c errorStuff.c\
expressionSemantics.c fixups.c garbage.c initialize.c lexer.c listing.c\
lookups.c macrossTables_$(PROC).c main.c malloc.c object.c\
operandStuffSD_$(PROC).c parserMisc.c semanticMisc.c statementSemantics.c\
structSemantics.c tokenStrings_$(PROC).c lexerTables.h macrossGlobals.h\
macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h driver.c
HEADERS = macrossTypes.h macrossGlobals.h
.c.o:
cc -O -c -DTARGET_CPU=CPU_$(PROC) $*.c
.c.run:
cc -O -o $* $*.c
macross: $(OBJECTS)
cc -O -o macross $(OBJECTS)
driver: driver.c
cc -O -o driver driver.c
update: .mark
kessel "(cd /u0/chip/macross; make macross >&errorfyle)" &
install: macross
cp macross /u1/gg/bin/macross_tmp
strip /u1/gg/bin/macross_tmp
mv /u1/gg/bin/macross_$(PROC) /u1/gg/bin/macross_$(PROC).old
mv /u1/gg/bin/macross_tmp /u1/gg/bin/macross_$(PROC)
cp /u1/gg/bin/macross_$(PROC) /net/mycroft/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/shem/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/weyr/u1/gg/bin
dinstall: driver
cp driver /u1/gg/bin/driver_tmp
strip /u1/gg/bin/driver_tmp
mv /u1/gg/bin/driver_tmp /u1/gg/bin/macross
cp /u1/gg/bin/macross /net/mycroft/u1/gg/bin/macross
cp /u1/gg/bin/macross /net/shem/u1/gg/bin/macross
cp /u1/gg/bin/macross /net/weyr/u1/gg/bin/macross
change:
rm *.o
rm *.tab.*
cp Makefile_68000 Makefile
move: .mark
.mark: $(SOURCES)
cp $? /net/kessel/u0/chip/macross
cp $? /net/kessel/u0/chip/macross/prof
cp $? ..
date >.mark
date >/net/kessel/u0/chip/macross/.mark
date >/net/kessel/u0/chip/macross/prof/.mark
date >../.mark
macrossTypes.h: macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h
actions.o: actions_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) actions_$(PROC).c
mv actions_$(PROC).o actions.o
buildStuff1.o: buildStuff1.c $(HEADERS)
buildStuff2.o: buildStuff2.c $(HEADERS)
buildStuff3.o: buildStuff3.c $(HEADERS)
builtInFunctions.o: builtInFunctions.c $(HEADERS)
builtInFunsSD.o: builtInFunsSD_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) builtInFunsSD_$(PROC).c
mv builtInFunsSD_$(PROC).o builtInFunsSD.o
debugPrint.o: debugPrint.c y.tab.h $(HEADERS)
debugPrintSD.o: debugPrintSD_$(PROC).c y.tab.h $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) debugPrintSD_$(PROC).c
mv debugPrintSD_$(PROC).o debugPrintSD.o
emitBranch.o: emitBranch_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) emitBranch_$(PROC).c
mv emitBranch_$(PROC).o emitBranch.o
emitStuff.o: emitStuff.c $(HEADERS)
cc -O -c -DBYTESWAPPED -DTARGET_CPU=CPU_$(PROC) emitStuff.c
errorStuff.o: errorStuff.c $(HEADERS)
expressionSemantics.o: expressionSemantics.c y.tab.h $(HEADERS)
fixups.o: fixups.c $(HEADERS)
garbage.o: garbage.c y.tab.h $(HEADERS)
initialize.o: initialize.c $(HEADERS)
lexer.o: lexer.c lexerTables.h y.tab.h $(HEADERS)
listing.o: listing.c $(HEADERS)
lookups.o: lookups.c $(HEADERS)
macrossTables.o: macrossTables_$(PROC).c y.tab.h macrossTypes.h
cc -O -c -DTARGET_CPU=CPU_$(PROC) macrossTables_$(PROC).c
mv macrossTables_$(PROC).o macrossTables.o
malloc.o: malloc.c
main.o: main.c $(HEADERS)
object.o: object.c $(HEADERS)
operandStuffSD.o: operandStuffSD_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) operandStuffSD_$(PROC).c
mv operandStuffSD_$(PROC).o operandStuffSD.o
parserMisc.o: parserMisc.c y.tab.h $(HEADERS)
semanticMisc.o: semanticMisc.c $(HEADERS)
statementSemantics.o: statementSemantics.c $(HEADERS)
structSemantics.o: structSemantics.c $(HEADERS)
tokenStrings.o: tokenStrings_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) tokenStrings_$(PROC).c
mv tokenStrings_$(PROC).o tokenStrings.o
y.tab.o: y.tab.c $(HEADERS)
cc -O -c -DYYDEBUG -DTARGET_CPU=CPU_$(PROC) y.tab.c
y.tab.c y.tab.h: macross_$(PROC).y
yacc -d macross_$(PROC).y
y.output: macross_$(PROC).y
yacc -vd macross_$(PROC).y
cleanup:
/bin/rm -f *.o y.output y.tab.c y.tab.h macross
love:
@echo "Not war?"

162
opt/Makefile_68000 Normal file
View File

@ -0,0 +1,162 @@
.SUFFIXES: .o .c .h .run
# to make for another target CPU, redefine PROC to the name of the target
# processor, e.g., 68000
PROC =68000
OBJECTS = y.tab.o actions.o buildStuff1.o buildStuff2.o\
buildStuff3.o builtInFunctions.o builtInFunsSD.o debugPrint.o debugPrintSD.o\
emitBranch.o emitStuff.o errorStuff.o expressionSemantics.o fixups.o\
garbage.o initialize.o lexer.o listing.o lookups.o macrossTables.o main.o\
malloc.o object.o operandStuffSD.o parserMisc.o semanticMisc.o\
statementSemantics.o structSemantics.o tokenStrings.o
SOURCES = macross_$(PROC).y actions_$(PROC).c buildStuff1.c buildStuff2.c\
buildStuff3.c builtInFunctions.c builtInFunsSD_$(PROC).c debugPrint.c\
debugPrintSD_$(PROC).c emitBranch_$(PROC).c emitStuff.c errorStuff.c\
expressionSemantics.c fixups.c garbage.c initialize.c lexer.c listing.c\
lookups.c macrossTables_$(PROC).c main.c malloc.c object.c\
operandStuffSD_$(PROC).c parserMisc.c semanticMisc.c statementSemantics.c\
structSemantics.c tokenStrings_$(PROC).c lexerTables.h macrossGlobals.h\
macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h driver.c
HEADERS = macrossTypes.h macrossGlobals.h
.c.o:
cc -O -c -DTARGET_CPU=CPU_$(PROC) $*.c
.c.run:
cc -O -o $* $*.c
macross: $(OBJECTS)
cc -O -o macross $(OBJECTS)
driver: driver.c
cc -O -o driver driver.c
update: .mark
kessel "(cd /u0/chip/macross; make macross >&errorfyle)" &
install: macross
cp macross /u1/gg/bin/macross_tmp
strip /u1/gg/bin/macross_tmp
mv /u1/gg/bin/macross_$(PROC) /u1/gg/bin/macross_$(PROC).old
mv /u1/gg/bin/macross_tmp /u1/gg/bin/macross_$(PROC)
cp /u1/gg/bin/macross_$(PROC) /net/mycroft/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/shem/u1/gg/bin
cp /u1/gg/bin/macross_$(PROC) /net/weyr/u1/gg/bin
dinstall: driver
cp driver /u1/gg/bin/driver_tmp
strip /u1/gg/bin/driver_tmp
mv /u1/gg/bin/driver_tmp /u1/gg/bin/macross
cp /u1/gg/bin/macross /net/mycroft/u1/gg/bin/macross
cp /u1/gg/bin/macross /net/shem/u1/gg/bin/macross
cp /u1/gg/bin/macross /net/weyr/u1/gg/bin/macross
change:
rm *.o
rm *.tab.*
cp Makefile_6502 Makefile
move: .mark
.mark: $(SOURCES)
cp $? /net/kessel/u0/chip/macross
cp $? /net/kessel/u0/chip/macross/prof
cp $? ..
date >.mark
date >/net/kessel/u0/chip/macross/.mark
date >/net/kessel/u0/chip/macross/prof/.mark
date >../.mark
macrossTypes.h: macrossTypes.h operandDefs_$(PROC).h operandBody_$(PROC).h\
conditionDefs_$(PROC).h
actions.o: actions_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) actions_$(PROC).c
mv actions_$(PROC).o actions.o
buildStuff1.o: buildStuff1.c $(HEADERS)
buildStuff2.o: buildStuff2.c $(HEADERS)
buildStuff3.o: buildStuff3.c $(HEADERS)
builtInFunctions.o: builtInFunctions.c $(HEADERS)
builtInFunsSD.o: builtInFunsSD_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) builtInFunsSD_$(PROC).c
mv builtInFunsSD_$(PROC).o builtInFunsSD.o
debugPrint.o: debugPrint.c y.tab.h $(HEADERS)
debugPrintSD.o: debugPrintSD_$(PROC).c y.tab.h $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) debugPrintSD_$(PROC).c
mv debugPrintSD_$(PROC).o debugPrintSD.o
emitBranch.o: emitBranch_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) emitBranch_$(PROC).c
mv emitBranch_$(PROC).o emitBranch.o
emitStuff.o: emitStuff.c $(HEADERS)
cc -O -c -DBYTESWAPPED -DTARGET_CPU=CPU_$(PROC) emitStuff.c
errorStuff.o: errorStuff.c $(HEADERS)
expressionSemantics.o: expressionSemantics.c y.tab.h $(HEADERS)
fixups.o: fixups.c $(HEADERS)
garbage.o: garbage.c y.tab.h $(HEADERS)
initialize.o: initialize.c $(HEADERS)
lexer.o: lexer.c lexerTables.h y.tab.h $(HEADERS)
listing.o: listing.c $(HEADERS)
lookups.o: lookups.c $(HEADERS)
macrossTables.o: macrossTables_$(PROC).c y.tab.h macrossTypes.h
cc -O -c -DTARGET_CPU=CPU_$(PROC) macrossTables_$(PROC).c
mv macrossTables_$(PROC).o macrossTables.o
malloc.o: malloc.c
main.o: main.c $(HEADERS)
object.o: object.c $(HEADERS)
operandStuffSD.o: operandStuffSD_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) operandStuffSD_$(PROC).c
mv operandStuffSD_$(PROC).o operandStuffSD.o
parserMisc.o: parserMisc.c y.tab.h $(HEADERS)
semanticMisc.o: semanticMisc.c $(HEADERS)
statementSemantics.o: statementSemantics.c $(HEADERS)
structSemantics.o: structSemantics.c $(HEADERS)
tokenStrings.o: tokenStrings_$(PROC).c $(HEADERS)
cc -O -c -DTARGET_CPU=CPU_$(PROC) tokenStrings_$(PROC).c
mv tokenStrings_$(PROC).o tokenStrings.o
y.tab.o: y.tab.c $(HEADERS)
cc -O -c -DYYDEBUG -DTARGET_CPU=CPU_$(PROC) y.tab.c
y.tab.c y.tab.h: macross_$(PROC).y
yacc -d macross_$(PROC).y
y.output: macross_$(PROC).y
yacc -vd macross_$(PROC).y
cleanup:
/bin/rm -f *.o y.output y.tab.c y.tab.h macross
love:
@echo "Not war?"

128
parserMisc.c Normal file
View File

@ -0,0 +1,128 @@
/*
parserMisc.c -- Miscellaneous parser support routines for the Macross
assembler.
Chip Morningstar -- Lucasfilm Ltd.
3-November-1984
*/
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "y.tab.h"
statementType *
addLabelToStatement(labelList, statement)
labelListType *labelList;
statementType *statement;
{
statementType *newStatement();
if (statement == NULL)
statement = newStatement(NULL_STATEMENT, NULL);
statement->labels = labelList;
return(statement);
}
void
botch(message, arg1, arg2, arg3)
char *message;
anyOldThing *arg1;
anyOldThing *arg2;
anyOldThing *arg3;
{
printf("Macross horrible terrible internal botch: ");
printf(message, arg1, arg2, arg3);
chokePukeAndDie();
}
void
checkDefineAssignmentOperator(assignmentOperator)
assignmentKindType assignmentOperator;
{
if (assignmentOperator != ASSIGN_ASSIGN)
puntOnError(DEFINE_ASSIGNMENT_WRONG_ERROR);
}
statementType *
convertDefineToMdefine(defineStatement)
statementType *defineStatement;
{
if (defineStatement->kindOfStatement != DEFINE_STATEMENT)
botch("convertDefineToMdefine got statement kind: %d\n",
defineStatement->kindOfStatement);
defineStatement->kindOfStatement = MDEFINE_STATEMENT;
return(defineStatement);
}
ifStatementBodyType *
extractIfBody(ifStatement)
statementType *ifStatement;
{
ifStatementBodyType *result;
result = ifStatement->statementBody.ifUnion;
if (ifStatement->labels != NULL)
botch("extract if body with non-null labels\n");
else if (ifStatement->nextStatement != NULL)
botch("extract if body with non-null next\n");
else
qfree(ifStatement);
return(result);
}
mifStatementBodyType *
extractMifBody(mifStatement)
statementType *mifStatement;
{
mifStatementBodyType *result;
result = mifStatement->statementBody.mifUnion;
if (mifStatement->labels != NULL)
botch("extract mif body with non-null labels\n");
else if (mifStatement->nextStatement != NULL)
botch("extract mif body with non-null next\n");
else
qfree(mifStatement);
return(result);
}
stringType *
extractString(textExpression)
operandType *textExpression;
{
stringType *result;
if (textExpression->kindOfOperand != STRING_OPND)
botch("extract string got handed an opnd kind: %d\n",
textExpression->kindOfOperand);
result = textExpression->theOperand.stringUnion;
qfree(textExpression);
return(result);
}
void
popMacroOrFunctionNestingDepth()
{
if (--macroOrFunctionNestingDepth == 0)
unknownSymbolTag = UNKNOWN_SYMBOL;
}
void
pushMacroOrFunctionNestingDepth()
{
macroOrFunctionNestingDepth++;
unknownSymbolTag = NESTED_UNKNOWN_SYMBOL;
}
char *
saveString(s)
char *s;
{
char *result;
result = (char *)malloc(strlen(s)+1);
strcpy(result, s);
return(result);
}

BIN
parserMisc.o Normal file

Binary file not shown.

1337
semanticMisc.c Normal file

File diff suppressed because it is too large Load Diff

BIN
semanticMisc.o Normal file

Binary file not shown.

1
slinky/.mark Normal file
View File

@ -0,0 +1 @@
Fri Jun 6 14:51:43 PDT 1986

8
slinky/DOC Normal file
View File

@ -0,0 +1,8 @@
/u0/chip/macross/slinky:
This directory contains the source to Slinky. Here's what's here:
DOC - This file
Makefile - Makefile to compile it
*.c, *.h - source files
opt/ - directory for optimized version, as mentioned in
documentation above for /u0/chip/macross/opt

77
slinky/Makefile Normal file
View File

@ -0,0 +1,77 @@
.SUFFIXES: .o .c .h .run
OBJECTS = builtins.o debugPrint.o errorStuff.o expr.o initialize.o\
instantiate.o link.o main.o map.o poke.o read.o relocate.o slinkyTables.o\
write.o
SOURCES = builtins.c debugPrint.c errorStuff.c expr.c initialize.c\
instantiate.c link.c main.c map.c poke.c read.c relocate.c slinkyTables.c\
write.c slinkyExpressions.h slinkyGlobals.h slinkyTypes.h y.tab.h
.c.o:
cc -c -g $*.c
.c.run:
cc -o $* $*.c
slinky: $(OBJECTS)
cc -g -o slinky $(OBJECTS)
update: .mark
kessel "(cd /u0/chip/macross/slinky; make slinky >&errorfyle)" &
move: .mark
.mark: $(SOURCES)
# cp $? /net/kessel/u0/chip/macross/slinky
cp $? /net/kessel/u0/chip/macross/slinky
# cp $? /net/kessel/u0/chip/macross/slinky/prof
cp $? /net/kessel/u0/chip/macross/slinky/prof
cp $? opt
date >.mark
# date >/net/kessel/u0/chip/macross/slinky/.mark
date >/net/kessel/u0/chip/macross/slinky/.mark
# date >/net/kessel/u0/chip/macross/slinky/prof/.mark
date >/net/kessel/u0/chip/macross/slinky/prof/.mark
date >opt/.mark
install: slinky
cp slinky /u1/gg/bin/slinky_tmp
strip /u1/gg/bin/slinky_tmp
mv /u1/gg/bin/slinky /u1/gg/bin/sliny.old
mv /u1/gg/bin/slinky_tmp /u1/gg/bin/slinky
builtins.o: builtins.c slinkyGlobals.h slinkyTypes.h slinkyExpressions.h
debugPrint.o: debugPrint.c slinkyGlobals.h slinkyTypes.h
errorStuff.o: errorStuff.c slinkyGlobals.h slinkyTypes.h
expr.o: expr.c slinkyExpressions.h slinkyGlobals.h slinkyTypes.h y.tab.h
initialize.o: initialize.c slinkyGlobals.h slinkyTypes.h
instantiate.o: instantiate.c slinkyGlobals.h slinkyTypes.h slinkyExpressions.h
link.o: link.c slinkyGlobals.h slinkyTypes.h
main.o: main.c slinkyGlobals.h slinkyTypes.h
map.o: map.c slinkyGlobals.h slinkyTypes.h
poke.o: poke.c slinkyGlobals.h slinkyTypes.h
read.o: read.c slinkyGlobals.h slinkyTypes.h
relocate.o: relocate.c slinkyGlobals.h slinkyTypes.h
slinkyTables.o: slinkyTables.c slinkyTypes.h
write.o: write.c slinkyGlobals.h slinkyTypes.h
cleanup:
/bin/rm -f *.o slinky
love:
@echo "Not war?"

431
slinky/builtins.c Normal file
View File

@ -0,0 +1,431 @@
/*
builtins.c -- Built-in functions for the Slinky linker
Chip Morningstar -- Lucasfilm Ltd.
14-November-1985
*/
#include "slinkyTypes.h"
#include "slinkyGlobals.h"
#include "slinkyExpressions.h"
#include <strings.h>
#define getSymbol() ((symbolType *)getNumber())
void
tooFewArgs(argCount, name)
int argCount;
stringType *name;
{
error(TOO_FEW_ARGUMENTS_TO_BIF_ERROR, name);
while (argCount-- > 0)
skipExpression();
}
void
tooManyArgs(argCount, name)
int argCount;
stringType *name;
{
error(TOO_MANY_ARGUMENTS_TO_BIF_ERROR, name);
while (argCount-- > 0)
skipExpression();
}
/*
The built-in-functions themselves: pointers to these are loaded into the
builtInFunctionTable at linker compile time. These are all known within
the Macross assembler: each symbol of the form "xxx" is assigned a pointer
to "xxxBIF" (BIF == Built-In-Function).
*/
/* The two ATASCII related BIF's refer to this table -- This really only
makes sense for the 6502 version, but is harmless in other versions. */
static char atasciiTable[] = { /* 0xFFs will become 0x00s on output */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0xFF,
};
/* Convert a string to ATASCII */
stringType *
atasciiBIF(argCount)
int argCount;
{
stringType *string;
stringType *newString;
int i;
if (argCount == 0) {
return("");
} else if (argCount > 1) {
tooManyArgs(argCount, "atascii");
return("");
} else {
string = (stringType *)evaluateExpression();
newString = (stringType *)malloc(strlen(string)+1);
for (i=0; string[i]!='\0'; i++)
newString[i] = atasciiTable[string[i]];
newString[i] = '\0';
return(newString);
}
}
/* Convert a string to ATASCII while setting high-order color bits */
stringType *
atasciiColorBIF(argCount)
int argCount;
{
stringType *string;
stringType *newString;
int color;
int i;
byte testChar;
if (argCount == 0) {
return("");
} else if (argCount == 1) {
return(atasciiBIF(argCount));
} else if (argCount > 2) {
tooManyArgs(argCount, "atasciiColor");
return("");
} else {
string = (stringType *)evaluateExpression();
color = (evaluateExpression() & 0x03) << 6;
newString = (stringType *)malloc(strlen(string)+1);
for (i=0; string[i]!='\0'; i++) {
testChar = atasciiTable[string[i]];
if (testChar == 0xFF)
testChar = 0;
testChar = (testChar & 0x3F) | color;
if (testChar == 0)
testChar = 0xFF;
newString[i] = testChar;
}
newString[i] = '\0';
return(newString);
}
}
/* Check if an operand is absolute (as opposed to relocatable) */
bool
isAbsoluteValueBIF(argCount)
int argCount;
{
if (argCount > 1)
tooManyArgs(argCount, "isAbsoluteValue");
return(TRUE);
}
/* Check if operand is a condition code */
bool
isConditionCodeBIF(argCount)
int argCount;
{
bool result;
if (argCount == 0)
return(FALSE);
else if (argCount > 1) {
tooManyArgs(argCount, "isConditionCode");
return(FALSE);
}
result = (*pc == CONDITION_CODE_TAG);
skipExpression();
return(result);
}
/* Check if a symbol is defined */
bool
isDefinedBIF(argCount)
int argCount;
{
symbolType *symbol;
if (argCount == 0)
return(FALSE);
else if (argCount > 1) {
tooManyArgs(argCount, "isDefined");
return(FALSE);
}
if (*pc != IDENTIFIER_TAG) {
skipExpression();
return(TRUE);
}
pc++; /* skip tag */
symbol = getSymbol();
return((symbol->symbolClass & ~SYMBOL_EXTERNAL) != 0);
}
/* Check if a symbol is externally visible */
bool
isExternalBIF(argCount)
int argCount;
{
symbolType *symbol;
if (argCount == 0)
return(FALSE);
else if (argCount > 1) {
tooManyArgs(argCount, "isExternal");
return(FALSE);
}
if (*pc != IDENTIFIER_TAG) {
skipExpression();
return(TRUE);
}
pc++; /* skip tag */
symbol = getSymbol();
return((symbol->symbolClass & SYMBOL_EXTERNAL) != 0);
}
/* Return the Nth character of a string (as an integer) */
int
nthCharBIF(argCount)
int argCount;
{
stringType *string;
int position;
if (argCount > 2) {
tooManyArgs(argCount, "nthChar");
return(0);
} else if (argCount != 2) {
tooFewArgs(argCount, "nthChar");
return(0);
}
string = (stringType *)evaluateExpression();
position = evaluateExpression();
if (position >= strlen(string)) {
error(BAD_POSITION_ARGUMENT_TO_NTH_CHAR_ERROR);
return(0);
}
return(string[position]);
}
/* Pass stuff through to stdio's 'printf' function */
int
printfBIF(argCount)
int argCount;
{
stringType *formatString;
int argument[20];
int i;
if (argCount < 1) {
tooFewArgs(argCount, "printf");
return(0);
} else if (argCount > 21) {
tooManyArgs(argCount, "printf");
return(0);
}
formatString = (stringType *)evaluateExpression();
argCount--;
for (i=0; i<argCount; ++i)
argument[i] = evaluateExpression();
/* cretinous hack */
return(printf(formatString, argument[0], argument[1], argument[2],
argument[3], argument[4], argument[5], argument[6],
argument[7], argument[8], argument[9], argument[10],
argument[11], argument[12], argument[13],
argument[14], argument[15], argument[16],
argument[17], argument[18], argument[19]));
}
/* Concatenate two strings */
stringType *
strcatBIF(argCount)
int argCount;
{
stringType *string1;
stringType *string2;
stringType *newString;
if (argCount == 0)
return("");
else if (argCount == 1)
return((stringType *)evaluateExpression());
else if (argCount > 2) {
tooManyArgs(argCount, "strcat");
return("");
}
string1 = (stringType *)evaluateExpression();
string2 = (stringType *)evaluateExpression();
newString = (stringType *)malloc(strlen(string1)+strlen(string2)+1);
strcpy(newString, string1);
strcat(newString, string2);
return(newString);
}
/* Compare two strings */
int
strcmpBIF(argCount)
int argCount;
{
stringType *string1;
stringType *string2;
if (argCount < 2) {
tooFewArgs(argCount, "strcmp");
return(0);
} else if (argCount > 2) {
tooManyArgs(argCount, "strcmp");
return(0);
}
string1 = (stringType *)evaluateExpression();
string2 = (stringType *)evaluateExpression();
return(strcmp(string1, string2));
}
/* Compare two strings in a case-independent fashion */
int
strcmplcBIF(argCount)
int argCount;
{
stringType *string1;
stringType *string2;
if (argCount < 2) {
tooFewArgs(argCount, "strcmplc");
return(0);
} else if (argCount > 2) {
tooManyArgs(argCount, "strcmplc");
return(0);
}
string1 = (stringType *)evaluateExpression();
string2 = (stringType *)evaluateExpression();
return(strcmplc(string1, string2));
}
/* Return the length of a string */
int
strlenBIF(argCount)
int argCount;
{
if (argCount < 1)
return(0);
else if (argCount > 1) {
tooManyArgs(argCount, "strlen");
return(0);
}
return(strlen(evaluateExpression()));
}
/* Return a substring of a string */
char *
substrBIF(argCount)
int argCount;
{
stringType *string;
int start;
int length;
stringType *newString;
int originalLength;
bool backwards;
if (argCount < 1)
return("");
else if (argCount == 1)
return((stringType *)evaluateExpression());
else if (argCount > 3) {
tooManyArgs(argCount, "substr");
return("");
}
string = (stringType *)evaluateExpression();
originalLength = strlen(string);
start = evaluateExpression();
if (start < 0) {
start = -start - 1;
backwards = TRUE;
} else
backwards = FALSE;
if (argCount == 2) {
length = originalLength - start;
if (backwards)
length = -length;
} else {
length = evaluateExpression();
}
if (length < 0) {
length = -length;
if (backwards)
start = start + length - 1;
else
start = start - length + 1;
}
if (backwards)
start = originalLength - start - 1;
if (originalLength <= start || originalLength < length + start ||
start < 0 ){
error(BAD_SUBSTRING_INDICES_ERROR);
return("");
}
newString = (stringType *)malloc(length+1);
strncpy(newString, string+start, length);
newString[length] = '\0';
return(newString);
}
/* Turn a string into a symbol and return its value */
addressType
symbolLookupBIF(argCount)
int argCount;
{
symbolType *symbol;
stringType *symbolName;
symbolType *lookupGlobalSymbol();
if (argCount < 1) {
tooFewArgs(argCount, "symbolLookup");
return(0);
} else if (argCount > 1) {
tooManyArgs(argCount, "symbolLookup");
return(0);
}
symbol = lookupGlobalSymbol(symbolName = (stringType *)
evaluateExpression());
if (symbol == NULL) {
error(SYMBOL_NOT_FOUND_IN_SYMBOL_LOOKUP_ERROR, symbolName);
return(0);
} else
return(symbol->symbolValue);
}
/* Turn a symbol into a string */
stringType *
symbolNameBIF(argCount)
int argCount;
{
symbolType *symbol;
if (argCount < 1) {
tooFewArgs(argCount, "symbolName");
return(NULL);
} else if (argCount > 1) {
tooManyArgs(argCount, "symbolName");
return(NULL);
}
if (*pc != IDENTIFIER_TAG) {
error(SYMBOL_NAME_ARG_IS_NOT_SYMBOL_ERROR);
skipExpression();
return("");
}
pc++;
symbol = getSymbol();
return(symbol->symbolName);
}

BIN
slinky/builtins.o Normal file

Binary file not shown.

124
slinky/debugPrint.c Normal file
View File

@ -0,0 +1,124 @@
/*
debugPrint.c -- Routines to dump stuff out in readable form for
debugging the Slinky linker.
Chip Morningstar -- Lucasfilm Ltd.
18-March-1985
*/
#include "slinkyTypes.h"
#include "slinkyGlobals.h"
static char *modeStrings[2] = {
"abs",
"rel",
};
static char *kindStrings[3] = {
"byte",
"word",
"dbyt",
};
static char *pcrelStrings[2] = {
" ",
"pcrel",
};
static char *externalStrings[2] = {
" ",
"extern",
};
static char *symbolStrings[6] = {
"und ", /* 0x00 */
"und ext", /* 0x01 */
"abs ", /* 0x02 */
"abs ext", /* 0x03 */
"rel ", /* 0x04 */
"rel ext", /* 0x05 */
};
void
printCode(startAddress, endAddress, mode)
int startAddress;
int endAddress;
int mode;
{
printf(" Code: 0x%04x:0x%04x %s\n", startAddress, endAddress,
modeStrings[mode]);
}
void
printReference(reference)
expressionReferenceType *reference;
{
printf(" Ref : 0x%04x (%s %s %s %s) expression #%d\n", reference->
referenceAddress, modeStrings[reference->referenceMode],
pcrelStrings[reference->referenceRelative], externalStrings[
reference->referenceExternal], kindStrings[reference->
referenceKind], reference->referenceExpression.inFile);
}
void
printReferenceFixup(reference)
expressionReferenceType *reference;
{
printf(" Ref : 0x%04x (%s %s %s %s) expression=0x%x\n",
reference->referenceAddress, modeStrings[reference->
referenceMode],pcrelStrings[reference->referenceRelative],
externalStrings[reference->referenceExternal], kindStrings[
reference->referenceKind], reference->referenceExpression.
inCore);
}
void
printSymbol(symbolTag, symbol)
int symbolTag;
symbolType *symbol;
{
printf(" Symb: %3d %s 0x%04x \"%s\"\n", symbolTag, symbolStrings[
symbol->symbolClass], symbol->symbolValue,
symbol->symbolName);
}
void
printLoadMapSymbol(symbol)
symbolType *symbol;
{
fprintf(mapFileOutput, "%-20s 0x%04x %s ", symbol->symbolName,
symbol->symbolValue, symbolStrings[symbol->symbolClass]);
}
void
printGlobalSymbols()
{
int symbolCount;
printf("Globals:\n");
printf(" %d global symbols\n", globalSymbolCount);
for (symbolCount=0; symbolCount<globalSymbolCount; symbolCount++) {
printf(" Gsym: %3d \"%s\"\n", symbolCount,
globalSymbolTable[symbolCount]->symbolName);
}
}
void
printExpression(expression, length)
expressionPCType expression;
int length;
{
int line;
int i;
printf("expression length = %d:\n", length);
for (line=0; line<length; line+=16) {
printf(" %4x:", line);
for (i=line; i<line+16 && i<length; i++)
printf(" %2x", expression[i]);
printf("\n");
}
}

BIN
slinky/debugPrint.o Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More