Introducing VIP memory controller and Characters window, fixing Format V instructions, adjusting JNI includes
This commit is contained in:
parent
9f5a5233ea
commit
8192fb6960
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
@ -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_ */
|
|
@ -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_ */
|
7
makefile
7
makefile
|
@ -1,8 +1,7 @@
|
|||
# Java include directory pathnames
|
||||
# The Windows files need to be copied from a Windows JDK installation
|
||||
include_linux = /usr/lib/jvm/java-15-openjdk-`\
|
||||
uname -r | sed 's/.*-//'`/include
|
||||
include_windows = jni-windows-include
|
||||
include_linux = jni/linux
|
||||
include_windows = jni/windows
|
||||
|
||||
# Default goal
|
||||
.PHONY: default
|
||||
|
@ -10,7 +9,7 @@ default:
|
|||
@echo $(include_linux)
|
||||
@echo "Planet Virtual Boy Emulator"
|
||||
@echo " https://www.planetvb.com/"
|
||||
@echo " December 17, 2020"
|
||||
@echo " December 25, 2020"
|
||||
@echo
|
||||
@echo "Intended build environment: Debian i386 or amd64"
|
||||
@echo " gcc-multilib"
|
||||
|
|
|
@ -265,9 +265,12 @@ static int32_t cpuGetSystemRegister(Vue *vue, int32_t index) {
|
|||
|
||||
/* Transfer program to another address */
|
||||
static void cpuJump(Vue *vue, int32_t address) {
|
||||
int level = vue->cpu.psw_np ? 2 : vue->cpu.psw_ep;
|
||||
vue->cpu.jumpFrom[level] = vue->cpu.pc;
|
||||
vue->cpu.jumpTo [level] = address;
|
||||
int level;
|
||||
if (address != vue->cpu.pc) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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]))
|
||||
|
||||
/* 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 */
|
||||
#define cpuAND(vue) \
|
||||
|
@ -499,7 +504,7 @@ static vbool cpuWrite(Vue *vue, int32_t address, int8_t type, int32_t value) {
|
|||
|
||||
/* And Immediate */
|
||||
#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)
|
||||
|
||||
/* Branch on Condition */
|
||||
|
@ -756,7 +761,7 @@ static void cpuMULU(Vue *vue) {
|
|||
|
||||
/* Or Immediate */
|
||||
#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)
|
||||
|
||||
/* Return from Trap or Interrupt */
|
||||
|
@ -876,7 +881,7 @@ static void cpuXH(Vue *vue) {
|
|||
|
||||
/* Exclusive Or Immediate */
|
||||
#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)
|
||||
|
||||
|
||||
|
@ -1182,6 +1187,12 @@ static vbool cpuFetch(Vue *vue) {
|
|||
return VUE_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Internal Functions *
|
||||
******************************************************************************/
|
||||
|
||||
/* Process the simulation */
|
||||
static void cpuEmulate(Vue *vue, uint32_t cycles) {
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ struct Vue {
|
|||
uint16_t ecr_fecc; /* Fatal Error Cause Code */
|
||||
} cpu;
|
||||
|
||||
/* Game pak */
|
||||
/* Game pak state */
|
||||
struct {
|
||||
uint8_t *ram; /* 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 */
|
||||
} pak;
|
||||
|
||||
/* VIP state */
|
||||
struct {
|
||||
uint8_t vram[0x40000]; /* Video memory */
|
||||
} vip;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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 *
|
||||
*****************************************************************************/
|
||||
|
@ -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 *
|
||||
*****************************************************************************/
|
||||
|
@ -167,7 +168,7 @@ uint32_t vueEmulate(Vue *vue, uint32_t maxCycles) {
|
|||
/*cycles = padUntil (vue, cycles);*/
|
||||
/*cycles = linkUntil (vue, cycles);*/
|
||||
/*cycles = timerUntil(vue, cycles);*/
|
||||
/*cycles = vipUntil (vue, cycles);*/
|
||||
cycles = vipUntil (vue, cycles);
|
||||
|
||||
/* Process all system components */
|
||||
vue->breakCode = 0;
|
||||
|
@ -176,7 +177,7 @@ uint32_t vueEmulate(Vue *vue, uint32_t maxCycles) {
|
|||
/*pakEmulate (vue, cycles);*/
|
||||
/*linkEmulate (vue, cycles);*/
|
||||
/*timerEmulate(vue, cycles);*/
|
||||
/*vipEmulate (vue, cycles);*/
|
||||
vipEmulate (vue, cycles);
|
||||
/*vsuEmulate (vue, cycles);*/
|
||||
maxCycles -= cycles;
|
||||
} while (vue->breakCode == 0 && maxCycles != 0);
|
||||
|
@ -288,16 +289,6 @@ VueOnAccess vueOnWrite(Vue *vue, VueOnAccess callback) {
|
|||
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 */
|
||||
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 */
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: return vipRead (vue , address,type);
|
||||
case 5: return readBuffer(vue->wram , 0x10000,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);
|
||||
|
@ -328,6 +320,8 @@ vbool vueReadBytes(Vue *vue, uint32_t address, uint8_t *dest, uint32_t length){
|
|||
if (length < count)
|
||||
count = length;
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: vipReadBytes(vue ,
|
||||
address, dest, count); break;
|
||||
case 5: readBytes(vue->wram , 0x10000,
|
||||
address, dest, count); break;
|
||||
case 6: readBytes(vue->pak.ram, vue->pak.ramSize,
|
||||
|
@ -363,8 +357,22 @@ void vueReset(Vue *vue) {
|
|||
|
||||
/* Specify a value for a register */
|
||||
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 :
|
||||
system ? cpuSetSystemRegister(vue, index, value, VUE_TRUE) :
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: vipWrite(vue ,
|
||||
address, type, value); break;
|
||||
case 5: writeBuffer(vue->wram , 0x10000,
|
||||
address, type, value); break;
|
||||
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)
|
||||
count = length;
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: vipWriteBytes(vue ,
|
||||
address, src, count); break;
|
||||
case 5: writeBytes(vue->wram , 0x10000,
|
||||
address, src, count); break;
|
||||
case 6: writeBytes(vue->pak.ram, vue->pak.ramSize,
|
||||
|
|
|
@ -23,6 +23,7 @@ public class App {
|
|||
int hexDigitWidth; // Width in pixels of one hex digit
|
||||
Localizer localizer; // UI localization manager
|
||||
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[] 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));
|
||||
hexDigitWidth = hexDigitWidth();
|
||||
rgbBase = new int[][] { GREEN, MAGENTA, RED };
|
||||
rgbClear = 0x003050;
|
||||
|
||||
// Additional processing
|
||||
setUseNative(useNative);
|
||||
|
|
|
@ -25,11 +25,11 @@ class BreakpointsWindow extends ChildWindow {
|
|||
private JCheckBox chkExecute; // Execute check box
|
||||
private JCheckBox chkRead; // Read 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 errCondition; // Condition error text
|
||||
private JPanel lstBreakpoints; // Breakpoint list
|
||||
private JPanel spacer; // List termination spacer
|
||||
private UPanel lstBreakpoints; // Breakpoint list
|
||||
private UPanel spacer; // List termination spacer
|
||||
private JTextField txtAddress; // Address text box
|
||||
private JTextField txtCondition; // Condition text box
|
||||
private JTextField txtName; // Name text box
|
||||
|
@ -161,31 +161,29 @@ class BreakpointsWindow extends ChildWindow {
|
|||
selectedIndex = -1;
|
||||
|
||||
// Configure client area
|
||||
client = new JPanel(new BorderLayout());
|
||||
client = new UPanel(new BorderLayout());
|
||||
client.setBackground(SystemColor.control);
|
||||
client.setFocusable(true);
|
||||
client.setPreferredSize(new Dimension(320, 240));
|
||||
|
||||
// Configure breakpoint list
|
||||
lstBreakpoints = new JPanel(new GridBagLayout()) {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
onPaint((Graphics2D) g, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
lstBreakpoints = new UPanel(new GridBagLayout());
|
||||
lstBreakpoints.setFocusable(true);
|
||||
lstBreakpoints.setBackground(SystemColor.window);
|
||||
lstBreakpoints.addFocusListener(Util.onFocus(
|
||||
e->lstBreakpoints.repaint(), e->lstBreakpoints.repaint()));
|
||||
lstBreakpoints.addMouseListener(Util.onMouse(e->onMouseDown(e), null));
|
||||
lstBreakpoints.addPaintListener((g,w,h)->onPaint(g, w, h));
|
||||
var scr = new JScrollPane(lstBreakpoints);
|
||||
scr.getVerticalScrollBar().setUnitIncrement(
|
||||
parent.app.fntDialog.metrics.getHeight());
|
||||
client.add(scr, BorderLayout.CENTER);
|
||||
spacer = new JPanel();
|
||||
spacer = new UPanel();
|
||||
spacer.setOpaque(false);
|
||||
lstBreakpoints.add(spacer, SPACER);
|
||||
|
||||
// Configure properties pane
|
||||
var props = new JPanel(new GridBagLayout());
|
||||
var props = new UPanel(new GridBagLayout());
|
||||
props.setBackground(SystemColor.control);
|
||||
props.addMouseListener(
|
||||
Util.onMouse(e->client.requestFocus(), null));
|
||||
|
@ -215,12 +213,12 @@ class BreakpointsWindow extends ChildWindow {
|
|||
errCondition = error(props);
|
||||
|
||||
// Configure buttons
|
||||
var buttons = new JPanel(new GridBagLayout());
|
||||
var buttons = new UPanel(new GridBagLayout());
|
||||
var gbc = new GridBagConstraints();
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
props.add(buttons, gbc);
|
||||
var fill = new JPanel();
|
||||
var fill = new UPanel();
|
||||
fill.setOpaque(false);
|
||||
fill.addMouseListener(Util.onMouse(e->onDebug(e), null));
|
||||
gbc = new GridBagConstraints();
|
||||
|
@ -448,7 +446,7 @@ class BreakpointsWindow extends ChildWindow {
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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();
|
||||
if (key != null)
|
||||
parent.app.localizer.add(btn, key);
|
||||
|
@ -462,7 +460,7 @@ class BreakpointsWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// 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();
|
||||
if (key != null)
|
||||
parent.app.localizer.add(chk, key);
|
||||
|
@ -509,7 +507,7 @@ class BreakpointsWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// Add an error label to the form
|
||||
private JLabel error(JPanel panel) {
|
||||
private JLabel error(UPanel panel) {
|
||||
var lbl = new JLabel();
|
||||
lbl.setForeground(Color.red);
|
||||
lbl.setVisible(false);
|
||||
|
@ -524,7 +522,7 @@ class BreakpointsWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// 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();
|
||||
if (key != null)
|
||||
parent.app.localizer.add(lbl, key);
|
||||
|
@ -594,7 +592,7 @@ class BreakpointsWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
var txt = new JTextField();
|
||||
txt.setEnabled(false);
|
||||
|
|
|
@ -13,14 +13,29 @@ import util.*;
|
|||
class CharactersWindow extends ChildWindow {
|
||||
|
||||
// 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
|
||||
private JPanel client; // Client area
|
||||
private JPanel panCharacters; // Characters panel
|
||||
private JPanel panPalette; // Palette panel
|
||||
private JPanel panPattern; // Pattern panel
|
||||
private JCheckBox chkGrid; // Grid check box
|
||||
private UPanel client; // Client area
|
||||
private UPanel panCharacters; // Characters panel
|
||||
private UPanel panPalette; // Palette panel
|
||||
private UPanel panPattern; // Pattern panel
|
||||
private JScrollPane scrCharacters; // Characters container
|
||||
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
|
||||
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
|
||||
client = new JPanel(new BorderLayout());
|
||||
client = new UPanel(new BorderLayout());
|
||||
client.setBackground(SystemColor.control);
|
||||
client.setFocusable(true);
|
||||
client.setPreferredSize(new Dimension(480, 360));
|
||||
client.addComponentListener(Util.onResize(e->onResize()));
|
||||
|
||||
// Configure controls panel
|
||||
var ctrls = new JPanel(new GridBagLayout());
|
||||
var ctrls = new UPanel(new GridBagLayout());
|
||||
ctrls.setBackground(SystemColor.control);
|
||||
ctrls.addMouseListener(
|
||||
Util.onMouse(e->client.requestFocus(), null));
|
||||
|
@ -54,17 +74,29 @@ class CharactersWindow extends ChildWindow {
|
|||
scrControls.getVerticalScrollBar().setUnitIncrement(20);
|
||||
client.add(scrControls, BorderLayout.WEST);
|
||||
|
||||
// Character controls
|
||||
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);
|
||||
textBox(ctrls);
|
||||
txtAddress = textBox(ctrls);
|
||||
txtAddress.addFocusListener(Util.onFocus(null,
|
||||
e->onAddress(txtAddress)));
|
||||
label(ctrls, "characters.mirror", false);
|
||||
textBox(ctrls);
|
||||
txtMirror = textBox(ctrls);
|
||||
txtMirror.addFocusListener(Util.onFocus(null,
|
||||
e->onAddress(txtMirror)));
|
||||
|
||||
// Pattern panel
|
||||
var panPattern = new JPanel();
|
||||
panPattern.setBackground(Color.black);
|
||||
panPattern = new UPanel();
|
||||
panPattern.setOpaque(false);
|
||||
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();
|
||||
gbc.anchor = GridBagConstraints.CENTER;
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
|
@ -72,16 +104,12 @@ class CharactersWindow extends ChildWindow {
|
|||
ctrls.add(panPattern, gbc);
|
||||
|
||||
// Palette panel
|
||||
panPalette = new JPanel() {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
onPaintPalette((Graphics2D) g, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
panPalette = new UPanel();
|
||||
panPalette.setOpaque(false);
|
||||
panPalette.setPreferredSize(new Dimension(0, 20 + 6));
|
||||
panPalette.addMouseListener(
|
||||
Util.onMouse(e->onMouseDownPalette(e), null));
|
||||
panPalette.addPaintListener((g,w,h)->onPaintPalette(g, w, h));
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
|
@ -89,27 +117,37 @@ class CharactersWindow extends ChildWindow {
|
|||
ctrls.add(panPalette, gbc);
|
||||
|
||||
// Fill the extra space above the view controls
|
||||
var spacer = new JPanel();
|
||||
var spacer = new UPanel();
|
||||
spacer.setOpaque(false);
|
||||
gbc = new GridBagConstraints();
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
gbc.weighty = 1;
|
||||
ctrls.add(spacer, gbc);
|
||||
|
||||
// View controls
|
||||
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);
|
||||
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);
|
||||
select(ctrls, new String[] { "palette.generic",
|
||||
cmbPalette = select(ctrls, new String[] { "palette.generic",
|
||||
"palette.gplt0", "palette.gplt1", "palette.gplt2", "palette.gplt3",
|
||||
"palette.jplt0", "palette.jplt1", "palette.jplt2", "palette.jplt3"
|
||||
});
|
||||
cmbPalette.addActionListener(e->{
|
||||
palette = cmbPalette.getSelectedIndex(); repaint(); });
|
||||
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
|
||||
spacer = new JPanel();
|
||||
spacer = new UPanel();
|
||||
spacer.setOpaque(false);
|
||||
spacer.setPreferredSize(new Dimension(0, 0));
|
||||
gbc = new GridBagConstraints();
|
||||
|
@ -118,20 +156,17 @@ class CharactersWindow extends ChildWindow {
|
|||
ctrls.add(spacer, gbc);
|
||||
|
||||
// Configure characters panel
|
||||
panCharacters = new JPanel() {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
onPaintCharacters((Graphics2D) g, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
panCharacters = new UPanel();
|
||||
panCharacters.setBackground(SystemColor.control);
|
||||
panCharacters.addMouseListener(
|
||||
Util.onMouse(e->client.requestFocus(), null));
|
||||
var scr = new JScrollPane(panCharacters);
|
||||
client.add(scr, BorderLayout.CENTER);
|
||||
Util.onMouse(e->onMouseDownCharacters(e), null));
|
||||
panCharacters.addPaintListener((g,w,h)->onPaintCharacters(g, w, h));
|
||||
scrCharacters = new JScrollPane(panCharacters);
|
||||
client.add(scrCharacters, BorderLayout.CENTER);
|
||||
|
||||
// Configure component
|
||||
setContentPane(client);
|
||||
setIndex(0);
|
||||
pack();
|
||||
}
|
||||
|
||||
|
@ -152,6 +187,64 @@ class CharactersWindow extends ChildWindow {
|
|||
// 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
|
||||
private void onMouseDownPalette(MouseEvent e) {
|
||||
|
||||
|
@ -183,16 +276,154 @@ class CharactersWindow extends ChildWindow {
|
|||
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
|
||||
private void onPaintCharacters(Graphics2D g, int width, int height) {
|
||||
g.setColor(new Color(0x001830));
|
||||
g.fillRect(0, 0, 256, 512);
|
||||
var clear = new Color(parent.app.rgbClear);
|
||||
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
|
||||
private void onPaintPalette(Graphics2D g, int width, int height) {
|
||||
int size = Math.max(1, Math.min((width - 18) / 4, height - 6));
|
||||
int left = (width - size * 4 - 18) / 2;
|
||||
var pal = parent.palettes[palette][MainWindow.RED];
|
||||
int top = (height - size - 6) / 2;
|
||||
|
||||
// Draw the color picker
|
||||
|
@ -207,27 +438,85 @@ class CharactersWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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
|
||||
private void onResize() {
|
||||
var viewport = scrControls.getViewport();
|
||||
int inner = viewport.getView().getPreferredSize().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
|
||||
scrControls.setPreferredSize(new Dimension(
|
||||
scrControls.getPreferredSize().width + inner - outer, 0));
|
||||
scrControls.revalidate();
|
||||
scrControls.repaint();
|
||||
if (inner != outer) {
|
||||
scrControls.setPreferredSize(new Dimension(
|
||||
scrControls.getPreferredSize().width + inner - outer, 0));
|
||||
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
|
||||
private JCheckBox checkBox(JPanel panel) {
|
||||
private JCheckBox checkBox(UPanel panel) {
|
||||
var chk = new JCheckBox();
|
||||
chk.setBorder(null);
|
||||
chk.setFocusable(false);
|
||||
|
@ -249,8 +538,21 @@ class CharactersWindow extends ChildWindow {
|
|||
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
|
||||
private void label(JPanel panel, String key, boolean top) {
|
||||
private void label(UPanel panel, String key, boolean top) {
|
||||
var lbl = new JLabel();
|
||||
parent.app.localizer.add(lbl, key);
|
||||
var gbc = new GridBagConstraints();
|
||||
|
@ -260,7 +562,7 @@ class CharactersWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// 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>();
|
||||
parent.app.localizer.add(cmb, options);
|
||||
cmb.setSelectedIndex(0);
|
||||
|
@ -272,8 +574,19 @@ class CharactersWindow extends ChildWindow {
|
|||
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
|
||||
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);
|
||||
sld.setFocusable(false);
|
||||
sld.setPreferredSize(new Dimension(0, sld.getPreferredSize().height));
|
||||
|
@ -286,10 +599,12 @@ class CharactersWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
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();
|
||||
gbc.fill = GridBagConstraints.BOTH;
|
||||
gbc.gridwidth = GridBagConstraints.REMAINDER;
|
||||
|
@ -300,9 +615,10 @@ class CharactersWindow extends ChildWindow {
|
|||
}
|
||||
|
||||
// Add a text box to the controls panel
|
||||
private JTextField textBox(JPanel panel) {
|
||||
private JTextField textBox(UPanel panel) {
|
||||
var txt = new JTextField();
|
||||
txt.setFont(parent.app.fntMono);
|
||||
txt.addActionListener(e->client.requestFocus());
|
||||
var size = txt.getPreferredSize();
|
||||
txt.setPreferredSize(new Dimension(
|
||||
parent.app.hexDigitWidth * 8 + 2 + size.width, size.height));
|
||||
|
|
|
@ -21,7 +21,7 @@ class DisassemblerPane extends JScrollPane {
|
|||
private int[] widths; // Column widths
|
||||
|
||||
// UI components
|
||||
private JPanel client; // Client area
|
||||
private UPanel client; // Client area
|
||||
private ArrayList<Row> rows; // Disassembler output
|
||||
|
||||
|
||||
|
@ -53,12 +53,7 @@ class DisassemblerPane extends JScrollPane {
|
|||
widths = new int[5];
|
||||
|
||||
// Configure client area
|
||||
client = new JPanel() {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
onPaint((Graphics2D) g, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
client = new UPanel();
|
||||
client.setBackground(SystemColor.window);
|
||||
client.setFocusable(true);
|
||||
client.addFocusListener(
|
||||
|
@ -66,6 +61,7 @@ class DisassemblerPane extends JScrollPane {
|
|||
client.addKeyListener(Util.onKey(e->onKeyDown(e), null));
|
||||
client.addMouseListener(Util.onMouse(e->client.requestFocus(), null));
|
||||
client.addMouseWheelListener(e->onMouseWheel(e));
|
||||
client.addPaintListener((g,w,h)->onPaint(g, w, h));
|
||||
|
||||
// Configure component
|
||||
setViewportView(client);
|
||||
|
|
|
@ -15,11 +15,12 @@ import vue.*;
|
|||
class MainWindow extends JFrame {
|
||||
|
||||
// Instance fields
|
||||
App app; // Containing application
|
||||
Breakpoint brkStep; // Single step internal breakpoint
|
||||
int[][][] palettes; // Raster palettes
|
||||
byte[] vram; // Snapshot of VIP memory
|
||||
Vue vue; // Emulation core context
|
||||
App app; // Containing application
|
||||
Breakpoint brkStep; // Single step internal breakpoint
|
||||
byte[][] chrs; // Decoded pixel patterns
|
||||
Color[][][] palettes; // Raster palettes
|
||||
byte[] vram; // Snapshot of VIP memory
|
||||
Vue vue; // Emulation core context
|
||||
|
||||
// Private fields
|
||||
private boolean debugMode; // Window is in debug mode
|
||||
|
@ -30,10 +31,10 @@ class MainWindow extends JFrame {
|
|||
private File romFile; // Currently loaded ROM file
|
||||
|
||||
// UI components
|
||||
private JPanel client; // Common client container
|
||||
private UPanel client; // Common client container
|
||||
private JDesktopPane desktop; // Container for child windows
|
||||
private JMenu mnuDebug; // Debug menu
|
||||
private JPanel video; // Video output
|
||||
private UPanel video; // Video output
|
||||
private JMenuItem mnuFileDebugMode; // File -> Debug 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 //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -95,26 +85,29 @@ class MainWindow extends JFrame {
|
|||
|
||||
// Configure instance fields
|
||||
this.app = app;
|
||||
palettes = new int[9][3][4];
|
||||
chrs = new byte[2048][64];
|
||||
palettes = new Color[9][3][4];
|
||||
pwd = Util.PWD;
|
||||
vram = new byte[0x40000];
|
||||
vue = Vue.create(app.getUseNative());
|
||||
System.out.println("Native: " +
|
||||
(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
|
||||
video = new JPanel() {
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
onPaintVideo((Graphics2D) g, getWidth(), getHeight());
|
||||
}
|
||||
};
|
||||
video = new UPanel();
|
||||
video.setPreferredSize(new Dimension(384, 224));
|
||||
video.setFocusable(true);
|
||||
video.addPaintListener((g,w,h)->onPaintVideo(g, w, h));
|
||||
|
||||
// Configure client area
|
||||
client = new JPanel(new BorderLayout());
|
||||
client = new UPanel(new BorderLayout());
|
||||
client.add(video, BorderLayout.CENTER);
|
||||
|
||||
// Configure window
|
||||
|
@ -258,12 +251,28 @@ class MainWindow extends JFrame {
|
|||
// 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
|
||||
void refreshDebug(boolean seekToPC) {
|
||||
|
||||
vue.readBytes(0x00000000, vram, 0, vram.length);
|
||||
refreshCharacters();
|
||||
refreshPalettes();
|
||||
refreshDebugLite(seekToPC);
|
||||
}
|
||||
|
||||
// Refresh all debug views without retrieving video memory
|
||||
void refreshDebugLite(boolean seekToPC) {
|
||||
breakpoints.refresh();
|
||||
characters .refresh();
|
||||
cpu .refresh(seekToPC);
|
||||
|
@ -403,6 +412,18 @@ class MainWindow extends JFrame {
|
|||
// 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
|
||||
private void refreshPalettes() {
|
||||
|
||||
|
@ -440,9 +461,10 @@ class MainWindow extends JFrame {
|
|||
var base = app.rgbBase[y];
|
||||
var dest = palettes[x][y];
|
||||
for (int z = 1; z < 4; z++) {
|
||||
dest[z] = 0xFF000000;
|
||||
int argb = 0xFF000000;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class MemoryWindow extends ChildWindow {
|
|||
private int address; // Address of top row
|
||||
|
||||
// UI components
|
||||
private JPanel client; // Client area
|
||||
private UPanel client; // Client area
|
||||
private ArrayList<Row> rows; // Rows of text
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ class MemoryWindow extends ChildWindow {
|
|||
rows = new ArrayList<Row>();
|
||||
|
||||
// Configure client area
|
||||
client = new JPanel(null);
|
||||
client = new UPanel();
|
||||
client.addComponentListener(Util.onResize(e->onResize()));
|
||||
client.addKeyListener(Util.onKey(e->onKeyDown(e), null));
|
||||
client.addMouseWheelListener(e->onWheel(e));
|
||||
|
@ -55,7 +55,7 @@ class MemoryWindow extends ChildWindow {
|
|||
client.setPreferredSize(new Dimension(480, 360));
|
||||
|
||||
// Configure component
|
||||
var content = new JPanel(new BorderLayout());
|
||||
var content = new UPanel(new BorderLayout());
|
||||
content.setBorder(new JScrollPane().getBorder());
|
||||
content.add(client, BorderLayout.CENTER);
|
||||
setContentPane(content);
|
||||
|
|
|
@ -24,9 +24,9 @@ class Register {
|
|||
private int value; // Current register value
|
||||
|
||||
// UI components
|
||||
JPanel expansion; // Expansion container
|
||||
UPanel expansion; // Expansion container
|
||||
JLabel btnExpand; // Expand button
|
||||
JPanel indent; // Expansion area indentation
|
||||
UPanel indent; // Expansion area indentation
|
||||
JLabel lblName; // Register name
|
||||
JTextField txtValue; // Register value
|
||||
ArrayList<JComponent> controls; // Expansion controls
|
||||
|
@ -133,7 +133,7 @@ class Register {
|
|||
|
||||
// Expansion indentation
|
||||
if (index != Vue.PC) {
|
||||
indent = new JPanel();
|
||||
indent = new UPanel();
|
||||
indent.setOpaque(false);
|
||||
indent.setPreferredSize(new Dimension(0, 0));
|
||||
indent.setVisible(false);
|
||||
|
@ -169,20 +169,20 @@ class Register {
|
|||
|
||||
// Expansion controls for CHCW
|
||||
private void initCHCW() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
addCheckBox("ICE", 1, false, true);
|
||||
}
|
||||
|
||||
// Expansion controls for ECR
|
||||
private void initECR() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
addTextBox("EICC", 0, 16, false, true);
|
||||
addTextBox("FECC", 16, 16, false, true);
|
||||
}
|
||||
|
||||
// Expansion controls for program registers
|
||||
private void initProgram() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
var group = new ButtonGroup();
|
||||
group.add(addRadioButton("cpu.hex" , HEX ));
|
||||
group.add(addRadioButton("cpu.signed" , SIGNED ));
|
||||
|
@ -192,13 +192,13 @@ class Register {
|
|||
|
||||
// Expansion controls for PC
|
||||
private void initPC() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
|
||||
// Configure controls
|
||||
for (int x = 0; x < 2; x++) {
|
||||
|
||||
// Indentation
|
||||
indent = new JPanel();
|
||||
indent = new UPanel();
|
||||
indent.setOpaque(false);
|
||||
indent.setPreferredSize(new Dimension(0, 0));
|
||||
var gbc = new GridBagConstraints();
|
||||
|
@ -234,7 +234,7 @@ class Register {
|
|||
|
||||
// Expansion controls for PSW
|
||||
private void initPSW() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
addCheckBox("Z" , 0, false, false);
|
||||
addCheckBox("FRO", 9, false, true );
|
||||
addCheckBox("S" , 1, false, false);
|
||||
|
@ -254,13 +254,13 @@ class Register {
|
|||
|
||||
// Expansion controls for PIR
|
||||
private void initPIR() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
addTextBox("PT", 0, 16, true, true);
|
||||
}
|
||||
|
||||
// Expansion controls for TKCW
|
||||
private void initTKCW() {
|
||||
expansion = new JPanel(new GridBagLayout());
|
||||
expansion = new UPanel(new GridBagLayout());
|
||||
addCheckBox("OTM", 8, true, false);
|
||||
addCheckBox("FVT", 5, true, true );
|
||||
addCheckBox("FIT", 7, true, false);
|
||||
|
|
|
@ -20,7 +20,7 @@ class RegisterList extends JScrollPane {
|
|||
private boolean shown; // Component has been shown
|
||||
|
||||
// UI components
|
||||
private JPanel client; // Client area
|
||||
private UPanel client; // Client area
|
||||
|
||||
|
||||
|
||||
|
@ -38,7 +38,7 @@ class RegisterList extends JScrollPane {
|
|||
shown = true;
|
||||
|
||||
// Configure client area
|
||||
client = new JPanel(new GridBagLayout()) {
|
||||
client = new UPanel(new GridBagLayout()) {
|
||||
public Dimension getPreferredSize() {
|
||||
var ret = super.getPreferredSize();
|
||||
if (!shown) ret.height = system ? getInitialHeight() : 0;
|
||||
|
@ -85,7 +85,7 @@ class RegisterList extends JScrollPane {
|
|||
}
|
||||
|
||||
// List terminator
|
||||
var spacer = new JPanel();
|
||||
var spacer = new UPanel();
|
||||
spacer.setOpaque(false);
|
||||
spacer.setPreferredSize(new Dimension(0, 0));
|
||||
var gbc = new GridBagConstraints();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -645,9 +645,11 @@ class CPU {
|
|||
|
||||
// Transfer program to another address
|
||||
private void jump(int address) {
|
||||
int level = psw_np != 0 ? 2 : psw_ep;
|
||||
jumpFrom[level] = pc;
|
||||
jumpTo [level] = address;
|
||||
if (address != pc) {
|
||||
int level = psw_np != 0 ? 2 : psw_ep;
|
||||
jumpFrom[level] = pc;
|
||||
jumpTo [level] = address;
|
||||
}
|
||||
pc = address - inst.size;
|
||||
}
|
||||
|
||||
|
@ -712,7 +714,7 @@ class CPU {
|
|||
|
||||
// Add Immediate
|
||||
private void ADDI() {
|
||||
program[inst.reg2] = add(program[inst.reg2], inst.imm);
|
||||
program[inst.reg2] = add(program[inst.reg1], inst.imm);
|
||||
}
|
||||
|
||||
// And
|
||||
|
@ -722,7 +724,7 @@ class CPU {
|
|||
|
||||
// And Immediate
|
||||
private void ANDI() {
|
||||
bitwise(program[inst.reg2] & inst.imm);
|
||||
bitwise(program[inst.reg1] & inst.imm);
|
||||
}
|
||||
|
||||
// Branch on Condition
|
||||
|
@ -988,7 +990,7 @@ class CPU {
|
|||
|
||||
// Or Immediate
|
||||
private void ORI() {
|
||||
bitwise(program[inst.reg2] | inst.imm);
|
||||
bitwise(program[inst.reg1] | inst.imm);
|
||||
}
|
||||
|
||||
// Output Byte to Port
|
||||
|
@ -1131,7 +1133,7 @@ class CPU {
|
|||
|
||||
// Exclusive Or Immediate
|
||||
private void XORI() {
|
||||
bitwise(program[inst.reg2] ^ inst.imm);
|
||||
bitwise(program[inst.reg1] ^ inst.imm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,11 +9,14 @@ class JavaVue extends Vue {
|
|||
// Package fields
|
||||
int breakCode; // Application breakpoint code
|
||||
int breakType; // Most recent breakpoint scenario
|
||||
CPU cpu; // Processor
|
||||
GamePak pak; // Game pak
|
||||
int[] stack; // Breakpoint condition evaluation stack
|
||||
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
|
||||
JavaVue() {
|
||||
cpu = new CPU (this);
|
||||
pak = new GamePak(this);
|
||||
|
||||
// Configure instance fields
|
||||
stack = new int[0];
|
||||
wram = new byte[0x10000];
|
||||
|
||||
// Configure system components
|
||||
cpu = new CPU (this);
|
||||
pak = new GamePak(this);
|
||||
vip = new VIP (this);
|
||||
|
||||
// Initialize state
|
||||
reset();
|
||||
}
|
||||
|
||||
|
@ -59,7 +69,7 @@ class JavaVue extends Vue {
|
|||
//cycles = pad .until(cycles);
|
||||
//cycles = link .until(cycles);
|
||||
//cycles = timer.until(cycles);
|
||||
//cycles = vip .until(cycles);
|
||||
cycles = vip .until(cycles);
|
||||
|
||||
// Process all system components
|
||||
breakCode = 0;
|
||||
|
@ -67,7 +77,7 @@ class JavaVue extends Vue {
|
|||
//pad .emulate(cycles);
|
||||
//link .emulate(cycles);
|
||||
//timer.emulate(cycles);
|
||||
//vip .emulate(cycles);
|
||||
vip .emulate(cycles);
|
||||
//vsu .emulate(cycles);
|
||||
maxCycles -= cycles;
|
||||
} while (breakCode == 0 && maxCycles != 0);
|
||||
|
@ -133,6 +143,7 @@ class JavaVue extends Vue {
|
|||
|
||||
// Perform the operation
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: return vip.read ( address, type);
|
||||
case 5: return readBuffer(wram , address, type);
|
||||
case 6: return readBuffer(pak.ram, address, type);
|
||||
case 7: return readBuffer(pak.rom, address, type);
|
||||
|
@ -155,6 +166,7 @@ class JavaVue extends Vue {
|
|||
while (length > 0) {
|
||||
int count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF));
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: vip.readBytes( 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 7: readBytes(pak.rom,address,dest,offset,count); break;
|
||||
|
@ -176,8 +188,18 @@ class JavaVue extends Vue {
|
|||
|
||||
// Specify a register 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
|
||||
index == Vue.PC && system ? cpu.pc = value & 0xFFFFFFFE :
|
||||
index < 0 || index > 31 ? 0 :
|
||||
system ? cpu.setSystemRegister(index, value, true) :
|
||||
index == 0 ? 0 : (cpu.program[index] = value)
|
||||
|
@ -205,6 +227,7 @@ class JavaVue extends Vue {
|
|||
// Write a value to the CPU bus
|
||||
public void write(int address, int type, int value) {
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: vip.write ( address, type, value); break;
|
||||
case 5: writeBuffer(wram , address, type, value); break;
|
||||
case 6: writeBuffer(pak.ram, address, type, value); break;
|
||||
case 7: writeBuffer(pak.rom, address, type, value); break;
|
||||
|
@ -226,6 +249,7 @@ class JavaVue extends Vue {
|
|||
while (length > 0) {
|
||||
int count = Math.min(length, 0x01000000 - (address & 0x00FFFFFF));
|
||||
switch (address >> 24 & 7) {
|
||||
case 0: vip.writeBytes( 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 7: writeBytes(pak.rom,address,src,offset,count); break;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue