xeij/LogicalSpaceMonitor.java
//========================================================================================
// LogicalSpaceMonitor.java
// en:Logical space monitor
// ja:論理空間モニタ
// Copyright (C) 2003-2024 Makoto Kamada
//
// This file is part of the XEiJ (X68000 Emulator in Java).
// You can use, modify and redistribute the XEiJ if the conditions are met.
// Read the XEiJ License for more details.
// https://stdkmd.net/xeij/
//========================================================================================
package xeij;
import java.awt.*; //BasicStroke,BorderLayout,BoxLayout,Color,Component,Container,Cursor,Desktop,Dimension,Font,FlowLayout,Frame,Graphics,Graphics2D,GraphicsDevice,GraphicsEnvironment,GridLayout,Image,Insets,Paint,Point,Rectangle,RenderingHints,Robot,Shape,Stroke,TexturePaint,Toolkit
import java.awt.event.*; //ActionEvent,ActionListener,ComponentAdapter,ComponentEvent,ComponentListener,FocusAdapter,FocusEvent,FocusListener,InputEvent,KeyAdapter,KeyEvent,KeyListener,MouseAdapter,MouseEvent,MouseListener,MouseMotionAdapter,MouseWheelEvent,WindowAdapter,WindowEvent,WindowListener,WindowStateListener
import java.lang.*; //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
import javax.swing.*; //AbstractButton,AbstractSpinnerModel,Box,ButtonGroup,DefaultListModel,ImageIcon,JApplet,JButton,JCheckBox,JCheckBoxMenuItem,JComponent,JDialog,JFileChooser,JFrame,JLabel,JList,JMenu,JMenuBar,JMenuItem,JPanel,JRadioButton,JScrollPane,JSpinner,JTextArea,JTextField,JTextPane,JViewport,ScrollPaneConstants,SpinnerListModel,SpinnerNumberModel,SwingConstants,SwingUtilities,UIManager,UIDefaults,UnsupportedLookAndFeelException
public class LogicalSpaceMonitor {
public static JFrame atwFrame; //ウインドウ
public static final ScrollTextArea[] atwBoard = new ScrollTextArea[2]; //スクロールテキストエリア
public static final JTextArea[] atwTextArea = new JTextArea[2]; //テキストエリア
//atwInit ()
// 初期化
public static void atwInit () {
atwFrame = null;
} //atwInit()
//atwStart ()
public static void atwStart () {
if (RestorableFrame.rfmGetOpened (Settings.SGS_ATW_FRAME_KEY)) {
atwOpen ();
}
} //atwStart()
//atwOpen ()
// アドレス変換ウインドウを開く
// 既に開いているときは手前に持ってくる
public static void atwOpen () {
if (atwFrame == null) {
atwMake ();
}
atwUpdate ();
XEiJ.pnlExitFullScreen (false);
atwFrame.setVisible (true);
XEiJ.dbgVisibleMask |= XEiJ.DBG_ATW_VISIBLE_MASK;
} //atwOpen()
//atwMake ()
// アドレス変換ウインドウを作る
public static void atwMake () {
for (int m = 0; m < 2; m++) {
//スクロールテキストエリア
atwBoard[m] = ComponentFactory.setPreferredSize (
ComponentFactory.setFont (new ScrollTextArea (), LnF.lnfMonospacedFont),
550, 250);
atwBoard[m].setMargin (new Insets (2, 4, 2, 4));
atwBoard[m].setHighlightCursorOn (true);
atwTextArea[m] = atwBoard[m].getTextArea ();
atwTextArea[m].setEditable (false);
}
//テキストエリアのマウスリスナー
ComponentFactory.addListener (
atwTextArea[0],
new MouseAdapter () {
@Override public void mousePressed (MouseEvent me) {
if (XEiJ.mpuTask == null && me.isPopupTrigger ()) {
XEiJ.dbgShowPopup (me, atwTextArea[0], false);
}
}
@Override public void mouseReleased (MouseEvent me) {
if (XEiJ.mpuTask == null && me.isPopupTrigger ()) {
XEiJ.dbgShowPopup (me, atwTextArea[0], false);
}
}
});
ComponentFactory.addListener (
atwTextArea[1],
new MouseAdapter () {
@Override public void mousePressed (MouseEvent me) {
if (XEiJ.mpuTask == null && me.isPopupTrigger ()) {
XEiJ.dbgShowPopup (me, atwTextArea[1], false);
}
}
@Override public void mouseReleased (MouseEvent me) {
if (XEiJ.mpuTask == null && me.isPopupTrigger ()) {
XEiJ.dbgShowPopup (me, atwTextArea[1], false);
}
}
});
//ボタンのアクションリスナー
ActionListener listener = new ActionListener () {
@Override public void actionPerformed (ActionEvent ae) {
Object source = ae.getSource ();
switch (ae.getActionCommand ()) {
case "Update":
atwUpdate ();
break;
}
}
};
//ウインドウ
atwFrame = Multilingual.mlnTitle (
ComponentFactory.createRestorableSubFrame (
Settings.SGS_ATW_FRAME_KEY,
"Logical space monitor",
null,
ComponentFactory.createBorderPanel (
ComponentFactory.createVerticalSplitPane (
ComponentFactory.createVerticalBox (
ComponentFactory.createHorizontalBox (
Multilingual.mlnText (ComponentFactory.createLabel ("User mode"), "ja", "ユーザモード"),
Box.createHorizontalGlue ()
),
atwBoard[0]
),
ComponentFactory.createVerticalBox (
ComponentFactory.createHorizontalBox (
Multilingual.mlnText (ComponentFactory.createLabel ("Supervisor mode"), "ja", "スーパーバイザモード"),
Box.createHorizontalGlue ()
),
atwBoard[1]
)
),
ComponentFactory.createHorizontalBox (
Multilingual.mlnToolTipText (
ComponentFactory.createImageButton (
XEiJ.createImage (
20, 14,
"11111111111111111111" +
"1..................1" +
"1.......1111.......1" +
"1......111111.1....1" +
"1.....11....111....1" +
"1....11.....111....1" +
"1....11....1111....1" +
"1....11............1" +
"1....11............1" +
"1.....11....11.....1" +
"1......111111......1" +
"1.......1111.......1" +
"1..................1" +
"11111111111111111111",
LnF.lnfRGB[0],
LnF.lnfRGB[12]),
"Update", listener),
"ja", "更新"),
Box.createHorizontalGlue ()
)
)
),
"ja", "論理空間モニタ");
ComponentFactory.addListener (
atwFrame,
new WindowAdapter () {
@Override public void windowClosing (WindowEvent we) {
XEiJ.dbgVisibleMask &= ~XEiJ.DBG_ATW_VISIBLE_MASK;
}
});
} //atwMake()
//atwUpdate ()
// アドレス変換ウインドウを更新する
public static void atwUpdate () {
for (int m = 0; m < 2; m++) {
StringBuilder sb = new StringBuilder ();
sb.append (Multilingual.mlnJapanese ?
//xxxxxxx-xxxxxxxx xxxxxxxx-xxxxxxxx
" 論理アドレス 物理アドレス\n" :
" Logical address Physical address\n");
int l0 = 0x00000000;
int p0 = MC68060.mmuTranslatePeek (l0, m, 0);
int f0 = MC68060.mmuPeekFlags;
if ((p0 ^ l0) == 1) {
p0 = 1;
}
int l1 = MC68060.mmuPageSize;
while (l1 != 0x00000000) {
int p1 = MC68060.mmuTranslatePeek (l1, m, 0);
int f1 = MC68060.mmuPeekFlags;
if ((p1 ^ l1) == 1) {
p1 = 1;
}
if (!(p0 == 1 && p1 == 1 ||
p0 != 1 && p1 != 1 && p1 - p0 == l1 - l0 && f0 == f1)) {
if (p0 != 1) {
XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (sb, l0).append ('-'), l1 - 1).append (" "), p0).append ('-'), p0 + (l1 - l0) - 1).append (' ');
if ((f0 & MC68060.MMU_DESCRIPTOR_SUPERVISOR_PROTECTED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [スーパーバイザ]" : " [Supervisor]");
}
if ((f0 & MC68060.MMU_DESCRIPTOR_MODIFIED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [修正済み]" : " [Modified]");
}
if ((f0 & MC68060.MMU_DESCRIPTOR_USED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [使用済み]" : " [Used]");
}
if ((f0 & MC68060.MMU_DESCRIPTOR_WRITE_PROTECTED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [書き込み禁止]" : " [Write-protected]");
}
sb.append ('\n');
}
l0 = l1;
p0 = p1;
f0 = f1;
}
l1 += MC68060.mmuPageSize;
}
if (p0 != 1) {
XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (XEiJ.fmtHex8 (sb, l0).append ('-'), l1 - 1).append (" "), p0).append ('-'), p0 + (l1 - l0) - 1).append (' ');
if ((f0 & MC68060.MMU_DESCRIPTOR_SUPERVISOR_PROTECTED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [スーパーバイザ]" : " [Supervisor]");
}
if ((f0 & MC68060.MMU_DESCRIPTOR_MODIFIED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [修正済み]" : " [Modified]");
}
if ((f0 & MC68060.MMU_DESCRIPTOR_USED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [使用済み]" : " [Used]");
}
if ((f0 & MC68060.MMU_DESCRIPTOR_WRITE_PROTECTED) != 0) {
sb.append (Multilingual.mlnJapanese ? " [書き込み禁止]" : " [Write-protected]");
}
sb.append ('\n');
}
atwTextArea[m].setText (sb.toString ());
atwTextArea[m].setCaretPosition (0);
}
} //atwUpdate()
} //class LogicalSpaceMonitor