mirror of
https://github.com/pfusik/xasm.git
synced 2024-12-09 04:52:21 +00:00
Upgraded to DMD 2.051.
This commit is contained in:
parent
034b95ea83
commit
6992795f55
326
xasm.d
326
xasm.d
@ -1,6 +1,6 @@
|
||||
// xasm 3.0.2 by Piotr Fusik <fox@scene.pl>
|
||||
// http://xasm.atari.org
|
||||
// Can be compiled with DMD v1.030.
|
||||
// Can be compiled with DMD v2.051.
|
||||
|
||||
// Poetic License:
|
||||
//
|
||||
@ -16,10 +16,11 @@
|
||||
// free or for profit.
|
||||
// These rights, on this notice, rely.
|
||||
|
||||
import std.stdio;
|
||||
import std.math;
|
||||
import std.stream;
|
||||
import std.cstream;
|
||||
import std.string;
|
||||
import std.conv;
|
||||
|
||||
version (Windows) {
|
||||
import std.c.windows.windows;
|
||||
@ -52,31 +53,31 @@ const char[] TITLE = "xasm 3.0.2";
|
||||
|
||||
char[] sourceFilename = null;
|
||||
|
||||
bit[26] options;
|
||||
bool[26] options;
|
||||
|
||||
char[][26] optionParameters;
|
||||
|
||||
char[][] commandLineDefinitions = null;
|
||||
|
||||
char[] makeTarget = null;
|
||||
char[] makeTarget;
|
||||
|
||||
char[] makeSources = "";
|
||||
char[] makeSources;
|
||||
|
||||
int exitCode = 0;
|
||||
int exitCode;
|
||||
|
||||
int totalLines;
|
||||
|
||||
bit pass2 = false;
|
||||
bool pass2;
|
||||
|
||||
bit optionFill; // opt f
|
||||
bool optionFill; // opt f
|
||||
|
||||
bit option5200; // opt g
|
||||
bool option5200; // opt g
|
||||
|
||||
bit optionHeaders; // opt h
|
||||
bool optionHeaders; // opt h
|
||||
|
||||
bit optionListing; // opt l
|
||||
bool optionListing; // opt l
|
||||
|
||||
bit optionObject; // opt o
|
||||
bool optionObject; // opt o
|
||||
|
||||
char[] line;
|
||||
|
||||
@ -84,11 +85,11 @@ int column;
|
||||
|
||||
class Location {
|
||||
|
||||
char[] filename;
|
||||
string filename;
|
||||
|
||||
int lineNo = 0;
|
||||
|
||||
this(char[] filename) {
|
||||
this(string filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
}
|
||||
@ -97,11 +98,15 @@ Location[] locations;
|
||||
|
||||
Location currentLocation;
|
||||
|
||||
bit foundEnd;
|
||||
bool foundEnd;
|
||||
|
||||
class AssemblyError : Exception {
|
||||
|
||||
this(char[] msg) {
|
||||
this(in char[] msg) {
|
||||
super(msg.idup);
|
||||
}
|
||||
|
||||
this(string msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@ -110,24 +115,24 @@ class Label {
|
||||
|
||||
int value;
|
||||
|
||||
bit unused = true;
|
||||
bool unused = true;
|
||||
|
||||
bit unknownInPass1 = false;
|
||||
bool unknownInPass1 = false;
|
||||
|
||||
bit passed = false;
|
||||
bool passed = false;
|
||||
|
||||
this(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
Label[char[]] labelTable;
|
||||
Label[string] labelTable;
|
||||
|
||||
Label currentLabel;
|
||||
|
||||
typedef int function(int a, int b) OperatorFunction;
|
||||
|
||||
bit inOpcode = false;
|
||||
bool inOpcode = false;
|
||||
|
||||
struct ValOp {
|
||||
|
||||
@ -142,7 +147,7 @@ ValOp[] valOpStack;
|
||||
|
||||
int value;
|
||||
|
||||
bit unknownInPass1;
|
||||
bool unknownInPass1;
|
||||
|
||||
enum AddrMode {
|
||||
ACCUMULATOR = 0,
|
||||
@ -175,17 +180,17 @@ ushort[] blockEnds;
|
||||
|
||||
int blockIndex;
|
||||
|
||||
bit repeating; // line
|
||||
bool repeating; // line
|
||||
|
||||
int repeatCounter; // line
|
||||
|
||||
bit instructionBegin;
|
||||
bool instructionBegin;
|
||||
|
||||
bit pairing;
|
||||
bool pairing;
|
||||
|
||||
bit willSkip;
|
||||
bool willSkip;
|
||||
|
||||
bit skipping;
|
||||
bool skipping;
|
||||
|
||||
ushort[] skipOffsets;
|
||||
|
||||
@ -193,7 +198,7 @@ int skipOffsetsIndex = 0;
|
||||
|
||||
int repeatOffset; // instruction repeat
|
||||
|
||||
bit wereManyInstructions;
|
||||
bool wereManyInstructions;
|
||||
|
||||
typedef void function(int move) MoveFunction;
|
||||
|
||||
@ -207,11 +212,11 @@ AddrMode addrMode2;
|
||||
|
||||
struct IfContext {
|
||||
|
||||
bit condition;
|
||||
bool condition;
|
||||
|
||||
bit wasElse;
|
||||
bool wasElse;
|
||||
|
||||
bit aConditionMatched;
|
||||
bool aConditionMatched;
|
||||
}
|
||||
|
||||
IfContext[] ifContexts;
|
||||
@ -222,37 +227,35 @@ char[32] listingLine;
|
||||
|
||||
int listingColumn;
|
||||
|
||||
char[] lastListedFilename = null;
|
||||
string lastListedFilename;
|
||||
|
||||
Stream objectStream = null;
|
||||
Stream objectStream;
|
||||
|
||||
int objectBytes = 0;
|
||||
|
||||
bit getOption(char letter) {
|
||||
bool getOption(char letter) {
|
||||
assert(letter >= 'a' && letter <= 'z');
|
||||
return options[letter - 'a'];
|
||||
}
|
||||
|
||||
void warning(char[] msg, bool error = false) {
|
||||
dout.flush();
|
||||
void warning(in char[] msg, bool error = false) {
|
||||
stdout.flush();
|
||||
version (Windows) {
|
||||
HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
GetConsoleScreenBufferInfo(h, &csbi);
|
||||
SetConsoleTextAttribute(h, (csbi.wAttributes & ~0xf) | (error ? 12 : 14));
|
||||
scope (exit) SetConsoleTextAttribute(h, csbi.wAttributes);
|
||||
}
|
||||
if (line !is null) {
|
||||
derr.printf("%.*s\n", line);
|
||||
stderr.writeln(line);
|
||||
}
|
||||
derr.printf("%.*s (%d) %.*s: %.*s\n",
|
||||
stderr.writefln("%s (%d) %s: %s",
|
||||
currentLocation.filename,
|
||||
currentLocation.lineNo,
|
||||
error ? "ERROR" : "WARNING",
|
||||
msg
|
||||
);
|
||||
version (Windows) {
|
||||
SetConsoleTextAttribute(h, csbi.wAttributes);
|
||||
}
|
||||
exitCode = 1;
|
||||
}
|
||||
|
||||
@ -260,7 +263,7 @@ void illegalCharacter() {
|
||||
throw new AssemblyError("Illegal character");
|
||||
}
|
||||
|
||||
bit eol() {
|
||||
bool eol() {
|
||||
return column >= line.length;
|
||||
}
|
||||
|
||||
@ -327,7 +330,7 @@ void readSpaces() {
|
||||
}
|
||||
|
||||
char[] readLabel() {
|
||||
char[] label = "";
|
||||
char[] label;
|
||||
while (!eol()) {
|
||||
char c = line[column++];
|
||||
if (c >= '0' && c <= '9' || c == '_') {
|
||||
@ -352,7 +355,7 @@ void readComma() {
|
||||
}
|
||||
|
||||
char[] readInstruction() {
|
||||
char[] r = "";
|
||||
char[] r;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char c = readChar() & 0xdf;
|
||||
if (c < 'A' || c > 'Z') {
|
||||
@ -364,12 +367,12 @@ char[] readInstruction() {
|
||||
}
|
||||
|
||||
char[] readFunction() {
|
||||
if (column + 5 >= line.length) return "";
|
||||
if (line[column + 3] != '(') return "";
|
||||
char[] r = "";
|
||||
if (column + 5 >= line.length) return null;
|
||||
if (line[column + 3] != '(') return null;
|
||||
char[] r;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
char c = line[column + i] & 0xdf;
|
||||
if (c < 'A' || c > 'Z') return "";
|
||||
if (c < 'A' || c > 'Z') return null;
|
||||
r ~= c;
|
||||
}
|
||||
column += 4;
|
||||
@ -377,7 +380,7 @@ char[] readFunction() {
|
||||
}
|
||||
|
||||
char[] readFilename() {
|
||||
char[] filename = "";
|
||||
char[] filename;
|
||||
readSpaces();
|
||||
char delimiter = readChar();
|
||||
switch (delimiter) {
|
||||
@ -391,6 +394,7 @@ char[] readFilename() {
|
||||
default:
|
||||
illegalCharacter();
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void readStringChar(char c) {
|
||||
@ -413,7 +417,7 @@ ubyte[] readString() {
|
||||
if (line[column] != delimiter) {
|
||||
if (line[column] == '*') {
|
||||
column++;
|
||||
foreach (inout ubyte b; r) {
|
||||
foreach (ref b; r) {
|
||||
b ^= 0x80;
|
||||
}
|
||||
}
|
||||
@ -548,7 +552,7 @@ int operatorShiftLeft(int a, int b) {
|
||||
if (b < 0) {
|
||||
return operatorShiftRight(a, -b);
|
||||
}
|
||||
if (a != 0 & b >= 32) {
|
||||
if (a != 0 && b >= 32) {
|
||||
throw new AssemblyError("Arithmetic overflow");
|
||||
}
|
||||
long r = cast(long) a << b;
|
||||
@ -672,8 +676,8 @@ void readValue() {
|
||||
}
|
||||
ValOp[] savedValOpStack = valOpStack;
|
||||
AddrMode savedAddrMode = addrMode;
|
||||
bit savedUnknownInPass1 = unknownInPass1;
|
||||
bit savedInstructionBegin = instructionBegin;
|
||||
bool savedUnknownInPass1 = unknownInPass1;
|
||||
bool savedInstructionBegin = instructionBegin;
|
||||
valOpStack.length = 0;
|
||||
inOpcode = true;
|
||||
assemblyInstruction(readInstruction());
|
||||
@ -863,11 +867,11 @@ void readValue() {
|
||||
valOpStack.length = 0;
|
||||
}
|
||||
|
||||
debug int testValue(char[] l) {
|
||||
line = l;
|
||||
debug int testValue(in char[] l) {
|
||||
line = l.dup;
|
||||
column = 0;
|
||||
readValue();
|
||||
dout.printf("Value of %.*s is %x\n", line, value);
|
||||
writefln("Value of %s is %x", line, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1139,11 +1143,11 @@ void readAbsoluteAddrMode() {
|
||||
addrMode = AddrMode.ABSOLUTE;
|
||||
}
|
||||
|
||||
debug AddrMode testAddrMode(char[] l) {
|
||||
line = l;
|
||||
debug AddrMode testAddrMode(in char[] l) {
|
||||
line = l.dup;
|
||||
column = 0;
|
||||
readAddrMode();
|
||||
dout.printf("Addressing mode of \"%.*s\" is %x\n", line, addrMode);
|
||||
writefln("Addressing mode of \"%s\" is %x", line, addrMode);
|
||||
return addrMode;
|
||||
}
|
||||
|
||||
@ -1166,14 +1170,14 @@ unittest {
|
||||
inOpcode = false;
|
||||
}
|
||||
|
||||
bit inFalseCondition() {
|
||||
bool inFalseCondition() {
|
||||
foreach (IfContext ic; ifContexts) {
|
||||
if (!ic.condition) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int filenameExt(char[] filename) {
|
||||
int filenameExt(in char[] filename) {
|
||||
int i = filename.length;
|
||||
while (--i >= 0) {
|
||||
switch (filename[i]) {
|
||||
@ -1197,19 +1201,19 @@ unittest {
|
||||
}
|
||||
|
||||
char[] makeEscape(char[] s) {
|
||||
return replace(s, "$", "$$");
|
||||
return replace(s.idup, "$", "$$").dup;
|
||||
}
|
||||
|
||||
Stream openInputFile(char[] filename) {
|
||||
makeSources ~= ' ' ~ makeEscape(filename);
|
||||
try {
|
||||
return new BufferedFile(filename, FileMode.In);
|
||||
return new BufferedFile(filename.idup, FileMode.In);
|
||||
} catch (OpenException e) {
|
||||
throw new AssemblyError(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Stream openOutputFile(char letter, char[] defaultExt) {
|
||||
Stream openOutputFile(char letter, string defaultExt) {
|
||||
char[] filename;
|
||||
if (optionParameters[letter - 'a'] is null) {
|
||||
filename = sourceFilename;
|
||||
@ -1225,24 +1229,24 @@ Stream openOutputFile(char letter, char[] defaultExt) {
|
||||
makeTarget = makeEscape(filename);
|
||||
}
|
||||
try {
|
||||
return new BufferedFile(filename, FileMode.OutNew);
|
||||
return new BufferedFile(filename.idup, FileMode.OutNew);
|
||||
} catch (OpenException e) {
|
||||
throw new AssemblyError(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void ensureListingFileOpen(char letter, char[] msg) {
|
||||
void ensureListingFileOpen(char letter, in char[] msg) {
|
||||
if (listingStream is null) {
|
||||
listingStream = openOutputFile(letter, ".lst");
|
||||
if (!getOption('q')) {
|
||||
dout.printf(msg);
|
||||
write(msg);
|
||||
}
|
||||
listingStream.printf(TITLE ~ "\r\n");
|
||||
listingStream.writeLine(TITLE);
|
||||
}
|
||||
}
|
||||
|
||||
void listNibble(int x) {
|
||||
listingLine[listingColumn++] = x <= 9 ? x + '0' : x + ('A' - 10);
|
||||
listingLine[listingColumn++] = cast(char) (x <= 9 ? x + '0' : x + ('A' - 10));
|
||||
}
|
||||
|
||||
void listByte(ubyte x) {
|
||||
@ -1268,13 +1272,13 @@ void listLine() {
|
||||
}
|
||||
ensureListingFileOpen('l', "Writing listing file...\n");
|
||||
if (currentLocation.filename != lastListedFilename) {
|
||||
listingStream.printf("Source: %.*s\n", currentLocation.filename);
|
||||
listingStream.writefln("Source: %s", currentLocation.filename);
|
||||
lastListedFilename = currentLocation.filename;
|
||||
}
|
||||
int i = 4;
|
||||
int x = currentLocation.lineNo;
|
||||
while (x > 0 && i >= 0) {
|
||||
listingLine[i--] = '0' + x % 10;
|
||||
listingLine[i--] = cast(char) ('0' + x % 10);
|
||||
x /= 10;
|
||||
}
|
||||
while (i >= 0) {
|
||||
@ -1284,7 +1288,7 @@ void listLine() {
|
||||
while (listingColumn < 32) {
|
||||
listingLine[listingColumn++] = ' ';
|
||||
}
|
||||
listingStream.printf("%.32s%.*s\r\n", cast(char*) listingLine, line);
|
||||
listingStream.writefln("%.32s%s", listingLine, line);
|
||||
}
|
||||
|
||||
void listCommentLine() {
|
||||
@ -1303,8 +1307,8 @@ void listLabelTable() {
|
||||
listingStream = null;
|
||||
}
|
||||
ensureListingFileOpen('t', "Writing label table...\n");
|
||||
listingStream.printf("Label table:\r\n");
|
||||
foreach (char[] name; labelTable.keys.sort) {
|
||||
listingStream.writefln("Label table:");
|
||||
foreach (name; labelTable.keys.sort) {
|
||||
Label l = labelTable[name];
|
||||
listingStream.write(l.unused ? 'n' : ' ');
|
||||
listingStream.write(l.unknownInPass1 ? '2' : ' ');
|
||||
@ -1314,8 +1318,8 @@ void listLabelTable() {
|
||||
sign = '-';
|
||||
value = -value;
|
||||
}
|
||||
listingStream.printf(
|
||||
(l.value & 0xffff0000) != 0 ? " %c%08X %.*s\r\n" : " %c%04X %.*s\r\n",
|
||||
listingStream.writefln(
|
||||
(l.value & 0xffff0000) != 0 ? " %s%08X %s" : " %s%04X %s",
|
||||
sign, value, name
|
||||
);
|
||||
}
|
||||
@ -1332,7 +1336,7 @@ void objectByte(ubyte b) {
|
||||
if (objectStream is null) {
|
||||
objectStream = openOutputFile('o', ".obx");
|
||||
if (!getOption('q')) {
|
||||
dout.printf("Writing object file...\n");
|
||||
writeln("Writing object file...");
|
||||
}
|
||||
}
|
||||
try {
|
||||
@ -1438,7 +1442,7 @@ void putCommand(ubyte b) {
|
||||
case AddrMode.ABSOLUTE_X:
|
||||
case AddrMode.ABSOLUTE_Y:
|
||||
case AddrMode.INDIRECT:
|
||||
putWord(value);
|
||||
putWord(cast(ushort) value);
|
||||
break;
|
||||
}
|
||||
switch (addrMode) {
|
||||
@ -1525,37 +1529,37 @@ void assemblyAccumulator(ubyte b, ubyte prefix, int move) {
|
||||
// STA #
|
||||
illegalAddrMode();
|
||||
}
|
||||
putCommand(b + 9);
|
||||
putCommand(cast(ubyte) (b + 9));
|
||||
break;
|
||||
case AddrMode.ABSOLUTE:
|
||||
putCommand(b + 0xd);
|
||||
putCommand(cast(ubyte) (b + 0xd));
|
||||
break;
|
||||
case AddrMode.ZEROPAGE:
|
||||
putCommand(b + 5);
|
||||
putCommand(cast(ubyte) (b + 5));
|
||||
break;
|
||||
case AddrMode.ABSOLUTE_X:
|
||||
putCommand(b + 0x1d);
|
||||
putCommand(cast(ubyte) (b + 0x1d));
|
||||
break;
|
||||
case AddrMode.ZEROPAGE_X:
|
||||
putCommand(b + 0x15);
|
||||
putCommand(cast(ubyte) (b + 0x15));
|
||||
break;
|
||||
case AddrMode.ZEROPAGE_Y:
|
||||
addrMode -= 1;
|
||||
goto case AddrMode.ABSOLUTE_Y;
|
||||
case AddrMode.ABSOLUTE_Y:
|
||||
putCommand(b + 0x19);
|
||||
putCommand(cast(ubyte) (b + 0x19));
|
||||
break;
|
||||
case AddrMode.INDIRECT_X:
|
||||
if ((addrMode & AddrMode.ZERO) != 0) {
|
||||
putWord(0x00a2);
|
||||
}
|
||||
putCommand(b + 1);
|
||||
putCommand(cast(ubyte) (b + 1));
|
||||
break;
|
||||
case AddrMode.INDIRECT_Y:
|
||||
if ((addrMode & AddrMode.ZERO) != 0) {
|
||||
putWord(0x00a0);
|
||||
}
|
||||
putCommand(b + 0x11);
|
||||
putCommand(cast(ubyte) (b + 0x11));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1568,19 +1572,19 @@ void assemblyShift(ubyte b) {
|
||||
// INC @, DEC @
|
||||
illegalAddrMode();
|
||||
}
|
||||
putByte(b + 0xa);
|
||||
putByte(cast(ubyte) (b + 0xa));
|
||||
break;
|
||||
case AddrMode.ABSOLUTE:
|
||||
putCommand(b + 0xe);
|
||||
putCommand(cast(ubyte) (b + 0xe));
|
||||
break;
|
||||
case AddrMode.ZEROPAGE:
|
||||
putCommand(b + 6);
|
||||
putCommand(cast(ubyte) (b + 6));
|
||||
break;
|
||||
case AddrMode.ABSOLUTE_X:
|
||||
putCommand(b + 0x1e);
|
||||
putCommand(cast(ubyte) (b + 0x1e));
|
||||
break;
|
||||
case AddrMode.ZEROPAGE_X:
|
||||
putCommand(b + 0x16);
|
||||
putCommand(cast(ubyte) (b + 0x16));
|
||||
break;
|
||||
default:
|
||||
illegalAddrMode();
|
||||
@ -1594,10 +1598,10 @@ void assemblyCompareIndex(ubyte b) {
|
||||
putCommand(b);
|
||||
break;
|
||||
case AddrMode.ABSOLUTE:
|
||||
putCommand(b + 0xc);
|
||||
putCommand(cast(ubyte) (b + 0xc));
|
||||
break;
|
||||
case AddrMode.ZEROPAGE:
|
||||
putCommand(b + 4);
|
||||
putCommand(cast(ubyte) (b + 4));
|
||||
break;
|
||||
default:
|
||||
illegalAddrMode();
|
||||
@ -1761,7 +1765,7 @@ ubyte calculateBranch(int offset) {
|
||||
} else {
|
||||
dist = offset - 0x7f;
|
||||
}
|
||||
throw new AssemblyError("Branch out of range by " ~ toString(dist) ~ " bytes");
|
||||
throw new AssemblyError("Branch out of range by " ~ to!string(dist) ~ " bytes");
|
||||
}
|
||||
return cast(ubyte) offset;
|
||||
}
|
||||
@ -1844,7 +1848,7 @@ void assemblyMove() {
|
||||
readAddrMode();
|
||||
value1 = value;
|
||||
addrMode1 = addrMode;
|
||||
bit unknown1 = unknownInPass1;
|
||||
bool unknown1 = unknownInPass1;
|
||||
readAddrMode();
|
||||
value2 = value;
|
||||
addrMode2 = addrMode;
|
||||
@ -1971,7 +1975,7 @@ void assemblyDtaInteger(char letter) {
|
||||
storeDtaNumber(value, letter);
|
||||
}
|
||||
|
||||
bit realSign;
|
||||
bool realSign;
|
||||
|
||||
int realExponent;
|
||||
|
||||
@ -2009,7 +2013,7 @@ void putReal() {
|
||||
putByte(cast(ubyte) realMantissa);
|
||||
}
|
||||
|
||||
bit readSign() {
|
||||
bool readSign() {
|
||||
switch (readChar()) {
|
||||
case '+':
|
||||
return false;
|
||||
@ -2022,7 +2026,7 @@ bit readSign() {
|
||||
}
|
||||
|
||||
void readExponent() {
|
||||
bit sign = readSign();
|
||||
bool sign = readSign();
|
||||
char c = readChar();
|
||||
if (c < '0' || c > '9') {
|
||||
illegalCharacter();
|
||||
@ -2165,11 +2169,11 @@ void assemblyDta() {
|
||||
foreach (ubyte b; s) {
|
||||
switch (b & 0x60) {
|
||||
case 0x00:
|
||||
putByte(b + 0x40);
|
||||
putByte(cast(ubyte) (b + 0x40));
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x40:
|
||||
putByte(b - 0x20);
|
||||
putByte(cast(ubyte) (b - 0x20));
|
||||
break;
|
||||
case 0x60:
|
||||
putByte(b);
|
||||
@ -2307,7 +2311,7 @@ void assemblyErt() {
|
||||
}
|
||||
}
|
||||
|
||||
bit readOption() {
|
||||
bool readOption() {
|
||||
switch (readChar()) {
|
||||
case '-':
|
||||
return false;
|
||||
@ -2316,6 +2320,7 @@ bit readOption() {
|
||||
default:
|
||||
illegalCharacter();
|
||||
}
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void assemblyOpt() {
|
||||
@ -2356,7 +2361,7 @@ void originWord(ushort value, char listingChar) {
|
||||
listingLine[listingColumn++] = listingChar;
|
||||
}
|
||||
|
||||
void setOrigin(int addr, bit requestedHeader, bit requestedFFFF) {
|
||||
void setOrigin(int addr, bool requestedHeader, bool requestedFFFF) {
|
||||
origin = loadOrigin = addr;
|
||||
if (requestedHeader || loadingOrigin < 0 || (addr != loadingOrigin && !optionFill)) {
|
||||
blockIndex++;
|
||||
@ -2395,8 +2400,8 @@ void checkHeadersOn() {
|
||||
void assemblyOrg() {
|
||||
noRepeatSkipDirective();
|
||||
readSpaces();
|
||||
bit requestedFFFF = false;
|
||||
bit requestedHeader = false;
|
||||
bool requestedFFFF = false;
|
||||
bool requestedHeader = false;
|
||||
if (column + 2 < line.length && line[column + 1] == ':') {
|
||||
switch (line[column]) {
|
||||
case 'F':
|
||||
@ -2433,7 +2438,7 @@ void assemblyRunIni(ushort addr) {
|
||||
setOrigin(addr, false, false);
|
||||
readSpaces();
|
||||
readUnsignedWord();
|
||||
putWord(value);
|
||||
putWord(cast(ushort) (value));
|
||||
loadingOrigin = -1; // don't fill
|
||||
}
|
||||
|
||||
@ -2463,6 +2468,7 @@ void assemblyIns() {
|
||||
}
|
||||
}
|
||||
Stream stream = openInputFile(filename);
|
||||
scope (exit) stream.close();
|
||||
try {
|
||||
stream.seek(offset, offset >= 0 ? SeekPos.Set : SeekPos.End);
|
||||
} catch (SeekException e) {
|
||||
@ -2481,7 +2487,6 @@ void assemblyIns() {
|
||||
putByte(b);
|
||||
if (length > 0) length--;
|
||||
}
|
||||
// stream.close(); bug in Phobos
|
||||
}
|
||||
|
||||
void assemblyInstruction(char[] instruction) {
|
||||
@ -2805,16 +2810,16 @@ void assemblyInstruction(char[] instruction) {
|
||||
skipping = false;
|
||||
}
|
||||
|
||||
debug ubyte[] testInstruction(char[] l) {
|
||||
debug ubyte[] testInstruction(in char[] l) {
|
||||
objectBuffer.length = 0;
|
||||
line = l;
|
||||
line = l.dup;
|
||||
column = 0;
|
||||
assemblyInstruction(readInstruction());
|
||||
dout.printf("%.*s assembles to", line);
|
||||
write(line, " assembles to");
|
||||
foreach (ubyte b; objectBuffer) {
|
||||
dout.printf(" %02x", b);
|
||||
writef(" %02x", b);
|
||||
}
|
||||
dout.printf("\n");
|
||||
writeln();
|
||||
return objectBuffer;
|
||||
}
|
||||
|
||||
@ -2853,14 +2858,14 @@ void assemblyPair() {
|
||||
|
||||
void assemblyLine() {
|
||||
debug {
|
||||
dout.printf("%.*s\n", line);
|
||||
writeln(line);
|
||||
}
|
||||
currentLocation.lineNo++;
|
||||
totalLines++;
|
||||
column = 0;
|
||||
listingColumn = 6;
|
||||
if (origin >= 0) {
|
||||
listWord(origin);
|
||||
listWord(cast(ushort) origin);
|
||||
listingLine[listingColumn++] = ' ';
|
||||
}
|
||||
char[] label = readLabel();
|
||||
@ -2872,7 +2877,7 @@ void assemblyLine() {
|
||||
throw new AssemblyError("Label declared twice");
|
||||
}
|
||||
currentLabel = new Label(origin);
|
||||
labelTable[label] = currentLabel;
|
||||
labelTable[label.idup] = currentLabel;
|
||||
} else {
|
||||
assert(label in labelTable);
|
||||
currentLabel = labelTable[label];
|
||||
@ -2978,48 +2983,45 @@ void assemblyFile(char[] filename) {
|
||||
if (getOption('p')) {
|
||||
filename = getFullPath(filename);
|
||||
}
|
||||
currentLocation = new Location(filename);
|
||||
currentLocation = new Location(filename.idup);
|
||||
foundEnd = false;
|
||||
Stream stream = openInputFile(filename);
|
||||
line = "";
|
||||
try {
|
||||
readChar: while (!foundEnd) {
|
||||
ubyte c;
|
||||
scope (exit) stream.close();
|
||||
line = null;
|
||||
readChar: while (!foundEnd) {
|
||||
ubyte c;
|
||||
try {
|
||||
stream.read(c);
|
||||
} catch (ReadException e) {
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case '\r':
|
||||
assemblyLine();
|
||||
line = null;
|
||||
try {
|
||||
stream.read(c);
|
||||
} catch (ReadException e) {
|
||||
break;
|
||||
break readChar;
|
||||
}
|
||||
switch (c) {
|
||||
case '\r':
|
||||
assemblyLine();
|
||||
line = "";
|
||||
try {
|
||||
stream.read(c);
|
||||
} catch (ReadException e) {
|
||||
break readChar;
|
||||
}
|
||||
if (c != '\n') {
|
||||
line ~= cast(char) c;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case '\x9b':
|
||||
assemblyLine();
|
||||
line = "";
|
||||
break;
|
||||
default:
|
||||
if (c != '\n') {
|
||||
line ~= cast(char) c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundEnd) {
|
||||
break;
|
||||
case '\n':
|
||||
case '\x9b':
|
||||
assemblyLine();
|
||||
line = null;
|
||||
break;
|
||||
default:
|
||||
line ~= cast(char) c;
|
||||
break;
|
||||
}
|
||||
foundEnd = false;
|
||||
} finally {
|
||||
// stream.close(); // bug in Phobos
|
||||
}
|
||||
if (!foundEnd) {
|
||||
assemblyLine();
|
||||
}
|
||||
foundEnd = false;
|
||||
if (locations.length > 0) {
|
||||
currentLocation = locations[locations.length - 1];
|
||||
locations.length = locations.length - 1;
|
||||
@ -3042,8 +3044,8 @@ void assemblyPass() {
|
||||
wereManyInstructions = false;
|
||||
if (commandLineDefinitions.length > 0) {
|
||||
currentLocation = new Location("command line");
|
||||
foreach (char[] definition; commandLineDefinitions) {
|
||||
int i = find(definition, '=');
|
||||
foreach (definition; commandLineDefinitions) {
|
||||
int i = indexOf(definition, '=');
|
||||
assert(i >= 0);
|
||||
line = definition[0 .. i] ~ " equ " ~ definition[i + 1 .. definition.length];
|
||||
assemblyLine();
|
||||
@ -3061,7 +3063,7 @@ void assemblyPass() {
|
||||
}
|
||||
}
|
||||
|
||||
bit isOption(char[] arg) {
|
||||
bool isOption(char[] arg) {
|
||||
if (arg.length < 2) return false;
|
||||
if (arg[0] == '-') return true;
|
||||
if (arg[0] != '/') return false;
|
||||
@ -3102,12 +3104,12 @@ int main(char[][] args) {
|
||||
char[] definition = null;
|
||||
if (arg[0] == '/') {
|
||||
if (arg.length >= 3 && arg[2] == ':') {
|
||||
definition = arg[3..arg.length];
|
||||
definition = arg[3 .. arg.length];
|
||||
}
|
||||
} else if (i + 1 < args.length && !isOption(args[i + 1])) {
|
||||
definition = args[++i];
|
||||
}
|
||||
if (definition is null || find(definition, '=') < 0) {
|
||||
if (definition is null || indexOf(definition, '=') < 0) {
|
||||
exitCode = 3;
|
||||
}
|
||||
commandLineDefinitions ~= definition;
|
||||
@ -3119,7 +3121,7 @@ int main(char[][] args) {
|
||||
char[] filename = null;
|
||||
if (arg[0] == '/') {
|
||||
if (arg.length >= 3 && arg[2] == ':') {
|
||||
filename = arg[3..arg.length];
|
||||
filename = arg[3 .. arg.length];
|
||||
}
|
||||
} else if (i + 1 < args.length && !isOption(args[i + 1])) {
|
||||
filename = args[++i];
|
||||
@ -3144,10 +3146,10 @@ int main(char[][] args) {
|
||||
exitCode = 3;
|
||||
}
|
||||
if (!getOption('q')) {
|
||||
dout.printf(TITLE ~ "\n");
|
||||
writeln(TITLE);
|
||||
}
|
||||
if (exitCode != 0) {
|
||||
dout.printf(
|
||||
write(
|
||||
"Syntax: xasm source [options]\n"
|
||||
"/c Include false conditionals in listing\n"
|
||||
"/d:label=value Define a label\n"
|
||||
@ -3181,13 +3183,13 @@ int main(char[][] args) {
|
||||
}
|
||||
if (exitCode <= 1) {
|
||||
if (!getOption('q')) {
|
||||
dout.printf("%d lines of source assembled\n", totalLines);
|
||||
writefln("%d lines of source assembled", totalLines);
|
||||
if (objectBytes > 0) {
|
||||
dout.printf("%d bytes written to the object file\n", objectBytes);
|
||||
writefln("%d bytes written to the object file", objectBytes);
|
||||
}
|
||||
}
|
||||
if (getOption('m')) {
|
||||
dout.printf("%.*s:%.*s\n\txasm", makeTarget, makeSources);
|
||||
writef("%s:%s\n\txasm", makeTarget, makeSources);
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
char[] arg = args[i];
|
||||
if (isOption(arg)) {
|
||||
@ -3199,9 +3201,9 @@ int main(char[][] args) {
|
||||
break;
|
||||
case 'o':
|
||||
if (arg[0] == '/') {
|
||||
dout.printf(" /%c:$@", arg[1]);
|
||||
writef(" /%c:$@", arg[1]);
|
||||
} else {
|
||||
dout.printf(" -%c $@", arg[1]);
|
||||
writef(" -%c $@", arg[1]);
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
@ -3209,18 +3211,18 @@ int main(char[][] args) {
|
||||
if (arg[0] == '-'
|
||||
&& (letter == 'd' || letter == 'l' || letter == 't')
|
||||
&& i + 1 < args.length && !isOption(args[i + 1])) {
|
||||
dout.printf(" %.*s %.*s", arg, makeEscape(args[++i]));
|
||||
writef(" %s %s", arg, makeEscape(args[++i]));
|
||||
}
|
||||
else {
|
||||
dout.printf(" %.*s", makeEscape(arg));
|
||||
writef(" %s", makeEscape(arg));
|
||||
}
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
dout.printf(" $<");
|
||||
writef(" $<");
|
||||
}
|
||||
dout.printf("\n");
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
return exitCode;
|
||||
|
Loading…
Reference in New Issue
Block a user