kopia lustrzana https://github.com/maccasoft/z80-tools
Implemented generic files upload and download
rodzic
1790c260c6
commit
7e6073308b
|
@ -10,16 +10,25 @@
|
|||
|
||||
package com.maccasoft.tools;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.core.databinding.observable.Realm;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.databinding.swt.DisplayRealm;
|
||||
import org.eclipse.jface.window.Window;
|
||||
import org.eclipse.jface.dialogs.ProgressIndicator;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.DisposeEvent;
|
||||
import org.eclipse.swt.events.DisposeListener;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
|
@ -27,7 +36,12 @@ import org.eclipse.swt.widgets.Combo;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.MenuItem;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
import com.maccasoft.tools.internal.ImageRegistry;
|
||||
|
@ -39,7 +53,7 @@ import jssc.SerialPortException;
|
|||
import jssc.SerialPortList;
|
||||
import jssc.SerialPortTimeoutException;
|
||||
|
||||
public class SerialTerminal extends Window {
|
||||
public class SerialTerminal {
|
||||
|
||||
public static final String[] BAUD_RATES = new String[] {
|
||||
String.valueOf(SerialPort.BAUDRATE_9600),
|
||||
|
@ -57,6 +71,7 @@ public class SerialTerminal extends Window {
|
|||
public static final byte C = 0x43; // 'C' which use in XModem/CRC
|
||||
|
||||
Display display;
|
||||
Shell shell;
|
||||
Composite container;
|
||||
Terminal term;
|
||||
|
||||
|
@ -64,6 +79,8 @@ public class SerialTerminal extends Window {
|
|||
Combo comPort;
|
||||
Combo baudRate;
|
||||
|
||||
ProgressIndicator progressBar;
|
||||
|
||||
String port;
|
||||
int baud;
|
||||
SerialPort serialPort;
|
||||
|
@ -109,13 +126,100 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
};
|
||||
|
||||
final IProgressMonitor progressMonitor = new IProgressMonitor() {
|
||||
|
||||
@Override
|
||||
public void beginTask(String name, int totalWork) {
|
||||
final boolean animated = (totalWork == UNKNOWN || totalWork == 0);
|
||||
display.syncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (progressBar == null || progressBar.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!progressBar.getVisible()) {
|
||||
progressBar.setVisible(true);
|
||||
container.layout();
|
||||
}
|
||||
if (!animated) {
|
||||
progressBar.beginTask(totalWork);
|
||||
}
|
||||
else {
|
||||
progressBar.beginAnimatedTask();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void done() {
|
||||
display.syncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (progressBar == null || progressBar.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
progressBar.sendRemainingWork();
|
||||
progressBar.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void internalWorked(double work) {
|
||||
display.syncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (progressBar == null || progressBar.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
progressBar.worked(work);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCanceled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCanceled(boolean value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTaskName(String name) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subTask(String name) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void worked(int work) {
|
||||
internalWorked(work);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public SerialTerminal() {
|
||||
super((Shell) null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureShell(Shell newShell) {
|
||||
super.configureShell(newShell);
|
||||
public void open() {
|
||||
display = Display.getDefault();
|
||||
preferences = Preferences.getInstance();
|
||||
|
||||
shell = new Shell(display);
|
||||
shell.setText(Application.APP_TITLE);
|
||||
shell.setData(this);
|
||||
|
||||
Image[] images = new Image[] {
|
||||
ImageRegistry.getImageFromResources("app128.png"),
|
||||
|
@ -124,16 +228,146 @@ public class SerialTerminal extends Window {
|
|||
ImageRegistry.getImageFromResources("app32.png"),
|
||||
ImageRegistry.getImageFromResources("app16.png"),
|
||||
};
|
||||
newShell.setImages(images);
|
||||
shell.setImages(images);
|
||||
|
||||
newShell.setData(this);
|
||||
Menu menu = new Menu(shell, SWT.BAR);
|
||||
createFileMenu(menu);
|
||||
createEditMenu(menu);
|
||||
createHelpMenu(menu);
|
||||
shell.setMenuBar(menu);
|
||||
|
||||
GridLayout layout = new GridLayout(1, false);
|
||||
layout.marginWidth = layout.marginHeight = 0;
|
||||
shell.setLayout(layout);
|
||||
|
||||
Control control = createContents(shell);
|
||||
control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||
|
||||
Rectangle screen = display.getClientArea();
|
||||
|
||||
Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
|
||||
|
||||
Rectangle rect = shell.computeTrim(0, 0, size.x, size.y);
|
||||
rect.x = (screen.width - rect.width) / 2;
|
||||
rect.y = (screen.height - rect.height) / 2;
|
||||
if (rect.y < 0) {
|
||||
rect.height += rect.y * 2;
|
||||
rect.y = 0;
|
||||
}
|
||||
|
||||
shell.setLocation(rect.x, rect.y);
|
||||
shell.setSize(rect.width, rect.height);
|
||||
|
||||
shell.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
display = parent.getDisplay();
|
||||
void createFileMenu(Menu parent) {
|
||||
final Menu menu = new Menu(parent.getParent(), SWT.DROP_DOWN);
|
||||
|
||||
preferences = Preferences.getInstance();
|
||||
MenuItem item = new MenuItem(parent, SWT.CASCADE);
|
||||
item.setText("&File");
|
||||
item.setMenu(menu);
|
||||
|
||||
item = new MenuItem(menu, SWT.CASCADE);
|
||||
item.setText("Packed CP/M Binary Upload...");
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleUploadPackedBinary();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new MenuItem(menu, SWT.SEPARATOR);
|
||||
|
||||
item = new MenuItem(menu, SWT.CASCADE);
|
||||
item.setText("XModem Upload...");
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleUploadXModem();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
item = new MenuItem(menu, SWT.CASCADE);
|
||||
item.setText("XModem Download...");
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleDownloadXModem();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new MenuItem(menu, SWT.SEPARATOR);
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Close");
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
shell.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void createEditMenu(Menu parent) {
|
||||
Menu menu = new Menu(parent.getParent(), SWT.DROP_DOWN);
|
||||
|
||||
MenuItem item = new MenuItem(parent, SWT.CASCADE);
|
||||
item.setText("&Edit");
|
||||
item.setMenu(menu);
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Paste\tShift+Ins");
|
||||
item.setAccelerator(SWT.MOD2 + SWT.INSERT);
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
term.pasteFromClipboard();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void createHelpMenu(Menu parent) {
|
||||
Menu menu = new Menu(parent.getParent(), SWT.DROP_DOWN);
|
||||
|
||||
MenuItem item = new MenuItem(parent, SWT.CASCADE);
|
||||
item.setText("&Help");
|
||||
item.setMenu(menu);
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("About " + Application.APP_TITLE);
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
AboutDialog dlg = new AboutDialog(shell);
|
||||
dlg.open();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected Control createContents(Composite parent) {
|
||||
port = preferences.getSerialPort();
|
||||
baud = preferences.getSerialBaud();
|
||||
|
||||
|
@ -229,6 +463,11 @@ public class SerialTerminal extends Window {
|
|||
label = new Label(container, SWT.NONE);
|
||||
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
|
||||
|
||||
progressBar = new ProgressIndicator(container, SWT.HORIZONTAL);
|
||||
GridData layoutData = new GridData(GridData.GRAB_VERTICAL);
|
||||
layoutData.widthHint = 128;
|
||||
progressBar.setLayoutData(layoutData);
|
||||
|
||||
label = new Label(container, SWT.NONE);
|
||||
label.setText("Port");
|
||||
|
||||
|
@ -291,7 +530,7 @@ public class SerialTerminal extends Window {
|
|||
e.printStackTrace();
|
||||
}
|
||||
|
||||
getShell().setText("Serial Terminal on " + port);
|
||||
shell.setText("Serial Terminal on " + port);
|
||||
}
|
||||
|
||||
public void setFocus() {
|
||||
|
@ -303,13 +542,129 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
|
||||
public void dispose() {
|
||||
getShell().dispose();
|
||||
shell.dispose();
|
||||
}
|
||||
|
||||
public void uploadPackedBinary(String name, byte[] data, IProgressMonitor monitor) throws SerialPortException, SerialPortTimeoutException {
|
||||
int checksum;
|
||||
private void handleUploadPackedBinary() {
|
||||
String s = preferences.getDownloadCommand();
|
||||
final File[] fileName = getFileToOpen("Packed-Binary Upload", s != null && !s.equals(""));
|
||||
if (fileName == null || fileName.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (int i = 0; i < fileName.length; i++) {
|
||||
InputStream is = new FileInputStream(fileName[i]);
|
||||
progressMonitor.beginTask("Upload", (is.available() + 127) / 128);
|
||||
try {
|
||||
uploadPackedBinary(fileName[i].getName().toUpperCase(), is, progressMonitor);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
progressMonitor.done();
|
||||
is.close();
|
||||
|
||||
if ((i + 1) < fileName.length) {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void handleUploadXModem() {
|
||||
String s = preferences.getXmodemCommand();
|
||||
final File[] fileName = getFileToOpen("XModem Upload", s != null && !s.equals(""));
|
||||
if (fileName == null || fileName.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (int i = 0; i < fileName.length; i++) {
|
||||
InputStream is = new FileInputStream(fileName[i]);
|
||||
progressMonitor.beginTask("Upload", (is.available() + 127) / 128);
|
||||
try {
|
||||
uploadXModem(fileName[i].getName().toUpperCase(), is, progressMonitor);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
progressMonitor.done();
|
||||
is.close();
|
||||
|
||||
if ((i + 1) < fileName.length) {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (Exception e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
private File[] getFileToOpen(String text, boolean multi) {
|
||||
int style = SWT.OPEN;
|
||||
if (multi) {
|
||||
style |= SWT.MULTI;
|
||||
}
|
||||
|
||||
FileDialog dlg = new FileDialog(shell, style);
|
||||
dlg.setText(text);
|
||||
dlg.setFilterNames(new String[] {
|
||||
"All Files",
|
||||
"CP/M Programs"
|
||||
});
|
||||
dlg.setFilterExtensions(new String[] {
|
||||
"*.*",
|
||||
"*.COM;*.com"
|
||||
});
|
||||
dlg.setFilterIndex(0);
|
||||
|
||||
if (dlg.open() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] names = dlg.getFileNames();
|
||||
|
||||
File[] files = new File[names.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
files[i] = new File(dlg.getFilterPath(), names[i]);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public void uploadPackedBinary(String name, byte[] data, IProgressMonitor monitor) throws Exception {
|
||||
uploadPackedBinary(name, new ByteArrayInputStream(data), monitor);
|
||||
}
|
||||
|
||||
public void uploadPackedBinary(String name, InputStream is, IProgressMonitor monitor) throws Exception {
|
||||
int data, checksum;
|
||||
String s;
|
||||
|
||||
int length = is.available();
|
||||
|
||||
try {
|
||||
serialPort.removeEventListener();
|
||||
} catch (SerialPortException e) {
|
||||
|
@ -317,14 +672,16 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
|
||||
try {
|
||||
s = preferences.getDownloadCommand();
|
||||
s = s.replace("{0}", name.toUpperCase());
|
||||
serialPort.writeString(s);
|
||||
serialPort.writeInt(13);
|
||||
flushOutput();
|
||||
do {
|
||||
s = readString();
|
||||
} while (s.length() != 0 && !s.contains("DOWNLOAD "));
|
||||
String cmd = preferences.getDownloadCommand();
|
||||
if (cmd != null && !cmd.equals("")) {
|
||||
cmd = cmd.replace("{0}", name.toUpperCase());
|
||||
serialPort.writeString(cmd);
|
||||
serialPort.writeInt(13);
|
||||
flushOutput();
|
||||
do {
|
||||
s = readString();
|
||||
} while (s.length() != 0 && !s.contains(cmd));
|
||||
}
|
||||
|
||||
serialPort.writeString("U0\r");
|
||||
flushOutput();
|
||||
|
@ -343,10 +700,11 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
|
||||
checksum = 0;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
serialPort.writeString(String.format("%02X", data[i] & 0xFF));
|
||||
for (int i = 0; i < length; i++) {
|
||||
data = is.read();
|
||||
serialPort.writeString(String.format("%02X", data & 0xFF));
|
||||
flushOutput();
|
||||
checksum += data[i] & 0xFF;
|
||||
checksum += data & 0xFF;
|
||||
if (i > 0 && (i & 127) == 0) {
|
||||
waitDot();
|
||||
if (monitor != null) {
|
||||
|
@ -360,7 +718,7 @@ public class SerialTerminal extends Window {
|
|||
|
||||
serialPort.writeString(">");
|
||||
flushOutput();
|
||||
if ((data.length & 127) != 0) {
|
||||
if ((length & 127) != 0) {
|
||||
waitDot();
|
||||
if (monitor != null) {
|
||||
monitor.worked(1);
|
||||
|
@ -374,7 +732,7 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
}
|
||||
|
||||
serialPort.writeString(String.format("%02X", data.length & 0xFF));
|
||||
serialPort.writeString(String.format("%02X", length & 0xFF));
|
||||
flushOutput();
|
||||
|
||||
serialPort.writeString(String.format("%02X", checksum & 0xFF));
|
||||
|
@ -426,8 +784,14 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
}
|
||||
|
||||
public void uploadXModem(String name, byte[] data, IProgressMonitor monitor) throws SerialPortException, SerialPortTimeoutException {
|
||||
public void uploadXModem(String name, byte[] data, IProgressMonitor monitor) throws Exception {
|
||||
uploadXModem(name, new ByteArrayInputStream(data), monitor);
|
||||
}
|
||||
|
||||
public void uploadXModem(String name, InputStream is, IProgressMonitor monitor) throws Exception {
|
||||
int i;
|
||||
String s;
|
||||
byte[] data = new byte[128];
|
||||
|
||||
try {
|
||||
serialPort.removeEventListener();
|
||||
|
@ -436,27 +800,29 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
|
||||
try {
|
||||
s = preferences.getXmodemCommand();
|
||||
s = s.replace("{0}", name.toUpperCase());
|
||||
serialPort.writeString(s);
|
||||
serialPort.writeInt(13);
|
||||
flushOutput();
|
||||
do {
|
||||
s = readString();
|
||||
} while (s.length() != 0 && !s.contains("XMODEM "));
|
||||
String cmd = preferences.getXmodemCommand();
|
||||
if (cmd != null && !cmd.equals("")) {
|
||||
cmd = cmd.replace("{0}", name.toUpperCase());
|
||||
serialPort.writeString(cmd);
|
||||
serialPort.writeInt(13);
|
||||
flushOutput();
|
||||
do {
|
||||
s = readString();
|
||||
} while (s.length() != 0 && !s.contains(cmd));
|
||||
|
||||
s = "";
|
||||
while (true) {
|
||||
byte[] b = serialPort.readBytes(1, 15000);
|
||||
term.write(b[0]);
|
||||
if (b[0] >= ' ') {
|
||||
s = s + (char) b[0];
|
||||
if (s.endsWith("Overwrite (Y/N)?")) {
|
||||
serialPort.writeString("Y\r");
|
||||
s = "";
|
||||
}
|
||||
if (s.endsWith("with CRCs")) {
|
||||
break;
|
||||
s = "";
|
||||
while (true) {
|
||||
byte[] b = serialPort.readBytes(1, 15000);
|
||||
term.write(b[0]);
|
||||
if (b[0] >= ' ') {
|
||||
s = s + (char) b[0];
|
||||
if (s.endsWith("Overwrite (Y/N)?")) {
|
||||
serialPort.writeString("Y\r");
|
||||
s = "";
|
||||
}
|
||||
if (s.endsWith("with CRCs")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -465,8 +831,12 @@ public class SerialTerminal extends Window {
|
|||
int packet = 1;
|
||||
int errors = 0;
|
||||
|
||||
int i = 0;
|
||||
while (i < data.length) {
|
||||
Arrays.fill(data, (byte) 0);
|
||||
if ((i = is.read(data)) < data.length) {
|
||||
data[i] = 0x1A;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
byte[] b = serialPort.readBytes(1, 15000);
|
||||
|
||||
|
@ -480,12 +850,28 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
|
||||
if (b[0] == ACK) {
|
||||
i += 128;
|
||||
packet++;
|
||||
if (monitor != null) {
|
||||
monitor.worked(1);
|
||||
}
|
||||
errors++;
|
||||
errors = 0;
|
||||
|
||||
Arrays.fill(data, (byte) 0);
|
||||
if ((i = is.read(data)) <= 0) {
|
||||
serialPort.writeByte(EOT);
|
||||
b = serialPort.readBytes(1, 5000);
|
||||
if (b[0] == NAK) {
|
||||
serialPort.writeByte(EOT);
|
||||
}
|
||||
b = serialPort.readBytes(1, 5000);
|
||||
if (b[0] == NAK) {
|
||||
serialPort.writeByte(EOT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i < data.length) {
|
||||
data[i] = 0x1A;
|
||||
}
|
||||
}
|
||||
|
||||
if (b[0] == NAK) {
|
||||
|
@ -501,23 +887,10 @@ public class SerialTerminal extends Window {
|
|||
serialPort.writeByte((byte) (packet ^ 0xFF));
|
||||
|
||||
int checksum = 0, crc = 0;
|
||||
int x = 0;
|
||||
while (x < 128 && (i + x) < data.length) {
|
||||
serialPort.writeByte(data[i + x]);
|
||||
checksum += data[i + x] & 0xFF;
|
||||
crc = updateCrc(crc, data[i + x] & 0xFF);
|
||||
x++;
|
||||
}
|
||||
if (x < 128) {
|
||||
serialPort.writeByte((byte) 0x1A);
|
||||
checksum += 0x1A;
|
||||
crc = updateCrc(crc, 0x1A);
|
||||
x++;
|
||||
while (x < 128) {
|
||||
serialPort.writeByte((byte) 0);
|
||||
crc = updateCrc(crc, 0);
|
||||
x++;
|
||||
}
|
||||
for (int x = 0; x < data.length; x++) {
|
||||
serialPort.writeByte(data[x]);
|
||||
checksum += data[x] & 0xFF;
|
||||
crc = updateCrc(crc, data[x] & 0xFF);
|
||||
}
|
||||
|
||||
if (doCrc) {
|
||||
|
@ -542,16 +915,145 @@ public class SerialTerminal extends Window {
|
|||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
serialPort.addEventListener(serialEventListener);
|
||||
} catch (SerialPortException e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= data.length) {
|
||||
serialPort.writeByte(EOT);
|
||||
byte[] b = serialPort.readBytes(1, 5000);
|
||||
if (b[0] == NAK) {
|
||||
serialPort.writeByte(EOT);
|
||||
private void handleDownloadXModem() {
|
||||
FileDialog dlg = new FileDialog(shell, SWT.SAVE);
|
||||
dlg.setText("XModem Download");
|
||||
dlg.setFilterNames(new String[] {
|
||||
"All Files",
|
||||
"CP/M Programs"
|
||||
});
|
||||
dlg.setFilterExtensions(new String[] {
|
||||
"*.*",
|
||||
"*.COM;*.com"
|
||||
});
|
||||
dlg.setFilterIndex(0);
|
||||
dlg.setOverwrite(true);
|
||||
|
||||
String fileName = dlg.open();
|
||||
if (fileName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final File file = new File(fileName);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
OutputStream os = new FileOutputStream(file);
|
||||
progressMonitor.beginTask("Upload", IProgressMonitor.UNKNOWN);
|
||||
try {
|
||||
downloadXModem(file.getName().toUpperCase(), os, progressMonitor);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
progressMonitor.done();
|
||||
os.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
b = serialPort.readBytes(1, 5000);
|
||||
if (b[0] == NAK) {
|
||||
serialPort.writeByte(EOT);
|
||||
}
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void downloadXModem(String name, OutputStream os, IProgressMonitor monitor) throws Exception {
|
||||
byte[] b, data, c;
|
||||
|
||||
try {
|
||||
serialPort.removeEventListener();
|
||||
} catch (SerialPortException e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
try {
|
||||
boolean doCrc = true;
|
||||
int packet = 1;
|
||||
int errors = 0;
|
||||
|
||||
serialPort.writeByte(doCrc ? C : NAK);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
b = serialPort.readBytes(1, 15000);
|
||||
|
||||
if (b[0] == SOH) {
|
||||
b = serialPort.readBytes(2, 15000);
|
||||
data = serialPort.readBytes(128, 15000);
|
||||
c = serialPort.readBytes(doCrc ? 2 : 1, 15000);
|
||||
|
||||
if (b[0] != (byte) packet || (b[0] ^ b[1]) != (byte) 0xFF) {
|
||||
serialPort.writeByte(NAK);
|
||||
errors++;
|
||||
if (errors >= 10) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
int checksum = 0, crc = 0;
|
||||
for (int x = 0; x < data.length; x++) {
|
||||
checksum += data[x] & 0xFF;
|
||||
crc = updateCrc(crc, data[x] & 0xFF);
|
||||
}
|
||||
|
||||
if (doCrc) {
|
||||
if (c[0] != (byte) (crc >> 8) || c[1] != (byte) (crc & 0xFF)) {
|
||||
serialPort.writeByte(NAK);
|
||||
errors++;
|
||||
if (errors >= 10) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (c[0] != (byte) (checksum & 0xFF)) {
|
||||
serialPort.writeByte(NAK);
|
||||
errors++;
|
||||
if (errors >= 10) {
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
os.write(data);
|
||||
|
||||
serialPort.writeByte(ACK);
|
||||
packet++;
|
||||
errors = 0;
|
||||
}
|
||||
else if (b[0] == EOT) {
|
||||
serialPort.writeByte(ACK);
|
||||
break;
|
||||
}
|
||||
if (monitor != null && monitor.isCanceled()) {
|
||||
serialPort.writeBytes(new byte[] {
|
||||
CAN, CAN, CAN
|
||||
});
|
||||
return;
|
||||
}
|
||||
} catch (SerialPortTimeoutException e) {
|
||||
errors++;
|
||||
if (errors >= 10) {
|
||||
return;
|
||||
}
|
||||
if (doCrc && errors >= 5) {
|
||||
doCrc = false;
|
||||
errors = 0;
|
||||
}
|
||||
serialPort.writeByte(doCrc ? C : NAK);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
@ -575,6 +1077,10 @@ public class SerialTerminal extends Window {
|
|||
return crc & 0xFFFF;
|
||||
}
|
||||
|
||||
public Shell getShell() {
|
||||
return shell;
|
||||
}
|
||||
|
||||
static {
|
||||
System.setProperty("SWT_GTK3", "0");
|
||||
}
|
||||
|
|
|
@ -356,7 +356,7 @@ public class Terminal {
|
|||
}
|
||||
}
|
||||
|
||||
void pasteFromClipboard() {
|
||||
public void pasteFromClipboard() {
|
||||
Clipboard clipboard = new Clipboard(display);
|
||||
try {
|
||||
String s = (String) clipboard.getContents(TextTransfer.getInstance());
|
||||
|
|
Ładowanie…
Reference in New Issue