From 057a1321489178f78bebfb58be66398f97c79d5a Mon Sep 17 00:00:00 2001 From: Marco Maccaferri Date: Sat, 15 Aug 2020 10:19:52 +0200 Subject: [PATCH] Added compact flash module to debugger --- src/com/maccasoft/tools/Application.java | 6 + src/com/maccasoft/tools/Debugger.java | 139 ++++++++++++++++++ src/com/maccasoft/tools/Preferences.java | 10 ++ .../maccasoft/tools/PreferencesDialog.java | 60 ++++++++ 4 files changed, 215 insertions(+) diff --git a/src/com/maccasoft/tools/Application.java b/src/com/maccasoft/tools/Application.java index 2ac9112..7ddc38b 100644 --- a/src/com/maccasoft/tools/Application.java +++ b/src/com/maccasoft/tools/Application.java @@ -2384,6 +2384,11 @@ public class Application { debugger.setDebugTerminal(debugTerminal); + String s = preferences.getDebuggerCompactFlashImage(); + if (s != null && !"".equals(s)) { + debugger.setCompactFlash(new File(s)); + } + debugger.tms9918Ram = preferences.getTms9918Ram(); debugger.tms9918Reg = preferences.getTms9918Register(); @@ -2449,6 +2454,7 @@ public class Application { tabItem.getControl().setFocus(); if (debugger != null) { + debugger.dispose(); debugger = null; } } diff --git a/src/com/maccasoft/tools/Debugger.java b/src/com/maccasoft/tools/Debugger.java index 3f8d6d6..6ea21cb 100644 --- a/src/com/maccasoft/tools/Debugger.java +++ b/src/com/maccasoft/tools/Debugger.java @@ -10,9 +10,13 @@ package com.maccasoft.tools; +import java.io.File; +import java.io.IOException; import java.io.PrintStream; +import java.io.RandomAccessFile; import com.maccasoft.tools.SourceMap.LineEntry; +import com.maccasoft.tools.internal.Utility; import nl.grauw.glass.Source; import z80core.MemIoOps; @@ -30,6 +34,13 @@ public class Debugger extends MemIoOps implements NotifyOps { int tms9918Reg; TMS9918 tms9918; + byte cfCommand; + byte[] cfLBA = new byte[4]; + byte cfSecCount; + RandomAccessFile cf; + byte[] cfIdentifyBuffer = new byte[512]; + int cfDataCount; + boolean stop; final PrintStream out; @@ -73,6 +84,39 @@ public class Debugger extends MemIoOps implements NotifyOps { this.debugTerminal = debugTerminal; } + public void setCompactFlash(File file) { + System.arraycopy("EM-CF-00000001 ".getBytes(), 0, cfIdentifyBuffer, 20, 20); // Serial number + System.arraycopy(Utility.getSwappedBytes("1.00 "), 0, cfIdentifyBuffer, 46, 8); // Firmware version + System.arraycopy(Utility.getSwappedBytes("EMULATED CF CARD "), 0, cfIdentifyBuffer, 54, 40); // Card model + + try { + if (file != null && file.exists()) { + cf = new RandomAccessFile(file, "rw"); + + long size = cf.length() >> 9; + cfIdentifyBuffer[14] = (byte) (size >> 16); + cfIdentifyBuffer[15] = (byte) (size >> 24); + cfIdentifyBuffer[16] = (byte) (size); + cfIdentifyBuffer[17] = (byte) (size >> 8); + + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void dispose() { + stop = true; + try { + if (cf != null) { + cf.close(); + cf = null; + } + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override public void reset() { tms9918.reset(); @@ -125,6 +169,49 @@ public class Debugger extends MemIoOps implements NotifyOps { return tms9918.inReg(); } + if (cf != null) { + switch (port) { + case Machine.CF_DATA: + if (cfCommand == Machine.CF_READ_SEC) { + if (cfDataCount < 512 * cfSecCount) { + try { + if (cf != null) { + return (byte) cf.read(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + else if (cfCommand == Machine.CF_IDENTIFY) { + if (cfDataCount < cfIdentifyBuffer.length) { + return cfIdentifyBuffer[cfDataCount++]; + } + return 0x00; + } + return 0x00; + case Machine.CF_SECCOUNT: + return cfSecCount & 0xFF; + case Machine.CF_STATUS: + if (cfCommand == Machine.CF_WRITE_SEC || cfCommand == Machine.CF_READ_SEC) { + return 0x48; // CF Ready, DRQ + } + else if (cfCommand == Machine.CF_IDENTIFY) { + if (cfDataCount < cfIdentifyBuffer.length) { + return 0x48; // CF Ready, DRQ + } + } + return 0x40; // CF Ready + case Machine.CF_ERROR: + return 0x01; // No error + case Machine.CF_SECTOR: + case Machine.CF_CYL_LOW: + case Machine.CF_CYL_HI: + case Machine.CF_HEAD: + return 0x00; + } + } + return port; } @@ -155,6 +242,57 @@ public class Debugger extends MemIoOps implements NotifyOps { if (port == tms9918Reg) { tms9918.outReg(value); } + + if (cf != null) { + switch (port) { + case Machine.CF_DATA: + if (cfCommand == Machine.CF_WRITE_SEC) { + if (cfDataCount < 512 * cfSecCount) { + cfDataCount++; + try { + if (cf != null) { + cf.write(value & 0xFF); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + break; + case Machine.CF_COMMAND: + cfCommand = (byte) value; + if (cfCommand == Machine.CF_WRITE_SEC || cfCommand == Machine.CF_READ_SEC) { + try { + long addr = ((cfLBA[3] & 0x0F) << 24) | ((cfLBA[2] & 0xFF) << 16) | ((cfLBA[1] & 0xFF) << 8) | (cfLBA[0] & 0xFF); + if (cf != null) { + cf.seek(addr << 9); + } + } catch (IOException e) { + e.printStackTrace(); + } + cfDataCount = 0; + } + else if (cfCommand == Machine.CF_IDENTIFY) { + cfDataCount = 0; + } + break; + case Machine.CF_LBA0: + cfLBA[0] = (byte) value; + break; + case Machine.CF_LBA1: + cfLBA[1] = (byte) value; + break; + case Machine.CF_LBA2: + cfLBA[2] = (byte) value; + break; + case Machine.CF_LBA3: + cfLBA[3] = (byte) value; + break; + case Machine.CF_SECCOUNT: + cfSecCount = (byte) value; + break; + } + } } @Override @@ -255,6 +393,7 @@ public class Debugger extends MemIoOps implements NotifyOps { @Override public void execDone() { + } public void doStop() { diff --git a/src/com/maccasoft/tools/Preferences.java b/src/com/maccasoft/tools/Preferences.java index 5a1b3ae..a1728bb 100644 --- a/src/com/maccasoft/tools/Preferences.java +++ b/src/com/maccasoft/tools/Preferences.java @@ -98,6 +98,8 @@ public class Preferences { int tms9918Ram; int tms9918Register; + String debuggerCompactFlashImage; + int lastUploadType; String lastPath; List lru; @@ -444,6 +446,14 @@ public class Preferences { this.tms9918Register = tms9918Control; } + public String getDebuggerCompactFlashImage() { + return debuggerCompactFlashImage; + } + + public void setDebuggerCompactFlashImage(String debuggerCompactFlashImage) { + this.debuggerCompactFlashImage = debuggerCompactFlashImage; + } + public void save() throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.INDENT_OUTPUT, true); diff --git a/src/com/maccasoft/tools/PreferencesDialog.java b/src/com/maccasoft/tools/PreferencesDialog.java index 8a65c05..3f4ceb6 100644 --- a/src/com/maccasoft/tools/PreferencesDialog.java +++ b/src/com/maccasoft/tools/PreferencesDialog.java @@ -89,6 +89,8 @@ public class PreferencesDialog extends Dialog { Text tms9918VRam; Text tms9918Register; + Text debuggerCompactFlashImage; + Preferences preferences; String defaultFont; Font fontBold; @@ -148,6 +150,7 @@ public class PreferencesDialog extends Dialog { createGeneralPage(stack); createAssemblerPage(stack); + createDebuggerPage(stack); createEditorPage(stack); createEmulatorPage(stack); createFormatterPage(stack); @@ -797,6 +800,61 @@ public class PreferencesDialog extends Dialog { tms9918Register.setText(String.format("%02X", preferences.getTms9918Register())); } + void createDebuggerPage(Composite parent) { + Composite composite = createPage(parent, "Debugger"); + + Label label = new Label(composite, SWT.NONE); + label.setText("CF card image"); + Composite container = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + layout.marginWidth = layout.marginHeight = 0; + container.setLayout(layout); + container.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + debuggerCompactFlashImage = new Text(container, SWT.BORDER); + debuggerCompactFlashImage.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + if (preferences.getDebuggerCompactFlashImage() != null) { + debuggerCompactFlashImage.setText(preferences.getDebuggerCompactFlashImage()); + } + + Button button = new Button(container, SWT.PUSH); + button.setText("Browse"); + button.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dlg = new FileDialog(getShell(), SWT.OPEN); + dlg.setText("Open Compact Flash image"); + dlg.setFilterNames(new String[] { + "All files", + "Compact Flash images" + }); + dlg.setFilterExtensions(new String[] { + "*.*", + "*.IMG;*.img" + }); + + String file = debuggerCompactFlashImage.getText(); + if (!"".equals(file)) { + dlg.setFilterPath(new File(file).getAbsoluteFile().getParent()); + if (file.toLowerCase().endsWith(".img")) { + dlg.setFilterIndex(1); + } + else { + dlg.setFilterIndex(0); + } + } + else { + dlg.setFilterIndex(1); + } + + if ((file = dlg.open()) != null) { + debuggerCompactFlashImage.setText(file); + } + } + }); + } + void addSeparator(Composite parent) { Label label = new Label(parent, SWT.NONE); label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, ((GridLayout) parent.getLayout()).numColumns, 1)); @@ -859,6 +917,8 @@ public class PreferencesDialog extends Dialog { preferences.setTms9918Ram(Integer.valueOf(tms9918VRam.getText(), 16)); preferences.setTms9918Register(Integer.valueOf(tms9918Register.getText(), 16)); + preferences.setDebuggerCompactFlashImage(debuggerCompactFlashImage.getText()); + super.okPressed(); } }