SystemCall Plugins - ParkerTenBroeck/MIPS GitHub Wiki
All that is needed to write a plugin is the jar itself simply add the MIPS.jar as a library and include the necessary classes
a basic example for a plugin that emulates a clock with only four SystemCalls would look like this
NOTE: each system call should only be registered once and never changed. An error will be thrown if the same SystemCall is registered more than once
NOTE: registering any GUI listeners (internal examples, general listeners or frame listeners) can be done although will not be shown until another plugin is loaded or unloaded. Due to this it is strongly recommended that registering GUI listeners is not done outside of the constructor or onLoad()
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.parker.mips.plugin.syscall.SystemCallPlugin;
public class ExampleSystemCallPlugin extends SystemCallPlugin {
ExampleFrame exampleFrame = new ExampleFrame();
public ExampleSystemCallPlugin() {
registerSystemCall(new PRSystemCall("EXAMPLE_SET_HOURS") { //make sure that the name entered here and the name in ExampleSystemCallPlugin match this is for verification
@Override
public void handleSystemCall() {
exampleFrame.opExampleFrame();
exampleFrame.setHours(getRegister(4));
}
});
registerSystemCall(new PRSystemCall("EXAMPLE_SET_MINS") {
@Override
public void handleSystemCall() {
exampleFrame.opExampleFrame();
exampleFrame.setMins(getRegister(4));
}
});
registerSystemCall(new PRSystemCall("EXAMPLE_READ_HOURS") {
@Override
public void handleSystemCall() {
exampleFrame.opExampleFrame();
setRegister(2, exampleFrame.getHours());
}
});
registerSystemCall(new PRSystemCall("EXAMPLE_READ_MINS") {
@Override
public void handleSystemCall() {
exampleFrame.opExampleFrame();
setRegister(2, exampleFrame.getMins());
}
});
//
registerInternalExamples(new Node("Root",
new Node[]{
new Node("Test 1 Folder",
new Node[]{
new Node("File 3", new ResourceActionLoader("exampleProgram1.asm")),
new Node("File 4", new ResourceActionLoader("exampleProgram2.asm"))
}),
new Node("File 1", new ResourceActionLoader("exampleProgram1.asm")),
new Node("File 2", new ResourceActionLoader("exampleProgram2.asm"))
}));
//
registerFrameListeners(new Node("Root",
new Node[]{
new Node("Clock", new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
exampleFrame.setVisible(true);
exampleFrame.requestFocus();
}
})}));
//
registerGeneralListeners(new Node("Root",
new Node[]{
new Node("Example 1", (ActionListener) (ActionEvent ae) -> {
logSystemCallPluginMessage("Example 1");
}),
new Node("Example SubFolder",
new Node[]{
new Node("Example 3", (ActionListener) (ActionEvent ae) -> {
logSystemCallPluginMessage("[Example SubFolder] Example 3");
}),
new Node("Example 4", (ActionListener) (ActionEvent ae) -> {
logSystemCallPluginMessage("[Example SubFolder] Example 4");
})}),
new Node("Example 2", (ActionListener) (ActionEvent ae) -> {
logSystemCallPluginWarning("Example 2");
})}));
}
@Override
public void onLoad() {
//this can be used for any initiation after the constructor if needed
}
@Override
public boolean onUnload() {
//nessisary code to unload the plugin
exampleFrame.dispose();
return true; //return false if there was an error
}
}
NOTE: each SYSTEM_CALL_NUMBER and SYSTEM_CALL_NAME Must be unique in the event there is a conflict ONLY the conflicting SystemCalls will not be loaded all others will all other information provided does not effect the system call in any way but is only to let the user know how the system call effects the system. if this information is wrong only the user will be confused
NOTE: all fields are required for the each SystemCall although only the Name and SYSTEM_CALL_NUMBER are used and verified. all other fields are not checked or verified and no errors or warnings will be thrown if these are incorrect. These only exist to show the user what the SystemCall modifies and uses
#required for all plugins
name: ExamplePlugin
main: examplesystemcallplugin.ExampleSystemCallPlugin
version: 1.1
#not required for all plugins
description: This is an example pluign.
author: Parker TenBroeck
authors: [Parker TenBroeck, Jim Williamson]
website: https://github.com/ParkerTenBroeck/MIPS
prefix: Example Plugin
#required for SystemCall plugins
system_calls:
EXAMPLE_SET_HOURS:
SYSTEM_CALL_NUMBER: 200
SYSTEM_CALL_DISCRIPTION: sets the hours from $4.
REGISTERS_READ_FROM: [4]
REGISTERS_WRITTEN_TO: []
PC_REG_READ_FROM: false
PC_REG_WRITTEN_TO: false
HIGH_REG_READ_FROM: false
HIGH_REG_WRITTEN_TO: false
LOW_REG_READ_FROM: false
LOW_REG_WRITTEN_TO: false
MEMORY_READ_FROM: false
MEMORY_WRITTEN_TO: false
EXAMPLE_SET_MINS:
SYSTEM_CALL_NUMBER: 201
SYSTEM_CALL_DISCRIPTION: sets the mins from $4.
REGISTERS_READ_FROM: [4]
REGISTERS_WRITTEN_TO: []
PC_REG_READ_FROM: false
PC_REG_WRITTEN_TO: false
HIGH_REG_READ_FROM: false
HIGH_REG_WRITTEN_TO: false
LOW_REG_READ_FROM: false
LOW_REG_WRITTEN_TO: false
MEMORY_READ_FROM: false
MEMORY_WRITTEN_TO: false
EXAMPLE_READ_HOURS:
SYSTEM_CALL_NUMBER: 202
SYSTEM_CALL_DISCRIPTION: reads the hours slider and places the value into $2
REGISTERS_READ_FROM: []
REGISTERS_WRITTEN_TO: [2]
PC_REG_READ_FROM: false
PC_REG_WRITTEN_TO: false
HIGH_REG_READ_FROM: false
HIGH_REG_WRITTEN_TO: false
LOW_REG_READ_FROM: false
LOW_REG_WRITTEN_TO: false
MEMORY_READ_FROM: false
MEMORY_WRITTEN_TO: false
EXAMPLE_READ_MINS:
SYSTEM_CALL_NUMBER: 203
SYSTEM_CALL_DISCRIPTION: reads the mins slider and places the value into $2
REGISTERS_READ_FROM: []
REGISTERS_WRITTEN_TO: [2]
PC_REG_READ_FROM: false
PC_REG_WRITTEN_TO: false
HIGH_REG_READ_FROM: false
HIGH_REG_WRITTEN_TO: false
LOW_REG_READ_FROM: false
LOW_REG_WRITTEN_TO: false
MEMORY_READ_FROM: false
MEMORY_WRITTEN_TO: false
import javax.swing.Timer;
import org.parker.mips.PluginHandler.SystemCallPluginHandler.SystemCallPluginFrame;
public class ExampleFrame extends SystemCallPluginFrame {
public void opExampleFrame() {
if (!isVisible()) {
setVisible(true);
}
}
public ExampleFrame() {
initComponents();
Timer timer;
timer = new Timer(1000, (ae) -> {
if (this.isShowing()) {
jRadioButton1.setSelected(!jRadioButton1.isSelected());
jRadioButton2.setSelected(jRadioButton1.isSelected());
}
});
timer.start();
}
public int getHours() {
return hoursSlider.getValue();
}
public int getMins() {
return minsSlider.getValue();
}
public void setHours(int val) {
if (val > 99) {
return;
}
this.hoursLable.setText(val + "");
}
public void setMins(int val) {
if (val > 99) {
return;
}
this.minsLable.setText(val + "");
}
private void initComponents() {
jPanel2 = new javax.swing.JPanel();
hoursSlider = new javax.swing.JSlider();
minsSlider = new javax.swing.JSlider();
jPanel1 = new javax.swing.JPanel();
jRadioButton2 = new javax.swing.JRadioButton();
jRadioButton1 = new javax.swing.JRadioButton();
hoursLable = new javax.swing.JLabel();
minsLable = new javax.swing.JLabel();
setAlwaysOnTop(true);
hoursSlider.setMajorTickSpacing(1);
hoursSlider.setMaximum(12);
hoursSlider.setPaintLabels(true);
hoursSlider.setPaintTicks(true);
hoursSlider.setSnapToTicks(true);
minsSlider.setMajorTickSpacing(5);
minsSlider.setMaximum(60);
minsSlider.setPaintLabels(true);
minsSlider.setPaintTicks(true);
jRadioButton2.setEnabled(false);
jRadioButton1.setEnabled(false);
jRadioButton1.setFocusable(false);
jRadioButton1.setName(""); // NOI18N
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jRadioButton2, javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jRadioButton1, javax.swing.GroupLayout.Alignment.TRAILING)))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addGap(41, 41, 41)
.addComponent(jRadioButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jRadioButton2)
.addGap(41, 41, 41))
);
hoursLable.setFont(new java.awt.Font("Arial", 0, 150)); // NOI18N
hoursLable.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
hoursLable.setText("10");
minsLable.setFont(new java.awt.Font("Arial", 0, 150)); // NOI18N
minsLable.setText("10");
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(hoursSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(minsSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(hoursLable, javax.swing.GroupLayout.DEFAULT_SIZE, 213, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(minsLable, javax.swing.GroupLayout.PREFERRED_SIZE, 213, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(hoursLable, javax.swing.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE)
.addComponent(minsLable, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(hoursSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(minsSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
}
private javax.swing.JLabel hoursLable;
private javax.swing.JSlider hoursSlider;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JRadioButton jRadioButton1;
private javax.swing.JRadioButton jRadioButton2;
private javax.swing.JLabel minsLable;
private javax.swing.JSlider minsSlider;
}