Skip to content

Commit

Permalink
[#318] TAP loader in memory
Browse files Browse the repository at this point in the history
  • Loading branch information
vbmacher committed Feb 19, 2023
1 parent 77e848e commit b3dd00b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ public void actionPerformed(ActionEvent e) {
false, IMAGE_EXTENSION_FILTER);
imagePath.ifPresent(path -> {
Loader loader = Loader.createLoader(path);
Loader.MemoryBank bank = askForMemoryBank(loader.isMemoryAddressAware());
Loader.MemoryBank bank = askForMemoryBank(!loader.isMemoryAddressAware());
try {
loader.load(path, context, bank);
repaint.run();
} catch (Exception ex) {
dialogs.showError("Could not load selected image file: " + ex.getMessage(), "Load image file");

ex.printStackTrace();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
*/
package net.emustudio.plugins.memory.bytemem.loaders;

import net.emustudio.emulib.runtime.helpers.NumberUtils;
import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext;

import java.io.RandomAccessFile;
import java.io.FileInputStream;
import java.nio.file.Path;

public class BinaryLoader implements Loader {
Expand All @@ -33,15 +34,11 @@ public boolean isMemoryAddressAware() {
@Override
public void load(Path path, ByteMemoryContext memory, MemoryBank bank) throws Exception {
int oldBank = memory.getSelectedBank();
try (RandomAccessFile binaryFile = new RandomAccessFile(path.toFile(), "r")) {
memory.selectBank(bank.bank);

long position = 0, length = binaryFile.length();
int address = bank.address;
while (position < length) {
memory.write(address++, (byte) (binaryFile.readUnsignedByte() & 0xFF));
position++;
}
try (FileInputStream stream = new FileInputStream(path.toFile())) {
memory.selectBank(bank.bank);
byte[] content = stream.readAllBytes();
memory.write(bank.address, NumberUtils.nativeBytesToBytes(content));
} catch (Exception e) {
memory.selectBank(oldBank);
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,75 @@
*/
package net.emustudio.plugins.memory.bytemem.loaders;

import net.emustudio.emulib.runtime.helpers.NumberUtils;
import net.emustudio.plugins.memory.bytemem.api.ByteMemoryContext;

import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.Optional;

public class TapLoader implements Loader {
public class TapLoader implements Loader {

@Override
public boolean isMemoryAddressAware() {
return true;
// Tape is usually loaded by BASIC; interprets program start line to address; it depends on emulated machine..
return false;
}

@Override
public void load(Path path, ByteMemoryContext memory, MemoryBank bank) throws Exception {
int oldBank = memory.getSelectedBank();
try (FileInputStream stream = new FileInputStream(path.toFile())) {
memory.selectBank(bank.bank);
parse(stream.readAllBytes(), bank.address, memory);
} catch (Exception e) {
memory.selectBank(oldBank);
throw e;
}
}

private void parse(byte[] content, int address, ByteMemoryContext memory) {
Optional<Integer> startAddress = Optional.empty();

ByteBuffer buffer = ByteBuffer.wrap(content);
buffer.order(ByteOrder.LITTLE_ENDIAN);
while (buffer.position() < buffer.limit()) {
int blockLength = buffer.getShort() & 0xFFFF;
int flagByte = buffer.get() & 0xFF;

if (flagByte == 0) {
final Optional<Integer> javaFail = startAddress;
startAddress = parseHeader(buffer).or(() -> javaFail);
} else {
byte[] data = new byte[blockLength - 2];
buffer.get(data);

if (startAddress.isPresent()) {
memory.write(startAddress.get(), NumberUtils.nativeBytesToBytes(data));
} else {
memory.write(0, NumberUtils.nativeBytesToBytes(data));
startAddress = Optional.of(data.length);
}
}
buffer.get(); // checksum
}

memory.write(address, NumberUtils.nativeBytesToBytes(content));
}

private Optional<Integer> parseHeader(ByteBuffer buffer) {
int headerFlag = buffer.get() & 0xFF;
byte[] maybeFileName = new byte[10];
buffer.get(maybeFileName); // filename
buffer.getShort(); // length
int maybeAddress = buffer.getShort() & 0xFFFF;
buffer.getShort();

if (headerFlag == 3) {
return Optional.of(maybeAddress);
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ public class TzxLoader implements Loader {

@Override
public boolean isMemoryAddressAware() {
return true;
return false;
}

@Override
public void load(Path path, ByteMemoryContext memory, MemoryBank bank) throws Exception {

throw new RuntimeException("Not supported yet!");
}
}

0 comments on commit b3dd00b

Please sign in to comment.