Skip to content

Commit

Permalink
[#318] byte-mem: introduce Loader classes
Browse files Browse the repository at this point in the history
  • Loading branch information
vbmacher committed Feb 17, 2023
1 parent e50194e commit 77e848e
Show file tree
Hide file tree
Showing 20 changed files with 704 additions and 313 deletions.
5 changes: 0 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ Projects:
- [simh](http://simh.trailing-edge.com/) project, which was the main inspiration for Altair8800 computer
- [MAME](https://www.mamedev.org/) project, which helped with resolving a lot of bugs in a correct implementation of
some 8080 and Z80 CPU instructions
- [RedCode Z80](https://github.com/redcode/Z80) project, for helping with correctly implementing some Z80 instructions
- [superzazu's Z80](https://github.com/superzazu/z80), includes test ROMs

Sites:
- [David Sharp's SSEM site](https://www.davidsharp.com/baby/), main inspiration for SSEM implementation
Expand All @@ -44,9 +42,6 @@ Sites:
- [Altair Clone](https://altairclone.com/), more inspiration for Altair8800
- [Study of techniques for emulation programming](http://www.xsim.com/papers/Bario.2001.emubook.pdf), emulation techniques classic
- [8080 instruction table](https://tobiasvl.github.io/optable/intel-8080/classic)
- [CLR home Z80 instructions table](https://clrhome.org/table/)
- [Z80 Undocumented documented](http://www.z80.info/zip/z80-documented.pdf), undocumented behavior of Z80 CPU
- [Z80 undocumented](https://baltazarstudios.com/zilog-z80-undocumented-behavior/), another undocumented behavior of Z80 CPU

Discord:
- [Discord Emulation Development](https://discord.com/channels/465585922579103744/channel-browser)
Expand Down
24 changes: 24 additions & 0 deletions plugins/cpu/z80-cpu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,27 @@ This project is emulator of Zilog Z80 CPU.
It is part of [emuStudio](https://www.emustudio.net/).

The official documentation can be found [here](https://www.emustudio.net/docuser/mits_altair_8800/index/#CPU-Z80)

## Z80 Information

- [CLR home Z80 instructions table](https://clrhome.org/table/)
- [Instructions decoding patterns](http://www.z80.info/decoding.htm)
- [Z80 undocumented documented](http://www.z80.info/zip/z80-documented.pdf)
- [Another Z80 undocumented](https://baltazarstudios.com/zilog-z80-undocumented-behavior/)
- [Undocumented flags](https://github.com/hoglet67/Z80Decoder/wiki/Undocumented-Flags)
- [Memptr register](https://gist.github.com/drhelius/8497817)
- https://floooh.github.io/visualz80remix/

## Z80 Emulators

- [RedCode Z80](https://github.com/redcode/Z80) project, for helping with correctly implementing some Z80 instructions
- [superzazu's Z80](https://github.com/superzazu/z80), includes test ROMs
- [zxpoly](https://github.com/raydac/zxpoly)


## Z80 Tests

- https://github.com/raxoft/z80test
- https://github.com/raydac/zxpoly/issues/63
- https://softspectrum48.weebly.com/test-results.html

Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ public byte read(int portAddress) {
if (!microphoneAndEar) {
result |= 0x40;
}

// System.out.print(Integer.toHexString(portAddress & 0xFF00) + " = " + Integer.toHexString(result & 0xFF) + "; ");
// if ((portAddress & 0xFF00) == 0x7F00) {
// System.out.println();
//}
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,20 @@

import net.emustudio.emulib.plugins.annotations.PluginContext;
import net.emustudio.emulib.plugins.memory.AbstractMemoryContext;
import net.emustudio.emulib.runtime.interaction.Dialogs;
import net.emustudio.emulib.runtime.io.IntelHEX;
import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext;

import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@PluginContext(id = "Byte Memory")
public class MemoryContextImpl extends AbstractMemoryContext<Byte> implements ByteMemoryContext {
final static int DEFAULT_MEM_SIZE = 65536;

private final RangeTree romRanges = new RangeTree();
private final Dialogs dialogs;
int lastImageStart = 0;
private Byte[][] mem = new Byte[1][0];
private int banksCount;
private int bankSelect = 0;
private int bankCommon = 0;
public MemoryContextImpl(Dialogs dialogs) {
this.dialogs = Objects.requireNonNull(dialogs);
}

void init(int size, int banks, int bankCommon) {
if (banks <= 0) {
Expand All @@ -63,7 +51,6 @@ public void clear() {
for (Byte[] bank : mem) {
Arrays.fill(bank, (byte) 0);
}
lastImageStart = 0;
notifyMemoryChanged(-1);
}

Expand Down Expand Up @@ -95,40 +82,6 @@ public int getCommonBoundary() {
return bankCommon;
}

public void loadHex(Path hexFile, int bank) {
int currentBank = bankSelect;
try {
bankSelect = (short) bank;
lastImageStart = IntelHEX.loadIntoMemory(hexFile.toFile(), this, p -> p);
} catch (FileNotFoundException ex) {
dialogs.showError("File not found: " + hexFile);
} catch (Exception e) {
dialogs.showError("Error opening file: " + hexFile);
} finally {
bankSelect = currentBank;
notifyMemoryChanged(-1);
}
}

public void loadBin(Path binFile, int address, int bank) {
lastImageStart = 0;
try (RandomAccessFile binaryFile = new RandomAccessFile(binFile.toFile(), "r")) {
long position = 0, length = binaryFile.length();
while (position < length) {
mem[bank][address++] = (byte) (binaryFile.readUnsignedByte() & 0xFF);
position++;
}
} catch (EOFException ignored) {
// ignored intentionally
} catch (FileNotFoundException ex) {
dialogs.showError("File not found: " + binFile);
} catch (Exception e) {
dialogs.showError("Error opening file: " + binFile);
} finally {
notifyMemoryChanged(-1);
}
}

@Override
public Byte read(int from) {
int activeBank = (from < bankCommon) ? bankSelect : 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import net.emustudio.emulib.runtime.settings.PluginSettings;
import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext;
import net.emustudio.plugins.memory.bytemem.gui.MemoryGui;
import net.emustudio.plugins.memory.bytemem.loaders.Loader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -48,15 +49,14 @@
public class MemoryImpl extends AbstractMemory {
private final static Logger LOGGER = LoggerFactory.getLogger(MemoryImpl.class);

private final MemoryContextImpl context;
private final MemoryContextImpl context = new MemoryContextImpl();
private final boolean guiNotSupported;
private MemoryGui gui;

public MemoryImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) {
super(pluginID, applicationApi, settings);

this.guiNotSupported = settings.getBoolean(PluginSettings.EMUSTUDIO_NO_GUI, false);
this.context = new MemoryContextImpl(applicationApi.getDialogs());
try {
ContextPool contextPool = applicationApi.getContextPool();
contextPool.register(pluginID, context, ByteMemoryContext.class);
Expand Down Expand Up @@ -157,17 +157,17 @@ private void loadImages() throws PluginInitializationException {
break;
}
} catch (NumberFormatException e) {
throw new PluginInitializationException(this, "Could not parse image address", e);
throw new PluginInitializationException(this, "Could not parse image address or bank", e);
} catch (Exception e) {
throw new PluginInitializationException(this, e);
}
}
}

public void loadImage(Path imagePath, int address, int bank) {
if (imagePath.toString().toLowerCase().endsWith(".hex")) {
context.loadHex(imagePath, bank);
} else {
context.loadBin(imagePath, address, bank);
}
public void loadImage(Path imagePath, int address, int bank) throws Exception {
Loader.MemoryBank memoryBank = Loader.MemoryBank.of(bank, address);
Loader loader = Loader.createLoader(imagePath);
loader.load(imagePath, context, memoryBank);
}

/*
Expand Down Expand Up @@ -210,12 +210,6 @@ public void saveROMRanges() {
}
}

@Override
public void setProgramLocation(int location) {
super.setProgramLocation(location);
context.lastImageStart = location;
}

@Override
public void showSettings(JFrame parent) {
if (!guiNotSupported) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@
import net.emustudio.emulib.runtime.interaction.FileExtensionsFilter;

import java.awt.*;
import java.util.List;

import static net.emustudio.plugins.memory.bytemem.loaders.Loader.IMAGE_LOADERS;


public class Constants {
public final static Font MEMORY_CELLS_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 12);

public final static FileExtensionsFilter IMAGE_EXTENSION_FILTER = new FileExtensionsFilter(
"Memory image", "hex", "bin", "com", "out"
"Memory image", List.copyOf(IMAGE_LOADERS.keySet())
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
package net.emustudio.plugins.memory.bytemem.gui;

import net.emustudio.emulib.runtime.interaction.Dialogs;
import net.emustudio.plugins.memory.bytemem.gui.actions.FindSequenceAction;
import net.emustudio.plugins.memory.bytemem.gui.actions.find_sequence.PerformFindSequenceAction;
import net.emustudio.plugins.memory.bytemem.gui.model.MemoryTableModel;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.util.function.Consumer;

public class FindSequenceDialog extends JDialog {
private final FindSequenceAction findSequenceAction;
private final PerformFindSequenceAction performFindSequenceAction;
private final JRadioButton radioCurrentPage = new JRadioButton();
private final JRadioButton radioPlainText = new JRadioButton();
private final JTextField txtPosition = new JTextField();
Expand All @@ -37,7 +37,7 @@ public FindSequenceDialog(Dialogs dialogs, JDialog parent, MemoryTableModel tabl
super(parent, true);
setLocationRelativeTo(parent);

this.findSequenceAction = new FindSequenceAction(
this.performFindSequenceAction = new PerformFindSequenceAction(
dialogs, this::dispose, tableModel, setFoundAddress, radioCurrentPage::isSelected,
radioPlainText::isSelected, currentAddress, txtPosition, txtSequence
);
Expand All @@ -51,7 +51,7 @@ private void initComponents() {
JRadioButton radioBytes = new JRadioButton();
JPanel jPanel2 = new JPanel();
JRadioButton radioSpecificPosition = new JRadioButton();
JButton btnFind = new JButton(findSequenceAction);
JButton btnFind = new JButton(performFindSequenceAction);
btnGroupSequenceToFind.add(radioPlainText);
btnGroupSequenceToFind.add(radioBytes);

Expand Down
Loading

0 comments on commit 77e848e

Please sign in to comment.