Introducing VIP memory controller and Characters window, fixing Format V instructions, adjusting JNI includes

This commit is contained in:
Guy Perfect 2020-12-25 17:59:08 -06:00
parent 9f5a5233ea
commit 8192fb6960
36 changed files with 7343 additions and 178 deletions

View File

@ -0,0 +1,588 @@
/*
* Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef CLASSFILE_CONSTANTS_H
#define CLASSFILE_CONSTANTS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Classfile version number for this information */
#define JVM_CLASSFILE_MAJOR_VERSION 59
#define JVM_CLASSFILE_MINOR_VERSION 0
/* Flags */
enum {
JVM_ACC_PUBLIC = 0x0001,
JVM_ACC_PRIVATE = 0x0002,
JVM_ACC_PROTECTED = 0x0004,
JVM_ACC_STATIC = 0x0008,
JVM_ACC_FINAL = 0x0010,
JVM_ACC_SYNCHRONIZED = 0x0020,
JVM_ACC_SUPER = 0x0020,
JVM_ACC_VOLATILE = 0x0040,
JVM_ACC_BRIDGE = 0x0040,
JVM_ACC_TRANSIENT = 0x0080,
JVM_ACC_VARARGS = 0x0080,
JVM_ACC_NATIVE = 0x0100,
JVM_ACC_INTERFACE = 0x0200,
JVM_ACC_ABSTRACT = 0x0400,
JVM_ACC_STRICT = 0x0800,
JVM_ACC_SYNTHETIC = 0x1000,
JVM_ACC_ANNOTATION = 0x2000,
JVM_ACC_ENUM = 0x4000,
JVM_ACC_MODULE = 0x8000
};
#define JVM_ACC_PUBLIC_BIT 0
#define JVM_ACC_PRIVATE_BIT 1
#define JVM_ACC_PROTECTED_BIT 2
#define JVM_ACC_STATIC_BIT 3
#define JVM_ACC_FINAL_BIT 4
#define JVM_ACC_SYNCHRONIZED_BIT 5
#define JVM_ACC_SUPER_BIT 5
#define JVM_ACC_VOLATILE_BIT 6
#define JVM_ACC_BRIDGE_BIT 6
#define JVM_ACC_TRANSIENT_BIT 7
#define JVM_ACC_VARARGS_BIT 7
#define JVM_ACC_NATIVE_BIT 8
#define JVM_ACC_INTERFACE_BIT 9
#define JVM_ACC_ABSTRACT_BIT 10
#define JVM_ACC_STRICT_BIT 11
#define JVM_ACC_SYNTHETIC_BIT 12
#define JVM_ACC_ANNOTATION_BIT 13
#define JVM_ACC_ENUM_BIT 14
/* Used in newarray instruction. */
enum {
JVM_T_BOOLEAN = 4,
JVM_T_CHAR = 5,
JVM_T_FLOAT = 6,
JVM_T_DOUBLE = 7,
JVM_T_BYTE = 8,
JVM_T_SHORT = 9,
JVM_T_INT = 10,
JVM_T_LONG = 11
};
/* Constant Pool Entries */
enum {
JVM_CONSTANT_Utf8 = 1,
JVM_CONSTANT_Unicode = 2, /* unused */
JVM_CONSTANT_Integer = 3,
JVM_CONSTANT_Float = 4,
JVM_CONSTANT_Long = 5,
JVM_CONSTANT_Double = 6,
JVM_CONSTANT_Class = 7,
JVM_CONSTANT_String = 8,
JVM_CONSTANT_Fieldref = 9,
JVM_CONSTANT_Methodref = 10,
JVM_CONSTANT_InterfaceMethodref = 11,
JVM_CONSTANT_NameAndType = 12,
JVM_CONSTANT_MethodHandle = 15, // JSR 292
JVM_CONSTANT_MethodType = 16, // JSR 292
JVM_CONSTANT_Dynamic = 17,
JVM_CONSTANT_InvokeDynamic = 18,
JVM_CONSTANT_Module = 19,
JVM_CONSTANT_Package = 20,
JVM_CONSTANT_ExternalMax = 20
};
/* JVM_CONSTANT_MethodHandle subtypes */
enum {
JVM_REF_getField = 1,
JVM_REF_getStatic = 2,
JVM_REF_putField = 3,
JVM_REF_putStatic = 4,
JVM_REF_invokeVirtual = 5,
JVM_REF_invokeStatic = 6,
JVM_REF_invokeSpecial = 7,
JVM_REF_newInvokeSpecial = 8,
JVM_REF_invokeInterface = 9
};
/* StackMapTable type item numbers */
enum {
JVM_ITEM_Top = 0,
JVM_ITEM_Integer = 1,
JVM_ITEM_Float = 2,
JVM_ITEM_Double = 3,
JVM_ITEM_Long = 4,
JVM_ITEM_Null = 5,
JVM_ITEM_UninitializedThis = 6,
JVM_ITEM_Object = 7,
JVM_ITEM_Uninitialized = 8
};
/* Type signatures */
enum {
JVM_SIGNATURE_SLASH = '/',
JVM_SIGNATURE_DOT = '.',
JVM_SIGNATURE_SPECIAL = '<',
JVM_SIGNATURE_ENDSPECIAL = '>',
JVM_SIGNATURE_ARRAY = '[',
JVM_SIGNATURE_BYTE = 'B',
JVM_SIGNATURE_CHAR = 'C',
JVM_SIGNATURE_CLASS = 'L',
JVM_SIGNATURE_ENDCLASS = ';',
JVM_SIGNATURE_ENUM = 'E',
JVM_SIGNATURE_FLOAT = 'F',
JVM_SIGNATURE_DOUBLE = 'D',
JVM_SIGNATURE_FUNC = '(',
JVM_SIGNATURE_ENDFUNC = ')',
JVM_SIGNATURE_INT = 'I',
JVM_SIGNATURE_LONG = 'J',
JVM_SIGNATURE_SHORT = 'S',
JVM_SIGNATURE_VOID = 'V',
JVM_SIGNATURE_BOOLEAN = 'Z'
};
/* Opcodes */
enum {
JVM_OPC_nop = 0,
JVM_OPC_aconst_null = 1,
JVM_OPC_iconst_m1 = 2,
JVM_OPC_iconst_0 = 3,
JVM_OPC_iconst_1 = 4,
JVM_OPC_iconst_2 = 5,
JVM_OPC_iconst_3 = 6,
JVM_OPC_iconst_4 = 7,
JVM_OPC_iconst_5 = 8,
JVM_OPC_lconst_0 = 9,
JVM_OPC_lconst_1 = 10,
JVM_OPC_fconst_0 = 11,
JVM_OPC_fconst_1 = 12,
JVM_OPC_fconst_2 = 13,
JVM_OPC_dconst_0 = 14,
JVM_OPC_dconst_1 = 15,
JVM_OPC_bipush = 16,
JVM_OPC_sipush = 17,
JVM_OPC_ldc = 18,
JVM_OPC_ldc_w = 19,
JVM_OPC_ldc2_w = 20,
JVM_OPC_iload = 21,
JVM_OPC_lload = 22,
JVM_OPC_fload = 23,
JVM_OPC_dload = 24,
JVM_OPC_aload = 25,
JVM_OPC_iload_0 = 26,
JVM_OPC_iload_1 = 27,
JVM_OPC_iload_2 = 28,
JVM_OPC_iload_3 = 29,
JVM_OPC_lload_0 = 30,
JVM_OPC_lload_1 = 31,
JVM_OPC_lload_2 = 32,
JVM_OPC_lload_3 = 33,
JVM_OPC_fload_0 = 34,
JVM_OPC_fload_1 = 35,
JVM_OPC_fload_2 = 36,
JVM_OPC_fload_3 = 37,
JVM_OPC_dload_0 = 38,
JVM_OPC_dload_1 = 39,
JVM_OPC_dload_2 = 40,
JVM_OPC_dload_3 = 41,
JVM_OPC_aload_0 = 42,
JVM_OPC_aload_1 = 43,
JVM_OPC_aload_2 = 44,
JVM_OPC_aload_3 = 45,
JVM_OPC_iaload = 46,
JVM_OPC_laload = 47,
JVM_OPC_faload = 48,
JVM_OPC_daload = 49,
JVM_OPC_aaload = 50,
JVM_OPC_baload = 51,
JVM_OPC_caload = 52,
JVM_OPC_saload = 53,
JVM_OPC_istore = 54,
JVM_OPC_lstore = 55,
JVM_OPC_fstore = 56,
JVM_OPC_dstore = 57,
JVM_OPC_astore = 58,
JVM_OPC_istore_0 = 59,
JVM_OPC_istore_1 = 60,
JVM_OPC_istore_2 = 61,
JVM_OPC_istore_3 = 62,
JVM_OPC_lstore_0 = 63,
JVM_OPC_lstore_1 = 64,
JVM_OPC_lstore_2 = 65,
JVM_OPC_lstore_3 = 66,
JVM_OPC_fstore_0 = 67,
JVM_OPC_fstore_1 = 68,
JVM_OPC_fstore_2 = 69,
JVM_OPC_fstore_3 = 70,
JVM_OPC_dstore_0 = 71,
JVM_OPC_dstore_1 = 72,
JVM_OPC_dstore_2 = 73,
JVM_OPC_dstore_3 = 74,
JVM_OPC_astore_0 = 75,
JVM_OPC_astore_1 = 76,
JVM_OPC_astore_2 = 77,
JVM_OPC_astore_3 = 78,
JVM_OPC_iastore = 79,
JVM_OPC_lastore = 80,
JVM_OPC_fastore = 81,
JVM_OPC_dastore = 82,
JVM_OPC_aastore = 83,
JVM_OPC_bastore = 84,
JVM_OPC_castore = 85,
JVM_OPC_sastore = 86,
JVM_OPC_pop = 87,
JVM_OPC_pop2 = 88,
JVM_OPC_dup = 89,
JVM_OPC_dup_x1 = 90,
JVM_OPC_dup_x2 = 91,
JVM_OPC_dup2 = 92,
JVM_OPC_dup2_x1 = 93,
JVM_OPC_dup2_x2 = 94,
JVM_OPC_swap = 95,
JVM_OPC_iadd = 96,
JVM_OPC_ladd = 97,
JVM_OPC_fadd = 98,
JVM_OPC_dadd = 99,
JVM_OPC_isub = 100,
JVM_OPC_lsub = 101,
JVM_OPC_fsub = 102,
JVM_OPC_dsub = 103,
JVM_OPC_imul = 104,
JVM_OPC_lmul = 105,
JVM_OPC_fmul = 106,
JVM_OPC_dmul = 107,
JVM_OPC_idiv = 108,
JVM_OPC_ldiv = 109,
JVM_OPC_fdiv = 110,
JVM_OPC_ddiv = 111,
JVM_OPC_irem = 112,
JVM_OPC_lrem = 113,
JVM_OPC_frem = 114,
JVM_OPC_drem = 115,
JVM_OPC_ineg = 116,
JVM_OPC_lneg = 117,
JVM_OPC_fneg = 118,
JVM_OPC_dneg = 119,
JVM_OPC_ishl = 120,
JVM_OPC_lshl = 121,
JVM_OPC_ishr = 122,
JVM_OPC_lshr = 123,
JVM_OPC_iushr = 124,
JVM_OPC_lushr = 125,
JVM_OPC_iand = 126,
JVM_OPC_land = 127,
JVM_OPC_ior = 128,
JVM_OPC_lor = 129,
JVM_OPC_ixor = 130,
JVM_OPC_lxor = 131,
JVM_OPC_iinc = 132,
JVM_OPC_i2l = 133,
JVM_OPC_i2f = 134,
JVM_OPC_i2d = 135,
JVM_OPC_l2i = 136,
JVM_OPC_l2f = 137,
JVM_OPC_l2d = 138,
JVM_OPC_f2i = 139,
JVM_OPC_f2l = 140,
JVM_OPC_f2d = 141,
JVM_OPC_d2i = 142,
JVM_OPC_d2l = 143,
JVM_OPC_d2f = 144,
JVM_OPC_i2b = 145,
JVM_OPC_i2c = 146,
JVM_OPC_i2s = 147,
JVM_OPC_lcmp = 148,
JVM_OPC_fcmpl = 149,
JVM_OPC_fcmpg = 150,
JVM_OPC_dcmpl = 151,
JVM_OPC_dcmpg = 152,
JVM_OPC_ifeq = 153,
JVM_OPC_ifne = 154,
JVM_OPC_iflt = 155,
JVM_OPC_ifge = 156,
JVM_OPC_ifgt = 157,
JVM_OPC_ifle = 158,
JVM_OPC_if_icmpeq = 159,
JVM_OPC_if_icmpne = 160,
JVM_OPC_if_icmplt = 161,
JVM_OPC_if_icmpge = 162,
JVM_OPC_if_icmpgt = 163,
JVM_OPC_if_icmple = 164,
JVM_OPC_if_acmpeq = 165,
JVM_OPC_if_acmpne = 166,
JVM_OPC_goto = 167,
JVM_OPC_jsr = 168,
JVM_OPC_ret = 169,
JVM_OPC_tableswitch = 170,
JVM_OPC_lookupswitch = 171,
JVM_OPC_ireturn = 172,
JVM_OPC_lreturn = 173,
JVM_OPC_freturn = 174,
JVM_OPC_dreturn = 175,
JVM_OPC_areturn = 176,
JVM_OPC_return = 177,
JVM_OPC_getstatic = 178,
JVM_OPC_putstatic = 179,
JVM_OPC_getfield = 180,
JVM_OPC_putfield = 181,
JVM_OPC_invokevirtual = 182,
JVM_OPC_invokespecial = 183,
JVM_OPC_invokestatic = 184,
JVM_OPC_invokeinterface = 185,
JVM_OPC_invokedynamic = 186,
JVM_OPC_new = 187,
JVM_OPC_newarray = 188,
JVM_OPC_anewarray = 189,
JVM_OPC_arraylength = 190,
JVM_OPC_athrow = 191,
JVM_OPC_checkcast = 192,
JVM_OPC_instanceof = 193,
JVM_OPC_monitorenter = 194,
JVM_OPC_monitorexit = 195,
JVM_OPC_wide = 196,
JVM_OPC_multianewarray = 197,
JVM_OPC_ifnull = 198,
JVM_OPC_ifnonnull = 199,
JVM_OPC_goto_w = 200,
JVM_OPC_jsr_w = 201,
JVM_OPC_MAX = 201
};
/* Opcode length initializer, use with something like:
* unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER;
*/
#define JVM_OPCODE_LENGTH_INITIALIZER { \
1, /* nop */ \
1, /* aconst_null */ \
1, /* iconst_m1 */ \
1, /* iconst_0 */ \
1, /* iconst_1 */ \
1, /* iconst_2 */ \
1, /* iconst_3 */ \
1, /* iconst_4 */ \
1, /* iconst_5 */ \
1, /* lconst_0 */ \
1, /* lconst_1 */ \
1, /* fconst_0 */ \
1, /* fconst_1 */ \
1, /* fconst_2 */ \
1, /* dconst_0 */ \
1, /* dconst_1 */ \
2, /* bipush */ \
3, /* sipush */ \
2, /* ldc */ \
3, /* ldc_w */ \
3, /* ldc2_w */ \
2, /* iload */ \
2, /* lload */ \
2, /* fload */ \
2, /* dload */ \
2, /* aload */ \
1, /* iload_0 */ \
1, /* iload_1 */ \
1, /* iload_2 */ \
1, /* iload_3 */ \
1, /* lload_0 */ \
1, /* lload_1 */ \
1, /* lload_2 */ \
1, /* lload_3 */ \
1, /* fload_0 */ \
1, /* fload_1 */ \
1, /* fload_2 */ \
1, /* fload_3 */ \
1, /* dload_0 */ \
1, /* dload_1 */ \
1, /* dload_2 */ \
1, /* dload_3 */ \
1, /* aload_0 */ \
1, /* aload_1 */ \
1, /* aload_2 */ \
1, /* aload_3 */ \
1, /* iaload */ \
1, /* laload */ \
1, /* faload */ \
1, /* daload */ \
1, /* aaload */ \
1, /* baload */ \
1, /* caload */ \
1, /* saload */ \
2, /* istore */ \
2, /* lstore */ \
2, /* fstore */ \
2, /* dstore */ \
2, /* astore */ \
1, /* istore_0 */ \
1, /* istore_1 */ \
1, /* istore_2 */ \
1, /* istore_3 */ \
1, /* lstore_0 */ \
1, /* lstore_1 */ \
1, /* lstore_2 */ \
1, /* lstore_3 */ \
1, /* fstore_0 */ \
1, /* fstore_1 */ \
1, /* fstore_2 */ \
1, /* fstore_3 */ \
1, /* dstore_0 */ \
1, /* dstore_1 */ \
1, /* dstore_2 */ \
1, /* dstore_3 */ \
1, /* astore_0 */ \
1, /* astore_1 */ \
1, /* astore_2 */ \
1, /* astore_3 */ \
1, /* iastore */ \
1, /* lastore */ \
1, /* fastore */ \
1, /* dastore */ \
1, /* aastore */ \
1, /* bastore */ \
1, /* castore */ \
1, /* sastore */ \
1, /* pop */ \
1, /* pop2 */ \
1, /* dup */ \
1, /* dup_x1 */ \
1, /* dup_x2 */ \
1, /* dup2 */ \
1, /* dup2_x1 */ \
1, /* dup2_x2 */ \
1, /* swap */ \
1, /* iadd */ \
1, /* ladd */ \
1, /* fadd */ \
1, /* dadd */ \
1, /* isub */ \
1, /* lsub */ \
1, /* fsub */ \
1, /* dsub */ \
1, /* imul */ \
1, /* lmul */ \
1, /* fmul */ \
1, /* dmul */ \
1, /* idiv */ \
1, /* ldiv */ \
1, /* fdiv */ \
1, /* ddiv */ \
1, /* irem */ \
1, /* lrem */ \
1, /* frem */ \
1, /* drem */ \
1, /* ineg */ \
1, /* lneg */ \
1, /* fneg */ \
1, /* dneg */ \
1, /* ishl */ \
1, /* lshl */ \
1, /* ishr */ \
1, /* lshr */ \
1, /* iushr */ \
1, /* lushr */ \
1, /* iand */ \
1, /* land */ \
1, /* ior */ \
1, /* lor */ \
1, /* ixor */ \
1, /* lxor */ \
3, /* iinc */ \
1, /* i2l */ \
1, /* i2f */ \
1, /* i2d */ \
1, /* l2i */ \
1, /* l2f */ \
1, /* l2d */ \
1, /* f2i */ \
1, /* f2l */ \
1, /* f2d */ \
1, /* d2i */ \
1, /* d2l */ \
1, /* d2f */ \
1, /* i2b */ \
1, /* i2c */ \
1, /* i2s */ \
1, /* lcmp */ \
1, /* fcmpl */ \
1, /* fcmpg */ \
1, /* dcmpl */ \
1, /* dcmpg */ \
3, /* ifeq */ \
3, /* ifne */ \
3, /* iflt */ \
3, /* ifge */ \
3, /* ifgt */ \
3, /* ifle */ \
3, /* if_icmpeq */ \
3, /* if_icmpne */ \
3, /* if_icmplt */ \
3, /* if_icmpge */ \
3, /* if_icmpgt */ \
3, /* if_icmple */ \
3, /* if_acmpeq */ \
3, /* if_acmpne */ \
3, /* goto */ \
3, /* jsr */ \
2, /* ret */ \
99, /* tableswitch */ \
99, /* lookupswitch */ \
1, /* ireturn */ \
1, /* lreturn */ \
1, /* freturn */ \
1, /* dreturn */ \
1, /* areturn */ \
1, /* return */ \
3, /* getstatic */ \
3, /* putstatic */ \
3, /* getfield */ \
3, /* putfield */ \
3, /* invokevirtual */ \
3, /* invokespecial */ \
3, /* invokestatic */ \
5, /* invokeinterface */ \
5, /* invokedynamic */ \
3, /* new */ \
2, /* newarray */ \
3, /* anewarray */ \
1, /* arraylength */ \
1, /* athrow */ \
3, /* checkcast */ \
3, /* instanceof */ \
1, /* monitorenter */ \
1, /* monitorexit */ \
0, /* wide */ \
4, /* multianewarray */ \
3, /* ifnull */ \
3, /* ifnonnull */ \
5, /* goto_w */ \
5 /* jsr_w */ \
}
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* CLASSFILE_CONSTANTS */

356
jni/linux/jawt.h Normal file
View File

@ -0,0 +1,356 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_JAWT_H_
#define _JAVASOFT_JAWT_H_
#include "jni.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* AWT native interface.
*
* The AWT native interface allows a native C or C++ application a means
* by which to access native structures in AWT. This is to facilitate moving
* legacy C and C++ applications to Java and to target the needs of the
* developers who need to do their own native rendering to canvases
* for performance or other reasons.
*
* Conversely it also provides mechanisms for an application which already
* has a native window to provide that to AWT for AWT rendering.
*
* Since every platform may be different in its native data structures
* and APIs for windowing systems the application must necessarily
* provided per-platform source and compile and deliver per-platform
* native code to use this API.
*
* These interfaces are not part of the Java SE specification and
* a VM is not required to implement this API. However it is strongly
* recommended that all implementations which support headful AWT
* also support these interfaces.
*
*/
/*
* AWT Native Drawing Surface (JAWT_DrawingSurface).
*
* For each platform, there is a native drawing surface structure. This
* platform-specific structure can be found in jawt_md.h. It is recommended
* that additional platforms follow the same model. It is also recommended
* that VMs on all platforms support the existing structures in jawt_md.h.
*
*******************
* EXAMPLE OF USAGE:
*******************
*
* In Win32, a programmer wishes to access the HWND of a canvas to perform
* native rendering into it. The programmer has declared the paint() method
* for their canvas subclass to be native:
*
*
* MyCanvas.java:
*
* import java.awt.*;
*
* public class MyCanvas extends Canvas {
*
* static {
* System.loadLibrary("mylib");
* }
*
* public native void paint(Graphics g);
* }
*
*
* myfile.c:
*
* #include "jawt_md.h"
* #include <assert.h>
*
* JNIEXPORT void JNICALL
* Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics)
* {
* JAWT awt;
* JAWT_DrawingSurface* ds;
* JAWT_DrawingSurfaceInfo* dsi;
* JAWT_Win32DrawingSurfaceInfo* dsi_win;
* jboolean result;
* jint lock;
*
* // Get the AWT. Request version 9 to access features in that release.
* awt.version = JAWT_VERSION_9;
* result = JAWT_GetAWT(env, &awt);
* assert(result != JNI_FALSE);
*
* // Get the drawing surface
* ds = awt.GetDrawingSurface(env, canvas);
* assert(ds != NULL);
*
* // Lock the drawing surface
* lock = ds->Lock(ds);
* assert((lock & JAWT_LOCK_ERROR) == 0);
*
* // Get the drawing surface info
* dsi = ds->GetDrawingSurfaceInfo(ds);
*
* // Get the platform-specific drawing info
* dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
*
* //////////////////////////////
* // !!! DO PAINTING HERE !!! //
* //////////////////////////////
*
* // Free the drawing surface info
* ds->FreeDrawingSurfaceInfo(dsi);
*
* // Unlock the drawing surface
* ds->Unlock(ds);
*
* // Free the drawing surface
* awt.FreeDrawingSurface(ds);
* }
*
*/
/*
* JAWT_Rectangle
* Structure for a native rectangle.
*/
typedef struct jawt_Rectangle {
jint x;
jint y;
jint width;
jint height;
} JAWT_Rectangle;
struct jawt_DrawingSurface;
/*
* JAWT_DrawingSurfaceInfo
* Structure for containing the underlying drawing information of a component.
*/
typedef struct jawt_DrawingSurfaceInfo {
/*
* Pointer to the platform-specific information. This can be safely
* cast to a JAWT_Win32DrawingSurfaceInfo on Windows or a
* JAWT_X11DrawingSurfaceInfo on Linux and Solaris. On Mac OS X this is a
* pointer to a NSObject that conforms to the JAWT_SurfaceLayers
* protocol. See jawt_md.h for details.
*/
void* platformInfo;
/* Cached pointer to the underlying drawing surface */
struct jawt_DrawingSurface* ds;
/* Bounding rectangle of the drawing surface */
JAWT_Rectangle bounds;
/* Number of rectangles in the clip */
jint clipSize;
/* Clip rectangle array */
JAWT_Rectangle* clip;
} JAWT_DrawingSurfaceInfo;
#define JAWT_LOCK_ERROR 0x00000001
#define JAWT_LOCK_CLIP_CHANGED 0x00000002
#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004
#define JAWT_LOCK_SURFACE_CHANGED 0x00000008
/*
* JAWT_DrawingSurface
* Structure for containing the underlying drawing information of a component.
* All operations on a JAWT_DrawingSurface MUST be performed from the same
* thread as the call to GetDrawingSurface.
*/
typedef struct jawt_DrawingSurface {
/*
* Cached reference to the Java environment of the calling thread.
* If Lock(), Unlock(), GetDrawingSurfaceInfo() or
* FreeDrawingSurfaceInfo() are called from a different thread,
* this data member should be set before calling those functions.
*/
JNIEnv* env;
/* Cached reference to the target object */
jobject target;
/*
* Lock the surface of the target component for native rendering.
* When finished drawing, the surface must be unlocked with
* Unlock(). This function returns a bitmask with one or more of the
* following values:
*
* JAWT_LOCK_ERROR - When an error has occurred and the surface could not
* be locked.
*
* JAWT_LOCK_CLIP_CHANGED - When the clip region has changed.
*
* JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed.
*
* JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed
*/
jint (JNICALL *Lock)
(struct jawt_DrawingSurface* ds);
/*
* Get the drawing surface info.
* The value returned may be cached, but the values may change if
* additional calls to Lock() or Unlock() are made.
* Lock() must be called before this can return a valid value.
* Returns NULL if an error has occurred.
* When finished with the returned value, FreeDrawingSurfaceInfo must be
* called.
*/
JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo)
(struct jawt_DrawingSurface* ds);
/*
* Free the drawing surface info.
*/
void (JNICALL *FreeDrawingSurfaceInfo)
(JAWT_DrawingSurfaceInfo* dsi);
/*
* Unlock the drawing surface of the target component for native rendering.
*/
void (JNICALL *Unlock)
(struct jawt_DrawingSurface* ds);
} JAWT_DrawingSurface;
/*
* JAWT
* Structure for containing native AWT functions.
*/
typedef struct jawt {
/*
* Version of this structure. This must always be set before
* calling JAWT_GetAWT(). It affects the functions returned.
* Must be one of the known pre-defined versions.
*/
jint version;
/*
* Return a drawing surface from a target jobject. This value
* may be cached.
* Returns NULL if an error has occurred.
* Target must be a java.awt.Component (should be a Canvas
* or Window for native rendering).
* FreeDrawingSurface() must be called when finished with the
* returned JAWT_DrawingSurface.
*/
JAWT_DrawingSurface* (JNICALL *GetDrawingSurface)
(JNIEnv* env, jobject target);
/*
* Free the drawing surface allocated in GetDrawingSurface.
*/
void (JNICALL *FreeDrawingSurface)
(JAWT_DrawingSurface* ds);
/*
* Since 1.4
* Locks the entire AWT for synchronization purposes
*/
void (JNICALL *Lock)(JNIEnv* env);
/*
* Since 1.4
* Unlocks the entire AWT for synchronization purposes
*/
void (JNICALL *Unlock)(JNIEnv* env);
/*
* Since 1.4
* Returns a reference to a java.awt.Component from a native
* platform handle. On Windows, this corresponds to an HWND;
* on Solaris and Linux, this is a Drawable. For other platforms,
* see the appropriate machine-dependent header file for a description.
* The reference returned by this function is a local
* reference that is only valid in this environment.
* This function returns a NULL reference if no component could be
* found with matching platform information.
*/
jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo);
/**
* Since 9
* Creates a java.awt.Frame placed in a native container. Container is
* referenced by the native platform handle. For example on Windows this
* corresponds to an HWND. For other platforms, see the appropriate
* machine-dependent header file for a description. The reference returned
* by this function is a local reference that is only valid in this
* environment. This function returns a NULL reference if no frame could be
* created with matching platform information.
*/
jobject (JNICALL *CreateEmbeddedFrame) (JNIEnv *env, void* platformInfo);
/**
* Since 9
* Moves and resizes the embedded frame. The new location of the top-left
* corner is specified by x and y parameters relative to the native parent
* component. The new size is specified by width and height.
*
* The embedded frame should be created by CreateEmbeddedFrame() method, or
* this function will not have any effect.
*
* java.awt.Component.setLocation() and java.awt.Component.setBounds() for
* EmbeddedFrame really don't move it within the native parent. These
* methods always locate the embedded frame at (0, 0) for backward
* compatibility. To allow moving embedded frames this method was
* introduced, and it works just the same way as setLocation() and
* setBounds() for usual, non-embedded components.
*
* Using usual get/setLocation() and get/setBounds() together with this new
* method is not recommended.
*/
void (JNICALL *SetBounds) (JNIEnv *env, jobject embeddedFrame,
jint x, jint y, jint w, jint h);
/**
* Since 9
* Synthesize a native message to activate or deactivate an EmbeddedFrame
* window depending on the value of parameter doActivate, if "true"
* activates the window; otherwise, deactivates the window.
*
* The embedded frame should be created by CreateEmbeddedFrame() method, or
* this function will not have any effect.
*/
void (JNICALL *SynthesizeWindowActivation) (JNIEnv *env,
jobject embeddedFrame, jboolean doActivate);
} JAWT;
/*
* Get the AWT native structure. This function returns JNI_FALSE if
* an error occurs.
*/
_JNI_IMPORT_OR_EXPORT_
jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt);
/*
* Specify one of these constants as the JAWT.version
* Specifying an earlier version will limit the available functions to
* those provided in that earlier version of JAWT.
* See the "Since" note on each API. Methods with no "Since"
* may be presumed to be present in JAWT_VERSION_1_3.
*/
#define JAWT_VERSION_1_3 0x00010003
#define JAWT_VERSION_1_4 0x00010004
#define JAWT_VERSION_1_7 0x00010007
#define JAWT_VERSION_9 0x00090000
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* !_JAVASOFT_JAWT_H_ */

276
jni/linux/jdwpTransport.h Normal file
View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Java Debug Wire Protocol Transport Service Provider Interface.
*/
#ifndef JDWPTRANSPORT_H
#define JDWPTRANSPORT_H
#include "jni.h"
enum {
JDWPTRANSPORT_VERSION_1_0 = 0x00010000,
JDWPTRANSPORT_VERSION_1_1 = 0x00010001
};
#ifdef __cplusplus
extern "C" {
#endif
struct jdwpTransportNativeInterface_;
struct _jdwpTransportEnv;
#ifdef __cplusplus
typedef _jdwpTransportEnv jdwpTransportEnv;
#else
typedef const struct jdwpTransportNativeInterface_ *jdwpTransportEnv;
#endif /* __cplusplus */
/*
* Errors. Universal errors with JVMTI/JVMDI equivalents keep the
* values the same.
*/
typedef enum {
JDWPTRANSPORT_ERROR_NONE = 0,
JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT = 103,
JDWPTRANSPORT_ERROR_OUT_OF_MEMORY = 110,
JDWPTRANSPORT_ERROR_INTERNAL = 113,
JDWPTRANSPORT_ERROR_ILLEGAL_STATE = 201,
JDWPTRANSPORT_ERROR_IO_ERROR = 202,
JDWPTRANSPORT_ERROR_TIMEOUT = 203,
JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE = 204
} jdwpTransportError;
/*
* Structure to define capabilities
*/
typedef struct {
unsigned int can_timeout_attach :1;
unsigned int can_timeout_accept :1;
unsigned int can_timeout_handshake :1;
unsigned int reserved3 :1;
unsigned int reserved4 :1;
unsigned int reserved5 :1;
unsigned int reserved6 :1;
unsigned int reserved7 :1;
unsigned int reserved8 :1;
unsigned int reserved9 :1;
unsigned int reserved10 :1;
unsigned int reserved11 :1;
unsigned int reserved12 :1;
unsigned int reserved13 :1;
unsigned int reserved14 :1;
unsigned int reserved15 :1;
} JDWPTransportCapabilities;
/*
* Structures to define packet layout.
*
* See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html
*/
#define JDWP_HEADER_SIZE 11
enum {
/*
* If additional flags are added that apply to jdwpCmdPacket,
* then debugLoop.c: reader() will need to be updated to
* accept more than JDWPTRANSPORT_FLAGS_NONE.
*/
JDWPTRANSPORT_FLAGS_NONE = 0x0,
JDWPTRANSPORT_FLAGS_REPLY = 0x80
};
typedef struct {
jint len;
jint id;
jbyte flags;
jbyte cmdSet;
jbyte cmd;
jbyte *data;
} jdwpCmdPacket;
typedef struct {
jint len;
jint id;
jbyte flags;
jshort errorCode;
jbyte *data;
} jdwpReplyPacket;
typedef struct {
union {
jdwpCmdPacket cmd;
jdwpReplyPacket reply;
} type;
} jdwpPacket;
/*
* JDWP functions called by the transport.
*/
typedef struct jdwpTransportCallback {
void *(*alloc)(jint numBytes); /* Call this for all allocations */
void (*free)(void *buffer); /* Call this for all deallocations */
} jdwpTransportCallback;
typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm,
jdwpTransportCallback *callback,
jint version,
jdwpTransportEnv** env);
/*
* JDWP transport configuration from the agent.
*/
typedef struct jdwpTransportConfiguration {
/* Field added in JDWPTRANSPORT_VERSION_1_1: */
const char* allowed_peers; /* Peers allowed for connection */
} jdwpTransportConfiguration;
/* Function Interface */
struct jdwpTransportNativeInterface_ {
/* 1 : RESERVED */
void *reserved1;
/* 2 : Get Capabilities */
jdwpTransportError (JNICALL *GetCapabilities)(jdwpTransportEnv* env,
JDWPTransportCapabilities *capabilities_ptr);
/* 3 : Attach */
jdwpTransportError (JNICALL *Attach)(jdwpTransportEnv* env,
const char* address,
jlong attach_timeout,
jlong handshake_timeout);
/* 4: StartListening */
jdwpTransportError (JNICALL *StartListening)(jdwpTransportEnv* env,
const char* address,
char** actual_address);
/* 5: StopListening */
jdwpTransportError (JNICALL *StopListening)(jdwpTransportEnv* env);
/* 6: Accept */
jdwpTransportError (JNICALL *Accept)(jdwpTransportEnv* env,
jlong accept_timeout,
jlong handshake_timeout);
/* 7: IsOpen */
jboolean (JNICALL *IsOpen)(jdwpTransportEnv* env);
/* 8: Close */
jdwpTransportError (JNICALL *Close)(jdwpTransportEnv* env);
/* 9: ReadPacket */
jdwpTransportError (JNICALL *ReadPacket)(jdwpTransportEnv* env,
jdwpPacket *pkt);
/* 10: Write Packet */
jdwpTransportError (JNICALL *WritePacket)(jdwpTransportEnv* env,
const jdwpPacket* pkt);
/* 11: GetLastError */
jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env,
char** error);
/* 12: SetTransportConfiguration added in JDWPTRANSPORT_VERSION_1_1 */
jdwpTransportError (JNICALL *SetTransportConfiguration)(jdwpTransportEnv* env,
jdwpTransportConfiguration *config);
};
/*
* Use inlined functions so that C++ code can use syntax such as
* env->Attach("mymachine:5000", 10*1000, 0);
*
* rather than using C's :-
*
* (*env)->Attach(env, "mymachine:5000", 10*1000, 0);
*/
struct _jdwpTransportEnv {
const struct jdwpTransportNativeInterface_ *functions;
#ifdef __cplusplus
jdwpTransportError GetCapabilities(JDWPTransportCapabilities *capabilities_ptr) {
return functions->GetCapabilities(this, capabilities_ptr);
}
jdwpTransportError Attach(const char* address, jlong attach_timeout,
jlong handshake_timeout) {
return functions->Attach(this, address, attach_timeout, handshake_timeout);
}
jdwpTransportError StartListening(const char* address,
char** actual_address) {
return functions->StartListening(this, address, actual_address);
}
jdwpTransportError StopListening(void) {
return functions->StopListening(this);
}
jdwpTransportError Accept(jlong accept_timeout, jlong handshake_timeout) {
return functions->Accept(this, accept_timeout, handshake_timeout);
}
jboolean IsOpen(void) {
return functions->IsOpen(this);
}
jdwpTransportError Close(void) {
return functions->Close(this);
}
jdwpTransportError ReadPacket(jdwpPacket *pkt) {
return functions->ReadPacket(this, pkt);
}
jdwpTransportError WritePacket(const jdwpPacket* pkt) {
return functions->WritePacket(this, pkt);
}
jdwpTransportError GetLastError(char** error) {
return functions->GetLastError(this, error);
}
/* SetTransportConfiguration added in JDWPTRANSPORT_VERSION_1_1 */
jdwpTransportError SetTransportConfiguration(jdwpTransportEnv* env,
return functions->SetTransportConfiguration(this, config);
}
#endif /* __cplusplus */
};
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* JDWPTRANSPORT_H */

1987
jni/linux/jni.h Normal file

File diff suppressed because it is too large Load Diff

2625
jni/linux/jvmti.h Normal file

File diff suppressed because it is too large Load Diff

115
jni/linux/jvmticmlr.h Normal file
View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This header file defines the data structures sent by the VM
* through the JVMTI CompiledMethodLoad callback function via the
* "void * compile_info" parameter. The memory pointed to by the
* compile_info parameter may not be referenced after returning from
* the CompiledMethodLoad callback. These are VM implementation
* specific data structures that may evolve in future releases. A
* JVMTI agent should interpret a non-NULL compile_info as a pointer
* to a region of memory containing a list of records. In a typical
* usage scenario, a JVMTI agent would cast each record to a
* jvmtiCompiledMethodLoadRecordHeader, a struct that represents
* arbitrary information. This struct contains a kind field to indicate
* the kind of information being passed, and a pointer to the next
* record. If the kind field indicates inlining information, then the
* agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord.
* This record contains an array of PCStackInfo structs, which indicate
* for every pc address what are the methods on the invocation stack.
* The "methods" and "bcis" fields in each PCStackInfo struct specify a
* 1-1 mapping between these inlined methods and their bytecode indices.
* This can be used to derive the proper source lines of the inlined
* methods.
*/
#ifndef _JVMTI_CMLR_H_
#define _JVMTI_CMLR_H_
enum {
JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001,
JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000,
JVMTI_CMLR_MAJOR_VERSION = 0x00000001,
JVMTI_CMLR_MINOR_VERSION = 0x00000000
/*
* This comment is for the "JDK import from HotSpot" sanity check:
* version: 1.0.0
*/
};
typedef enum {
JVMTI_CMLR_DUMMY = 1,
JVMTI_CMLR_INLINE_INFO = 2
} jvmtiCMLRKind;
/*
* Record that represents arbitrary information passed through JVMTI
* CompiledMethodLoadEvent void pointer.
*/
typedef struct _jvmtiCompiledMethodLoadRecordHeader {
jvmtiCMLRKind kind; /* id for the kind of info passed in the record */
jint majorinfoversion; /* major and minor info version values. Init'ed */
jint minorinfoversion; /* to current version value in jvmtiExport.cpp. */
struct _jvmtiCompiledMethodLoadRecordHeader* next;
} jvmtiCompiledMethodLoadRecordHeader;
/*
* Record that gives information about the methods on the compile-time
* stack at a specific pc address of a compiled method. Each element in
* the methods array maps to same element in the bcis array.
*/
typedef struct _PCStackInfo {
void* pc; /* the pc address for this compiled method */
jint numstackframes; /* number of methods on the stack */
jmethodID* methods; /* array of numstackframes method ids */
jint* bcis; /* array of numstackframes bytecode indices */
} PCStackInfo;
/*
* Record that contains inlining information for each pc address of
* an nmethod.
*/
typedef struct _jvmtiCompiledMethodLoadInlineRecord {
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
jint numpcs; /* number of pc descriptors in this nmethod */
PCStackInfo* pcinfo; /* array of numpcs pc descriptors */
} jvmtiCompiledMethodLoadInlineRecord;
/*
* Dummy record used to test that we can pass records with different
* information through the void pointer provided that they can be cast
* to a jvmtiCompiledMethodLoadRecordHeader.
*/
typedef struct _jvmtiCompiledMethodLoadDummyRecord {
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
char message[50];
} jvmtiCompiledMethodLoadDummyRecord;
#endif

60
jni/linux/linux/jawt_md.h Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_JAWT_MD_H_
#define _JAVASOFT_JAWT_MD_H_
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "jawt.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* X11-specific declarations for AWT native interface.
* See notes in jawt.h for an example of use.
*/
typedef struct jawt_X11DrawingSurfaceInfo {
Drawable drawable;
Display* display;
VisualID visualID;
Colormap colormapID;
int depth;
/*
* Since 1.4
* Returns a pixel value from a set of RGB values.
* This is useful for paletted color (256 color) modes.
*/
int (JNICALL *GetAWTColor)(JAWT_DrawingSurface* ds,
int r, int g, int b);
} JAWT_X11DrawingSurfaceInfo;
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_JAWT_MD_H_ */

66
jni/linux/linux/jni_md.h Normal file
View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#ifndef JNIEXPORT
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#ifdef ARM
#define JNIEXPORT __attribute__((externally_visible,visibility("default")))
#else
#define JNIEXPORT __attribute__((visibility("default")))
#endif
#else
#define JNIEXPORT
#endif
#endif
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#ifdef ARM
#define JNIIMPORT __attribute__((externally_visible,visibility("default")))
#else
#define JNIIMPORT __attribute__((visibility("default")))
#endif
#else
#define JNIIMPORT
#endif
#define JNICALL
typedef int jint;
#ifdef _LP64
typedef long jlong;
#else
typedef long long jlong;
#endif
typedef signed char jbyte;
#endif /* !_JAVASOFT_JNI_MD_H_ */

View File

@ -1,8 +1,7 @@
# Java include directory pathnames # Java include directory pathnames
# The Windows files need to be copied from a Windows JDK installation # The Windows files need to be copied from a Windows JDK installation
include_linux = /usr/lib/jvm/java-15-openjdk-`\ include_linux = jni/linux
uname -r | sed 's/.*-//'`/include include_windows = jni/windows
include_windows = jni-windows-include
# Default goal # Default goal
.PHONY: default .PHONY: default
@ -10,7 +9,7 @@ default:
@echo $(include_linux) @echo $(include_linux)
@echo "Planet Virtual Boy Emulator" @echo "Planet Virtual Boy Emulator"
@echo " https://www.planetvb.com/" @echo " https://www.planetvb.com/"
@echo " December 17, 2020" @echo " December 25, 2020"
@echo @echo
@echo "Intended build environment: Debian i386 or amd64" @echo "Intended build environment: Debian i386 or amd64"
@echo " gcc-multilib" @echo " gcc-multilib"

View File

@ -265,9 +265,12 @@ static int32_t cpuGetSystemRegister(Vue *vue, int32_t index) {
/* Transfer program to another address */ /* Transfer program to another address */
static void cpuJump(Vue *vue, int32_t address) { static void cpuJump(Vue *vue, int32_t address) {
int level = vue->cpu.psw_np ? 2 : vue->cpu.psw_ep; int level;
vue->cpu.jumpFrom[level] = vue->cpu.pc; if (address != vue->cpu.pc) {
vue->cpu.jumpTo [level] = address; level = vue->cpu.psw_np ? 2 : vue->cpu.psw_ep;
vue->cpu.jumpFrom[level] = vue->cpu.pc;
vue->cpu.jumpTo [level] = address;
}
vue->cpu.pc = address - vue->cpu.inst.size; vue->cpu.pc = address - vue->cpu.inst.size;
} }
@ -490,7 +493,9 @@ static vbool cpuWrite(Vue *vue, int32_t address, int8_t type, int32_t value) {
cpuFloat(vue->cpu.program[vue->cpu.inst.reg1])) cpuFloat(vue->cpu.program[vue->cpu.inst.reg1]))
/* Add Immediate */ /* Add Immediate */
#define cpuADDI(vue) cpuADD_IMM(vue) #define cpuADDI(vue) \
vue->cpu.program[vue->cpu.inst.reg2] = cpuAdd(vue, \
vue->cpu.program[vue->cpu.inst.reg1], vue->cpu.inst.imm)
/* And */ /* And */
#define cpuAND(vue) \ #define cpuAND(vue) \
@ -499,7 +504,7 @@ static vbool cpuWrite(Vue *vue, int32_t address, int8_t type, int32_t value) {
/* And Immediate */ /* And Immediate */
#define cpuANDI(vue) \ #define cpuANDI(vue) \
cpuBitwise(vue, vue->cpu.program[vue->cpu.inst.reg2] & \ cpuBitwise(vue, vue->cpu.program[vue->cpu.inst.reg1] & \
vue->cpu.inst.imm) vue->cpu.inst.imm)
/* Branch on Condition */ /* Branch on Condition */
@ -756,7 +761,7 @@ static void cpuMULU(Vue *vue) {
/* Or Immediate */ /* Or Immediate */
#define cpuORI(vue) \ #define cpuORI(vue) \
cpuBitwise(vue, vue->cpu.program[vue->cpu.inst.reg2] | \ cpuBitwise(vue, vue->cpu.program[vue->cpu.inst.reg1] | \
vue->cpu.inst.imm) vue->cpu.inst.imm)
/* Return from Trap or Interrupt */ /* Return from Trap or Interrupt */
@ -876,7 +881,7 @@ static void cpuXH(Vue *vue) {
/* Exclusive Or Immediate */ /* Exclusive Or Immediate */
#define cpuXORI(vue) \ #define cpuXORI(vue) \
cpuBitwise(vue, vue->cpu.program[vue->cpu.inst.reg2] ^ \ cpuBitwise(vue, vue->cpu.program[vue->cpu.inst.reg1] ^ \
vue->cpu.inst.imm) vue->cpu.inst.imm)
@ -1182,6 +1187,12 @@ static vbool cpuFetch(Vue *vue) {
return VUE_FALSE; return VUE_FALSE;
} }
/*****************************************************************************
* Internal Functions *
******************************************************************************/
/* Process the simulation */ /* Process the simulation */
static void cpuEmulate(Vue *vue, uint32_t cycles) { static void cpuEmulate(Vue *vue, uint32_t cycles) {

View File

@ -244,7 +244,7 @@ struct Vue {
uint16_t ecr_fecc; /* Fatal Error Cause Code */ uint16_t ecr_fecc; /* Fatal Error Cause Code */
} cpu; } cpu;
/* Game pak */ /* Game pak state */
struct { struct {
uint8_t *ram; /* Cartridge SRAM */ uint8_t *ram; /* Cartridge SRAM */
uint32_t ramSize; /* Number of bytes in cartridge SRAM */ uint32_t ramSize; /* Number of bytes in cartridge SRAM */
@ -254,6 +254,11 @@ struct Vue {
int8_t wcr_rom1w; /* ROM one-wait mode */ int8_t wcr_rom1w; /* ROM one-wait mode */
} pak; } pak;
/* VIP state */
struct {
uint8_t vram[0x40000]; /* Video memory */
} vip;
}; };

298
src/core/vip.c Normal file
View File

@ -0,0 +1,298 @@
/* This file is included through vue.c and cannot be built directly. */
#ifdef VUEAPI
/*****************************************************************************
* Internal Functions *
******************************************************************************/
/* Process the simulation */
static void vipEmulate(Vue *vue, uint32_t cycles) {
vue = vue;
cycles = cycles;
}
/* Read an I/O register */
static int32_t vipReadRegister(Vue *vue, int32_t address) {
vue=vue;
/* Process by register */
switch (address & ~1) {
case 0x0005F800: break; /* INTPND */
case 0x0005F802: break; /* INTENB */
case 0x0005F804: break; /* INTCLR */
case 0x0005F820: break; /* DPSTTS */
case 0x0005F822: break; /* DPCTRL */
case 0x0005F824: break; /* BRTA */
case 0x0005F826: break; /* BRTB */
case 0x0005F828: break; /* BRTC */
case 0x0005F82A: break; /* REST */
case 0x0005F82E: break; /* FRMCYC */
case 0x0005F830: break; /* CTA */
case 0x0005F840: break; /* XPSTTS */
case 0x0005F842: break; /* XPCTRL */
case 0x0005F844: break; /* VER */
case 0x0005F848: break; /* SPT0 */
case 0x0005F84A: break; /* SPT1 */
case 0x0005F84C: break; /* SPT2 */
case 0x0005F84E: break; /* SPT3 */
case 0x0005F860: break; /* GPLT0 */
case 0x0005F862: break; /* GPLT1 */
case 0x0005F864: break; /* GPLT2 */
case 0x0005F866: break; /* GPLT3 */
case 0x0005F868: break; /* JPLT0 */
case 0x0005F86A: break; /* JPLT1 */
case 0x0005F86C: break; /* JPLT2 */
case 0x0005F86E: break; /* JPLT3 */
case 0x0005F870: break; /* BKCOL */
}
/* Unmapped */
return 0;
}
/* Read an I/O register */
static void vipWriteRegister(Vue *vue, int32_t address, int32_t value) {
vue=vue;
value=value;
/* Process by register */
switch (address & ~1) {
case 0x0005F800: break; /* INTPND */
case 0x0005F802: break; /* INTENB */
case 0x0005F804: break; /* INTCLR */
case 0x0005F820: break; /* DPSTTS */
case 0x0005F822: break; /* DPCTRL */
case 0x0005F824: break; /* BRTA */
case 0x0005F826: break; /* BRTB */
case 0x0005F828: break; /* BRTC */
case 0x0005F82A: break; /* REST */
case 0x0005F82E: break; /* FRMCYC */
case 0x0005F830: break; /* CTA */
case 0x0005F840: break; /* XPSTTS */
case 0x0005F842: break; /* XPCTRL */
case 0x0005F844: break; /* VER */
case 0x0005F848: break; /* SPT0 */
case 0x0005F84A: break; /* SPT1 */
case 0x0005F84C: break; /* SPT2 */
case 0x0005F84E: break; /* SPT3 */
case 0x0005F860: break; /* GPLT0 */
case 0x0005F862: break; /* GPLT1 */
case 0x0005F864: break; /* GPLT2 */
case 0x0005F866: break; /* GPLT3 */
case 0x0005F868: break; /* JPLT0 */
case 0x0005F86A: break; /* JPLT1 */
case 0x0005F86C: break; /* JPLT2 */
case 0x0005F86E: break; /* JPLT3 */
case 0x0005F870: break; /* BKCOL */
}
}
/* Read a value from the CPU bus */
static int32_t vipRead(Vue *vue, int32_t address, int32_t type) {
int32_t value; /* Register value */
address &= 0x0007FFFF;
/* VRAM */
if (address < 0x00040000)
return readBuffer(vue->vip.vram, 0x40000, address, type);
/* Mirrors of character memory */
if (address >= 0x00078000)
return readBuffer(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
type);
/* I/O register or unmapped */
value = vipReadRegister(vue, address);
if (type < 2 && (address & 1) == 1)
value >>= 8;
switch (type) {
case VUE_S8 : return SIGN_EXTEND(value, 8);
case VUE_U8 : return value & 0x000000FF;
case VUE_S16: return SIGN_EXTEND(value, 16);
case VUE_S32: return value | vipReadRegister(vue, address + 2) << 16;
}
return value; /* U16 */
}
/* Read bytes from the CPU bus */
static void vipReadBytes(Vue *vue, int address, uint8_t *dest, int length) {
int32_t count, size, value; /* Working variables */
address &= 0x0007FFFF;
/* Perform the operation */
while (length > 0) {
/* VRAM */
if (address < 0x00040000) {
count = 0x00040000 - address;
if (length < count)
count = length;
readBytes(vue->vip.vram, 0x40000, address, dest, count);
}
/* Mirrors of character memory */
else if (address >= 0x00078000) {
count = 0x2000 - (address & 0x1FFF);
if (length < count)
count = length;
readBytes(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
dest, count);
}
/* I/O register or unmapped */
else {
count = 0x00078000 - address;
if (length < count)
count = length;
/* Read all registers in the range */
while (count > 0) {
value = vipReadRegister(vue, address);
/* Odd address */
if ((address & 1) == 1) {
*dest = value >> 8;
address++;
count --;
length --;
dest ++;
continue;
}
/* Even address */
size = count == 1 ? 1 : 2;
*dest = value;
if (size == 2)
dest[1] = value >> 8;
address += size;
count -= size;
length -= size;
dest += size;
}
continue;
}
/* Advance to the next region */
address += count;
length -= count;
dest += count;
}
}
/* System reset */
static void vipReset(Vue *vue) {
vue = vue;
}
/* Determine the number of CPU cycles until a breakpoint could trigger */
static uint32_t vipUntil(Vue *vue, uint32_t cycles) {
vue = vue;
return cycles;
}
/* Write a value to the CPU bus */
static void vipWrite(Vue *vue, int32_t address, int32_t type, int32_t value) {
address &= 0x0007FFFF;
/* VRAM */
if (address < 0x00040000) {
writeBuffer(vue->vip.vram, 0x40000, address, type, value);
return;
}
/* Mirrors of character memory */
if (address >= 0x00078000) {
writeBuffer(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
type, value);
return;
}
/* I/O register or unmapped */
if (type < 2 && (address & 1) == 1)
value <<= 8;
vipWriteRegister(vue, address, value);
if (type == VUE_S32)
vipWriteRegister(vue, address + 2, value >> 16);
}
/* Write bytes to the CPU bus */
static void vipWriteBytes(Vue *vue, int address, uint8_t *src, int length) {
int32_t count, size, value; /* Working variables */
address &= 0x0007FFFF;
/* Perform the operation */
while (length > 0) {
/* VRAM */
if (address < 0x00040000) {
count = 0x00040000 - address;
if (length < count)
count = length;
writeBytes(vue->vip.vram, 0x40000, address, src, count);
}
/* Mirrors of character memory */
else if (address >= 0x00078000) {
count = 0x2000 - (address & 0x1FFF);
if (length < count)
count = length;
writeBytes(vue->vip.vram, 0x40000,
(address - 0x00078000) >> 13 << 15 | 0x00006000 |
(address & 0x00001FFF),
src, count);
}
/* I/O register or unmapped */
else {
count = 0x00078000 - address;
if (length < count)
count = length;
/* Read all registers in the range */
while (count > 0) {
value = *src;
/* Odd address */
if ((address & 1) == 1) {
vipWriteRegister(vue, address, value << 8);
address++;
count --;
length --;
src ++;
continue;
}
/* Even address */
size = count == 1 ? 1 : 2;
if (size == 2)
value |= src[1] << 8;
vipWriteRegister(vue, address, value);
address += size;
count -= size;
length -= size;
src += size;
}
continue;
}
/* Advance to the next region */
address += count;
length -= count;
src += count;
}
}
#endif

View File

@ -22,15 +22,6 @@ static const uint32_t TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
/*****************************************************************************
* Component Includes *
*****************************************************************************/
#include "cpu.c"
#include "gamepak.c"
/***************************************************************************** /*****************************************************************************
* Module Functions * * Module Functions *
*****************************************************************************/ *****************************************************************************/
@ -150,6 +141,16 @@ static void writeBytes(uint8_t *data, uint32_t datlen, uint32_t address,
/*****************************************************************************
* Component Includes *
*****************************************************************************/
#include "cpu.c"
#include "gamepak.c"
#include "vip.c"
/***************************************************************************** /*****************************************************************************
* Library Functions * * Library Functions *
*****************************************************************************/ *****************************************************************************/
@ -167,7 +168,7 @@ uint32_t vueEmulate(Vue *vue, uint32_t maxCycles) {
/*cycles = padUntil (vue, cycles);*/ /*cycles = padUntil (vue, cycles);*/
/*cycles = linkUntil (vue, cycles);*/ /*cycles = linkUntil (vue, cycles);*/
/*cycles = timerUntil(vue, cycles);*/ /*cycles = timerUntil(vue, cycles);*/
/*cycles = vipUntil (vue, cycles);*/ cycles = vipUntil (vue, cycles);
/* Process all system components */ /* Process all system components */
vue->breakCode = 0; vue->breakCode = 0;
@ -176,7 +177,7 @@ uint32_t vueEmulate(Vue *vue, uint32_t maxCycles) {
/*pakEmulate (vue, cycles);*/ /*pakEmulate (vue, cycles);*/
/*linkEmulate (vue, cycles);*/ /*linkEmulate (vue, cycles);*/
/*timerEmulate(vue, cycles);*/ /*timerEmulate(vue, cycles);*/
/*vipEmulate (vue, cycles);*/ vipEmulate (vue, cycles);
/*vsuEmulate (vue, cycles);*/ /*vsuEmulate (vue, cycles);*/
maxCycles -= cycles; maxCycles -= cycles;
} while (vue->breakCode == 0 && maxCycles != 0); } while (vue->breakCode == 0 && maxCycles != 0);
@ -288,16 +289,6 @@ VueOnAccess vueOnWrite(Vue *vue, VueOnAccess callback) {
return ret; return ret;
} }
/* Specify a new application reference */
void* vueSetTag(Vue *vue, void *tag) {
void *ret;
if (vue == NULL)
return NULL;
ret = vue->tag;
vue->tag = tag;
return ret;
}
/* Read a value from the CPU bus */ /* Read a value from the CPU bus */
int32_t vueRead(Vue *vue, uint32_t address, int32_t type) { int32_t vueRead(Vue *vue, uint32_t address, int32_t type) {
@ -307,6 +298,7 @@ int32_t vueRead(Vue *vue, uint32_t address, int32_t type) {
/* Perform the operation */ /* Perform the operation */
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: return vipRead (vue , address,type);
case 5: return readBuffer(vue->wram , 0x10000,address,type); case 5: return readBuffer(vue->wram , 0x10000,address,type);
case 6: return readBuffer(vue->pak.ram,vue->pak.ramSize,address,type); case 6: return readBuffer(vue->pak.ram,vue->pak.ramSize,address,type);
case 7: return readBuffer(vue->pak.rom,vue->pak.romSize,address,type); case 7: return readBuffer(vue->pak.rom,vue->pak.romSize,address,type);
@ -328,6 +320,8 @@ vbool vueReadBytes(Vue *vue, uint32_t address, uint8_t *dest, uint32_t length){
if (length < count) if (length < count)
count = length; count = length;
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: vipReadBytes(vue ,
address, dest, count); break;
case 5: readBytes(vue->wram , 0x10000, case 5: readBytes(vue->wram , 0x10000,
address, dest, count); break; address, dest, count); break;
case 6: readBytes(vue->pak.ram, vue->pak.ramSize, case 6: readBytes(vue->pak.ram, vue->pak.ramSize,
@ -363,8 +357,22 @@ void vueReset(Vue *vue) {
/* Specify a value for a register */ /* Specify a value for a register */
int32_t vueSetRegister(Vue *vue, int32_t index, vbool system, int32_t value) { int32_t vueSetRegister(Vue *vue, int32_t index, vbool system, int32_t value) {
return vue == NULL ? 0 :
index == VUE_PC && system ? vue->cpu.pc = value & 0xFFFFFFFE : /* Error checking */
if (vue == NULL)
return 0;
/* PC */
if (index == VUE_PC && system) {
if (vue->cpu.stage == CPU_EXECUTE || vue->cpu.stage == CPU_FETCH) {
vue->cpu.fetch = -1;
vue->cpu.stage = CPU_FETCH;
}
return vue->cpu.pc = value & 0xFFFFFFFE;
}
/* Other */
return
index < 0 || index > 31 ? 0 : index < 0 || index > 31 ? 0 :
system ? cpuSetSystemRegister(vue, index, value, VUE_TRUE) : system ? cpuSetSystemRegister(vue, index, value, VUE_TRUE) :
index == 0 ? 0 : (vue->cpu.program[index] = value) index == 0 ? 0 : (vue->cpu.program[index] = value)
@ -388,6 +396,16 @@ vbool vueSetROM(Vue *vue, uint8_t *rom, uint32_t size) {
return VUE_TRUE; return VUE_TRUE;
} }
/* Specify a new application reference */
void* vueSetTag(Vue *vue, void *tag) {
void *ret;
if (vue == NULL)
return NULL;
ret = vue->tag;
vue->tag = tag;
return ret;
}
/* Write a value to the CPU bus */ /* Write a value to the CPU bus */
void vueWrite(Vue *vue, uint32_t address, int32_t type, int32_t value) { void vueWrite(Vue *vue, uint32_t address, int32_t type, int32_t value) {
@ -397,6 +415,8 @@ void vueWrite(Vue *vue, uint32_t address, int32_t type, int32_t value) {
/* Perform the operation */ /* Perform the operation */
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: vipWrite(vue ,
address, type, value); break;
case 5: writeBuffer(vue->wram , 0x10000, case 5: writeBuffer(vue->wram , 0x10000,
address, type, value); break; address, type, value); break;
case 6: writeBuffer(vue->pak.ram, vue->pak.ramSize, case 6: writeBuffer(vue->pak.ram, vue->pak.ramSize,
@ -421,6 +441,8 @@ vbool vueWriteBytes(Vue *vue, uint32_t address, uint8_t *src, uint32_t length){
if (length < count) if (length < count)
count = length; count = length;
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: vipWriteBytes(vue ,
address, src, count); break;
case 5: writeBytes(vue->wram , 0x10000, case 5: writeBytes(vue->wram , 0x10000,
address, src, count); break; address, src, count); break;
case 6: writeBytes(vue->pak.ram, vue->pak.ramSize, case 6: writeBytes(vue->pak.ram, vue->pak.ramSize,

View File

@ -23,6 +23,7 @@ public class App {
int hexDigitWidth; // Width in pixels of one hex digit int hexDigitWidth; // Width in pixels of one hex digit
Localizer localizer; // UI localization manager Localizer localizer; // UI localization manager
int[][] rgbBase; // Base anaglyph filter colors int[][] rgbBase; // Base anaglyph filter colors
int rgbClear; // Transparent pixel color
@ -36,11 +37,6 @@ public class App {
static final int[] GREEN = { 0x00, 0xB4, 0x00 }; static final int[] GREEN = { 0x00, 0xB4, 0x00 };
static final int[] MAGENTA = { 0xC8, 0x00, 0xFF }; static final int[] MAGENTA = { 0xC8, 0x00, 0xFF };
// Eyes
static final int LEFT = 0;
static final int RIGHT = 1;
static final int CHR = 2;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -60,6 +56,7 @@ public class App {
{ "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14)); { "Consolas", Font.MONOSPACED } ), Font.PLAIN, 14));
hexDigitWidth = hexDigitWidth(); hexDigitWidth = hexDigitWidth();
rgbBase = new int[][] { GREEN, MAGENTA, RED }; rgbBase = new int[][] { GREEN, MAGENTA, RED };
rgbClear = 0x003050;
// Additional processing // Additional processing
setUseNative(useNative); setUseNative(useNative);

View File

@ -25,11 +25,11 @@ class BreakpointsWindow extends ChildWindow {
private JCheckBox chkExecute; // Execute check box private JCheckBox chkExecute; // Execute check box
private JCheckBox chkRead; // Read check box private JCheckBox chkRead; // Read check box
private JCheckBox chkWrite; // Write check box private JCheckBox chkWrite; // Write check box
private JPanel client; // Client area private UPanel client; // Client area
private JLabel errAddress; // Address error text private JLabel errAddress; // Address error text
private JLabel errCondition; // Condition error text private JLabel errCondition; // Condition error text
private JPanel lstBreakpoints; // Breakpoint list private UPanel lstBreakpoints; // Breakpoint list
private JPanel spacer; // List termination spacer private UPanel spacer; // List termination spacer
private JTextField txtAddress; // Address text box private JTextField txtAddress; // Address text box
private JTextField txtCondition; // Condition text box private JTextField txtCondition; // Condition text box
private JTextField txtName; // Name text box private JTextField txtName; // Name text box
@ -161,31 +161,29 @@ class BreakpointsWindow extends ChildWindow {
selectedIndex = -1; selectedIndex = -1;
// Configure client area // Configure client area
client = new JPanel(new BorderLayout()); client = new UPanel(new BorderLayout());
client.setBackground(SystemColor.control); client.setBackground(SystemColor.control);
client.setFocusable(true); client.setFocusable(true);
client.setPreferredSize(new Dimension(320, 240)); client.setPreferredSize(new Dimension(320, 240));
// Configure breakpoint list // Configure breakpoint list
lstBreakpoints = new JPanel(new GridBagLayout()) { lstBreakpoints = new UPanel(new GridBagLayout());
public void paintComponent(Graphics g) {
super.paintComponent(g);
onPaint((Graphics2D) g, getWidth(), getHeight());
}
};
lstBreakpoints.setFocusable(true); lstBreakpoints.setFocusable(true);
lstBreakpoints.setBackground(SystemColor.window); lstBreakpoints.setBackground(SystemColor.window);
lstBreakpoints.addFocusListener(Util.onFocus( lstBreakpoints.addFocusListener(Util.onFocus(
e->lstBreakpoints.repaint(), e->lstBreakpoints.repaint())); e->lstBreakpoints.repaint(), e->lstBreakpoints.repaint()));
lstBreakpoints.addMouseListener(Util.onMouse(e->onMouseDown(e), null)); lstBreakpoints.addMouseListener(Util.onMouse(e->onMouseDown(e), null));
lstBreakpoints.addPaintListener((g,w,h)->onPaint(g, w, h));
var scr = new JScrollPane(lstBreakpoints); var scr = new JScrollPane(lstBreakpoints);
scr.getVerticalScrollBar().setUnitIncrement(
parent.app.fntDialog.metrics.getHeight());
client.add(scr, BorderLayout.CENTER); client.add(scr, BorderLayout.CENTER);
spacer = new JPanel(); spacer = new UPanel();
spacer.setOpaque(false); spacer.setOpaque(false);
lstBreakpoints.add(spacer, SPACER); lstBreakpoints.add(spacer, SPACER);
// Configure properties pane // Configure properties pane
var props = new JPanel(new GridBagLayout()); var props = new UPanel(new GridBagLayout());
props.setBackground(SystemColor.control); props.setBackground(SystemColor.control);
props.addMouseListener( props.addMouseListener(
Util.onMouse(e->client.requestFocus(), null)); Util.onMouse(e->client.requestFocus(), null));
@ -215,12 +213,12 @@ class BreakpointsWindow extends ChildWindow {
errCondition = error(props); errCondition = error(props);
// Configure buttons // Configure buttons
var buttons = new JPanel(new GridBagLayout()); var buttons = new UPanel(new GridBagLayout());
var gbc = new GridBagConstraints(); var gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL; gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER;
props.add(buttons, gbc); props.add(buttons, gbc);
var fill = new JPanel(); var fill = new UPanel();
fill.setOpaque(false); fill.setOpaque(false);
fill.addMouseListener(Util.onMouse(e->onDebug(e), null)); fill.addMouseListener(Util.onMouse(e->onDebug(e), null));
gbc = new GridBagConstraints(); gbc = new GridBagConstraints();
@ -448,7 +446,7 @@ class BreakpointsWindow extends ChildWindow {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Add a button to the form // Add a button to the form
private JButton button(JPanel panel, String key, boolean last) { private JButton button(UPanel panel, String key, boolean last) {
var btn = new JButton(); var btn = new JButton();
if (key != null) if (key != null)
parent.app.localizer.add(btn, key); parent.app.localizer.add(btn, key);
@ -462,7 +460,7 @@ class BreakpointsWindow extends ChildWindow {
} }
// Add a check box to the form // Add a check box to the form
private JCheckBox checkBox(JPanel panel, String key, boolean last) { private JCheckBox checkBox(UPanel panel, String key, boolean last) {
var chk = new JCheckBox(); var chk = new JCheckBox();
if (key != null) if (key != null)
parent.app.localizer.add(chk, key); parent.app.localizer.add(chk, key);
@ -509,7 +507,7 @@ class BreakpointsWindow extends ChildWindow {
} }
// Add an error label to the form // Add an error label to the form
private JLabel error(JPanel panel) { private JLabel error(UPanel panel) {
var lbl = new JLabel(); var lbl = new JLabel();
lbl.setForeground(Color.red); lbl.setForeground(Color.red);
lbl.setVisible(false); lbl.setVisible(false);
@ -524,7 +522,7 @@ class BreakpointsWindow extends ChildWindow {
} }
// Add a label to the form // Add a label to the form
private void label(JPanel panel, String key, int top) { private void label(UPanel panel, String key, int top) {
var lbl = new JLabel(); var lbl = new JLabel();
if (key != null) if (key != null)
parent.app.localizer.add(lbl, key); parent.app.localizer.add(lbl, key);
@ -594,7 +592,7 @@ class BreakpointsWindow extends ChildWindow {
} }
// Add a text box to the form // Add a text box to the form
private JTextField textBox(JPanel panel, boolean mono, int top, private JTextField textBox(UPanel panel, boolean mono, int top,
Commit handler) { Commit handler) {
var txt = new JTextField(); var txt = new JTextField();
txt.setEnabled(false); txt.setEnabled(false);

View File

@ -13,14 +13,29 @@ import util.*;
class CharactersWindow extends ChildWindow { class CharactersWindow extends ChildWindow {
// Instance fields // Instance fields
private int color; // Selected color index private int color; // Selected color index
private Point dragging; // Most recent pattern mouse position
private int index; // Current character index
private boolean grid; // Draw a grid around characters
private int palette; // Palette index
private int scale; // Display scale
private int wide; // Number of characters per row
// UI components // UI components
private JPanel client; // Client area private JCheckBox chkGrid; // Grid check box
private JPanel panCharacters; // Characters panel private UPanel client; // Client area
private JPanel panPalette; // Palette panel private UPanel panCharacters; // Characters panel
private JPanel panPattern; // Pattern panel private UPanel panPalette; // Palette panel
private UPanel panPattern; // Pattern panel
private JScrollPane scrCharacters; // Characters container
private JScrollPane scrControls; // Controls panel private JScrollPane scrControls; // Controls panel
private JScrollBar scrWidth; // Width template scroll bar
private JSlider sldScale; // Scale slider
private JSpinner spnIndex; // Index spinner
private JSpinner spnWide; // Wide spinner
private JTextField txtAddress; // Address text box
private JTextField txtMirror; // Mirror text box
private JComboBox<String> cmbPalette; // Palette drop-down
@ -34,16 +49,21 @@ class CharactersWindow extends ChildWindow {
// Configure instance fields // Configure instance fields
color = 0; color = 0;
grid = true;
scale = 3;
// Template scroll bar to check control width in the current LAF
scrWidth = new JScrollBar(JScrollBar.VERTICAL);
// Configure client area // Configure client area
client = new JPanel(new BorderLayout()); client = new UPanel(new BorderLayout());
client.setBackground(SystemColor.control); client.setBackground(SystemColor.control);
client.setFocusable(true); client.setFocusable(true);
client.setPreferredSize(new Dimension(480, 360)); client.setPreferredSize(new Dimension(480, 360));
client.addComponentListener(Util.onResize(e->onResize())); client.addComponentListener(Util.onResize(e->onResize()));
// Configure controls panel // Configure controls panel
var ctrls = new JPanel(new GridBagLayout()); var ctrls = new UPanel(new GridBagLayout());
ctrls.setBackground(SystemColor.control); ctrls.setBackground(SystemColor.control);
ctrls.addMouseListener( ctrls.addMouseListener(
Util.onMouse(e->client.requestFocus(), null)); Util.onMouse(e->client.requestFocus(), null));
@ -54,17 +74,29 @@ class CharactersWindow extends ChildWindow {
scrControls.getVerticalScrollBar().setUnitIncrement(20); scrControls.getVerticalScrollBar().setUnitIncrement(20);
client.add(scrControls, BorderLayout.WEST); client.add(scrControls, BorderLayout.WEST);
// Character controls
label(ctrls, "characters.index", true); label(ctrls, "characters.index", true);
spinner(ctrls, 0, 2047, 0, true); spnIndex = spinner(ctrls, 0, 2047, 0, true);
spnIndex.addChangeListener(e->{
setIndex((Integer) spnIndex.getValue()); });
label(ctrls, "characters.address", false); label(ctrls, "characters.address", false);
textBox(ctrls); txtAddress = textBox(ctrls);
txtAddress.addFocusListener(Util.onFocus(null,
e->onAddress(txtAddress)));
label(ctrls, "characters.mirror", false); label(ctrls, "characters.mirror", false);
textBox(ctrls); txtMirror = textBox(ctrls);
txtMirror.addFocusListener(Util.onFocus(null,
e->onAddress(txtMirror)));
// Pattern panel // Pattern panel
var panPattern = new JPanel(); panPattern = new UPanel();
panPattern.setBackground(Color.black); panPattern.setOpaque(false);
panPattern.setPreferredSize(new Dimension(96, 96)); panPattern.setPreferredSize(new Dimension(96, 96));
panPattern.addMouseListener(
Util.onMouse(e->onMousePattern(e), e->onMousePattern(e)));
panPattern.addMouseMotionListener(
Util.onMouseMove(null, e->onMousePattern(e)));
panPattern.addPaintListener((g,w,h)->onPaintPattern(g, w, h));
var gbc = new GridBagConstraints(); var gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER; gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER;
@ -72,16 +104,12 @@ class CharactersWindow extends ChildWindow {
ctrls.add(panPattern, gbc); ctrls.add(panPattern, gbc);
// Palette panel // Palette panel
panPalette = new JPanel() { panPalette = new UPanel();
public void paintComponent(Graphics g) {
super.paintComponent(g);
onPaintPalette((Graphics2D) g, getWidth(), getHeight());
}
};
panPalette.setOpaque(false); panPalette.setOpaque(false);
panPalette.setPreferredSize(new Dimension(0, 20 + 6)); panPalette.setPreferredSize(new Dimension(0, 20 + 6));
panPalette.addMouseListener( panPalette.addMouseListener(
Util.onMouse(e->onMouseDownPalette(e), null)); Util.onMouse(e->onMouseDownPalette(e), null));
panPalette.addPaintListener((g,w,h)->onPaintPalette(g, w, h));
gbc = new GridBagConstraints(); gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL; gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER;
@ -89,27 +117,37 @@ class CharactersWindow extends ChildWindow {
ctrls.add(panPalette, gbc); ctrls.add(panPalette, gbc);
// Fill the extra space above the view controls // Fill the extra space above the view controls
var spacer = new JPanel(); var spacer = new UPanel();
spacer.setOpaque(false); spacer.setOpaque(false);
gbc = new GridBagConstraints(); gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weighty = 1; gbc.weighty = 1;
ctrls.add(spacer, gbc); ctrls.add(spacer, gbc);
// View controls
label(ctrls, "characters.grid", false); label(ctrls, "characters.grid", false);
checkBox(ctrls).setSelected(true); chkGrid = checkBox(ctrls);
chkGrid.setSelected(grid);
chkGrid.addActionListener(e->{
grid = chkGrid.isSelected(); onView(); });
label(ctrls, "characters.wide", false); label(ctrls, "characters.wide", false);
spinner(ctrls, 0, 2048, 0, false); spnWide = spinner(ctrls, 0, 2048, 0, false);
spnWide.addChangeListener(e->{
wide = (Integer) spnWide.getValue(); onView(); });
label(ctrls, "characters.palette", false); label(ctrls, "characters.palette", false);
select(ctrls, new String[] { "palette.generic", cmbPalette = select(ctrls, new String[] { "palette.generic",
"palette.gplt0", "palette.gplt1", "palette.gplt2", "palette.gplt3", "palette.gplt0", "palette.gplt1", "palette.gplt2", "palette.gplt3",
"palette.jplt0", "palette.jplt1", "palette.jplt2", "palette.jplt3" "palette.jplt0", "palette.jplt1", "palette.jplt2", "palette.jplt3"
}); });
cmbPalette.addActionListener(e->{
palette = cmbPalette.getSelectedIndex(); repaint(); });
label(ctrls, "characters.scale", false); label(ctrls, "characters.scale", false);
slider(ctrls, 1, 10, 1); sldScale = slider(ctrls, 1, 10, scale);
sldScale.addChangeListener(e->{
scale = sldScale.getValue(); onView(); });
// Terminate the list of controls // Terminate the list of controls
spacer = new JPanel(); spacer = new UPanel();
spacer.setOpaque(false); spacer.setOpaque(false);
spacer.setPreferredSize(new Dimension(0, 0)); spacer.setPreferredSize(new Dimension(0, 0));
gbc = new GridBagConstraints(); gbc = new GridBagConstraints();
@ -118,20 +156,17 @@ class CharactersWindow extends ChildWindow {
ctrls.add(spacer, gbc); ctrls.add(spacer, gbc);
// Configure characters panel // Configure characters panel
panCharacters = new JPanel() { panCharacters = new UPanel();
public void paintComponent(Graphics g) {
super.paintComponent(g);
onPaintCharacters((Graphics2D) g, getWidth(), getHeight());
}
};
panCharacters.setBackground(SystemColor.control); panCharacters.setBackground(SystemColor.control);
panCharacters.addMouseListener( panCharacters.addMouseListener(
Util.onMouse(e->client.requestFocus(), null)); Util.onMouse(e->onMouseDownCharacters(e), null));
var scr = new JScrollPane(panCharacters); panCharacters.addPaintListener((g,w,h)->onPaintCharacters(g, w, h));
client.add(scr, BorderLayout.CENTER); scrCharacters = new JScrollPane(panCharacters);
client.add(scrCharacters, BorderLayout.CENTER);
// Configure component // Configure component
setContentPane(client); setContentPane(client);
setIndex(0);
pack(); pack();
} }
@ -152,6 +187,64 @@ class CharactersWindow extends ChildWindow {
// Event Handlers // // Event Handlers //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Address and Mirror text box commit
private void onAddress(JTextField src) {
int address;
// Parse the given address
try { address = (int) Long.parseLong(src.getText(), 16); }
catch (Exception e) {
setIndex(index);
return;
}
// Restrict address range
if ((address >> 24 & 7) != 0) {
setIndex(index);
return;
}
address &= 0x0007FFFF;
// Character memory
if ((address & 0x00066000) == 0x00006000)
index = address >> 15 << 9 | address >> 4 & 511;
// Mirror of character memory
else if (address >= 0x00078000)
index = address - 0x00078000 >> 4;
// Common processing
setIndex(index);
}
// Characters mouse button press
private void onMouseDownCharacters(MouseEvent e) {
// Common processing
client.requestFocus();
// Only consider left clicks
if (e.getButton() != MouseEvent.BUTTON1)
return;
// Working variables
int grid = this.grid ? 1 : 0;
int size = 8 * scale + grid;
int wide = this.wide != 0 ? this.wide :
Math.max(1, (panCharacters.getWidth() + grid) / size);
int col = e.getX() / size;
int row = e.getY() / size;
// The pixel is not within a character
if (col >= wide || row >= (2047 + wide) / wide)
return;
// Calculate the index of the selected character
int index = row * wide + col;
if (index < 2048)
setIndex(index);
}
// Palette mouse button press // Palette mouse button press
private void onMouseDownPalette(MouseEvent e) { private void onMouseDownPalette(MouseEvent e) {
@ -183,16 +276,154 @@ class CharactersWindow extends ChildWindow {
panPalette.repaint(); panPalette.repaint();
} }
// Pattern mouse
private void onMousePattern(MouseEvent e) {
int id = e.getID();
// Mouse release
if (id == MouseEvent.MOUSE_RELEASED) {
if (e.getButton() == MouseEvent.BUTTON1)
dragging = null;
return;
}
// Mouse press
if (id == MouseEvent.MOUSE_PRESSED) {
if (e.getButton() != MouseEvent.BUTTON1)
return;
dragging = e.getPoint();
}
// Not dragging
if (dragging == null)
return;
// Configure working variables
var pix = parent.chrs[index];
var pos = e.getPoint();
int scale = Math.max(1, Math.min(
panPattern.getWidth() / 8, panPattern.getHeight() / 8));
// Determine the bounds of the line segment
int left = Math.min(dragging.x, pos.x) / scale;
int right = (Math.max(dragging.x, pos.x) - 1) / scale;
int top = Math.min(dragging.y, pos.y) / scale;
int bottom = (Math.max(dragging.y, pos.y) - 1) / scale;
if (left >= 8 || right < 0 || top >= 8 || bottom < 0) {
dragging = pos;
return;
}
// The line segment occupies a single column of pixels
if (left == right) {
top = Math.max(0, top );
bottom = Math.min(7, bottom);
// Draw the column
for (
int y = top, dest = left + top * 8;
y <= bottom;
y++, dest += 8
) pix[dest] = (byte) color;
// Update the current VRAM state
parent.encode(index);
dragging = pos;
return;
}
// Calculate and order the vertex coordinates
float v0x = (float) dragging.x / scale;
float v0y = (float) dragging.y / scale;
float v1x = (float) pos .x / scale;
float v1y = (float) pos .y / scale;
if (v0x > v1x) {
float t = v0x; v0x = v1x; v1x = t;
t = v0y; v0y = v1y; v1y = t;
}
// Determine the starting position of the line segment
float slope = (v1y - v0y) / (v1x - v0x);
float cur, next;
if (v0x < 0) {
left = 0;
cur = v0y - slope * v0x;
next = cur + slope;
} else {
cur = v0y;
next = v0y + slope * (1 - v0x % 1);
}
// Draw all columns of pixels
int last = Math.min(7, right);
for (int x = left; x <= last; x++) {
// The column is the final column in the line segment
if (x == right)
next = v1y;
// Determine the top and bottom rows of pixels
v0y = Math.max(cur, next);
if (v0y % 1 == 0)
v0y--;
top = Math.max(0, (int) Math.floor(Math.min(cur, next)));
bottom = Math.min(7, (int) Math.floor(v0y ));
// Draw the column
for (
int y = top, dest = x + top * 8;
y <= bottom;
y++, dest += 8
) pix[dest] = (byte) color;
// Advance to the next column
cur = next;
next += slope;
}
// Update the current VRAM state
parent.encode(index);
dragging = pos;
}
// Characters paint // Characters paint
private void onPaintCharacters(Graphics2D g, int width, int height) { private void onPaintCharacters(Graphics2D g, int width, int height) {
g.setColor(new Color(0x001830)); var clear = new Color(parent.app.rgbClear);
g.fillRect(0, 0, 256, 512); int grid = this.grid ? 1 : 0;
var pal = parent.palettes[palette][MainWindow.RED];
var pix = new byte[64];
int size = scale * 8 + grid;
int wide = this.wide != 0 ? this.wide :
Math.max(1, (width + grid) / size);
int tall = (2047 + wide) / wide;
// Draw all characters
for (int Y = 0, y = 0, z = 0; y < tall; y++, Y += size)
for (int X = 0, x = 0; x < wide; x++, z++, X += size) {
if (z == 2048)
break;
g.setColor(clear);
g.fillRect(X, Y, size - grid, size - grid);
drawCharacter(g, X, Y, scale, z, pal);
}
// Highlight the selected character
int X = index % wide * size;
int Y = index / wide * size;
int light = SystemColor.textHighlight.getRGB() & 0x00FFFFFF;
g.setColor(new Color(0xD0000000 | light, true));
g.drawRect(X , Y , 8 * scale - 1, 8 * scale - 1);
g.setColor(new Color(0x90000000 | light, true));
g.drawRect(X + 1, Y + 1, 8 * scale - 3, 8 * scale - 3);
g.setColor(new Color(0x50000000 | light, true));
g.fillRect(X + 2, Y + 2, 8 * scale - 4, 8 * scale - 4);
} }
// Palette paint // Palette paint
private void onPaintPalette(Graphics2D g, int width, int height) { private void onPaintPalette(Graphics2D g, int width, int height) {
int size = Math.max(1, Math.min((width - 18) / 4, height - 6)); int size = Math.max(1, Math.min((width - 18) / 4, height - 6));
int left = (width - size * 4 - 18) / 2; int left = (width - size * 4 - 18) / 2;
var pal = parent.palettes[palette][MainWindow.RED];
int top = (height - size - 6) / 2; int top = (height - size - 6) / 2;
// Draw the color picker // Draw the color picker
@ -207,27 +438,85 @@ class CharactersWindow extends ChildWindow {
} }
// Draw the color area // Draw the color area
g.setColor(Color.black); g.setColor(x == 0 ? new Color(parent.app.rgbClear) : pal[x]);
g.fillRect(left + 3, top + 3, size , size ); g.fillRect(left + 3, top + 3, size , size );
} }
} }
// Pattern paint
private void onPaintPattern(Graphics2D g, int width, int height) {
int scale = Math.max(1, Math.min(width >> 3, height >> 3));
int x = (width - (scale << 3) + 1) >> 1;
int y = (height - (scale << 3) + 1) >> 1;
g.setColor(new Color(parent.app.rgbClear));
g.fillRect(x, y, scale * 8, scale * 8);
drawCharacter(g, x, y, scale, index,
parent.palettes[palette][MainWindow.RED]);
}
// Window resize // Window resize
private void onResize() { private void onResize() {
var viewport = scrControls.getViewport(); var viewport = scrControls.getViewport();
int inner = viewport.getView().getPreferredSize().width; int inner = viewport.getView().getPreferredSize().width;
int outer = viewport.getExtentSize().width; int outer = viewport.getExtentSize().width;
// The controls container does not need to be resized
if (inner == outer)
return;
// Size the controls container to match the inner component // Size the controls container to match the inner component
scrControls.setPreferredSize(new Dimension( if (inner != outer) {
scrControls.getPreferredSize().width + inner - outer, 0)); scrControls.setPreferredSize(new Dimension(
scrControls.revalidate(); scrControls.getPreferredSize().width + inner - outer, 0));
scrControls.repaint(); scrControls.revalidate();
scrControls.repaint();
}
// The number of characters per row is dynamic
if (wide == 0) {
var bar = scrWidth.getPreferredSize().width;
var border = scrCharacters.getBorder();
int grid = this.grid ? 1 : 0;
var insets = border == null ? new Insets(0, 0, 0, 0) :
border.getBorderInsets(scrCharacters);
var size = new Dimension(
scrCharacters.getWidth () - insets.left - insets.right,
scrCharacters.getHeight() - insets.top - insets.bottom
);
// Calculate the dimensions without the vertical scroll bar
int wide = Math.max(1, (size.width + grid) / (8 * scale + grid));
int height = (2047 + wide) / wide * (8 * scale + grid) - grid;
// Calculate the dimensions with the vertical scroll bar
if (height > size.height) {
wide = Math.max(1, (size.width-bar+grid) / (8 * scale + grid));
height = (2047 + wide) / wide * (8 * scale + grid) - grid;
}
// Configure the component
panCharacters.setPreferredSize(
new Dimension(wide * (8 * scale + grid) - grid, height));
panCharacters.revalidate();
panCharacters.repaint();
}
}
// View control changed
private void onView() {
// Number of characters per row is dynamic: defer to resize processing
if (wide == 0) {
onResize();
return;
}
// Calculate the space occupied by the character images
int grid = this.grid ? 1 : 0;
panCharacters.setPreferredSize(new Dimension(
wide * (scale * 8 + grid) - grid,
(2047 + wide) / wide * (scale * 8 + grid) - grid
));
panCharacters.revalidate();
panCharacters.repaint();
} }
@ -237,7 +526,7 @@ class CharactersWindow extends ChildWindow {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Add a check box to the controls panel // Add a check box to the controls panel
private JCheckBox checkBox(JPanel panel) { private JCheckBox checkBox(UPanel panel) {
var chk = new JCheckBox(); var chk = new JCheckBox();
chk.setBorder(null); chk.setBorder(null);
chk.setFocusable(false); chk.setFocusable(false);
@ -249,8 +538,21 @@ class CharactersWindow extends ChildWindow {
return chk; return chk;
} }
// Draw a character
private void drawCharacter(Graphics2D g, int X, int Y, int scale,
int index, Color[] pal) {
var pix = parent.chrs[index];
for (int y = 0, src = 0; y < 8; y++)
for (int x = 0; x < 8; x++, src++) {
if (pix[src] == 0)
continue;
g.setColor(pal[pix[src]]);
g.fillRect(X + x * scale, Y + y * scale, scale, scale);
}
}
// Add a label to the controls panel // Add a label to the controls panel
private void label(JPanel panel, String key, boolean top) { private void label(UPanel panel, String key, boolean top) {
var lbl = new JLabel(); var lbl = new JLabel();
parent.app.localizer.add(lbl, key); parent.app.localizer.add(lbl, key);
var gbc = new GridBagConstraints(); var gbc = new GridBagConstraints();
@ -260,7 +562,7 @@ class CharactersWindow extends ChildWindow {
} }
// Add a combo box to the controls panel // Add a combo box to the controls panel
private JComboBox<String> select(JPanel panel, String[] options) { private JComboBox<String> select(UPanel panel, String[] options) {
var cmb = new JComboBox<String>(); var cmb = new JComboBox<String>();
parent.app.localizer.add(cmb, options); parent.app.localizer.add(cmb, options);
cmb.setSelectedIndex(0); cmb.setSelectedIndex(0);
@ -272,8 +574,19 @@ class CharactersWindow extends ChildWindow {
return cmb; return cmb;
} }
// Specify the current character index
private void setIndex(int index) {
this.index = index;
spnIndex.setValue(index);
txtAddress.setText(String.format("%08X",
index >> 9 << 15 | 0x00006000 | (index & 511) << 4));
txtMirror .setText(String.format("%08X",
index << 4 | 0x00078000));
repaint();
}
// Add a slider to the controls panel // Add a slider to the controls panel
private JSlider slider(JPanel panel, int min, int max, int value) { private JSlider slider(UPanel panel, int min, int max, int value) {
var sld = new JSlider(min, max, value); var sld = new JSlider(min, max, value);
sld.setFocusable(false); sld.setFocusable(false);
sld.setPreferredSize(new Dimension(0, sld.getPreferredSize().height)); sld.setPreferredSize(new Dimension(0, sld.getPreferredSize().height));
@ -286,10 +599,12 @@ class CharactersWindow extends ChildWindow {
} }
// Add a spinner to the controls panel // Add a spinner to the controls panel
private JSpinner spinner(JPanel panel, int min, int max, int value, private JSpinner spinner(UPanel panel, int min, int max, int value,
boolean top) { boolean top) {
var spn = new JSpinner(new SpinnerNumberModel(value, min, max, 1)); var spn = new JSpinner(new SpinnerNumberModel(value, min, max, 1));
spn.setEditor(new JSpinner.NumberEditor(spn, "#")); var txt = new JSpinner.NumberEditor(spn, "#");
txt.getTextField().addActionListener(e->client.requestFocus());
spn.setEditor(txt);
var gbc = new GridBagConstraints(); var gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH; gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridwidth = GridBagConstraints.REMAINDER;
@ -300,9 +615,10 @@ class CharactersWindow extends ChildWindow {
} }
// Add a text box to the controls panel // Add a text box to the controls panel
private JTextField textBox(JPanel panel) { private JTextField textBox(UPanel panel) {
var txt = new JTextField(); var txt = new JTextField();
txt.setFont(parent.app.fntMono); txt.setFont(parent.app.fntMono);
txt.addActionListener(e->client.requestFocus());
var size = txt.getPreferredSize(); var size = txt.getPreferredSize();
txt.setPreferredSize(new Dimension( txt.setPreferredSize(new Dimension(
parent.app.hexDigitWidth * 8 + 2 + size.width, size.height)); parent.app.hexDigitWidth * 8 + 2 + size.width, size.height));

View File

@ -21,7 +21,7 @@ class DisassemblerPane extends JScrollPane {
private int[] widths; // Column widths private int[] widths; // Column widths
// UI components // UI components
private JPanel client; // Client area private UPanel client; // Client area
private ArrayList<Row> rows; // Disassembler output private ArrayList<Row> rows; // Disassembler output
@ -53,12 +53,7 @@ class DisassemblerPane extends JScrollPane {
widths = new int[5]; widths = new int[5];
// Configure client area // Configure client area
client = new JPanel() { client = new UPanel();
public void paintComponent(Graphics g) {
super.paintComponent(g);
onPaint((Graphics2D) g, getWidth(), getHeight());
}
};
client.setBackground(SystemColor.window); client.setBackground(SystemColor.window);
client.setFocusable(true); client.setFocusable(true);
client.addFocusListener( client.addFocusListener(
@ -66,6 +61,7 @@ class DisassemblerPane extends JScrollPane {
client.addKeyListener(Util.onKey(e->onKeyDown(e), null)); client.addKeyListener(Util.onKey(e->onKeyDown(e), null));
client.addMouseListener(Util.onMouse(e->client.requestFocus(), null)); client.addMouseListener(Util.onMouse(e->client.requestFocus(), null));
client.addMouseWheelListener(e->onMouseWheel(e)); client.addMouseWheelListener(e->onMouseWheel(e));
client.addPaintListener((g,w,h)->onPaint(g, w, h));
// Configure component // Configure component
setViewportView(client); setViewportView(client);

View File

@ -15,11 +15,12 @@ import vue.*;
class MainWindow extends JFrame { class MainWindow extends JFrame {
// Instance fields // Instance fields
App app; // Containing application App app; // Containing application
Breakpoint brkStep; // Single step internal breakpoint Breakpoint brkStep; // Single step internal breakpoint
int[][][] palettes; // Raster palettes byte[][] chrs; // Decoded pixel patterns
byte[] vram; // Snapshot of VIP memory Color[][][] palettes; // Raster palettes
Vue vue; // Emulation core context byte[] vram; // Snapshot of VIP memory
Vue vue; // Emulation core context
// Private fields // Private fields
private boolean debugMode; // Window is in debug mode private boolean debugMode; // Window is in debug mode
@ -30,10 +31,10 @@ class MainWindow extends JFrame {
private File romFile; // Currently loaded ROM file private File romFile; // Currently loaded ROM file
// UI components // UI components
private JPanel client; // Common client container private UPanel client; // Common client container
private JDesktopPane desktop; // Container for child windows private JDesktopPane desktop; // Container for child windows
private JMenu mnuDebug; // Debug menu private JMenu mnuDebug; // Debug menu
private JPanel video; // Video output private UPanel video; // Video output
private JMenuItem mnuFileDebugMode; // File -> Debug mode private JMenuItem mnuFileDebugMode; // File -> Debug mode
private JMenuItem mnuFileGameMode; // File -> Game mode private JMenuItem mnuFileGameMode; // File -> Game mode
@ -74,17 +75,6 @@ class MainWindow extends JFrame {
///////////////////////////////////////////////////////////////////////////
// Static Methods //
///////////////////////////////////////////////////////////////////////////
// Calculate the address of a character by index
static int chrAddress(int index) {
return index >> 9 << 15 | (index & 511) << 4;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Constructors // // Constructors //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -95,26 +85,29 @@ class MainWindow extends JFrame {
// Configure instance fields // Configure instance fields
this.app = app; this.app = app;
palettes = new int[9][3][4]; chrs = new byte[2048][64];
palettes = new Color[9][3][4];
pwd = Util.PWD; pwd = Util.PWD;
vram = new byte[0x40000]; vram = new byte[0x40000];
vue = Vue.create(app.getUseNative()); vue = Vue.create(app.getUseNative());
System.out.println("Native: " + System.out.println("Native: " +
(vue.isNative() ? Vue.getNativeID() : "No")); (vue.isNative() ? Vue.getNativeID() : "No"));
//vue.write(0x00078000, Vue.S32, -1);
// Initialize palettes
var invis = new Color(0, true);
for (int x = 0; x < 9; x++)
for (int y = 0; y < 3; y++)
for (int z = 0; z < 4; z++)
palettes[x][y][z] = invis;
// Configure video pane // Configure video pane
video = new JPanel() { video = new UPanel();
public void paintComponent(Graphics g) {
super.paintComponent(g);
onPaintVideo((Graphics2D) g, getWidth(), getHeight());
}
};
video.setPreferredSize(new Dimension(384, 224)); video.setPreferredSize(new Dimension(384, 224));
video.setFocusable(true); video.setFocusable(true);
video.addPaintListener((g,w,h)->onPaintVideo(g, w, h));
// Configure client area // Configure client area
client = new JPanel(new BorderLayout()); client = new UPanel(new BorderLayout());
client.add(video, BorderLayout.CENTER); client.add(video, BorderLayout.CENTER);
// Configure window // Configure window
@ -258,12 +251,28 @@ class MainWindow extends JFrame {
// Package Methods // // Package Methods //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Encode a character graphic
void encode(int index) {
int dest = index >> 9 << 15 | 0x00006000 | (index & 511) << 4;
var pix = chrs[index];
for (int y = 0, src = 0; y < 8; y++)
for (int b = 0, bits = 0; b < 2; b++, vram[dest++] = (byte) bits)
for (int x = 0; x < 4; x++, src++)
bits = bits >> 2 | pix[src] << 6;
vue.writeBytes(dest - 16, pix, dest - 16, 16);
refreshDebugLite(false);
}
// Refresh all debug views // Refresh all debug views
void refreshDebug(boolean seekToPC) { void refreshDebug(boolean seekToPC) {
vue.readBytes(0x00000000, vram, 0, vram.length); vue.readBytes(0x00000000, vram, 0, vram.length);
refreshCharacters();
refreshPalettes(); refreshPalettes();
refreshDebugLite(seekToPC);
}
// Refresh all debug views without retrieving video memory
void refreshDebugLite(boolean seekToPC) {
breakpoints.refresh(); breakpoints.refresh();
characters .refresh(); characters .refresh();
cpu .refresh(seekToPC); cpu .refresh(seekToPC);
@ -403,6 +412,18 @@ class MainWindow extends JFrame {
// Private Methods // // Private Methods //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Update the character patterns
private void refreshCharacters() {
for (int index = 0; index < 2048; index++) {
var pix = chrs[index];
int src = index >> 9 << 15 | 0x00006000 | (index & 511) << 4;
for (int y = 0, dest = 0; y < 8; y++)
for (int b = 0; b < 2; b++, src++)
for (int x = 0, bits = vram[src]; x < 4; x++, dest++, bits >>= 2)
pix[dest] = (byte) (bits & 3);
}
}
// Update the palette composites // Update the palette composites
private void refreshPalettes() { private void refreshPalettes() {
@ -440,9 +461,10 @@ class MainWindow extends JFrame {
var base = app.rgbBase[y]; var base = app.rgbBase[y];
var dest = palettes[x][y]; var dest = palettes[x][y];
for (int z = 1; z < 4; z++) { for (int z = 1; z < 4; z++) {
dest[z] = 0xFF000000; int argb = 0xFF000000;
for (int w = 0, bits = 16; w < 3; w++, bits -= 8) for (int w = 0, bits = 16; w < 3; w++, bits -= 8)
dest[z] |= (pal[z] * base[w] + 255) / 510 << bits; argb |= (pal[z] * base[w] + 255) / 510 << bits;
dest[z] = new Color(argb);
} }
} }

View File

@ -16,7 +16,7 @@ class MemoryWindow extends ChildWindow {
private int address; // Address of top row private int address; // Address of top row
// UI components // UI components
private JPanel client; // Client area private UPanel client; // Client area
private ArrayList<Row> rows; // Rows of text private ArrayList<Row> rows; // Rows of text
@ -46,7 +46,7 @@ class MemoryWindow extends ChildWindow {
rows = new ArrayList<Row>(); rows = new ArrayList<Row>();
// Configure client area // Configure client area
client = new JPanel(null); client = new UPanel();
client.addComponentListener(Util.onResize(e->onResize())); client.addComponentListener(Util.onResize(e->onResize()));
client.addKeyListener(Util.onKey(e->onKeyDown(e), null)); client.addKeyListener(Util.onKey(e->onKeyDown(e), null));
client.addMouseWheelListener(e->onWheel(e)); client.addMouseWheelListener(e->onWheel(e));
@ -55,7 +55,7 @@ class MemoryWindow extends ChildWindow {
client.setPreferredSize(new Dimension(480, 360)); client.setPreferredSize(new Dimension(480, 360));
// Configure component // Configure component
var content = new JPanel(new BorderLayout()); var content = new UPanel(new BorderLayout());
content.setBorder(new JScrollPane().getBorder()); content.setBorder(new JScrollPane().getBorder());
content.add(client, BorderLayout.CENTER); content.add(client, BorderLayout.CENTER);
setContentPane(content); setContentPane(content);

View File

@ -24,9 +24,9 @@ class Register {
private int value; // Current register value private int value; // Current register value
// UI components // UI components
JPanel expansion; // Expansion container UPanel expansion; // Expansion container
JLabel btnExpand; // Expand button JLabel btnExpand; // Expand button
JPanel indent; // Expansion area indentation UPanel indent; // Expansion area indentation
JLabel lblName; // Register name JLabel lblName; // Register name
JTextField txtValue; // Register value JTextField txtValue; // Register value
ArrayList<JComponent> controls; // Expansion controls ArrayList<JComponent> controls; // Expansion controls
@ -133,7 +133,7 @@ class Register {
// Expansion indentation // Expansion indentation
if (index != Vue.PC) { if (index != Vue.PC) {
indent = new JPanel(); indent = new UPanel();
indent.setOpaque(false); indent.setOpaque(false);
indent.setPreferredSize(new Dimension(0, 0)); indent.setPreferredSize(new Dimension(0, 0));
indent.setVisible(false); indent.setVisible(false);
@ -169,20 +169,20 @@ class Register {
// Expansion controls for CHCW // Expansion controls for CHCW
private void initCHCW() { private void initCHCW() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
addCheckBox("ICE", 1, false, true); addCheckBox("ICE", 1, false, true);
} }
// Expansion controls for ECR // Expansion controls for ECR
private void initECR() { private void initECR() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
addTextBox("EICC", 0, 16, false, true); addTextBox("EICC", 0, 16, false, true);
addTextBox("FECC", 16, 16, false, true); addTextBox("FECC", 16, 16, false, true);
} }
// Expansion controls for program registers // Expansion controls for program registers
private void initProgram() { private void initProgram() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
var group = new ButtonGroup(); var group = new ButtonGroup();
group.add(addRadioButton("cpu.hex" , HEX )); group.add(addRadioButton("cpu.hex" , HEX ));
group.add(addRadioButton("cpu.signed" , SIGNED )); group.add(addRadioButton("cpu.signed" , SIGNED ));
@ -192,13 +192,13 @@ class Register {
// Expansion controls for PC // Expansion controls for PC
private void initPC() { private void initPC() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
// Configure controls // Configure controls
for (int x = 0; x < 2; x++) { for (int x = 0; x < 2; x++) {
// Indentation // Indentation
indent = new JPanel(); indent = new UPanel();
indent.setOpaque(false); indent.setOpaque(false);
indent.setPreferredSize(new Dimension(0, 0)); indent.setPreferredSize(new Dimension(0, 0));
var gbc = new GridBagConstraints(); var gbc = new GridBagConstraints();
@ -234,7 +234,7 @@ class Register {
// Expansion controls for PSW // Expansion controls for PSW
private void initPSW() { private void initPSW() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
addCheckBox("Z" , 0, false, false); addCheckBox("Z" , 0, false, false);
addCheckBox("FRO", 9, false, true ); addCheckBox("FRO", 9, false, true );
addCheckBox("S" , 1, false, false); addCheckBox("S" , 1, false, false);
@ -254,13 +254,13 @@ class Register {
// Expansion controls for PIR // Expansion controls for PIR
private void initPIR() { private void initPIR() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
addTextBox("PT", 0, 16, true, true); addTextBox("PT", 0, 16, true, true);
} }
// Expansion controls for TKCW // Expansion controls for TKCW
private void initTKCW() { private void initTKCW() {
expansion = new JPanel(new GridBagLayout()); expansion = new UPanel(new GridBagLayout());
addCheckBox("OTM", 8, true, false); addCheckBox("OTM", 8, true, false);
addCheckBox("FVT", 5, true, true ); addCheckBox("FVT", 5, true, true );
addCheckBox("FIT", 7, true, false); addCheckBox("FIT", 7, true, false);

View File

@ -20,7 +20,7 @@ class RegisterList extends JScrollPane {
private boolean shown; // Component has been shown private boolean shown; // Component has been shown
// UI components // UI components
private JPanel client; // Client area private UPanel client; // Client area
@ -38,7 +38,7 @@ class RegisterList extends JScrollPane {
shown = true; shown = true;
// Configure client area // Configure client area
client = new JPanel(new GridBagLayout()) { client = new UPanel(new GridBagLayout()) {
public Dimension getPreferredSize() { public Dimension getPreferredSize() {
var ret = super.getPreferredSize(); var ret = super.getPreferredSize();
if (!shown) ret.height = system ? getInitialHeight() : 0; if (!shown) ret.height = system ? getInitialHeight() : 0;
@ -85,7 +85,7 @@ class RegisterList extends JScrollPane {
} }
// List terminator // List terminator
var spacer = new JPanel(); var spacer = new UPanel();
spacer.setOpaque(false); spacer.setOpaque(false);
spacer.setPreferredSize(new Dimension(0, 0)); spacer.setPreferredSize(new Dimension(0, 0));
var gbc = new GridBagConstraints(); var gbc = new GridBagConstraints();

View File

@ -0,0 +1,93 @@
package util;
// Java imports
import java.awt.*;
import java.util.*;
import javax.swing.*;
// Wrapper around JPanel to work around a bug in GridBagLayout
public class UPanel extends JPanel {
// Instance fields
private HashSet<PaintListener> paintListeners;
///////////////////////////////////////////////////////////////////////////
// Classes //
///////////////////////////////////////////////////////////////////////////
// Functional interface for paint events
public interface PaintListener {
void paint(Graphics2D g, int width, int height);
}
///////////////////////////////////////////////////////////////////////////
// Constructors //
///////////////////////////////////////////////////////////////////////////
// Default constructor
public UPanel() {
this(null);
}
// Layout manager constructor
public UPanel(LayoutManager layout) {
super(layout);
paintListeners = new HashSet<PaintListener>();
}
///////////////////////////////////////////////////////////////////////////
// Public Methods //
///////////////////////////////////////////////////////////////////////////
// Add a listener to receive paint events
public void addPaintListener(PaintListener l) {
if (l != null)
paintListeners.add(l);
}
// Retrieve a list of the current paint listeners
public PaintListener[] getPaintListeners() {
return paintListeners.toArray(
new PaintListener[paintListeners.size()]);
}
// Retrieve the maximum size of the component
public Dimension getMaximumSize() {
var ret = super.getMaximumSize();
return ret != null ? ret : new Dimension();
}
// Retrieve the minimum size of the component
public Dimension getMinimumSize() {
var ret = super.getMinimumSize();
return ret != null ? ret : new Dimension();
}
// Retrieve the preferred size of the component
public Dimension getPreferredSize() {
var ret = super.getPreferredSize();
return ret != null ? ret : new Dimension();
}
// Draw the component
public void paintComponent(Graphics g) {
super.paintComponent(g);
var G = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
for (var lst : paintListeners)
lst.paint(G, width, height);
}
// Remove a paint listener from the collection
public void removePaintListener(PaintListener l) {
paintListeners.remove(l);
}
}

View File

@ -645,9 +645,11 @@ class CPU {
// Transfer program to another address // Transfer program to another address
private void jump(int address) { private void jump(int address) {
int level = psw_np != 0 ? 2 : psw_ep; if (address != pc) {
jumpFrom[level] = pc; int level = psw_np != 0 ? 2 : psw_ep;
jumpTo [level] = address; jumpFrom[level] = pc;
jumpTo [level] = address;
}
pc = address - inst.size; pc = address - inst.size;
} }
@ -712,7 +714,7 @@ class CPU {
// Add Immediate // Add Immediate
private void ADDI() { private void ADDI() {
program[inst.reg2] = add(program[inst.reg2], inst.imm); program[inst.reg2] = add(program[inst.reg1], inst.imm);
} }
// And // And
@ -722,7 +724,7 @@ class CPU {
// And Immediate // And Immediate
private void ANDI() { private void ANDI() {
bitwise(program[inst.reg2] & inst.imm); bitwise(program[inst.reg1] & inst.imm);
} }
// Branch on Condition // Branch on Condition
@ -988,7 +990,7 @@ class CPU {
// Or Immediate // Or Immediate
private void ORI() { private void ORI() {
bitwise(program[inst.reg2] | inst.imm); bitwise(program[inst.reg1] | inst.imm);
} }
// Output Byte to Port // Output Byte to Port
@ -1131,7 +1133,7 @@ class CPU {
// Exclusive Or Immediate // Exclusive Or Immediate
private void XORI() { private void XORI() {
bitwise(program[inst.reg2] ^ inst.imm); bitwise(program[inst.reg1] ^ inst.imm);
} }
} }

View File

@ -9,11 +9,14 @@ class JavaVue extends Vue {
// Package fields // Package fields
int breakCode; // Application breakpoint code int breakCode; // Application breakpoint code
int breakType; // Most recent breakpoint scenario int breakType; // Most recent breakpoint scenario
CPU cpu; // Processor
GamePak pak; // Game pak
int[] stack; // Breakpoint condition evaluation stack int[] stack; // Breakpoint condition evaluation stack
byte[] wram; // System WRAM byte[] wram; // System WRAM
// System components
CPU cpu; // Processor
GamePak pak; // Game pak
VIP vip; // Video unit
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -31,10 +34,17 @@ class JavaVue extends Vue {
// Default constructor // Default constructor
JavaVue() { JavaVue() {
cpu = new CPU (this);
pak = new GamePak(this); // Configure instance fields
stack = new int[0]; stack = new int[0];
wram = new byte[0x10000]; wram = new byte[0x10000];
// Configure system components
cpu = new CPU (this);
pak = new GamePak(this);
vip = new VIP (this);
// Initialize state
reset(); reset();
} }
@ -59,7 +69,7 @@ class JavaVue extends Vue {
//cycles = pad .until(cycles); //cycles = pad .until(cycles);
//cycles = link .until(cycles); //cycles = link .until(cycles);
//cycles = timer.until(cycles); //cycles = timer.until(cycles);
//cycles = vip .until(cycles); cycles = vip .until(cycles);
// Process all system components // Process all system components
breakCode = 0; breakCode = 0;
@ -67,7 +77,7 @@ class JavaVue extends Vue {
//pad .emulate(cycles); //pad .emulate(cycles);
//link .emulate(cycles); //link .emulate(cycles);
//timer.emulate(cycles); //timer.emulate(cycles);
//vip .emulate(cycles); vip .emulate(cycles);
//vsu .emulate(cycles); //vsu .emulate(cycles);
maxCycles -= cycles; maxCycles -= cycles;
} while (breakCode == 0 && maxCycles != 0); } while (breakCode == 0 && maxCycles != 0);
@ -133,6 +143,7 @@ class JavaVue extends Vue {
// Perform the operation // Perform the operation
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: return vip.read ( address, type);
case 5: return readBuffer(wram , address, type); case 5: return readBuffer(wram , address, type);
case 6: return readBuffer(pak.ram, address, type); case 6: return readBuffer(pak.ram, address, type);
case 7: return readBuffer(pak.rom, address, type); case 7: return readBuffer(pak.rom, address, type);
@ -155,6 +166,7 @@ class JavaVue extends Vue {
while (length > 0) { while (length > 0) {
int count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF)); int count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF));
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: vip.readBytes( address,dest,offset,count); break;
case 5: readBytes(wram ,address,dest,offset,count); break; case 5: readBytes(wram ,address,dest,offset,count); break;
case 6: readBytes(pak.ram,address,dest,offset,count); break; case 6: readBytes(pak.ram,address,dest,offset,count); break;
case 7: readBytes(pak.rom,address,dest,offset,count); break; case 7: readBytes(pak.rom,address,dest,offset,count); break;
@ -176,8 +188,18 @@ class JavaVue extends Vue {
// Specify a register value // Specify a register value
public int setRegister(int index, boolean system, int value) { public int setRegister(int index, boolean system, int value) {
// PC
if (index == Vue.PC && system) {
if (cpu.stage == CPU.EXECUTE || cpu.stage == CPU.FETCH) {
cpu.fetch = -1;
cpu.stage = CPU.FETCH;
}
return cpu.pc = value & 0xFFFFFFFE;
}
// Other
return return
index == Vue.PC && system ? cpu.pc = value & 0xFFFFFFFE :
index < 0 || index > 31 ? 0 : index < 0 || index > 31 ? 0 :
system ? cpu.setSystemRegister(index, value, true) : system ? cpu.setSystemRegister(index, value, true) :
index == 0 ? 0 : (cpu.program[index] = value) index == 0 ? 0 : (cpu.program[index] = value)
@ -205,6 +227,7 @@ class JavaVue extends Vue {
// Write a value to the CPU bus // Write a value to the CPU bus
public void write(int address, int type, int value) { public void write(int address, int type, int value) {
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: vip.write ( address, type, value); break;
case 5: writeBuffer(wram , address, type, value); break; case 5: writeBuffer(wram , address, type, value); break;
case 6: writeBuffer(pak.ram, address, type, value); break; case 6: writeBuffer(pak.ram, address, type, value); break;
case 7: writeBuffer(pak.rom, address, type, value); break; case 7: writeBuffer(pak.rom, address, type, value); break;
@ -226,6 +249,7 @@ class JavaVue extends Vue {
while (length > 0) { while (length > 0) {
int count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF)); int count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF));
switch (address >> 24 & 7) { switch (address >> 24 & 7) {
case 0: vip.writeBytes( address,src,offset,count); break;
case 5: writeBytes(wram ,address,src,offset,count); break; case 5: writeBytes(wram ,address,src,offset,count); break;
case 6: writeBytes(pak.ram,address,src,offset,count); break; case 6: writeBytes(pak.ram,address,src,offset,count); break;
case 7: writeBytes(pak.rom,address,src,offset,count); break; case 7: writeBytes(pak.rom,address,src,offset,count); break;

309
src/desktop/vue/VIP.java Normal file
View File

@ -0,0 +1,309 @@
package vue;
// Java imports
import java.util.*;
// VIP state
class VIP {
// Instance fields
byte[] vram; // Video memory
// Private fields
private JavaVue vue; // Emulation state
///////////////////////////////////////////////////////////////////////////
// Constructors //
///////////////////////////////////////////////////////////////////////////
// Default constructor
VIP(JavaVue vue) {
vram = new byte[0x40000];
this.vue = vue;
}
///////////////////////////////////////////////////////////////////////////
// Package Methods //
///////////////////////////////////////////////////////////////////////////
// Process the simulation
void emulate(int cycles) {
}
// Read a value from the CPU bus
int read(int address, int type) {
address &= 0x0007FFFF;
// VRAM
if (address < 0x00040000)
return JavaVue.readBuffer(vram, address, type);
// Mirrors of character memory
if (address >= 0x00078000)
return JavaVue.readBuffer(vram,
address - 0x00078000 >> 13 << 15 | 0x00006000 |
address & 0x00001FFF,
type);
// I/O register or unmapped
int value = readRegister(address);
if (type < 2 && (address & 1) == 1)
value >>= 8;
switch (type) {
case Vue.S8 : return value << 24 >> 24;
case Vue.U8 : return value & 0x000000FF;
case Vue.S16: return value << 16 >> 16;
case Vue.S32: return value | readRegister(address + 2) << 16;
}
return value; // U16
}
// Read bytes from the CPU bus
void readBytes(int address, byte[] dest, int offset, int length) {
address &= 0x0007FFFF;
// Perform the operation
while (length > 0) {
int count;
// VRAM
if (address < 0x00040000) {
count = Math.min(length, 0x00040000 - address);
JavaVue.readBytes(vram, address, dest, offset, count);
}
// Mirrors of character memory
else if (address >= 0x00078000) {
count = Math.min(length, 0x2000 - (address & 0x1FFF));
JavaVue.readBytes(vram,
address - 0x00078000 >> 13 << 15 | 0x00006000 |
address & 0x00001FFF,
dest, offset, count);
}
// I/O register or unmapped
else {
count = Math.min(length, 0x00078000 - address);
// Read all registers in the range
while (count > 0) {
int value = readRegister(address);
// Odd address
if ((address & 1) == 1) {
dest[offset] = (byte) (value >> 8);
address++;
count --;
length --;
offset ++;
continue;
}
// Even address
int size = count == 1 ? 1 : 2;
dest[offset] = (byte) value;
if (size == 2)
dest[offset + 1] = (byte) (value >> 8);
address += size;
count -= size;
length -= size;
offset += size;
}
continue;
}
// Advance to the next region
address += count;
length -= count;
offset += count;
}
}
// System reset
void reset() {
}
// Determine the number of CPU cycles until a breakpoint could trigger
int until(int cycles) {
return cycles;
}
// Write a value to the CPU bus
void write(int address, int type, int value) {
address &= 0x0007FFFF;
// VRAM
if (address < 0x00040000) {
JavaVue.writeBuffer(vram, address, type, value);
return;
}
// Mirrors of character memory
if (address >= 0x00078000) {
JavaVue.writeBuffer(vram,
address - 0x00078000 >> 13 << 15 | 0x00006000 |
address & 0x00001FFF,
type, value);
return;
}
// I/O register or unmapped
if (type < 2 && (address & 1) == 1)
value <<= 8;
writeRegister(address, value);
if (type == Vue.S32)
writeRegister(address + 2, value >> 16);
}
// Write bytes to the CPU bus
void writeBytes(int address, byte[] src, int offset, int length) {
address &= 0x0007FFFF;
// Perform the operation
while (length > 0) {
int count;
// VRAM
if (address < 0x00040000) {
count = Math.min(length, 0x00040000 - address);
JavaVue.writeBytes(vram, address, src, offset, count);
}
// Mirrors of character memory
else if (address >= 0x00078000) {
count = Math.min(length, 0x2000 - (address & 0x1FFF));
JavaVue.writeBytes(vram,
address - 0x00078000 >> 13 << 15 | 0x00006000 |
address & 0x00001FFF,
src, offset, count);
}
// I/O register or unmapped
else {
count = Math.min(length, 0x00078000 - address);
// Write all registers in the range
while (count > 0) {
int value = src[offset] & 0xFF;
// Odd address
if ((address & 1) == 1) {
writeRegister(address, value << 8);
address++;
count --;
length --;
offset ++;
continue;
}
// Even address
int size = count == 1 ? 1 : 2;
if (size == 2)
value |= src[offset + 1] << 8;
writeRegister(address, value);
address += size;
count -= size;
length -= size;
offset += size;
}
continue;
}
// Advance to the next region
address += count;
length -= count;
offset += count;
}
}
///////////////////////////////////////////////////////////////////////////
// Private Methods //
///////////////////////////////////////////////////////////////////////////
// Read an I/O register
private int readRegister(int address) {
// Process by register
switch (address & ~1) {
case 0x0005F800: break; // INTPND
case 0x0005F802: break; // INTENB
case 0x0005F804: break; // INTCLR
case 0x0005F820: break; // DPSTTS
case 0x0005F822: break; // DPCTRL
case 0x0005F824: break; // BRTA
case 0x0005F826: break; // BRTB
case 0x0005F828: break; // BRTC
case 0x0005F82A: break; // REST
case 0x0005F82E: break; // FRMCYC
case 0x0005F830: break; // CTA
case 0x0005F840: break; // XPSTTS
case 0x0005F842: break; // XPCTRL
case 0x0005F844: break; // VER
case 0x0005F848: break; // SPT0
case 0x0005F84A: break; // SPT1
case 0x0005F84C: break; // SPT2
case 0x0005F84E: break; // SPT3
case 0x0005F860: break; // GPLT0
case 0x0005F862: break; // GPLT1
case 0x0005F864: break; // GPLT2
case 0x0005F866: break; // GPLT3
case 0x0005F868: break; // JPLT0
case 0x0005F86A: break; // JPLT1
case 0x0005F86C: break; // JPLT2
case 0x0005F86E: break; // JPLT3
case 0x0005F870: break; // BKCOL
}
// Unmapped
return 0;
}
// Write an I/O register
private void writeRegister(int address, int value) {
// Process by register
switch (address & ~1) {
case 0x0005F800: break; // INTPND
case 0x0005F802: break; // INTENB
case 0x0005F804: break; // INTCLR
case 0x0005F820: break; // DPSTTS
case 0x0005F822: break; // DPCTRL
case 0x0005F824: break; // BRTA
case 0x0005F826: break; // BRTB
case 0x0005F828: break; // BRTC
case 0x0005F82A: break; // REST
case 0x0005F82E: break; // FRMCYC
case 0x0005F830: break; // CTA
case 0x0005F840: break; // XPSTTS
case 0x0005F842: break; // XPCTRL
case 0x0005F844: break; // VER
case 0x0005F848: break; // SPT0
case 0x0005F84A: break; // SPT1
case 0x0005F84C: break; // SPT2
case 0x0005F84E: break; // SPT3
case 0x0005F860: break; // GPLT0
case 0x0005F862: break; // GPLT1
case 0x0005F864: break; // GPLT2
case 0x0005F866: break; // GPLT3
case 0x0005F868: break; // JPLT0
case 0x0005F86A: break; // JPLT1
case 0x0005F86C: break; // JPLT2
case 0x0005F86E: break; // JPLT3
case 0x0005F870: break; // BKCOL
}
}
}