commit e3fbf385f8f2621155902f1616c42eb3ef95503f Author: Sebastian Cabrera Date: Sun Jul 26 11:20:59 2020 -0400 Initial Commit diff --git a/bin/chip/Chip.class b/bin/chip/Chip.class new file mode 100644 index 0000000..5acb772 Binary files /dev/null and b/bin/chip/Chip.class differ diff --git a/bin/chip/ChipData.class b/bin/chip/ChipData.class new file mode 100644 index 0000000..d73727b Binary files /dev/null and b/bin/chip/ChipData.class differ diff --git a/bin/emu/ChipFrame.class b/bin/emu/ChipFrame.class new file mode 100644 index 0000000..3c20d0e Binary files /dev/null and b/bin/emu/ChipFrame.class differ diff --git a/bin/emu/ChipPanel.class b/bin/emu/ChipPanel.class new file mode 100644 index 0000000..b53c5f8 Binary files /dev/null and b/bin/emu/ChipPanel.class differ diff --git a/bin/emu/Main.class b/bin/emu/Main.class new file mode 100644 index 0000000..5684625 Binary files /dev/null and b/bin/emu/Main.class differ diff --git a/res/invaders.c8 b/res/invaders.c8 new file mode 100644 index 0000000..3ada8df Binary files /dev/null and b/res/invaders.c8 differ diff --git a/res/pong2.c8 b/res/pong2.c8 new file mode 100644 index 0000000..6af8d1e Binary files /dev/null and b/res/pong2.c8 differ diff --git a/res/tetris.c8 b/res/tetris.c8 new file mode 100644 index 0000000..9f5e087 Binary files /dev/null and b/res/tetris.c8 differ diff --git a/src/chip/Chip.java b/src/chip/Chip.java new file mode 100644 index 0000000..078629f --- /dev/null +++ b/src/chip/Chip.java @@ -0,0 +1,190 @@ +package chip; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class Chip { + + private char[] memory; + private char[] V; + private char I; + private char pc; + + private char stack[]; + private int stackPointer; + + private int delay_timer; + private int sound_timer; + + private byte[] keys; + + private byte[] display; + + private boolean needRedraw; + + public void init() { + memory = new char[4096]; + V = new char[16]; + I = 0x0; + pc = 0x200; + + stack = new char[16]; + stackPointer = 0; + + delay_timer = 0; + sound_timer = 0; + + keys = new byte[16]; + + display = new byte[64 * 32]; + + needRedraw = false; + loadFontset(); + } + + public void run() { + //fetch opcode + char opcode = (char)((memory[pc] << 8) | memory[pc + 1]); + System.out.println("Opcode: " + Integer.toHexString(opcode).toUpperCase()); + //decode opcode + switch(opcode & 0xF000) { + + case 0x1000: { + System.err.println("Unsupported Opcode!"); + System.exit(0); + break; + } + + case 0x2000: { + stack[stackPointer] = pc; + stackPointer++; + pc = (char)(opcode & 0x0FFF); + break; + } + + case 0x3000: { + int x = (opcode & 0x0F00) >> 8; + int nn = (opcode & 0x00FF); + if (V[x] == nn) { + pc += 4; + System.out.println("VX = NN: Skipping 4"); + } else { + pc += 2; + } + break; + } + + case 0x6000: { + int index = (opcode & 0x0F00) >> 8; + V[index] = (char)(opcode & 0x00FF); + pc += 2; + break; + } + + case 0x7000: { + int x = (opcode & 0x0F00) >> 8; + int nn = (opcode & 0x00FF); + V[x] = (char)((V[x] + nn) & 0xFF); + pc += 2; + break; + } + + case 0x8000: //Contains more data in last nibble + + switch(opcode & 0x000F) { + + case 0x0000: //8XY0: Sets VX to the value of VY. + default: + System.err.println("Unsupported Opcode!"); + System.exit(0); + break; + + } + + break; + + case 0xA000: { + I = (char)(opcode & 0x0FFF); + pc += 2; + break; + } + + case 0xD000: { + int x = V[(opcode & 0x0F00) >> 8]; + int y = V[(opcode & 0x00F0) >> 4]; + int height = opcode & 0x000F; + + V[0xF] = 0; + + for (int _y=0;_y> _x); + if (pixel != 0) { + int totalX = _x + _x; + int totalY = y + _y; + int index = totalY * 64 + totalX; + + if (display[index] == 1) + V[0xF] = 1; + + display[index] ^= 1; + } + } + } + pc += 2; + needRedraw = true; + break; + } + + default: + System.err.println("Unsupported Opcode!"); + System.exit(0); + } + //execute opcode + } + + public byte[] getDisplay() { + return display; + } + + public boolean needsRedraw() { + return needRedraw; + } + + public void removeDrawFlag() { + needRedraw = false; + } + + public void loadProgram(String file) { + DataInputStream input = null; + try { + input = new DataInputStream(new FileInputStream(new File(file))); + + int offset = 0; + while(input.available() > 0) { + memory[0x200 + offset] = (char)(input.readByte() & 0xFF); + offset++; + } + + //for (int offset = 0; input.available() > 0; offset++) { + // + //} + } catch (IOException e) { + e.printStackTrace(); + System.exit(0); + } finally { + if(input != null) { + try { input.close(); } catch (IOException ex) {}; + } + } + } + + public void loadFontset() { + for (int i=0;i < ChipData.fontset.length;i++) { + memory[0x50 + i] = (char)(ChipData.fontset[i] & 0xFF); + } + } +} diff --git a/src/chip/ChipData.java b/src/chip/ChipData.java new file mode 100644 index 0000000..1e6122f --- /dev/null +++ b/src/chip/ChipData.java @@ -0,0 +1,29 @@ +package chip; + +public class ChipData { + + /** + * Fontset in bytes + * Memory position 0x50 + */ + + public static int[] fontset = + { + 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0 + 0x20, 0x60, 0x20, 0x20, 0x70, // 1 + 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2 + 0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3 + 0x90, 0x90, 0xF0, 0x10, 0x10, // 4 + 0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5 + 0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6 + 0xF0, 0x10, 0x20, 0x40, 0x40, // 7 + 0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8 + 0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9 + 0xF0, 0x90, 0xF0, 0x90, 0x90, // A + 0xE0, 0x90, 0xE0, 0x90, 0xE0, // B + 0xF0, 0x80, 0x80, 0x80, 0xF0, // C + 0xE0, 0x90, 0x90, 0x90, 0xE0, // D + 0xF0, 0x80, 0xF0, 0x80, 0xF0, // E + 0xF0, 0x80, 0xF0, 0x80, 0x80 // F + }; +} diff --git a/src/emu/ChipFrame.java b/src/emu/ChipFrame.java new file mode 100644 index 0000000..8d77bb1 --- /dev/null +++ b/src/emu/ChipFrame.java @@ -0,0 +1,27 @@ +package emu; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import javax.swing.JFrame; + +import chip.Chip; + +public class ChipFrame extends JFrame { + + private ChipPanel panel; + + public ChipFrame(Chip c) { + setPreferredSize(new Dimension(640, 320)); + pack(); + setPreferredSize(new Dimension(640 + getInsets().left + getInsets().right, 320 + getInsets().top + getInsets().bottom)); + panel = new ChipPanel(c); + setLayout(new BorderLayout()); + add(panel, BorderLayout.CENTER); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setTitle("Chip 8 Emulator"); + pack(); + setLocationRelativeTo(null); + setVisible(true); + } + +} diff --git a/src/emu/ChipPanel.java b/src/emu/ChipPanel.java new file mode 100644 index 0000000..16274e4 --- /dev/null +++ b/src/emu/ChipPanel.java @@ -0,0 +1,32 @@ +package emu; + +import java.awt.Color; +import java.awt.Graphics; + +import javax.swing.JPanel; + +import chip.Chip; + +public class ChipPanel extends JPanel { + + private Chip chip; + + public ChipPanel(Chip chip) { + this.chip = chip; + } + + public void paint(Graphics g) { + byte[] display = chip.getDisplay(); + for (int i=0;i