diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/Main.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/Main.java index b323787..370a9d2 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/Main.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/Main.java @@ -26,543 +26,507 @@ import java.util.regex.PatternSyntaxException; -public class Main -{ - public static final String APPNAME = "JTCEMU"; - public static final String VERSION = "2.1"; - public static final String APPINFO = APPNAME + " Version " + VERSION; - - public static final String PROP_LAF_CLASSNAME = "laf.classname"; - public static final String PROP_PREFIX = "jtcemu."; - public static final String PROP_VERSION = "version"; - public static final String PROP_UI_SCALE = "ui.scale"; - public static final String VALUE_NONE = "none"; - - private static final String SYSPROP_UI_SCALE_VALUE = "sun.java2d.uiScale"; - private static final String SYSPROP_UI_SCALE_ENABLED - = "sun.java2d.uiScale.enabled"; - - private static final String pathsFileName = "jtcemu_paths.xml"; - private static final String propsFileName = "jtcemu_config.xml"; - - private static TopFrm topFrm = null; - private static PrintWriter consoleWriter = null; - private static File pathsFile = null; - private static File propsFile = null; - private static PrintRequestAttributeSet printAtts = null; - private static java.util.List windowIcons = null; - - private static String[] usageLines = { - "", - "Aufruf:", - " java -jar jtcemu.jar ", - "", - "Argumente:", - " Emulator starten", - " -h oder --help diese Hilfe anzeigen", - " -V oder --version Versionsnummer anzeigen", - " --as oder --assembler Assembler starten", - " --as -h Hilfe zum Assembler anzeigen", - "" }; - - - public static void main( String[] args ) - { - // Unter MacOS Applikationsname setzen - if( JTCUtil.isMacOS() ) { - System.setProperty( "apple.awt.application.name", APPNAME ); +public class Main { + public static final String APPNAME = "JTCEMU"; + public static final String VERSION = "2.1"; + public static final String APPINFO = APPNAME + " Version " + VERSION; + + public static final String PROP_LAF_CLASSNAME = "laf.classname"; + public static final String PROP_PREFIX = "jtcemu."; + public static final String PROP_VERSION = "version"; + public static final String PROP_UI_SCALE = "ui.scale"; + public static final String VALUE_NONE = "none"; + + private static final String SYSPROP_UI_SCALE_VALUE = "sun.java2d.uiScale"; + private static final String SYSPROP_UI_SCALE_ENABLED + = "sun.java2d.uiScale.enabled"; + + private static final String pathsFileName = "jtcemu_paths.xml"; + private static final String propsFileName = "jtcemu_config.xml"; + + private static TopFrm topFrm = null; + private static PrintWriter consoleWriter = null; + private static File pathsFile = null; + private static File propsFile = null; + private static PrintRequestAttributeSet printAtts = null; + private static java.util.List windowIcons = null; + + private static String[] usageLines = { + "", + "Aufruf:", + " java -jar jtcemu.jar ", + "", + "Argumente:", + " Emulator starten", + " -h oder --help diese Hilfe anzeigen", + " -V oder --version Versionsnummer anzeigen", + " --as oder --assembler Assembler starten", + " --as -h Hilfe zum Assembler anzeigen", + ""}; + + + public static void main(String[] args) { + // Unter MacOS Applikationsname setzen + if (JTCUtil.isMacOS()) { + System.setProperty("apple.awt.application.name", APPNAME); + } + + // interner Applikationskontext setzen + AppContext.setAppInfo(APPNAME, VERSION); + AppContext.setPropPrefix(PROP_PREFIX); + + /* + * In der Eingabeaufforderung von Windows + * ist der DOS-Zeichensatz installiert. + * Deshalb werden ueber System.out und System.err ausgegebene Umlaute + * dort falsch angezeigt. + * Ueber System.console() erfolgt die Ausgabe dagegen richtig. + * Aus diesem Grund wird unter Windows die Console verwendet, + * wenn sie vorhanden ist. + */ + if (File.separatorChar == '\\') { + Console console = System.console(); + if (console != null) { + consoleWriter = console.writer(); + } + } + + // Konfigurationsdatei ermitteln + try { + String appData = System.getenv("APPDATA"); + if (appData != null) { + if (!appData.isEmpty()) { + pathsFile = new File(appData, pathsFileName); + propsFile = new File(appData, propsFileName); + } + } + String homeDir = System.getProperty("user.home"); + if (homeDir != null) { + if (!homeDir.isEmpty()) { + if (pathsFile == null) { + if (File.separatorChar == '/') { + pathsFile = new File(homeDir, "." + pathsFileName); + } else { + pathsFile = new File(homeDir, pathsFileName); + } + } + if (propsFile == null) { + if (File.separatorChar == '/') { + propsFile = new File(homeDir, "." + propsFileName); + } else { + propsFile = new File(homeDir, propsFileName); + } + } + } + } + } catch (SecurityException ex) { + } + + // Kommenadozeile auswerten + boolean done = false; + int argIdx = 0; + if (argIdx < args.length) { + String arg = args[argIdx++]; + if (arg.equals("-?") + || arg.equalsIgnoreCase("-h") + || arg.equalsIgnoreCase("--help")) { + printlnOut(); + printlnOut(APPINFO); + printlnOut(AppContext.COPYRIGHT); + for (String s : usageLines) { + printlnOut(s); + } + exitSuccess(); + } else if (arg.equals("-V") || arg.equalsIgnoreCase("--version")) { + printlnOut(APPINFO); + exitSuccess(); + } else if (arg.equals("--as") + || arg.equalsIgnoreCase("--assembler")) { + if (CmdLineAssembler.execute(args, argIdx)) { + exitSuccess(); + } else { + exitFailure(); + } + } else if (arg.startsWith("-")) { + printlnErr(String.format("Unbekannte Option \'%s\'", arg)); + } + } + + if (!done) { + + // gespeicherte Eigenschaften lesen + Exception propsEx = null; + if (pathsFile == null) { + pathsFile = new File(pathsFileName); + } + AppContext.setLastPathsFile(pathsFile); + if (propsFile == null) { + propsFile = new File(propsFileName); + } + if (propsFile.exists()) { + InputStream in = null; + try { + in = new FileInputStream(propsFile); + Properties props = new Properties(); + props.loadFromXML(in); + String v = props.getProperty(PROP_PREFIX + PROP_VERSION); + if (v != null) { + if (v.equals(VERSION)) { + AppContext.putProperties(props); + } + } + } catch (IOException ex) { + propsEx = ex; + } finally { + JTCUtil.closeSilently(in); + } + } + + /* + * UI-Skalierung + * + * Wenn in den Systemeigenschaften Einstellungen zur UI-Skalierung + * zu finden sind, d.h. wenn also beim Aufruf von JKCEMU + * welche explizit angegeben wurden + * sollen die im Profil befindlichen Einstellungen + * nicht angewendet werden. + */ + if (!containsSysProperty(SYSPROP_UI_SCALE_VALUE) + && !containsSysProperty(SYSPROP_UI_SCALE_ENABLED) + && !containsSysProperty("sun.java2d.win.uiScaleX") + && !containsSysProperty("sun.java2d.win.uiScaleY")) { + String text = AppContext.getProperty(PROP_UI_SCALE); + if (text != null) { + text = text.trim(); + if (text.equalsIgnoreCase(VALUE_NONE)) { + System.setProperty(SYSPROP_UI_SCALE_ENABLED, "false"); + } else { + Integer v = parseUIScalePercentText(text); + if (v != null) { + System.setProperty(SYSPROP_UI_SCALE_ENABLED, "true"); + System.setProperty( + SYSPROP_UI_SCALE_VALUE, + String.valueOf((float) v / 100F)); + } + } + } + } + + // Bei Metal L&F fette Schrift ausschalten + UIManager.put("swing.boldMetal", Boolean.FALSE); + + // Emulator im AWT-Thread starten + final Exception propsEx1 = propsEx; + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + startEmu(propsEx1); + } + }); + } } - // interner Applikationskontext setzen - AppContext.setAppInfo( APPNAME, VERSION ); - AppContext.setPropPrefix( PROP_PREFIX ); - - /* - * In der Eingabeaufforderung von Windows - * ist der DOS-Zeichensatz installiert. - * Deshalb werden ueber System.out und System.err ausgegebene Umlaute - * dort falsch angezeigt. - * Ueber System.console() erfolgt die Ausgabe dagegen richtig. - * Aus diesem Grund wird unter Windows die Console verwendet, - * wenn sie vorhanden ist. - */ - if( File.separatorChar == '\\' ) { - Console console = System.console(); - if( console != null ) { - consoleWriter = console.writer(); - } - } - // Konfigurationsdatei ermitteln - try { - String appData = System.getenv( "APPDATA" ); - if( appData != null ) { - if( !appData.isEmpty() ) { - pathsFile = new File( appData, pathsFileName ); - propsFile = new File( appData, propsFileName ); - } - } - String homeDir = System.getProperty( "user.home" ); - if( homeDir != null ) { - if( !homeDir.isEmpty() ) { - if( pathsFile == null ) { - if( File.separatorChar == '/' ) { - pathsFile = new File( homeDir, "." + pathsFileName ); - } else { - pathsFile = new File( homeDir, pathsFileName ); - } - } - if( propsFile == null ) { - if( File.separatorChar == '/' ) { - propsFile = new File( homeDir, "." + propsFileName ); - } else { - propsFile = new File( homeDir, propsFileName ); - } - } - } - } - } - catch( SecurityException ex ) {} - - // Kommenadozeile auswerten - boolean done = false; - int argIdx = 0; - if( argIdx < args.length ) { - String arg = args[ argIdx++ ]; - if( arg.equals( "-?" ) - || arg.equalsIgnoreCase( "-h" ) - || arg.equalsIgnoreCase( "--help" ) ) - { - printlnOut(); - printlnOut( APPINFO ); - printlnOut( AppContext.COPYRIGHT ); - for( String s : usageLines ) { - printlnOut( s ); - } - exitSuccess(); - } - else if( arg.equals( "-V" ) || arg.equalsIgnoreCase( "--version" ) ) { - printlnOut( APPINFO ); - exitSuccess(); - } - else if( arg.equals( "--as" ) - || arg.equalsIgnoreCase( "--assembler" ) ) - { - if( CmdLineAssembler.execute( args, argIdx ) ) { - exitSuccess(); - } else { - exitFailure(); - } - } - else if( arg.startsWith( "-" ) ) { - printlnErr( String.format( "Unbekannte Option \'%s\'", arg ) ); - } + public static void exitFailure() { + System.exit(-1); } - if( !done ) { - - // gespeicherte Eigenschaften lesen - Exception propsEx = null; - if( pathsFile == null ) { - pathsFile = new File( pathsFileName ); - } - AppContext.setLastPathsFile( pathsFile ); - if( propsFile == null ) { - propsFile = new File( propsFileName ); - } - if( propsFile.exists() ) { - InputStream in = null; - try { - in = new FileInputStream( propsFile ); - Properties props = new Properties(); - props.loadFromXML( in ); - String v = props.getProperty( PROP_PREFIX + PROP_VERSION ); - if( v != null ) { - if( v.equals( VERSION ) ) { - AppContext.putProperties( props ); - } - } - } - catch( IOException ex ) { - propsEx = ex; - } - finally { - JTCUtil.closeSilently( in ); - } - } - - /* - * UI-Skalierung - * - * Wenn in den Systemeigenschaften Einstellungen zur UI-Skalierung - * zu finden sind, d.h. wenn also beim Aufruf von JKCEMU - * welche explizit angegeben wurden - * sollen die im Profil befindlichen Einstellungen - * nicht angewendet werden. - */ - if( !containsSysProperty( SYSPROP_UI_SCALE_VALUE ) - && !containsSysProperty( SYSPROP_UI_SCALE_ENABLED ) - && !containsSysProperty( "sun.java2d.win.uiScaleX" ) - && !containsSysProperty( "sun.java2d.win.uiScaleY" ) ) - { - String text = AppContext.getProperty( PROP_UI_SCALE ); - if( text != null ) { - text = text.trim(); - if( text.equalsIgnoreCase( VALUE_NONE ) ) { - System.setProperty( SYSPROP_UI_SCALE_ENABLED, "false" ); - } else { - Integer v = parseUIScalePercentText( text ); - if( v != null ) { - System.setProperty( SYSPROP_UI_SCALE_ENABLED, "true" ); - System.setProperty( - SYSPROP_UI_SCALE_VALUE, - String.valueOf( (float) v / 100F ) ); - } - } - } - } - - // Bei Metal L&F fette Schrift ausschalten - UIManager.put( "swing.boldMetal", Boolean.FALSE ); - - // Emulator im AWT-Thread starten - final Exception propsEx1 = propsEx; - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - startEmu( propsEx1 ); - } - } ); + + public static void exitSuccess() { + System.exit(0); } - } - public static void exitFailure() - { - System.exit( -1 ); - } + public static File getPathsFile() { + return pathsFile; + } - public static void exitSuccess() - { - System.exit( 0 ); - } + public static PrintRequestAttributeSet getPrintRequestAttributeSet() { + if (printAtts == null) { + printAtts = new HashPrintRequestAttributeSet(); + } + return printAtts; + } - public static File getPathsFile() - { - return pathsFile; - } + public static File getPropertiesFile() { + return propsFile; + } - public static PrintRequestAttributeSet getPrintRequestAttributeSet() - { - if( printAtts == null ) { - printAtts = new HashPrintRequestAttributeSet(); - } - return printAtts; - } - - - public static File getPropertiesFile() - { - return propsFile; - } - - - public static TopFrm getTopFrm() - { - return topFrm; - } - - - public static Integer parseUIScalePercentText( String text ) - { - Integer rv = null; - if( text != null ) { - int pos = text.indexOf( '%' ); - if( pos >= 0 ) { - text = text.substring( 0, pos ); - } - try { - int v = Integer.parseInt( text.trim() ); - if( (v >= 50) && (v <= 400) ) { - rv = Integer.valueOf( v ); - } - } - catch( NumberFormatException ex ) {} + public static TopFrm getTopFrm() { + return topFrm; } - return rv; - } - public static void printErr( String text ) - { - if( consoleWriter != null ) { - consoleWriter.print( text ); - } else { - System.err.print( text ); + public static Integer parseUIScalePercentText(String text) { + Integer rv = null; + if (text != null) { + int pos = text.indexOf('%'); + if (pos >= 0) { + text = text.substring(0, pos); + } + try { + int v = Integer.parseInt(text.trim()); + if ((v >= 50) && (v <= 400)) { + rv = Integer.valueOf(v); + } + } catch (NumberFormatException ex) { + } + } + return rv; } - } - public static void printlnErr( String text ) - { - if( consoleWriter != null ) { - consoleWriter.println( text ); - consoleWriter.flush(); - } else { - System.err.println( text ); + public static void printErr(String text) { + if (consoleWriter != null) { + consoleWriter.print(text); + } else { + System.err.print(text); + } } - } - public static void printlnErr() - { - if( consoleWriter != null ) { - consoleWriter.println(); - consoleWriter.flush(); - } else { - System.err.println(); + public static void printlnErr(String text) { + if (consoleWriter != null) { + consoleWriter.println(text); + consoleWriter.flush(); + } else { + System.err.println(text); + } } - } - public static void printOut( String text ) - { - if( consoleWriter != null ) { - consoleWriter.print( text ); - } else { - System.out.print( text ); + public static void printlnErr() { + if (consoleWriter != null) { + consoleWriter.println(); + consoleWriter.flush(); + } else { + System.err.println(); + } } - } - public static void printlnOut( String text ) - { - if( consoleWriter != null ) { - consoleWriter.println( text ); - consoleWriter.flush(); - } else { - System.out.println( text ); + public static void printOut(String text) { + if (consoleWriter != null) { + consoleWriter.print(text); + } else { + System.out.print(text); + } } - } - public static void printlnOut() - { - if( consoleWriter != null ) { - consoleWriter.println(); - consoleWriter.flush(); - } else { - System.out.println(); - } - } - - - public static void setPrintRequestAttributeSet( PrintRequestAttributeSet a ) - { - printAtts = a; - } - - - public static void showError( Component owner, String msg ) - { - JOptionPane.showMessageDialog( - owner, - msg != null ? msg : "Unbekannter Fehler", - "Fehler", - JOptionPane.ERROR_MESSAGE ); - } - - - public static void showError( Component owner, Exception ex ) - { - if( ex != null ) { - String msg = ex.getMessage(); - if( msg != null ) { - if( msg.isEmpty() ) { - msg = null; - } - } - if( msg == null ) { - msg = ex.getClass().getName(); - } - if( ex instanceof RuntimeException ) { - try { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter( sw ); - ex.printStackTrace( pw ); - pw.flush(); - pw.close(); - sw.close(); - for( String line : sw.toString().split( "\n" ) ) { - int idx1 = line.indexOf( "jtcemu." ); - int idx2 = line.indexOf( "z8." ); - if( (idx1 >= 0) || (idx2 >= 0) ) { - int idx3 = line.indexOf( '(' ); - int idx4 = line.indexOf( ')' ); - if( (idx3 >= 0) && (idx4 > (idx3 + 1)) ) { - msg = String.format( - "%s:\n%s", - line.substring( idx3 + 1, idx4 ), - msg ); - break; - } - } - } - } - catch( IOException ex1 ) {} - catch( PatternSyntaxException ex2 ) {} - } - showError( owner, msg ); + public static void printlnOut(String text) { + if (consoleWriter != null) { + consoleWriter.println(text); + consoleWriter.flush(); + } else { + System.out.println(text); + } } - } - public static void setIconImages( Window window ) - { - if( windowIcons != null ) { - if( !windowIcons.isEmpty() ) { - window.setIconImages( windowIcons ); - } + public static void printlnOut() { + if (consoleWriter != null) { + consoleWriter.println(); + consoleWriter.flush(); + } else { + System.out.println(); + } } - } - - - /* --- private Methoden --- */ - - private static boolean containsSysProperty( String propName ) - { - String s = System.getProperty( propName ); - return s != null ? !s.trim().isEmpty() : false; - } - - - private static void initDesktop( Image taskBarIcon ) - { - /* - * Default-Menu setzen (ab Java 9 moeglich), - * relevant auf dem Mac - */ - try { - if( Desktop.isDesktopSupported() ) { - Desktop d = Desktop.getDesktop(); - Method m = d.getClass().getMethod( - "setDefaultMenuBar", - JMenuBar.class ); - - JMenu menu = new JMenu(); - menu.add( topFrm.createAboutMenuItem() ); - menu.addSeparator(); - menu.add( topFrm.createQuitMenuItem() ); - - JMenuBar mnuBar = new JMenuBar(); - mnuBar.add( menu ); - m.invoke( d, mnuBar ); - } - } - catch( Throwable t ) {} - - /* - * Icon in Taskbar setzen (ab Java 9 moeglich), - * Damit setzt man auf einem Mac das Dok-Icon. - */ - if( taskBarIcon != null ) { - try { - Class cl = Main.class.forName( "java.awt.Taskbar" ); - Object obj = cl.getDeclaredMethod( "getTaskbar" ).invoke( null ); - cl.getMethod( "setIconImage", Image.class ).invoke( - obj, - taskBarIcon ); - } - catch( Throwable t ) {} + + + public static void setPrintRequestAttributeSet(PrintRequestAttributeSet a) { + printAtts = a; } - } - private static void readWindowIcon( String resource ) - { - URL url = Main.class.getResource( resource ); - if( url != null ) { - Image image = topFrm.getToolkit().createImage( url ); - if( image != null ) { - windowIcons.add( image ); - } + public static void showError(Component owner, String msg) { + JOptionPane.showMessageDialog( + owner, + msg != null ? msg : "Unbekannter Fehler", + "Fehler", + JOptionPane.ERROR_MESSAGE); } - } - private static void startEmu( Exception propsEx ) - { - // ggf. Fehlermeldung vom Laden der Einstellungen anzeigen - if( propsEx != null ) { - showError( null, propsEx ); + public static void showError(Component owner, Exception ex) { + if (ex != null) { + String msg = ex.getMessage(); + if (msg != null) { + if (msg.isEmpty()) { + msg = null; + } + } + if (msg == null) { + msg = ex.getClass().getName(); + } + if (ex instanceof RuntimeException) { + try { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + ex.printStackTrace(pw); + pw.flush(); + pw.close(); + sw.close(); + for (String line : sw.toString().split("\n")) { + int idx1 = line.indexOf("jtcemu."); + int idx2 = line.indexOf("z8."); + if ((idx1 >= 0) || (idx2 >= 0)) { + int idx3 = line.indexOf('('); + int idx4 = line.indexOf(')'); + if ((idx3 >= 0) && (idx4 > (idx3 + 1))) { + msg = String.format( + "%s:\n%s", + line.substring(idx3 + 1, idx4), + msg); + break; + } + } + } + } catch (IOException ex1) { + } catch (PatternSyntaxException ex2) { + } + } + showError(owner, msg); + } } - // Erscheinungsbild setzen - String lafClassName = AppContext.getProperty( PROP_LAF_CLASSNAME ); - if( lafClassName != null ) { - if( lafClassName.isEmpty() ) { - lafClassName = null; - } + + public static void setIconImages(Window window) { + if (windowIcons != null) { + if (!windowIcons.isEmpty()) { + window.setIconImages(windowIcons); + } + } } - if( lafClassName == null ) { - String osName = System.getProperty( "os.name" ); - if( osName != null ) { - osName = osName.toLowerCase(); - if( (osName.indexOf( "mac" ) >= 0) - || (osName.indexOf( "win" ) >= 0) ) - { - lafClassName = UIManager.getSystemLookAndFeelClassName(); - } - } + + + /* --- private Methoden --- */ + + private static boolean containsSysProperty(String propName) { + String s = System.getProperty(propName); + return s != null ? !s.trim().isEmpty() : false; } - if( lafClassName != null ) { - if( !lafClassName.isEmpty() ) { - try { - UIManager.setLookAndFeel( lafClassName ); - } - catch( Exception ex ) { - ex.printStackTrace(); - } - } + + + private static void initDesktop(Image taskBarIcon) { + /* + * Default-Menu setzen (ab Java 9 moeglich), + * relevant auf dem Mac + */ + try { + if (Desktop.isDesktopSupported()) { + Desktop d = Desktop.getDesktop(); + Method m = d.getClass().getMethod( + "setDefaultMenuBar", + JMenuBar.class); + + JMenu menu = new JMenu(); + menu.add(topFrm.createAboutMenuItem()); + menu.addSeparator(); + menu.add(topFrm.createQuitMenuItem()); + + JMenuBar mnuBar = new JMenuBar(); + mnuBar.add(menu); + m.invoke(d, mnuBar); + } + } catch (Throwable t) { + } + + /* + * Icon in Taskbar setzen (ab Java 9 moeglich), + * Damit setzt man auf einem Mac das Dok-Icon. + */ + if (taskBarIcon != null) { + try { + Class cl = Main.class.forName("java.awt.Taskbar"); + Object obj = cl.getDeclaredMethod("getTaskbar").invoke(null); + cl.getMethod("setIconImage", Image.class).invoke( + obj, + taskBarIcon); + } catch (Throwable t) { + } + } } - // Emulation aufsetzen - try { - - // Emulation der JTC-Hardware aufsetzen - JTCSys jtcSys = new JTCSys(); - - // Hauptfenster anlegen und Icons laden - topFrm = new TopFrm( jtcSys ); - windowIcons = new ArrayList<>(); - readWindowIcon( "/images/window/jtcemu_20x20.png" ); - readWindowIcon( "/images/window/jtcemu_32x32.png" ); - readWindowIcon( "/images/window/jtcemu_48x48.png" ); - setIconImages( topFrm ); - - // Desktop-Integration - int nIcons = windowIcons.size(); - initDesktop( nIcons > 0 ? windowIcons.get( nIcons - 1 ) : null ); - - // Hauptfenster anzeigen - topFrm.setVisible( true ); - jtcSys.setErrorViewer( topFrm ); - - // ggf. Fehler beim Laden der externen ROM-Dateien anzeigen - String errText = jtcSys.getErrorText(); - if( errText != null ) { - showError( topFrm, errText ); - } + + private static void readWindowIcon(String resource) { + URL url = Main.class.getResource(resource); + if (url != null) { + Image image = topFrm.getToolkit().createImage(url); + if (image != null) { + windowIcons.add(image); + } + } } - catch( IOException ex ) { - showError( null, ex ); - System.exit( -1 ); + + + private static void startEmu(Exception propsEx) { + // ggf. Fehlermeldung vom Laden der Einstellungen anzeigen + if (propsEx != null) { + showError(null, propsEx); + } + + // Erscheinungsbild setzen + String lafClassName = AppContext.getProperty(PROP_LAF_CLASSNAME); + if (lafClassName != null) { + if (lafClassName.isEmpty()) { + lafClassName = null; + } + } + if (lafClassName == null) { + String osName = System.getProperty("os.name"); + if (osName != null) { + osName = osName.toLowerCase(); + if ((osName.indexOf("mac") >= 0) + || (osName.indexOf("win") >= 0)) { + lafClassName = UIManager.getSystemLookAndFeelClassName(); + } + } + } + if (lafClassName != null) { + if (!lafClassName.isEmpty()) { + try { + UIManager.setLookAndFeel(lafClassName); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + + // Emulation aufsetzen + try { + + // Emulation der JTC-Hardware aufsetzen + JTCSys jtcSys = new JTCSys(); + + // Hauptfenster anlegen und Icons laden + topFrm = new TopFrm(jtcSys); + windowIcons = new ArrayList<>(); + readWindowIcon("/images/window/jtcemu_20x20.png"); + readWindowIcon("/images/window/jtcemu_32x32.png"); + readWindowIcon("/images/window/jtcemu_48x48.png"); + setIconImages(topFrm); + + // Desktop-Integration + int nIcons = windowIcons.size(); + initDesktop(nIcons > 0 ? windowIcons.get(nIcons - 1) : null); + + // Hauptfenster anzeigen + topFrm.setVisible(true); + jtcSys.setErrorViewer(topFrm); + + // ggf. Fehler beim Laden der externen ROM-Dateien anzeigen + String errText = jtcSys.getErrorText(); + if (errText != null) { + showError(topFrm, errText); + } + } catch (IOException ex) { + showError(null, ex); + System.exit(-1); + } } - } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseDlg.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseDlg.java index 0aceb3f..d65029a 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseDlg.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseDlg.java @@ -18,123 +18,109 @@ import java.util.Set; -public class BaseDlg extends JDialog implements WindowListener -{ - private static Set suppressedMessages = new HashSet<>(); +public class BaseDlg extends JDialog implements WindowListener { + private static Set suppressedMessages = new HashSet<>(); - protected BaseDlg( Window owner ) - { - super( owner, ModalityType.DOCUMENT_MODAL ); - setDefaultCloseOperation( DO_NOTHING_ON_CLOSE ); - Main.setIconImages( this ); - addWindowListener( this ); - } + protected BaseDlg(Window owner) { + super(owner, ModalityType.DOCUMENT_MODAL); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + Main.setIconImages(this); + addWindowListener(this); + } - protected boolean doClose() - { - setVisible( false ); - dispose(); - return true; - } + protected boolean doClose() { + setVisible(false); + dispose(); + return true; + } - protected void setParentCentered() - { - setParentCentered( this ); - } + protected void setParentCentered() { + setParentCentered(this); + } - public static void setParentCentered( Window window ) - { - Component p = window.getParent(); - if( p != null ) { - int x = p.getX() + ((p.getWidth() - window.getWidth()) / 2); - int y = p.getY() + ((p.getHeight() - window.getHeight()) / 2); - window.setLocation( x > 0 ? x : 0, y > 0 ? y : 0 ); + public static void setParentCentered(Window window) { + Component p = window.getParent(); + if (p != null) { + int x = p.getX() + ((p.getWidth() - window.getWidth()) / 2); + int y = p.getY() + ((p.getHeight() - window.getHeight()) / 2); + window.setLocation(x > 0 ? x : 0, y > 0 ? y : 0); + } } - } - public static void showError( Component owner, String msg ) - { - if( msg == null ) { - msg = "Unbekannter Fehler"; + public static void showError(Component owner, String msg) { + if (msg == null) { + msg = "Unbekannter Fehler"; + } + JOptionPane.showMessageDialog( + owner, + msg, + "Fehler", + JOptionPane.ERROR_MESSAGE); } - JOptionPane.showMessageDialog( - owner, - msg, - "Fehler", - JOptionPane.ERROR_MESSAGE ); - } - - - public static void showSuppressableInfoDlg( Component owner, String msg ) - { - if( msg != null ) { - if( !suppressedMessages.contains( msg ) ) { - JCheckBox cb = new JCheckBox( "Diesen Hinweis nicht mehr anzeigen" ); - JOptionPane.showMessageDialog( - owner, - new Object[] { msg, cb }, - "Hinweis", - JOptionPane.INFORMATION_MESSAGE ); - if( cb.isSelected() ) { - suppressedMessages.add( msg ); - } - } + + + public static void showSuppressableInfoDlg(Component owner, String msg) { + if (msg != null) { + if (!suppressedMessages.contains(msg)) { + JCheckBox cb = new JCheckBox("Diesen Hinweis nicht mehr anzeigen"); + JOptionPane.showMessageDialog( + owner, + new Object[]{msg, cb}, + "Hinweis", + JOptionPane.INFORMATION_MESSAGE); + if (cb.isSelected()) { + suppressedMessages.add(msg); + } + } + } } - } - /* --- WindowListener --- */ + /* --- WindowListener --- */ - @Override - public void windowActivated( WindowEvent e ) - { - // leer; - } + @Override + public void windowActivated(WindowEvent e) { + // leer; + } - @Override - public void windowClosed( WindowEvent e ) - { - // leer; - } + @Override + public void windowClosed(WindowEvent e) { + // leer; + } - @Override - public void windowClosing( WindowEvent e ) - { - doClose(); - } + @Override + public void windowClosing(WindowEvent e) { + doClose(); + } - @Override - public void windowDeactivated( WindowEvent e ) - { - // leer; - } + @Override + public void windowDeactivated(WindowEvent e) { + // leer; + } - @Override - public void windowDeiconified( WindowEvent e ) - { - // leer; - } + @Override + public void windowDeiconified(WindowEvent e) { + // leer; + } - @Override - public void windowIconified( WindowEvent e ) - { - // leer; - } + @Override + public void windowIconified(WindowEvent e) { + // leer; + } - @Override - public void windowOpened( WindowEvent e ) - { - // leer - } + @Override + public void windowOpened(WindowEvent e) { + // leer + } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseFrm.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseFrm.java index 9fe6955..df69638 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseFrm.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/BaseFrm.java @@ -16,109 +16,94 @@ import java.awt.event.WindowListener; -public abstract class BaseFrm extends JFrame implements WindowListener -{ - protected BaseFrm() - { - setDefaultCloseOperation( DO_NOTHING_ON_CLOSE ); - Main.setIconImages( this ); - addWindowListener( this ); - } +public abstract class BaseFrm extends JFrame implements WindowListener { + protected BaseFrm() { + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + Main.setIconImages(this); + addWindowListener(this); + } - protected boolean doClose() - { - setVisible( false ); - dispose(); - return true; - } + protected boolean doClose() { + setVisible(false); + dispose(); + return true; + } - public KeyStroke getMenuShortcut( int keyCode ) - { - return KeyStroke.getKeyStroke( - keyCode, - GUIUtil.getMenuShortcutKeyMask( this ) ); - } + public KeyStroke getMenuShortcut(int keyCode) { + return KeyStroke.getKeyStroke( + keyCode, + GUIUtil.getMenuShortcutKeyMask(this)); + } - public KeyStroke getMenuShortcutWithShift( int keyCode ) - { - return KeyStroke.getKeyStroke( - keyCode, - GUIUtil.getMenuShortcutKeyMask( this ) - | InputEvent.SHIFT_DOWN_MASK ); - } + public KeyStroke getMenuShortcutWithShift(int keyCode) { + return KeyStroke.getKeyStroke( + keyCode, + GUIUtil.getMenuShortcutKeyMask(this) + | InputEvent.SHIFT_DOWN_MASK); + } - public abstract String getPropPrefix(); + public abstract String getPropPrefix(); - public void lafChanged() - { - // leer - } + public void lafChanged() { + // leer + } - public void memorizeSettings() - { - GUIUtil.memorizeWindowSettings( this ); - } + public void memorizeSettings() { + GUIUtil.memorizeWindowSettings(this); + } - public void settingsChanged() - { - // leer - } + public void settingsChanged() { + // leer + } - /* --- WindowListener --- */ + /* --- WindowListener --- */ - @Override - public void windowActivated( WindowEvent e ) - { - // leer; - } + @Override + public void windowActivated(WindowEvent e) { + // leer; + } - @Override - public void windowClosed( WindowEvent e ) - { - // leer; - } + @Override + public void windowClosed(WindowEvent e) { + // leer; + } - @Override - public void windowClosing( WindowEvent e ) - { - doClose(); - } + @Override + public void windowClosing(WindowEvent e) { + doClose(); + } - @Override - public void windowDeactivated( WindowEvent e ) - { - // leer; - } + @Override + public void windowDeactivated(WindowEvent e) { + // leer; + } - @Override - public void windowDeiconified( WindowEvent e ) - { - // leer; - } + @Override + public void windowDeiconified(WindowEvent e) { + // leer; + } - @Override - public void windowIconified( WindowEvent e ) - { - // leer; - } + @Override + public void windowIconified(WindowEvent e) { + // leer; + } - @Override - public void windowOpened( WindowEvent e ) - { - // leer - } + @Override + public void windowOpened(WindowEvent e) { + // leer + } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/GUIUtil.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/GUIUtil.java index 92b0047..9bc6814 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/GUIUtil.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/GUIUtil.java @@ -34,477 +34,448 @@ import java.util.Iterator; -public class GUIUtil -{ - public static final String PROP_WINDOW_X = "window.x"; - public static final String PROP_WINDOW_Y = "window.y"; - public static final String PROP_WINDOW_W = "window.width"; - public static final String PROP_WINDOW_H = "window.height"; - - public static FileFilter asmFileFilter = new FileNameExtensionFilter( - "Assembler-Dateien (*.asm; *.s)", - "asm", "s" ); - - public static FileFilter basicFileFilter = new FileNameExtensionFilter( - "BASIC-Dateien (*.bas)", - "bas" ); - - public static FileFilter binaryFileFilter = new FileNameExtensionFilter( - "Bin\u00E4rdateien (*.bin)", - "bin" ); - - public static FileFilter hexFileFilter = new FileNameExtensionFilter( - "HEX-Dateien (*.hex)", - "hex" ); - - public static FileFilter prjFileFilter = new FileNameExtensionFilter( - "Projektdateien (*.prj)", - "prj" ); - - public static FileFilter jtcFileFilter = new FileNameExtensionFilter( - "JTC-Dateien (*.jtc)", - "jtc" ); - - public static FileFilter romFileFilter = new FileNameExtensionFilter( - "ROM-Dateien (*.bin; *.rom)", - "bin", "rom" ); - - public static FileFilter tapFileFilter = new FileNameExtensionFilter( - "TAP-Dateien (*.tap)", - "tap" ); - - public static FileFilter textFileFilter = new FileNameExtensionFilter( - "Textdateien (*.asc, *.log, *.txt)", - "asc", "log", "txt" ); - - - private static final Cursor defaultCursor = Cursor.getDefaultCursor(); - private static final Cursor waitCursor = new Cursor( Cursor.WAIT_CURSOR ); - - private static Integer menuShortcutKeyMask = null; - - - public static boolean applyWindowSettings( BaseFrm frm ) - { - boolean rv = false; - String prefix = frm.getPropPrefix(); - Integer xNew = AppContext.getIntegerProperty( prefix + PROP_WINDOW_X ); - Integer yNew = AppContext.getIntegerProperty( prefix + PROP_WINDOW_Y ); - if( (xNew != null) && (yNew != null) ) { - Integer wNew = null; - Integer hNew = null; - if( frm.isResizable() ) { - wNew = AppContext.getIntegerProperty( prefix + PROP_WINDOW_W ); - hNew = AppContext.getIntegerProperty( prefix + PROP_WINDOW_H ); - } - - /* - * Eigenschaften nur anwenden, wenn das Fenster - * auf einem Bildschirm mit mindestens 48x48 Pixel sichtbar ist - */ - int x = xNew.intValue(); - int y = yNew.intValue(); - int w = frm.getWidth(); - int h = frm.getHeight(); - if( wNew != null ) { - w = wNew.intValue(); - } - if( hNew != null ) { - h = hNew.intValue(); - } - if( (w > 0) && (h > 0) ) { - boolean visible = false; - Rectangle windowBounds = new Rectangle( x, y, w, h ); - for( GraphicsDevice gd : GraphicsEnvironment - .getLocalGraphicsEnvironment() - .getScreenDevices() ) - { - for( GraphicsConfiguration gc : gd.getConfigurations() ) { - Rectangle deviceBounds = gc.getBounds(); - if( deviceBounds != null ) { - Rectangle2D intersection = deviceBounds.createIntersection( - windowBounds ); - if( intersection != null ) { - if( (intersection.getWidth() > 48.0) - && (intersection.getHeight() > 48.0) ) - { - visible = true; - break; - } - } - } - } - if( visible ) { - break; - } - } - if( visible ) { - if( (wNew != null) && (hNew != null) ) { - frm.setBounds( x, y, w, h ); - } else { - frm.setLocation( x, y ); - } - rv = true; - } - } +public class GUIUtil { + public static final String PROP_WINDOW_X = "window.x"; + public static final String PROP_WINDOW_Y = "window.y"; + public static final String PROP_WINDOW_W = "window.width"; + public static final String PROP_WINDOW_H = "window.height"; + + public static FileFilter asmFileFilter = new FileNameExtensionFilter( + "Assembler-Dateien (*.asm; *.s)", + "asm", "s"); + + public static FileFilter basicFileFilter = new FileNameExtensionFilter( + "BASIC-Dateien (*.bas)", + "bas"); + + public static FileFilter binaryFileFilter = new FileNameExtensionFilter( + "Bin\u00E4rdateien (*.bin)", + "bin"); + + public static FileFilter hexFileFilter = new FileNameExtensionFilter( + "HEX-Dateien (*.hex)", + "hex"); + + public static FileFilter prjFileFilter = new FileNameExtensionFilter( + "Projektdateien (*.prj)", + "prj"); + + public static FileFilter jtcFileFilter = new FileNameExtensionFilter( + "JTC-Dateien (*.jtc)", + "jtc"); + + public static FileFilter romFileFilter = new FileNameExtensionFilter( + "ROM-Dateien (*.bin; *.rom)", + "bin", "rom"); + + public static FileFilter tapFileFilter = new FileNameExtensionFilter( + "TAP-Dateien (*.tap)", + "tap"); + + public static FileFilter textFileFilter = new FileNameExtensionFilter( + "Textdateien (*.asc, *.log, *.txt)", + "asc", "log", "txt"); + + + private static final Cursor defaultCursor = Cursor.getDefaultCursor(); + private static final Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR); + + private static Integer menuShortcutKeyMask = null; + + + public static boolean applyWindowSettings(BaseFrm frm) { + boolean rv = false; + String prefix = frm.getPropPrefix(); + Integer xNew = AppContext.getIntegerProperty(prefix + PROP_WINDOW_X); + Integer yNew = AppContext.getIntegerProperty(prefix + PROP_WINDOW_Y); + if ((xNew != null) && (yNew != null)) { + Integer wNew = null; + Integer hNew = null; + if (frm.isResizable()) { + wNew = AppContext.getIntegerProperty(prefix + PROP_WINDOW_W); + hNew = AppContext.getIntegerProperty(prefix + PROP_WINDOW_H); + } + + /* + * Eigenschaften nur anwenden, wenn das Fenster + * auf einem Bildschirm mit mindestens 48x48 Pixel sichtbar ist + */ + int x = xNew.intValue(); + int y = yNew.intValue(); + int w = frm.getWidth(); + int h = frm.getHeight(); + if (wNew != null) { + w = wNew.intValue(); + } + if (hNew != null) { + h = hNew.intValue(); + } + if ((w > 0) && (h > 0)) { + boolean visible = false; + Rectangle windowBounds = new Rectangle(x, y, w, h); + for (GraphicsDevice gd : GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getScreenDevices()) { + for (GraphicsConfiguration gc : gd.getConfigurations()) { + Rectangle deviceBounds = gc.getBounds(); + if (deviceBounds != null) { + Rectangle2D intersection = deviceBounds.createIntersection( + windowBounds); + if (intersection != null) { + if ((intersection.getWidth() > 48.0) + && (intersection.getHeight() > 48.0)) { + visible = true; + break; + } + } + } + } + if (visible) { + break; + } + } + if (visible) { + if ((wNew != null) && (hNew != null)) { + frm.setBounds(x, y, w, h); + } else { + frm.setLocation(x, y); + } + rv = true; + } + } + } + return rv; } - return rv; - } - - - public static Integer askDecimal( - Component owner, - String msg, - Integer preSelection, - Integer minValue ) - { - Integer rv = null; - while( rv == null ) { - String errMsg = null; - String text = null; - if( preSelection != null ) { - text = JOptionPane.showInputDialog( - owner, - msg + ":", - preSelection.toString() ); - } else { - text = JOptionPane.showInputDialog( owner, msg + ":" ); - } - if( text != null ) { - if( !text.isEmpty() ) { - try { - rv = Integer.valueOf( text ); - if( (rv != null) && (minValue != null) ) { - if( rv.intValue() < minValue.intValue() ) { - Main.showError( owner, "Zahl zu klein!" ); - rv = null; - } - } - } - catch( NumberFormatException ex ) { - Main.showError( owner, "Ung\u00FCltige Eingabe" ); - } - } else { - Main.showError( owner, "Eingabe erwartet" ); - } - } else { - break; - } - } - return rv; - } - - - public static Integer askHex4( - Component owner, - String msg, - Integer preSelection ) - { - Integer rv = null; - while( rv == null ) { - String text = null; - if( preSelection != null ) { - text = JOptionPane.showInputDialog( - owner, - msg + ":", - String.format( "%04X", preSelection ) ); - } else { - text = JOptionPane.showInputDialog( owner, msg + ":" ); - } - if( text != null ) { - text = text.trim(); - if( (text.length() > 1) && text.startsWith( "%" ) ) { - text = text.substring( 1 ); - } - try { - rv = JTCUtil.parseHex4( text, msg ); - } - catch( UserInputException ex ) { - Main.showError( owner, ex ); - } - } else { - break; - } - } - return rv; - } - - - public static boolean copyToClipboard( Component c, String text ) - { - boolean done = false; - if( text != null ) { - if( !text.isEmpty() ) { - try { - Clipboard clipboard = c.getToolkit().getSystemClipboard(); - if( clipboard != null ) { - StringSelection ss = new StringSelection( text ); - clipboard.setContents( ss, ss ); - done = true; - } - } - catch( IllegalStateException ex ) {} - } - } - return done; - } - - - public static JButton createImageButton( - Component owner, - String imgName, - String text, - String actionCmd ) - { - JButton btn = null; - Image img = readImage( owner, imgName ); - if( img != null ) { - btn = new JButton( new ImageIcon( img ) ); - btn.setToolTipText( text ); - } else { - btn = new JButton( text ); + + + public static Integer askDecimal( + Component owner, + String msg, + Integer preSelection, + Integer minValue) { + Integer rv = null; + while (rv == null) { + String errMsg = null; + String text = null; + if (preSelection != null) { + text = JOptionPane.showInputDialog( + owner, + msg + ":", + preSelection.toString()); + } else { + text = JOptionPane.showInputDialog(owner, msg + ":"); + } + if (text != null) { + if (!text.isEmpty()) { + try { + rv = Integer.valueOf(text); + if ((rv != null) && (minValue != null)) { + if (rv.intValue() < minValue.intValue()) { + Main.showError(owner, "Zahl zu klein!"); + rv = null; + } + } + } catch (NumberFormatException ex) { + Main.showError(owner, "Ung\u00FCltige Eingabe"); + } + } else { + Main.showError(owner, "Eingabe erwartet"); + } + } else { + break; + } + } + return rv; } - btn.setFocusable( false ); - if( owner instanceof ActionListener ) { - btn.addActionListener( (ActionListener) owner ); + + + public static Integer askHex4( + Component owner, + String msg, + Integer preSelection) { + Integer rv = null; + while (rv == null) { + String text = null; + if (preSelection != null) { + text = JOptionPane.showInputDialog( + owner, + msg + ":", + String.format("%04X", preSelection)); + } else { + text = JOptionPane.showInputDialog(owner, msg + ":"); + } + if (text != null) { + text = text.trim(); + if ((text.length() > 1) && text.startsWith("%")) { + text = text.substring(1); + } + try { + rv = JTCUtil.parseHex4(text, msg); + } catch (UserInputException ex) { + Main.showError(owner, ex); + } + } else { + break; + } + } + return rv; } - if( actionCmd != null ) { - btn.setActionCommand( actionCmd ); + + + public static boolean copyToClipboard(Component c, String text) { + boolean done = false; + if (text != null) { + if (!text.isEmpty()) { + try { + Clipboard clipboard = c.getToolkit().getSystemClipboard(); + if (clipboard != null) { + StringSelection ss = new StringSelection(text); + clipboard.setContents(ss, ss); + done = true; + } + } catch (IllegalStateException ex) { + } + } + } + return done; } - return btn; - } - - - public static JButton createImageButton( - Component owner, - String imgName, - String text ) - { - return createImageButton( owner, imgName, text, null ); - } - - - public static File fileDrop( Component owner, DropTargetDropEvent e ) - { - File file = null; - if( isFileDrop( e ) ) { - e.acceptDrop( DnDConstants.ACTION_COPY ); // Quelle nicht loeschen - Transferable t = e.getTransferable(); - if( t != null ) { - try { - Object o = t.getTransferData( DataFlavor.javaFileListFlavor ); - if( o != null ) { - if( o instanceof Collection ) { - Iterator iter = ((Collection) o).iterator(); - if( iter != null ) { - while( iter.hasNext() ) { - o = iter.next(); - if( o != null ) { - if( o instanceof File ) { - file = (File) o; - } else { - String s = o.toString(); - if( s != null ) { - if( !s.isEmpty() ) { - file = new File( s ); - break; - } - } - } - } - } - } - } - } - } - catch( Exception ex ) {} - } - e.dropComplete( true ); - } else { - e.rejectDrop(); + + + public static JButton createImageButton( + Component owner, + String imgName, + String text, + String actionCmd) { + JButton btn = null; + Image img = readImage(owner, imgName); + if (img != null) { + btn = new JButton(new ImageIcon(img)); + btn.setToolTipText(text); + } else { + btn = new JButton(text); + } + btn.setFocusable(false); + if (owner instanceof ActionListener) { + btn.addActionListener((ActionListener) owner); + } + if (actionCmd != null) { + btn.setActionCommand(actionCmd); + } + return btn; } - return file; - } - - - public static String getClipboardText( Component c ) - { - String text = null; - try { - Clipboard clipboard = c.getToolkit().getSystemClipboard(); - if( clipboard != null ) { - if( clipboard.isDataFlavorAvailable( DataFlavor.stringFlavor ) ) { - Object o = clipboard.getData( DataFlavor.stringFlavor ); - if( o != null ) { - text = o.toString(); - } - } - } + + + public static JButton createImageButton( + Component owner, + String imgName, + String text) { + return createImageButton(owner, imgName, text, null); } - catch( Exception ex ) {} - return text; - } - - - public static int getMenuShortcutKeyMask( Component c ) - { - if( menuShortcutKeyMask == null ) { - Toolkit tk = c.getToolkit(); - for( String methodName : new String[] { - "getMenuShortcutKeyMaskEx", - "getMenuShortcutKeyMask" } ) - { - try { - Object v = tk.getClass().getMethod( methodName ).invoke( tk ); - if( v != null ) { - if( v instanceof Number ) { - menuShortcutKeyMask = Integer.valueOf( - ((Number) v).intValue() ); - break; - } - } - } - catch( Exception ex ) {} - } + + + public static File fileDrop(Component owner, DropTargetDropEvent e) { + File file = null; + if (isFileDrop(e)) { + e.acceptDrop(DnDConstants.ACTION_COPY); // Quelle nicht loeschen + Transferable t = e.getTransferable(); + if (t != null) { + try { + Object o = t.getTransferData(DataFlavor.javaFileListFlavor); + if (o != null) { + if (o instanceof Collection) { + Iterator iter = ((Collection) o).iterator(); + if (iter != null) { + while (iter.hasNext()) { + o = iter.next(); + if (o != null) { + if (o instanceof File) { + file = (File) o; + } else { + String s = o.toString(); + if (s != null) { + if (!s.isEmpty()) { + file = new File(s); + break; + } + } + } + } + } + } + } + } + } catch (Exception ex) { + } + } + e.dropComplete(true); + } else { + e.rejectDrop(); + } + return file; } - if( menuShortcutKeyMask == null ) { - menuShortcutKeyMask = Integer.valueOf( InputEvent.CTRL_DOWN_MASK ); + + + public static String getClipboardText(Component c) { + String text = null; + try { + Clipboard clipboard = c.getToolkit().getSystemClipboard(); + if (clipboard != null) { + if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { + Object o = clipboard.getData(DataFlavor.stringFlavor); + if (o != null) { + text = o.toString(); + } + } + } + } catch (Exception ex) { + } + return text; } - return menuShortcutKeyMask.intValue(); - } - - - public static Font getMonospacedFont( Component c ) - { - int style = Font.BOLD; - int size = 12; - if( c != null ) { - Font font = c.getFont(); - if( font != null ) { - style = font.getStyle(); - size = font.getSize(); - } + + + public static int getMenuShortcutKeyMask(Component c) { + if (menuShortcutKeyMask == null) { + Toolkit tk = c.getToolkit(); + for (String methodName : new String[]{ + "getMenuShortcutKeyMaskEx", + "getMenuShortcutKeyMask"}) { + try { + Object v = tk.getClass().getMethod(methodName).invoke(tk); + if (v != null) { + if (v instanceof Number) { + menuShortcutKeyMask = Integer.valueOf( + ((Number) v).intValue()); + break; + } + } + } catch (Exception ex) { + } + } + } + if (menuShortcutKeyMask == null) { + menuShortcutKeyMask = Integer.valueOf(InputEvent.CTRL_DOWN_MASK); + } + return menuShortcutKeyMask.intValue(); } - return new Font( Font.MONOSPACED, style, size ); - } - public static Window getWindow( Component c ) - { - while( c != null ) { - if( c instanceof Window ) { - return (Window) c; - } - c = c.getParent(); + public static Font getMonospacedFont(Component c) { + int style = Font.BOLD; + int size = 12; + if (c != null) { + Font font = c.getFont(); + if (font != null) { + style = font.getStyle(); + size = font.getSize(); + } + } + return new Font(Font.MONOSPACED, style, size); } - return null; - } - public static boolean hasSelection( JTextComponent textComp ) - { - boolean rv = false; - if( textComp != null ) { - int e = textComp.getSelectionEnd(); - rv = (textComp.getSelectionStart() < e) && (e > 0); + public static Window getWindow(Component c) { + while (c != null) { + if (c instanceof Window) { + return (Window) c; + } + c = c.getParent(); + } + return null; } - return rv; - } - - - public static boolean isFileDrop( DropTargetDragEvent e ) - { - boolean rv = false; - int action = e.getDropAction(); - if( (action == DnDConstants.ACTION_COPY) - || (action == DnDConstants.ACTION_MOVE) - || (action == DnDConstants.ACTION_COPY_OR_MOVE) - || (action == DnDConstants.ACTION_LINK) ) - { - rv = e.isDataFlavorSupported( DataFlavor.javaFileListFlavor ); + + + public static boolean hasSelection(JTextComponent textComp) { + boolean rv = false; + if (textComp != null) { + int e = textComp.getSelectionEnd(); + rv = (textComp.getSelectionStart() < e) && (e > 0); + } + return rv; } - return rv; - } - - - public static boolean isFileDrop( DropTargetDropEvent e ) - { - boolean rv = false; - int action = e.getDropAction(); - if( (action == DnDConstants.ACTION_COPY) - || (action == DnDConstants.ACTION_MOVE) - || (action == DnDConstants.ACTION_COPY_OR_MOVE) - || (action == DnDConstants.ACTION_LINK) ) - { - rv = e.isDataFlavorSupported( DataFlavor.javaFileListFlavor ); + + + public static boolean isFileDrop(DropTargetDragEvent e) { + boolean rv = false; + int action = e.getDropAction(); + if ((action == DnDConstants.ACTION_COPY) + || (action == DnDConstants.ACTION_MOVE) + || (action == DnDConstants.ACTION_COPY_OR_MOVE) + || (action == DnDConstants.ACTION_LINK)) { + rv = e.isDataFlavorSupported(DataFlavor.javaFileListFlavor); + } + return rv; } - return rv; - } - - - public static void memorizeWindowSettings( BaseFrm frm ) - { - if( frm.isVisible() ) { - String prefix = frm.getPropPrefix(); - AppContext.setProperty( prefix + PROP_WINDOW_X, frm.getX() ); - AppContext.setProperty( prefix + PROP_WINDOW_Y, frm.getY() ); - AppContext.setProperty( prefix + PROP_WINDOW_W, frm.getWidth() ); - AppContext.setProperty( prefix + PROP_WINDOW_H, frm.getHeight() ); + + + public static boolean isFileDrop(DropTargetDropEvent e) { + boolean rv = false; + int action = e.getDropAction(); + if ((action == DnDConstants.ACTION_COPY) + || (action == DnDConstants.ACTION_MOVE) + || (action == DnDConstants.ACTION_COPY_OR_MOVE) + || (action == DnDConstants.ACTION_LINK)) { + rv = e.isDataFlavorSupported(DataFlavor.javaFileListFlavor); + } + return rv; } - } - public static int parseHex4( - JTextField fld, - String fldName ) throws UserInputException - { - int value = JTCUtil.parseHex4( fld.getText(), fldName ); - fld.setText( String.format( "%04X", value ) ); - return value; - } + public static void memorizeWindowSettings(BaseFrm frm) { + if (frm.isVisible()) { + String prefix = frm.getPropPrefix(); + AppContext.setProperty(prefix + PROP_WINDOW_X, frm.getX()); + AppContext.setProperty(prefix + PROP_WINDOW_Y, frm.getY()); + AppContext.setProperty(prefix + PROP_WINDOW_W, frm.getWidth()); + AppContext.setProperty(prefix + PROP_WINDOW_H, frm.getHeight()); + } + } - public static Image readImage( Component owner, String resource ) - { - Image img = null; - URL url = GUIUtil.class.getResource( resource ); - if( url != null ) { - img = owner.getToolkit().createImage( url ); + public static int parseHex4( + JTextField fld, + String fldName) throws UserInputException { + int value = JTCUtil.parseHex4(fld.getText(), fldName); + fld.setText(String.format("%04X", value)); + return value; } - return img; - } - - - public static void setWaitCursor( RootPaneContainer c, boolean state ) - { - Component glassPane = c.getGlassPane(); - if( state ) { - glassPane.setCursor( waitCursor ); - glassPane.setVisible( true ); - } else { - glassPane.setCursor( defaultCursor ); - glassPane.setVisible( false ); + + + public static Image readImage(Component owner, String resource) { + Image img = null; + URL url = GUIUtil.class.getResource(resource); + if (url != null) { + img = owner.getToolkit().createImage(url); + } + return img; } - } - public static void toFront( final Frame frame ) - { - int state = frame.getExtendedState(); - if( (state & Frame.ICONIFIED) != 0 ) { - frame.setExtendedState( state & ~Frame.ICONIFIED ); + public static void setWaitCursor(RootPaneContainer c, boolean state) { + Component glassPane = c.getGlassPane(); + if (state) { + glassPane.setCursor(waitCursor); + glassPane.setVisible(true); + } else { + glassPane.setCursor(defaultCursor); + glassPane.setVisible(false); + } } - if( !frame.isShowing() ) { - frame.setVisible( true ); + + + public static void toFront(final Frame frame) { + int state = frame.getExtendedState(); + if ((state & Frame.ICONIFIED) != 0) { + frame.setExtendedState(state & ~Frame.ICONIFIED); + } + if (!frame.isShowing()) { + frame.setVisible(true); + } + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + frame.toFront(); + } + }); } - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - frame.toFront(); - } - } ); - } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/LoadDlg.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/LoadDlg.java index 0572458..9e8807e 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/LoadDlg.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/LoadDlg.java @@ -22,331 +22,318 @@ import java.io.File; -public class LoadDlg extends BaseDlg implements ActionListener -{ - private static final String LABEL_BEG_ADDR = "Laden ab Adresse:"; - private static final String LABEL_END_ADDR = "Bis max. Adresse:"; - - private TopFrm topFrm; - private Z8Memory memory; - private File file; - private FileInfo.Format fileFmt; - private JTextField fldBegAddr; - private JTextField fldEndAddr; - private JCheckBox btnLoadAsBIN; - private JButton btnLoad; - private JButton btnHelp; - private JButton btnCancel; - - - public static boolean loadFile( - Window owner, - TopFrm topFrm, - Z8Memory memory, - File file, - FileInfo.Format fmt, - int begAddr, - int endAddr, - int startAddr ) - { - boolean done = false; - FileLoader fileLoader = new FileLoader( memory ); - String statusText = fileLoader.loadFile( - file, - fmt, - begAddr, - endAddr, - startAddr ); - if( statusText != null ) { - AppContext.setLastFile( FileInfo.FILE_GROUP_SOFTWARE, file ); - done = true; +public class LoadDlg extends BaseDlg implements ActionListener { + private static final String LABEL_BEG_ADDR = "Laden ab Adresse:"; + private static final String LABEL_END_ADDR = "Bis max. Adresse:"; + + private TopFrm topFrm; + private Z8Memory memory; + private File file; + private FileInfo.Format fileFmt; + private JTextField fldBegAddr; + private JTextField fldEndAddr; + private JCheckBox btnLoadAsBIN; + private JButton btnLoad; + private JButton btnHelp; + private JButton btnCancel; + + + public static boolean loadFile( + Window owner, + TopFrm topFrm, + Z8Memory memory, + File file, + FileInfo.Format fmt, + int begAddr, + int endAddr, + int startAddr) { + boolean done = false; + FileLoader fileLoader = new FileLoader(memory); + String statusText = fileLoader.loadFile( + file, + fmt, + begAddr, + endAddr, + startAddr); + if (statusText != null) { + AppContext.setLastFile(FileInfo.FILE_GROUP_SOFTWARE, file); + done = true; + } + String msg = fileLoader.getMessage(); + if (!done && (msg == null)) { + msg = "Datei konnte nicht geladen werden."; + } + if (msg != null) { + if (done) { + showSuppressableInfoDlg(owner, msg); + } else { + JOptionPane.showMessageDialog( + owner, + msg, + "Fehler", + JOptionPane.ERROR_MESSAGE); + } + } + if (statusText != null) { + topFrm.showStatusText(statusText); + } + return done; } - String msg = fileLoader.getMessage(); - if( !done && (msg == null) ) { - msg = "Datei konnte nicht geladen werden."; - } - if( msg != null ) { - if( done ) { - showSuppressableInfoDlg( owner, msg ); - } else { - JOptionPane.showMessageDialog( - owner, - msg, - "Fehler", - JOptionPane.ERROR_MESSAGE ); - } - } - if( statusText != null ) { - topFrm.showStatusText( statusText ); - } - return done; - } - - public static void open( - TopFrm topFrm, - Z8Memory memory, - File file, - FileInfo fileInfo ) - { - (new LoadDlg( topFrm, memory, file, fileInfo )).setVisible( true ); - } + public static void open( + TopFrm topFrm, + Z8Memory memory, + File file, + FileInfo fileInfo) { + (new LoadDlg(topFrm, memory, file, fileInfo)).setVisible(true); + } - /* --- ActionListener --- */ - @Override - public void actionPerformed( ActionEvent e ) - { - Object src = e.getSource(); - if( (src == this.fldEndAddr) || (src == this.btnLoad) ) { - doLoad(); - } - else if( src == this.btnHelp ) { - HelpFrm.open( "/help/loadsave.htm" ); - } - else if( src == this.btnCancel ) { - doClose(); - } - else if( src == this.fldBegAddr ) { - this.fldBegAddr.transferFocus(); + /* --- ActionListener --- */ + + @Override + public void actionPerformed(ActionEvent e) { + Object src = e.getSource(); + if ((src == this.fldEndAddr) || (src == this.btnLoad)) { + doLoad(); + } else if (src == this.btnHelp) { + HelpFrm.open("/help/loadsave.htm"); + } else if (src == this.btnCancel) { + doClose(); + } else if (src == this.fldBegAddr) { + this.fldBegAddr.transferFocus(); + } } - } - /* --- ueberschriebene Methoden --- */ + /* --- ueberschriebene Methoden --- */ - @Override - protected boolean doClose() - { - boolean rv = super.doClose(); - if( rv ) { - this.fldBegAddr.removeActionListener( this ); - this.fldEndAddr.removeActionListener( this ); - this.btnLoad.removeActionListener( this ); - this.btnHelp.removeActionListener( this ); - this.btnCancel.removeActionListener( this ); - } - return rv; - } - - - /* --- Konstruktor --- */ - - private LoadDlg( - TopFrm topFrm, - Z8Memory memory, - File file, - FileInfo fileInfo ) - { - super( topFrm ); - setTitle( "Datei laden" ); - this.topFrm = topFrm; - this.memory = memory; - this.file = file; - this.fileFmt = fileInfo.getFormat(); - - - // Fensterinhalt - setLayout( new GridBagLayout() ); - - GridBagConstraints gbc = new GridBagConstraints( - 0, 0, - 1, 1, - 1.0, 0.0, - GridBagConstraints.CENTER, - GridBagConstraints.HORIZONTAL, - new Insets( 5, 5, 5, 5 ), - 0, 0 ); - - - // Bereich Dateiformat - JPanel panelFile = new JPanel( new GridBagLayout() ); - panelFile.setBorder( BorderFactory.createTitledBorder( "Datei" ) ); - add( panelFile, gbc ); - - GridBagConstraints gbcFile = new GridBagConstraints( - 0, 0, - 1, 1, - 0.0, 0.0, - GridBagConstraints.EAST, - GridBagConstraints.NONE, - new Insets( 5, 5, 5, 5 ), - 0, 0 ); - - panelFile.add( new JLabel( "Dateiname:" ), gbcFile ); - gbcFile.insets.top = 0; - gbcFile.gridy++; - panelFile.add( new JLabel( "Info:" ), gbcFile ); - - JTextField fldFileName = new JTextField(); - fldFileName.setEditable( false ); - gbcFile.anchor = GridBagConstraints.WEST; - gbcFile.fill = GridBagConstraints.HORIZONTAL; - gbcFile.weightx = 1.0; - gbcFile.insets.top = 5; - gbcFile.gridx = 1; - gbcFile.gridy = 0; - panelFile.add( fldFileName, gbcFile ); - - JTextField fldFileInfo = new JTextField(); - fldFileInfo.setEditable( false ); - gbcFile.insets.top = 0; - gbcFile.gridy++; - panelFile.add( fldFileInfo, gbcFile ); - - this.btnLoadAsBIN = null; - if( !this.fileFmt.equals( FileInfo.Format.BIN ) ) { - this.btnLoadAsBIN = new JCheckBox( "Als BIN-Datei laden" ); - gbcFile.fill = GridBagConstraints.NONE; - gbcFile.weightx = 0.0; - gbcFile.gridy++; - panelFile.add( this.btnLoadAsBIN, gbcFile ); + @Override + protected boolean doClose() { + boolean rv = super.doClose(); + if (rv) { + this.fldBegAddr.removeActionListener(this); + this.fldEndAddr.removeActionListener(this); + this.btnLoad.removeActionListener(this); + this.btnHelp.removeActionListener(this); + this.btnCancel.removeActionListener(this); + } + return rv; } - // Bereich Ladeadressen - JPanel panelAddr = new JPanel( new GridBagLayout() ); - panelAddr.setBorder( BorderFactory.createTitledBorder( "Ladeadressen" ) ); - gbc.gridy++; - add( panelAddr, gbc ); - - GridBagConstraints gbcAddr = new GridBagConstraints( - 0, 0, - 1, 1, - 0.0, 0.0, - GridBagConstraints.WEST, - GridBagConstraints.NONE, - new Insets( 5, 5, 5, 5 ), - 0, 0 ); - - panelAddr.add( new JLabel( LABEL_BEG_ADDR ), gbcAddr ); - - this.fldBegAddr = createJTextField( 4 ); - gbcAddr.fill = GridBagConstraints.HORIZONTAL; - gbcAddr.weightx = 0.5; - gbcAddr.gridx++; - panelAddr.add( this.fldBegAddr, gbcAddr ); - - gbcAddr.fill = GridBagConstraints.NONE; - gbcAddr.weightx = 0.0; - gbcAddr.gridx++; - panelAddr.add( new JLabel( LABEL_END_ADDR ), gbcAddr ); - - this.fldEndAddr = createJTextField( 4 ); - gbcAddr.fill = GridBagConstraints.HORIZONTAL; - gbcAddr.weightx = 0.5; - gbcAddr.gridx++; - panelAddr.add( this.fldEndAddr, gbcAddr ); - - - // Knoepfe - JPanel panelBtn = new JPanel( new GridLayout( 1, 3, 5, 5 ) ); - gbc.fill = GridBagConstraints.NONE; - gbc.weightx = 0.0; - gbc.insets.top = 10; - gbc.insets.left = 10; - gbc.insets.right = 10; - gbc.insets.bottom = 10; - gbc.gridy++; - add( panelBtn,gbc ); - - this.btnLoad = new JButton( "Laden" ); - panelBtn.add( this.btnLoad ); - - this.btnHelp = new JButton( "Hilfe..." ); - panelBtn.add( this.btnHelp ); - - this.btnCancel = new JButton( "Abbrechen" ); - panelBtn.add( this.btnCancel ); - - - // Vorbelegung - String fileName = file.getName(); - if( fileName != null ) { - fldFileName.setText( fileName ); - } - String infoText = fileInfo.getInfoText(); - if( infoText != null ) { - fldFileInfo.setText( infoText ); + /* --- Konstruktor --- */ + + private LoadDlg( + TopFrm topFrm, + Z8Memory memory, + File file, + FileInfo fileInfo) { + super(topFrm); + setTitle("Datei laden"); + this.topFrm = topFrm; + this.memory = memory; + this.file = file; + this.fileFmt = fileInfo.getFormat(); + + + // Fensterinhalt + setLayout(new GridBagLayout()); + + GridBagConstraints gbc = new GridBagConstraints( + 0, 0, + 1, 1, + 1.0, 0.0, + GridBagConstraints.CENTER, + GridBagConstraints.HORIZONTAL, + new Insets(5, 5, 5, 5), + 0, 0); + + + // Bereich Dateiformat + JPanel panelFile = new JPanel(new GridBagLayout()); + panelFile.setBorder(BorderFactory.createTitledBorder("Datei")); + add(panelFile, gbc); + + GridBagConstraints gbcFile = new GridBagConstraints( + 0, 0, + 1, 1, + 0.0, 0.0, + GridBagConstraints.EAST, + GridBagConstraints.NONE, + new Insets(5, 5, 5, 5), + 0, 0); + + panelFile.add(new JLabel("Dateiname:"), gbcFile); + gbcFile.insets.top = 0; + gbcFile.gridy++; + panelFile.add(new JLabel("Info:"), gbcFile); + + JTextField fldFileName = new JTextField(); + fldFileName.setEditable(false); + gbcFile.anchor = GridBagConstraints.WEST; + gbcFile.fill = GridBagConstraints.HORIZONTAL; + gbcFile.weightx = 1.0; + gbcFile.insets.top = 5; + gbcFile.gridx = 1; + gbcFile.gridy = 0; + panelFile.add(fldFileName, gbcFile); + + JTextField fldFileInfo = new JTextField(); + fldFileInfo.setEditable(false); + gbcFile.insets.top = 0; + gbcFile.gridy++; + panelFile.add(fldFileInfo, gbcFile); + + this.btnLoadAsBIN = null; + if (!this.fileFmt.equals(FileInfo.Format.BIN)) { + this.btnLoadAsBIN = new JCheckBox("Als BIN-Datei laden"); + gbcFile.fill = GridBagConstraints.NONE; + gbcFile.weightx = 0.0; + gbcFile.gridy++; + panelFile.add(this.btnLoadAsBIN, gbcFile); + } + + + // Bereich Ladeadressen + JPanel panelAddr = new JPanel(new GridBagLayout()); + panelAddr.setBorder(BorderFactory.createTitledBorder("Ladeadressen")); + gbc.gridy++; + add(panelAddr, gbc); + + GridBagConstraints gbcAddr = new GridBagConstraints( + 0, 0, + 1, 1, + 0.0, 0.0, + GridBagConstraints.WEST, + GridBagConstraints.NONE, + new Insets(5, 5, 5, 5), + 0, 0); + + panelAddr.add(new JLabel(LABEL_BEG_ADDR), gbcAddr); + + this.fldBegAddr = createJTextField(4); + gbcAddr.fill = GridBagConstraints.HORIZONTAL; + gbcAddr.weightx = 0.5; + gbcAddr.gridx++; + panelAddr.add(this.fldBegAddr, gbcAddr); + + gbcAddr.fill = GridBagConstraints.NONE; + gbcAddr.weightx = 0.0; + gbcAddr.gridx++; + panelAddr.add(new JLabel(LABEL_END_ADDR), gbcAddr); + + this.fldEndAddr = createJTextField(4); + gbcAddr.fill = GridBagConstraints.HORIZONTAL; + gbcAddr.weightx = 0.5; + gbcAddr.gridx++; + panelAddr.add(this.fldEndAddr, gbcAddr); + + + // Knoepfe + JPanel panelBtn = new JPanel(new GridLayout(1, 3, 5, 5)); + gbc.fill = GridBagConstraints.NONE; + gbc.weightx = 0.0; + gbc.insets.top = 10; + gbc.insets.left = 10; + gbc.insets.right = 10; + gbc.insets.bottom = 10; + gbc.gridy++; + add(panelBtn, gbc); + + this.btnLoad = new JButton("Laden"); + panelBtn.add(this.btnLoad); + + this.btnHelp = new JButton("Hilfe..."); + panelBtn.add(this.btnHelp); + + this.btnCancel = new JButton("Abbrechen"); + panelBtn.add(this.btnCancel); + + + // Vorbelegung + String fileName = file.getName(); + if (fileName != null) { + fldFileName.setText(fileName); + } + String infoText = fileInfo.getInfoText(); + if (infoText != null) { + fldFileInfo.setText(infoText); + } + int begAddr = fileInfo.getBegAddr(); + if (begAddr < 0) { + begAddr = FileLoader.DEFAULt_LOAD_ADDR; + } + this.fldBegAddr.setText(String.format("%04X", begAddr)); + + + // Fenstergroesse + pack(); + this.fldBegAddr.setColumns(0); + this.fldEndAddr.setColumns(0); + setParentCentered(); + setResizable(true); + + + // Listener + this.fldBegAddr.addActionListener(this); + this.fldEndAddr.addActionListener(this); + this.btnLoad.addActionListener(this); + this.btnHelp.addActionListener(this); + this.btnCancel.addActionListener(this); } - int begAddr = fileInfo.getBegAddr(); - if( begAddr < 0 ) { - begAddr = FileLoader.DEFAULt_LOAD_ADDR; - } - this.fldBegAddr.setText( String.format( "%04X", begAddr ) ); - - // Fenstergroesse - pack(); - this.fldBegAddr.setColumns( 0 ); - this.fldEndAddr.setColumns( 0 ); - setParentCentered(); - setResizable( true ); + /* --- private Methoden --- */ - // Listener - this.fldBegAddr.addActionListener( this ); - this.fldEndAddr.addActionListener( this ); - this.btnLoad.addActionListener( this ); - this.btnHelp.addActionListener( this ); - this.btnCancel.addActionListener( this ); - } - + private JTextField createJTextField(int cols) { + JTextField fld = new JTextField(cols); + Dimension pSize = fld.getPreferredSize(); + if (pSize != null) { + if (pSize.height > 0) { + fld.setPreferredSize(new Dimension(1, pSize.height)); + } + } + return fld; + } - /* --- private Methoden --- */ - private JTextField createJTextField( int cols ) - { - JTextField fld = new JTextField( cols ); - Dimension pSize = fld.getPreferredSize(); - if( pSize != null ) { - if( pSize.height > 0 ) { - fld.setPreferredSize( new Dimension( 1, pSize.height ) ); - } - } - return fld; - } - - - private void doLoad() - { - try { - int endAddr = -1; - int begAddr = JTCUtil.parseHex4( - this.fldBegAddr.getText(), - LABEL_BEG_ADDR ); - - String text = this.fldEndAddr.getText(); - if( text != null ) { - text = text.trim(); - if( !text.isEmpty() ) { - endAddr = JTCUtil.parseHex4( text, LABEL_END_ADDR ); - } - } - FileInfo.Format fmt = this.fileFmt; - if( this.btnLoadAsBIN != null ) { - if( this.btnLoadAsBIN.isSelected() ) { - fmt = FileInfo.Format.BIN; - } - } - if( fmt != null ) { - if( loadFile( - this, - this.topFrm, - this.memory, - this.file, - fmt, - begAddr, - endAddr, - -1 ) ) - { - doClose(); - } - } - } - catch( Exception ex ) { - Main.showError( this, ex ); + private void doLoad() { + try { + int endAddr = -1; + int begAddr = JTCUtil.parseHex4( + this.fldBegAddr.getText(), + LABEL_BEG_ADDR); + + String text = this.fldEndAddr.getText(); + if (text != null) { + text = text.trim(); + if (!text.isEmpty()) { + endAddr = JTCUtil.parseHex4(text, LABEL_END_ADDR); + } + } + FileInfo.Format fmt = this.fileFmt; + if (this.btnLoadAsBIN != null) { + if (this.btnLoadAsBIN.isSelected()) { + fmt = FileInfo.Format.BIN; + } + } + if (fmt != null) { + if (loadFile( + this, + this.topFrm, + this.memory, + this.file, + fmt, + begAddr, + endAddr, + -1)) { + doClose(); + } + } + } catch (Exception ex) { + Main.showError(this, ex); + } } - } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/ScreenFld.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/ScreenFld.java index b19ba34..062e400 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/ScreenFld.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/ScreenFld.java @@ -22,493 +22,462 @@ public class ScreenFld - extends JComponent - implements JTCScreen, MouseMotionListener -{ - private TopFrm topFrm; - private JTCSys jtcSys; - private int jtcScreenH; - private int jtcScreenW; - private int scale; - private int margin; - private volatile boolean dirty; - private Color[] colors; - private Color markXORColor; - private CharRaster charRaster; - private Point dragStart; - private Point dragEnd; - private boolean textSelected; - private int selectionCharX1; - private int selectionCharX2; - private int selectionCharY1; - private int selectionCharY2; - - - public ScreenFld( TopFrm topFrm, JTCSys jtcSys, int scale ) - { - this.topFrm = topFrm; - this.jtcSys = jtcSys; - this.scale = scale; - this.margin = 0; - this.dirty = false; - this.markXORColor = new Color( 192, 192, 0 ); - this.colors = null; - this.charRaster = null; - this.dragStart = null; - this.dragEnd = null; - this.textSelected = false; - this.selectionCharX1 = -1; - this.selectionCharY1 = -1; - this.selectionCharX2 = -1; - this.selectionCharY2 = -1; - - int[] rgbs = jtcSys.getColorModeRGBs(); - this.colors = new Color[ rgbs.length ]; - for( int i = 0; i < this.colors.length; i++ ) { - this.colors[ i ] = new Color( 0xFF000000 | rgbs[ i ] ); + extends JComponent + implements JTCScreen, MouseMotionListener { + private TopFrm topFrm; + private JTCSys jtcSys; + private int jtcScreenH; + private int jtcScreenW; + private int scale; + private int margin; + private volatile boolean dirty; + private Color[] colors; + private Color markXORColor; + private CharRaster charRaster; + private Point dragStart; + private Point dragEnd; + private boolean textSelected; + private int selectionCharX1; + private int selectionCharX2; + private int selectionCharY1; + private int selectionCharY2; + + + public ScreenFld(TopFrm topFrm, JTCSys jtcSys, int scale) { + this.topFrm = topFrm; + this.jtcSys = jtcSys; + this.scale = scale; + this.margin = 0; + this.dirty = false; + this.markXORColor = new Color(192, 192, 0); + this.colors = null; + this.charRaster = null; + this.dragStart = null; + this.dragEnd = null; + this.textSelected = false; + this.selectionCharX1 = -1; + this.selectionCharY1 = -1; + this.selectionCharX2 = -1; + this.selectionCharY2 = -1; + + int[] rgbs = jtcSys.getColorModeRGBs(); + this.colors = new Color[rgbs.length]; + for (int i = 0; i < this.colors.length; i++) { + this.colors[i] = new Color(0xFF000000 | rgbs[i]); + } + updPreferredSize(); + this.jtcSys.setScreen(this); + addMouseMotionListener(this); + addMouseListener( + new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + clearSelection(); + } + } + }); } - updPreferredSize(); - this.jtcSys.setScreen( this ); - addMouseMotionListener( this ); - addMouseListener( - new MouseAdapter() - { - @Override - public void mouseClicked( MouseEvent e ) - { - if( e.getButton() == MouseEvent.BUTTON1 ) { - clearSelection(); - } - } - } ); - } - - - public void clearSelection() - { - this.dragStart = null; - this.dragEnd = null; - this.selectionCharX1 = -1; - this.selectionCharY1 = -1; - this.selectionCharX2 = -1; - this.selectionCharY2 = -1; - setScreenDirty(); - } - - - public BufferedImage createBufferedImage() - { - BufferedImage img = null; - int w = getWidth(); - int h = getHeight(); - if( (w > 0) && (h > 0) && (this.colors != null) ) { - byte[] r = new byte[ this.colors.length ]; - byte[] g = new byte[ this.colors.length ]; - byte[] b = new byte[ this.colors.length ]; - for( int i = 0; i < this.colors.length; i++ ) { - r[ i ] = (byte) this.colors[ i ].getRed(); - g[ i ] = (byte) this.colors[ i ].getGreen(); - b[ i ] = (byte) this.colors[ i ].getBlue(); - } - img = new BufferedImage( - w, - h, - BufferedImage.TYPE_BYTE_INDEXED, - new IndexColorModel( - Integer.highestOneBit( - this.colors.length - 1 ), - this.colors.length, - r, g, b ) ); - Graphics graphics = img.createGraphics(); - paint( graphics, w, h, false ); - graphics.dispose(); + + + public void clearSelection() { + this.dragStart = null; + this.dragEnd = null; + this.selectionCharX1 = -1; + this.selectionCharY1 = -1; + this.selectionCharX2 = -1; + this.selectionCharY2 = -1; + setScreenDirty(); + } + + + public BufferedImage createBufferedImage() { + BufferedImage img = null; + int w = getWidth(); + int h = getHeight(); + if ((w > 0) && (h > 0) && (this.colors != null)) { + byte[] r = new byte[this.colors.length]; + byte[] g = new byte[this.colors.length]; + byte[] b = new byte[this.colors.length]; + for (int i = 0; i < this.colors.length; i++) { + r[i] = (byte) this.colors[i].getRed(); + g[i] = (byte) this.colors[i].getGreen(); + b[i] = (byte) this.colors[i].getBlue(); + } + img = new BufferedImage( + w, + h, + BufferedImage.TYPE_BYTE_INDEXED, + new IndexColorModel( + Integer.highestOneBit( + this.colors.length - 1), + this.colors.length, + r, g, b)); + Graphics graphics = img.createGraphics(); + paint(graphics, w, h, false); + graphics.dispose(); + } + return img; } - return img; - } - - - public int getMargin() - { - return this.margin; - } - - - public int getScale() - { - return this.scale; - } - - - public String getSelectedText() - { - String text = null; - if( (this.selectionCharX1 >= 0) - && (this.selectionCharY1 >= 0) - && (this.selectionCharX2 >= 0) - && (this.selectionCharY2 >= 0) ) - { - text = this.jtcSys.getScreenText( - this.selectionCharX1, - this.selectionCharY1, - this.selectionCharX2, - this.selectionCharY2 ); + + + public int getMargin() { + return this.margin; } - return text; - } - public boolean isDirty() - { - return this.dirty; - } + public int getScale() { + return this.scale; + } - public void setMargin( int margin ) - { - this.margin = margin; - updPreferredSize(); - } + public String getSelectedText() { + String text = null; + if ((this.selectionCharX1 >= 0) + && (this.selectionCharY1 >= 0) + && (this.selectionCharX2 >= 0) + && (this.selectionCharY2 >= 0)) { + text = this.jtcSys.getScreenText( + this.selectionCharX1, + this.selectionCharY1, + this.selectionCharX2, + this.selectionCharY2); + } + return text; + } - public void setScale( int scale ) - { - if( (scale > 0) && (scale != this.scale) ) { - this.scale = scale; - updPreferredSize(); + public boolean isDirty() { + return this.dirty; } - } - public void updPreferredSize() - { - this.jtcScreenW = jtcSys.getScreenWidth(); - this.jtcScreenH = jtcSys.getScreenHeight(); + public void setMargin(int margin) { + this.margin = margin; + updPreferredSize(); + } + - int margin = this.margin; - if( margin < 0 ) { - margin = 0; + public void setScale(int scale) { + if ((scale > 0) && (scale != this.scale)) { + this.scale = scale; + updPreferredSize(); + } } - setPreferredSize( - new Dimension( - (2 * margin) + (this.jtcScreenW * this.scale), - (2 * margin) + (this.jtcScreenH * this.scale) ) ); - Container parent = getParent(); - if( parent != null ) { - parent.invalidate(); - } else { - invalidate(); + + + public void updPreferredSize() { + this.jtcScreenW = jtcSys.getScreenWidth(); + this.jtcScreenH = jtcSys.getScreenHeight(); + + int margin = this.margin; + if (margin < 0) { + margin = 0; + } + setPreferredSize( + new Dimension( + (2 * margin) + (this.jtcScreenW * this.scale), + (2 * margin) + (this.jtcScreenH * this.scale))); + Container parent = getParent(); + if (parent != null) { + parent.invalidate(); + } else { + invalidate(); + } } - } - - - /* --- JTCScreen --- */ - - @Override - public void screenConfigChanged() - { - final TopFrm topFrm = this.topFrm; - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - topFrm.screenConfigChanged(); - } - } ); - } - - - @Override - public void setScreenDirty() - { - this.dirty = true; - } - - - /* --- MouseMotionListener --- */ - - @Override - public void mouseDragged( MouseEvent e ) - { - if( e.getComponent() == this ) { - if( this.dragStart == null ) { - this.charRaster = this.jtcSys.getScreenCharRaster(); - if( this.charRaster != null ) { - this.dragStart = new Point( e.getX(), e.getY() ); - this.dragEnd = null; - setScreenDirty(); - } - } else { - if( this.charRaster != null ) { - this.dragEnd = new Point( e.getX(), e.getY() ); - } else { - this.dragEnd = null; - this.dragStart = null; - } - setScreenDirty(); - } - e.consume(); + + + /* --- JTCScreen --- */ + + @Override + public void screenConfigChanged() { + final TopFrm topFrm = this.topFrm; + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + topFrm.screenConfigChanged(); + } + }); } - } - - - @Override - public void mouseMoved( MouseEvent e ) - { - // leer - } - - - /* --- ueberschriebene Methoden --- */ - - @Override - public boolean isFocusable() - { - return true; - } - - - @Override - public void paint( Graphics g ) - { - this.dirty = false; - paint( g, getWidth(), getHeight(), true ); - } - - - /* - * update(...) wird ueberschrieben, - * da paint(...) die Komponente vollstaendig fuellt - * und somit das standardmaessige Fuellen mit der Hintegrundfarbe - * entfallen kann. - */ - @Override - public void update( Graphics g ) - { - paint( g ); - } - - - /* --- private Methoden --- */ - - private Color getColor( int colorNum ) - { - Color color = Color.BLACK; - if( this.jtcSys.isMonochrome() ) { - if( colorNum > 0 ) { - color = Color.WHITE; - } - } else { - if( (colorNum >= 0) && (colorNum < this.colors.length) ) { - color = this.colors[ colorNum ]; - } + + + @Override + public void setScreenDirty() { + this.dirty = true; } - return color; - } - - - private void paint( Graphics g, int w, int h, boolean withMarking ) - { - if( (w > 0) && (h > 0) ) { - - // Hintergrund - Color bgColor = Color.BLACK; - g.setColor( bgColor ); - g.fillRect( 0, 0, w, h ); - - // Vordergrund - int baseW = this.jtcScreenW; - int baseH = this.jtcScreenH; - if( (baseW > 0) && (baseH > 0) - && this.jtcSys.isScreenOutputEnabled() ) - { - // zentrieren - int xOffs = (w - (baseW * this.scale)) / 2; - if( xOffs < 0) { - xOffs = 0; - } - int yOffs = (h - (baseH * this.scale)) / 2; - if( yOffs < 0) { - yOffs = 0; - } - if( (xOffs > 0) || (yOffs > 0) ) { - g.translate( xOffs, yOffs ); - } - - /* - * Aus Gruenden der Performance werden nebeneinander liegende - * Punkte zusammengefasst und als Linie gezeichnet. - */ - for( int y = 0; y < baseH; y++ ) { - Color lastColor = null; - int xColorBeg = -1; - for( int x = 0; x < baseW; x++ ) { - Color color = getColor( this.jtcSys.getPixelColorNum( x, y ) ); - if( (color != null) && (color != lastColor) ) { - if( (lastColor != null) - && (lastColor != bgColor) - && (xColorBeg >= 0) ) - { - g.setColor( lastColor ); - g.fillRect( - xColorBeg * this.scale, - y * this.scale, - (x - xColorBeg) * this.scale, - this.scale ); - } - xColorBeg = x; - lastColor = color; - } - } - if( (lastColor != null) - && (lastColor != bgColor) - && (xColorBeg >= 0) ) - { - g.setColor( lastColor ); - g.fillRect( - xColorBeg * this.scale, - y * this.scale, - (baseW - xColorBeg) * this.scale, - this.scale ); - } - } - - // Markierter Text - if( withMarking ) { - if( (xOffs > 0) && (yOffs > 0) ) { - g.translate( -xOffs, -yOffs ); - } - boolean textSelected = false; - CharRaster charRaster = this.charRaster; - Point dragStart = this.dragStart; - Point dragEnd = this.dragEnd; - int scale = this.scale; - if( (charRaster != null) - && (dragStart != null) - && (dragEnd != null) - && (scale > 0) ) - { - int nCols = charRaster.getColCount(); - int nRows = charRaster.getRowCount(); - int wChar = charRaster.getCharWidth(); - int hChar = charRaster.getCharHeight(); - if( (nCols > 0) && (nRows > 0) - && (wChar > 0) && (hChar > 0) ) - { - int x1 = dragStart.x; - int y1 = dragStart.y; - int x2 = dragEnd.x; - int y2 = dragEnd.y; - xOffs += (charRaster.getXOffset() * scale); - yOffs += (charRaster.getYOffset() * scale); - - // Zeichenpositionen berechnen - this.selectionCharX1 = Math.max( - (x1 - xOffs) / scale, 0 ) / wChar; - this.selectionCharY1 = Math.max( - (y1 - yOffs) / scale, 0 ) / hChar; - this.selectionCharX2 = Math.max( - (x2 - xOffs) / scale, 0 ) / wChar; - this.selectionCharY2 = Math.max( - (y2 - yOffs) / scale , 0 ) / hChar; - if( this.selectionCharX1 >= nCols ) { - this.selectionCharX1 = nCols - 1; - } - if( this.selectionCharY1 >= nRows ) { - this.selectionCharY1 = nRows - 1; - } - if( this.selectionCharX2 >= nCols ) { - this.selectionCharX2 = nCols - 1; - } - if( this.selectionCharY2 >= nRows ) { - this.selectionCharY2 = nRows - 1; - } - - // Koordinaten tauschen, wenn Endpunkt vor Startpunkt liegt - if( (this.selectionCharY1 > this.selectionCharY2) - || ((this.selectionCharY1 == this.selectionCharY2) - && (this.selectionCharX1 > this.selectionCharX2)) ) - { - int m = this.selectionCharX1; - this.selectionCharX1 = this.selectionCharX2; - this.selectionCharX2 = m; - - m = this.selectionCharY1; - this.selectionCharY1 = this.selectionCharY2; - this.selectionCharY2 = m; - - m = x1; - x1 = x2; - x2 = m; - - m = y1; - y1 = y2; - y2 = m; - } - - /* - * Koordinaten anpassen, - * wenn Endpunkt ausserhalb der Bildschirmausgabe liegt - */ - if( y1 < yOffs ) { - this.selectionCharX1 = 0; - this.selectionCharY1 = 0; - } else { - if( x1 > (xOffs + (scale * nCols * wChar)) ) { - this.selectionCharX1 = 0; - this.selectionCharY1++; - } - } - if( y2 > (yOffs + (scale * (nRows * hChar))) ) { - this.selectionCharX2 = nCols - 1; - this.selectionCharY2 = nRows - 1; - } else { - if( x2 < xOffs ) { - this.selectionCharX2 = nCols - 1; - --this.selectionCharY2; - } - } - - // Markierter Text visualisieren - g.setColor( Color.WHITE ); - g.setXORMode( this.markXORColor ); - if( this.selectionCharY1 == this.selectionCharY2 ) { - g.fillRect( - xOffs + (scale * this.selectionCharX1 * wChar), - yOffs + (scale * this.selectionCharY1 * hChar), - scale * (this.selectionCharX2 - - this.selectionCharX1 + 1) * wChar, - scale * hChar ); - } else { - g.fillRect( - xOffs + (scale * this.selectionCharX1 * wChar), - yOffs + (scale * this.selectionCharY1 * hChar), - scale * (nCols - this.selectionCharX1) * wChar, - scale * hChar ); - if( this.selectionCharY1 + 1 < this.selectionCharY2 ) { - g.fillRect( - xOffs, - yOffs + (scale * (this.selectionCharY1 + 1) * hChar), - scale * nCols * wChar, - scale * (this.selectionCharY2 - - this.selectionCharY1 - 1) * hChar ); - } - g.fillRect( - xOffs, - yOffs + (scale * this.selectionCharY2 * hChar), - scale * (this.selectionCharX2 + 1) * wChar, - scale * hChar ); - } - textSelected = true; - } - } - if( textSelected != this.textSelected ) { - this.textSelected = textSelected; - this.topFrm.setScreenTextSelected( textSelected ); - } - } - } + + + /* --- MouseMotionListener --- */ + + @Override + public void mouseDragged(MouseEvent e) { + if (e.getComponent() == this) { + if (this.dragStart == null) { + this.charRaster = this.jtcSys.getScreenCharRaster(); + if (this.charRaster != null) { + this.dragStart = new Point(e.getX(), e.getY()); + this.dragEnd = null; + setScreenDirty(); + } + } else { + if (this.charRaster != null) { + this.dragEnd = new Point(e.getX(), e.getY()); + } else { + this.dragEnd = null; + this.dragStart = null; + } + setScreenDirty(); + } + e.consume(); + } + } + + + @Override + public void mouseMoved(MouseEvent e) { + // leer + } + + + /* --- ueberschriebene Methoden --- */ + + @Override + public boolean isFocusable() { + return true; + } + + + @Override + public void paint(Graphics g) { + this.dirty = false; + paint(g, getWidth(), getHeight(), true); + } + + + /* + * update(...) wird ueberschrieben, + * da paint(...) die Komponente vollstaendig fuellt + * und somit das standardmaessige Fuellen mit der Hintegrundfarbe + * entfallen kann. + */ + @Override + public void update(Graphics g) { + paint(g); + } + + + /* --- private Methoden --- */ + + private Color getColor(int colorNum) { + Color color = Color.BLACK; + if (this.jtcSys.isMonochrome()) { + if (colorNum > 0) { + color = Color.WHITE; + } + } else { + if ((colorNum >= 0) && (colorNum < this.colors.length)) { + color = this.colors[colorNum]; + } + } + return color; + } + + + private void paint(Graphics g, int w, int h, boolean withMarking) { + if ((w > 0) && (h > 0)) { + + // Hintergrund + Color bgColor = Color.BLACK; + g.setColor(bgColor); + g.fillRect(0, 0, w, h); + + // Vordergrund + int baseW = this.jtcScreenW; + int baseH = this.jtcScreenH; + if ((baseW > 0) && (baseH > 0) + && this.jtcSys.isScreenOutputEnabled()) { + // zentrieren + int xOffs = (w - (baseW * this.scale)) / 2; + if (xOffs < 0) { + xOffs = 0; + } + int yOffs = (h - (baseH * this.scale)) / 2; + if (yOffs < 0) { + yOffs = 0; + } + if ((xOffs > 0) || (yOffs > 0)) { + g.translate(xOffs, yOffs); + } + + /* + * Aus Gruenden der Performance werden nebeneinander liegende + * Punkte zusammengefasst und als Linie gezeichnet. + */ + for (int y = 0; y < baseH; y++) { + Color lastColor = null; + int xColorBeg = -1; + for (int x = 0; x < baseW; x++) { + Color color = getColor(this.jtcSys.getPixelColorNum(x, y)); + if ((color != null) && (color != lastColor)) { + if ((lastColor != null) + && (lastColor != bgColor) + && (xColorBeg >= 0)) { + g.setColor(lastColor); + g.fillRect( + xColorBeg * this.scale, + y * this.scale, + (x - xColorBeg) * this.scale, + this.scale); + } + xColorBeg = x; + lastColor = color; + } + } + if ((lastColor != null) + && (lastColor != bgColor) + && (xColorBeg >= 0)) { + g.setColor(lastColor); + g.fillRect( + xColorBeg * this.scale, + y * this.scale, + (baseW - xColorBeg) * this.scale, + this.scale); + } + } + + // Markierter Text + if (withMarking) { + if ((xOffs > 0) && (yOffs > 0)) { + g.translate(-xOffs, -yOffs); + } + boolean textSelected = false; + CharRaster charRaster = this.charRaster; + Point dragStart = this.dragStart; + Point dragEnd = this.dragEnd; + int scale = this.scale; + if ((charRaster != null) + && (dragStart != null) + && (dragEnd != null) + && (scale > 0)) { + int nCols = charRaster.getColCount(); + int nRows = charRaster.getRowCount(); + int wChar = charRaster.getCharWidth(); + int hChar = charRaster.getCharHeight(); + if ((nCols > 0) && (nRows > 0) + && (wChar > 0) && (hChar > 0)) { + int x1 = dragStart.x; + int y1 = dragStart.y; + int x2 = dragEnd.x; + int y2 = dragEnd.y; + xOffs += (charRaster.getXOffset() * scale); + yOffs += (charRaster.getYOffset() * scale); + + // Zeichenpositionen berechnen + this.selectionCharX1 = Math.max( + (x1 - xOffs) / scale, 0) / wChar; + this.selectionCharY1 = Math.max( + (y1 - yOffs) / scale, 0) / hChar; + this.selectionCharX2 = Math.max( + (x2 - xOffs) / scale, 0) / wChar; + this.selectionCharY2 = Math.max( + (y2 - yOffs) / scale, 0) / hChar; + if (this.selectionCharX1 >= nCols) { + this.selectionCharX1 = nCols - 1; + } + if (this.selectionCharY1 >= nRows) { + this.selectionCharY1 = nRows - 1; + } + if (this.selectionCharX2 >= nCols) { + this.selectionCharX2 = nCols - 1; + } + if (this.selectionCharY2 >= nRows) { + this.selectionCharY2 = nRows - 1; + } + + // Koordinaten tauschen, wenn Endpunkt vor Startpunkt liegt + if ((this.selectionCharY1 > this.selectionCharY2) + || ((this.selectionCharY1 == this.selectionCharY2) + && (this.selectionCharX1 > this.selectionCharX2))) { + int m = this.selectionCharX1; + this.selectionCharX1 = this.selectionCharX2; + this.selectionCharX2 = m; + + m = this.selectionCharY1; + this.selectionCharY1 = this.selectionCharY2; + this.selectionCharY2 = m; + + m = x1; + x1 = x2; + x2 = m; + + m = y1; + y1 = y2; + y2 = m; + } + + /* + * Koordinaten anpassen, + * wenn Endpunkt ausserhalb der Bildschirmausgabe liegt + */ + if (y1 < yOffs) { + this.selectionCharX1 = 0; + this.selectionCharY1 = 0; + } else { + if (x1 > (xOffs + (scale * nCols * wChar))) { + this.selectionCharX1 = 0; + this.selectionCharY1++; + } + } + if (y2 > (yOffs + (scale * (nRows * hChar)))) { + this.selectionCharX2 = nCols - 1; + this.selectionCharY2 = nRows - 1; + } else { + if (x2 < xOffs) { + this.selectionCharX2 = nCols - 1; + --this.selectionCharY2; + } + } + + // Markierter Text visualisieren + g.setColor(Color.WHITE); + g.setXORMode(this.markXORColor); + if (this.selectionCharY1 == this.selectionCharY2) { + g.fillRect( + xOffs + (scale * this.selectionCharX1 * wChar), + yOffs + (scale * this.selectionCharY1 * hChar), + scale * (this.selectionCharX2 + - this.selectionCharX1 + 1) * wChar, + scale * hChar); + } else { + g.fillRect( + xOffs + (scale * this.selectionCharX1 * wChar), + yOffs + (scale * this.selectionCharY1 * hChar), + scale * (nCols - this.selectionCharX1) * wChar, + scale * hChar); + if (this.selectionCharY1 + 1 < this.selectionCharY2) { + g.fillRect( + xOffs, + yOffs + (scale * (this.selectionCharY1 + 1) * hChar), + scale * nCols * wChar, + scale * (this.selectionCharY2 + - this.selectionCharY1 - 1) * hChar); + } + g.fillRect( + xOffs, + yOffs + (scale * this.selectionCharY2 * hChar), + scale * (this.selectionCharX2 + 1) * wChar, + scale * hChar); + } + textSelected = true; + } + } + if (textSelected != this.textSelected) { + this.textSelected = textSelected; + this.topFrm.setScreenTextSelected(textSelected); + } + } + } + } } - } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/TopFrm.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/TopFrm.java index fb6a796..6e5b7a3 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/TopFrm.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/base/TopFrm.java @@ -39,1390 +39,1290 @@ public class TopFrm extends BaseFrm - implements - ActionListener, - DropTargetListener, - ErrorViewer, - FlavorListener, - KeyListener, - PasteObserver, - Z8Listener -{ - public static final int DEFAULT_SCREEN_MARGIN = 20; - public static final int DEFAULT_SCREEN_REFRESH_MS = 50; - public static final int DEFAULT_SCREEN_SCALE = 3; - - public static final String PROP_SCREEN_MARGIN = "screen.margin"; - public static final String PROP_SCREEN_REFRESH_MS = "screen.refresh.ms"; - public static final String PROP_SCREEN_SCALE = "screen.scale"; - - private static final String ACTION_ABOUT = "about"; - private static final String ACTION_AUDIO = "audio"; - private static final String ACTION_COPY = "copy"; - private static final String ACTION_DEBUG = "debug"; - private static final String ACTION_HELP = "help"; - private static final String ACTION_HEXEDIT = "hexedit"; - private static final String ACTION_KEYBOARD = "keyboard"; - private static final String ACTION_LOAD = "load"; - private static final String ACTION_LOAD_OPT = "load_opt"; - private static final String ACTION_LICENSE = "license"; - private static final String ACTION_MEMEDIT = "memedit"; - private static final String ACTION_PASTE = "paste"; - private static final String ACTION_PASTE_CANCEL = "paste.cancel"; - private static final String ACTION_PAUSE = "pause"; - private static final String ACTION_POWER_ON = "power_on"; - private static final String ACTION_QUIT = "quit"; - private static final String ACTION_REASS = "reass"; - private static final String ACTION_RESET = "reset"; - private static final String ACTION_SAVE = "save"; - private static final String ACTION_SCALE_PREFIX = "scale."; - private static final String ACTION_SCR_IMG_COPY = "screen.img.copy"; - private static final String ACTION_SCR_IMG_SAVE_AS = "screen.img.save"; - private static final String ACTION_SCR_TEXT_COPY = "screen.text.copy"; - private static final String ACTION_SETTINGS = "settings"; - private static final String ACTION_SPEED = "speed"; - private static final String ACTION_TEXTEDIT = "textedit"; - private static final String ACTION_THANKS = "thanks"; - private static final String FILE_GROUP_IMAGE = "image"; - - private static final String DEFAULT_STATUS_TEXT = "Emulator l\u00E4uft..."; - - private static final String TEXT_MAX_SPEED = "Maximale Geschwindigkeit"; - private static final String TEXT_NORM_SPEED = "Normale Geschwindigkeit"; - private static final String TEXT_PAUSE = "Pause"; - private static final String TEXT_GO_ON = "Fortsetzen"; - - private static final int STATUS_REFRESH_MILLIS = 750; - private static final int STATUS_SHOW_MSG_MILLIS = 5000; - - private JTCSys jtcSys; - private Z8 z8; - private Map scale2MenuItems; - private Map jtcScreenSize2Scale; - private Dimension jtcScreenSize; - private Thread emuThread; - private Clipboard clipboard; - private boolean screenOutputEnabled; - private ScreenFld screenFld; - private javax.swing.Timer screenRefreshTimer; - private javax.swing.Timer statusRefreshTimer; - private int mnuShortcutKeyMask; - private JMenuItem mnuCopy; - private JMenuItem mnuPaste; - private JMenuItem mnuPasteCancel; - private JMenuItem mnuPause; - private JMenuItem mnuSpeed; - private JLabel fldStatusText; - - - public TopFrm( JTCSys jtcSys ) - { - setTitle( "JU+TE-Computer" ); - this.jtcSys = jtcSys; - this.z8 = jtcSys.getZ8(); - this.clipboard = getToolkit().getSystemClipboard(); - this.screenOutputEnabled = false; - this.scale2MenuItems = new HashMap(); - this.jtcScreenSize2Scale = new HashMap(); - this.jtcScreenSize2Scale.put( - new Dimension( 64, 64 ), - DEFAULT_SCREEN_SCALE ); - this.jtcScreenSize2Scale.put( new Dimension( 128, 128 ), 2 ); - this.jtcScreenSize2Scale.put( new Dimension( 320, 192 ), 1 ); - - - /* - * Die Shortcut-Taste soll nicht die Control-Taste sein. - * Aus diesem Grund wird geprueft, - * ob die uebliche Shortcut-Taste die Control-Taste ist. - * Wenn nein, wird diese verwendet (ist beim Mac so), - * anderenfalls die ALT-Taste. - */ - this.mnuShortcutKeyMask = 0; - Toolkit tk = getToolkit(); - try { - // Seit Java 10 gibt es die Methode Toolkit.getMenuShortcutKeyMaskEx() - Object v = tk.getClass().getMethod( "getMenuShortcutKeyMaskEx" ) - .invoke( tk ); - if( v != null ) { - if( v instanceof Number ) { - this.mnuShortcutKeyMask = ((Number) v).intValue(); - if( this.mnuShortcutKeyMask == InputEvent.CTRL_DOWN_MASK ) { - this.mnuShortcutKeyMask = InputEvent.ALT_DOWN_MASK; - } - } - } + implements + ActionListener, + DropTargetListener, + ErrorViewer, + FlavorListener, + KeyListener, + PasteObserver, + Z8Listener { + public static final int DEFAULT_SCREEN_MARGIN = 20; + public static final int DEFAULT_SCREEN_REFRESH_MS = 50; + public static final int DEFAULT_SCREEN_SCALE = 3; + + public static final String PROP_SCREEN_MARGIN = "screen.margin"; + public static final String PROP_SCREEN_REFRESH_MS = "screen.refresh.ms"; + public static final String PROP_SCREEN_SCALE = "screen.scale"; + + private static final String ACTION_ABOUT = "about"; + private static final String ACTION_AUDIO = "audio"; + private static final String ACTION_COPY = "copy"; + private static final String ACTION_DEBUG = "debug"; + private static final String ACTION_HELP = "help"; + private static final String ACTION_HEXEDIT = "hexedit"; + private static final String ACTION_KEYBOARD = "keyboard"; + private static final String ACTION_LOAD = "load"; + private static final String ACTION_LOAD_OPT = "load_opt"; + private static final String ACTION_LICENSE = "license"; + private static final String ACTION_MEMEDIT = "memedit"; + private static final String ACTION_PASTE = "paste"; + private static final String ACTION_PASTE_CANCEL = "paste.cancel"; + private static final String ACTION_PAUSE = "pause"; + private static final String ACTION_POWER_ON = "power_on"; + private static final String ACTION_QUIT = "quit"; + private static final String ACTION_REASS = "reass"; + private static final String ACTION_RESET = "reset"; + private static final String ACTION_SAVE = "save"; + private static final String ACTION_SCALE_PREFIX = "scale."; + private static final String ACTION_SCR_IMG_COPY = "screen.img.copy"; + private static final String ACTION_SCR_IMG_SAVE_AS = "screen.img.save"; + private static final String ACTION_SCR_TEXT_COPY = "screen.text.copy"; + private static final String ACTION_SETTINGS = "settings"; + private static final String ACTION_SPEED = "speed"; + private static final String ACTION_TEXTEDIT = "textedit"; + private static final String ACTION_THANKS = "thanks"; + private static final String FILE_GROUP_IMAGE = "image"; + + private static final String DEFAULT_STATUS_TEXT = "Emulator l\u00E4uft..."; + + private static final String TEXT_MAX_SPEED = "Maximale Geschwindigkeit"; + private static final String TEXT_NORM_SPEED = "Normale Geschwindigkeit"; + private static final String TEXT_PAUSE = "Pause"; + private static final String TEXT_GO_ON = "Fortsetzen"; + + private static final int STATUS_REFRESH_MILLIS = 750; + private static final int STATUS_SHOW_MSG_MILLIS = 5000; + + private JTCSys jtcSys; + private Z8 z8; + private Map scale2MenuItems; + private Map jtcScreenSize2Scale; + private Dimension jtcScreenSize; + private Thread emuThread; + private Clipboard clipboard; + private boolean screenOutputEnabled; + private ScreenFld screenFld; + private javax.swing.Timer screenRefreshTimer; + private javax.swing.Timer statusRefreshTimer; + private int mnuShortcutKeyMask; + private JMenuItem mnuCopy; + private JMenuItem mnuPaste; + private JMenuItem mnuPasteCancel; + private JMenuItem mnuPause; + private JMenuItem mnuSpeed; + private JLabel fldStatusText; + + + public TopFrm(JTCSys jtcSys) { + setTitle("JU+TE-Computer"); + this.jtcSys = jtcSys; + this.z8 = jtcSys.getZ8(); + this.clipboard = getToolkit().getSystemClipboard(); + this.screenOutputEnabled = false; + this.scale2MenuItems = new HashMap(); + this.jtcScreenSize2Scale = new HashMap(); + this.jtcScreenSize2Scale.put( + new Dimension(64, 64), + DEFAULT_SCREEN_SCALE); + this.jtcScreenSize2Scale.put(new Dimension(128, 128), 2); + this.jtcScreenSize2Scale.put(new Dimension(320, 192), 1); + + + /* + * Die Shortcut-Taste soll nicht die Control-Taste sein. + * Aus diesem Grund wird geprueft, + * ob die uebliche Shortcut-Taste die Control-Taste ist. + * Wenn nein, wird diese verwendet (ist beim Mac so), + * anderenfalls die ALT-Taste. + */ + this.mnuShortcutKeyMask = 0; + Toolkit tk = getToolkit(); + try { + // Seit Java 10 gibt es die Methode Toolkit.getMenuShortcutKeyMaskEx() + Object v = tk.getClass().getMethod("getMenuShortcutKeyMaskEx") + .invoke(tk); + if (v != null) { + if (v instanceof Number) { + this.mnuShortcutKeyMask = ((Number) v).intValue(); + if (this.mnuShortcutKeyMask == InputEvent.CTRL_DOWN_MASK) { + this.mnuShortcutKeyMask = InputEvent.ALT_DOWN_MASK; + } + } + } + } catch (Exception ex) { + } + if (this.mnuShortcutKeyMask == 0) { + /* + * Vor Java 10 gibt es die Methode Toolkit.getMenuShortcutKeyMask(), + * die noch eine alte Control-Maske liefert + * (Event.CTRL_MASK bzw. InputEvent.CTRL_MASK). + * Da aber die Felder der alten Codes mit Java 9 deprecated sind, + * werden diese hier per Reflection ausgelesen und es wird auch + * auf InputEvent.CTRL_DOWN_MASK geprueft. + */ + int ctrlMask = InputEvent.CTRL_DOWN_MASK; + try { + ctrlMask |= getClass().forName("java.awt.Event") + .getDeclaredField("CTRL_MASK") + .getInt(null); + } catch (Exception ex) { + } + try { + ctrlMask |= InputEvent.class.getDeclaredField("CTRL_MASK") + .getInt(null); + } catch (Exception ex) { + } + try { + Object v = tk.getClass().getMethod("getMenuShortcutKeyMask") + .invoke(tk); + if (v != null) { + if (v instanceof Number) { + this.mnuShortcutKeyMask = ((Number) v).intValue(); + if ((this.mnuShortcutKeyMask & ctrlMask) != 0) { + this.mnuShortcutKeyMask = InputEvent.ALT_DOWN_MASK; + } + } + } + } catch (Exception ex) { + } + } + if (this.mnuShortcutKeyMask == 0) { + this.mnuShortcutKeyMask = InputEvent.ALT_DOWN_MASK; + } + + // Menu + JMenuBar mnuBar = new JMenuBar(); + setJMenuBar(mnuBar); + + + // Menu Datei + JMenu mnuFile = new JMenu("Datei"); + mnuFile.setMnemonic(KeyEvent.VK_D); + mnuBar.add(mnuFile); + mnuFile.add( + createJMenuItem("Laden...", KeyEvent.VK_L, ACTION_LOAD)); + mnuFile.add( + createJMenuItem("Laden mit Optionen...", ACTION_LOAD_OPT)); + mnuFile.add( + createJMenuItem("Speichern...", KeyEvent.VK_S, ACTION_SAVE)); + mnuFile.addSeparator(); + mnuFile.add( + createJMenuItem("Texteditor...", KeyEvent.VK_T, ACTION_TEXTEDIT)); + mnuFile.addSeparator(); + mnuFile.add(createQuitMenuItem()); + + + // Menu Bearbeiten + JMenu mnuEdit = new JMenu("Bearbeiten"); + mnuEdit.setMnemonic(KeyEvent.VK_B); + mnuBar.add(mnuEdit); + + this.mnuCopy = createJMenuItem( + "Kopieren", + KeyEvent.VK_C, + ACTION_COPY); + this.mnuCopy.setEnabled(false); + mnuEdit.add(this.mnuCopy); + + this.mnuPaste = createJMenuItem( + "Einf\u00FCgen", + KeyEvent.VK_V, + ACTION_PASTE); + mnuEdit.add(this.mnuPaste); + mnuEdit.addSeparator(); + + this.mnuPasteCancel = createJMenuItem( + "Einf\u00FCgen abbrechen", + ACTION_PASTE_CANCEL); + this.mnuPasteCancel.setEnabled(false); + mnuEdit.add(this.mnuPasteCancel); + + + // Menu Extra + JMenu mnuExtra = new JMenu("Extra"); + mnuExtra.setMnemonic(KeyEvent.VK_E); + mnuBar.add(mnuExtra); + + JMenu mnuScreenScale = new JMenu("Ansicht"); + mnuExtra.add(mnuScreenScale); + + int screenScale = AppContext.getIntProperty( + PROP_SCREEN_SCALE, + DEFAULT_SCREEN_SCALE); + ButtonGroup grpScale = new ButtonGroup(); + for (int v = 1; v <= 9; v++) { + String text = Integer.toString(v); + JRadioButtonMenuItem item = new JRadioButtonMenuItem( + text + "00 %", + v == screenScale); + item.setActionCommand(ACTION_SCALE_PREFIX + text); + item.setAccelerator(KeyStroke.getKeyStroke( + (char) ('0' + v), + this.mnuShortcutKeyMask)); + item.addActionListener(this); + grpScale.add(item); + mnuScreenScale.add(item); + this.scale2MenuItems.put(v, item); + } + + JMenu mnuScreenImg = new JMenu("Bildschirmausgabe"); + mnuExtra.add(mnuScreenImg); + mnuExtra.addSeparator(); + + mnuScreenImg.add(createJMenuItem( + "als Text kopieren", + ACTION_SCR_TEXT_COPY)); + mnuScreenImg.add(createJMenuItem( + "als Bild kopieren", + ACTION_SCR_IMG_COPY)); + mnuScreenImg.add(createJMenuItem( + "als Bild speichern unter...", + ACTION_SCR_IMG_SAVE_AS)); + + mnuExtra.add(createJMenuItem( + "Debugger...", + KeyEvent.VK_D, + true, + ACTION_DEBUG)); + mnuExtra.add(createJMenuItem( + "Reassembler...", + KeyEvent.VK_R, + true, + ACTION_REASS)); + mnuExtra.add(createJMenuItem( + "Speichereditor...", + KeyEvent.VK_M, + true, + ACTION_MEMEDIT)); + mnuExtra.add(createJMenuItem( + "Hex-Editor...", + KeyEvent.VK_H, + true, + ACTION_HEXEDIT)); + mnuExtra.addSeparator(); + mnuExtra.add(createJMenuItem( + "Audio/Kassette...", + KeyEvent.VK_A, + ACTION_AUDIO)); + mnuExtra.add(createJMenuItem( + "Tastatur...", + KeyEvent.VK_K, + ACTION_KEYBOARD)); + mnuExtra.add(createJMenuItem( + "Einstellungen...", + ACTION_SETTINGS)); + mnuExtra.addSeparator(); + + this.mnuSpeed = createJMenuItem( + TEXT_MAX_SPEED, + KeyEvent.VK_G, + ACTION_SPEED); + mnuExtra.add(this.mnuSpeed); + + this.mnuPause = createJMenuItem( + TEXT_PAUSE, + KeyEvent.VK_P, + ACTION_PAUSE); + mnuExtra.add(this.mnuPause); + mnuExtra.addSeparator(); + mnuExtra.add(createJMenuItem( + "Zur\u00FCcksetzen (RESET)", + KeyEvent.VK_R, + ACTION_RESET)); + mnuExtra.add(createJMenuItem( + "Einschalten (Speicher l\u00F6schen)", + KeyEvent.VK_I, + ACTION_POWER_ON)); + + + // Menu Hilfe + JMenu mnuHelp = new JMenu("Hilfe"); + mnuHelp.setMnemonic(KeyEvent.VK_H); + mnuHelp.add(createJMenuItem( + AppContext.getAppName() + "-Hilfe...", + ACTION_HELP)); + mnuHelp.addSeparator(); + mnuHelp.add(createAboutMenuItem()); + mnuHelp.add( + createJMenuItem("Lizenzbestimmungen...", ACTION_LICENSE)); + mnuHelp.add(createJMenuItem("Danksagung...", ACTION_THANKS)); + mnuBar.add(mnuHelp); + + + // Fensterinhalt + setLayout(new BorderLayout()); + + + // Werkzeugleiste + JPanel panelToolBar = new JPanel( + new FlowLayout(FlowLayout.LEFT, 0, 0)); + add(panelToolBar, BorderLayout.NORTH); + + JToolBar toolBar = new JToolBar(); + toolBar.setFloatable(false); + toolBar.setBorderPainted(false); + toolBar.setOrientation(JToolBar.HORIZONTAL); + toolBar.setRollover(true); + panelToolBar.add(toolBar); + + toolBar.add(GUIUtil.createImageButton( + this, + "/images/file/open.png", + "Laden", + ACTION_LOAD)); + + toolBar.add(GUIUtil.createImageButton( + this, + "/images/file/save.png", + "Speichern", + ACTION_SAVE)); + toolBar.addSeparator(); + + toolBar.add(GUIUtil.createImageButton( + this, + "/images/file/edit.png", + "Texteditor", + ACTION_TEXTEDIT)); + toolBar.add(GUIUtil.createImageButton( + this, + "/images/file/audio.png", + "Audio/Kassette", + ACTION_AUDIO)); + toolBar.add(GUIUtil.createImageButton( + this, + "/images/edit/settings.png", + "Einstellungen", + ACTION_SETTINGS)); + + toolBar.addSeparator(); + + toolBar.add(GUIUtil.createImageButton( + this, + "/images/file/reset.png", + "Zur\u00FCcksetzen (RESET)", + ACTION_RESET)); + + + // Bildschirmausgabe + this.screenFld = new ScreenFld(this, this.jtcSys, screenScale); + this.screenFld.addKeyListener(this); + add(this.screenFld, BorderLayout.CENTER); + + this.jtcScreenSize = getJTCScreenSize(); + this.jtcScreenSize2Scale.put(this.jtcScreenSize, screenScale); + + + // Statuszeile + JPanel panelStatusBar = new JPanel( + new FlowLayout(FlowLayout.LEFT, 5, 5)); + add(panelStatusBar, BorderLayout.SOUTH); + + this.fldStatusText = new JLabel(DEFAULT_STATUS_TEXT); + panelStatusBar.add(this.fldStatusText); + + + // Timer zum zyklischen Aktualisieren der Bildschirmausgabe + this.screenRefreshTimer = new javax.swing.Timer( + getSettingsScreenRefreshMillis(), + this); + this.screenRefreshTimer.start(); + + + // Timer zum Aktualisieren der Statuszeile + this.statusRefreshTimer = new javax.swing.Timer( + STATUS_REFRESH_MILLIS, + this); + + + // Fenstergroesse und -position + updScreenSize(false); + setResizable(true); + if (!GUIUtil.applyWindowSettings(this)) { + pack(); + setLocationByPlatform(true); + } + + + // Clipboard ueberwachen + if (this.clipboard != null) { + this.clipboard.addFlavorListener(this); + clipboardContentChanged(); + } + + + // Drop-Ziel + (new DropTarget(this.screenFld, this)).setActive(true); + + + // Emulation starten + this.z8.setStatusListener(this); + this.emuThread = new Thread(this.z8, "Z8 emulation"); + this.emuThread.start(); + this.jtcSys.setResetListener(this); } - catch( Exception ex ) {} - if( this.mnuShortcutKeyMask == 0 ) { - /* - * Vor Java 10 gibt es die Methode Toolkit.getMenuShortcutKeyMask(), - * die noch eine alte Control-Maske liefert - * (Event.CTRL_MASK bzw. InputEvent.CTRL_MASK). - * Da aber die Felder der alten Codes mit Java 9 deprecated sind, - * werden diese hier per Reflection ausgelesen und es wird auch - * auf InputEvent.CTRL_DOWN_MASK geprueft. - */ - int ctrlMask = InputEvent.CTRL_DOWN_MASK; - try { - ctrlMask |= getClass().forName( "java.awt.Event" ) - .getDeclaredField( "CTRL_MASK" ) - .getInt( null ); - } - catch( Exception ex ) {} - try { - ctrlMask |= InputEvent.class.getDeclaredField( "CTRL_MASK" ) - .getInt( null ); - } - catch( Exception ex ) {} - try { - Object v = tk.getClass().getMethod( "getMenuShortcutKeyMask" ) - .invoke( tk ); - if( v != null ) { - if( v instanceof Number ) { - this.mnuShortcutKeyMask = ((Number) v).intValue(); - if( (this.mnuShortcutKeyMask & ctrlMask) != 0 ) { - this.mnuShortcutKeyMask = InputEvent.ALT_DOWN_MASK; - } - } - } - } - catch( Exception ex ) {} + + + public JMenuItem createAboutMenuItem() { + return createJMenuItem( + "\u00DCber " + AppContext.getAppName() + "...", + ACTION_ABOUT); } - if( this.mnuShortcutKeyMask == 0 ) { - this.mnuShortcutKeyMask = InputEvent.ALT_DOWN_MASK; + + + public JMenuItem createQuitMenuItem() { + return createJMenuItem("Beenden", ACTION_QUIT); } - // Menu - JMenuBar mnuBar = new JMenuBar(); - setJMenuBar( mnuBar ); - - - // Menu Datei - JMenu mnuFile = new JMenu( "Datei" ); - mnuFile.setMnemonic( KeyEvent.VK_D ); - mnuBar.add( mnuFile ); - mnuFile.add( - createJMenuItem( "Laden...", KeyEvent.VK_L, ACTION_LOAD ) ); - mnuFile.add( - createJMenuItem( "Laden mit Optionen...", ACTION_LOAD_OPT ) ); - mnuFile.add( - createJMenuItem( "Speichern...", KeyEvent.VK_S, ACTION_SAVE ) ); - mnuFile.addSeparator(); - mnuFile.add( - createJMenuItem( "Texteditor...", KeyEvent.VK_T, ACTION_TEXTEDIT ) ); - mnuFile.addSeparator(); - mnuFile.add( createQuitMenuItem() ); - - - // Menu Bearbeiten - JMenu mnuEdit = new JMenu( "Bearbeiten" ); - mnuEdit.setMnemonic( KeyEvent.VK_B ); - mnuBar.add( mnuEdit ); - - this.mnuCopy = createJMenuItem( - "Kopieren", - KeyEvent.VK_C, - ACTION_COPY ); - this.mnuCopy.setEnabled( false ); - mnuEdit.add( this.mnuCopy ); - - this.mnuPaste = createJMenuItem( - "Einf\u00FCgen", - KeyEvent.VK_V, - ACTION_PASTE ); - mnuEdit.add( this.mnuPaste ); - mnuEdit.addSeparator(); - - this.mnuPasteCancel = createJMenuItem( - "Einf\u00FCgen abbrechen", - ACTION_PASTE_CANCEL ); - this.mnuPasteCancel.setEnabled( false ); - mnuEdit.add( this.mnuPasteCancel ); - - - // Menu Extra - JMenu mnuExtra = new JMenu( "Extra" ); - mnuExtra.setMnemonic( KeyEvent.VK_E ); - mnuBar.add( mnuExtra ); - - JMenu mnuScreenScale = new JMenu( "Ansicht" ); - mnuExtra.add( mnuScreenScale ); - - int screenScale = AppContext.getIntProperty( - PROP_SCREEN_SCALE, - DEFAULT_SCREEN_SCALE ); - ButtonGroup grpScale = new ButtonGroup(); - for( int v = 1; v <= 9; v++ ) { - String text = Integer.toString( v ); - JRadioButtonMenuItem item = new JRadioButtonMenuItem( - text + "00 %", - v == screenScale ); - item.setActionCommand( ACTION_SCALE_PREFIX + text ); - item.setAccelerator( KeyStroke.getKeyStroke( - (char) ('0' + v), - this.mnuShortcutKeyMask ) ); - item.addActionListener( this ); - grpScale.add( item ); - mnuScreenScale.add( item ); - this.scale2MenuItems.put( v, item ); + + public void doPowerOn() { + boolean state = true; + if (AppContext.getBooleanProperty( + JTCUtil.PROP_CONFIRM_POWER_ON, + true)) { + if (JOptionPane.showConfirmDialog( + this, + "M\u00F6chten Sie das Aus- und wieder Einschalten" + + " emulieren\n" + + "und den Emulator initialisieren?\n" + + "Dabei wird der Arbeitsspeicher gel\u00F6scht.", + "Best\u00E4tigung", + JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { + state = false; + } + } + if (state) { + resetEmu(true); + } } - JMenu mnuScreenImg = new JMenu( "Bildschirmausgabe" ); - mnuExtra.add( mnuScreenImg ); - mnuExtra.addSeparator(); - - mnuScreenImg.add( createJMenuItem( - "als Text kopieren", - ACTION_SCR_TEXT_COPY ) ); - mnuScreenImg.add( createJMenuItem( - "als Bild kopieren", - ACTION_SCR_IMG_COPY ) ); - mnuScreenImg.add( createJMenuItem( - "als Bild speichern unter...", - ACTION_SCR_IMG_SAVE_AS ) ); - - mnuExtra.add( createJMenuItem( - "Debugger...", - KeyEvent.VK_D, - true, - ACTION_DEBUG ) ); - mnuExtra.add( createJMenuItem( - "Reassembler...", - KeyEvent.VK_R, - true, - ACTION_REASS ) ); - mnuExtra.add( createJMenuItem( - "Speichereditor...", - KeyEvent.VK_M, - true, - ACTION_MEMEDIT ) ); - mnuExtra.add( createJMenuItem( - "Hex-Editor...", - KeyEvent.VK_H, - true, - ACTION_HEXEDIT ) ); - mnuExtra.addSeparator(); - mnuExtra.add( createJMenuItem( - "Audio/Kassette...", - KeyEvent.VK_A, - ACTION_AUDIO ) ); - mnuExtra.add( createJMenuItem( - "Tastatur...", - KeyEvent.VK_K, - ACTION_KEYBOARD ) ); - mnuExtra.add( createJMenuItem( - "Einstellungen...", - ACTION_SETTINGS ) ); - mnuExtra.addSeparator(); - - this.mnuSpeed = createJMenuItem( - TEXT_MAX_SPEED, - KeyEvent.VK_G, - ACTION_SPEED ); - mnuExtra.add( this.mnuSpeed ); - - this.mnuPause = createJMenuItem( - TEXT_PAUSE, - KeyEvent.VK_P, - ACTION_PAUSE ); - mnuExtra.add( this.mnuPause ); - mnuExtra.addSeparator(); - mnuExtra.add( createJMenuItem( - "Zur\u00FCcksetzen (RESET)", - KeyEvent.VK_R, - ACTION_RESET ) ); - mnuExtra.add( createJMenuItem( - "Einschalten (Speicher l\u00F6schen)", - KeyEvent.VK_I, - ACTION_POWER_ON ) ); - - - // Menu Hilfe - JMenu mnuHelp = new JMenu( "Hilfe" ); - mnuHelp.setMnemonic( KeyEvent.VK_H ); - mnuHelp.add( createJMenuItem( - AppContext.getAppName() + "-Hilfe...", - ACTION_HELP ) ); - mnuHelp.addSeparator(); - mnuHelp.add( createAboutMenuItem() ); - mnuHelp.add( - createJMenuItem( "Lizenzbestimmungen...", ACTION_LICENSE ) ); - mnuHelp.add( createJMenuItem( "Danksagung...", ACTION_THANKS ) ); - mnuBar.add( mnuHelp ); - - - // Fensterinhalt - setLayout( new BorderLayout() ); - - - // Werkzeugleiste - JPanel panelToolBar = new JPanel( - new FlowLayout( FlowLayout.LEFT, 0, 0 ) ); - add( panelToolBar, BorderLayout.NORTH ); - - JToolBar toolBar = new JToolBar(); - toolBar.setFloatable( false ); - toolBar.setBorderPainted( false ); - toolBar.setOrientation( JToolBar.HORIZONTAL ); - toolBar.setRollover( true ); - panelToolBar.add( toolBar ); - - toolBar.add( GUIUtil.createImageButton( - this, - "/images/file/open.png", - "Laden", - ACTION_LOAD ) ); - - toolBar.add( GUIUtil.createImageButton( - this, - "/images/file/save.png", - "Speichern", - ACTION_SAVE ) ); - toolBar.addSeparator(); - - toolBar.add( GUIUtil.createImageButton( - this, - "/images/file/edit.png", - "Texteditor", - ACTION_TEXTEDIT ) ); - toolBar.add( GUIUtil.createImageButton( - this, - "/images/file/audio.png", - "Audio/Kassette", - ACTION_AUDIO ) ); - toolBar.add( GUIUtil.createImageButton( - this, - "/images/edit/settings.png", - "Einstellungen", - ACTION_SETTINGS ) ); - - toolBar.addSeparator(); - - toolBar.add( GUIUtil.createImageButton( - this, - "/images/file/reset.png", - "Zur\u00FCcksetzen (RESET)", - ACTION_RESET ) ); - - - // Bildschirmausgabe - this.screenFld = new ScreenFld( this, this.jtcSys, screenScale ); - this.screenFld.addKeyListener( this ); - add( this.screenFld, BorderLayout.CENTER ); - - this.jtcScreenSize = getJTCScreenSize(); - this.jtcScreenSize2Scale.put( this.jtcScreenSize, screenScale ); - - - // Statuszeile - JPanel panelStatusBar = new JPanel( - new FlowLayout( FlowLayout.LEFT, 5, 5 ) ); - add( panelStatusBar, BorderLayout.SOUTH ); - - this.fldStatusText = new JLabel( DEFAULT_STATUS_TEXT ); - panelStatusBar.add( this.fldStatusText ); - - - // Timer zum zyklischen Aktualisieren der Bildschirmausgabe - this.screenRefreshTimer = new javax.swing.Timer( - getSettingsScreenRefreshMillis(), - this ); - this.screenRefreshTimer.start(); - - - // Timer zum Aktualisieren der Statuszeile - this.statusRefreshTimer = new javax.swing.Timer( - STATUS_REFRESH_MILLIS, - this ); - - - // Fenstergroesse und -position - updScreenSize( false ); - setResizable( true ); - if( !GUIUtil.applyWindowSettings( this ) ) { - pack(); - setLocationByPlatform( true ); + + public void doReset() { + boolean state = true; + if (AppContext.getBooleanProperty( + JTCUtil.PROP_CONFIRM_RESET, + true)) { + String msg = "M\u00F6chten Sie jetzt ein RESET ausl\u00F6sen\n" + + "und den Emulator zur\u00FCcksetzen?"; + if ((this.jtcSys.getOSType() == JTCSys.OSType.OS2K) + || (this.jtcSys.getOSType() == JTCSys.OSType.ES1988)) { + msg += "\nWenn der A-Cursor zu sehen ist,\n" + + "sollten Sie kein RESET ausl\u00F6sen!"; + } + if (JOptionPane.showConfirmDialog( + this, + msg, + "Best\u00E4tigung", + JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { + state = false; + } + } + if (state) { + resetEmu(false); + } } - // Clipboard ueberwachen - if( this.clipboard != null ) { - this.clipboard.addFlavorListener( this ); - clipboardContentChanged(); + public int getScreenRefreshMillis() { + return this.screenRefreshTimer.getDelay(); } - // Drop-Ziel - (new DropTarget( this.screenFld, this )).setActive( true ); - - - // Emulation starten - this.z8.setStatusListener( this ); - this.emuThread = new Thread( this.z8, "Z8 emulation" ); - this.emuThread.start(); - this.jtcSys.setResetListener( this ); - } - - - public JMenuItem createAboutMenuItem() - { - return createJMenuItem( - "\u00DCber " + AppContext.getAppName() + "...", - ACTION_ABOUT ); - } - - - public JMenuItem createQuitMenuItem() - { - return createJMenuItem( "Beenden", ACTION_QUIT ); - } - - - public void doPowerOn() - { - boolean state = true; - if( AppContext.getBooleanProperty( - JTCUtil.PROP_CONFIRM_POWER_ON, - true ) ) - { - if( JOptionPane.showConfirmDialog( - this, - "M\u00F6chten Sie das Aus- und wieder Einschalten" - + " emulieren\n" - + "und den Emulator initialisieren?\n" - + "Dabei wird der Arbeitsspeicher gel\u00F6scht.", - "Best\u00E4tigung", - JOptionPane.YES_NO_OPTION ) != JOptionPane.YES_OPTION ) - { - state = false; - } + public void screenConfigChanged() { + if (updScreenSize(true)) { + pack(); + } + JRadioButtonMenuItem item = this.scale2MenuItems.get( + this.screenFld.getScale()); + if (item != null) { + item.setSelected(true); + } } - if( state ) { - resetEmu( true ); + + + public boolean setMaxSpeed(Component owner, boolean state) { + boolean rv = false; + if (state) { + if (this.z8.getCyclesPerSecond() > 0) { + if (AudioIO.isCPUSynchronLineOpen()) { + JOptionPane.showMessageDialog( + owner, + "Solange ein Audiokanal ge\u00F6ffnet ist,\n" + + "kann nicht auf maximale Geschwindigkeit" + + " geschaltet werden,\n" + + "da der Audiokanal bremst.", + "Hinweis", + JOptionPane.INFORMATION_MESSAGE); + } else { + this.z8.setCyclesPerSecond(0); + rv = true; + } + } + } else { + this.z8.setCyclesPerSecond(JTCSys.DEFAULT_Z8_CYCLES_PER_SECOND); + rv = true; + } + return rv; } - } - - - public void doReset() - { - boolean state = true; - if( AppContext.getBooleanProperty( - JTCUtil.PROP_CONFIRM_RESET, - true ) ) - { - String msg = "M\u00F6chten Sie jetzt ein RESET ausl\u00F6sen\n" - + "und den Emulator zur\u00FCcksetzen?"; - if( (this.jtcSys.getOSType() == JTCSys.OSType.OS2K) - || (this.jtcSys.getOSType() == JTCSys.OSType.ES1988) ) - { - msg += "\nWenn der A-Cursor zu sehen ist,\n" - + "sollten Sie kein RESET ausl\u00F6sen!"; - } - if( JOptionPane.showConfirmDialog( - this, - msg, - "Best\u00E4tigung", - JOptionPane.YES_NO_OPTION ) != JOptionPane.YES_OPTION ) - { - state = false; - } + + + public void setScreenTextSelected(boolean state) { + this.mnuCopy.setEnabled(state); } - if( state ) { - resetEmu( false ); + + + public void showStatusText(String text) { + if (text != null) { + if (!text.isEmpty()) { + if (this.statusRefreshTimer.isRunning()) { + this.statusRefreshTimer.stop(); + } + this.fldStatusText.setText(text); + this.statusRefreshTimer.setDelay(STATUS_SHOW_MSG_MILLIS); + this.statusRefreshTimer.setInitialDelay(STATUS_SHOW_MSG_MILLIS); + this.statusRefreshTimer.start(); + } + } } - } - public int getScreenRefreshMillis() - { - return this.screenRefreshTimer.getDelay(); - } + /* --- ActionListener --- */ + + @Override + public void actionPerformed(ActionEvent e) { + Object src = e.getSource(); + if (src == this.screenRefreshTimer) { + boolean screenOutputEnabled = this.jtcSys.isScreenOutputEnabled(); + if ((screenOutputEnabled != this.screenOutputEnabled) + || this.screenFld.isDirty()) { + this.screenFld.repaint(); + this.screenOutputEnabled = screenOutputEnabled; + } + } else if (src == this.statusRefreshTimer) { + updStatusText(); + } else { + String actionCmd = e.getActionCommand(); + if (actionCmd != null) { + if (actionCmd.equals(ACTION_QUIT)) { + doQuit(); + } else { + GUIUtil.setWaitCursor(this, true); + try { + if (actionCmd.equals(ACTION_LOAD)) { + doLoad(false); + } else if (actionCmd.equals(ACTION_LOAD_OPT)) { + doLoad(true); + } else if (actionCmd.equals(ACTION_SAVE)) { + (new SaveDlg(this, this.jtcSys)).setVisible(true); + } else if (actionCmd.equals(ACTION_TEXTEDIT)) { + TextEditFrm.open(this.jtcSys); + } else if (actionCmd.equals(ACTION_COPY)) { + copyText(this.screenFld.getSelectedText()); + } else if (actionCmd.equals(ACTION_PASTE)) { + doPaste(); + } else if (actionCmd.equals(ACTION_PASTE_CANCEL)) { + doPasteCancel(); + } else if (actionCmd.equals(ACTION_SCR_TEXT_COPY)) { + copyText(this.jtcSys.getScreenText()); + } else if (actionCmd.equals(ACTION_SCR_IMG_COPY)) { + doScreenImageCopy(); + } else if (actionCmd.equals(ACTION_SCR_IMG_SAVE_AS)) { + doScreenImageSaveAs(); + } else if (actionCmd.equals(ACTION_DEBUG)) { + DebugFrm.open(this.z8); + } else if (actionCmd.equals(ACTION_REASS)) { + ReassFrm.open(this.jtcSys); + } else if (actionCmd.equals(ACTION_MEMEDIT)) { + MemEditFrm.open(this.jtcSys); + } else if (actionCmd.equals(ACTION_HEXEDIT)) { + HexEditFrm.open(); + } else if (actionCmd.equals(ACTION_AUDIO)) { + AudioFrm.open(this.jtcSys); + } else if (actionCmd.equals(ACTION_KEYBOARD)) { + KeyboardFrm.open(this.jtcSys); + } else if (actionCmd.equals(ACTION_SETTINGS)) { + SettingsFrm.open(this, this.jtcSys); + } else if (actionCmd.equals(ACTION_SPEED)) { + doSpeed(); + } else if (actionCmd.equals(ACTION_PAUSE)) { + doPause(); + } else if (actionCmd.equals(ACTION_POWER_ON)) { + doPowerOn(); + } else if (actionCmd.equals(ACTION_RESET)) { + doReset(); + } else if (actionCmd.equals(ACTION_HELP)) { + HelpFrm.open(null); + } else if (actionCmd.equals(ACTION_ABOUT)) { + doAbout(); + } else if (actionCmd.equals(ACTION_LICENSE)) { + HelpFrm.open("/help/common/license.htm"); + } else if (actionCmd.equals(ACTION_THANKS)) { + HelpFrm.open("/help/common/thanks.htm"); + } else if (actionCmd.startsWith(ACTION_SCALE_PREFIX)) { + int prefixLen = ACTION_SCALE_PREFIX.length(); + if (actionCmd.length() > prefixLen) { + try { + int scale = Integer.parseInt( + actionCmd.substring(prefixLen)); + this.screenFld.setScale(scale); + this.jtcScreenSize2Scale.put(this.jtcScreenSize, scale); + pack(); + } catch (NumberFormatException ex) { + } + } + } + } catch (Exception ex) { + Main.showError(this, ex); + } + GUIUtil.setWaitCursor(this, false); + } + } + } + } + + /* --- DropTargetListener --- */ - public void screenConfigChanged() - { - if( updScreenSize( true ) ) { - pack(); + @Override + public void dragEnter(DropTargetDragEvent e) { + if (!GUIUtil.isFileDrop(e)) + e.rejectDrag(); } - JRadioButtonMenuItem item = this.scale2MenuItems.get( - this.screenFld.getScale() ); - if( item != null ) { - item.setSelected( true ); + + + @Override + public void dragExit(DropTargetEvent e) { + // leer } - } - - - public boolean setMaxSpeed( Component owner, boolean state ) - { - boolean rv = false; - if( state ) { - if( this.z8.getCyclesPerSecond() > 0 ) { - if( AudioIO.isCPUSynchronLineOpen() ) { - JOptionPane.showMessageDialog( - owner, - "Solange ein Audiokanal ge\u00F6ffnet ist,\n" - + "kann nicht auf maximale Geschwindigkeit" - + " geschaltet werden,\n" - + "da der Audiokanal bremst.", - "Hinweis", - JOptionPane.INFORMATION_MESSAGE ); - } else { - this.z8.setCyclesPerSecond( 0 ); - rv = true; - } - } - } else { - this.z8.setCyclesPerSecond( JTCSys.DEFAULT_Z8_CYCLES_PER_SECOND ); - rv = true; + + + @Override + public void dragOver(DropTargetDragEvent e) { + // leer } - return rv; - } - - - public void setScreenTextSelected( boolean state ) - { - this.mnuCopy.setEnabled( state ); - } - - - public void showStatusText( String text ) - { - if( text != null ) { - if( !text.isEmpty() ) { - if( this.statusRefreshTimer.isRunning() ) { - this.statusRefreshTimer.stop(); - } - this.fldStatusText.setText( text ); - this.statusRefreshTimer.setDelay( STATUS_SHOW_MSG_MILLIS ); - this.statusRefreshTimer.setInitialDelay( STATUS_SHOW_MSG_MILLIS ); - this.statusRefreshTimer.start(); - } + + + @Override + public void drop(DropTargetDropEvent e) { + final File file = GUIUtil.fileDrop(this, e); + if (file != null) { + // nicht auf Benutzereingaben warten + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + loadFile(file, false); + } + }); + } } - } - - - /* --- ActionListener --- */ - - @Override - public void actionPerformed( ActionEvent e ) - { - Object src = e.getSource(); - if( src == this.screenRefreshTimer ) { - boolean screenOutputEnabled = this.jtcSys.isScreenOutputEnabled(); - if( (screenOutputEnabled != this.screenOutputEnabled) - || this.screenFld.isDirty() ) - { - this.screenFld.repaint(); - this.screenOutputEnabled = screenOutputEnabled; - } - } else if( src == this.statusRefreshTimer ) { - updStatusText(); - } else { - String actionCmd = e.getActionCommand(); - if( actionCmd != null ) { - if( actionCmd.equals( ACTION_QUIT ) ) { - doQuit(); - } else { - GUIUtil.setWaitCursor( this, true ); - try { - if( actionCmd.equals( ACTION_LOAD ) ) { - doLoad( false ); - } - else if( actionCmd.equals( ACTION_LOAD_OPT ) ) { - doLoad( true ); - } - else if( actionCmd.equals( ACTION_SAVE ) ) { - (new SaveDlg( this, this.jtcSys )).setVisible( true ); - } - else if( actionCmd.equals( ACTION_TEXTEDIT ) ) { - TextEditFrm.open( this.jtcSys ); - } - else if( actionCmd.equals( ACTION_COPY ) ) { - copyText( this.screenFld.getSelectedText() ); - } - else if( actionCmd.equals( ACTION_PASTE ) ) { - doPaste(); - } - else if( actionCmd.equals( ACTION_PASTE_CANCEL ) ) { - doPasteCancel(); - } - else if( actionCmd.equals( ACTION_SCR_TEXT_COPY ) ) { - copyText( this.jtcSys.getScreenText() ); - } - else if( actionCmd.equals( ACTION_SCR_IMG_COPY ) ) { - doScreenImageCopy(); - } - else if( actionCmd.equals( ACTION_SCR_IMG_SAVE_AS ) ) { - doScreenImageSaveAs(); - } - else if( actionCmd.equals( ACTION_DEBUG ) ) { - DebugFrm.open( this.z8 ); - } - else if( actionCmd.equals( ACTION_REASS ) ) { - ReassFrm.open( this.jtcSys ); - } - else if( actionCmd.equals( ACTION_MEMEDIT ) ) { - MemEditFrm.open( this.jtcSys ); - } - else if( actionCmd.equals( ACTION_HEXEDIT ) ) { - HexEditFrm.open(); - } - else if( actionCmd.equals( ACTION_AUDIO ) ) { - AudioFrm.open( this.jtcSys ); - } - else if( actionCmd.equals( ACTION_KEYBOARD ) ) { - KeyboardFrm.open( this.jtcSys ); - } - else if( actionCmd.equals( ACTION_SETTINGS ) ) { - SettingsFrm.open( this, this.jtcSys ); - } - else if( actionCmd.equals( ACTION_SPEED ) ) { - doSpeed(); - } - else if( actionCmd.equals( ACTION_PAUSE ) ) { - doPause(); - } - else if( actionCmd.equals( ACTION_POWER_ON ) ) { - doPowerOn(); - } - else if( actionCmd.equals( ACTION_RESET ) ) { - doReset(); - } - else if( actionCmd.equals( ACTION_HELP ) ) { - HelpFrm.open( null ); - } - else if( actionCmd.equals( ACTION_ABOUT ) ) { - doAbout(); - } - else if( actionCmd.equals( ACTION_LICENSE ) ) { - HelpFrm.open( "/help/common/license.htm" ); - } - else if( actionCmd.equals( ACTION_THANKS ) ) { - HelpFrm.open( "/help/common/thanks.htm" ); - } - else if( actionCmd.startsWith( ACTION_SCALE_PREFIX ) ) { - int prefixLen = ACTION_SCALE_PREFIX.length(); - if( actionCmd.length() > prefixLen ) { - try { - int scale = Integer.parseInt( - actionCmd.substring( prefixLen ) ); - this.screenFld.setScale( scale ); - this.jtcScreenSize2Scale.put( this.jtcScreenSize, scale ); - pack(); - } - catch( NumberFormatException ex ) {} - } - } - } - catch( Exception ex ) { - Main.showError( this, ex ); - } - GUIUtil.setWaitCursor( this, false ); - } - } + + + @Override + public void dropActionChanged(DropTargetDragEvent e) { + if (!GUIUtil.isFileDrop(e)) + e.rejectDrag(); } - } - - - /* --- DropTargetListener --- */ - - @Override - public void dragEnter( DropTargetDragEvent e ) - { - if( !GUIUtil.isFileDrop( e ) ) - e.rejectDrag(); - } - - - @Override - public void dragExit( DropTargetEvent e ) - { - // leer - } - - - @Override - public void dragOver( DropTargetDragEvent e ) - { - // leer - } - - - @Override - public void drop( DropTargetDropEvent e ) - { - final File file = GUIUtil.fileDrop( this, e ); - if( file != null ) { - // nicht auf Benutzereingaben warten - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - loadFile( file, false ); - } - } ); + + + /* --- ErrorViewer --- */ + + public void showError(final String msg) { + final Component owner = this; + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + Main.showError(owner, msg); + } + }); } - } - - - @Override - public void dropActionChanged( DropTargetDragEvent e ) - { - if( !GUIUtil.isFileDrop( e ) ) - e.rejectDrag(); - } - - - /* --- ErrorViewer --- */ - - public void showError( final String msg ) - { - final Component owner = this; - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - Main.showError( owner, msg ); - } - } ); - } - - - /* --- FlavorListener --- */ - - @Override - public void flavorsChanged( FlavorEvent e ) - { - if( e.getSource() == this.clipboard ) - clipboardContentChanged(); - } - - - /* --- KeyListener --- */ - - @Override - public void keyPressed( KeyEvent e ) - { - if( !e.isAltDown() ) { - JTCSys.Key key = null; - switch( e.getKeyCode() ) { - case KeyEvent.VK_LEFT: - key = JTCSys.Key.LEFT; - break; - case KeyEvent.VK_RIGHT: - key = JTCSys.Key.RIGHT; - break; - case KeyEvent.VK_UP: - key = JTCSys.Key.UP; - break; - case KeyEvent.VK_DOWN: - key = JTCSys.Key.DOWN; - break; - case KeyEvent.VK_BACK_SPACE: - key = JTCSys.Key.BACK_SPACE; - break; - case KeyEvent.VK_HOME: - key = JTCSys.Key.HOME; - break; - case KeyEvent.VK_SPACE: - key = JTCSys.Key.SPACE; - break; - case KeyEvent.VK_ENTER: - key = JTCSys.Key.ENTER; - break; - case KeyEvent.VK_ESCAPE: - key = JTCSys.Key.ESCAPE; - break; - case KeyEvent.VK_INSERT: - key = JTCSys.Key.INSERT; - break; - case KeyEvent.VK_DELETE: - key = JTCSys.Key.DELETE; - break; - case KeyEvent.VK_CLEAR: - key = JTCSys.Key.CLEAR; - break; - case KeyEvent.VK_F1: - key = JTCSys.Key.F1; - break; - case KeyEvent.VK_F2: - key = JTCSys.Key.F2; - break; - case KeyEvent.VK_F3: - key = JTCSys.Key.F3; - break; - case KeyEvent.VK_F4: - key = JTCSys.Key.F4; - break; - case KeyEvent.VK_F5: - key = JTCSys.Key.F5; - break; - case KeyEvent.VK_F6: - key = JTCSys.Key.F6; - break; - case KeyEvent.VK_F7: - key = JTCSys.Key.F7; - break; - case KeyEvent.VK_F8: - key = JTCSys.Key.F8; - break; - } - if( key != null ) { - if( this.jtcSys.keyPressed( key, e.isShiftDown() ) ) { - KeyboardFrm.updKeyFields(); - e.consume(); - } - } + + + /* --- FlavorListener --- */ + + @Override + public void flavorsChanged(FlavorEvent e) { + if (e.getSource() == this.clipboard) + clipboardContentChanged(); } - } - @Override - public void keyReleased( KeyEvent e ) - { - if( !e.isAltDown() ) { - this.jtcSys.keyReleased(); - KeyboardFrm.updKeyFields(); - e.consume(); + /* --- KeyListener --- */ + + @Override + public void keyPressed(KeyEvent e) { + if (!e.isAltDown()) { + JTCSys.Key key = null; + switch (e.getKeyCode()) { + case KeyEvent.VK_LEFT: + key = JTCSys.Key.LEFT; + break; + case KeyEvent.VK_RIGHT: + key = JTCSys.Key.RIGHT; + break; + case KeyEvent.VK_UP: + key = JTCSys.Key.UP; + break; + case KeyEvent.VK_DOWN: + key = JTCSys.Key.DOWN; + break; + case KeyEvent.VK_BACK_SPACE: + key = JTCSys.Key.BACK_SPACE; + break; + case KeyEvent.VK_HOME: + key = JTCSys.Key.HOME; + break; + case KeyEvent.VK_SPACE: + key = JTCSys.Key.SPACE; + break; + case KeyEvent.VK_ENTER: + key = JTCSys.Key.ENTER; + break; + case KeyEvent.VK_ESCAPE: + key = JTCSys.Key.ESCAPE; + break; + case KeyEvent.VK_INSERT: + key = JTCSys.Key.INSERT; + break; + case KeyEvent.VK_DELETE: + key = JTCSys.Key.DELETE; + break; + case KeyEvent.VK_CLEAR: + key = JTCSys.Key.CLEAR; + break; + case KeyEvent.VK_F1: + key = JTCSys.Key.F1; + break; + case KeyEvent.VK_F2: + key = JTCSys.Key.F2; + break; + case KeyEvent.VK_F3: + key = JTCSys.Key.F3; + break; + case KeyEvent.VK_F4: + key = JTCSys.Key.F4; + break; + case KeyEvent.VK_F5: + key = JTCSys.Key.F5; + break; + case KeyEvent.VK_F6: + key = JTCSys.Key.F6; + break; + case KeyEvent.VK_F7: + key = JTCSys.Key.F7; + break; + case KeyEvent.VK_F8: + key = JTCSys.Key.F8; + break; + } + if (key != null) { + if (this.jtcSys.keyPressed(key, e.isShiftDown())) { + KeyboardFrm.updKeyFields(); + e.consume(); + } + } + } } - } - @Override - public void keyTyped( KeyEvent e ) - { - if( !e.isAltDown() ) { - this.jtcSys.keyTyped( e.getKeyChar() ); - KeyboardFrm.updKeyFields(); - e.consume(); + @Override + public void keyReleased(KeyEvent e) { + if (!e.isAltDown()) { + this.jtcSys.keyReleased(); + KeyboardFrm.updKeyFields(); + e.consume(); + } } - } - - - /* --- PasteObserver --- */ - - @Override - public void pastingFinished() - { - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - setPasting( false ); - } - } ); - } - - - /* --- Z8Listener --- */ - - @Override - public void z8Update( Z8 z8, final Z8Listener.Reason reason ) - { - if( z8 == this.z8 ) { - if( z8.isPause() ) { - AudioFrm.closeCPUSynchronLine(); - } - EventQueue.invokeLater( - new Runnable() - { - @Override - public void run() - { - z8UpdateInternal( reason ); - } - } ); + + + @Override + public void keyTyped(KeyEvent e) { + if (!e.isAltDown()) { + this.jtcSys.keyTyped(e.getKeyChar()); + KeyboardFrm.updKeyFields(); + e.consume(); + } } - } - /* --- ueberschriebene Methoden --- */ + /* --- PasteObserver --- */ - @Override - public String getPropPrefix() - { - return "emulator."; - } + @Override + public void pastingFinished() { + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + setPasting(false); + } + }); + } - @Override - public void lafChanged() - { - pack(); - } + /* --- Z8Listener --- */ + + @Override + public void z8Update(Z8 z8, final Z8Listener.Reason reason) { + if (z8 == this.z8) { + if (z8.isPause()) { + AudioFrm.closeCPUSynchronLine(); + } + EventQueue.invokeLater( + new Runnable() { + @Override + public void run() { + z8UpdateInternal(reason); + } + }); + } + } - @Override - public void memorizeSettings() - { - super.memorizeSettings(); - AppContext.setProperty( - PROP_SCREEN_SCALE, - Integer.toString( this.screenFld.getScale() ) ); - } + /* --- ueberschriebene Methoden --- */ + + @Override + public String getPropPrefix() { + return "emulator."; + } - @Override - public void settingsChanged() - { - this.screenRefreshTimer.setDelay( getSettingsScreenRefreshMillis() ); - if( ((this.jtcSys.getOSType() != JTCSys.OSType.OS2K) - && (this.jtcSys.getOSType() != JTCSys.OSType.ES1988)) ) - { - KeyboardFrm.close(); + @Override + public void lafChanged() { + pack(); } - } - @Override - public void windowClosing( WindowEvent e ) - { - doQuit(); - } + @Override + public void memorizeSettings() { + super.memorizeSettings(); + AppContext.setProperty( + PROP_SCREEN_SCALE, + Integer.toString(this.screenFld.getScale())); + } - @Override - public void windowOpened( WindowEvent e ) - { - AudioFrm.checkOpen( this.jtcSys ); - this.screenFld.requestFocus(); - } + @Override + public void settingsChanged() { + this.screenRefreshTimer.setDelay(getSettingsScreenRefreshMillis()); + if (((this.jtcSys.getOSType() != JTCSys.OSType.OS2K) + && (this.jtcSys.getOSType() != JTCSys.OSType.ES1988))) { + KeyboardFrm.close(); + } + } - /* --- Aktionen --- */ + @Override + public void windowClosing(WindowEvent e) { + doQuit(); + } - private void doAbout() - { - JPanel panel = new JPanel(); - panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) ); - JLabel labelName = new JLabel( AppContext.getAppName() ); - labelName.setFont( new Font( Font.SANS_SERIF, Font.BOLD, 24 ) ); - panel.add( labelName ); + @Override + public void windowOpened(WindowEvent e) { + AudioFrm.checkOpen(this.jtcSys); + this.screenFld.requestFocus(); + } + - JLabel labelVersion = new JLabel( - "Version " + AppContext.getAppVersion() ); - labelVersion.setFont( new Font( Font.SANS_SERIF, Font.BOLD, 18 ) ); - panel.add( labelVersion ); + /* --- Aktionen --- */ - panel.add( Box.createRigidArea( new Dimension( 0, 10 ) ) ); + private void doAbout() { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - JOptionPane.showMessageDialog( - this, - new Object[] { panel, AppContext.getAboutContent() }, - "\u00DCber...", - JOptionPane.INFORMATION_MESSAGE ); - } + JLabel labelName = new JLabel(AppContext.getAppName()); + labelName.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 24)); + panel.add(labelName); + JLabel labelVersion = new JLabel( + "Version " + AppContext.getAppVersion()); + labelVersion.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 18)); + panel.add(labelVersion); - private void doLoad( boolean withOptions ) - { - String title = "Datei laden"; - if( withOptions ) { - title += " mit Optionen"; + panel.add(Box.createRigidArea(new Dimension(0, 10))); + + JOptionPane.showMessageDialog( + this, + new Object[]{panel, AppContext.getAboutContent()}, + "\u00DCber...", + JOptionPane.INFORMATION_MESSAGE); } - File file = FileDlg.showFileOpenDlg( - this, - title, - "Laden...", - AppContext.getLastDirFile( - FileInfo.FILE_GROUP_SOFTWARE ), - GUIUtil.binaryFileFilter, - GUIUtil.hexFileFilter, - GUIUtil.jtcFileFilter, - GUIUtil.tapFileFilter ); - if( file != null ) { - loadFile( file, withOptions ); + + + private void doLoad(boolean withOptions) { + String title = "Datei laden"; + if (withOptions) { + title += " mit Optionen"; + } + File file = FileDlg.showFileOpenDlg( + this, + title, + "Laden...", + AppContext.getLastDirFile( + FileInfo.FILE_GROUP_SOFTWARE), + GUIUtil.binaryFileFilter, + GUIUtil.hexFileFilter, + GUIUtil.jtcFileFilter, + GUIUtil.tapFileFilter); + if (file != null) { + loadFile(file, withOptions); + } } - } - - - private void doPaste() - { - if( this.clipboard != null ) { - try { - if( this.clipboard.isDataFlavorAvailable( - DataFlavor.stringFlavor ) ) - { - Object o = this.clipboard.getData( DataFlavor.stringFlavor ); - if( o != null ) { - this.jtcSys.startPastingText( o.toString(), this ); - setPasting( true ); - } - } - } - catch( Exception ex ) {} + + + private void doPaste() { + if (this.clipboard != null) { + try { + if (this.clipboard.isDataFlavorAvailable( + DataFlavor.stringFlavor)) { + Object o = this.clipboard.getData(DataFlavor.stringFlavor); + if (o != null) { + this.jtcSys.startPastingText(o.toString(), this); + setPasting(true); + } + } + } catch (Exception ex) { + } + } } - } - - - private void doPasteCancel() - { - this.jtcSys.cancelPastingText(); - setPasting( false ); - } - - - private void doPause() - { - this.z8.setPause( !this.z8.isPause() ); - } - - - private void doQuit() - { - boolean state = true; - if( AppContext.getBooleanProperty( - JTCUtil.PROP_CONFIRM_QUIT, - true ) ) - { - if( JOptionPane.showConfirmDialog( - this, - "M\u00F6chten Sie " + AppContext.getAppName() + " beenden?", - "Best\u00E4tigung", - JOptionPane.YES_NO_OPTION ) != JOptionPane.YES_OPTION ) - { - state = false; - } + + + private void doPasteCancel() { + this.jtcSys.cancelPastingText(); + setPasting(false); } - if( state ) { - state = TextEditFrm.close(); + + + private void doPause() { + this.z8.setPause(!this.z8.isPause()); } - if( state ) { - state = HexEditFrm.close(); + + + private void doQuit() { + boolean state = true; + if (AppContext.getBooleanProperty( + JTCUtil.PROP_CONFIRM_QUIT, + true)) { + if (JOptionPane.showConfirmDialog( + this, + "M\u00F6chten Sie " + AppContext.getAppName() + " beenden?", + "Best\u00E4tigung", + JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) { + state = false; + } + } + if (state) { + state = TextEditFrm.close(); + } + if (state) { + state = HexEditFrm.close(); + } + if (state) { + this.screenRefreshTimer.stop(); + this.z8.fireQuit(); + AudioFrm.quit(); + DebugFrm.close(); + HelpFrm.close(); + KeyboardFrm.close(); + MemEditFrm.close(); + ReassFrm.close(); + SettingsFrm.close(); + try { + this.emuThread.join(500); + } catch (InterruptedException ex) { + } + doClose(); + System.exit(0); + } } - if( state ) { - this.screenRefreshTimer.stop(); - this.z8.fireQuit(); - AudioFrm.quit(); - DebugFrm.close(); - HelpFrm.close(); - KeyboardFrm.close(); - MemEditFrm.close(); - ReassFrm.close(); - SettingsFrm.close(); - try { - this.emuThread.join( 500 ); - } - catch( InterruptedException ex ) {} - doClose(); - System.exit( 0 ); + + + private void doScreenImageCopy() { + try { + if (this.clipboard != null) { + Image image = this.screenFld.createBufferedImage(); + if (image != null) { + TransferableImage tImg = new TransferableImage(image); + this.clipboard.setContents(tImg, tImg); + } + } + } catch (IllegalStateException ex) { + } } - } - - - private void doScreenImageCopy() - { - try { - if( this.clipboard != null ) { - Image image = this.screenFld.createBufferedImage(); - if( image != null ) { - TransferableImage tImg = new TransferableImage( image ); - this.clipboard.setContents( tImg, tImg ); - } - } + + + private void doScreenImageSaveAs() { + try { + String[] fmtNames = ImageIO.getWriterFormatNames(); + if (fmtNames != null) { + if (fmtNames.length < 1) { + fmtNames = null; + } + } + if (fmtNames == null) { + throw new IOException( + "Das Speichern von Bilddateien wird auf\n" + + "dieser Plattform nicht unterst\u00FCtzt."); + } + BufferedImage image = this.screenFld.createBufferedImage(); + if (image != null) { + File file = FileDlg.showFileSaveDlg( + this, + "Bilddatei speichern", + AppContext.getLastDirFile(FILE_GROUP_IMAGE), + new FileNameExtensionFilter( + "Unterst\u00FCtzte Bilddateien", + fmtNames)); + if (file != null) { + String s = file.getName(); + if (s != null) { + s = s.toUpperCase(); + String fmt = null; + for (int i = 0; i < fmtNames.length; i++) { + if (s.endsWith("." + fmtNames[i].toUpperCase())) { + fmt = fmtNames[i]; + break; + } + } + if (fmt != null) { + OutputStream out = null; + try { + out = new FileOutputStream(file); + if (!ImageIO.write(image, fmt, file)) { + fmt = null; + } + out.close(); + AppContext.setLastFile(FILE_GROUP_IMAGE, file); + } catch (IOException ex) { + file.delete(); + throw ex; + } finally { + JTCUtil.closeSilently(out); + } + } + if (fmt == null) { + throw new IOException( + "Das durch die Dateiendung angegebene Format\n" + + "wird nicht unterst\u00FCtzt."); + } + } + } + } + } catch (Exception ex) { + Main.showError(this, ex); + } } - catch( IllegalStateException ex ) {} - } - - - private void doScreenImageSaveAs() - { - try { - String[] fmtNames = ImageIO.getWriterFormatNames(); - if( fmtNames != null ) { - if( fmtNames.length < 1 ) { - fmtNames = null; - } - } - if( fmtNames == null ) { - throw new IOException( - "Das Speichern von Bilddateien wird auf\n" - + "dieser Plattform nicht unterst\u00FCtzt." ); - } - BufferedImage image = this.screenFld.createBufferedImage(); - if( image != null ) { - File file = FileDlg.showFileSaveDlg( - this, - "Bilddatei speichern", - AppContext.getLastDirFile( FILE_GROUP_IMAGE ), - new FileNameExtensionFilter( - "Unterst\u00FCtzte Bilddateien", - fmtNames ) ); - if( file != null ) { - String s = file.getName(); - if( s != null ) { - s = s.toUpperCase(); - String fmt = null; - for( int i = 0; i < fmtNames.length; i++ ) { - if( s.endsWith( "." + fmtNames[ i ].toUpperCase() ) ) { - fmt = fmtNames[ i ]; - break; - } - } - if( fmt != null ) { - OutputStream out = null; - try { - out = new FileOutputStream( file ); - if( !ImageIO.write( image, fmt, file ) ) { - fmt = null; - } - out.close(); - AppContext.setLastFile( FILE_GROUP_IMAGE, file ); - } - catch( IOException ex ) { - file.delete(); - throw ex; - } - finally { - JTCUtil.closeSilently( out ); - } - } - if( fmt == null ) { - throw new IOException( - "Das durch die Dateiendung angegebene Format\n" - + "wird nicht unterst\u00FCtzt." ); - } - } - } - } + + + private void doSpeed() { + setMaxSpeed(this, this.z8.getCyclesPerSecond() > 0); } - catch( Exception ex ) { - Main.showError( this, ex ); + + + /* --- private Methoden --- */ + + private void clipboardContentChanged() { + boolean state = false; + if (this.clipboard != null) { + try { + state = this.clipboard.isDataFlavorAvailable( + DataFlavor.stringFlavor); + } catch (IllegalStateException ex) { + } + } + this.mnuPaste.setEnabled(state); } - } - private void doSpeed() - { - setMaxSpeed( this, this.z8.getCyclesPerSecond() > 0 ); - } + private void copyText(String text) { + if ((this.clipboard != null) && (text != null)) { + try { + StringSelection data = new StringSelection(text); + this.clipboard.setContents(data, data); + } catch (IllegalStateException ex) { + } + } + } + + private JMenuItem createJMenuItem(String text, String actionCmd) { + JMenuItem item = new JMenuItem(text); + if (actionCmd != null) { + item.setActionCommand(actionCmd); + } + item.addActionListener(this); + return item; + } - /* --- private Methoden --- */ - private void clipboardContentChanged() - { - boolean state = false; - if( this.clipboard != null ) { - try { - state = this.clipboard.isDataFlavorAvailable( - DataFlavor.stringFlavor ); - } - catch( IllegalStateException ex ) {} + private JMenuItem createJMenuItem( + String text, + int accKeyCode, + boolean shift, + String actionCmd) { + JMenuItem item = createJMenuItem(text, actionCmd); + item.setAccelerator( + KeyStroke.getKeyStroke( + accKeyCode, + this.mnuShortcutKeyMask + | (shift ? InputEvent.SHIFT_DOWN_MASK : 0))); + return item; } - this.mnuPaste.setEnabled( state ); - } - - - private void copyText( String text ) - { - if( (this.clipboard != null) && (text != null) ) { - try { - StringSelection data = new StringSelection( text ); - this.clipboard.setContents( data, data ); - } - catch( IllegalStateException ex ) {} + + + private JMenuItem createJMenuItem( + String text, + int accKeyCode, + String actionCmd) { + return createJMenuItem(text, accKeyCode, false, actionCmd); } - } - private JMenuItem createJMenuItem( String text, String actionCmd ) - { - JMenuItem item = new JMenuItem( text ); - if( actionCmd != null ) { - item.setActionCommand( actionCmd ); + private Dimension getJTCScreenSize() { + return new Dimension( + this.jtcSys.getScreenWidth(), + this.jtcSys.getScreenHeight()); } - item.addActionListener( this ); - return item; - } - - - private JMenuItem createJMenuItem( - String text, - int accKeyCode, - boolean shift, - String actionCmd ) - { - JMenuItem item = createJMenuItem( text, actionCmd ); - item.setAccelerator( - KeyStroke.getKeyStroke( - accKeyCode, - this.mnuShortcutKeyMask - | (shift ? InputEvent.SHIFT_DOWN_MASK : 0) ) ); - return item; - } - - - private JMenuItem createJMenuItem( - String text, - int accKeyCode, - String actionCmd ) - { - return createJMenuItem( text, accKeyCode, false, actionCmd ); - } - - - private Dimension getJTCScreenSize() - { - return new Dimension( - this.jtcSys.getScreenWidth(), - this.jtcSys.getScreenHeight() ); - } - - - private static int getSettingsScreenRefreshMillis() - { - return AppContext.getIntProperty( - PROP_SCREEN_REFRESH_MS, - DEFAULT_SCREEN_REFRESH_MS ); - } - - - private void loadFile( File file, boolean withOptions ) - { - if( this.jtcSys != null ) { - int begAddr = -1; - FileInfo fileInfo = FileInfo.analyzeFile( file ); - if( fileInfo != null ) { - begAddr = fileInfo.getBegAddr(); - } - if( !withOptions && (fileInfo != null) && (begAddr >= 0) ) { - LoadDlg.loadFile( - this, - this, - this.jtcSys, - file, - fileInfo.getFormat(), - begAddr, - fileInfo.getEndAddr(), - fileInfo.getStartAddr() ); - } else { - LoadDlg.open( this, this.jtcSys, file, fileInfo ); - } + + + private static int getSettingsScreenRefreshMillis() { + return AppContext.getIntProperty( + PROP_SCREEN_REFRESH_MS, + DEFAULT_SCREEN_REFRESH_MS); } - } - - - private void resetEmu( boolean initRAM ) - { - this.screenFld.clearSelection(); - this.jtcSys.fireReset( initRAM ); - - /* - * Der Timer wird neu gestartet fuer den Fall, - * dass sich der Timer aufgehaengt haben sollte, - * und man moechte ihn mit RESET reaktivieren. - */ - this.screenRefreshTimer.restart(); - } - - - private void setPasting( boolean state ) - { - this.mnuPasteCancel.setEnabled( state ); - } - - - private boolean updScreenSize( boolean updScale ) - { - Dimension newSize = getJTCScreenSize(); - boolean sizeChanged = !newSize.equals( this.jtcScreenSize ); - if( sizeChanged ) { - Integer screenScale = null; - if( updScale ) { - screenScale = this.jtcScreenSize2Scale.get( newSize ); - } - if( screenScale != null ) { - this.screenFld.setScale( screenScale ); - } else { - this.screenFld.updPreferredSize(); - } - this.jtcScreenSize = newSize; + + + private void loadFile(File file, boolean withOptions) { + if (this.jtcSys != null) { + int begAddr = -1; + FileInfo fileInfo = FileInfo.analyzeFile(file); + if (fileInfo != null) { + begAddr = fileInfo.getBegAddr(); + } + if (!withOptions && (fileInfo != null) && (begAddr >= 0)) { + LoadDlg.loadFile( + this, + this, + this.jtcSys, + file, + fileInfo.getFormat(), + begAddr, + fileInfo.getEndAddr(), + fileInfo.getStartAddr()); + } else { + LoadDlg.open(this, this.jtcSys, file, fileInfo); + } + } } - int mOld = this.screenFld.getMargin(); - int mNew = AppContext.getIntProperty( - PROP_SCREEN_MARGIN, - DEFAULT_SCREEN_MARGIN ); - this.screenFld.setMargin( mNew ); - if( mNew != mOld ) { - sizeChanged = true; + + + private void resetEmu(boolean initRAM) { + this.screenFld.clearSelection(); + this.jtcSys.fireReset(initRAM); + + /* + * Der Timer wird neu gestartet fuer den Fall, + * dass sich der Timer aufgehaengt haben sollte, + * und man moechte ihn mit RESET reaktivieren. + */ + this.screenRefreshTimer.restart(); } - return sizeChanged; - } - private void updStatusText() - { - if( this.statusRefreshTimer.isRunning() ) { - this.statusRefreshTimer.stop(); + private void setPasting(boolean state) { + this.mnuPasteCancel.setEnabled(state); } - String text = null; - if( this.z8.isPause() ) { - this.mnuPause.setText( TEXT_GO_ON ); - this.mnuPause.setEnabled( true ); - text = "Emulator angehalten"; - } else { - this.mnuPause.setText( TEXT_PAUSE ); - this.mnuPause.setEnabled( true ); - Double mhz = this.z8.getEmulatedMHz(); - int millis = STATUS_REFRESH_MILLIS; - if( this.z8.getCyclesPerSecond() > 0 ) { - if( mhz != null ) { - if( (mhz.doubleValue() >= 3.8) - && (mhz.doubleValue() <= 4.2) ) - { - mhz = null; - } else { - millis = STATUS_REFRESH_MILLIS; - } - } - } else { - millis = STATUS_REFRESH_MILLIS; - } - if( mhz != null ) { - text = JTCUtil.getEmulatedSpeedText( mhz.doubleValue() ); - } - this.statusRefreshTimer.setDelay( millis ); - this.statusRefreshTimer.setInitialDelay( millis ); - this.statusRefreshTimer.start(); + + + private boolean updScreenSize(boolean updScale) { + Dimension newSize = getJTCScreenSize(); + boolean sizeChanged = !newSize.equals(this.jtcScreenSize); + if (sizeChanged) { + Integer screenScale = null; + if (updScale) { + screenScale = this.jtcScreenSize2Scale.get(newSize); + } + if (screenScale != null) { + this.screenFld.setScale(screenScale); + } else { + this.screenFld.updPreferredSize(); + } + this.jtcScreenSize = newSize; + } + int mOld = this.screenFld.getMargin(); + int mNew = AppContext.getIntProperty( + PROP_SCREEN_MARGIN, + DEFAULT_SCREEN_MARGIN); + this.screenFld.setMargin(mNew); + if (mNew != mOld) { + sizeChanged = true; + } + return sizeChanged; } - this.fldStatusText.setText( text != null ? text : DEFAULT_STATUS_TEXT ); - } - - - private void z8UpdateInternal( Z8Listener.Reason reason ) - { - switch( reason ) { - case POWER_ON: - case RESET: - AudioFrm.reset(); - KeyboardFrm.reset(); - MemEditFrm.reset(); - ReassFrm.reset(); - break; - - case CYCLES_PER_SECOND_CHANGED: - if( this.z8.getCyclesPerSecond() > 0 ) { - this.mnuSpeed.setText( TEXT_MAX_SPEED ); - } else { - this.mnuSpeed.setText( TEXT_NORM_SPEED ); - } - AudioFrm.z8CyclesPerSecondChanged(); - updStatusText(); - break; - - case STATUS_CHANGED: - updStatusText(); - DebugFrm.z8StatusChanged(); - break; + + + private void updStatusText() { + if (this.statusRefreshTimer.isRunning()) { + this.statusRefreshTimer.stop(); + } + String text = null; + if (this.z8.isPause()) { + this.mnuPause.setText(TEXT_GO_ON); + this.mnuPause.setEnabled(true); + text = "Emulator angehalten"; + } else { + this.mnuPause.setText(TEXT_PAUSE); + this.mnuPause.setEnabled(true); + Double mhz = this.z8.getEmulatedMHz(); + int millis = STATUS_REFRESH_MILLIS; + if (this.z8.getCyclesPerSecond() > 0) { + if (mhz != null) { + if ((mhz.doubleValue() >= 3.8) + && (mhz.doubleValue() <= 4.2)) { + mhz = null; + } else { + millis = STATUS_REFRESH_MILLIS; + } + } + } else { + millis = STATUS_REFRESH_MILLIS; + } + if (mhz != null) { + text = JTCUtil.getEmulatedSpeedText(mhz.doubleValue()); + } + this.statusRefreshTimer.setDelay(millis); + this.statusRefreshTimer.setInitialDelay(millis); + this.statusRefreshTimer.start(); + } + this.fldStatusText.setText(text != null ? text : DEFAULT_STATUS_TEXT); + } + + + private void z8UpdateInternal(Z8Listener.Reason reason) { + switch (reason) { + case POWER_ON: + case RESET: + AudioFrm.reset(); + KeyboardFrm.reset(); + MemEditFrm.reset(); + ReassFrm.reset(); + break; + + case CYCLES_PER_SECOND_CHANGED: + if (this.z8.getCyclesPerSecond() > 0) { + this.mnuSpeed.setText(TEXT_MAX_SPEED); + } else { + this.mnuSpeed.setText(TEXT_NORM_SPEED); + } + AudioFrm.z8CyclesPerSecondChanged(); + updStatusText(); + break; + + case STATUS_CHANGED: + updStatusText(); + DebugFrm.z8StatusChanged(); + break; + } } - } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/FindAndReplaceDlg.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/FindAndReplaceDlg.java index dc1d239..ccdf6ae 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/FindAndReplaceDlg.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/FindAndReplaceDlg.java @@ -1,9 +1,10 @@ /* - * (c) 2019 Jens Mueller + * (c) 2007-2019 Jens Mueller + * (c) 2017 Lars Sonchocky-Helldorf * * Jugend+Technik-Computer-Emulator * - * Dialog zur Eingabe eines Suchtextes + * Dialog fuer Suchen & Ersetzen */ package org.jens_mueller.jtcemu.platform.se.tools; diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/ReassFrm.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/ReassFrm.java index 2ce6ff1..0de545e 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/ReassFrm.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/ReassFrm.java @@ -34,537 +34,500 @@ public class ReassFrm extends AbstractTextFrm implements - ActionListener, - CaretListener -{ - private static final String FILE_GROUP_REASS = "reass"; - private static final String FILE_GROUP_SOURCE = "reass_to_source"; - private static final String LABEL_BEG_ADDR = "Anfangsadresse:"; - private static final String LABEL_END_ADDR = "Endadresse:"; - - private static ReassFrm instance = null; - private static Point lastLocation = null; - - private Z8Reassembler z8Reass; - private TextFinder textFinder; - private File file; - private File sourceFile; - private String labelPrefix; - private JTextComponent selectionFld; - private int begAddr; - private int endAddr; - private JButton btnReassemble; - private JMenuItem mnuReassemble; - private JMenuItem mnuSaveAs; - private JMenuItem mnuSourceCopy; - private JMenuItem mnuSourceSaveAs; - private JMenuItem mnuPrintOptions; - private JMenuItem mnuPrint; - private JMenuItem mnuClose; - private JMenuItem mnuCopy; - private JMenuItem mnuFind; - private JMenuItem mnuFindNext; - private JMenuItem mnuFindPrev; - private JMenuItem mnuSelectAll; - private JMenuItem mnuHelpContent; - private JTextField fldBegAddr; - private JTextField fldEndAddr; - - - public static void close() - { - if( instance != null ) - instance.doClose(); - } - - - public static void open( Z8Memory memory ) - { - if( instance == null ) { - instance = new ReassFrm( memory ); - if( lastLocation != null ) { - instance.setLocation( lastLocation ); - } - instance.setVisible( true ); + ActionListener, + CaretListener { + private static final String FILE_GROUP_REASS = "reass"; + private static final String FILE_GROUP_SOURCE = "reass_to_source"; + private static final String LABEL_BEG_ADDR = "Anfangsadresse:"; + private static final String LABEL_END_ADDR = "Endadresse:"; + + private static ReassFrm instance = null; + private static Point lastLocation = null; + + private Z8Reassembler z8Reass; + private TextFinder textFinder; + private File file; + private File sourceFile; + private String labelPrefix; + private JTextComponent selectionFld; + private int begAddr; + private int endAddr; + private JButton btnReassemble; + private JMenuItem mnuReassemble; + private JMenuItem mnuSaveAs; + private JMenuItem mnuSourceCopy; + private JMenuItem mnuSourceSaveAs; + private JMenuItem mnuPrintOptions; + private JMenuItem mnuPrint; + private JMenuItem mnuClose; + private JMenuItem mnuCopy; + private JMenuItem mnuFind; + private JMenuItem mnuFindNext; + private JMenuItem mnuFindPrev; + private JMenuItem mnuSelectAll; + private JMenuItem mnuHelpContent; + private JTextField fldBegAddr; + private JTextField fldEndAddr; + + + public static void close() { + if (instance != null) + instance.doClose(); } - GUIUtil.toFront( instance ); - } - - - public static void reset() - { - if( instance != null ) - instance.updView(); - } - - - /* --- ActionListener --- */ - - @Override - public void actionPerformed( ActionEvent e ) - { - Object src = e.getSource(); - if( src != null ) { - if( src == this.fldBegAddr ) { - this.fldEndAddr.requestFocus(); - } - else if( (src == this.fldEndAddr) - || (src == this.btnReassemble) - || (src == this.mnuReassemble) ) - { - doReassemble(); - } - else if( src == this.mnuSaveAs ) { - doSaveAs(); - } - else if( src == this.mnuSourceCopy ) { - doSourceCopy(); - } - else if( src == this.mnuSourceSaveAs ) { - doSourceSaveAs(); - } - else if( src == this.mnuPrintOptions ) { - PrintOptionsDlg.open( this ); - } - else if( src == this.mnuPrint ) { - doPrint(); - } - else if( src == this.mnuClose ) { - doClose(); - } - else if( src == this.mnuCopy ) { - if( this.selectionFld != null ){ - this.selectionFld.copy(); - } - } - else if( src == this.mnuFind ) { - doFind(); - } - else if( src == this.mnuFindNext ) { - doFindNext(); - } - else if( src == this.mnuFindPrev ) { - doFindPrev(); - } - else if( src == this.mnuSelectAll ) { - this.textArea.requestFocus(); - this.textArea.selectAll(); - } - else if( src == this.mnuHelpContent ) { - HelpFrm.open( "/help/common/reassembler.htm" ); - } + + + public static void open(Z8Memory memory) { + if (instance == null) { + instance = new ReassFrm(memory); + if (lastLocation != null) { + instance.setLocation(lastLocation); + } + instance.setVisible(true); + } + GUIUtil.toFront(instance); + } + + + public static void reset() { + if (instance != null) + instance.updView(); } - } - - - /* --- CaretListener --- */ - - @Override - public void caretUpdate( CaretEvent e ) - { - Object src = e.getSource(); - if( src != null ) { - if( src instanceof JTextComponent ) { - this.selectionFld = (JTextComponent) src; - int begPos = this.selectionFld.getSelectionStart(); - this.mnuCopy.setEnabled( (begPos >= 0) - && (begPos < this.selectionFld.getSelectionEnd()) ); - } + + + /* --- ActionListener --- */ + + @Override + public void actionPerformed(ActionEvent e) { + Object src = e.getSource(); + if (src != null) { + if (src == this.fldBegAddr) { + this.fldEndAddr.requestFocus(); + } else if ((src == this.fldEndAddr) + || (src == this.btnReassemble) + || (src == this.mnuReassemble)) { + doReassemble(); + } else if (src == this.mnuSaveAs) { + doSaveAs(); + } else if (src == this.mnuSourceCopy) { + doSourceCopy(); + } else if (src == this.mnuSourceSaveAs) { + doSourceSaveAs(); + } else if (src == this.mnuPrintOptions) { + PrintOptionsDlg.open(this); + } else if (src == this.mnuPrint) { + doPrint(); + } else if (src == this.mnuClose) { + doClose(); + } else if (src == this.mnuCopy) { + if (this.selectionFld != null) { + this.selectionFld.copy(); + } + } else if (src == this.mnuFind) { + doFind(); + } else if (src == this.mnuFindNext) { + doFindNext(); + } else if (src == this.mnuFindPrev) { + doFindPrev(); + } else if (src == this.mnuSelectAll) { + this.textArea.requestFocus(); + this.textArea.selectAll(); + } else if (src == this.mnuHelpContent) { + HelpFrm.open("/help/common/reassembler.htm"); + } + } } - } - /* --- ueberschriebene Methoden --- */ + /* --- CaretListener --- */ - @Override - protected boolean doClose() - { - boolean rv = super.doClose(); - if( rv ) { - lastLocation = getLocation(); - instance = null; + @Override + public void caretUpdate(CaretEvent e) { + Object src = e.getSource(); + if (src != null) { + if (src instanceof JTextComponent) { + this.selectionFld = (JTextComponent) src; + int begPos = this.selectionFld.getSelectionStart(); + this.mnuCopy.setEnabled((begPos >= 0) + && (begPos < this.selectionFld.getSelectionEnd())); + } + } } - return rv; - } - - - @Override - public String getPropPrefix() - { - return "reassembler."; - } - - - /* --- Konstruktor --- */ - - private ReassFrm( Z8Memory memory ) - { - setTitle( AppContext.getAppName() + " Reassembler" ); - this.z8Reass = new Z8Reassembler( memory ); - this.textFinder = new TextFinder(); - this.labelPrefix = "M_"; - this.file = null; - this.sourceFile = null; - this.selectionFld = null; - this.begAddr = -1; - this.endAddr = -1; - - - // Menu - JMenuBar mnuBar = new JMenuBar(); - setJMenuBar( mnuBar ); - - - // Menu Datei - JMenu mnuFile = new JMenu( "Datei" ); - mnuFile.setMnemonic( KeyEvent.VK_D ); - mnuBar.add( mnuFile ); - - this.mnuReassemble = new JMenuItem( "Reassemblieren" ); - this.mnuReassemble.setAccelerator( getMenuShortcut( KeyEvent.VK_R ) ); - this.mnuReassemble.addActionListener( this ); - mnuFile.add( this.mnuReassemble ); - - this.mnuSaveAs = new JMenuItem( "Speichern unter..." ); - this.mnuSaveAs.setAccelerator( - getMenuShortcutWithShift( KeyEvent.VK_S ) ); - this.mnuSaveAs.setEnabled( false ); - this.mnuSaveAs.addActionListener( this ); - mnuFile.add( this.mnuSaveAs ); - mnuFile.addSeparator(); - - JMenu mnuSource = new JMenu( "Als Assembler-Quelltext" ); - mnuFile.add( mnuSource ); - - this.mnuSourceCopy = new JMenuItem( "kopieren" ); - this.mnuSourceCopy.setEnabled( false ); - this.mnuSourceCopy.addActionListener( this ); - mnuSource.add( this.mnuSourceCopy ); - - this.mnuSourceSaveAs = new JMenuItem( "speichern unter..." ); - this.mnuSourceSaveAs.setEnabled( false ); - this.mnuSourceSaveAs.addActionListener( this ); - mnuSource.add( this.mnuSourceSaveAs ); - - this.mnuPrintOptions = new JMenuItem( "Druckoptionen..." ); - this.mnuPrintOptions.addActionListener( this ); - mnuFile.add( this.mnuPrintOptions ); - - this.mnuPrint = new JMenuItem( "Drucken..." ); - this.mnuPrint.setAccelerator( getMenuShortcut( KeyEvent.VK_P ) ); - this.mnuPrint.setEnabled( false ); - this.mnuPrint.addActionListener( this ); - mnuFile.add( this.mnuPrint ); - mnuFile.addSeparator(); - - this.mnuClose = new JMenuItem( "Schlie\u00DFen" ); - this.mnuClose.addActionListener( this ); - mnuFile.add( this.mnuClose ); - - - // Menu Bearbeiten - JMenu mnuEdit = new JMenu( "Bearbeiten" ); - mnuEdit.setMnemonic( KeyEvent.VK_B ); - mnuBar.add( mnuEdit ); - - this.mnuCopy = new JMenuItem( "Kopieren" ); - this.mnuCopy.setAccelerator( getMenuShortcut( KeyEvent.VK_C ) ); - this.mnuCopy.setEnabled( false ); - this.mnuCopy.addActionListener( this ); - mnuEdit.add( this.mnuCopy ); - mnuEdit.addSeparator(); - - this.mnuFind = new JMenuItem( "Suchen..." ); - this.mnuFind.setAccelerator( getMenuShortcut( KeyEvent.VK_F ) ); - this.mnuFind.setEnabled( false ); - this.mnuFind.addActionListener( this ); - mnuEdit.add( this.mnuFind ); - - this.mnuFindNext = new JMenuItem( "Weitersuchen" ); - this.mnuFindNext.setAccelerator( - KeyStroke.getKeyStroke( KeyEvent.VK_F3, 0 ) ); - this.mnuFindNext.setEnabled( false ); - this.mnuFindNext.addActionListener( this ); - mnuEdit.add( this.mnuFindNext ); - - this.mnuFindPrev = new JMenuItem( "R\u00FCckw\u00E4rts suchen" ); - this.mnuFindPrev.setAccelerator( - KeyStroke.getKeyStroke( - KeyEvent.VK_F3, - InputEvent.SHIFT_DOWN_MASK ) ); - this.mnuFindPrev.setEnabled( false ); - this.mnuFindPrev.addActionListener( this ); - mnuEdit.add( this.mnuFindPrev ); - mnuEdit.addSeparator(); - - this.mnuSelectAll = new JMenuItem( "Alles ausw\u00E4hlen" ); - this.mnuSelectAll.setEnabled( false ); - this.mnuSelectAll.addActionListener( this ); - mnuEdit.add( this.mnuSelectAll ); - - - // Menu Hilfe - JMenu mnuHelp = new JMenu( "Hilfe" ); - mnuHelp.setMnemonic( KeyEvent.VK_H ); - mnuBar.add( mnuHelp ); - - this.mnuHelpContent = new JMenuItem( "Hilfe zum Reassembler..." ); - this.mnuHelpContent.addActionListener( this ); - mnuHelp.add( this.mnuHelpContent ); - - - // Fensterinhalt - setLayout( new BorderLayout() ); - - - // Kopfbereich - JPanel panelHead = new JPanel( new GridBagLayout() ); - add( panelHead, BorderLayout.NORTH ); - - GridBagConstraints gbcHead = new GridBagConstraints( - 0, 0, - 1, 1, - 0.0, 0.0, - GridBagConstraints.WEST, - GridBagConstraints.NONE, - new Insets( 5, 5, 5, 5 ), - 0, 0 ); - - panelHead.add( new JLabel( LABEL_BEG_ADDR ), gbcHead ); - - this.fldBegAddr = new JTextField( 4 ); - this.fldBegAddr.addActionListener( this ); - this.fldBegAddr.addCaretListener( this ); - gbcHead.fill = GridBagConstraints.HORIZONTAL; - gbcHead.weightx = 0.5; - gbcHead.gridx++; - panelHead.add( this.fldBegAddr, gbcHead ); - - gbcHead.fill = GridBagConstraints.NONE; - gbcHead.weightx = 0.0; - gbcHead.gridx++; - panelHead.add( new JLabel( LABEL_END_ADDR ), gbcHead ); - - this.fldEndAddr = new JTextField( 4 ); - this.fldEndAddr.addActionListener( this ); - this.fldEndAddr.addCaretListener( this ); - gbcHead.fill = GridBagConstraints.HORIZONTAL; - gbcHead.weightx = 0.5; - gbcHead.gridx++; - panelHead.add( this.fldEndAddr, gbcHead ); - - this.btnReassemble = GUIUtil.createImageButton( - this, - "/images/file/reload.png", - "Reassemblieren" ); - gbcHead.fill = GridBagConstraints.NONE; - gbcHead.weightx = 0.0; - gbcHead.gridx++; - panelHead.add( this.btnReassemble, gbcHead ); - - - // Ergebnisbereich - this.textArea.setColumns( 40 ); - this.textArea.setRows( 20 ); - this.textArea.setEditable( false ); - this.textArea.setMargin( new Insets( 5, 5, 5, 5 ) ); - this.textArea.addCaretListener( this ); - add( new JScrollPane( this.textArea ), BorderLayout.CENTER ); - - - // sonstiges - setResizable( true ); - if( !GUIUtil.applyWindowSettings( this ) ) { - pack(); - setLocationByPlatform( true ); - this.fldBegAddr.setColumns( 0 ); - this.fldEndAddr.setColumns( 0 ); - this.textArea.setColumns( 0 ); - this.textArea.setRows( 0 ); + + + /* --- ueberschriebene Methoden --- */ + + @Override + protected boolean doClose() { + boolean rv = super.doClose(); + if (rv) { + lastLocation = getLocation(); + instance = null; + } + return rv; } - } - /* --- Aktionen --- */ + @Override + public String getPropPrefix() { + return "reassembler."; + } + - private void doFind() - { - this.textFinder.openFindDlg( this.textArea ); - if( textFinder.hasSearchText() ) { - this.mnuFindPrev.setEnabled( true ); - this.mnuFindNext.setEnabled( true ); + /* --- Konstruktor --- */ + + private ReassFrm(Z8Memory memory) { + setTitle(AppContext.getAppName() + " Reassembler"); + this.z8Reass = new Z8Reassembler(memory); + this.textFinder = new TextFinder(); + this.labelPrefix = "M_"; + this.file = null; + this.sourceFile = null; + this.selectionFld = null; + this.begAddr = -1; + this.endAddr = -1; + + + // Menu + JMenuBar mnuBar = new JMenuBar(); + setJMenuBar(mnuBar); + + + // Menu Datei + JMenu mnuFile = new JMenu("Datei"); + mnuFile.setMnemonic(KeyEvent.VK_D); + mnuBar.add(mnuFile); + + this.mnuReassemble = new JMenuItem("Reassemblieren"); + this.mnuReassemble.setAccelerator(getMenuShortcut(KeyEvent.VK_R)); + this.mnuReassemble.addActionListener(this); + mnuFile.add(this.mnuReassemble); + + this.mnuSaveAs = new JMenuItem("Speichern unter..."); + this.mnuSaveAs.setAccelerator( + getMenuShortcutWithShift(KeyEvent.VK_S)); + this.mnuSaveAs.setEnabled(false); + this.mnuSaveAs.addActionListener(this); + mnuFile.add(this.mnuSaveAs); + mnuFile.addSeparator(); + + JMenu mnuSource = new JMenu("Als Assembler-Quelltext"); + mnuFile.add(mnuSource); + + this.mnuSourceCopy = new JMenuItem("kopieren"); + this.mnuSourceCopy.setEnabled(false); + this.mnuSourceCopy.addActionListener(this); + mnuSource.add(this.mnuSourceCopy); + + this.mnuSourceSaveAs = new JMenuItem("speichern unter..."); + this.mnuSourceSaveAs.setEnabled(false); + this.mnuSourceSaveAs.addActionListener(this); + mnuSource.add(this.mnuSourceSaveAs); + + this.mnuPrintOptions = new JMenuItem("Druckoptionen..."); + this.mnuPrintOptions.addActionListener(this); + mnuFile.add(this.mnuPrintOptions); + + this.mnuPrint = new JMenuItem("Drucken..."); + this.mnuPrint.setAccelerator(getMenuShortcut(KeyEvent.VK_P)); + this.mnuPrint.setEnabled(false); + this.mnuPrint.addActionListener(this); + mnuFile.add(this.mnuPrint); + mnuFile.addSeparator(); + + this.mnuClose = new JMenuItem("Schlie\u00DFen"); + this.mnuClose.addActionListener(this); + mnuFile.add(this.mnuClose); + + + // Menu Bearbeiten + JMenu mnuEdit = new JMenu("Bearbeiten"); + mnuEdit.setMnemonic(KeyEvent.VK_B); + mnuBar.add(mnuEdit); + + this.mnuCopy = new JMenuItem("Kopieren"); + this.mnuCopy.setAccelerator(getMenuShortcut(KeyEvent.VK_C)); + this.mnuCopy.setEnabled(false); + this.mnuCopy.addActionListener(this); + mnuEdit.add(this.mnuCopy); + mnuEdit.addSeparator(); + + this.mnuFind = new JMenuItem("Suchen..."); + this.mnuFind.setAccelerator(getMenuShortcut(KeyEvent.VK_F)); + this.mnuFind.setEnabled(false); + this.mnuFind.addActionListener(this); + mnuEdit.add(this.mnuFind); + + this.mnuFindNext = new JMenuItem("Weitersuchen"); + this.mnuFindNext.setAccelerator( + KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0)); + this.mnuFindNext.setEnabled(false); + this.mnuFindNext.addActionListener(this); + mnuEdit.add(this.mnuFindNext); + + this.mnuFindPrev = new JMenuItem("R\u00FCckw\u00E4rts suchen"); + this.mnuFindPrev.setAccelerator( + KeyStroke.getKeyStroke( + KeyEvent.VK_F3, + InputEvent.SHIFT_DOWN_MASK)); + this.mnuFindPrev.setEnabled(false); + this.mnuFindPrev.addActionListener(this); + mnuEdit.add(this.mnuFindPrev); + mnuEdit.addSeparator(); + + this.mnuSelectAll = new JMenuItem("Alles ausw\u00E4hlen"); + this.mnuSelectAll.setEnabled(false); + this.mnuSelectAll.addActionListener(this); + mnuEdit.add(this.mnuSelectAll); + + + // Menu Hilfe + JMenu mnuHelp = new JMenu("Hilfe"); + mnuHelp.setMnemonic(KeyEvent.VK_H); + mnuBar.add(mnuHelp); + + this.mnuHelpContent = new JMenuItem("Hilfe zum Reassembler..."); + this.mnuHelpContent.addActionListener(this); + mnuHelp.add(this.mnuHelpContent); + + + // Fensterinhalt + setLayout(new BorderLayout()); + + + // Kopfbereich + JPanel panelHead = new JPanel(new GridBagLayout()); + add(panelHead, BorderLayout.NORTH); + + GridBagConstraints gbcHead = new GridBagConstraints( + 0, 0, + 1, 1, + 0.0, 0.0, + GridBagConstraints.WEST, + GridBagConstraints.NONE, + new Insets(5, 5, 5, 5), + 0, 0); + + panelHead.add(new JLabel(LABEL_BEG_ADDR), gbcHead); + + this.fldBegAddr = new JTextField(4); + this.fldBegAddr.addActionListener(this); + this.fldBegAddr.addCaretListener(this); + gbcHead.fill = GridBagConstraints.HORIZONTAL; + gbcHead.weightx = 0.5; + gbcHead.gridx++; + panelHead.add(this.fldBegAddr, gbcHead); + + gbcHead.fill = GridBagConstraints.NONE; + gbcHead.weightx = 0.0; + gbcHead.gridx++; + panelHead.add(new JLabel(LABEL_END_ADDR), gbcHead); + + this.fldEndAddr = new JTextField(4); + this.fldEndAddr.addActionListener(this); + this.fldEndAddr.addCaretListener(this); + gbcHead.fill = GridBagConstraints.HORIZONTAL; + gbcHead.weightx = 0.5; + gbcHead.gridx++; + panelHead.add(this.fldEndAddr, gbcHead); + + this.btnReassemble = GUIUtil.createImageButton( + this, + "/images/file/reload.png", + "Reassemblieren"); + gbcHead.fill = GridBagConstraints.NONE; + gbcHead.weightx = 0.0; + gbcHead.gridx++; + panelHead.add(this.btnReassemble, gbcHead); + + + // Ergebnisbereich + this.textArea.setColumns(40); + this.textArea.setRows(20); + this.textArea.setEditable(false); + this.textArea.setMargin(new Insets(5, 5, 5, 5)); + this.textArea.addCaretListener(this); + add(new JScrollPane(this.textArea), BorderLayout.CENTER); + + + // sonstiges + setResizable(true); + if (!GUIUtil.applyWindowSettings(this)) { + pack(); + setLocationByPlatform(true); + this.fldBegAddr.setColumns(0); + this.fldEndAddr.setColumns(0); + this.textArea.setColumns(0); + this.textArea.setRows(0); + } } - } - private void doFindNext() - { - this.textFinder.findNext( this.textArea ); - } + /* --- Aktionen --- */ + + private void doFind() { + this.textFinder.openFindDlg(this.textArea); + if (textFinder.hasSearchText()) { + this.mnuFindPrev.setEnabled(true); + this.mnuFindNext.setEnabled(true); + } + } - private void doFindPrev() - { - this.textFinder.findPrev( this.textArea ); - } + private void doFindNext() { + this.textFinder.findNext(this.textArea); + } - private void doReassemble() - { - try { - this.begAddr = GUIUtil.parseHex4( this.fldBegAddr, LABEL_BEG_ADDR ); - this.endAddr = GUIUtil.parseHex4( this.fldEndAddr, LABEL_END_ADDR ); - if( this.endAddr < this.begAddr ) { - throw new UserInputException( - "Endadresse ist kleiner als Anfangsadresse." ); - } - updView(); + private void doFindPrev() { + this.textFinder.findPrev(this.textArea); } - catch( UserInputException ex ) { - JOptionPane.showMessageDialog( - this, - ex.getMessage(), - "Eingabefehler", - JOptionPane.ERROR_MESSAGE ); + + + private void doReassemble() { + try { + this.begAddr = GUIUtil.parseHex4(this.fldBegAddr, LABEL_BEG_ADDR); + this.endAddr = GUIUtil.parseHex4(this.fldEndAddr, LABEL_END_ADDR); + if (this.endAddr < this.begAddr) { + throw new UserInputException( + "Endadresse ist kleiner als Anfangsadresse."); + } + updView(); + } catch (UserInputException ex) { + JOptionPane.showMessageDialog( + this, + ex.getMessage(), + "Eingabefehler", + JOptionPane.ERROR_MESSAGE); + } } - } - - - private void doSaveAs() - { - saveTextFileAs( - this.textArea.getText(), - "Textdatei speichern", - this.file, - FILE_GROUP_REASS, - GUIUtil.textFileFilter ); - } - - - private void doSourceCopy() - { - String sourceText = createSourceText(); - if( sourceText != null ) { - if( !GUIUtil.copyToClipboard( this, sourceText ) ) { - Main.showError( - this, - "Der erzeugte Assembler-Quelltext konnte nicht\n" - + "in die Zwischenablage kopiert werden." ); - } + + + private void doSaveAs() { + saveTextFileAs( + this.textArea.getText(), + "Textdatei speichern", + this.file, + FILE_GROUP_REASS, + GUIUtil.textFileFilter); } - } - - - private void doSourceSaveAs() - { - saveTextFileAs( - createSourceText(), - "Assembler-Quelltext speichern", - this.sourceFile, - FILE_GROUP_SOURCE, - GUIUtil.asmFileFilter ); - } - - - /* --- private Methoden --- */ - - private String createSourceText() - { - String text = null; - if( (this.z8Reass != null) - && (this.begAddr >= 0) && (this.begAddr < this.endAddr) ) - { - String labelPrefix = JOptionPane.showInputDialog( - this, - "Prefix f\u00FCr Marken:", - this.labelPrefix ); - if( labelPrefix != null ) { - boolean prefixOK = false; - int len = labelPrefix.length(); - if( len > 0 ) { - prefixOK = AsmUtil.isIdentifierStart( labelPrefix.charAt( 0 ) ); - for( int i = 1; i < len; i++ ) { - prefixOK &= AsmUtil.isIdentifierPart( labelPrefix.charAt( i ) ); - } - } - if( prefixOK ) { - this.labelPrefix = labelPrefix; - text = this.z8Reass.reassembleToSource( - this.begAddr, - this.endAddr, - labelPrefix ); - } else { - BaseDlg.showError( - this, - "Der Pr\u00E4fix entspricht nicht den Namenskonventionen" - + " f\u00FCr Assembler-Marken." ); - } - } + + + private void doSourceCopy() { + String sourceText = createSourceText(); + if (sourceText != null) { + if (!GUIUtil.copyToClipboard(this, sourceText)) { + Main.showError( + this, + "Der erzeugte Assembler-Quelltext konnte nicht\n" + + "in die Zwischenablage kopiert werden."); + } + } } - return text; - } - - - private void saveTextFileAs( - String text, - String title, - File oldFile, - String fileGroup, - FileFilter... fileFilters ) - { - if( text != null ) { - File file = FileDlg.showFileSaveDlg( - this, - title, - oldFile != null ? - oldFile - : AppContext.getLastDirFile( fileGroup ), - GUIUtil.asmFileFilter ); - if( file != null ) { - try { - BufferedWriter out = null; - try { - out = new BufferedWriter( new FileWriter( file ) ); - int len = text.length(); - for( int i = 0; i < len; i++ ) { - char ch = text.charAt( i ); - if( ch == '\n' ) { - out.newLine(); - } else { - out.write( ch ); - } - } - out.close(); - out = null; - this.sourceFile = file; - AppContext.setLastFile( FILE_GROUP_SOURCE, file ); - } - finally { - JTCUtil.closeSilently( out ); - } - } - catch( IOException ex ) { - Main.showError( this, ex ); - } - } + + + private void doSourceSaveAs() { + saveTextFileAs( + createSourceText(), + "Assembler-Quelltext speichern", + this.sourceFile, + FILE_GROUP_SOURCE, + GUIUtil.asmFileFilter); } - } - - - private void updView() - { - if( (this.begAddr >= 0) && (this.begAddr <= this.endAddr) ) { - String text = this.z8Reass.reassemble( this.begAddr, this.endAddr ); - setText( text ); - this.textArea.requestFocus(); - if( !text.isEmpty() ) { - this.mnuSaveAs.setEnabled( true ); - this.mnuSourceCopy.setEnabled( true ); - this.mnuSourceSaveAs.setEnabled( true ); - this.mnuPrint.setEnabled( true ); - this.mnuFind.setEnabled( true ); - this.mnuSelectAll.setEnabled( true ); - } + + + /* --- private Methoden --- */ + + private String createSourceText() { + String text = null; + if ((this.z8Reass != null) + && (this.begAddr >= 0) && (this.begAddr < this.endAddr)) { + String labelPrefix = JOptionPane.showInputDialog( + this, + "Prefix f\u00FCr Marken:", + this.labelPrefix); + if (labelPrefix != null) { + boolean prefixOK = false; + int len = labelPrefix.length(); + if (len > 0) { + prefixOK = AsmUtil.isIdentifierStart(labelPrefix.charAt(0)); + for (int i = 1; i < len; i++) { + prefixOK &= AsmUtil.isIdentifierPart(labelPrefix.charAt(i)); + } + } + if (prefixOK) { + this.labelPrefix = labelPrefix; + text = this.z8Reass.reassembleToSource( + this.begAddr, + this.endAddr, + labelPrefix); + } else { + BaseDlg.showError( + this, + "Der Pr\u00E4fix entspricht nicht den Namenskonventionen" + + " f\u00FCr Assembler-Marken."); + } + } + } + return text; + } + + + private void saveTextFileAs( + String text, + String title, + File oldFile, + String fileGroup, + FileFilter... fileFilters) { + if (text != null) { + File file = FileDlg.showFileSaveDlg( + this, + title, + oldFile != null ? + oldFile + : AppContext.getLastDirFile(fileGroup), + GUIUtil.asmFileFilter); + if (file != null) { + try { + BufferedWriter out = null; + try { + out = new BufferedWriter(new FileWriter(file)); + int len = text.length(); + for (int i = 0; i < len; i++) { + char ch = text.charAt(i); + if (ch == '\n') { + out.newLine(); + } else { + out.write(ch); + } + } + out.close(); + out = null; + this.sourceFile = file; + AppContext.setLastFile(FILE_GROUP_SOURCE, file); + } finally { + JTCUtil.closeSilently(out); + } + } catch (IOException ex) { + Main.showError(this, ex); + } + } + } + } + + + private void updView() { + if ((this.begAddr >= 0) && (this.begAddr <= this.endAddr)) { + String text = this.z8Reass.reassemble(this.begAddr, this.endAddr); + setText(text); + this.textArea.requestFocus(); + if (!text.isEmpty()) { + this.mnuSaveAs.setEnabled(true); + this.mnuSourceCopy.setEnabled(true); + this.mnuSourceSaveAs.setEnabled(true); + this.mnuPrint.setEnabled(true); + this.mnuFind.setEnabled(true); + this.mnuSelectAll.setEnabled(true); + } + } } - } } diff --git a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/TextEditFrm.java b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/TextEditFrm.java index 1cadf8c..6aa5fc4 100644 --- a/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/TextEditFrm.java +++ b/JTCEMU/src/main/java/org/jens_mueller/jtcemu/platform/se/tools/TextEditFrm.java @@ -1,12 +1,12 @@ /* * (c) 2007-2021 Jens Mueller * - * Jugend+Technik-Computer-Emulator + * Jugend+Technik-Computer-Emulator * - * Texteditor + * Texteditor */ -package org.jens_mueller.jtcemu.platform.se.tools; + package org.jens_mueller.jtcemu.platform.se.tools; import org.jens_mueller.jtcemu.base.AppContext; import org.jens_mueller.jtcemu.base.JTCSys; @@ -42,17 +42,17 @@ import java.util.Properties; -public class TextEditFrm extends AbstractTextFrm - implements - ActionListener, - CaretListener, - DocumentListener, - DropTargetListener, - FlavorListener, - FocusListener, - MouseListener, - UndoableEditListener -{ + public class TextEditFrm extends AbstractTextFrm + implements + ActionListener, + CaretListener, + DocumentListener, + DropTargetListener, + FlavorListener, + FocusListener, + MouseListener, + UndoableEditListener + { private static final String FILE_GROUP_TEXT = "text"; private static final String FILE_GROUP_PROJECT = "project"; private static final String LABEL_BEG_ADDR_OF_BASIC_PRG = diff --git a/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/ExtROM.java b/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/ExtROM.java index 05c8da9..2647178 100644 --- a/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/ExtROM.java +++ b/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/ExtROM.java @@ -12,149 +12,137 @@ import java.io.IOException; -public class ExtROM implements Comparable -{ - private int begAddr; - private int endAddr; - private int maxSize; - private File file; - private byte[] fileBytes; - private String text; - - - public ExtROM( File file, int maxSize ) throws IOException - { - this.maxSize = maxSize; - this.file = file; - this.fileBytes = null; - this.begAddr = 0; - this.endAddr = 0; - this.text = "%0000 " + this.file.getPath(); - reload(); - } - - - public synchronized int getBegAddr() - { - return this.begAddr; - } - - - public synchronized int getEndAddr() - { - return this.endAddr; - } - - - public synchronized int getByte( int addr ) - { - int rv = 0; - if( this.fileBytes != null ) { - int idx = addr - this.begAddr; - if( (idx >= 0) && (idx < this.fileBytes.length) ) { - rv = (int) this.fileBytes[ idx ] & 0xFF; - } +public class ExtROM implements Comparable { + private int begAddr; + private int endAddr; + private int maxSize; + private File file; + private byte[] fileBytes; + private String text; + + + public ExtROM(File file, int maxSize) throws IOException { + this.maxSize = maxSize; + this.file = file; + this.fileBytes = null; + this.begAddr = 0; + this.endAddr = 0; + this.text = "%0000 " + this.file.getPath(); + reload(); } - return rv; - } - public File getFile() - { - return this.file; - } + public synchronized int getBegAddr() { + return this.begAddr; + } + + + public synchronized int getEndAddr() { + return this.endAddr; + } + + + public synchronized int getByte(int addr) { + int rv = 0; + if (this.fileBytes != null) { + int idx = addr - this.begAddr; + if ((idx >= 0) && (idx < this.fileBytes.length)) { + rv = (int) this.fileBytes[idx] & 0xFF; + } + } + return rv; + } + + + public File getFile() { + return this.file; + } - public void reload() throws IOException - { - byte[] fileBytes = JTCUtil.readFile( this.file, this.maxSize ); - if( fileBytes != null ) { - this.fileBytes = fileBytes; - this.endAddr = this.begAddr + this.fileBytes.length - 1; + public void reload() throws IOException { + byte[] fileBytes = JTCUtil.readFile(this.file, this.maxSize); + if (fileBytes != null) { + this.fileBytes = fileBytes; + this.endAddr = this.begAddr + this.fileBytes.length - 1; + } } - } - public synchronized void setBegAddr( int addr ) - { - this.begAddr = addr; - this.endAddr = 0; - if( this.fileBytes != null ) { - this.endAddr = this.begAddr + this.fileBytes.length - 1; + public synchronized void setBegAddr(int addr) { + this.begAddr = addr; + this.endAddr = 0; + if (this.fileBytes != null) { + this.endAddr = this.begAddr + this.fileBytes.length - 1; + } + this.text = String.format( + "%%%04X %s", + this.begAddr, + this.file.getPath()); } - this.text = String.format( - "%%%04X %s", - this.begAddr, - this.file.getPath() ); - } - - - public int size() - { - return this.fileBytes != null ? this.fileBytes.length : 0; - } - - - /* --- Comparable --- */ - - @Override - public int compareTo( ExtROM data ) - { - return data != null ? (this.begAddr - data.begAddr) : -1; - } - - - /* --- ueberschriebene Methoden --- */ - - @Override - public boolean equals( Object o ) - { - boolean rv = false; - if( o != null ) { - if( o == this ) { - rv = true; - } else { - if( o instanceof ExtROM ) { - rv = true; - ExtROM data = (ExtROM) o; - if( this.begAddr != data.getBegAddr() ) { - rv = false; - } else { - if( (this.fileBytes != null) && (data.fileBytes != null) ) { - if( this.fileBytes.length == data.fileBytes.length ) { - for( int i = 0; i < this.fileBytes.length; i++ ) { - if( this.fileBytes[ i ] != data.fileBytes[ i ] ) { - rv = false; - break; - } - } - } else { - rv = false; - } - } else { - int n1 = 0; - if( this.fileBytes != null ) { - n1 = this.fileBytes.length; - } - int n2 = 0; - if( data.fileBytes != null ) { - n2 = data.fileBytes.length; - } - if( n1 != n2 ) { - rv = false; - } - } - } - } - } + + + public int size() { + return this.fileBytes != null ? this.fileBytes.length : 0; + } + + + /* --- Comparable --- */ + + @Override + public int compareTo(ExtROM data) { + return data != null ? (this.begAddr - data.begAddr) : -1; } - return rv; - } - @Override - public String toString() - { - return this.text; - } + /* --- ueberschriebene Methoden --- */ + + @Override + public boolean equals(Object o) { + boolean rv = false; + if (o != null) { + if (o == this) { + rv = true; + } else { + if (o instanceof ExtROM) { + rv = true; + ExtROM data = (ExtROM) o; + if (this.begAddr != data.getBegAddr()) { + rv = false; + } else { + if ((this.fileBytes != null) && (data.fileBytes != null)) { + if (this.fileBytes.length == data.fileBytes.length) { + for (int i = 0; i < this.fileBytes.length; i++) { + if (this.fileBytes[i] != data.fileBytes[i]) { + rv = false; + break; + } + } + } else { + rv = false; + } + } else { + int n1 = 0; + if (this.fileBytes != null) { + n1 = this.fileBytes.length; + } + int n2 = 0; + if (data.fileBytes != null) { + n2 = data.fileBytes.length; + } + if (n1 != n2) { + rv = false; + } + } + } + } + } + } + return rv; + } + + + @Override + public String toString() { + return this.text; + } } \ No newline at end of file diff --git a/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/FileLoader.java b/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/FileLoader.java index 42702a8..46df14e 100644 --- a/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/FileLoader.java +++ b/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/FileLoader.java @@ -19,340 +19,326 @@ import java.io.Reader; -public class FileLoader -{ - public static final int DEFAULt_LOAD_ADDR = 0xE000; - - private Z8Memory memory; - private String msg; - private int lastLoadedAddr; - private boolean outOfRam; - - - public FileLoader( Z8Memory memory ) - { - this.memory = memory; - this.msg = null; - this.lastLoadedAddr = -1; - this.outOfRam = false; - } - - - public String getMessage() - { - return this.msg; - } - - - /* - * Die Methode laedt eine Datei in den Arbeitsspeicher. - * Im Erfolgsfall wird ein Infotext zurueckgeliefert. - */ - public String loadFile( - File file, - FileInfo.Format fmt, - int begAddr, - int endAddr, - int startAddr ) - { - String rv = null; - if( begAddr < 0 ) { - this.msg = "Die Datei konnte nicht geladen werden,\n" - + "da die Anfangsadresse nicht bekannt ist."; - } else if( (endAddr >= 0) && (endAddr < begAddr) ) { - this.msg = "Die Datei konnte nicht geladen werden,\n" - + "da die Endadresse kleiner als die" - + " Anfangsadresse ist."; - } else { - if( endAddr < 0 ) { - endAddr = 0xFFFF; - } - try { - if( (file != null) && (fmt != null) - && (begAddr >= 0) && (begAddr <= endAddr) ) - { - this.lastLoadedAddr = -1; - switch( fmt ) { - case JTC: - loadFileIntoMem( file, begAddr, endAddr, 128 ); - break; - - case TAP: - loadTapFileIntoMem( file, begAddr, endAddr ); - break; - - case BIN: - loadFileIntoMem( file, begAddr, endAddr, 0 ); - break; - - case HEX: - loadHexFileIntoMem( file, begAddr, endAddr ); - break; - } - if( this.lastLoadedAddr >= begAddr ) { - if( (startAddr >= 0) && (startAddr <= 0xFFFF) ) { - rv = String.format( - "Datei nach %%%04X-%%%04X geladen, Start: %%%04X", - begAddr, - this.lastLoadedAddr, - startAddr ); - } else { - rv = String.format( - "Datei nach %%%04X-%%%04X geladen", - begAddr, - this.lastLoadedAddr ); - } - } - } - if( this.outOfRam ) { - if( rv != null ) { - this.msg = "Die Datei konnte nur teilweise geladen werden,\n" - + "da entweder der betreffenden Adressbereich nicht" - + " vollst\u00E4ndig RAM ist\n" - + "oder versucht wurde, \u00FCber das Ende des Adressbereichs" - + " hinaus zu laden."; - } else { - this.msg = "Die Datei konnte nicht geladen werden,\n" - + "da der betreffende Adressbereich kein RAM ist."; - } - } - } - catch( IOException ex ) { - this.msg = ex.getMessage(); - rv = null; - } - } - return rv; - } - - - /* --- private Methoden --- */ - - private void loadFileIntoMem( - File file, - int addr, - int endAddr, - int bytesToSkip ) throws IOException - { - InputStream in = null; - try { - in = new FileInputStream( file ); - while( bytesToSkip > 0 ) { - if( in.read() < 0 ) { - break; - } - --bytesToSkip; - } - while( addr <= endAddr ) { - int b = in.read(); - if( b < 0 ) { - break; - } - setMemByte( addr++, b ); - } - } - finally { - JTCUtil.closeSilently( in ); +public class FileLoader { + public static final int DEFAULt_LOAD_ADDR = 0xE000; + + private Z8Memory memory; + private String msg; + private int lastLoadedAddr; + private boolean outOfRam; + + + public FileLoader(Z8Memory memory) { + this.memory = memory; + this.msg = null; + this.lastLoadedAddr = -1; + this.outOfRam = false; } - } - - - private void loadHexFileIntoMem( - File file, - int memAddr, - int memEndAddr ) throws IOException - { - boolean success = false; - Reader in = null; - try { - in = new BufferedReader( new FileReader( file ) ); - - boolean firstAddr = true; - boolean enabled = true; - boolean cancelled = false; - boolean outOfRange = false; - int memOffs = 0; - int ch = in.read(); - while( enabled && (ch != -1) ) { - - // Startmarkierung suchen - while( (ch >= 0) && (ch != ':') ) { - ch = in.read(); - } - if( ch >= 0 ) { - - // Segment verarbeiten - int cnt = parseHex( in, 2 ); - int addr = parseHex( in, 4 ); - int type = parseHex( in, 2 ); - switch( type ) { - case 0: // Data Record - if( cnt > 0 ) { - if( firstAddr ) { - firstAddr = false; - memOffs = memAddr - addr; - } - int dstAddr = addr + memOffs; - while( cnt > 0 ) { - if( (dstAddr >= memAddr) && (dstAddr <= memEndAddr) ) { - success |= setMemByte( dstAddr++, parseHex( in, 2 ) ); - } else { - outOfRange = true; - } - --cnt; - } - } - break; - - case 1: // End of File Record - enabled = false; - break; - - case 2: // Extended Segment Address Record - while( cnt > 0 ) { - if( parseHex( in, 2 ) != 0 ) { - this.msg = "Die Datei enth\u00E4lt einen Datensatz" - + " f\u00FCr eine segmentierte Adresse,\n" - + "der von " - + AppContext.getAppName() - + " nicht unterst\u00FCtzt wird."; - cancelled = true; - enabled = false; - break; - } - --cnt; - } - break; - - case 3: // Start Segment Address Record - case 5: // Start Linear Address Record - // Datensatz ignorieren - break; - - case 4: // Extended Linear Address Record - while( cnt > 0 ) { - if( parseHex( in, 2 ) != 0 ) { - this.msg = "Die Datei enth\u00E4lt einen Datensatz" - + " f\u00FCr eine lineare 32-Bit-Adresse,\n" - + "die au\u00DFerhalb des von " - + AppContext.getAppName() - + " emulierten Adressraums liegt."; - cancelled = true; - enabled = false; - break; - } - --cnt; - } - break; - - default: - this.msg = String.format( - "Die Datei enth\u00E4lt einen Datensatzart" - + " des Typs %d,\n" - + "der von " - + AppContext.getAppName() - + " nicht unterst\u00FCtzt wird.", - type ); - cancelled = true; - enabled = false; - } - if( this.msg != null ) { - if( success && cancelled ) { - this.msg = this.msg - + "\nEs werden nur die Daten bis zu diesem Datensatz" - + " geladen."; - } - enabled = false; - } - ch = in.read(); - } - } - if( outOfRange ) { - String msg2 = "Die Datei enth\u00E4lt Datens\u00E4tze" - + " mit Adressen, die entweder vor der\n" - + "Anfangsadresse oder hinter dem zu ladenden" - + " Adressbereich liegen.\n" - + "Diese Datens\u00E4tze werden ignoriert."; - if( this.msg != null ) { - this.msg = this.msg + "\n\n" + msg2; - } else { - this.msg = msg2; - } - } + + + public String getMessage() { + return this.msg; } - finally { - JTCUtil.closeSilently( in ); + + + /* + * Die Methode laedt eine Datei in den Arbeitsspeicher. + * Im Erfolgsfall wird ein Infotext zurueckgeliefert. + */ + public String loadFile( + File file, + FileInfo.Format fmt, + int begAddr, + int endAddr, + int startAddr) { + String rv = null; + if (begAddr < 0) { + this.msg = "Die Datei konnte nicht geladen werden,\n" + + "da die Anfangsadresse nicht bekannt ist."; + } else if ((endAddr >= 0) && (endAddr < begAddr)) { + this.msg = "Die Datei konnte nicht geladen werden,\n" + + "da die Endadresse kleiner als die" + + " Anfangsadresse ist."; + } else { + if (endAddr < 0) { + endAddr = 0xFFFF; + } + try { + if ((file != null) && (fmt != null) + && (begAddr >= 0) && (begAddr <= endAddr)) { + this.lastLoadedAddr = -1; + switch (fmt) { + case JTC: + loadFileIntoMem(file, begAddr, endAddr, 128); + break; + + case TAP: + loadTapFileIntoMem(file, begAddr, endAddr); + break; + + case BIN: + loadFileIntoMem(file, begAddr, endAddr, 0); + break; + + case HEX: + loadHexFileIntoMem(file, begAddr, endAddr); + break; + } + if (this.lastLoadedAddr >= begAddr) { + if ((startAddr >= 0) && (startAddr <= 0xFFFF)) { + rv = String.format( + "Datei nach %%%04X-%%%04X geladen, Start: %%%04X", + begAddr, + this.lastLoadedAddr, + startAddr); + } else { + rv = String.format( + "Datei nach %%%04X-%%%04X geladen", + begAddr, + this.lastLoadedAddr); + } + } + } + if (this.outOfRam) { + if (rv != null) { + this.msg = "Die Datei konnte nur teilweise geladen werden,\n" + + "da entweder der betreffenden Adressbereich nicht" + + " vollst\u00E4ndig RAM ist\n" + + "oder versucht wurde, \u00FCber das Ende des Adressbereichs" + + " hinaus zu laden."; + } else { + this.msg = "Die Datei konnte nicht geladen werden,\n" + + "da der betreffende Adressbereich kein RAM ist."; + } + } + } catch (IOException ex) { + this.msg = ex.getMessage(); + rv = null; + } + } + return rv; } - } - - - private void loadTapFileIntoMem( - File file, - int addr, - int endAddr ) throws IOException - { - InputStream in = null; - try { - in = new FileInputStream( file ); - for( int i = 0; i < 145; i++ ) { - if( in.read() < 0 ) { - break; - } - } - int posInBlk = 0; - while( addr <= endAddr ) { - int b = in.read(); - if( b < 0 ) { - break; - } - if( posInBlk == 0 ) { - posInBlk = 128; - } else { - setMemByte( addr++, b ); - --posInBlk; - } - } + + + /* --- private Methoden --- */ + + private void loadFileIntoMem( + File file, + int addr, + int endAddr, + int bytesToSkip) throws IOException { + InputStream in = null; + try { + in = new FileInputStream(file); + while (bytesToSkip > 0) { + if (in.read() < 0) { + break; + } + --bytesToSkip; + } + while (addr <= endAddr) { + int b = in.read(); + if (b < 0) { + break; + } + setMemByte(addr++, b); + } + } finally { + JTCUtil.closeSilently(in); + } } - finally { - JTCUtil.closeSilently( in ); + + + private void loadHexFileIntoMem( + File file, + int memAddr, + int memEndAddr) throws IOException { + boolean success = false; + Reader in = null; + try { + in = new BufferedReader(new FileReader(file)); + + boolean firstAddr = true; + boolean enabled = true; + boolean cancelled = false; + boolean outOfRange = false; + int memOffs = 0; + int ch = in.read(); + while (enabled && (ch != -1)) { + + // Startmarkierung suchen + while ((ch >= 0) && (ch != ':')) { + ch = in.read(); + } + if (ch >= 0) { + + // Segment verarbeiten + int cnt = parseHex(in, 2); + int addr = parseHex(in, 4); + int type = parseHex(in, 2); + switch (type) { + case 0: // Data Record + if (cnt > 0) { + if (firstAddr) { + firstAddr = false; + memOffs = memAddr - addr; + } + int dstAddr = addr + memOffs; + while (cnt > 0) { + if ((dstAddr >= memAddr) && (dstAddr <= memEndAddr)) { + success |= setMemByte(dstAddr++, parseHex(in, 2)); + } else { + outOfRange = true; + } + --cnt; + } + } + break; + + case 1: // End of File Record + enabled = false; + break; + + case 2: // Extended Segment Address Record + while (cnt > 0) { + if (parseHex(in, 2) != 0) { + this.msg = "Die Datei enth\u00E4lt einen Datensatz" + + " f\u00FCr eine segmentierte Adresse,\n" + + "der von " + + AppContext.getAppName() + + " nicht unterst\u00FCtzt wird."; + cancelled = true; + enabled = false; + break; + } + --cnt; + } + break; + + case 3: // Start Segment Address Record + case 5: // Start Linear Address Record + // Datensatz ignorieren + break; + + case 4: // Extended Linear Address Record + while (cnt > 0) { + if (parseHex(in, 2) != 0) { + this.msg = "Die Datei enth\u00E4lt einen Datensatz" + + " f\u00FCr eine lineare 32-Bit-Adresse,\n" + + "die au\u00DFerhalb des von " + + AppContext.getAppName() + + " emulierten Adressraums liegt."; + cancelled = true; + enabled = false; + break; + } + --cnt; + } + break; + + default: + this.msg = String.format( + "Die Datei enth\u00E4lt einen Datensatzart" + + " des Typs %d,\n" + + "der von " + + AppContext.getAppName() + + " nicht unterst\u00FCtzt wird.", + type); + cancelled = true; + enabled = false; + } + if (this.msg != null) { + if (success && cancelled) { + this.msg = this.msg + + "\nEs werden nur die Daten bis zu diesem Datensatz" + + " geladen."; + } + enabled = false; + } + ch = in.read(); + } + } + if (outOfRange) { + String msg2 = "Die Datei enth\u00E4lt Datens\u00E4tze" + + " mit Adressen, die entweder vor der\n" + + "Anfangsadresse oder hinter dem zu ladenden" + + " Adressbereich liegen.\n" + + "Diese Datens\u00E4tze werden ignoriert."; + if (this.msg != null) { + this.msg = this.msg + "\n\n" + msg2; + } else { + this.msg = msg2; + } + } + } finally { + JTCUtil.closeSilently(in); + } } - } - - - private static int parseHex( Reader in, int cnt ) throws IOException - { - int value = 0; - while( cnt > 0 ) { - int ch = in.read(); - if( (ch >= '0') && (ch <= '9') ) { - value = (value << 4) | ((ch - '0') & 0x0F); - } else if( (ch >= 'A') && (ch <= 'F') ) { - value = (value << 4) | ((ch - 'A' + 10) & 0x0F); - } else if( (ch >= 'a') && (ch <= 'f') ) { - value = (value << 4) | ((ch - 'a' + 10) & 0x0F); - } else { - throw new IOException( - "Die Datei entspricht nicht dem erwarteten HEX-Format." ); - } - --cnt; + + + private void loadTapFileIntoMem( + File file, + int addr, + int endAddr) throws IOException { + InputStream in = null; + try { + in = new FileInputStream(file); + for (int i = 0; i < 145; i++) { + if (in.read() < 0) { + break; + } + } + int posInBlk = 0; + while (addr <= endAddr) { + int b = in.read(); + if (b < 0) { + break; + } + if (posInBlk == 0) { + posInBlk = 128; + } else { + setMemByte(addr++, b); + --posInBlk; + } + } + } finally { + JTCUtil.closeSilently(in); + } } - return value; - } - private boolean setMemByte( int addr, int b ) - { - boolean done = false; - if( addr < 0x10000 ) { - done = this.memory.setMemByte( addr, false, b ); + private static int parseHex(Reader in, int cnt) throws IOException { + int value = 0; + while (cnt > 0) { + int ch = in.read(); + if ((ch >= '0') && (ch <= '9')) { + value = (value << 4) | ((ch - '0') & 0x0F); + } else if ((ch >= 'A') && (ch <= 'F')) { + value = (value << 4) | ((ch - 'A' + 10) & 0x0F); + } else if ((ch >= 'a') && (ch <= 'f')) { + value = (value << 4) | ((ch - 'a' + 10) & 0x0F); + } else { + throw new IOException( + "Die Datei entspricht nicht dem erwarteten HEX-Format."); + } + --cnt; + } + return value; } - if( done ) { - if( addr > this.lastLoadedAddr ) { - this.lastLoadedAddr = addr; - } - } else { - this.outOfRam = true; + + + private boolean setMemByte(int addr, int b) { + boolean done = false; + if (addr < 0x10000) { + done = this.memory.setMemByte(addr, false, b); + } + if (done) { + if (addr > this.lastLoadedAddr) { + this.lastLoadedAddr = addr; + } + } else { + this.outOfRam = true; + } + return done; } - return done; - } } diff --git a/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/JTCSys.java b/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/JTCSys.java index 4258a44..af7237d 100644 --- a/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/JTCSys.java +++ b/JTCEMUCommon/src/main/java/org/jens_mueller/jtcemu/base/JTCSys.java @@ -26,1749 +26,1664 @@ import java.util.Random; -public class JTCSys implements Z8IO, Z8Listener, Z8Memory -{ - public static final int DEFAULT_BASIC_ADDR = 0xE000; - public static final int DEFAULT_Z8_CYCLES_PER_SECOND = 4000000; // intern - public static final int MAX_ROM_SIZE = 0x10000; - public static final int MAX_ROMBANK_SIZE = 256 * 0x2000; - - public static final String PROP_Z8_REGS_80_TO_EF = "z8.regs80toEF"; - public static final String PROP_Z8_REG_INIT_ZERO = "z8.reg.init.zero"; - public static final String PROP_RAM_INIT_ZERO = "ram.init.zero"; - public static final String PROP_RAM_SIZE = "ram.size"; - public static final String PROP_ROM_PREFIX = "rom."; - public static final String PROP_ROM_COUNT = "rom.count"; - public static final String PROP_ROM_RELOAD = "rom.reload"; - public static final String PROP_ROMBANK_ENABLED = "rombank.enabled"; - public static final String PROP_ROMBANK_FILE = "rombank.file"; - public static final String PROP_OS = "os"; - public static final String VALUE_OS_2K = "2K"; - public static final String VALUE_OS_ES1988 = "ES1988"; - public static final String VALUE_OS_ES23 = "ES2.3"; - public static final String VALUE_OS_ES40 = "ES4.0"; - - public static final boolean DEFAULT_RAM_INIT_ZERO = true; - public static final boolean DEFAULT_Z8_REG_INIT_ZERO = true; - - public static enum OSType { OS2K, ES1988, ES23, ES40 }; - - public static enum Key { LEFT, RIGHT, UP, DOWN, BACK_SPACE, HOME, - SPACE, ENTER, ESCAPE, INSERT, DELETE, CLEAR, - F1, F2, F3, F4, F5, F6, F7, F8 }; - - private static final int[][] keyMatrix2kNormal = { - { 0, 0x20, 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', - 0x0D, 0x1B }, - { 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '*', '-' }, - { 0, 0x0B, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', '+' }, - { 0, 0x0A, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', - 0x08 } }; - - private static final int[][] keyMatrix2kShift = { - { 0, 0, 0, 0, 0, 0, 0, '\\', ']', '<', '>', '?', 0x7F, }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, '[', 'l', ':', '=' }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '_', '@', ';' }, - { 0, 0, '!', '\"', '#', '$', '%', '&', '\'', '(', ')' } }; - - private static final int[][] keyMatrixES1988Normal = { - { 0, 0x20, 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', - 0x0D, 0x1B }, - { 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '*', '-' }, - { 0, '=', 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', '+' }, - { 0, 0x0A, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' } }; - - private static final int[][] keyMatrixES23Normal = { - { 0, 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0x0D, 0x20 }, - { 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '+', '*' }, - { 0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', '-', '=' }, - { 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '<', '>' } }; - - private static final int[][] keyMatrixES23Shift = { - { 0, 0, 0, 0, 0, 0, 0, 0, '[', ']', '?' }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ':', '\\', '^' }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '_' }, - { 0, '!', '\"', '#', '$', '%', '&', '\'', '@', '(', ')' } }; - - private static final int[][] keyMatrixES23Control = { - { 0, 25, 24, 3, 22, 2, 14, 13 }, - { 0, 1, 19, 4, 6, 7, 8, 10, 11, 12 }, - { 0, 17, 23, 5, 18, 20, 26, 21, 9, 15, 16 }, - { 0 } }; - - private static final int[][] keyMatrixES40Normal = { - { 0, 0, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', 0x20, 0x0D }, - { 0, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '*' }, - { 0, 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '+' }, - { 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '<' } }; - - private static final int[][] keyMatrixES40Shift1 = { - { 0, 0, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '[', ']', '=', '?' }, - { 0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '/' }, - { 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '-' }, - { 0, 0, '!', '\"', '#', '$', '%', '&', '\'', '@', '(', ')', '>' } }; - - private static final int[][] keyMatrixES40Shift2 = { - { 0, 0, 0, 4, 0, 0x0E, 0, 0, 0, '{', '}', '_', '~' }, - { 0, 0, 1, 5, 2, 0x0B, 0, 0, 0, 0, 0, 0, '|' }, - { 0, 0, 7, 3, 6, 0x0A, 0, 0, 0, 0, 0, 0, '\\' }, - { 0, 0, 8, 9, 0x0C, 0, '\u00C4', '\u00D6', '\u00DC', - '\u00E4', '\u00F6', '\u00FC', '^' } }; - - private static final int ADDR_VIDEO_INTERRUPT = 0x080C; - - /* - * Farbzuordnung in der Methode getPixelColorNum(x,y) - * Diese Zuordnung hat nichts mit der Farbzuordnung - * im emulierten System zu tun. - */ - private static final int RED_MASK = 0x08; - private static final int GREEN_MASK = 0x04; - private static final int BLUE_MASK = 0x02; - private static final int BRIGHT_MASK = 0x01; - - private String errorText; - private volatile ErrorViewer errorViewer; - private volatile JTCScreen screen; - private volatile Z8Listener resetListener; - private PasteWorker pasteWorker; - private Random random; - private volatile Z8 z8; - private OSType osType; - private OSType newOSType; - private ExtROM[] extROMs; - private ExtROM[] newExtROMs; - private ExtROM romBank; - private ExtROM[] newRomBank; - private volatile AudioReader tapeReader; - private volatile AudioWriter tapeWriter; - private volatile AudioWriter loudspeaker; - private volatile long lastScreenCycles; - private int screenWidth; - private int screenHeight; - private CharRaster charRaster; - private byte[] u883rom; - private byte[] os2k_0800; - private byte[] es1988_0800; - private byte[] es1988_2000; - private byte[] es23_0800; - private byte[] es40_0800; - private byte[] es40RomBank_0800; - private byte[] rom0800; - private byte[] rom2000; - private byte[] ram; - private byte[] ramV; - private byte[] ramB; - private byte[] ramG; - private byte[] ramR; - private int newMaxGPRNum; - private int newRamSize; - private int ramSize; - private int romBankMask; - private int romBankNum; - private int port3Value; - private int[] colorModeRGBs; - private int[] keyMatrixCols; - private boolean ignoreKeyChar; - private volatile boolean shiftStatusSet; - private volatile boolean tapeInPhase; - private volatile boolean tapeOutPhase; - private volatile boolean loudspeakerPhase; - private boolean videoV; - private boolean videoB; - private boolean videoG; - private boolean videoR; - private volatile boolean monochrome; - - - public JTCSys() throws IOException - { - this.errorText = null; - this.errorViewer = null; - this.resetListener = null; - this.random = new Random( System.currentTimeMillis() ); - this.ram = new byte[ 0x10000 ]; - this.ramV = new byte[ 0x2000 ]; - this.ramB = new byte[ 0x2000 ]; - this.ramG = new byte[ 0x2000 ]; - this.ramR = new byte[ 0x2000 ]; - this.screen = null; - this.charRaster = null; - this.pasteWorker = null; - this.tapeReader = null; - this.tapeWriter = null; - this.loudspeaker = null; - this.romBankMask = 0; - this.romBankNum = 0; - this.port3Value = 0xFF; - this.lastScreenCycles = -1; - this.screenHeight = 0; - this.screenWidth = 0; - this.ignoreKeyChar = false; - this.shiftStatusSet = false; - this.tapeInPhase = false; - this.tapeOutPhase = false; - this.loudspeakerPhase = false; - this.videoV = false; - this.videoB = false; - this.videoG = false; - this.videoR = false; - this.monochrome = true; - this.newOSType = null; - this.newExtROMs = null; - this.newRomBank = null; - this.newMaxGPRNum = 0; - this.newRamSize = 0; - this.keyMatrixCols = new int[ 0x10 ]; - resetKeyMatrixStatus(); - - // Farbtabelle fuer Color-Mode - this.colorModeRGBs = new int[ 0x10 ]; - for( int i = 0; i < this.colorModeRGBs.length; i++ ) { - int r = ((i & RED_MASK) == 0 ? 0xA0 : 0); - int g = ((i & GREEN_MASK) == 0 ? 0xA0 : 0); - int b = ((i & BLUE_MASK) == 0 ? 0xA0 : 0); - if( (i & BRIGHT_MASK) == 0 ) { - r += 0x5F; - g += 0x5F; - b += 0x5F; - } - this.colorModeRGBs[ i ] = ((r << 16) & 0x00FF0000) - | ((g << 8) & 0x0000FF00) - | (b & 0x000000FF); +public class JTCSys implements Z8IO, Z8Listener, Z8Memory { + public static final int DEFAULT_BASIC_ADDR = 0xE000; + public static final int DEFAULT_Z8_CYCLES_PER_SECOND = 4000000; // intern + public static final int MAX_ROM_SIZE = 0x10000; + public static final int MAX_ROMBANK_SIZE = 256 * 0x2000; + + public static final String PROP_Z8_REGS_80_TO_EF = "z8.regs80toEF"; + public static final String PROP_Z8_REG_INIT_ZERO = "z8.reg.init.zero"; + public static final String PROP_RAM_INIT_ZERO = "ram.init.zero"; + public static final String PROP_RAM_SIZE = "ram.size"; + public static final String PROP_ROM_PREFIX = "rom."; + public static final String PROP_ROM_COUNT = "rom.count"; + public static final String PROP_ROM_RELOAD = "rom.reload"; + public static final String PROP_ROMBANK_ENABLED = "rombank.enabled"; + public static final String PROP_ROMBANK_FILE = "rombank.file"; + public static final String PROP_OS = "os"; + public static final String VALUE_OS_2K = "2K"; + public static final String VALUE_OS_ES1988 = "ES1988"; + public static final String VALUE_OS_ES23 = "ES2.3"; + public static final String VALUE_OS_ES40 = "ES4.0"; + + public static final boolean DEFAULT_RAM_INIT_ZERO = true; + public static final boolean DEFAULT_Z8_REG_INIT_ZERO = true; + + public static enum OSType {OS2K, ES1988, ES23, ES40} + + ; + + public static enum Key { + LEFT, RIGHT, UP, DOWN, BACK_SPACE, HOME, + SPACE, ENTER, ESCAPE, INSERT, DELETE, CLEAR, + F1, F2, F3, F4, F5, F6, F7, F8 } - // Einstellungen lesen - this.osType = readOSType(); - this.ramSize = readRamSize(); - - // Resourcen lesen - this.u883rom = readResource( "/org.jens_mueller/rom/u883rom.bin" ); - this.os2k_0800 = readResource( "/org.jens_mueller/rom/os2k_0800.bin" ); - this.es1988_0800 = readResource( "/org.jens_mueller/rom/es1988_0800.bin" ); - this.es1988_2000 = readResource( "/org.jens_mueller/rom/es1988_2000.bin" ); - this.es23_0800 = readResource( "/org.jens_mueller/rom/es23_0800.bin" ); - this.es40_0800 = readResource( "/org.jens_mueller/rom/es40_0800.bin" ); - this.es40RomBank_0800 = readResource( "/org.jens_mueller/rom/es40c_0800.bin" ); - - // externe ROM-Dateien laden - StringBuilder buf = new StringBuilder(); - this.extROMs = readExtROMs( buf ); - if( supportsROMBank( this.osType ) ) { - this.romBank = readRomBank( buf ); - buildRomBankMask(); - } - if( buf.length() > 0 ) { - this.errorText = buf.toString(); + ; + + private static final int[][] keyMatrix2kNormal = { + {0, 0x20, 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', + 0x0D, 0x1B}, + {0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '*', '-'}, + {0, 0x0B, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', '+'}, + {0, 0x0A, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + 0x08}}; + + private static final int[][] keyMatrix2kShift = { + {0, 0, 0, 0, 0, 0, 0, '\\', ']', '<', '>', '?', 0x7F,}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, '[', 'l', ':', '='}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '_', '@', ';'}, + {0, 0, '!', '\"', '#', '$', '%', '&', '\'', '(', ')'}}; + + private static final int[][] keyMatrixES1988Normal = { + {0, 0x20, 'Y', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', + 0x0D, 0x1B}, + {0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '*', '-'}, + {0, '=', 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', '+'}, + {0, 0x0A, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}}; + + private static final int[][] keyMatrixES23Normal = { + {0, 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0x0D, 0x20}, + {0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '+', '*'}, + {0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', '-', '='}, + {0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '<', '>'}}; + + private static final int[][] keyMatrixES23Shift = { + {0, 0, 0, 0, 0, 0, 0, 0, '[', ']', '?'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ':', '\\', '^'}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '_'}, + {0, '!', '\"', '#', '$', '%', '&', '\'', '@', '(', ')'}}; + + private static final int[][] keyMatrixES23Control = { + {0, 25, 24, 3, 22, 2, 14, 13}, + {0, 1, 19, 4, 6, 7, 8, 10, 11, 12}, + {0, 17, 23, 5, 18, 20, 26, 21, 9, 15, 16}, + {0}}; + + private static final int[][] keyMatrixES40Normal = { + {0, 0, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', 0x20, 0x0D}, + {0, 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '*'}, + {0, 0, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '+'}, + {0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '<'}}; + + private static final int[][] keyMatrixES40Shift1 = { + {0, 0, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '[', ']', '=', '?'}, + {0, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '/'}, + {0, 0, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '-'}, + {0, 0, '!', '\"', '#', '$', '%', '&', '\'', '@', '(', ')', '>'}}; + + private static final int[][] keyMatrixES40Shift2 = { + {0, 0, 0, 4, 0, 0x0E, 0, 0, 0, '{', '}', '_', '~'}, + {0, 0, 1, 5, 2, 0x0B, 0, 0, 0, 0, 0, 0, '|'}, + {0, 0, 7, 3, 6, 0x0A, 0, 0, 0, 0, 0, 0, '\\'}, + {0, 0, 8, 9, 0x0C, 0, '\u00C4', '\u00D6', '\u00DC', + '\u00E4', '\u00F6', '\u00FC', '^'}}; + + private static final int ADDR_VIDEO_INTERRUPT = 0x080C; + + /* + * Farbzuordnung in der Methode getPixelColorNum(x,y) + * Diese Zuordnung hat nichts mit der Farbzuordnung + * im emulierten System zu tun. + */ + private static final int RED_MASK = 0x08; + private static final int GREEN_MASK = 0x04; + private static final int BLUE_MASK = 0x02; + private static final int BRIGHT_MASK = 0x01; + + private String errorText; + private volatile ErrorViewer errorViewer; + private volatile JTCScreen screen; + private volatile Z8Listener resetListener; + private PasteWorker pasteWorker; + private Random random; + private volatile Z8 z8; + private OSType osType; + private OSType newOSType; + private ExtROM[] extROMs; + private ExtROM[] newExtROMs; + private ExtROM romBank; + private ExtROM[] newRomBank; + private volatile AudioReader tapeReader; + private volatile AudioWriter tapeWriter; + private volatile AudioWriter loudspeaker; + private volatile long lastScreenCycles; + private int screenWidth; + private int screenHeight; + private CharRaster charRaster; + private byte[] u883rom; + private byte[] os2k_0800; + private byte[] es1988_0800; + private byte[] es1988_2000; + private byte[] es23_0800; + private byte[] es40_0800; + private byte[] es40RomBank_0800; + private byte[] rom0800; + private byte[] rom2000; + private byte[] ram; + private byte[] ramV; + private byte[] ramB; + private byte[] ramG; + private byte[] ramR; + private int newMaxGPRNum; + private int newRamSize; + private int ramSize; + private int romBankMask; + private int romBankNum; + private int port3Value; + private int[] colorModeRGBs; + private int[] keyMatrixCols; + private boolean ignoreKeyChar; + private volatile boolean shiftStatusSet; + private volatile boolean tapeInPhase; + private volatile boolean tapeOutPhase; + private volatile boolean loudspeakerPhase; + private boolean videoV; + private boolean videoB; + private boolean videoG; + private boolean videoR; + private volatile boolean monochrome; + + + public JTCSys() throws IOException { + this.errorText = null; + this.errorViewer = null; + this.resetListener = null; + this.random = new Random(System.currentTimeMillis()); + this.ram = new byte[0x10000]; + this.ramV = new byte[0x2000]; + this.ramB = new byte[0x2000]; + this.ramG = new byte[0x2000]; + this.ramR = new byte[0x2000]; + this.screen = null; + this.charRaster = null; + this.pasteWorker = null; + this.tapeReader = null; + this.tapeWriter = null; + this.loudspeaker = null; + this.romBankMask = 0; + this.romBankNum = 0; + this.port3Value = 0xFF; + this.lastScreenCycles = -1; + this.screenHeight = 0; + this.screenWidth = 0; + this.ignoreKeyChar = false; + this.shiftStatusSet = false; + this.tapeInPhase = false; + this.tapeOutPhase = false; + this.loudspeakerPhase = false; + this.videoV = false; + this.videoB = false; + this.videoG = false; + this.videoR = false; + this.monochrome = true; + this.newOSType = null; + this.newExtROMs = null; + this.newRomBank = null; + this.newMaxGPRNum = 0; + this.newRamSize = 0; + this.keyMatrixCols = new int[0x10]; + resetKeyMatrixStatus(); + + // Farbtabelle fuer Color-Mode + this.colorModeRGBs = new int[0x10]; + for (int i = 0; i < this.colorModeRGBs.length; i++) { + int r = ((i & RED_MASK) == 0 ? 0xA0 : 0); + int g = ((i & GREEN_MASK) == 0 ? 0xA0 : 0); + int b = ((i & BLUE_MASK) == 0 ? 0xA0 : 0); + if ((i & BRIGHT_MASK) == 0) { + r += 0x5F; + g += 0x5F; + b += 0x5F; + } + this.colorModeRGBs[i] = ((r << 16) & 0x00FF0000) + | ((g << 8) & 0x0000FF00) + | (b & 0x000000FF); + } + + // Einstellungen lesen + this.osType = readOSType(); + this.ramSize = readRamSize(); + + // Resourcen lesen + this.u883rom = readResource("/org.jens_mueller/rom/u883rom.bin"); + this.os2k_0800 = readResource("/org.jens_mueller/rom/os2k_0800.bin"); + this.es1988_0800 = readResource("/org.jens_mueller/rom/es1988_0800.bin"); + this.es1988_2000 = readResource("/org.jens_mueller/rom/es1988_2000.bin"); + this.es23_0800 = readResource("/org.jens_mueller/rom/es23_0800.bin"); + this.es40_0800 = readResource("/org.jens_mueller/rom/es40_0800.bin"); + this.es40RomBank_0800 = readResource("/org.jens_mueller/rom/es40c_0800.bin"); + + // externe ROM-Dateien laden + StringBuilder buf = new StringBuilder(); + this.extROMs = readExtROMs(buf); + if (supportsROMBank(this.osType)) { + this.romBank = readRomBank(buf); + buildRomBankMask(); + } + if (buf.length() > 0) { + this.errorText = buf.toString(); + } + + // Z8 anlegen + this.z8 = new Z8(isRegInitZero(), this, this); + this.z8.setCyclesPerSecond(DEFAULT_Z8_CYCLES_PER_SECOND); + this.z8.setMaxGPRNum(readMaxGPRNum()); + this.z8.setResetListener(this); + resetInternal(false, false); // kein Power On! + checkSetZ8PreExecInstListener(); + initRAM(); } - // Z8 anlegen - this.z8 = new Z8( isRegInitZero(), this, this ); - this.z8.setCyclesPerSecond( DEFAULT_Z8_CYCLES_PER_SECOND ); - this.z8.setMaxGPRNum( readMaxGPRNum() ); - this.z8.setResetListener( this ); - resetInternal( false, false ); // kein Power On! - checkSetZ8PreExecInstListener(); - initRAM(); - } - - - public void cancelPastingText() - { - PasteWorker pasteWorker = this.pasteWorker; - if( pasteWorker != null ) { - pasteWorker.fireStop(); - this.pasteWorker = null; - } - } - - - public void fireReset( boolean initRAM ) - { - cancelPastingText(); - resetKeyMatrixStatus(); - this.z8.fireReset( initRAM ); - } - - - public int[] getColorModeRGBs() - { - return this.colorModeRGBs; - } - - - public boolean getEmulateRegisters80ToEF() - { - return this.z8.getMaxGPRNum() >= 0xEF; - } - - - public String getErrorText() - { - return this.errorText; - } - - - public ExtROM[] getExtROMs() - { - return this.extROMs; - } - - - public int[] getKeyMatrixCols() - { - return this.keyMatrixCols; - } - - - public OSType getOSType() - { - return this.osType; - } - - - public int getPixelColorNum ( int x, int y ) - { - int rv = 0; - if( this.osType == OSType.ES40 ) { - int grp = y / 3; - int yGrp = y % 3; - int idx = (grp * 128) + (yGrp * 40) + (x / 8); - if( idx < this.ramV.length ) { - int m = (1 << (7 - (x % 8))); - if( (this.ramV[ idx ] & m) == 0 ) { - rv |= BRIGHT_MASK; - } - if( (this.ramB[ idx ] & m) == 0 ) { - rv |= BLUE_MASK; - } - if( (this.ramG[ idx ] & m) == 0 ) { - rv |= GREEN_MASK; - } - if( (this.ramR[ idx ] & m) == 0 ) { - rv |= RED_MASK; - } - } - } else if( this.osType == OSType.ES23 ) { - int idx = 0xF800 + (y * 16) + (x / 8); - if( (idx >= 0) && (idx < this.ram.length) ) { - if( (this.ram[ idx ] & (1 << (7 - (x % 8)))) == 0 ) { - rv = 1; - } else { - rv = 0; - } - } - } else { - int idx = 0xFE00 + (y * 8) + (x / 8); - if( (idx >= 0) && (idx < this.ram.length) ) { - if( (this.ram[ idx ] & (1 << (7 - (x % 8)))) == 0 ) { - rv = 1; - } else { - rv = 0; - } - } + + public void cancelPastingText() { + PasteWorker pasteWorker = this.pasteWorker; + if (pasteWorker != null) { + pasteWorker.fireStop(); + this.pasteWorker = null; + } } - return rv; - } - public int getRAMSize() - { - return this.ramSize; - } + public void fireReset(boolean initRAM) { + cancelPastingText(); + resetKeyMatrixStatus(); + this.z8.fireReset(initRAM); + } - public ExtROM getROMBank() - { - return this.romBank; - } + public int[] getColorModeRGBs() { + return this.colorModeRGBs; + } - public static String getROMPropFile( int idx ) - { - return String.format( "%s%d.file", PROP_ROM_PREFIX, idx ); - } + public boolean getEmulateRegisters80ToEF() { + return this.z8.getMaxGPRNum() >= 0xEF; + } - public static String getROMPropAddr( int idx ) - { - return String.format( "%s%d.addr", PROP_ROM_PREFIX, idx ); - } + public String getErrorText() { + return this.errorText; + } - public synchronized CharRaster getScreenCharRaster() - { - return this.charRaster; - } + public ExtROM[] getExtROMs() { + return this.extROMs; + } - public synchronized int getScreenHeight() - { - return this.screenHeight; - } + public int[] getKeyMatrixCols() { + return this.keyMatrixCols; + } - public synchronized int getScreenWidth() - { - return this.screenWidth; - } + public OSType getOSType() { + return this.osType; + } - public String getScreenText() - { - String rv = null; - if( this.osType == OSType.ES23 ) { - rv = getScreenText( 0xF400, 16, 16, 16, 0, 0, 15, 15 ); - } else if( this.osType == OSType.ES40 ) { - rv = getScreenText( 0xFC00, 24, 40, 40, 0, 0, 39, 23 ); - } else { - rv = getScreenText( 0xFD00, 8, 13, 16, 0, 0, 12, 7 ); - } - return rv; - } - - - public String getScreenText( int x1, int y1, int x2, int y2 ) - { - String rv = null; - if( this.osType == OSType.ES23 ) { - rv = getScreenText( 0xF400, 16, 16, 16, x1, y1, x2, y2 ); - } else if( this.osType == OSType.ES40 ) { - rv = getScreenText( 0xFC00, 24, 40, 40, x1, y1, x2, y2 ); - } else { - rv = getScreenText( 0xFD00, 8, 13, 16, x1, y1, x2, y2 ); + public int getPixelColorNum(int x, int y) { + int rv = 0; + if (this.osType == OSType.ES40) { + int grp = y / 3; + int yGrp = y % 3; + int idx = (grp * 128) + (yGrp * 40) + (x / 8); + if (idx < this.ramV.length) { + int m = (1 << (7 - (x % 8))); + if ((this.ramV[idx] & m) == 0) { + rv |= BRIGHT_MASK; + } + if ((this.ramB[idx] & m) == 0) { + rv |= BLUE_MASK; + } + if ((this.ramG[idx] & m) == 0) { + rv |= GREEN_MASK; + } + if ((this.ramR[idx] & m) == 0) { + rv |= RED_MASK; + } + } + } else if (this.osType == OSType.ES23) { + int idx = 0xF800 + (y * 16) + (x / 8); + if ((idx >= 0) && (idx < this.ram.length)) { + if ((this.ram[idx] & (1 << (7 - (x % 8)))) == 0) { + rv = 1; + } else { + rv = 0; + } + } + } else { + int idx = 0xFE00 + (y * 8) + (x / 8); + if ((idx >= 0) && (idx < this.ram.length)) { + if ((this.ram[idx] & (1 << (7 - (x % 8)))) == 0) { + rv = 1; + } else { + rv = 0; + } + } + } + return rv; } - return rv; - } - public Z8 getZ8() - { - return this.z8; - } + public int getRAMSize() { + return this.ramSize; + } - public boolean isMonochrome() - { - return this.monochrome; - } + public ExtROM getROMBank() { + return this.romBank; + } - public static boolean isRamInitZero() - { - return AppContext.getBooleanProperty( - PROP_RAM_INIT_ZERO, - DEFAULT_RAM_INIT_ZERO ); - } + public static String getROMPropFile(int idx) { + return String.format("%s%d.file", PROP_ROM_PREFIX, idx); + } - public static boolean isRegInitZero() - { - return AppContext.getBooleanProperty( - PROP_Z8_REG_INIT_ZERO, - DEFAULT_Z8_REG_INIT_ZERO ); - } + public static String getROMPropAddr(int idx) { + return String.format("%s%d.addr", PROP_ROM_PREFIX, idx); + } - public boolean isScreenOutputEnabled() - { - boolean rv = (this.osType == OSType.ES40); - if( !rv ) { - if( (this.z8.getTotalCycles() - this.lastScreenCycles) < 400000 ) { - rv = true; - } + public synchronized CharRaster getScreenCharRaster() { + return this.charRaster; } - return rv; - } - - - public boolean keyPressed( Key key, boolean shiftDown ) - { - boolean rv = false; - synchronized( this.keyMatrixCols ) { - resetKeyMatrixStatus(); - if( this.osType == OSType.ES23 ) { - int keyValue = 0; - switch( key ) { - case LEFT: - keyValue = 1; - break; - case RIGHT: - keyValue = 2; - break; - case UP: - keyValue = 3; - break; - case DOWN: - keyValue = 4; - break; - case HOME: - keyValue = 5; - break; - case DELETE: - keyValue = 7; - break; - case BACK_SPACE: - keyValue = 8; - break; - case INSERT: - keyValue = 9; - break; - case CLEAR: - keyValue = 0x0C; - break; - case ENTER: - keyValue = 0x0D; - break; - } - rv = setKeyMatrixStatusES23( keyValue ); - } - else if( this.osType == OSType.ES40 ) { - switch( key ) { - case LEFT: - rv = setKeyMatrixStatusES40( 1 ); - break; - case RIGHT: - rv = setKeyMatrixStatusES40( 2 ); - break; - case UP: - rv = setKeyMatrixStatusES40( 3 ); - break; - case DOWN: - rv = setKeyMatrixStatusES40( 4 ); - break; - case HOME: - rv = setKeyMatrixStatusES40( 5 ); - break; - case DELETE: - rv = setKeyMatrixStatusES40( 7 ); - break; - case BACK_SPACE: - rv = setKeyMatrixStatusES40( 8 ); - break; - case INSERT: - rv = setKeyMatrixStatusES40( 9 ); - break; - case CLEAR: - rv = setKeyMatrixStatusES40( 0x0C ); - break; - case ENTER: - rv = setKeyMatrixStatusES40( 0x0D ); - break; - case ESCAPE: - rv = setKeyMatrixStatusES40( 0x0E ); - break; - case F1: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 2 ] = 0x04; - rv = true; - break; - case F2: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 3 ] = 0x04; - rv = true; - break; - case F3: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 4 ] = 0x04; - rv = true; - break; - case F4: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 5 ] = 0x04; - rv = true; - break; - case F5: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 6 ] = 0x04; - rv = true; - break; - case F6: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 7 ] = 0x04; - rv = true; - break; - case F7: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 8 ] = 0x04; - rv = true; - break; - case F8: - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 9 ] = 0x04; - rv = true; - break; - } - } else { - switch( key ) { - case LEFT: - setShift( false ); - this.keyMatrixCols[ 1 ] = 0x04; - rv = true; - break; - case RIGHT: - setShift( true ); - this.keyMatrixCols[ 1 ] = 0x04; - rv = true; - break; - case UP: - if( this.osType == OSType.OS2K ) { - setShift( true ); - this.keyMatrixCols[ 1 ] = 0x08; - rv = true; - } - break; - case DOWN: - if( this.osType == OSType.OS2K ) { - setShift( false ); - this.keyMatrixCols[ 1 ] = 0x08; - rv = true; - } - break; - case BACK_SPACE: - setShift( false ); - this.keyMatrixCols[ 12 ] = 0x08; - rv = true; - break; - case SPACE: - setShift( false ); - this.keyMatrixCols[ 1 ] = 0x01; - rv = true; - break; - case ENTER: - setShift( shiftDown ); - this.keyMatrixCols[ 12 ] = 0x01; - rv = true; - break; - case ESCAPE: - setShift( false ); - this.keyMatrixCols[ 13 ] = 0x01; - rv = true; - break; - } - } - if( rv ) { - this.ignoreKeyChar = true; - } - } - return rv; - } - public void keyReleased() - { - synchronized( this.keyMatrixCols ) { - resetKeyMatrixStatus(); - this.ignoreKeyChar = false; - } - } - - - public boolean keyTyped( char ch ) - { - return keyTyped( ch, false ); - } - - - public boolean keyTyped( char ch, boolean forceCase ) - { - boolean rv = false; - synchronized( this.keyMatrixCols ) { - if( this.ignoreKeyChar ) { - this.ignoreKeyChar = false; - } else { - if( this.osType == OSType.ES23 ) { - if( (ch >= 'A') && (ch <= 'Z') ) { - ch = (char) (ch - 'A' + 'a'); - } - rv = setKeyMatrixStatusES23( ch ); - } else if( this.osType == OSType.ES40 ) { - if( !forceCase ) { - if( (ch >= 'A') && (ch <= 'Z') ) { - ch = (char) (ch - 'A' + 'a'); - } - else if( (ch >= 'a') && (ch <= 'z') ) { - ch = (char) (ch - 'a' + 'A'); - } - } - rv = setKeyMatrixStatusES40( ch ); - } else { - rv = setKeyMatrixStatus2kOrES1988( ch ); - } - } + public synchronized int getScreenHeight() { + return this.screenHeight; } - return rv; - } - - public void setErrorViewer( ErrorViewer errorViewer ) - { - this.errorViewer = errorViewer; - } + public synchronized int getScreenWidth() { + return this.screenWidth; + } - public void setLoudspeaker( AudioWriter audioWriter ) - { - this.loudspeaker = audioWriter; - checkSetZ8PreExecInstListener(); - } + public String getScreenText() { + String rv = null; + if (this.osType == OSType.ES23) { + rv = getScreenText(0xF400, 16, 16, 16, 0, 0, 15, 15); + } else if (this.osType == OSType.ES40) { + rv = getScreenText(0xFC00, 24, 40, 40, 0, 0, 39, 23); + } else { + rv = getScreenText(0xFD00, 8, 13, 16, 0, 0, 12, 7); + } + return rv; + } - public void setResetListener( Z8Listener listener ) - { - this.resetListener = listener; - } + public String getScreenText(int x1, int y1, int x2, int y2) { + String rv = null; + if (this.osType == OSType.ES23) { + rv = getScreenText(0xF400, 16, 16, 16, x1, y1, x2, y2); + } else if (this.osType == OSType.ES40) { + rv = getScreenText(0xFC00, 24, 40, 40, x1, y1, x2, y2); + } else { + rv = getScreenText(0xFD00, 8, 13, 16, x1, y1, x2, y2); + } + return rv; + } - public synchronized void settingsChanged( - ExtROM[] extROMs, - ExtROM romBank ) - { - boolean forcePowerOn = false; - int maxGPRNum = readMaxGPRNum(); - if( maxGPRNum != this.z8.getMaxGPRNum() ) { - this.newMaxGPRNum = maxGPRNum; - forcePowerOn = true; + public Z8 getZ8() { + return this.z8; } - int ramSize = readRamSize(); - if( ramSize != this.ramSize ) { - this.newRamSize = ramSize; - forcePowerOn = true; - } - OSType osType = readOSType(); - if( osType != this.osType ) { - this.newOSType = osType; - forcePowerOn = true; + public boolean isMonochrome() { + return this.monochrome; } - if( !supportsROMBank( osType ) ) { - romBank = null; - } - if( JTCUtil.differsExtROM( this.romBank, romBank ) ) { - if( romBank != null ) { - romBank.setBegAddr( 0 ); - this.newRomBank = new ExtROM[] { romBank }; - } else { - this.newRomBank = new ExtROM[ 0 ]; - } - forcePowerOn = true; - } - if( JTCUtil.differsExtROMs( this.extROMs, extROMs ) ) { - this.newExtROMs = (extROMs != null ? extROMs : new ExtROM[ 0 ]); - forcePowerOn = true; + public static boolean isRamInitZero() { + return AppContext.getBooleanProperty( + PROP_RAM_INIT_ZERO, + DEFAULT_RAM_INIT_ZERO); } - this.z8.setRegInitZero( isRegInitZero() ); - if( forcePowerOn ) { - fireReset( true ); + + public static boolean isRegInitZero() { + return AppContext.getBooleanProperty( + PROP_Z8_REG_INIT_ZERO, + DEFAULT_Z8_REG_INIT_ZERO); } - } - public void setTapeReader( AudioReader audioReader ) - { - this.tapeReader = audioReader; - checkSetZ8PreExecInstListener(); - } + public boolean isScreenOutputEnabled() { + boolean rv = (this.osType == OSType.ES40); + if (!rv) { + if ((this.z8.getTotalCycles() - this.lastScreenCycles) < 400000) { + rv = true; + } + } + return rv; + } - public void setTapeWriter( AudioWriter audioWriter ) - { - this.tapeWriter = audioWriter; - checkSetZ8PreExecInstListener(); - } + public boolean keyPressed(Key key, boolean shiftDown) { + boolean rv = false; + synchronized (this.keyMatrixCols) { + resetKeyMatrixStatus(); + if (this.osType == OSType.ES23) { + int keyValue = 0; + switch (key) { + case LEFT: + keyValue = 1; + break; + case RIGHT: + keyValue = 2; + break; + case UP: + keyValue = 3; + break; + case DOWN: + keyValue = 4; + break; + case HOME: + keyValue = 5; + break; + case DELETE: + keyValue = 7; + break; + case BACK_SPACE: + keyValue = 8; + break; + case INSERT: + keyValue = 9; + break; + case CLEAR: + keyValue = 0x0C; + break; + case ENTER: + keyValue = 0x0D; + break; + } + rv = setKeyMatrixStatusES23(keyValue); + } else if (this.osType == OSType.ES40) { + switch (key) { + case LEFT: + rv = setKeyMatrixStatusES40(1); + break; + case RIGHT: + rv = setKeyMatrixStatusES40(2); + break; + case UP: + rv = setKeyMatrixStatusES40(3); + break; + case DOWN: + rv = setKeyMatrixStatusES40(4); + break; + case HOME: + rv = setKeyMatrixStatusES40(5); + break; + case DELETE: + rv = setKeyMatrixStatusES40(7); + break; + case BACK_SPACE: + rv = setKeyMatrixStatusES40(8); + break; + case INSERT: + rv = setKeyMatrixStatusES40(9); + break; + case CLEAR: + rv = setKeyMatrixStatusES40(0x0C); + break; + case ENTER: + rv = setKeyMatrixStatusES40(0x0D); + break; + case ESCAPE: + rv = setKeyMatrixStatusES40(0x0E); + break; + case F1: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[2] = 0x04; + rv = true; + break; + case F2: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[3] = 0x04; + rv = true; + break; + case F3: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[4] = 0x04; + rv = true; + break; + case F4: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[5] = 0x04; + rv = true; + break; + case F5: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[6] = 0x04; + rv = true; + break; + case F6: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[7] = 0x04; + rv = true; + break; + case F7: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[8] = 0x04; + rv = true; + break; + case F8: + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[9] = 0x04; + rv = true; + break; + } + } else { + switch (key) { + case LEFT: + setShift(false); + this.keyMatrixCols[1] = 0x04; + rv = true; + break; + case RIGHT: + setShift(true); + this.keyMatrixCols[1] = 0x04; + rv = true; + break; + case UP: + if (this.osType == OSType.OS2K) { + setShift(true); + this.keyMatrixCols[1] = 0x08; + rv = true; + } + break; + case DOWN: + if (this.osType == OSType.OS2K) { + setShift(false); + this.keyMatrixCols[1] = 0x08; + rv = true; + } + break; + case BACK_SPACE: + setShift(false); + this.keyMatrixCols[12] = 0x08; + rv = true; + break; + case SPACE: + setShift(false); + this.keyMatrixCols[1] = 0x01; + rv = true; + break; + case ENTER: + setShift(shiftDown); + this.keyMatrixCols[12] = 0x01; + rv = true; + break; + case ESCAPE: + setShift(false); + this.keyMatrixCols[13] = 0x01; + rv = true; + break; + } + } + if (rv) { + this.ignoreKeyChar = true; + } + } + return rv; + } - public void setScreen( JTCScreen screen ) - { - this.screen = screen; - } + public void keyReleased() { + synchronized (this.keyMatrixCols) { + resetKeyMatrixStatus(); + this.ignoreKeyChar = false; + } + } - public void startPastingText( String text, PasteObserver observer ) - { - boolean done = false; - if( text != null ) { - if( !text.isEmpty() ) { - cancelPastingText(); - this.pasteWorker = new PasteWorker( this, text, observer ); - this.pasteWorker.start(); - done = true; - } + public boolean keyTyped(char ch) { + return keyTyped(ch, false); } - if( !done && (observer != null) ) { - observer.pastingFinished(); + + + public boolean keyTyped(char ch, boolean forceCase) { + boolean rv = false; + synchronized (this.keyMatrixCols) { + if (this.ignoreKeyChar) { + this.ignoreKeyChar = false; + } else { + if (this.osType == OSType.ES23) { + if ((ch >= 'A') && (ch <= 'Z')) { + ch = (char) (ch - 'A' + 'a'); + } + rv = setKeyMatrixStatusES23(ch); + } else if (this.osType == OSType.ES40) { + if (!forceCase) { + if ((ch >= 'A') && (ch <= 'Z')) { + ch = (char) (ch - 'A' + 'a'); + } else if ((ch >= 'a') && (ch <= 'z')) { + ch = (char) (ch - 'a' + 'A'); + } + } + rv = setKeyMatrixStatusES40(ch); + } else { + rv = setKeyMatrixStatus2kOrES1988(ch); + } + } + } + return rv; } - } - public boolean supportsLoudspeaker() - { - return (this.osType == OSType.OS2K); - } + public void setErrorViewer(ErrorViewer errorViewer) { + this.errorViewer = errorViewer; + } + + public void setLoudspeaker(AudioWriter audioWriter) { + this.loudspeaker = audioWriter; + checkSetZ8PreExecInstListener(); + } - public static boolean supportsROMBank( OSType osType ) - { - return (osType == OSType.ES40); - } + public void setResetListener(Z8Listener listener) { + this.resetListener = listener; + } - /* --- Z8IO --- */ - @Override - public int getPortValue( int port ) - { - int rv = 0xFF; - if( port == 3 ) { - rv &= ~0x04; // P32=0 - if( !this.tapeInPhase ) { - rv &= ~0x01; // P30=0 - } + public synchronized void settingsChanged( + ExtROM[] extROMs, + ExtROM romBank) { + boolean forcePowerOn = false; + + int maxGPRNum = readMaxGPRNum(); + if (maxGPRNum != this.z8.getMaxGPRNum()) { + this.newMaxGPRNum = maxGPRNum; + forcePowerOn = true; + } + + int ramSize = readRamSize(); + if (ramSize != this.ramSize) { + this.newRamSize = ramSize; + forcePowerOn = true; + } + + OSType osType = readOSType(); + if (osType != this.osType) { + this.newOSType = osType; + forcePowerOn = true; + } + + if (!supportsROMBank(osType)) { + romBank = null; + } + if (JTCUtil.differsExtROM(this.romBank, romBank)) { + if (romBank != null) { + romBank.setBegAddr(0); + this.newRomBank = new ExtROM[]{romBank}; + } else { + this.newRomBank = new ExtROM[0]; + } + forcePowerOn = true; + } + + if (JTCUtil.differsExtROMs(this.extROMs, extROMs)) { + this.newExtROMs = (extROMs != null ? extROMs : new ExtROM[0]); + forcePowerOn = true; + } + + this.z8.setRegInitZero(isRegInitZero()); + if (forcePowerOn) { + fireReset(true); + } } - return rv; - } - - - @Override - public void setPortValue( int port, int value ) - { - if( port == 3 ) { - if( ((value & 0x20) == 0) && ((this.port3Value & 0x20) != 0) ) { - this.romBankNum = 0; - } - else if( ((value & 0x80) == 0) && ((this.port3Value & 0x80) != 0) ) - { - this.romBankNum = (this.romBankNum + 1) & this.romBankMask; - } - this.port3Value = value; - - if( this.osType == OSType.OS2K ) { - value &= 0xC0; - this.tapeOutPhase = (value != 0xC0); - this.loudspeakerPhase = (value != 0x40); - } else { - this.tapeOutPhase = ((value & 0x40) != 0); - } + + + public void setTapeReader(AudioReader audioReader) { + this.tapeReader = audioReader; + checkSetZ8PreExecInstListener(); } - } - - - /* --- Z8Listener --- */ - - @Override - public void z8Update( Z8 z8, Z8Listener.Reason reason ) - { - if( z8 == this.z8 ) { - switch( reason ) { - case PRE_INST_EXEC: - if( (z8.getPC() == ADDR_VIDEO_INTERRUPT) - && (this.osType != OSType.ES40) ) - { - this.lastScreenCycles = z8.getTotalCycles(); - } - AudioReader tapeReader = this.tapeReader; - if( tapeReader != null ) { - if( this.osType == OSType.OS2K ) { - this.tapeInPhase = tapeReader.readVolumeStatus(); - } else { - this.tapeInPhase = tapeReader.readPhase(); - } - } - AudioWriter tapeWriter = this.tapeWriter; - if( tapeWriter != null ) { - tapeWriter.writePhase( this.tapeOutPhase ); - } - AudioWriter loudspeaker = this.loudspeaker; - if( loudspeaker != null ) { - loudspeaker.writePhase( this.loudspeakerPhase ); - } - break; - - case POWER_ON: - case RESET: - resetInternal( - reason == Z8Listener.Reason.POWER_ON, - AppContext.getBooleanProperty( PROP_ROM_RELOAD, false ) ); - Z8Listener listener = this.resetListener; - if( listener != null ) { - listener.z8Update( z8, reason ); - } - break; - } + + + public void setTapeWriter(AudioWriter audioWriter) { + this.tapeWriter = audioWriter; + checkSetZ8PreExecInstListener(); } - } - /* --- Z8Memory --- */ + public void setScreen(JTCScreen screen) { + this.screen = screen; + } - @Override - public int getMemByte( int addr, boolean dataMem ) - { - addr &= 0xFFFF; - int rv = 0xFF; - boolean done = false; - if( (addr >= 0x2000) && (addr < 0x4000) ) { - ExtROM romBank = this.romBank; - if( romBank != null ) { - rv = romBank.getByte( (addr - 0x2000) + (this.romBankNum * 0x2000) ); - done = true; - } + public void startPastingText(String text, PasteObserver observer) { + boolean done = false; + if (text != null) { + if (!text.isEmpty()) { + cancelPastingText(); + this.pasteWorker = new PasteWorker(this, text, observer); + this.pasteWorker.start(); + done = true; + } + } + if (!done && (observer != null)) { + observer.pastingFinished(); + } } - if( !done ) { - for( ExtROM rom : this.extROMs ) { - if( (addr >= rom.getBegAddr()) && (addr <= rom.getEndAddr()) ) { - rv = rom.getByte( addr ); - done = true; - break; - } - } + + + public boolean supportsLoudspeaker() { + return (this.osType == OSType.OS2K); } - if( !done ) { - if( (addr >= 0) && (addr < this.u883rom.length) ) { - rv = this.u883rom[ addr ]; - } else if( (addr >= 0x0800) && (addr - 0x0800 < this.rom0800.length) ) { - rv = this.rom0800[ addr - 0x0800 ]; - } else if( (addr >= 0x2000) && (addr - 0x2000 < this.rom2000.length) ) { - rv = this.rom2000[ addr - 0x2000 ]; - } else if( (addr >= 0x4000) && (addr <= 0x5FFF) ) { - if( this.osType == OSType.ES40 ) { - int idx = addr - 0x4000; - if( this.videoV && (idx < this.ramV.length) ) { - rv &= this.ramV[ idx ]; - } - if( this.videoB && (idx < this.ramB.length) ) { - rv &= this.ramB[ idx ]; - } - if( this.videoG && (idx < this.ramG.length) ) { - rv &= this.ramG[ idx ]; - } - if( this.videoR && (idx < this.ramR.length) ) { - rv &= this.ramR[ idx ]; - } - } else { - if( addr >= 0x10000 - this.ramSize ) { - rv = this.ram[ addr ]; - } - } - } else if( (addr >= 0x6000) && (addr < 0x8000) ) { - if( (this.osType != OSType.ES40) || (addr >= 0x7000) ) { - synchronized( this.keyMatrixCols ) { - rv = (this.keyMatrixCols[ addr & 0x000F ] << 4) | 0x0F; - } - } - } else { - if( (ramSize == 0x0400) && (addr >= 0xE000) ) { - int a = addr & 0x03FF; - if( a >= 0x0100 ) { - rv = this.ram[ 0xFD00 - 0x0100 + a ]; - } else { - rv = this.ram[ 0xE000 + a ]; - } - } - else if( (ramSize == 0x0800) && (addr >= 0xE000) ) { - int a = addr & 0x07FF; - if( a >= 0x0500 ) { - rv = this.ram[ 0xFD00 - 0x0500 + a ]; - } else { - rv = this.ram[ 0xE000 + a ]; - } - } - else if( addr >= 0x10000 - this.ramSize ) { - rv = this.ram[ addr ]; - } - } + + + public static boolean supportsROMBank(OSType osType) { + return (osType == OSType.ES40); } - return rv & 0xFF; - } - @Override - public boolean setMemByte( int addr, boolean dataMem, int v ) - { - addr &= 0xFFFF; + /* --- Z8IO --- */ - boolean rv = false; - boolean done = false; - if( (addr >= 0x2000) && (addr < 0x4000) && (this.romBank != null) ) { - done = true; - } - if( !done ) { - for( ExtROM rom : this.extROMs ) { - if( (addr >= rom.getBegAddr()) && (addr <= rom.getEndAddr()) ) { - done = true; - break; - } - } - } - if( !done ) { - int ramBegAddr = 0x10000 - this.ramSize; - if( (addr >= 0x1000) && (addr <= 0x17FF) - && (addr >= ramBegAddr) - && ((this.osType == OSType.OS2K) || (this.osType == OSType.ES1988)) ) - { - this.ram[ addr ] = (byte) v; - rv = true; - } - else if( (addr >= 0x1800) && (addr <= 0x1FFF) - && (addr >= ramBegAddr) - && (this.osType != OSType.ES40) ) - { - this.ram[ addr ] = (byte) v; - rv = true; - } - else if( (addr >= 0x2000) && (addr <= 0x27FF) - && (addr >= ramBegAddr) - && (this.osType != OSType.ES1988) ) - { - this.ram[ addr ] = (byte) v; - rv = true; - } - else if( (addr >= 0x2800) && (addr <= 0x3FFF) - && (addr >= ramBegAddr) ) - { - this.ram[ addr ] = (byte) v; - rv = true; - } - else if( (addr >= 0x4000) && (addr <= 0x5FFF) ) { - if( this.osType == OSType.ES40 ) { - int idx = addr - 0x4000; - boolean dirty = false; - if( this.videoV && (idx < this.ramV.length) ) { - this.ramV[ idx ] = (byte) v; - dirty = true; - } - if( this.videoB && (idx < this.ramB.length) ) { - this.ramB[ idx ] = (byte) v; - dirty = true; - } - if( this.videoG && (idx < this.ramG.length) ) { - this.ramG[ idx ] = (byte) v; - dirty = true; - } - if( this.videoR && (idx < this.ramR.length) ) { - this.ramR[ idx ] = (byte) v; - dirty = true; - } - if( dirty ) { - setScreenDirty(); - } - } else { - if( addr >= ramBegAddr ) { - this.ram[ addr ] = (byte) v; - rv = true; - } - } - } else if( (addr >= 0x6000) && (addr < 0x8000) ) { - if( (this.osType == OSType.ES40) && (addr < 0x6400) ) { - this.videoV = ((addr & 0x0010) == 0); - this.videoB = ((addr & 0x0020) == 0); - this.videoG = ((addr & 0x0040) == 0); - this.videoR = ((addr & 0x0080) == 0); - } - } - else if( addr >= 0x8000 ) { - if( (ramSize == 0x0400) && (addr >= 0xE000) ) { - int a = addr & 0x03FF; - if( a >= 0x0100 ) { - this.ram[ 0xFD00 - 0x0100 + a ] = (byte) v; - if( (a >= 0x0200) - && ((this.osType == OSType.OS2K) - || (this.osType == OSType.ES1988)) ) - { - setScreenDirty(); - } - } else { - this.ram[ 0xE000 + a ] = (byte) v; - } - if( this.osType == OSType.ES23 ) { - setScreenDirty(); - } - rv = true; - } - if( (ramSize == 0x0800) && (addr >= 0xE000) ) { - int a = addr & 0x7FF; - if( a >= 0x0500 ) { - this.ram[ 0xFD00 - 0x0500 + a ] = (byte) v; - if( (a >= 0x0600) - && ((this.osType == OSType.OS2K) - || (this.osType == OSType.ES1988)) ) - { - setScreenDirty(); - } - } else { - this.ram[ 0xE000 + a ] = (byte) v; - } - if( this.osType == OSType.ES23 ) { - setScreenDirty(); - } - rv = true; - } - else if( addr >= ramBegAddr ) { - this.ram[ addr ] = (byte) v; - rv = true; - if( ((addr >= 0xFE00) - && ((this.osType == OSType.OS2K) - || (this.osType == OSType.ES1988))) - || ((addr >= 0xF800) && (this.osType == OSType.ES23)) ) - { - setScreenDirty(); - } - } - } - } - return rv; - } - - - /* --- private Methoden --- */ - - private void buildRomBankMask() - { - int mask = 0; - if( this.romBank != null ) { - int nBanks = (this.romBank.size() + 0x1FFF) / 0x2000; - if( nBanks > 0 ) { - --nBanks; - while( (nBanks | mask) != mask ) { - mask = (mask << 1) | 1; - } - } - } - this.romBankMask = mask; - } - - - private boolean checkKeyMatrix( int[][] matrix, int ch ) - { - boolean rv = false; - if( ch > 0 ) { - for( int row = 0; !rv && (row < matrix.length); row++ ) { - int[] line = matrix[ row ]; - for( int col = 1; !rv && (col < line.length); col++ ) { - if( line[ col ] == ch ) { - if( col < this.keyMatrixCols.length ) { - this.keyMatrixCols[ col ] = (1 << row); - } - rv = true; - } - } - } + @Override + public int getPortValue(int port) { + int rv = 0xFF; + if (port == 3) { + rv &= ~0x04; // P32=0 + if (!this.tapeInPhase) { + rv &= ~0x01; // P30=0 + } + } + return rv; } - return rv; - } - - - private void checkSetZ8PreExecInstListener() - { - if( (this.osType != OSType.ES40) - || (this.tapeReader != null) - || (this.tapeWriter != null) - || (this.loudspeaker != null) ) - { - this.z8.setPreInstExecListener( this ); - } else { - this.z8.setPreInstExecListener( null ); - } - } - - - private String getScreenText( - int begAddr, - int nRows, - int nCols, - int rowDist, - int x1, - int y1, - int x2, - int y2 ) - { - StringBuilder buf = new StringBuilder( nRows * (nCols + 1) ); - int nNL = 0; - for( int i = y1; i < nRows; i++ ) { - if( i > y2 ) { - break; - } - if( i > y1 ) { - nNL++; - } - int addr = begAddr + (i * rowDist); - int nSpaces = 0; - for( int k = 0; k < nCols; k++ ) { - if( (i == y2) && (k > x2) ) { - break; - } - int b = getMemByte( addr++, false ); - if( (i > y1) || (k >= x1) ) { - if( b == 0x20 ) { - nSpaces++; - } else { - if( this.osType == OSType.ES40 ) { - switch( b ) { - case 0x1A: // ae - b = '\u00E4'; - break; - case 0x1B: // oe - b = '\u00F6'; - break; - case 0x1C: // ue - b = '\u00FC'; - break; - case 0x1D: // Ae - b = '\u00C4'; - break; - case 0x1E: // Oe - b = '\u00D6'; - break; - case 0x1F: // Ue - b = '\u00DC'; - break; - case 0x7F: // Ae - b = '\u00DF'; - break; - default: - if( (b < 0x1A) || (b > 0x7F) ) { - b = '_'; - } - } - } else { - if( (b < 0x20) || (b > 0x7E) ) { - b = '_'; - } else { - if( (this.osType == OSType.OS2K) - || (this.osType == OSType.ES1988) ) - { - if( b == 0x5C ) { - b = 0x5E; - } else if( b == 0x5E ) { - b = 0x5C; - } - } - } - } - while( nNL > 0 ) { - buf.append( (char) '\n' ); - --nNL; - } - while( nSpaces > 0 ) { - buf.append( (char) '\u0020' ); - --nSpaces; - } - buf.append( (char) b ); - } - } - } - } - return buf.toString(); - } - - - private void initRAM() - { - if( isRamInitZero() ) { - Arrays.fill( this.ram, (byte) 0 ); - Arrays.fill( this.ramV, (byte) 0 ); - Arrays.fill( this.ramB, (byte) 0 ); - Arrays.fill( this.ramG, (byte) 0 ); - Arrays.fill( this.ramR, (byte) 0 ); - } else { - this.random.nextBytes( this.ram ); - this.random.nextBytes( this.ramV ); - this.random.nextBytes( this.ramB ); - this.random.nextBytes( this.ramG ); - this.random.nextBytes( this.ramR ); - } - } - - - private static ExtROM[] readExtROMs( StringBuilder outErrText ) - { - ExtROM[] roms = null; - int n = AppContext.getIntProperty( PROP_ROM_COUNT, 0 ); - if( n > 0 ) { - java.util.List list = new ArrayList<>( n ); - for( int i = 0; i < n; i++ ) { - String addrText = AppContext.getProperty( getROMPropAddr( i ) ); - String fileName = AppContext.getProperty( getROMPropFile( i ) ); - if( (addrText != null) && (fileName != null) ) { - int addr = -1; - try { - if( addrText.startsWith( "%" ) ) { - addr = Integer.parseInt( addrText.substring( 1 ), 16 ); - } else { - addr = Integer.parseInt( addrText ); - } - if( (addr >= 0) && !fileName.isEmpty() ) { - ExtROM rom = new ExtROM( new File( fileName ), MAX_ROM_SIZE ); - rom.setBegAddr( addr ); - list.add( rom ); - } - } - catch( NumberFormatException ex ) {} - catch( IOException ex ) { - if( outErrText != null ) { - if( outErrText.length() > 0 ) { - outErrText.append( "\n\n" ); - } - outErrText.append( - String.format( - "Laden der externen ROM-Datei an Adresse %%%04X:\n", - addr ) ); - outErrText.append( ex.getMessage() ); - } - } - } - } - roms = list.toArray( new ExtROM[ list.size() ] ); - } - return roms != null ? roms : new ExtROM[ 0 ]; - } - - - private static int readMaxGPRNum() - { - return AppContext.getBooleanProperty( PROP_Z8_REGS_80_TO_EF, false ) ? - 0xEF : 0x7F; - } - - - private static OSType readOSType() - { - OSType osType = OSType.OS2K; - String text = AppContext.getProperty( PROP_OS ); - if( text != null ) { - for( OSType tmpOSType : OSType.values() ) { - if( text.equals( tmpOSType.toString() ) ) { - osType = tmpOSType; - break; - } - } - } - return osType; - } - - - private static int readRamSize() - { - int ramSize = 0x8000; // Standard: 32 KByte - String text = AppContext.getProperty( PROP_RAM_SIZE ); - if( text != null ) { - try { - text = text.toUpperCase().trim(); - int idx = text.indexOf( 'H' ); - if( idx > 0 ) { - ramSize = Integer.parseInt( - text.substring( 0, idx ).trim(), - 16 ); - } else { - idx = text.indexOf( 'K' ); - if( idx > 0 ) { - ramSize = Integer.parseInt( - text.substring( 0, idx ).trim() ) * 0x0400; - } else { - ramSize = Integer.parseInt( text ); - } - } - } - catch( NumberFormatException ex ) {} + + + @Override + public void setPortValue(int port, int value) { + if (port == 3) { + if (((value & 0x20) == 0) && ((this.port3Value & 0x20) != 0)) { + this.romBankNum = 0; + } else if (((value & 0x80) == 0) && ((this.port3Value & 0x80) != 0)) { + this.romBankNum = (this.romBankNum + 1) & this.romBankMask; + } + this.port3Value = value; + + if (this.osType == OSType.OS2K) { + value &= 0xC0; + this.tapeOutPhase = (value != 0xC0); + this.loudspeakerPhase = (value != 0x40); + } else { + this.tapeOutPhase = ((value & 0x40) != 0); + } + } } - return ramSize; - } - - - private byte[] readResource( String resource ) throws IOException - { - ByteArrayOutputStream buf = new ByteArrayOutputStream( 0x0800 ); - boolean done = false; - InputStream in = null; - try { - in = getClass().getResourceAsStream( resource ); - if( in != null ) { - int b = in.read(); - while( b >= 0 ) { - buf.write( b ); - b = in.read(); - } - done = true; - } + + + /* --- Z8Listener --- */ + + @Override + public void z8Update(Z8 z8, Z8Listener.Reason reason) { + if (z8 == this.z8) { + switch (reason) { + case PRE_INST_EXEC: + if ((z8.getPC() == ADDR_VIDEO_INTERRUPT) + && (this.osType != OSType.ES40)) { + this.lastScreenCycles = z8.getTotalCycles(); + } + AudioReader tapeReader = this.tapeReader; + if (tapeReader != null) { + if (this.osType == OSType.OS2K) { + this.tapeInPhase = tapeReader.readVolumeStatus(); + } else { + this.tapeInPhase = tapeReader.readPhase(); + } + } + AudioWriter tapeWriter = this.tapeWriter; + if (tapeWriter != null) { + tapeWriter.writePhase(this.tapeOutPhase); + } + AudioWriter loudspeaker = this.loudspeaker; + if (loudspeaker != null) { + loudspeaker.writePhase(this.loudspeakerPhase); + } + break; + + case POWER_ON: + case RESET: + resetInternal( + reason == Z8Listener.Reason.POWER_ON, + AppContext.getBooleanProperty(PROP_ROM_RELOAD, false)); + Z8Listener listener = this.resetListener; + if (listener != null) { + listener.z8Update(z8, reason); + } + break; + } + } } - catch( IOException ex ) {} - finally { - JTCUtil.closeSilently( in ); + + + /* --- Z8Memory --- */ + + @Override + public int getMemByte(int addr, boolean dataMem) { + addr &= 0xFFFF; + + int rv = 0xFF; + boolean done = false; + if ((addr >= 0x2000) && (addr < 0x4000)) { + ExtROM romBank = this.romBank; + if (romBank != null) { + rv = romBank.getByte((addr - 0x2000) + (this.romBankNum * 0x2000)); + done = true; + } + } + if (!done) { + for (ExtROM rom : this.extROMs) { + if ((addr >= rom.getBegAddr()) && (addr <= rom.getEndAddr())) { + rv = rom.getByte(addr); + done = true; + break; + } + } + } + if (!done) { + if ((addr >= 0) && (addr < this.u883rom.length)) { + rv = this.u883rom[addr]; + } else if ((addr >= 0x0800) && (addr - 0x0800 < this.rom0800.length)) { + rv = this.rom0800[addr - 0x0800]; + } else if ((addr >= 0x2000) && (addr - 0x2000 < this.rom2000.length)) { + rv = this.rom2000[addr - 0x2000]; + } else if ((addr >= 0x4000) && (addr <= 0x5FFF)) { + if (this.osType == OSType.ES40) { + int idx = addr - 0x4000; + if (this.videoV && (idx < this.ramV.length)) { + rv &= this.ramV[idx]; + } + if (this.videoB && (idx < this.ramB.length)) { + rv &= this.ramB[idx]; + } + if (this.videoG && (idx < this.ramG.length)) { + rv &= this.ramG[idx]; + } + if (this.videoR && (idx < this.ramR.length)) { + rv &= this.ramR[idx]; + } + } else { + if (addr >= 0x10000 - this.ramSize) { + rv = this.ram[addr]; + } + } + } else if ((addr >= 0x6000) && (addr < 0x8000)) { + if ((this.osType != OSType.ES40) || (addr >= 0x7000)) { + synchronized (this.keyMatrixCols) { + rv = (this.keyMatrixCols[addr & 0x000F] << 4) | 0x0F; + } + } + } else { + if ((ramSize == 0x0400) && (addr >= 0xE000)) { + int a = addr & 0x03FF; + if (a >= 0x0100) { + rv = this.ram[0xFD00 - 0x0100 + a]; + } else { + rv = this.ram[0xE000 + a]; + } + } else if ((ramSize == 0x0800) && (addr >= 0xE000)) { + int a = addr & 0x07FF; + if (a >= 0x0500) { + rv = this.ram[0xFD00 - 0x0500 + a]; + } else { + rv = this.ram[0xE000 + a]; + } + } else if (addr >= 0x10000 - this.ramSize) { + rv = this.ram[addr]; + } + } + } + return rv & 0xFF; } - if( !done ) { - throw new IOException( "Resource " + resource - + " kann nicht geladen werden." ); + + + @Override + public boolean setMemByte(int addr, boolean dataMem, int v) { + addr &= 0xFFFF; + + boolean rv = false; + boolean done = false; + if ((addr >= 0x2000) && (addr < 0x4000) && (this.romBank != null)) { + done = true; + } + if (!done) { + for (ExtROM rom : this.extROMs) { + if ((addr >= rom.getBegAddr()) && (addr <= rom.getEndAddr())) { + done = true; + break; + } + } + } + if (!done) { + int ramBegAddr = 0x10000 - this.ramSize; + if ((addr >= 0x1000) && (addr <= 0x17FF) + && (addr >= ramBegAddr) + && ((this.osType == OSType.OS2K) || (this.osType == OSType.ES1988))) { + this.ram[addr] = (byte) v; + rv = true; + } else if ((addr >= 0x1800) && (addr <= 0x1FFF) + && (addr >= ramBegAddr) + && (this.osType != OSType.ES40)) { + this.ram[addr] = (byte) v; + rv = true; + } else if ((addr >= 0x2000) && (addr <= 0x27FF) + && (addr >= ramBegAddr) + && (this.osType != OSType.ES1988)) { + this.ram[addr] = (byte) v; + rv = true; + } else if ((addr >= 0x2800) && (addr <= 0x3FFF) + && (addr >= ramBegAddr)) { + this.ram[addr] = (byte) v; + rv = true; + } else if ((addr >= 0x4000) && (addr <= 0x5FFF)) { + if (this.osType == OSType.ES40) { + int idx = addr - 0x4000; + boolean dirty = false; + if (this.videoV && (idx < this.ramV.length)) { + this.ramV[idx] = (byte) v; + dirty = true; + } + if (this.videoB && (idx < this.ramB.length)) { + this.ramB[idx] = (byte) v; + dirty = true; + } + if (this.videoG && (idx < this.ramG.length)) { + this.ramG[idx] = (byte) v; + dirty = true; + } + if (this.videoR && (idx < this.ramR.length)) { + this.ramR[idx] = (byte) v; + dirty = true; + } + if (dirty) { + setScreenDirty(); + } + } else { + if (addr >= ramBegAddr) { + this.ram[addr] = (byte) v; + rv = true; + } + } + } else if ((addr >= 0x6000) && (addr < 0x8000)) { + if ((this.osType == OSType.ES40) && (addr < 0x6400)) { + this.videoV = ((addr & 0x0010) == 0); + this.videoB = ((addr & 0x0020) == 0); + this.videoG = ((addr & 0x0040) == 0); + this.videoR = ((addr & 0x0080) == 0); + } + } else if (addr >= 0x8000) { + if ((ramSize == 0x0400) && (addr >= 0xE000)) { + int a = addr & 0x03FF; + if (a >= 0x0100) { + this.ram[0xFD00 - 0x0100 + a] = (byte) v; + if ((a >= 0x0200) + && ((this.osType == OSType.OS2K) + || (this.osType == OSType.ES1988))) { + setScreenDirty(); + } + } else { + this.ram[0xE000 + a] = (byte) v; + } + if (this.osType == OSType.ES23) { + setScreenDirty(); + } + rv = true; + } + if ((ramSize == 0x0800) && (addr >= 0xE000)) { + int a = addr & 0x7FF; + if (a >= 0x0500) { + this.ram[0xFD00 - 0x0500 + a] = (byte) v; + if ((a >= 0x0600) + && ((this.osType == OSType.OS2K) + || (this.osType == OSType.ES1988))) { + setScreenDirty(); + } + } else { + this.ram[0xE000 + a] = (byte) v; + } + if (this.osType == OSType.ES23) { + setScreenDirty(); + } + rv = true; + } else if (addr >= ramBegAddr) { + this.ram[addr] = (byte) v; + rv = true; + if (((addr >= 0xFE00) + && ((this.osType == OSType.OS2K) + || (this.osType == OSType.ES1988))) + || ((addr >= 0xF800) && (this.osType == OSType.ES23))) { + setScreenDirty(); + } + } + } + } + return rv; } - return buf.toByteArray(); - } - - - private static ExtROM readRomBank( StringBuilder outErrText ) - { - ExtROM romBank = null; - if( AppContext.getBooleanProperty( PROP_ROMBANK_ENABLED, false ) ) { - String file = AppContext.getProperty( PROP_ROMBANK_FILE ); - if( file != null ) { - try { - if( !file.isEmpty() ) { - romBank = new ExtROM( new File( file ), MAX_ROMBANK_SIZE ); - } - } - catch( IOException ex ) { - if( outErrText != null ) { - if( outErrText.length() > 0 ) { - outErrText.append( "\n\n" ); - } - outErrText.append( - "Laden der Datei f\u00FCr ROM-Bank:\n" ); - outErrText.append( ex.getMessage() ); - } - } - } + + + /* --- private Methoden --- */ + + private void buildRomBankMask() { + int mask = 0; + if (this.romBank != null) { + int nBanks = (this.romBank.size() + 0x1FFF) / 0x2000; + if (nBanks > 0) { + --nBanks; + while ((nBanks | mask) != mask) { + mask = (mask << 1) | 1; + } + } + } + this.romBankMask = mask; } - return romBank; - } - - - private void reload( ExtROM rom, String info, StringBuilder outErrText ) - { - if( (rom != null) - && AppContext.getBooleanProperty( PROP_ROM_RELOAD, false ) ) - { - try { - rom.reload(); - } - catch( IOException ex ) { - if( outErrText != null ) { - if( outErrText.length() > 0 ) { - outErrText.append( "\n\n" ); - } - outErrText.append( info ); - outErrText.append( " konnte nicht erneut geladen werden.\n" - + "Es bleibt der alte Inhalt erhalten." ); - } - } + + + private boolean checkKeyMatrix(int[][] matrix, int ch) { + boolean rv = false; + if (ch > 0) { + for (int row = 0; !rv && (row < matrix.length); row++) { + int[] line = matrix[row]; + for (int col = 1; !rv && (col < line.length); col++) { + if (line[col] == ch) { + if (col < this.keyMatrixCols.length) { + this.keyMatrixCols[col] = (1 << row); + } + rv = true; + } + } + } + } + return rv; } - } - - - private synchronized void resetInternal( - boolean powerOn, - boolean reloadEnabled ) - { - this.errorText = null; - this.port3Value = 0xFF; - this.romBankNum = 0; - this.shiftStatusSet = false; - Arrays.fill( this.keyMatrixCols, 0 ); - - StringBuilder outErrText = null; - if( this.newExtROMs != null ) { - this.extROMs = this.newExtROMs; - this.newExtROMs = null; + + + private void checkSetZ8PreExecInstListener() { + if ((this.osType != OSType.ES40) + || (this.tapeReader != null) + || (this.tapeWriter != null) + || (this.loudspeaker != null)) { + this.z8.setPreInstExecListener(this); + } else { + this.z8.setPreInstExecListener(null); + } } - if( reloadEnabled && powerOn ) { - if( this.extROMs.length > 0 ) { - outErrText = new StringBuilder(); - for( ExtROM rom : this.extROMs ) { - reload( - rom, - String.format( "ROM an Adresse %%%04X", rom.getBegAddr() ), - outErrText ); - } - } + + + private String getScreenText( + int begAddr, + int nRows, + int nCols, + int rowDist, + int x1, + int y1, + int x2, + int y2) { + StringBuilder buf = new StringBuilder(nRows * (nCols + 1)); + int nNL = 0; + for (int i = y1; i < nRows; i++) { + if (i > y2) { + break; + } + if (i > y1) { + nNL++; + } + int addr = begAddr + (i * rowDist); + int nSpaces = 0; + for (int k = 0; k < nCols; k++) { + if ((i == y2) && (k > x2)) { + break; + } + int b = getMemByte(addr++, false); + if ((i > y1) || (k >= x1)) { + if (b == 0x20) { + nSpaces++; + } else { + if (this.osType == OSType.ES40) { + switch (b) { + case 0x1A: // ae + b = '\u00E4'; + break; + case 0x1B: // oe + b = '\u00F6'; + break; + case 0x1C: // ue + b = '\u00FC'; + break; + case 0x1D: // Ae + b = '\u00C4'; + break; + case 0x1E: // Oe + b = '\u00D6'; + break; + case 0x1F: // Ue + b = '\u00DC'; + break; + case 0x7F: // Ae + b = '\u00DF'; + break; + default: + if ((b < 0x1A) || (b > 0x7F)) { + b = '_'; + } + } + } else { + if ((b < 0x20) || (b > 0x7E)) { + b = '_'; + } else { + if ((this.osType == OSType.OS2K) + || (this.osType == OSType.ES1988)) { + if (b == 0x5C) { + b = 0x5E; + } else if (b == 0x5E) { + b = 0x5C; + } + } + } + } + while (nNL > 0) { + buf.append((char) '\n'); + --nNL; + } + while (nSpaces > 0) { + buf.append((char) '\u0020'); + --nSpaces; + } + buf.append((char) b); + } + } + } + } + return buf.toString(); } - if( this.newRomBank != null ) { - if( this.newRomBank.length > 0 ) { - this.romBank = this.newRomBank [ 0 ]; - buildRomBankMask(); - } else { - this.romBank = null; - this.romBankMask = 0; - } - this.newRomBank = null; + + + private void initRAM() { + if (isRamInitZero()) { + Arrays.fill(this.ram, (byte) 0); + Arrays.fill(this.ramV, (byte) 0); + Arrays.fill(this.ramB, (byte) 0); + Arrays.fill(this.ramG, (byte) 0); + Arrays.fill(this.ramR, (byte) 0); + } else { + this.random.nextBytes(this.ram); + this.random.nextBytes(this.ramV); + this.random.nextBytes(this.ramB); + this.random.nextBytes(this.ramG); + this.random.nextBytes(this.ramR); + } } - if( reloadEnabled && powerOn && (this.romBank != null) ) { - if( outErrText == null ) { - outErrText = new StringBuilder(); - } - reload( this.romBank, "ROM-Bank", outErrText ); - buildRomBankMask(); + + + private static ExtROM[] readExtROMs(StringBuilder outErrText) { + ExtROM[] roms = null; + int n = AppContext.getIntProperty(PROP_ROM_COUNT, 0); + if (n > 0) { + java.util.List list = new ArrayList<>(n); + for (int i = 0; i < n; i++) { + String addrText = AppContext.getProperty(getROMPropAddr(i)); + String fileName = AppContext.getProperty(getROMPropFile(i)); + if ((addrText != null) && (fileName != null)) { + int addr = -1; + try { + if (addrText.startsWith("%")) { + addr = Integer.parseInt(addrText.substring(1), 16); + } else { + addr = Integer.parseInt(addrText); + } + if ((addr >= 0) && !fileName.isEmpty()) { + ExtROM rom = new ExtROM(new File(fileName), MAX_ROM_SIZE); + rom.setBegAddr(addr); + list.add(rom); + } + } catch (NumberFormatException ex) { + } catch (IOException ex) { + if (outErrText != null) { + if (outErrText.length() > 0) { + outErrText.append("\n\n"); + } + outErrText.append( + String.format( + "Laden der externen ROM-Datei an Adresse %%%04X:\n", + addr)); + outErrText.append(ex.getMessage()); + } + } + } + } + roms = list.toArray(new ExtROM[list.size()]); + } + return roms != null ? roms : new ExtROM[0]; } - if( outErrText != null ) { - if( outErrText.length() > 0 ) { - this.errorText = outErrText.toString(); - ErrorViewer errorViewer = this.errorViewer; - if( errorViewer != null ) { - errorViewer.showError( this.errorText ); - } - } + + + private static int readMaxGPRNum() { + return AppContext.getBooleanProperty(PROP_Z8_REGS_80_TO_EF, false) ? + 0xEF : 0x7F; } - if( this.newMaxGPRNum > 0 ) { - this.z8.setMaxGPRNum( this.newMaxGPRNum ); - this.newMaxGPRNum = 0; + + + private static OSType readOSType() { + OSType osType = OSType.OS2K; + String text = AppContext.getProperty(PROP_OS); + if (text != null) { + for (OSType tmpOSType : OSType.values()) { + if (text.equals(tmpOSType.toString())) { + osType = tmpOSType; + break; + } + } + } + return osType; } - if( this.newRamSize > 0 ) { - this.ramSize = this.newRamSize; - this.newRamSize = 0; + + + private static int readRamSize() { + int ramSize = 0x8000; // Standard: 32 KByte + String text = AppContext.getProperty(PROP_RAM_SIZE); + if (text != null) { + try { + text = text.toUpperCase().trim(); + int idx = text.indexOf('H'); + if (idx > 0) { + ramSize = Integer.parseInt( + text.substring(0, idx).trim(), + 16); + } else { + idx = text.indexOf('K'); + if (idx > 0) { + ramSize = Integer.parseInt( + text.substring(0, idx).trim()) * 0x0400; + } else { + ramSize = Integer.parseInt(text); + } + } + } catch (NumberFormatException ex) { + } + } + return ramSize; } - if( this.newOSType != null ) { - if( this.newOSType != this.osType ) { - powerOn = true; - } - this.osType = this.newOSType; - this.newOSType = null; + + + private byte[] readResource(String resource) throws IOException { + ByteArrayOutputStream buf = new ByteArrayOutputStream(0x0800); + boolean done = false; + InputStream in = null; + try { + in = getClass().getResourceAsStream(resource); + if (in != null) { + int b = in.read(); + while (b >= 0) { + buf.write(b); + b = in.read(); + } + done = true; + } + } catch (IOException ex) { + } finally { + JTCUtil.closeSilently(in); + } + if (!done) { + throw new IOException("Resource " + resource + + " kann nicht geladen werden."); + } + return buf.toByteArray(); } - if( powerOn ) { - initRAM(); + + + private static ExtROM readRomBank(StringBuilder outErrText) { + ExtROM romBank = null; + if (AppContext.getBooleanProperty(PROP_ROMBANK_ENABLED, false)) { + String file = AppContext.getProperty(PROP_ROMBANK_FILE); + if (file != null) { + try { + if (!file.isEmpty()) { + romBank = new ExtROM(new File(file), MAX_ROMBANK_SIZE); + } + } catch (IOException ex) { + if (outErrText != null) { + if (outErrText.length() > 0) { + outErrText.append("\n\n"); + } + outErrText.append( + "Laden der Datei f\u00FCr ROM-Bank:\n"); + outErrText.append(ex.getMessage()); + } + } + } + } + return romBank; } - int oldScreenWidth = this.screenWidth; - int oldScreenHeight = this.screenHeight; - boolean oldMonochrome = this.monochrome; - switch( this.osType ) { - case ES40: - this.monochrome = false; - this.screenWidth = 320; - this.screenHeight = 192; - this.charRaster = new CharRaster( 40, 24, 8, 8 ); - if( this.romBank != null ) { - this.rom0800 = this.es40RomBank_0800; - } else { - this.rom0800 = this.es40_0800; - } - this.rom2000 = new byte[ 0 ]; - break; - case ES23: - this.monochrome = true; - this.screenWidth = 128; - this.screenHeight = 128; - this.charRaster = new CharRaster( 16, 16, 8, 8 ); - this.rom0800 = this.es23_0800; - this.rom2000 = new byte[ 0 ]; - break; - case ES1988: - this.monochrome = true; - this.screenWidth = 64; - this.screenHeight = 64; - this.charRaster = new CharRaster( 13, 8, 5, 7, 0, 7 ); - this.rom0800 = this.es1988_0800; - this.rom2000 = this.es1988_2000; - break; - default: - this.monochrome = true; - this.screenWidth = 64; - this.screenHeight = 64; - this.charRaster = new CharRaster( 13, 8, 5, 7, 0, 7 ); - this.rom0800 = this.os2k_0800; - this.rom2000 = new byte[ 0 ]; + + private void reload(ExtROM rom, String info, StringBuilder outErrText) { + if ((rom != null) + && AppContext.getBooleanProperty(PROP_ROM_RELOAD, false)) { + try { + rom.reload(); + } catch (IOException ex) { + if (outErrText != null) { + if (outErrText.length() > 0) { + outErrText.append("\n\n"); + } + outErrText.append(info); + outErrText.append(" konnte nicht erneut geladen werden.\n" + + "Es bleibt der alte Inhalt erhalten."); + } + } + } } - JTCScreen screen = this.screen; - if( screen != null ) { - if( (this.monochrome != oldMonochrome) - || (this.screenWidth != oldScreenWidth) - || (this.screenHeight != oldScreenHeight) ) - { - screen.screenConfigChanged(); - } - screen.setScreenDirty(); + + + private synchronized void resetInternal( + boolean powerOn, + boolean reloadEnabled) { + this.errorText = null; + this.port3Value = 0xFF; + this.romBankNum = 0; + this.shiftStatusSet = false; + Arrays.fill(this.keyMatrixCols, 0); + + StringBuilder outErrText = null; + if (this.newExtROMs != null) { + this.extROMs = this.newExtROMs; + this.newExtROMs = null; + } + if (reloadEnabled && powerOn) { + if (this.extROMs.length > 0) { + outErrText = new StringBuilder(); + for (ExtROM rom : this.extROMs) { + reload( + rom, + String.format("ROM an Adresse %%%04X", rom.getBegAddr()), + outErrText); + } + } + } + if (this.newRomBank != null) { + if (this.newRomBank.length > 0) { + this.romBank = this.newRomBank[0]; + buildRomBankMask(); + } else { + this.romBank = null; + this.romBankMask = 0; + } + this.newRomBank = null; + } + if (reloadEnabled && powerOn && (this.romBank != null)) { + if (outErrText == null) { + outErrText = new StringBuilder(); + } + reload(this.romBank, "ROM-Bank", outErrText); + buildRomBankMask(); + } + if (outErrText != null) { + if (outErrText.length() > 0) { + this.errorText = outErrText.toString(); + ErrorViewer errorViewer = this.errorViewer; + if (errorViewer != null) { + errorViewer.showError(this.errorText); + } + } + } + if (this.newMaxGPRNum > 0) { + this.z8.setMaxGPRNum(this.newMaxGPRNum); + this.newMaxGPRNum = 0; + } + if (this.newRamSize > 0) { + this.ramSize = this.newRamSize; + this.newRamSize = 0; + } + if (this.newOSType != null) { + if (this.newOSType != this.osType) { + powerOn = true; + } + this.osType = this.newOSType; + this.newOSType = null; + } + if (powerOn) { + initRAM(); + } + + int oldScreenWidth = this.screenWidth; + int oldScreenHeight = this.screenHeight; + boolean oldMonochrome = this.monochrome; + switch (this.osType) { + case ES40: + this.monochrome = false; + this.screenWidth = 320; + this.screenHeight = 192; + this.charRaster = new CharRaster(40, 24, 8, 8); + if (this.romBank != null) { + this.rom0800 = this.es40RomBank_0800; + } else { + this.rom0800 = this.es40_0800; + } + this.rom2000 = new byte[0]; + break; + case ES23: + this.monochrome = true; + this.screenWidth = 128; + this.screenHeight = 128; + this.charRaster = new CharRaster(16, 16, 8, 8); + this.rom0800 = this.es23_0800; + this.rom2000 = new byte[0]; + break; + case ES1988: + this.monochrome = true; + this.screenWidth = 64; + this.screenHeight = 64; + this.charRaster = new CharRaster(13, 8, 5, 7, 0, 7); + this.rom0800 = this.es1988_0800; + this.rom2000 = this.es1988_2000; + break; + default: + this.monochrome = true; + this.screenWidth = 64; + this.screenHeight = 64; + this.charRaster = new CharRaster(13, 8, 5, 7, 0, 7); + this.rom0800 = this.os2k_0800; + this.rom2000 = new byte[0]; + } + JTCScreen screen = this.screen; + if (screen != null) { + if ((this.monochrome != oldMonochrome) + || (this.screenWidth != oldScreenWidth) + || (this.screenHeight != oldScreenHeight)) { + screen.screenConfigChanged(); + } + screen.setScreenDirty(); + } + checkSetZ8PreExecInstListener(); } - checkSetZ8PreExecInstListener(); - } - - - private void resetKeyMatrixStatus() - { - synchronized( this.keyMatrixCols ) { - Arrays.fill( this.keyMatrixCols, 0 ); - if( this.shiftStatusSet ) { - this.ram[ 0xFFFF ] = (byte) 0xFF; - this.shiftStatusSet = false; - } + + + private void resetKeyMatrixStatus() { + synchronized (this.keyMatrixCols) { + Arrays.fill(this.keyMatrixCols, 0); + if (this.shiftStatusSet) { + this.ram[0xFFFF] = (byte) 0xFF; + this.shiftStatusSet = false; + } + } } - } - - - private boolean setKeyMatrixStatus2kOrES1988( int ch ) - { - boolean rv = false; - resetKeyMatrixStatus(); - switch( ch ) { - case 0x0A: - case 0x1A: - this.keyMatrixCols[ 1 ] = 0x08; - rv = true; - break; - - case 0x0B: - case 0x1B: - this.keyMatrixCols[ 1 ] = 0x04; - rv = true; - break; - - case 0x20: - this.keyMatrixCols[ 1 ] = 0x01; - rv = true; - break; - - case 0x08: - case 0x18: - this.keyMatrixCols[ 12 ] = 0x08; - rv = true; - break; - - case 0x0D: - case 0x7F: - this.keyMatrixCols[ 12 ] = 0x01; - rv = true; - break; - - default: - if( (ch >= 'A') && (ch <= 'Z') ) { - this.ram[ 0xFFFF ] = (byte) 0; - } else { - ch = Character.toUpperCase( ch ); - } - if( this.osType == OSType.OS2K ) { - rv = checkKeyMatrix( keyMatrix2kNormal, ch ); - if( !rv ) { - if( checkKeyMatrix( keyMatrix2kShift, ch ) ) { - this.ram[ 0xFFFF ] = (byte) 0; - rv = true; - } - } - } else { - rv = checkKeyMatrix( keyMatrixES1988Normal, ch ); - if( !rv ) { - // Shift-Ebene identisch zum 2K-System - if( checkKeyMatrix( keyMatrix2kShift, ch ) ) { - this.ram[ 0xFFFF ] = (byte) 0; - rv = true; - } - } - } + + + private boolean setKeyMatrixStatus2kOrES1988(int ch) { + boolean rv = false; + resetKeyMatrixStatus(); + switch (ch) { + case 0x0A: + case 0x1A: + this.keyMatrixCols[1] = 0x08; + rv = true; + break; + + case 0x0B: + case 0x1B: + this.keyMatrixCols[1] = 0x04; + rv = true; + break; + + case 0x20: + this.keyMatrixCols[1] = 0x01; + rv = true; + break; + + case 0x08: + case 0x18: + this.keyMatrixCols[12] = 0x08; + rv = true; + break; + + case 0x0D: + case 0x7F: + this.keyMatrixCols[12] = 0x01; + rv = true; + break; + + default: + if ((ch >= 'A') && (ch <= 'Z')) { + this.ram[0xFFFF] = (byte) 0; + } else { + ch = Character.toUpperCase(ch); + } + if (this.osType == OSType.OS2K) { + rv = checkKeyMatrix(keyMatrix2kNormal, ch); + if (!rv) { + if (checkKeyMatrix(keyMatrix2kShift, ch)) { + this.ram[0xFFFF] = (byte) 0; + rv = true; + } + } + } else { + rv = checkKeyMatrix(keyMatrixES1988Normal, ch); + if (!rv) { + // Shift-Ebene identisch zum 2K-System + if (checkKeyMatrix(keyMatrix2kShift, ch)) { + this.ram[0xFFFF] = (byte) 0; + rv = true; + } + } + } + } + return rv; } - return rv; - } - - - private boolean setKeyMatrixStatusES23( int ch ) - { - boolean rv = false; - resetKeyMatrixStatus(); - switch( ch ) { - case 1: - this.keyMatrixCols[ 13 ] = 0x02; - rv = true; - break; - - case 2: - this.keyMatrixCols[ 15 ] = 0x02; - rv = true; - break; - - case 3: - this.keyMatrixCols[ 14 ] = 0x04; - rv = true; - break; - - case 4: - this.keyMatrixCols[ 14 ] = 0x01; - rv = true; - break; - - case 5: - this.keyMatrixCols[ 14 ] = 0x02; - rv = true; - break; - - case 7: - this.keyMatrixCols[ 13 ] = 0x04; - rv = true; - break; - - case 8: - this.keyMatrixCols[ 13 ] = 0x08; - rv = true; - break; - - case 9: - this.keyMatrixCols[ 14 ] = 0x08; - rv = true; - break; - - case 0x0C: - this.keyMatrixCols[ 15 ] = 0x08; - rv = true; - break; - - case 0x0D: - this.keyMatrixCols[ 11 ] = 0x01; - rv = true; - break; - - default: - rv = checkKeyMatrix( keyMatrixES23Normal, ch ); - if( !rv ) { - if( checkKeyMatrix( keyMatrixES23Shift, ch ) ) { - this.keyMatrixCols[ 0 ] = 0x01; - rv = true; - } else { - if( checkKeyMatrix( keyMatrixES23Control, ch ) ) { - this.keyMatrixCols[ 0 ] = 0x02; - rv = true; - } - } - } + + + private boolean setKeyMatrixStatusES23(int ch) { + boolean rv = false; + resetKeyMatrixStatus(); + switch (ch) { + case 1: + this.keyMatrixCols[13] = 0x02; + rv = true; + break; + + case 2: + this.keyMatrixCols[15] = 0x02; + rv = true; + break; + + case 3: + this.keyMatrixCols[14] = 0x04; + rv = true; + break; + + case 4: + this.keyMatrixCols[14] = 0x01; + rv = true; + break; + + case 5: + this.keyMatrixCols[14] = 0x02; + rv = true; + break; + + case 7: + this.keyMatrixCols[13] = 0x04; + rv = true; + break; + + case 8: + this.keyMatrixCols[13] = 0x08; + rv = true; + break; + + case 9: + this.keyMatrixCols[14] = 0x08; + rv = true; + break; + + case 0x0C: + this.keyMatrixCols[15] = 0x08; + rv = true; + break; + + case 0x0D: + this.keyMatrixCols[11] = 0x01; + rv = true; + break; + + default: + rv = checkKeyMatrix(keyMatrixES23Normal, ch); + if (!rv) { + if (checkKeyMatrix(keyMatrixES23Shift, ch)) { + this.keyMatrixCols[0] = 0x01; + rv = true; + } else { + if (checkKeyMatrix(keyMatrixES23Control, ch)) { + this.keyMatrixCols[0] = 0x02; + rv = true; + } + } + } + } + return rv; } - return rv; - } - - - private boolean setKeyMatrixStatusES40( int ch ) - { - boolean rv = false; - resetKeyMatrixStatus(); - if( ch == '\u00DF' ) { - this.keyMatrixCols[ 1 ] = 0x04; - this.keyMatrixCols[ 12 ] = 0x08; - rv = true; - } else { - rv = checkKeyMatrix( keyMatrixES40Normal, ch ); - if( !rv ) { - if( checkKeyMatrix( keyMatrixES40Shift1, ch ) ) { - this.keyMatrixCols[ 1 ] = 0x01; - rv = true; - } else { - if( checkKeyMatrix( keyMatrixES40Shift2, ch ) ) { - this.keyMatrixCols[ 1 ] = 0x02; - rv = true; - } - } - } + + + private boolean setKeyMatrixStatusES40(int ch) { + boolean rv = false; + resetKeyMatrixStatus(); + if (ch == '\u00DF') { + this.keyMatrixCols[1] = 0x04; + this.keyMatrixCols[12] = 0x08; + rv = true; + } else { + rv = checkKeyMatrix(keyMatrixES40Normal, ch); + if (!rv) { + if (checkKeyMatrix(keyMatrixES40Shift1, ch)) { + this.keyMatrixCols[1] = 0x01; + rv = true; + } else { + if (checkKeyMatrix(keyMatrixES40Shift2, ch)) { + this.keyMatrixCols[1] = 0x02; + rv = true; + } + } + } + } + return rv; } - return rv; - } - private void setScreenDirty() - { - JTCScreen screen = this.screen; - if( screen != null ) { - screen.setScreenDirty(); + private void setScreenDirty() { + JTCScreen screen = this.screen; + if (screen != null) { + screen.setScreenDirty(); + } } - } - private void setShift( boolean state ) - { - this.ram[ 0xFFFF ] = (byte) (state ? 0 : 0xFF); - this.shiftStatusSet = true; - } + private void setShift(boolean state) { + this.ram[0xFFFF] = (byte) (state ? 0 : 0xFF); + this.shiftStatusSet = true; + } }