Refining core interface, setROM() behavior validated
This commit is contained in:
		
							parent
							
								
									b86c046dd5
								
							
						
					
					
						commit
						030fc96fc7
					
				
							
								
								
									
										11
									
								
								makefile
								
								
								
								
							
							
						
						
									
										11
									
								
								makefile
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
# Java include directory pathnames
 | 
			
		||||
# The Windows files need to be copied from a Windows JDK installation
 | 
			
		||||
include_linux   = /usr/lib/jvm/java-13-openjdk-`\
 | 
			
		||||
include_linux   = /usr/lib/jvm/java-14-openjdk-`\
 | 
			
		||||
    uname -r | sed 's/.*-//'`/include
 | 
			
		||||
include_windows = jni-windows-include
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,12 +10,12 @@ default:
 | 
			
		|||
	@echo
 | 
			
		||||
	@echo "Planet Virtual Boy Emulator"
 | 
			
		||||
	@echo "  https://www.planetvb.com/"
 | 
			
		||||
	@echo "  July 30, 2020"
 | 
			
		||||
	@echo "  August 3, 2020"
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "Intended build environment: Debian i386 or amd64"
 | 
			
		||||
	@echo "  gcc-multilib"
 | 
			
		||||
	@echo "  mingw-w64"
 | 
			
		||||
	@echo "  openjdk-13-jdk"
 | 
			
		||||
	@echo "  openjdk-14-jdk"
 | 
			
		||||
	@echo
 | 
			
		||||
	@echo "Usage: make <recipe>"
 | 
			
		||||
	@echo "  Package recipes:"
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ core:
 | 
			
		|||
desktop: clean_desktop
 | 
			
		||||
	@echo "  Compiling Java desktop application"
 | 
			
		||||
	@javac -sourcepath src/desktop --release 10 -Xlint:unchecked \
 | 
			
		||||
        -d . src/desktop/Main.java
 | 
			
		||||
        -h src/desktop/native -d . src/desktop/Main.java
 | 
			
		||||
 | 
			
		||||
# Build all native modules
 | 
			
		||||
.PHONY: native
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +112,7 @@ clean_most: clean_desktop
 | 
			
		|||
src/desktop/native/vue_NativeVUE.h: src/desktop/vue/NativeVUE.java
 | 
			
		||||
	@javac -h src/desktop/native -sourcepath src/desktop -d . \
 | 
			
		||||
        src/desktop/vue/NativeVUE.java
 | 
			
		||||
	@sleep 3
 | 
			
		||||
 | 
			
		||||
# linux_x86
 | 
			
		||||
.PHONY: lin32_pre
 | 
			
		||||
| 
						 | 
				
			
			@ -159,6 +160,6 @@ win64: win64_pre native_common
 | 
			
		|||
.PHONY: native_common
 | 
			
		||||
native_common:
 | 
			
		||||
	@echo "  Building native module $(name)"
 | 
			
		||||
	@$(prefix)gcc $(include) -Isrc/core/include $(gccargs) -s -shared -Os \
 | 
			
		||||
	@$(prefix)gcc $(include) -Isrc/core/include $(gccargs) -s -shared -O2 \
 | 
			
		||||
        -fno-strict-aliasing \
 | 
			
		||||
        -o native/$(name)$(ext) src/desktop/native/native.c src/core/vue.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,8 +19,8 @@ public class Main {
 | 
			
		|||
        for (String filename : Util.listFiles("native")) {
 | 
			
		||||
            File file = null;
 | 
			
		||||
 | 
			
		||||
            // Skip .gitignore
 | 
			
		||||
            if (filename.equals(".gitignore"))
 | 
			
		||||
            // Skip any file that isn't a shared object library
 | 
			
		||||
            if (!filename.endsWith(".dll") && !filename.endsWith(".so"))
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            // Write the contents of the native object file
 | 
			
		||||
| 
						 | 
				
			
			@ -33,15 +33,17 @@ public class Main {
 | 
			
		|||
            try { stream.close(); } catch (Exception e) { }
 | 
			
		||||
 | 
			
		||||
            // Load the native object file into the JVM
 | 
			
		||||
            try { System.load(file.getAbsolutePath()); break; }
 | 
			
		||||
            try {
 | 
			
		||||
                System.load(file.getAbsolutePath());
 | 
			
		||||
                VUE.setNativeID(filename.substring(0,
 | 
			
		||||
                    filename.lastIndexOf(".")));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Error e) { }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Begin application operations
 | 
			
		||||
        new App();
 | 
			
		||||
 | 
			
		||||
        var vue = VUE.create(true);
 | 
			
		||||
        System.out.println(vue.isNative());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import java.util.*;
 | 
			
		|||
 | 
			
		||||
// Project imports
 | 
			
		||||
import util.*;
 | 
			
		||||
import vue.*;
 | 
			
		||||
 | 
			
		||||
// Top-level software state manager
 | 
			
		||||
public class App {
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +13,7 @@ public class App {
 | 
			
		|||
    // Instance fields
 | 
			
		||||
    private Localizer.Locale[] locales;   // Language translations
 | 
			
		||||
    private Localizer          localizer; // UI localization manager
 | 
			
		||||
    private boolean            useNative; // Produce native core contexts
 | 
			
		||||
    private ArrayList<Window>  windows;   // Application windows
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,10 +26,11 @@ public class App {
 | 
			
		|||
    public App() {
 | 
			
		||||
 | 
			
		||||
        // Instance fields
 | 
			
		||||
        localizer = new Localizer();
 | 
			
		||||
        windows   = new ArrayList<Window>();
 | 
			
		||||
        localizer     = new Localizer();
 | 
			
		||||
        windows       = new ArrayList<Window>();
 | 
			
		||||
 | 
			
		||||
        // Additional processing
 | 
			
		||||
        setUseNative(true);
 | 
			
		||||
        initLocales();
 | 
			
		||||
        addWindow();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +52,11 @@ public class App {
 | 
			
		|||
        return localizer.getLocale();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Determine whether the native module is in use
 | 
			
		||||
    boolean getUseNative() {
 | 
			
		||||
        return useNative;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Retrieve the localization manager
 | 
			
		||||
    Localizer getLocalizer() {
 | 
			
		||||
        return localizer;
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +85,11 @@ public class App {
 | 
			
		|||
        localizer.setLocale(locale);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Specify whether using the native module
 | 
			
		||||
    boolean setUseNative(boolean useNative) {
 | 
			
		||||
        return this.useNative = useNative && VUE.isNativeLoaded();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ import javax.swing.filechooser.*;
 | 
			
		|||
 | 
			
		||||
// Project imports
 | 
			
		||||
import util.*;
 | 
			
		||||
import vue.*;
 | 
			
		||||
 | 
			
		||||
// Main application window
 | 
			
		||||
class Window extends JFrame {
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +20,7 @@ class Window extends JFrame {
 | 
			
		|||
    private boolean only;    // This is the only application window
 | 
			
		||||
    private ROM     rom;     // Currently loaded ROM
 | 
			
		||||
    private File    romFile; // Currently loaded ROM file
 | 
			
		||||
    private VUE     vue;     // Emulation core context
 | 
			
		||||
 | 
			
		||||
    // UI components
 | 
			
		||||
    private File   pwd;   // Most recent working directory
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +52,8 @@ class Window extends JFrame {
 | 
			
		|||
 | 
			
		||||
        // Configure instance fields
 | 
			
		||||
        this.app = app;
 | 
			
		||||
        pwd      = Util.PWD;
 | 
			
		||||
        vue      = VUE.create(app.getUseNative());
 | 
			
		||||
 | 
			
		||||
        // Configure video pane
 | 
			
		||||
        video = new JPanel() {
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +142,7 @@ class Window extends JFrame {
 | 
			
		|||
    private void onClose() {
 | 
			
		||||
        app.removeWindow(this);
 | 
			
		||||
        dispose();
 | 
			
		||||
        vue.dispose();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // File -> Load ROM
 | 
			
		||||
| 
						 | 
				
			
			@ -185,11 +190,17 @@ class Window extends JFrame {
 | 
			
		|||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Update the emulation state
 | 
			
		||||
        // Update instance fields
 | 
			
		||||
        this.rom = rom;
 | 
			
		||||
        romFile  = file;
 | 
			
		||||
        loc.put(this, "ctrl.filename", file.getName());
 | 
			
		||||
        updateTitle();
 | 
			
		||||
 | 
			
		||||
        // Update the emulation state
 | 
			
		||||
        var bytes = rom.toByteArray();
 | 
			
		||||
        // Pause emulation
 | 
			
		||||
        vue.setROM(bytes, 0, bytes.length);
 | 
			
		||||
        // Resume emulation
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // File -> New window
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,72 @@
 | 
			
		|||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <jni.h>
 | 
			
		||||
#include "vue_NativeVUE.h"
 | 
			
		||||
 | 
			
		||||
// NativeVUE class lookup data
 | 
			
		||||
static struct {
 | 
			
		||||
    jclass   clazz;   // Handle to NativeVUE class
 | 
			
		||||
    jfieldID pointer; // ID of NativeVUE.pointer field
 | 
			
		||||
} NativeVUE;
 | 
			
		||||
 | 
			
		||||
// Core context state type
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint8_t *rom;
 | 
			
		||||
    uint32_t rom_size;
 | 
			
		||||
} CORE;
 | 
			
		||||
 | 
			
		||||
// Retrieve the handle to a NativeVUE's core context
 | 
			
		||||
static CORE* GetCore(JNIEnv *env, jobject vue) {
 | 
			
		||||
    jbyteArray pointer =
 | 
			
		||||
        (*env)->GetObjectField(env, vue, NativeVUE.pointer);
 | 
			
		||||
    jbyte     *elems   = (*env)->GetByteArrayElements(env, pointer, NULL);
 | 
			
		||||
    CORE      *core    = *(CORE **)elems;
 | 
			
		||||
    (*env)->ReleaseByteArrayElements(env, pointer, elems, 0);
 | 
			
		||||
    return core;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Native constructor
 | 
			
		||||
JNIEXPORT void JNICALL Java_vue_NativeVUE_construct
 | 
			
		||||
  (JNIEnv *env, jobject vue) {
 | 
			
		||||
 | 
			
		||||
    // Initialize the class data
 | 
			
		||||
    if (NativeVUE.clazz == NULL) {
 | 
			
		||||
        NativeVUE.clazz   = (*env)->GetObjectClass(env, vue);
 | 
			
		||||
        NativeVUE.pointer =
 | 
			
		||||
            (*env)->GetFieldID(env, NativeVUE.clazz, "pointer", "[B");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Produce and initialize s new core context
 | 
			
		||||
    CORE *core = calloc(sizeof (CORE), 1);
 | 
			
		||||
    core->rom  = calloc(1024, 1);
 | 
			
		||||
 | 
			
		||||
    // Encode the context handle into a byte array
 | 
			
		||||
    jbyteArray pointer = (*env)->NewByteArray(env, sizeof (void *));
 | 
			
		||||
    jbyte     *elems   = (*env)->GetByteArrayElements(env, pointer, NULL);
 | 
			
		||||
    *(CORE **)elems = core;
 | 
			
		||||
    (*env)->ReleaseByteArrayElements(env, pointer, elems, 0);
 | 
			
		||||
    (*env)->SetObjectField(env, vue, NativeVUE.pointer, pointer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Release any used resources
 | 
			
		||||
JNIEXPORT void JNICALL Java_vue_NativeVUE_dispose
 | 
			
		||||
  (JNIEnv *env, jobject vue) {
 | 
			
		||||
    CORE *core = GetCore(env, vue);
 | 
			
		||||
    free(core->rom);
 | 
			
		||||
    free(core);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Retrieve a copy of the ROM data
 | 
			
		||||
JNIEXPORT jbyteArray JNICALL Java_vue_NativeVUE_getROM
 | 
			
		||||
  (JNIEnv *env, jobject vue) {
 | 
			
		||||
    CORE *core = GetCore(env, vue);
 | 
			
		||||
    jbyteArray ret   = (*env)->NewByteArray(env, (jint) core->rom_size);
 | 
			
		||||
    jbyte     *elems = (*env)->GetByteArrayElements(env, ret, NULL);
 | 
			
		||||
    memcpy(elems, core->rom, core->rom_size);
 | 
			
		||||
    (*env)->ReleaseByteArrayElements(env, ret, elems, 0);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Determine whether the context is native-backed
 | 
			
		||||
| 
						 | 
				
			
			@ -18,19 +78,20 @@ JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_isNative
 | 
			
		|||
// Provide new ROM data
 | 
			
		||||
JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_setROM
 | 
			
		||||
  (JNIEnv *env, jobject vue, jbyteArray data, jint offset, jint length) {
 | 
			
		||||
    jsize data_length = (*env)->GetArrayLength(env, data);
 | 
			
		||||
 | 
			
		||||
    // Error checking
 | 
			
		||||
    if (data == NULL || offset < 0 || length < 1024 ||
 | 
			
		||||
        offset + length > data_length || (length & length - 1) != 0)
 | 
			
		||||
        offset + length > (*env)->GetArrayLength(env, data) ||
 | 
			
		||||
        (length & length - 1) != 0)
 | 
			
		||||
        return JNI_FALSE;
 | 
			
		||||
 | 
			
		||||
    // Accept the new ROM data
 | 
			
		||||
    return JNI_TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Invoke native code to ensure the module is loaded
 | 
			
		||||
JNIEXPORT jboolean JNICALL Java_vue_NativeVUE_testNative
 | 
			
		||||
  (JNIEnv *env, jclass vue) {
 | 
			
		||||
    CORE *core = GetCore(env, vue);
 | 
			
		||||
    free(core->rom);
 | 
			
		||||
    core->rom = calloc(length, 1);
 | 
			
		||||
    jbyte *elems = (*env)->GetByteArrayElements(env, data, NULL);
 | 
			
		||||
    memcpy(core->rom, &elems[offset], length);
 | 
			
		||||
    (*env)->ReleaseByteArrayElements(env, data, elems, 0);
 | 
			
		||||
    core->rom_size = (uint32_t) length;
 | 
			
		||||
    return JNI_TRUE;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,9 @@ public final class Util {
 | 
			
		|||
    //                               Constants                               //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Directory from which the JVM was initialized
 | 
			
		||||
    public static final File PWD = new File(System.getProperty("user.dir"));
 | 
			
		||||
 | 
			
		||||
    // Text file byte-order marks
 | 
			
		||||
    private static final BOM[] BOMS = {
 | 
			
		||||
        new BOM(new byte[] { -17, -69, -65 }, StandardCharsets.UTF_8   ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,7 @@
 | 
			
		|||
package vue;
 | 
			
		||||
 | 
			
		||||
// Java emulation core implementation
 | 
			
		||||
// Native-backed emulation core implementation
 | 
			
		||||
class JavaVUE implements VUE {
 | 
			
		||||
class JavaVUE extends VUE {
 | 
			
		||||
 | 
			
		||||
    // Instance fields
 | 
			
		||||
    private byte[] rom; // Cartridge ROM
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +23,9 @@ class JavaVUE implements VUE {
 | 
			
		|||
    //                            Public Methods                             //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Release any used resources
 | 
			
		||||
    public void dispose() { }; // No action needed
 | 
			
		||||
 | 
			
		||||
    // Retrieve a copy of the ROM data
 | 
			
		||||
    public byte[] getROM() {
 | 
			
		||||
        var ret = new byte[rom.length];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
package vue;
 | 
			
		||||
 | 
			
		||||
// Native-backed emulation core implementation
 | 
			
		||||
class NativeVUE implements VUE {
 | 
			
		||||
class NativeVUE extends VUE {
 | 
			
		||||
 | 
			
		||||
    // Instance fields
 | 
			
		||||
    private byte[] pointer; // Instance address in native memory
 | 
			
		||||
    private byte[] pointer; // Context address in native memory
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -14,18 +14,7 @@ class NativeVUE implements VUE {
 | 
			
		|||
 | 
			
		||||
    // Default constructor
 | 
			
		||||
    NativeVUE() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    //                            Package Methods                            //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Determine whether the native library has been loaded
 | 
			
		||||
    static boolean isLoaded() {
 | 
			
		||||
        try { return testNative(); }
 | 
			
		||||
        catch (Exception e) { return false; }
 | 
			
		||||
        construct();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +23,9 @@ class NativeVUE implements VUE {
 | 
			
		|||
    //                            Public Methods                             //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Release any used resources
 | 
			
		||||
    public native void dispose();
 | 
			
		||||
 | 
			
		||||
    // Retrieve a copy of the ROM data
 | 
			
		||||
    public native byte[] getROM();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +41,7 @@ class NativeVUE implements VUE {
 | 
			
		|||
    //                            Private Methods                            //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Invoke native code to ensure the module is loaded
 | 
			
		||||
    private static native boolean testNative();
 | 
			
		||||
    // Native constructor
 | 
			
		||||
    private native void construct();
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,36 @@
 | 
			
		|||
package vue;
 | 
			
		||||
 | 
			
		||||
// Template for emulation core implementations
 | 
			
		||||
public interface VUE {
 | 
			
		||||
public abstract class VUE {
 | 
			
		||||
 | 
			
		||||
    // Static fields
 | 
			
		||||
    private static String nativeID = null; // ID of loaded native library
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    //                            Factory Methods                            //
 | 
			
		||||
    //                               Static Methods                          //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Produce an emulation core context
 | 
			
		||||
    public static VUE create(boolean useNative) {
 | 
			
		||||
        return !useNative ? new JavaVUE() :
 | 
			
		||||
            NativeVUE.isLoaded() ? new NativeVUE() : null;
 | 
			
		||||
            isNativeLoaded() ? new NativeVUE() : null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Retrieve the ID of the loaded native library, if any
 | 
			
		||||
    public static String getNativeID() {
 | 
			
		||||
        return nativeID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Determine whether the native module is loaded
 | 
			
		||||
    public static boolean isNativeLoaded() {
 | 
			
		||||
        return nativeID != null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Specify the ID of the loaded native library
 | 
			
		||||
    public static void setNativeID(String nativeID) {
 | 
			
		||||
        VUE.nativeID = nativeID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,13 +39,16 @@ public interface VUE {
 | 
			
		|||
    //                            Public Methods                             //
 | 
			
		||||
    ///////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Release any used resources
 | 
			
		||||
    public abstract void dispose();
 | 
			
		||||
 | 
			
		||||
    // Retrieve a copy of the ROM data
 | 
			
		||||
    byte[] getROM();
 | 
			
		||||
    public abstract byte[] getROM();
 | 
			
		||||
 | 
			
		||||
    // Determine whether the context is native-backed
 | 
			
		||||
    boolean isNative();
 | 
			
		||||
    public abstract boolean isNative();
 | 
			
		||||
 | 
			
		||||
    // Provide new ROM data
 | 
			
		||||
    boolean setROM(byte[] data, int offset, int length);
 | 
			
		||||
    public abstract boolean setROM(byte[] data, int offset, int length);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue