Generating binary AppleSoft program.

This commit is contained in:
Rob Greene 2018-05-07 23:21:29 -05:00
parent 3dd328cb1a
commit 731930b56e
5 changed files with 113 additions and 0 deletions

View File

@ -1,5 +1,7 @@
package net.sf.applecommander.bastokenizer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@ -25,4 +27,21 @@ public class Line {
ps.println();
}
}
public int toBytes(int address, ByteArrayOutputStream os) throws IOException {
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
for (Statement stmt : statements) {
if (tmp.size() > 0) tmp.write(':');
stmt.toBytes(tmp);
}
int nextAddress = address + tmp.size() + 5;
os.write(nextAddress);
os.write(nextAddress >> 8);
os.write(lineNumber);
os.write(lineNumber >> 8);
tmp.writeTo(os);
os.write(0x00);
return nextAddress;
}
}

View File

@ -16,5 +16,42 @@ public class Main {
Parser parser = new Parser(tokens);
Program program = parser.parse();
program.prettyPrint(System.out);
int address = 0x801;
byte[] data = program.toBytes(address);
print(address, data, false);
print(address, data, true);
}
public static void print(int address, byte[] data, boolean forApple) {
final int line = 16;
int offset = 0;
while (offset < data.length) {
System.out.printf("%04x: ", address);
for (int i=0; i<line; i++) {
if (offset < data.length) {
System.out.printf("%02x ", data[offset]);
} else if (!forApple) {
System.out.printf(".. ");
}
offset++;
}
System.out.print(" ");
if (!forApple) {
offset -= line;
for (int i=0; i<line; i++) {
char ch = ' ';
if (offset < data.length) {
byte b = data[offset];
ch = (b >= ' ') ? (char)b : '.';
}
System.out.printf("%c", ch);
offset++;
}
}
System.out.printf("\n");
address += line;
}
}
}

View File

@ -1,5 +1,7 @@
package net.sf.applecommander.bastokenizer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@ -12,4 +14,12 @@ public class Program {
line.prettyPrint(ps);
}
}
public byte[] toBytes(int address) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (Line line : lines) address = line.toBytes(address, os);
os.write(0x00);
os.write(0x00);
return os.toByteArray();
}
}

View File

@ -1,5 +1,7 @@
package net.sf.applecommander.bastokenizer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@ -12,4 +14,8 @@ public class Statement {
token.prettyPrint(ps);
}
}
public void toBytes(ByteArrayOutputStream os) throws IOException {
for (Token t : tokens) t.toBytes(os);
}
}

View File

@ -1,6 +1,9 @@
package net.sf.applecommander.bastokenizer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Optional;
public class Token {
public final int line;
@ -58,6 +61,44 @@ public class Token {
}
}
public void toBytes(ByteArrayOutputStream os) throws IOException {
switch (type) {
case COMMENT:
os.write(ApplesoftKeyword.REM.code);
os.write(text.getBytes());
break;
case EOL:
os.write(0x00);
break;
case IDENT:
os.write(text.getBytes());
break;
case KEYWORD:
os.write(keyword.code);
break;
case NUMBER:
if (Math.rint(number) == number) {
os.write(Integer.toString(number.intValue()).getBytes());
} else {
os.write(Double.toString(number).getBytes());
}
break;
case STRING:
os.write('"');
os.write(text.getBytes());
os.write('"');
break;
case SYNTAX:
Optional<ApplesoftKeyword> opt = ApplesoftKeyword.find(text);
if (opt.isPresent()) {
os.write(opt.get().code);
} else {
os.write(text.getBytes());
}
break;
}
}
public static Token eol(int line) {
return new Token(line, Type.EOL, null, null, null);
}