Source code of MARS Assembler
First commit of the 4.5 version (latest version available)
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
package mars.tools;
|
||||
import mars.*;
|
||||
import mars.mips.hardware.*;
|
||||
import mars.venus.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
/**
|
||||
* Simple Demo of Mars tool capability
|
||||
*/
|
||||
|
||||
public class MarsBot implements Observer, MarsTool
|
||||
{
|
||||
private static final int GRAPHIC_WIDTH = 512;
|
||||
private static final int GRAPHIC_HEIGHT = 512;
|
||||
private static final int ADDR_HEADING = 0xffff8010;
|
||||
private static final int ADDR_LEAVETRACK = 0xffff8020;
|
||||
private static final int ADDR_WHEREAREWEX = 0xffff8030;
|
||||
private static final int ADDR_WHEREAREWEY = 0xffff8040;
|
||||
private static final int ADDR_MOVE = 0xffff8050;
|
||||
private MarsBotDisplay graphicArea;
|
||||
private int MarsBotHeading = 0; // 0 --> North (up), 90 --> East (right), etc.
|
||||
private boolean MarsBotLeaveTrack = false; // true --> leave track when moving, false --> do not ...
|
||||
private double MarsBotXPosition = 0; // X pixel position of MarsBot
|
||||
private double MarsBotYPosition = 0; // Y pixel position of MarsBot
|
||||
private boolean MarsBotMoving = false; // true --> MarsBot is moving, false --> MarsBot not moving
|
||||
|
||||
// The begin and end points of a "track" segment are kept in neighboring pairs
|
||||
// of elements of the array. arrayOfTrack[i] is the start pt, arrayOfTrack[i+1] is
|
||||
// the end point of a path that should leave a track.
|
||||
private final int trackPts = 256; // TBD Hardcoded. Array contains start-end points for segments in track.
|
||||
private Point[] arrayOfTrack = new Point[trackPts];
|
||||
private int trackIndex = 0;
|
||||
|
||||
// private inner class
|
||||
private class BotRunnable implements Runnable
|
||||
{
|
||||
JPanel panel;
|
||||
public BotRunnable() // constructor
|
||||
{
|
||||
final JFrame frame = new JFrame("Bot");
|
||||
panel = new JPanel(new BorderLayout());
|
||||
graphicArea = new MarsBotDisplay(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
|
||||
JPanel buttonPanel = new JPanel();
|
||||
JButton clearButton = new JButton("Clear");
|
||||
clearButton.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
graphicArea.clear();
|
||||
MarsBotLeaveTrack = false; // true --> leave track when moving, false --> do not ...
|
||||
MarsBotXPosition = 0; // X pixel position of MarsBot
|
||||
MarsBotYPosition = 0; // Y pixel position of MarsBot
|
||||
MarsBotMoving = false; // true --> MarsBot is moving, false --> MarsBot not moving
|
||||
|
||||
trackIndex = 0;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
buttonPanel.add(clearButton);
|
||||
JButton closeButton = new JButton("Close");
|
||||
closeButton.addActionListener(
|
||||
new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
frame.setVisible(false);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
buttonPanel.add(closeButton);
|
||||
panel.add(graphicArea, BorderLayout.CENTER);
|
||||
panel.add(buttonPanel, BorderLayout.SOUTH);
|
||||
frame.getContentPane().add(panel);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
frame.setTitle(" This is the MarsBot");
|
||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // changed 12/12/09 DPS (was EXIT)
|
||||
frame.setSize(GRAPHIC_WIDTH + 200, GRAPHIC_HEIGHT + 100); // TBD SIZE
|
||||
frame.setVisible(true); // show();
|
||||
|
||||
} // end BotRunnable() constructor
|
||||
|
||||
public void run()
|
||||
{
|
||||
|
||||
double tempAngle;
|
||||
// infinite loop: move the bot according to the current directives
|
||||
// (which may be to NOT move)
|
||||
do
|
||||
{
|
||||
if (MarsBotMoving)
|
||||
{
|
||||
//System.out.println("BotRunnable.run: bot IS moving.");
|
||||
// TBD This is an arbitrary distance for bot movement. This could just
|
||||
// as easily be a random distance to simulate terrain, etc.
|
||||
// adjust bot position.
|
||||
// The "mathematical angle" is zero at east, 90 at north, etc.
|
||||
// The "heading" is 0 at north, 90 at east, etc.
|
||||
// Conversion: MathAngle = [(360 - heading) + 90] mod 360
|
||||
tempAngle = ((360 - MarsBotHeading) + 90) % 360;
|
||||
MarsBotXPosition += Math.cos(Math.toRadians(tempAngle)); // Math.cos parameter unit is radians
|
||||
MarsBotYPosition += -Math.sin(Math.toRadians(tempAngle)); // Negate value because Y coord grows down
|
||||
|
||||
// Write this new information to MARS memory area
|
||||
try
|
||||
{
|
||||
Globals.memory.setWord(ADDR_WHEREAREWEX, (int) MarsBotXPosition);
|
||||
Globals.memory.setWord(ADDR_WHEREAREWEY, (int) MarsBotYPosition);
|
||||
|
||||
}
|
||||
catch ( AddressErrorException e)
|
||||
{
|
||||
// TBD TBD TBD No action
|
||||
}
|
||||
|
||||
//System.out.println(" ------- Heading is " + MarsBotHeading + ", angle is " + tempAngle);
|
||||
//System.out.println(" ------- New X,Y is (" + MarsBotXPosition + "," + MarsBotYPosition + ")" );
|
||||
|
||||
// Whether or not we're leaving a track, write the current point to the
|
||||
// current position in the array.
|
||||
// -- If we are not leaving a track now, we will need the current point to
|
||||
// start a future track, and that goes into the array.
|
||||
// -- If we are leaving a track now, the current point may end the track,
|
||||
// and that goes into the array.
|
||||
arrayOfTrack[trackIndex] = new Point((int)MarsBotXPosition, (int)MarsBotYPosition);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Action for if the MarsBot isn't moving
|
||||
// System.out.println("BotRunnable.run: bot is not moving.");
|
||||
}
|
||||
|
||||
// TBD Pause whether the bot is or is not moving. This gives the MIPS program
|
||||
// opportunity to consider results of movement, or to make the bot move.
|
||||
// ??? What is relationship of robot speed to MARS's
|
||||
// execution time for a single instruction? Does the robot speed have to
|
||||
// be slow enough to allow a MARS busy loop to detect the bot position
|
||||
// at a specific pixel?
|
||||
try
|
||||
{
|
||||
//System.out.println(" Hello from the bot runner");
|
||||
Thread.sleep(40);
|
||||
}
|
||||
catch (InterruptedException exception)
|
||||
{// no action
|
||||
}
|
||||
|
||||
panel.repaint(); // show new bot position
|
||||
} while (true);
|
||||
|
||||
} // end run method of BotRunnable class
|
||||
|
||||
} // end BotRunnable class
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
private class MarsBotDisplay extends JPanel
|
||||
{
|
||||
private int width;
|
||||
private int height;
|
||||
private boolean clearTheDisplay = true;
|
||||
|
||||
|
||||
public MarsBotDisplay(int tw, int th)
|
||||
{
|
||||
width = tw;
|
||||
height = th;
|
||||
|
||||
}
|
||||
|
||||
public void redraw()
|
||||
{
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
// clear the graphic display
|
||||
clearTheDisplay = true;
|
||||
//System.out.println("MarsBotDisplay.clear: called to clear the display");
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g)
|
||||
{
|
||||
long tempN;
|
||||
// System.out.println("MarsBotDisplay.paintComponent: I'm painting! n is " + n);
|
||||
|
||||
|
||||
// Recover Graphics2D
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
|
||||
/*
|
||||
if (clearTheDisplay)
|
||||
{
|
||||
g2.setColor(Color.lightGray);
|
||||
g2.fillRect(0, 0, width - 1, height - 1); // Clear all previous drawn information
|
||||
clearTheDisplay = false;
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw the track left behind, for each segment of the path
|
||||
g2.setColor(Color.blue);
|
||||
for (int i = 1; i <= trackIndex; i += 2) // Index grows by two (begin-end pair)
|
||||
{
|
||||
//System.out.print(".");
|
||||
try
|
||||
{
|
||||
g2.drawLine((int)arrayOfTrack[i-1].getX(), (int)arrayOfTrack[i-1].getY(),
|
||||
(int)arrayOfTrack[i].getX(), (int)arrayOfTrack[i].getY() );
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
// No action TBD sloppy
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
// No action TBD sloppy
|
||||
}
|
||||
}
|
||||
|
||||
g2.setColor(Color.black);
|
||||
g2.fillRect((int) MarsBotXPosition, (int) MarsBotYPosition, 20, 20); // Draw bot at its current position
|
||||
|
||||
/*
|
||||
g2.setColor(Color.blue);
|
||||
g2.setFont(new Font(g2.getFont().getName(), g2.getFont().getStyle(), 20) ); // same font and style in larger size
|
||||
g2.drawOval( width/2 - 30, // TBD Hardcoded oval size
|
||||
height/2 - 30,
|
||||
60,
|
||||
60);
|
||||
g2.drawString(" " + n, width/2, height/2);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
} // end private inner class MarsBotDisplay
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return "Mars Bot";
|
||||
}
|
||||
|
||||
/*
|
||||
* This will set up the Bot's GUI. Invoked when Bot menu item selected.
|
||||
*/
|
||||
public void action()
|
||||
{
|
||||
BotRunnable br1 = new BotRunnable();
|
||||
Thread t1 = new Thread(br1);
|
||||
t1.start();
|
||||
// New: DPS 27 Feb 2006. Register observer for memory subrange.
|
||||
try {
|
||||
Globals.memory.addObserver(this,0xffff8000,0xffff8060);
|
||||
}
|
||||
catch (AddressErrorException aee) {
|
||||
System.out.println(aee);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This method observes MIPS program directives to modify Bot activity (that is,
|
||||
* MIPS program write to MMIO) and updates instance variables to reflect that
|
||||
* directive.
|
||||
*/
|
||||
public void update(Observable o, Object arg)
|
||||
{
|
||||
MemoryAccessNotice notice;
|
||||
int address;
|
||||
if (arg instanceof MemoryAccessNotice)
|
||||
{
|
||||
notice = (MemoryAccessNotice) arg;
|
||||
address = notice.getAddress();
|
||||
if (address < 0 && notice.getAccessType() == AccessNotice.WRITE)
|
||||
{
|
||||
String message = "";
|
||||
if (address == ADDR_HEADING)
|
||||
{
|
||||
message = "MarsBot.update: got move heading value: ";
|
||||
MarsBotHeading = notice.getValue();
|
||||
//System.out.println(message + notice.getValue() );
|
||||
}
|
||||
else if (address == ADDR_LEAVETRACK)
|
||||
{
|
||||
message = "MarsBot.update: got leave track directive value ";
|
||||
|
||||
// If we HAD NOT been leaving a track, but we should NOW leave
|
||||
// a track, put start point into array.
|
||||
if (MarsBotLeaveTrack == false && notice.getValue() == 1)
|
||||
{
|
||||
MarsBotLeaveTrack = true;
|
||||
arrayOfTrack[trackIndex] = new Point((int) MarsBotXPosition, (int) MarsBotYPosition);
|
||||
trackIndex++; // the index of the end point
|
||||
}
|
||||
// If we HAD NOT been leaving a track, and get another directive
|
||||
// to NOT leave a track, do nothing (nothing to do).
|
||||
else if (MarsBotLeaveTrack == false && notice.getValue() == 0)
|
||||
{
|
||||
// NO ACTION
|
||||
}
|
||||
// If we HAD been leaving a track, and get another directive
|
||||
// to LEAVE a track, do nothing (nothing to do).
|
||||
else if (MarsBotLeaveTrack == true && notice.getValue() == 1)
|
||||
{
|
||||
// NO ACTION
|
||||
}
|
||||
// If we HAD been leaving a track, and get another directive
|
||||
// to NOT leave a track, put end point into array.
|
||||
else if (MarsBotLeaveTrack == true && notice.getValue() == 0)
|
||||
{
|
||||
MarsBotLeaveTrack = false;
|
||||
arrayOfTrack[trackIndex] = new Point((int) MarsBotXPosition, (int) MarsBotYPosition);
|
||||
trackIndex++; // the index of the next start point
|
||||
}
|
||||
|
||||
//System.out.println("MarsBotDisplay.paintComponent: putting point in track array at " + trackIndex);
|
||||
|
||||
//System.out.println(message + notice.getValue() );
|
||||
}
|
||||
else if (address == ADDR_MOVE)
|
||||
{
|
||||
message = "MarsBot.update: got move control value: ";
|
||||
if (notice.getValue() == 0) MarsBotMoving = false;
|
||||
else MarsBotMoving = true;
|
||||
//System.out.println(message + notice.getValue() );
|
||||
}
|
||||
else if (address == ADDR_WHEREAREWEX ||
|
||||
address == ADDR_WHEREAREWEY)
|
||||
{
|
||||
// Ignore these memory writes, because the writes originated within
|
||||
// this tool. This tool is being notified of the writes in the usual
|
||||
// manner, but the writes are already known to this tool.
|
||||
// NO ACTION
|
||||
}
|
||||
else
|
||||
{
|
||||
//message = "MarsBot.update: HEY!!! unknown address of " + Integer.toString(address) + ", value: ";
|
||||
//System.out.println(message + notice.getValue() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user