Uploaded stuff.

main
aieque 2020-12-31 19:40:49 +01:00
parent a0ff1cf91a
commit 383396b35c
453 changed files with 16578 additions and 25302 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
*** SESSION Dec 23, 2020 07:03:49.60 -------------------------------------------
*** SESSION Dec 25, 2020 11:04:14.20 -------------------------------------------
*** SESSION Dec 27, 2020 18:11:45.63 -------------------------------------------
*** SESSION Dec 28, 2020 07:25:11.73 -------------------------------------------
*** SESSION Dec 29, 2020 08:41:22.31 -------------------------------------------
*** SESSION Dec 29, 2020 20:45:41.12 -------------------------------------------
*** SESSION Dec 30, 2020 07:33:14.96 -------------------------------------------
*** SESSION Dec 31, 2020 06:46:47.09 -------------------------------------------

View File

@ -1,43 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x21:
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31:
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0xAF:
registers.writeA(registers.readA() ^ registers.readA());
break;
}
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core;
public class Registers {
}

View File

@ -1,35 +0,0 @@
package playingcoffee.core;
import javax.swing.JOptionPane;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x31:
}
}
}

View File

@ -1,12 +0,0 @@
package playingcoffee.core;
public class CPU {
public CPU() {
}
public void clock() {
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core.cpu;
public class MicroOps {
}

View File

@ -1,35 +0,0 @@
package playingcoffee.core;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class MMU {
private int ram[];
public void loadBootRom() {
byte[] data;
try {
data = Files.readAllBytes(Paths.get("DMG_ROM.bin"));
for (int i = 0; i < data.length; i++) {
ram[i] = Byte.toUnsignedInt(data[i]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public MMU() {
ram = new int[0x10000];
}
public void write(int value, int address) {
ram[address] = value;
}
public int read(int address) {
return ram[address];
}
}

View File

@ -1,35 +0,0 @@
package playingcoffee.core;
import javax.swing.JOptionPane;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// Is subject to change.
switch (opcode) {
case 0x00: // NOP
break;
default:
new JOptionPane(String.format("Unknown opcode: 0x%2x", opcode), JOptionPane.OK_OPTION).show();;
}
}
}

View File

@ -1,112 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
public class CPUDebugger {
private JFrame frame;
private JTable memoryViewTable;
private CPU cpu;
private MMU mmu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
cpu = new CPU();
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
JList<String> registerList = new JList<String>();
memoryViewTable = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblRegisters)
.addGap(18))
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblMemoryView)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,108 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static final int[] INSTRUCTION_CYCLE_COUNT = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16,
8, 12, 12, -1, 12, 16, 8, 16, 8, 16, 12, -1, 12, -1, 8, 16,
12, 12, 8, -1, -1, 16, 8, 16, 16, 4, 16, -1, -1, -1, 8, 16,
12, 12, 8, 4, -1, 16, 8, 16, 12, 8, 16, 4, -1, -1, 8, 16
};
public static final int[] PREFIXED_CYCLE_COUNT = {
8, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 8, 8, 16, 8,
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
cycles += INSTRUCTION_CYCLE_COUNT[opcode];
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
cycles += INSTRUCTION_CYCLE_COUNT[opcode & 0xF];
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,14 +0,0 @@
package playingcoffee.core;
public class CPU {
private final Memory memory;
public CPU() {
}
public void clock() {
}
}

View File

@ -1,11 +0,0 @@
package playingcoffee.core;
public class CPU {
private Registers registers;
public Registers getRegisters() {
return registers;
}
}

View File

@ -1,93 +0,0 @@
package playingcoffee.core;
public class Registers {
private int af;
private int bc;
private int de;
private int hl;
public int pc;
public int sp;
public int readAF() {
return af;
}
public int readBC() {
return bc;
}
public int readDE() {
return de;
}
public int readHL() {
return hl;
}
public int readA() {
return af & 0xff;
}
public void writeA(int a) {
this.af = a & 0xff;
}
public int readF() {
return (af >> 8) & 0xff;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core;
public class Memory {
}

View File

@ -1,123 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
public int pc;
public int sp;
public static final int FLAG_Z = 1 << 7;
public static final int FLAG_N = 1 << 6;
public static final int FLAG_H = 1 << 5;
public static final int FLAG_C = 1 << 4;
public void setFlag(int flag, boolean value) {
if (value)
}
public int readAF() {
return a << 8 | f;
}
public int readBC() {
return b << 8 | c;
}
public int readDE() {
return d << 8 | e;
}
public int readHL() {
return h << 8 | l;
}
public void writeAF(int af) {
a = (af >> 8) & 0xFF;
f = af & 0xFF;
}
public void writeBC(int bc) {
b = (bc >> 8) & 0xFF;
c = bc & 0xFF;
}
public void writeDE(int de) {
d = (de >> 8) & 0xFF;
e = de & 0xFF;
}
public void writeHL(int hl) {
h = (hl >> 8) & 0xFF;
l = hl & 0xFF;
}
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
}

View File

@ -1,68 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() != 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,16 +0,0 @@
package playingcoffee.core.cpu;
import java.util.ArrayList;
import java.util.List;
import playingcoffee.core.cpu.microop.MicroOp;
public class Opcode {
List<MicroOp> microOps;
public Opcode(MicroOp... ops) {
microOps = new ArrayList<MicroOp>();
}
}

View File

@ -1,23 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
}
}

View File

@ -1,103 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16,
8, 12, 12, -1, 12, 16, 8, 16, 8, 16, 12, -1, 12, -1, 8, 16,
12, 12, 8, -1, -1, 16, 8, 16, 16, 4, 16, -1, -1, -1, 8, 16,
12, 12, 8, 4, -1, 16, 8, 16, 12, 8, 16, 4, -1, -1, 8, 16
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
cycles += instructionCycle[opcode];
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
cycles += instructionCycle[opcode];
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,17 +0,0 @@
package playingcoffee.core;
public class MMU {
private int ram[];
public void write(int value, int address) {
ram[address] = value;
}
public int read(int address) {
return ram[address];
}
}

View File

@ -1,110 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
public class CPUDebugger {
private JFrame frame;
private JTable table;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public CPUDebugger() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
JList<String> list = new JList<String>();
table = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblRegisters)
.addGap(18))
.addComponent(list, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(table, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE)
.addComponent(lblMemoryView))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(list, GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE)
.addComponent(table, GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,50 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
System.out.println(registers.readL());
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
break;
}
}
}

View File

@ -1,106 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16,
8, 12, 12, -1, 12, 16, 8, 16, 8, 16, 12, -1, 12, -1, 8, 16,
12, 12, 8, -1, -1, 16, 8, 16, 16, 4, 16, -1, -1, -1, 8, 16,
12, 12, 8, 4, -1, 16, 8, 16, 12, 8, 16, 4, -1, -1, 8, 16
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
cycles += instructionCycle[opcode];
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
cycles += instructionCycle[opcode];
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,46 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
break;
}
}
}

View File

@ -1,9 +0,0 @@
package playingcoffee.core.cpu;
public class Opcode {
public Opcode(MicroOp ops...) {
}
}

View File

@ -1,12 +0,0 @@
package playingcoffee.core.cpu;
public abstract class MicroOp {
private int cycles;
public int getLength() {
return cycles;
}
public abstract void execute();
}

View File

@ -1,80 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core.cpu;
public class Opcode {
}

View File

@ -1,113 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
private int pc;
private int sp;
public int readA() {
return a;
}
public void writeA(int a) {
verify(a);
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
verify(a);
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
verify(a);
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
verify(a);
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
verify(a);
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
verify(a);
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
verify(a);
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
verify(a);
this.l = l;
}
public int readPC() {
return pc;
}
public void writePC(int pc) {
verify(a);
this.pc = pc;
}
public int readSP() {
return sp;
}
public void writeSP(int sp) {
verify(a);
this.sp = sp;
}
}

View File

@ -1,53 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
break;
}
}
}

View File

@ -1,118 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
public class CPUDebugger {
private JFrame frmCpuDebugger;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frmCpuDebugger.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU(mmu);
updateValues();
}
private void updateValues() {
DefaultListModel<String> model = new DefaultListModel<String>();
model.addElement("AF: 0x" + Integer.toHexString(cpu.getRegisters().readAF()));
model.addElement("BC: 0x" + Integer.toHexString(cpu.getRegisters().readBC()));
model.addElement("DE: 0x" + Integer.toHexString(cpu.getRegisters().readDE()));
model.addElement("HL: 0x" + Integer.toHexString(cpu.getRegisters().readHL()));
model.addElement("PC: 0x" + Integer.toHexString(cpu.getRegisters().readPC()));
model.addElement("SP: 0x" + Integer.toHexString(cpu.getRegisters().readSP()));
registerList.setModel(model);
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frmCpuDebugger = new JFrame();
frmCpuDebugger.setTitle("CPU Debugger");
frmCpuDebugger.setBounds(100, 100, 350, 350);
frmCpuDebugger.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
btnStep.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cpu.cycle();
updateValues();
}
});
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
GroupLayout groupLayout = new GroupLayout(frmCpuDebugger.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(registerList, GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)
.addComponent(lblRegisters)
.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED, 198, Short.MAX_VALUE)
.addComponent(btnReset)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblRegisters)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)
.addGap(51)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnReset)
.addComponent(btnStep))
.addContainerGap())
);
frmCpuDebugger.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,120 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.ListModel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
public class CPUDebugger {
private JFrame frame;
private JTable memoryViewTable;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU();
updateValues();
}
private void updateValues() {
DefaultListModel<String> model = new DefaultListModel<String>();
model.
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
memoryViewTable = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addComponent(lblRegisters)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblMemoryView)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,93 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
private int pc;
private int sp;
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
public int readPC() {
return pc;
}
public void writePC(int pc) {
this.pc = pc;
}
public int readSP() {
return sp;
}
public void writeSP(int sp) {
this.sp = sp;
}
}

View File

@ -1,13 +0,0 @@
package playingcoffee.core;
public class Gameboy {
private CPU m_CPU;
public Gameboy() {
m_CPU = new CPU();
}
}

View File

@ -1,87 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,94 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
private int pc;
private int sp;
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
public int readPC() {
return pc;
}
public void writePC(int pc) {
this.pc = pc;
}
public int readSP() {
return sp;
}
public void writeSP(int sp) {
this.sp = sp;
}
}

View File

@ -1,17 +0,0 @@
package playingcoffee.core.cpu;
import playingcoffee.core.cpu.microop.MicroOp;
public class Opcode {
MicroOp microOps[];
public Opcode(MicroOp... ops) {
microOps = ops;
}
public void execute() {
for(MicroOp op : microOps)
op.execute();
}
}

View File

@ -1,23 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.readPC());
}
}

View File

@ -1,25 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
public Opcode(Op... ops) {
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(regs, mmu);
}
public interface Op {
public void execute(Registers regs, MMU mmu);
}
public class Read16BitOperand implements Op {
}
}

View File

@ -1,21 +0,0 @@
package playingcoffee.core.cpu;
import playingcoffee.core.Memory;
public class CPU {
private final Memory memory;
public CPU(Memory memory) {
this.memory = memory;
}
public void registerOpcodes() {
// Example: instructions[0x01] = new OpcodeBuilder().read(OpcodeArgument.C, OpcodeArgument.PC_INC).read(OpcodeArgument.B, OpcodeArgument.PC_INC);
}
public void clock() {
}
}

View File

@ -1,22 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
public Opcode(Op... ops) {
this.ops = ops;
}
public void execute() {
for (Op op : ops)
op.execute();
}
public class Op {
}
}

View File

@ -1,17 +0,0 @@
package playingcoffee.core.cpu;
import java.util.ArrayList;
import java.util.List;
import playingcoffee.core.cpu.microop.MicroOp;
public class Opcode {
List<MicroOp> microOps;
public Opcode(MicroOp... ops) {
microOps = new ArrayList<MicroOp>();
microOps.add(ops);
}
}

View File

@ -1,118 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class CPUDebugger {
private JFrame frmCpuDebugger;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frmCpuDebugger.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU(mmu);
updateValues();
}
private void updateValues() {
DefaultListModel<String> model = new DefaultListModel<String>();
model.addElement("AF: 0x" + Integer.toHexString(cpu.getRegisters().readAF()));
model.addElement("BC: 0x" + Integer.toHexString(cpu.getRegisters().readBC()));
model.addElement("DE: 0x" + Integer.toHexString(cpu.getRegisters().readDE()));
model.addElement("HL: 0x" + Integer.toHexString(cpu.getRegisters().readHL()));
model.addElement("PC: 0x" + Integer.toHexString(cpu.getRegisters().readPC()));
model.addElement("SP: 0x" + Integer.toHexString(cpu.getRegisters().readSP()));
registerList.setModel(model);
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frmCpuDebugger = new JFrame();
frmCpuDebugger.setTitle("CPU Debugger");
frmCpuDebugger.setBounds(100, 100, 350, 350);
frmCpuDebugger.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
btnStep.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
GroupLayout groupLayout = new GroupLayout(frmCpuDebugger.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(registerList, GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)
.addComponent(lblRegisters)
.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED, 198, Short.MAX_VALUE)
.addComponent(btnReset)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblRegisters)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)
.addGap(51)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnReset)
.addComponent(btnStep))
.addContainerGap())
);
frmCpuDebugger.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,106 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
public class CPUDebugger {
private JFrame frame;
private JTable table;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
JList<String> list = new JList<String>();
table = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblRegisters)
.addGap(18))
.addComponent(list, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblMemoryView)
.addComponent(table, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(table, GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(list, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,35 +0,0 @@
package playingcoffee.core;
import javax.swing.JOptionPane;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// Is subject to change.
switch (opcode) {
case 0x00: // NOP
break;
default:
JOptionPane.showMessageDialog(null, String.format("Unknown opcode: 0x%2x", opcode));
}
}
}

View File

@ -1,68 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,7 +0,0 @@
package playingcoffee.core;
public class CPU {
}

View File

@ -1,119 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
public int pc;
public int sp;
public static final int FLAG_Z = 1 << 7;
public void setFlag(int flag, boolean value) {
}
public int readAF() {
return a << 8 | f;
}
public int readBC() {
return b << 8 | c;
}
public int readDE() {
return d << 8 | e;
}
public int readHL() {
return h << 8 | l;
}
public void writeAF(int af) {
a = (af >> 8) & 0xFF;
f = af & 0xFF;
}
public void writeBC(int bc) {
b = (bc >> 8) & 0xFF;
c = bc & 0xFF;
}
public void writeDE(int de) {
d = (de >> 8) & 0xFF;
e = de & 0xFF;
}
public void writeHL(int hl) {
h = (hl >> 8) & 0xFF;
l = hl & 0xFF;
}
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
}

View File

@ -1,38 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
private int stored;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute();
}
public interface Op {
public void execute();
}
public class Read16BitOperand implements Op {
@Override
public void execute() {
stored = (mmu.read(registers.pc++) << 8) | mmu.read(registers.pc);
}
}
}

View File

@ -1,16 +0,0 @@
package playingcoffee.core.cpu;
import java.util.ArrayList;
import java.util.List;
import playingcoffee.core.cpu.microop.MicroOp;
public class Opcode {
List<MicroOp> microOps;
public Opcode(MicroOp... ops) {
microOps = new ArrayList<MicroOp>(ops);
}
}

View File

@ -1,123 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
public int pc;
public int sp;
public static final int FLAG_Z = 1 << 7;
public static final int FLAG_N = 1 << 6;
public static final int FLAG_H = 1 << 5;
public static final int FLAG_C = 1 << 4;
public void setFlag(int flag, boolean value) {
if (value)
f |= flag;
}
public int readAF() {
return a << 8 | f;
}
public int readBC() {
return b << 8 | c;
}
public int readDE() {
return d << 8 | e;
}
public int readHL() {
return h << 8 | l;
}
public void writeAF(int af) {
a = (af >> 8) & 0xFF;
f = af & 0xFF;
}
public void writeBC(int bc) {
b = (bc >> 8) & 0xFF;
c = bc & 0xFF;
}
public void writeDE(int de) {
d = (de >> 8) & 0xFF;
e = de & 0xFF;
}
public void writeHL(int hl) {
h = (hl >> 8) & 0xFF;
l = hl & 0xFF;
}
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core;
public class Op {
}

View File

@ -1,72 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,60 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
break;
default:
System.err.printf("Unknown opcode: 0x%fx\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
}
}

View File

@ -1,20 +0,0 @@
package playingcoffee.core.cpu;
import playingcoffee.core.Memory;
public class CPU {
private final Memory memory;
public CPU(Memory memory) {
this.memory = memory;
}
public void registerOpcodes() {
// Example: instructions[0x01] = new OpcodeBuilder().read(OpcodeArgument.C, OpcodeArgument.PC_INC).read(OpcodeArgument.B, OpcodeArgument.PC_INC);
}
public void clock() {
}
}

View File

@ -1,30 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
public Opcode(Op... ops) {
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(regs, mmu);
}
public interface Op {
public void execute(Registers regs, MMU mmu);
}
public class Read16BitOperand implements Op {
@Override
public void execute(Registers regs, MMU mmu) {
}
}
}

View File

@ -1,25 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
public Opcode(Op... ops) {
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(regs, mmu);
}
public interface Op {
public void execute(Registers regs, MMU mmu);
}
public class Read16BitOp implements {
}
}

View File

@ -1,11 +0,0 @@
package playingcoffee.core;
public class Gameboy {
private CPU m_CPU;
public Gameboy() {
m_CPU = new CPU();
}
}

View File

@ -1,30 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// Is subject to change.
switch (opcode) {
}
}
}

View File

@ -1,100 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16,
8, 12, 12, -1, 12, 16, 8, 16, 8, 16, 12, -1, 12, -1, 8, 16
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,15 +0,0 @@
package playingcoffee.core;
public class Gameboy {
private CPU m_CPU;
public Gameboy() {
m_CPU = new CPU();
while (true) {
m_CPU.clock();
}
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core.cpu;
public abstract class MicroOp {
}

View File

@ -1,64 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
}
}

View File

@ -1,120 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.ListModel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
public class CPUDebugger {
private JFrame frame;
private JTable memoryViewTable;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU();
updateValues();
}
private void updateValues() {
DefaultListModel<String> model = new DefaultListModel<String>();
model.addElement("");
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
memoryViewTable = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addComponent(lblRegisters)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblMemoryView)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,16 +0,0 @@
package playingcoffee.core;
import playingcoffee.core.Memory;
public class CPU {
private final Memory memory;
public CPU(Memory memory) {
this.memory = memory;
}
public void clock() {
}
}

View File

@ -1,35 +0,0 @@
package playingcoffee.core;
import javax.swing.JOptionPane;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// Is subject to change.
switch (opcode) {
case 0x00: // NOP
break;
default:
new JOptionPane(String.format("Unknown opcode: 0x%2x", opcode), JOptionPane.OK_OPTION);
}
}
}

View File

@ -1,25 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.readPC());
registers.writePC(registers.readPC() + 1);
}
}

View File

@ -1,24 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
}
}

View File

@ -1,38 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
private int stored;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(this);
}
public interface Op {
public void execute(Opcode opcode);
}
public class Read16BitOperand implements Op {
@Override
public void execute(Opcode opcode) {
opcode.stored =
}
}
}

View File

@ -1,36 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(regs, mmu);
}
public interface Op {
public void execute(Opcode opcode);
}
public class Read16BitOperand implements Op {
@Override
public void execute(Opcode opcode) {
}
}
}

View File

@ -1,30 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
public Opcode(Op... ops) {
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(regs, mmu);
}
public interface Op {
public void execute(Registers regs, MMU mmu);
}
public class Read16BitOperand implements Op {
@Override
public void execute(Registers regs, MMU mmu) {
}
}
}

View File

@ -1,24 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
}
}

View File

@ -1,93 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
private int pc;
private int sp;
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
public int readPC() {
return pc;
}
public void writePC(int pc) {
this.pc = pc;
}
public int readSP() {
return sp;
}
public void writeSP(int sp) {
this.sp = sp;
}
}

View File

@ -1,97 +0,0 @@
package playingcoffee.core;
public class Registers {
private int a, f;
private int b, c;
private int d, e;
private int h, l;
private int pc;
private int sp;
public int readAF() {
return a << 8 | F;
}
public int readA() {
return a;
}
public void writeA(int a) {
this.a = a;
}
public int readF() {
return f;
}
public void writeF(int f) {
this.f = f;
}
public int readB() {
return b;
}
public void writeB(int b) {
this.b = b;
}
public int readC() {
return c;
}
public void writeC(int c) {
this.c = c;
}
public int readD() {
return d;
}
public void writeD(int d) {
this.d = d;
}
public int readE() {
return e;
}
public void writeE(int e) {
this.e = e;
}
public int readH() {
return h;
}
public void writeH(int h) {
this.h = h;
}
public int readL() {
return l;
}
public void writeL(int l) {
this.l = l;
}
public int readPC() {
return pc;
}
public void writePC(int pc) {
this.pc = pc;
}
public int readSP() {
return sp;
}
public void writeSP(int sp) {
this.sp = sp;
}
}

View File

@ -1,72 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,5 +0,0 @@
package playingcoffee.core;
public class CPU {
}

View File

@ -1,36 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(regs, mmu);
}
public interface Op {
public void execute(Registers regs, MMU mmu);
}
public class Read16BitOperand implements Op {
@Override
public void execute(Registers regs, MMU mmu) {
}
}
}

View File

@ -1,14 +0,0 @@
package playingcoffee.core;
public class CPU {
private final Memory memory;
public CPU(Memory memory) {
this.memory = memory;
}
public void clock() {
}
}

View File

@ -1,37 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
private int stored;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute();
}
public interface Op {
public void execute();
}
public class Read16BitOperand implements Op {
@Override
public void execute() {
stored = (mmu.read(registers.pc++) << 8) | mmu.read(registers.pc);
}
}
}

View File

@ -1,48 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32:
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
break;
}
}
}

View File

@ -1,100 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16,
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,15 +0,0 @@
package playingcoffee.core;
public class MMU {
private int ram[];
public void write(int value, int address) {
ram[address] = value;
}
public int read(int address) {
return ram[address];
}
}

View File

@ -1,43 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class CPUDebugger {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public CPUDebugger() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

View File

@ -1,110 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
public class CPUDebugger {
private JFrame frame;
private JTable memoryViewTable;
private CPU cpu;
private MMU mmu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
JList<String> registerList = new JList<String>();
memoryViewTable = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addGroup(groupLayout.createSequentialGroup()
.addComponent(lblRegisters)
.addGap(18))
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblMemoryView)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,33 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x31:
}
}
}

View File

@ -1,36 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute(this);
}
public interface Op {
public void execute(Opcode opcode);
}
public class Read16BitOperand implements Op {
@Override
public void execute(Opcode opcode) {
opcode.registers.pc = 0x00;
}
}
}

View File

@ -1,70 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,39 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
private int operand;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute();
}
public interface Op {
public void execute();
}
public class Read16BitOperand implements Op {
@Override
public void execute() {
operand = (mmu.read(registers.pc++) << 8) | mmu.read(registers.pc);
}
}
public class
}

View File

@ -1,79 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
}
public void decodeOpcode(int opcode) {
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,109 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
public class CPUDebugger {
private JFrame frmCpuDebugger;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frmCpuDebugger.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU();
updateValues();
}
private void updateValues() {
DefaultListModel<String> model = new DefaultListModel<String>();
model.addElement("AF: 0x" + Integer.toHexString(cpu.getRegisters().readAF()));
model.addElement("BC: 0x" + Integer.toHexString(cpu.getRegisters().readBC()));
model.addElement("DE: 0x" + Integer.toHexString(cpu.getRegisters().readDE()));
model.addElement("HL: 0x" + Integer.toHexString(cpu.getRegisters().readHL()));
registerList.setModel(model);
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frmCpuDebugger = new JFrame();
frmCpuDebugger.setTitle("CPU Debugger");
frmCpuDebugger.setBounds(100, 100, 350, 350);
frmCpuDebugger.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
GroupLayout groupLayout = new GroupLayout(frmCpuDebugger.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(registerList, GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)
.addComponent(lblRegisters)
.addGroup(Alignment.TRAILING, groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED, 198, Short.MAX_VALUE)
.addComponent(btnReset)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblRegisters)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)
.addGap(51)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnReset)
.addComponent(btnStep))
.addContainerGap())
);
frmCpuDebugger.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,113 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.DefaultListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
public class CPUDebugger {
private JFrame frmCpuDebugger;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frmCpuDebugger.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU();
updateValues();
}
private void updateValues() {
DefaultListModel<String> model = new DefaultListModel<String>();
model.addElement("AF: 0x" + Integer.toHexString(cpu.getRegisters().readAF()));
model.addElement("BC: 0x" + Integer.toHexString(cpu.getRegisters().readBC()));
model.addElement("DE: 0x" + Integer.toHexString(cpu.getRegisters().readDE()));
model.addElement("HL: 0x" + Integer.toHexString(cpu.getRegisters().readHL()));
registerList.setModel(model);
int data[][] = {
{},
};
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frmCpuDebugger = new JFrame();
frmCpuDebugger.setTitle("CPU Debugger");
frmCpuDebugger.setBounds(100, 100, 350, 350);
frmCpuDebugger.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
GroupLayout groupLayout = new GroupLayout(frmCpuDebugger.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(registerList, GroupLayout.DEFAULT_SIZE, 314, Short.MAX_VALUE)
.addComponent(lblRegisters)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED, 198, Short.MAX_VALUE)
.addComponent(btnReset)))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lblRegisters)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)
.addGap(51)
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(btnStep)
.addComponent(btnReset))
.addContainerGap())
);
frmCpuDebugger.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,90 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,102 +0,0 @@
// Basic CPU implementation.
// This will be changed in the future.
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
private int cycles = 0;
public static int[] instructionCycle = {
4, 12, 8, 8, 4, 4, 8, 4, 20, 8, 8, 8, 4, 4, 8, 4,
4, 12, 8, 8, 4, 4, 8, 4, 12, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
8, 12, 8, 8, 12, 12, 12, 4, 8, 8, 8, 8, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4,
8, 12, 12, 16, 12, 16, 8, 16, 8, 16, 12, 4, 12, 24, 8, 16,
8, 12, 12, -1, 12, 16, 8, 16, 8, 16, 12, -1, 12, -1, 8, 16,
12, 12, 8, -1, -1, 16, 8, 16, 16, 4, 16, -1, -1, -1, 8, 16,
12, 12, 8, 4, -1, 16, 8, 16, 12, 8, 16, 4, -1, -1, 8, 16
};
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
if (cycles == 0) {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
decodeOpcode(opcode);
}
cycles--;
}
public void decodeOpcode(int opcode) {
// Apply cycle count
cycles += instructionCycle[opcode]
switch (opcode) {
case 0x00: // NOP
break;
case 0x21: // LD HL, d16
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31: // LD SP, d16
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0x32: // LD (HL-), A
mmu.write(registers.readA(), registers.readHL());
registers.writeHL(registers.readHL() - 1);
break;
case 0xAF: // XOR A
registers.writeA(registers.readA() ^ registers.readA());
registers.setFlag(Registers.FLAG_Z, registers.readA() == 0);
break;
case 0xCB: // CB - prefix
decodePrefixedOpcode(mmu.read(registers.pc++));
break;
default:
System.err.printf("Unknown opcode: 0x%2x\n", opcode);
}
}
public void decodePrefixedOpcode(int opcode) {
switch (opcode) {
case 0x7C:
registers.setFlag(Registers.FLAG_Z, (registers.readH() & (1 << 7)) == 0);
registers.setFlag(Registers.FLAG_N, false);
registers.setFlag(Registers.FLAG_H, true);
break;
default:
System.err.printf("Unknown opcode: 0xcb%2x\n", opcode);
}
}
}

View File

@ -1,39 +0,0 @@
package playingcoffee.core;
public class Opcode {
private Op[] ops;
private final Registers registers;
private final MMU mmu;
private int operand;
public Opcode(Registers registers, MMU mmu, Op... ops) {
this.registers = registers;
this.mmu = mmu;
this.ops = ops;
}
public void execute(Registers regs, MMU mmu) {
for (Op op : ops)
op.execute();
}
public interface Op {
public void execute();
}
public class Read16BitOperand implements Op {
@Override
public void execute() {
operand = (mmu.read(registers.pc++) << 8) | mmu.read(registers.pc);
}
}
}

View File

@ -1,118 +0,0 @@
package playingcoffee.ui;
import java.awt.EventQueue;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.ListModel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import playingcoffee.core.CPU;
import playingcoffee.core.MMU;
public class CPUDebugger {
private JFrame frame;
private JTable memoryViewTable;
private JList<String> registerList;
private MMU mmu;
private CPU cpu;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
CPUDebugger window = new CPUDebugger();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public CPUDebugger() {
initialize();
mmu = new MMU();
cpu = new CPU();
updateValues();
}
private void updateValues() {
ListModel<String> model = new
}
private void initialize() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
| UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
frame = new JFrame();
frame.setBounds(100, 100, 750, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnStep = new JButton("Step");
JButton btnReset = new JButton("Reset");
JLabel lblRegisters = new JLabel("Registers:");
registerList = new JList<String>();
memoryViewTable = new JTable();
JLabel lblMemoryView = new JLabel("Memory View:");
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(btnStep)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(btnReset))
.addComponent(lblRegisters)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 122, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addComponent(lblMemoryView)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE))
.addContainerGap())
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.TRAILING)
.addGroup(groupLayout.createSequentialGroup()
.addContainerGap()
.addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
.addComponent(lblRegisters)
.addComponent(lblMemoryView))
.addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addGap(8)
.addComponent(memoryViewTable, GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE))
.addGroup(groupLayout.createSequentialGroup()
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(registerList, GroupLayout.PREFERRED_SIZE, 195, GroupLayout.PREFERRED_SIZE)))
.addGap(18)
.addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
.addComponent(btnStep)
.addComponent(btnReset))
.addGap(5))
);
frame.getContentPane().setLayout(groupLayout);
}
}

View File

@ -1,44 +0,0 @@
package playingcoffee.core;
public class CPU {
private final MMU mmu;
private Registers registers;
public CPU(final MMU mmu) {
this.mmu = mmu;
registers = new Registers();
}
public Registers getRegisters() {
return registers;
}
public void cycle() {
int opcode = mmu.read(registers.pc++);
System.out.printf("Fetched opcode: 0x%02x\n", opcode);
// Basic CPU implementation.
// This will be changed in the future.
switch (opcode) {
case 0x00: // NOP
break;
case 0x21:
registers.writeL(mmu.read(registers.pc++));
registers.writeH(mmu.read(registers.pc++));
break;
case 0x31:
registers.sp = mmu.read(registers.pc++) | (mmu.read(registers.pc++) << 8);
break;
case 0xAF:
registers.writeA(registers.readA() ^ registers.readA());
break;
}
}
}

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