Skip to content

Commit 330a4a3

Browse files
committed
v2.9
1 parent c39204f commit 330a4a3

File tree

13 files changed

+148
-112
lines changed

13 files changed

+148
-112
lines changed

.DS_Store

2 KB
Binary file not shown.

.vscode/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"name": "Launch EaterEmulator",
2424
"request": "launch",
2525
"mainClass": "EaterEmulator",
26-
"projectName": "Java-6502-Emulator_cdf032ed"
26+
"projectName": "Java-6502-Emulator_cdf032ed",
27+
"args": "-verbose"
2728
},
2829
{
2930
"type": "java",

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Java 6502 Emulator
22

3+
## Update: v2.9: ACIA and Command line options!
4+
Thanks to Steve Rubin, the emulator now supports ACIA communication through the command line! Like the VIA, the ACIA's address can be adjusted in the options menu.
5+
6+
Speaking of the command line, the first command line option has been added: `-verbose`. Use it to enable debug messages in the command line, which are now disabled by default.
7+
8+
That's it for this update. Remember to save new config files!
9+
10+
Coming soon:
11+
- ROM preloading via a command line argument
12+
- Implement all 65C02 instructions
13+
- More bug fixes
14+
- Code cleanup
15+
316
## Update: v2.8: Bigger is better!
417
Added support for:
518
- 20x4 LCDs

src/ACIA.java

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import java.util.Scanner;
22

33
public class ACIA {
4-
private byte dataRegister = 0;
5-
private byte commandRegister = 0;
6-
private byte statusRegister =0;
7-
private byte controlRegister = 0;
4+
private byte DATA = 0;
5+
private byte COMMAND = 0;
6+
private byte STATUS =0;
7+
private byte CONTROL = 0;
88

99
private Scanner s;
1010

@@ -13,62 +13,50 @@ public ACIA() {
1313

1414
}
1515

16-
/**
17-
* @return theF dataRegister
18-
*/
19-
public byte getDataRegister() {
20-
return dataRegister;
16+
public byte getDATA() {
17+
return DATA;
2118
}
2219

23-
/**
24-
* @return the commandRegister
25-
*/
26-
public byte getCommandRegister() {
27-
return commandRegister;
20+
public byte getCOMMAND() {
21+
return COMMAND;
2822
}
2923

30-
/**
31-
* @return the statusRegister
32-
*/
33-
public byte getStatusRegister() {
34-
return statusRegister;
24+
public byte getSTATUS() {
25+
return STATUS;
3526
}
3627

37-
/**
38-
* @return the controlRegister
39-
*/
40-
public byte getControlRegister() {
41-
return controlRegister;
28+
public byte getCONTROL() {
29+
return CONTROL;
4230
}
4331

4432
public byte read(short address) {
4533

4634
switch (Short.toUnsignedInt(address) - Bus.ACIA_ADDRESS) {
4735
case 0x00:
4836
try {
49-
dataRegister = (byte) System.in.read();
50-
if (dataRegister == 0xa) dataRegister = 0xd; //convert \n to \r
37+
DATA = (byte) System.in.read();
38+
if (DATA == 0xa) DATA = 0xd; //convert \n to \r
5139

5240
} catch (Exception e) {
5341
System.err.println("Error reading from System.in");
5442
}
55-
return dataRegister; // Read Receiver Data Register
43+
return DATA; // Read Receiver Data Register
5644
case 0x01:
5745
try {
5846
if (System.in.available() >= 1) { // TODO: Remove this later when we go to a windowed interface
59-
statusRegister = 1 << 3;
47+
STATUS = 1 << 3;
6048
} else {
61-
statusRegister = 0 << 3;
49+
STATUS = 0 << 3;
6250
}
6351
} catch (Exception e) {
6452
System.err.println("Error reading from System.in");
6553
}
66-
return statusRegister; // Read Status Register
54+
return STATUS; // Read Status Register
6755
case 0x02:
68-
return commandRegister; // Read Command Register
56+
return COMMAND; // Read Command Register
6957

7058
case 0x03:
71-
return controlRegister; // Read Control Register
59+
return CONTROL; // Read Control Register
7260
default:
7361
System.err.printf("Attempted to read from invalid ACIA register: %04x\n", address);
7462
return 0;
@@ -86,10 +74,10 @@ public void write(short address, byte data) {
8674
// Clear bits 4 through 0 in the Command Register and bit 2 in the Status
8775
// Register
8876
case 0x02:
89-
commandRegister = data;
77+
COMMAND = data;
9078
break; // Write Command Register
9179
case 0x03:
92-
controlRegister = data;
80+
CONTROL = data;
9381
break; // Write Control Register
9482
default:
9583
System.err.printf("Attempted to write to invalid ACIA register: %04x\n", address);

src/Bus.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ public static void write(short address, byte data) {
2424
} else {
2525
EaterEmulator.ram.write(address, data);
2626
}
27-
//System.out.println("Wrote "+data+" at "+address);
27+
//if (EaterEmulator.verbose) System.out.println("Wrote "+data+" at "+address);
2828
}
2929
}

src/CPU.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ boolean getFlag(char flag) {
313313
case 'C':
314314
return ((flags&0b00000001) == 0b00000001);
315315
}
316-
System.out.println("Something has gone wrong in getFlag!");
316+
if (EaterEmulator.verbose) System.out.println("Something has gone wrong in getFlag!");
317317
return false;
318318
}
319319

@@ -371,7 +371,7 @@ void clock() {
371371
System.out.print(",Y");
372372
}
373373
System.out.print(" A:"+Integer.toHexString(Byte.toUnsignedInt(a))+" X:"+Integer.toHexString(Byte.toUnsignedInt(x))+" Y:"+Integer.toHexString(Byte.toUnsignedInt(y))+" Flags:"+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(flags)), 8));
374-
System.out.println();
374+
if (EaterEmulator.verbose) System.out.println();
375375
}
376376
}
377377

@@ -423,7 +423,7 @@ void executeAddressModeFunction(String addressMode) {
423423
IZY();
424424
break;
425425
default:
426-
System.out.println("Something has gone seriously wrong! AddressMode: "+addressMode);
426+
if (EaterEmulator.verbose) System.out.println("Something has gone seriously wrong! AddressMode: "+addressMode);
427427
break;
428428
}
429429
}
@@ -653,7 +653,7 @@ void reset() {
653653
void irq() {
654654
if (!getFlag('I')) {
655655
if (debug)
656-
System.out.println("Interrupted!");
656+
if (EaterEmulator.verbose) System.out.println("Interrupted!");
657657

658658
Bus.write((short)(0x0100+Byte.toUnsignedInt(stackPointer)), (byte)(programCounter>>8));
659659
stackPointer--;
@@ -1308,6 +1308,6 @@ public void TYA() {
13081308
}
13091309

13101310
public void XXX() {
1311-
System.out.println("Illegal Opcode at $"+Integer.toHexString(Short.toUnsignedInt(programCounter)).toUpperCase()+" (" + ROMLoader.byteToHexString(opcode) +") - "+lookup[Byte.toUnsignedInt(opcode)].opcode);
1311+
if (EaterEmulator.verbose) System.out.println("Illegal Opcode at $"+Integer.toHexString(Short.toUnsignedInt(programCounter)).toUpperCase()+" (" + ROMLoader.byteToHexString(opcode) +") - "+lookup[Byte.toUnsignedInt(opcode)].opcode);
13121312
}
13131313
}

src/DisplayPanel.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public DisplayPanel() {
3434
ge.registerFont(courierNewBold);
3535
} catch (FontFormatException | IOException e) {
3636
e.printStackTrace();
37-
System.out.println("Error loading Courier Font!");
37+
if (EaterEmulator.verbose) System.out.println("Error loading Courier Font!");
3838
}
3939

4040
romPageString = EaterEmulator.rom.ROMString.substring(romPage*960,(romPage+1)*960);
@@ -122,13 +122,12 @@ public void paintComponent(Graphics g) {
122122
g.drawString(" IFR: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.via.IFR)), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.via.IFR)+")", 35, 670);
123123
g.drawString(" IER: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.via.IER)), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.via.IER)+")", 35, 700);
124124

125-
//ACIA
126-
g.drawString("ACIA Registers:",350,490);
127-
g.drawString("Data Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getDataRegister())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getDataRegister())+")", 325, 520);
128-
g.drawString("Command Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getCommandRegister())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getCommandRegister())+")", 325, 550);
129-
g.drawString("Status Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getStatusRegister())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getStatusRegister())+")", 325, 580);
130-
g.drawString("Control Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getControlRegister())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getControlRegister())+")", 325, 610);
131-
125+
//ACIA
126+
g.drawString("ACIA Registers:",350,490);
127+
g.drawString("Data Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getDATA())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getDATA())+")", 325, 520);
128+
g.drawString("Command Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getCOMMAND())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getCOMMAND())+")", 325, 550);
129+
g.drawString("Status Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getSTATUS())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getSTATUS())+")", 325, 580);
130+
g.drawString("Control Register: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.acia.getCONTROL())), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.acia.getCONTROL())+")", 325, 610);
132131

133132
//Controls
134133

@@ -237,12 +236,13 @@ public void keyTyped(KeyEvent arg0) {
237236
EaterEmulator.cpu.reset();
238237
EaterEmulator.lcd.reset();
239238
EaterEmulator.via = new VIA();
239+
EaterEmulator.acia = new ACIA();
240240
EaterEmulator.ram = new RAM();
241241
EaterEmulator.gpu.setRAM(EaterEmulator.ram);
242242
ramPageString = EaterEmulator.ram.RAMString.substring(ramPage*960,(ramPage+1)*960);
243243

244244
if (EaterEmulator.debug)
245-
System.out.println("Size: "+this.getWidth()+" x "+this.getHeight());
245+
if (EaterEmulator.verbose) System.out.println("Size: "+this.getWidth()+" x "+this.getHeight());
246246
break;
247247
case ' ':
248248
EaterEmulator.cpu.clock();

src/EaterEmulator.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import javax.swing.*;
99

1010
public class EaterEmulator extends JFrame implements ActionListener {
11-
public static String versionString = "2.8";
11+
public static String versionString = "2.9";
1212
public static boolean debug = false;
13+
14+
public static boolean verbose = false;
1315

1416
//Swing Things
1517
JPanel p = new JPanel();
@@ -182,6 +184,12 @@ public static void main(String[] args) {
182184
javax.swing.SwingUtilities.invokeLater(new Runnable() {
183185
public void run() {
184186
emu = new EaterEmulator();
187+
188+
for (String s : args) {
189+
if (s.equals("-verbose"))
190+
verbose = true;
191+
System.out.println("Running in verbose mode!");
192+
}
185193
}
186194
});
187195
}

src/GPU.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public GPU(RAM vram,boolean isVisible) {
5757
effectiveCharHeight = height/n_rows;
5858

5959
if (debug)
60-
System.out.println("charWidth, charHeight = "+charWidth+", "+charHeight);
60+
if (EaterEmulator.verbose) System.out.println("charWidth, charHeight = "+charWidth+", "+charHeight);
6161

6262
charsetStream = this.getClass().getClassLoader().getResourceAsStream("DylSCII.bin");
6363
byte[] charsetBytes = {};
@@ -95,12 +95,12 @@ public GPU(RAM vram,boolean isVisible) {
9595
// ImageIO.write(charImages[i], "png", new File("charImg/"+i+".png"));
9696
// } catch (Exception e) {
9797
// e.printStackTrace();
98-
// System.out.println("ERROR WRITING CHAR IMAGE");
98+
// if (EaterEmulator.verbose) System.out.println("ERROR WRITING CHAR IMAGE");
9999
// }
100100
// }
101101

102102
if (debug)
103-
System.out.println();
103+
if (EaterEmulator.verbose) System.out.println();
104104
}
105105

106106
if (debug) {
@@ -126,7 +126,7 @@ public static void main(String[] args) {
126126

127127
@SuppressWarnings("resource")
128128
Scanner scan = new Scanner(System.in);
129-
System.out.println("Enter the path to a .bin file with character data:");
129+
if (EaterEmulator.verbose) System.out.println("Enter the path to a .bin file with character data:");
130130

131131
while (true) {
132132
String input = scan.nextLine();
@@ -135,7 +135,7 @@ public static void main(String[] args) {
135135
byte[] newData = new byte[0];
136136
byte[] newRAMArray = new byte[0x8000];
137137

138-
System.out.println("Created new RAM Array with "+newRAMArray.length+" bytes.");
138+
if (EaterEmulator.verbose) System.out.println("Created new RAM Array with "+newRAMArray.length+" bytes.");
139139

140140
try {
141141
newData = Files.readAllBytes(f.toPath());
@@ -145,14 +145,14 @@ public static void main(String[] args) {
145145
System.exit(ABORT);
146146
}
147147

148-
System.out.println("Read "+newData.length+" bytes.");
148+
if (EaterEmulator.verbose) System.out.println("Read "+newData.length+" bytes.");
149149

150150
System.arraycopy(newData, 0, newRAMArray, (gpuMode == 1 | gpuMode == 2) ? 0 : (GPU.VRAM_START_ADDRESS), Math.min(newData.length,newRAMArray.length));
151151

152152
gpu.vram.setRAMArray(newRAMArray);
153153

154154
gpu.scanned = true;
155-
// System.out.println(ROMLoader.ROMString(gpu.vram.getRAMArray(),40,false));
155+
// if (EaterEmulator.verbose) System.out.println(ROMLoader.ROMString(gpu.vram.getRAMArray(),40,false));
156156
// System.exit(0);
157157
}
158158
}
@@ -182,7 +182,7 @@ public void paintComponent(Graphics g) {
182182

183183
g.drawImage(charImages[character],j*effectiveCharWidth,i*effectiveCharHeight,effectiveCharWidth,effectiveCharHeight,this);
184184
if (debug) {
185-
System.out.println("Painted Char #"+character+" @ index "+index+" ("+j*charWidth+","+i*charHeight+")");
185+
if (EaterEmulator.verbose) System.out.println("Painted Char #"+character+" @ index "+index+" ("+j*charWidth+","+i*charHeight+")");
186186
}
187187
}
188188
}
@@ -215,9 +215,9 @@ public void paintComponent(Graphics g) {
215215
);
216216

217217
if (scanned && debug) {
218-
System.out.println("PixelData: "+ROMLoader.byteToHexString(pixelData)+" Color "+c.toString()+" @ ("+i+","+j+"), Index "+Integer.toHexString(index));
219-
System.out.println("PixelData "+Integer.toBinaryString(pixelData)+" R:"+Integer.toBinaryString(red)+" G:"+Integer.toBinaryString(green)+" B:"+Integer.toBinaryString(blue));
220-
System.out.println("NextPowerOf2: "+nextPowerOf2);
218+
if (EaterEmulator.verbose) System.out.println("PixelData: "+ROMLoader.byteToHexString(pixelData)+" Color "+c.toString()+" @ ("+i+","+j+"), Index "+Integer.toHexString(index));
219+
if (EaterEmulator.verbose) System.out.println("PixelData "+Integer.toBinaryString(pixelData)+" R:"+Integer.toBinaryString(red)+" G:"+Integer.toBinaryString(green)+" B:"+Integer.toBinaryString(blue));
220+
if (EaterEmulator.verbose) System.out.println("NextPowerOf2: "+nextPowerOf2);
221221
}
222222

223223
g.setColor(c);

0 commit comments

Comments
 (0)