/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp 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 for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.Debugger;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import jpcsp.Emulator;
import jpcsp.Allegrex.CpuState;
public class StepLogger {
private static int size = 0;
private static int position = 0;
private static final int capacity = 64;
private static StepFrame[] frames;
private static String name;
private static int status = Emulator.EMU_STATUS_UNKNOWN;
static {
frames = new StepFrame[capacity];
for (int i = 0; i < capacity; i++) {
frames[i] = new StepFrame();
}
}
public static void append(CpuState cpu) {
frames[position].make(cpu);
if (size < capacity) {
size++;
}
position = (position + 1) % capacity;
}
public static void clear() {
size = 0;
position = 0;
}
private static String statusToStringLocalized(int status) {
return statusToString(status, true);
}
private static String statusToString(int status, boolean localize) {
java.util.ResourceBundle bundle;
if (localize) {
bundle = java.util.ResourceBundle.getBundle("jpcsp/languages/jpcsp");
} else {
bundle = java.util.ResourceBundle.getBundle("jpcsp/languages/jpcsp", new Locale("en"));
}
switch (status) {
case Emulator.EMU_STATUS_OK:
return bundle.getString("StepLogger.strStatusOk.text");
case Emulator.EMU_STATUS_UNKNOWN:
return bundle.getString("StepLogger.strStatusUnknown.text");
case Emulator.EMU_STATUS_WDT_IDLE:
return bundle.getString("StepLogger.strStatusWDTIdle.text");
case Emulator.EMU_STATUS_WDT_HOG:
return bundle.getString("StepLogger.strStatusWDTHog.text");
case Emulator.EMU_STATUS_MEM_READ:
return bundle.getString("StepLogger.strStatusMemRead.text");
case Emulator.EMU_STATUS_MEM_WRITE:
return bundle.getString("StepLogger.strStatusMemWrite.text");
case Emulator.EMU_STATUS_BREAKPOINT:
return bundle.getString("StepLogger.strStatusBreakpoint.text");
case Emulator.EMU_STATUS_UNIMPLEMENTED:
return bundle.getString("StepLogger.strStatusUnimplemented.text");
case Emulator.EMU_STATUS_PAUSE:
return bundle.getString("StepLogger.strStatusPause.text");
case Emulator.EMU_STATUS_JUMPSELF:
return bundle.getString("StepLogger.strStatusJumpSelf.text");
default:
return bundle.getString("StepLogger.strStatusUnknown.text")
+ String.format(" code:0x%08x", status);
}
}
public static void flush() {
if (status == Emulator.EMU_STATUS_OK) {
clear();
status = Emulator.EMU_STATUS_UNKNOWN;
return;
}
try {
FileWriter fw = new FileWriter("step-trace.txt");
PrintWriter out = new PrintWriter(fw);
int i;
int flushPosition = (position - size + capacity) % capacity;
out.println(name);
out.println("Instruction Trace Dump - " + statusToString(status, false));
out.println();
// Don't bother printing on wdt hog, the log gets thrashed
if (status != Emulator.EMU_STATUS_WDT_HOG) {
int localDepth = 5;
out.println("Local depth: " + localDepth);
out.println();
for (i = 0; i < size; i++) {
out.println(frames[flushPosition].getMessage());
out.println();
if (frames[flushPosition].isJAL()) {
localDepth++;
out.println("Local depth: " + localDepth);
out.println();
} else if (frames[flushPosition].isJRRA()) {
localDepth--;
out.println("Local depth: " + localDepth);
out.println();
}
flushPosition = (flushPosition + 1) % capacity;
}
} else {
out.println("Detailed log unavailable.");
}
out.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
clear();
status = Emulator.EMU_STATUS_UNKNOWN;
}
public static void setName(String name) {
StepLogger.name = name;
}
public static void setStatus(int status) {
StepLogger.status = status;
}
public static String getStatusString() {
return statusToStringLocalized(StepLogger.status);
}
}