Skip to content

Commit

Permalink
v2.0
Browse files Browse the repository at this point in the history
You can now hide and show the LCD and GPU windows with the buttons at the top right!
You can now customize the address ranges of the VIA and GPU!
The GPU's resolution and array size is _whatever you want it to be_!
The fonts actually work now!
And **COLORS!!**
  • Loading branch information
DylanSpeiser committed Oct 18, 2022
1 parent 058209e commit 10f4745
Show file tree
Hide file tree
Showing 23 changed files with 756 additions and 41 deletions.
Binary file added .DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/bin/
.project
.classpath
.classpath
/charImg/
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Launch GPU",
"request": "launch",
"mainClass": "GPU",
"projectName": "Java-6502-Emulator_cdf032ed"
},
{
"type": "java",
"name": "Launch EaterEmulator",
"request": "launch",
"mainClass": "EaterEmulator",
"projectName": "Java-6502-Emulator_cdf032ed"
},
{
"type": "java",
"name": "Launch OptionsPane",
"request": "launch",
"mainClass": "OptionsPane",
"projectName": "Java-6502-Emulator_cdf032ed"
},
{
"type": "java",
"name": "Launch Current File",
Expand Down
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"java.project.sourcePaths": [
"src",
"resources"
]
}
Binary file added DylSCII.bin
Binary file not shown.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Java 6502 Emulator


## Update: v2.0 is here!
Whoa! Almost a year after the last update it's back and better than ever! The emulator now includes a character-driven GPU (bitmap modes in development) and SO MUCH customizability!
You can now hide and show the LCD and GPU windows with the buttons at the top right!
You can now customize the address ranges of the VIA and GPU!
The GPU's resolution and array size is _whatever you want it to be_!
The fonts actually work now!
And **COLORS!!**

(The GPU Mode setting doesn't do anything yet, but that will allow me to implement more fun modes in the future.)

Enjoy the new features!
-Dylan

## Overview
This is a project I started because I wanted a place to write and test code for my Ben Eater 6502 kit. After seeing some other emulators written in C++ ~~(by sane people)~~, I tried downloading them but had trouble building them. So, I figured I would just write my own. It was a fun process, and was greatly helped by [OneLoneCoder's NES Emulator Tutorial](https://github.com/OneLoneCoder/olcNES). The LCD simulator was 100% me, and I'm proud of it.

UNIMPLEMENTED FEATURES:
Expand Down
Binary file added courbd.ttf
Binary file not shown.
Binary file added resources/.DS_Store
Binary file not shown.
Binary file added resources/5x8_lcd_hd44780u_a02.ttf
Binary file not shown.
Binary file added resources/DylSCII.bin
Binary file not shown.
Binary file added resources/courbd.ttf
Binary file not shown.
Binary file modified screenshots/screenshot0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/screenshot1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/screenshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/.DS_Store
Binary file not shown.
10 changes: 6 additions & 4 deletions src/Bus.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
public class Bus {
public static int VIA_ADDRESS = 0x7ff0;

public static byte read(short address) {
if (Short.toUnsignedInt(address) >= 32768) {
if (Short.toUnsignedInt(address) >= 0x8000) {
return EaterEmulator.rom.read((short)(address-0x8000));
} else if (Short.toUnsignedInt(address) <= 24592 && Short.toUnsignedInt(address) >= 24576) {
} else if (Short.toUnsignedInt(address) <= VIA_ADDRESS+16 && Short.toUnsignedInt(address) >= VIA_ADDRESS) {
return EaterEmulator.via.read(address);
} else {
return EaterEmulator.ram.read(address);
}
}

public static void write(short address, byte data) {
if (Short.toUnsignedInt(address) >= 32768) {
if (Short.toUnsignedInt(address) >= 0x8000) {
System.err.println("Can't write to ROM! ("+Integer.toHexString(Short.toUnsignedInt(address)).toUpperCase()+")");
} else if (Short.toUnsignedInt(address) <= 24592 && Short.toUnsignedInt(address) >= 24576) {
} else if (Short.toUnsignedInt(address) <= VIA_ADDRESS+16 && Short.toUnsignedInt(address) >= VIA_ADDRESS) {
EaterEmulator.via.write(address, data);
} else {
EaterEmulator.ram.write(address, data);
Expand Down
45 changes: 39 additions & 6 deletions src/DisplayPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,40 @@
import java.awt.event.*;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.io.File;
import java.io.IOException;

public class DisplayPanel extends JPanel implements ActionListener, KeyListener {
Timer t;
int ramPage = 0;
int romPage = 0;

int rightAlignHelper = Math.max(getWidth(), 1334);

public Font courierNewBold;

String ramPageString = "";
String romPageString = "";

public static Color bgColor = Color.blue;
public static Color fgColor = Color.white;

public DisplayPanel() {
super(null);

t = new javax.swing.Timer(16, this);
t.start();
setBackground(Color.blue);
setBackground(bgColor);
setPreferredSize(new Dimension(1936, 966));

try {
courierNewBold = Font.createFont(Font.TRUETYPE_FONT,this.getClass().getClassLoader().getResourceAsStream("courbd.ttf")).deriveFont(20f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(courierNewBold);
} catch (FontFormatException | IOException e) {
e.printStackTrace();
System.out.println("Error loading Courier Font!");
}

romPageString = EaterEmulator.rom.ROMString.substring(romPage*960,(romPage+1)*960);
ramPageString = EaterEmulator.ram.RAMString.substring(ramPage*960,(ramPage+1)*960);
Expand All @@ -31,7 +47,7 @@ public DisplayPanel() {

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.setColor(fgColor);
//g.drawString("Render Mode: paintComponent",5,15);

// g.setColor(getBackground());
Expand All @@ -46,7 +62,7 @@ public void paintComponent(Graphics g) {
g.drawString("Ben Eater 6502 Emulator", 40, 50);

//Version
g.setFont(new Font("Courier New Bold",20,20));
g.setFont(courierNewBold);
g.drawString("v"+EaterEmulator.versionString, 7, 1033);

//Clocks
Expand All @@ -65,7 +81,7 @@ public void paintComponent(Graphics g) {
if (ramPage == 1) {
g.setColor(new Color(0.7f,0f,0f));
g.fillRect(rightAlignHelper-708+36*(Byte.toUnsignedInt(EaterEmulator.cpu.stackPointer)%8), 156+23*((int)Byte.toUnsignedInt(EaterEmulator.cpu.stackPointer)/8), 25, 22);
g.setColor(Color.white);
g.setColor(fgColor);
}

//RAM
Expand Down Expand Up @@ -95,7 +111,7 @@ public void paintComponent(Graphics g) {
counter++;
}

g.setColor(Color.white);
g.setColor(fgColor);
//VIA
g.drawString("VIA Registers:",50,490);
g.drawString("PORT A: "+ROMLoader.padStringWithZeroes(Integer.toBinaryString(Byte.toUnsignedInt(EaterEmulator.via.PORTA)), 8)+" ("+ROMLoader.byteToHexString(EaterEmulator.via.PORTA)+")", 35, 520);
Expand All @@ -120,13 +136,27 @@ public static void drawString(Graphics g, String text, int x, int y) {
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}

public void resetGraphics() {
bgColor = EaterEmulator.options.data.bgColor;
fgColor = EaterEmulator.options.data.fgColor;
setBackground(bgColor);
}

@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(t)) {
EaterEmulator.running = true;

ramPageString = EaterEmulator.ram.RAMString.substring(ramPage*960,(ramPage+1)*960);
EaterEmulator.ROMopenButton.setBounds(rightAlignHelper-150, 15, 125, 25);
EaterEmulator.RAMopenButton.setBounds(rightAlignHelper-150, 45, 125, 25);
EaterEmulator.ShowLCDButton.setBounds(rightAlignHelper-300, 15, 125, 25);
EaterEmulator.ShowGPUButton.setBounds(rightAlignHelper-300, 45, 125, 25);
EaterEmulator.optionsButton.setBounds(rightAlignHelper-450, 15, 125, 55);
this.repaint();

if (!EaterEmulator.options.isVisible())
this.requestFocus();
}
}

Expand Down Expand Up @@ -172,8 +202,11 @@ public void keyTyped(KeyEvent arg0) {
EaterEmulator.lcd.reset();
EaterEmulator.via = new VIA();
EaterEmulator.ram = new RAM();
EaterEmulator.gpu.setRAM(EaterEmulator.ram);
ramPageString = EaterEmulator.ram.RAMString.substring(ramPage*960,(ramPage+1)*960);
System.out.println("Size: "+this.getWidth()+" x "+this.getHeight());

if (EaterEmulator.debug)
System.out.println("Size: "+this.getWidth()+" x "+this.getHeight());
break;
case ' ':
EaterEmulator.cpu.clock();
Expand Down
74 changes: 68 additions & 6 deletions src/EaterEmulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@

public class EaterEmulator extends JFrame implements ActionListener {
public static EaterEmulator emu;
public static String versionString = "1.4";
public static String versionString = "2.0";
public static boolean debug = false;

//Swing Things
JPanel p = new JPanel();
JPanel header = new JPanel();
JFileChooser fc = new JFileChooser();
public static JFileChooser fc = new JFileChooser();
public static JButton ROMopenButton = new JButton("Open ROM File");
public static JButton RAMopenButton = new JButton("Open RAM File");

public static JButton ShowLCDButton = new JButton("Hide LCD");
public static JButton ShowGPUButton = new JButton("Show GPU");

public static JButton optionsButton = new JButton("Options");

//Clock Stuff
public static Thread clockThread;
Expand All @@ -32,8 +38,14 @@ public class EaterEmulator extends JFrame implements ActionListener {
public static VIA via = new VIA();
public static Bus bus = new Bus();
public static CPU cpu = new CPU();

public DisplayPanel GraphicsPanel = new DisplayPanel();
public static GPU gpu = new GPU(ram);

public static DisplayPanel GraphicsPanel = new DisplayPanel();

//Options
public static OptionsPane options = new OptionsPane();

public static boolean running = false;

public EaterEmulator() {
//Swing Stuff:
Expand All @@ -52,10 +64,30 @@ public EaterEmulator() {
RAMopenButton.setBounds(getWidth()-150, 45, 125, 25);
RAMopenButton.setBackground(Color.white);
GraphicsPanel.add(RAMopenButton);

//Show Extra Windows buttons
ShowLCDButton.setVisible(true);
ShowLCDButton.addActionListener(this);
ShowLCDButton.setBounds(getWidth()-300, 15, 125, 25);
ShowLCDButton.setBackground(Color.white);
GraphicsPanel.add(ShowLCDButton);

ShowGPUButton.setVisible(true);
ShowGPUButton.addActionListener(this);
ShowGPUButton.setBounds(getWidth()-300, 45, 125, 25);
ShowGPUButton.setBackground(Color.white);
GraphicsPanel.add(ShowGPUButton);

//Options Button
optionsButton.setVisible(true);
optionsButton.addActionListener(this);
optionsButton.setBounds(getWidth()-450, 15, 125, 55);
optionsButton.setBackground(Color.white);
GraphicsPanel.add(optionsButton);

//file chooser
fc.setVisible(true);
fc.setCurrentDirectory(new File(System.getProperty("user.home") + System.getProperty("file.separator")+ "Downloads"));
fc.setCurrentDirectory(new File(options.data.defaultFileChooserDirectory));

//Clock thread setup
clockThread = new Thread(() -> {
Expand All @@ -74,10 +106,16 @@ public EaterEmulator() {

//Final Setup
GraphicsPanel.setVisible(true);
GraphicsPanel.t.addActionListener(this);
options.setVisible(false);

this.setTitle("6502 Emulator");
this.setContentPane(GraphicsPanel);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);

options.updateSwingComponents();
options.applySwingValues();
}

@Override
Expand All @@ -102,10 +140,34 @@ public void actionPerformed(ActionEvent e) {
GraphicsPanel.requestFocus();
GraphicsPanel.ramPageString = EaterEmulator.ram.RAMString.substring(GraphicsPanel.ramPage*960,(GraphicsPanel.ramPage+1)*960);
cpu.reset();
} else if (e.getSource().equals(ShowLCDButton)) {
lcd.setVisible(!lcd.isVisible());
} else if (e.getSource().equals(ShowGPUButton)) {
gpu.setVisible(!gpu.isVisible());
} else if (e.getSource().equals(optionsButton)) {
options.setVisible(!options.isVisible());
} else if (e.getSource().equals(GraphicsPanel.t)) {
if (!gpu.isVisible()) {
ShowGPUButton.setText("Show GPU");
} else {
ShowGPUButton.setText("Hide GPU");
}

if (!lcd.isVisible()) {
ShowLCDButton.setText("Show LCD");
} else {
ShowLCDButton.setText("Hide LCD");
}
}


}

public static void main(String[] args) {
emu = new EaterEmulator();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
emu = new EaterEmulator();
}
});
}
}
Loading

0 comments on commit 10f4745

Please sign in to comment.