-led0: obits.jar
- java -Djava.library.path=/usr/lib \
- -cp /usr/share/java/RXTXcomm.jar:obits.jar \
- edu.berkeley.obits.AtmelSerial < bitstreams/led0.md4
+java = java -Djava.library.path=$(shell pwd)/lib/ -cp lib/RXTXcomm.jar:obits.jar
+
+led0: obits.jar
+ $(java) edu.berkeley.obits.AtmelSerial < bitstreams/led0.md4
led1: obits.jar
- java -Djava.library.path=/usr/lib \
- -cp /usr/share/java/RXTXcomm.jar:obits.jar \
- edu.berkeley.obits.AtmelSerial < bitstreams/led1.md4
+ $(java) edu.berkeley.obits.AtmelSerial < bitstreams/led1.md4
run: obits.jar
- java -Djava.library.path=/usr/lib \
- -cp /usr/share/java/RXTXcomm.jar:obits.jar \
- edu.berkeley.obits.AtmelSerial
+ $(java) edu.berkeley.obits.AtmelSerial < stupid.md4
obits.jar: $(shell find src -name \*.java)
- javac -cp /usr/share/java/RXTXcomm.jar -d build $(shell find src -name \*.java)
+ javac -cp lib/RXTXcomm.jar -d build $(shell find src -name \*.java)
cd build; jar cvf ../$@ .
# -O3 is required; otherwise the poor AVR can't keep up with us!
import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
import edu.berkeley.obits.device.atmel.*;
+import edu.berkeley.obits.gui.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.color.*;
c.h(L2, true);
-
// catch a rising transition
/*
c = c.west();
c.hwire(L2).west().drives(c.hwire(L2), false);
c.hwire(L2).east().drives(c.hwire(L2), false);
+
+
+ //////
+
+ c = at40k.cell(20,20);
+ c.yi(WEST);
+ c.ylut(LUT_SELF);
+ c.c(YLUT);
+ c.oe(H4);
+ c.h(L4, true);
+ c.b(false);
+ c.f(false);
+ c.out(L4);
+
+ c = at40k.cell(21,20);
+ c.c(YLUT);
+ c.oe(NONE);
+ c.h(L4, true);
+ c.b(false);
+ c.f(false);
+
+
+ c = at40k.cell(8,8);
+ c.f(true);
+ c.b(true);
+ c.xo(true);
+ c.xi(NE);
+ c.zi(L3);
+ c.wi(L0);
+ c.yi(NORTH);
+ c.oe(H4);
+ c.h(L0, true);
+ c.h(L2, true);
+ c.h(L4, true);
+ c.v(L1, true);
+ c.v(L3, true);
+ c.out(L0, true);
+ c.out(L1, true);
+ c.out(L2, true);
+ c.out(L3, true);
+ c.out(L4, true);
+ c.c(ZMUX);
+
//for(int x=5; x<PIPELEN; x++) {
//at40k.cell(x,23).hwire(L0).drives(at40k.cell(x,23).hwire(L0).east());
//}
//device.scanFPGA(true);
- Visual vis = new Visual(at40k);
- vis.show();
- vis.setSize(600, 600);
+ at40k.cell(10,10).f(true);
+ at40k.cell(10,10).c(ZMUX);
+
+ at40k.cell(8,7).xlut(LUT_SELF);
+ at40k.cell(8,7).xi(NW);
+
+ at40k.cell(7,8).xlut(LUT_SELF & LUT_Z);
+ at40k.cell(7,8).xi(SE);
+ at40k.cell(7,8).c(XLUT);
+ at40k.cell(7,8).f(false);
+ at40k.cell(7,8).b(false);
+ at40k.cell(7,8).t(TMUX_FB);
+ at40k.cell(7,8).xo(false);
+ System.out.println(at40k.cell(7,8).fb_relevant());
+
+ at40k.cell(6,13).xi(SE);
+ at40k.cell(6,13).c(ZMUX);
+ at40k.cell(6,13).xlut(LUT_SELF);
+ at40k.cell(6,13).ylut(LUT_OTHER);
+ at40k.cell(6,13).xo(false);
+ at40k.cell(6,13).yo(false);
+ at40k.cell(7,12).xi(SE);
+
+ Gui vis = new Gui(at40k);
+ Frame fr = new Frame();
+ fr.setLayout(new BorderLayout());
+ fr.add(vis, BorderLayout.CENTER);
+ fr.pack();
+ fr.show();
+ fr.setSize(600, 600);
+ fr.addKeyListener(vis);
synchronized(AtmelSerial.class) { AtmelSerial.class.wait(); }
+
Visualizer v = new Visualizer(at40k, device);
v.show();
v.setSize(1380, 1080);
}
private static String pad(int i, String s) { if (s.length()>i) return s; return "0"+pad((i-1),s); }
- private static String bin8(byte b) {
+ public static String bin8(byte b) {
int n = b & 0xff;
String ret = "";
for(int i=7; i>=0; i--)
+++ /dev/null
-package edu.berkeley.obits;
-
-import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
-import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
-import edu.berkeley.obits.device.atmel.*;
-import java.awt.*;
-import java.awt.geom.*;
-import java.awt.event.*;
-import java.awt.color.*;
-import org.ibex.util.*;
-import java.io.*;
-import java.util.*;
-import javax.swing.*;
-
-public class Visual extends JFrame implements KeyListener {
-
- public static int SIZE = 92;
- public static int RINGS = 3;
- public static int BEVEL = 5;
- public static int CORE_SIZE = 64;
- public static int CORE_OFFSET = 10;
-
- public static int HOFF = 52;
-
- /*
- public static void main(String[] s) {
- Visual v = new Visual();
- v.show();
- v.setSize(400, 400);
- }
- */
-
- At40k at40k;
-
- public Visual(At40k at40k) {
- this.at40k = at40k;
- for(int x=0; x<7; x++)
- for(int y=0; y<7; y++)
- new Cell(x,y, at40k.cell(x+7, y+7));
- addKeyListener(this);
- }
-
- private HashSet<Cell> cells = new HashSet<Cell>();
-
- public class Cell {
- Graphics2D g;
- At40k.Cell cell;
- int _x, _y;
- public Cell(int x, int y, At40k.Cell cell) {
- _x = x;
- _y = y;
- this.cell = cell;
- cells.add(this);
- }
- public void draw() {
- drawHwires();
- drawVwires();
- drawInternalRouting();
- drawLocal();
- drawGates();
- drawMux();
- drawRegister();
- drawBorder();
- }
- public void drawHwires() {
- g.setColor(Color.magenta);
- for(int i=0; i<5; i++)
- if (cell.hwire(i).isDriven())
- g.drawLine(0, SIZE-(2*(1+RINGS)+2*i), SIZE, SIZE-(2*(1+RINGS)+2*i));
- }
- public void drawVwires() {
- g.setColor(Color.magenta);
- for(int i=0; i<5; i++)
- if (cell.vwire(i).isDriven())
- g.drawLine(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE);
- }
- public void drawInternalRouting() {
- }
-
- public void drawLocal() {
- if (!cell.ylut_relevant() && !cell.ylut_relevant()) return;
- Point2D in = new Point2D.Double(HOFF, 0);
- Point2D join = new Point2D.Double(HOFF, CORE_OFFSET);
- rotateOuter(in);
- rotateInner(join);
- int rot = rot();
- switch(rot) {
- case 0: case 2:
- join.setLocation(in.getX(), join.getY());
- break;
- case 1: case 3:
- join.setLocation(join.getX(), in.getY());
- break;
- }
-
- Point2D xi = null;
- g.setColor(new Color(0xff, 0x00, 0x00));
- int xring = 4;
- switch(cell.xi()) {
- case NW:
- xi = new Point2D.Double(0+2*xring, SIZE-2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(0, SIZE), xi));
- break;
-
- case SW:
- xi = new Point2D.Double(0+2*xring, 0+2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(0, 0), xi));
- break;
-
- case NE:
- xi = new Point2D.Double(SIZE-2*xring, SIZE-2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(SIZE, SIZE), xi));
- break;
-
- case SE:
- xi = new Point2D.Double(SIZE-2*xring, 0+2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(SIZE, 0), xi));
- break;
-
- }
-
- if (cell.xlut_relevant()) {
- g.setColor(new Color(0x00, 0x00, 0xff));
- Point2D c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20);
- rotateInner(c);
- route(in, c, 5);
-
- g.setColor(new Color(0xff, 0x00, 0x00));
- c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20);
- rotateInner(c);
- if (xi != null)
- route(xi, c, 4);
-
- Point2D xo = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + 41 - 3);
- Point2D xout = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3);
- rotateInner(xo);
- rotateInner(xout);
- g.setColor(new Color(0xff, 0xcc, 0xcc));
- g.draw(new Line2D.Double(xo, xout));
- if (cell.ne() != null && cell.ne().xi()==SW) {
- Point2D xoo = new Point2D.Double(SIZE-2*xring, SIZE-2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(SIZE, SIZE), xoo));
- route(xout, xoo, xring);
- }
- if (cell.nw() != null && cell.nw().xi()==SE) {
- Point2D xoo = new Point2D.Double(0+2*xring, SIZE-2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(0, SIZE), xoo));
- route(xout, xoo, xring);
- }
- if (cell.se() != null && cell.se().xi()==NW) {
- Point2D xoo = new Point2D.Double(SIZE-2*xring, 0+2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(SIZE, 0), xoo));
- route(xout, xoo, xring);
- }
- if (cell.sw() != null && cell.sw().xi()==NE) {
- Point2D xoo = new Point2D.Double(0+2*xring, 0+2*xring);
- g.draw(new Line2D.Double(new Point2D.Double(0, 0), xoo));
- route(xout, xoo, xring);
- }
- }
-
- if (cell.ylut_relevant()) {
- g.setColor(new Color(0x00, 0x00, 0xff));
- Point2D c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20);
- rotateInner(c);
- route(in, c, 5);
-
- g.setColor(new Color(0xff, 0x00, 0x00));
- c = new Point2D.Double(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20);
- rotateInner(c);
- if (xi != null)
- route(xi, c, 4);
-
- Point2D yo = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + 41 - 3);
- Point2D yout = new Point2D.Double(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3);
- rotateInner(yo);
- rotateInner(yout);
- g.setColor(new Color(0xbb, 0xbb, 0xff));
- //g.setColor(new Color(0x00, 0x00, 0xff));
- g.draw(new Line2D.Double(yo, yout));
- if (cell.north() != null && cell.north().yi()==SOUTH) route(yout, new Point2D.Double(SIZE-40, SIZE+ 0), 2);
- if (cell.east() != null && cell.east().yi()==WEST) route(yout, new Point2D.Double(SIZE+ 0, 40), 2);
- if (cell.south() != null && cell.south().yi()==NORTH) route(yout, new Point2D.Double( 40, 0), 2);
- if (cell.west() != null && cell.west().yi()==EAST) route(yout, new Point2D.Double( 0, SIZE-40), 2);
- }
-
- }
-
- private void rotateOuter(Point2D p) {
- int rot = rot();
- AffineTransform a = new AffineTransform();
- a.rotate((Math.PI/2) * rot);
- switch(rot) {
- case 0: break;
- case 1: a.translate(0, -SIZE); break;
- case 2: a.translate(-SIZE, -SIZE); break;
- case 3: a.translate(-SIZE, 0); break;
- }
- a.transform(p, p);
- }
-
- private void rotateInner(Point2D p) {
- int rot = rot();
- AffineTransform a = new AffineTransform();
- a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
- a.rotate((Math.PI/2) * rot);
- switch(rot) {
- case 0: break;
- case 1: a.translate(0, -CORE_SIZE); break;
- case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break;
- case 3: a.translate(-CORE_SIZE, 0); break;
- }
- a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET);
- a.transform(p, p);
- }
-
- private Point2D project(Point2D p1, int ring) {
- double north = Math.abs( (SIZE-(ring*2)) - p1.getY() );
- double south = Math.abs( ( (ring*2)) - p1.getY() );
- double east = Math.abs( (SIZE-(ring*2)) - p1.getX() );
- double west = Math.abs( ( (ring*2)) - p1.getX() );
- if (north < south && north < east && north < west) {
- return new Point2D.Double(p1.getX(), SIZE-ring*2);
- } else if (south < east && south < west) {
- return new Point2D.Double(p1.getX(), ring*2);
- } else if (east < west) {
- return new Point2D.Double(SIZE-ring*2, p1.getY());
- } else {
- return new Point2D.Double(ring*2, p1.getY());
- }
- }
-
- private void route(Point2D p1, Point2D p2, int ring) {
- int ringpos = ring * 2;
- Point2D projected = project(p1, ring);
- g.draw(new Line2D.Double(p1, projected));
- p1 = projected;
-
- projected = project(p2, ring);
- g.draw(new Line2D.Double(p2, projected));
- p2 = projected;
-
- double x1 = p1.getX();
- double y1 = p1.getY();
- double x2 = p2.getX();
- double y2 = p2.getY();
-
- if (x1==x2 || y1==y2) {
- g.draw(new Line2D.Double(p1, p2));
- return;
- }
-
- if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) {
- Point2D p3 = new Point2D.Double(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2);
- g.draw(new Line2D.Double(p1, p3));
- route(p3, p2, ring);
- }
-
- if (y1==SIZE-ring*2 || y1==ring*2) {
- Point2D p3 = new Point2D.Double(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1);
- g.draw(new Line2D.Double(p1, p3));
- route(p3, p2, ring);
- }
-
- }
-
- private int rot() {
- int rot = 0;
- switch(cell.yi()) {
- case SOUTH: rot = 0; break;
- case NORTH: rot = 2; break;
- case EAST: rot = 1; break;
- case WEST: rot = 3; break;
- default: {
- // FIXME: choose based on xin
- if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; }
- if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; }
- if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; }
- if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; }
- }
- }
- return rot;
- }
-
- public void drawGates() {
- AffineTransform t = g.getTransform();
- try {
- g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
-
- int rot = rot();
- g.rotate((Math.PI/2) * rot);
- switch(rot) {
- case 0: break;
- case 1: g.translate(0, -CORE_SIZE); break;
- case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break;
- case 3: g.translate(-CORE_SIZE, 0); break;
- }
-
- //g.setColor(Color.gray);
- //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE);
- g.scale(1, -1);
-
- GeneralPath p = new GeneralPath();
- p.moveTo(29.141f, 36.301f);
- p.lineTo(29.141f, 36.301f-7.161f);
- p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f);
- p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f);
- p.lineTo(0.5f, 29.141f+7.161f);
- float x = 0.5f;
- float y = 29.141f+7.161f;
- p.curveTo(5.729f+x, -1.789f+y,
- 6.444f+x, -2.686f+y,
- 14.32f+x, -3.58f+y);
- p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f);
- g.translate(0, -40f);
- if (cell.xlut_relevant()) {
- g.setColor(Color.white);
- g.fill(p);
- g.setColor(Color.red);
- g.draw(p);
- }
- g.translate(34f, 0f);
- if (cell.ylut_relevant()) {
- g.setColor(Color.white);
- g.fill(p);
- g.setColor(Color.blue);
- g.draw(p);
- }
- } finally {
- g.setTransform(t);
- }
- }
- public void drawMux() {
- if (cell.c() != ZMUX) return;
- g.setColor(Color.black);
- g.drawLine(46, 54, 46+2, 54+5);
- g.drawLine(46+2, 54+5, 60-2, 54+5);
- g.drawLine(60-2, 54+5, 60, 54);
- g.drawLine(60, 54, 46, 54);
- }
- public void drawRegister() {
- }
- public void drawBorder() {
- g.setColor(Color.gray);
- //g.drawLine(0, BEVEL, BEVEL, 0);
- g.drawLine(BEVEL, 0, SIZE-BEVEL, 0);
- //g.drawLine(SIZE-BEVEL, 0, SIZE, BEVEL);
- g.drawLine(SIZE, BEVEL, SIZE, SIZE-BEVEL);
- //g.drawLine(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE);
- g.drawLine(SIZE-BEVEL, SIZE, BEVEL, SIZE);
- //g.drawLine(BEVEL, SIZE, 0, SIZE-BEVEL);
- g.drawLine(0, SIZE-BEVEL, 0, BEVEL);
- }
- }
-
- public void paint(Graphics _g) {
- Graphics2D g = (Graphics2D)_g;
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
- g.setStroke(new BasicStroke((float)0.5));
- g.translate(10, 0);
- g.scale(1, -1);
- g.translate(5, -1 * getHeight() + 10);
- g.scale(scale,scale);
- for(Cell c : cells) {
- AffineTransform t = g.getTransform();
- g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/);
- c.g = g;
- c.draw();
- c.g = null;
- g.setTransform(t);
- }
- }
-
- double scale = 1.0;
-
- public void clear() {
- Graphics2D g = (Graphics2D)getGraphics();
- //g.setColor(Color.black);
- //g.setColor(Color.lightGray);
- g.clearRect(0, 0, getWidth(), getHeight());
- }
-
- public void keyTyped(KeyEvent k) {
- }
- public void keyReleased(KeyEvent k) {
- }
- public void keyPressed(KeyEvent keyevent) {
- char c = keyevent.getKeyChar();
- switch(c) {
- case '+': scale += 0.1; clear(); paint(getGraphics()); return;
- case '-': scale -= 0.1; clear(); paint(getGraphics()); return;
- }
- }
-
-}
case TMUX_Z: throw new Error("not implemented, but should be possible");
case TMUX_W_AND_Z: result = 0x20; break;
- case TMUX_FB: result = 0x04; break; /* I think this is actually W_AND_FB, sadly */
+ case TMUX_FB: result = 0x34; break; /* I think this is actually W_AND_FB, sadly */
case TMUX_W_AND_FB: result = 0x14; break;
case TMUX_W: result = 0x00; break;
}
dev.mode4(1, row, col, result, 0x34);
}
+ public int t() {
+ return dev.mode4(1, row, col) & 0x34;
+ }
public void t(boolean ignore_z_and_fb, boolean zm_drives_fb, boolean fb_drives_wm) {
// still not totally satisfied...
// how to we distinguish between z&w vs z or w&fb vs fb? ==> you can't! this is a false connection in my diagram
// ZM->FB = 0x04
// FB->WM = 0x10
// WZ->WM = 0x20
-
- // tff => w&z
- // fff => w
- // ttt => fb&w
- // ftt => fb&w
- // fft => fb&w
-
- // ttf => w&z
- // ftf => w
- // tft => fb&w
+
+ // tff => w&z [0x20]
+ // fff => w [0x00]
+ // ttt => fb&w [0x34]
+ // ftt => fb&w [0x14]
+ // fft => fb&w [0x10]
+
+ // ttf => w&z [0x24]
+ // ftf => w [0x04]
+ // tft => fb&w [0x30]
if (ignore_z_and_fb) result |= 0x20;
if (zm_drives_fb) result |= 0x04;
if (fb_drives_wm) result |= 0x10;
dev.mode4(1, row, col, result, 0x34);
}
- public boolean xlut_relevant() {
+ public boolean xlut_relevant() { return xlut_relevant(true); }
+ public boolean xlut_relevant(boolean recurse) {
if ((c()==XLUT || c()==ZMUX) && c_relevant()) return true;
if (xo()) return false;
- if (nw() != null && nw().xi()==SE) return true;
- if (ne() != null && ne().xi()==SW) return true;
- if (sw() != null && sw().xi()==NE) return true;
- if (se() != null && se().xi()==NW) return true;
+ if (nw() != null && nw().xi()==SE && nw().xi_relevant() && (recurse || nw().xlut_relevant())) return true;
+ if (ne() != null && ne().xi()==SW && ne().xi_relevant() && (recurse || ne().xlut_relevant())) return true;
+ if (sw() != null && sw().xi()==NE && sw().xi_relevant() && (recurse || sw().xlut_relevant())) return true;
+ if (se() != null && se().xi()==NW && se().xi_relevant() && (recurse || se().xlut_relevant())) return true;
return false;
}
+ public boolean xi_to_ylut_relevant() {
+ int lut = ylut();
+ if (((lut & 0xcc) >> 2) == (lut & 0x33)) return false;
+ return true;
+ }
+ public boolean yi_to_xlut_relevant() {
+ int lut = xlut();
+ if (((lut & 0xcc) >> 2) == (lut & 0x33)) return false;
+ return true;
+ }
+ public boolean xi_relevant() { return xi_to_xlut_relevant() || xi_to_ylut_relevant(); }
+ public boolean yi_relevant() { return yi_to_xlut_relevant() || yi_to_ylut_relevant(); }
+ public boolean zi_to_xlut_relevant() {
+ int lut = xlut();
+ if (((lut & LUT_Z) >> 4) == (lut & LUT_Z)) return false;
+ return true;
+ }
+ public boolean zi_to_ylut_relevant() {
+ int lut = ylut();
+ if (((lut & LUT_Z) >> 4) == (lut & LUT_Z)) return false;
+ return true;
+ }
+ public boolean xi_to_xlut_relevant() {
+ int lut = xlut();
+ if (((lut & LUT_SELF) >> 1) == (lut & (LUT_SELF >> 1))) return false;
+ return true;
+ }
+ public boolean yi_to_ylut_relevant() {
+ int lut = ylut();
+ if (((lut & LUT_SELF) >> 1) == (lut & (LUT_SELF >> 1))) return false;
+ return true;
+ }
public boolean ylut_relevant() {
if ((c()==YLUT || c()==ZMUX) && c_relevant()) return true;
if (yo()) return false;
return false;
}
+ public boolean register_relevant() {
+ if (!c_relevant() && !fb_relevant()) return false;
+ if (f() && out_relevant()) return true;
+ if (f() && fb_relevant()) return true;
+ if (b() && xo()) return true;
+ if (b() && yo()) return true;
+ return false;
+ }
+ public boolean out_relevant() {
+ boolean out = false;
+ boolean connect = false;
+ for(int i=0; i<4; i++) {
+ if (out(L0+i)) out = true;
+ if (hx(L0+i)) connect = true;
+ if (vx(L0+i)) connect = true;
+ }
+ return out && connect;
+ }
+ public boolean fb_relevant() {
+ //if (!c_relevant()) return false;
+ if (!(zi_to_xlut_relevant() && xlut_relevant()) ||
+ !(zi_to_ylut_relevant() && ylut_relevant())) return false;
+ switch(t()) {
+ case 0x34: return true;
+ case 0x14: return true;
+ case 0x10: return true;
+ case 0x30: return true;
+ }
+ return false;
+ }
+
public void c(int source) {
switch(source) {
case XLUT: dev.mode4(1, row, col, 0x00, 0xc0); break;
}
}
public int c() {
- switch (dev.mode4(1, row, col) >> 6) {
+ int cval = dev.mode4(1, row, col) & 0xc0;
+ switch (cval) {
case 0x00: return XLUT;
- case 0x01: return YLUT;
- case 0x02: return ZMUX;
+ case 0x40: return YLUT;
+ case 0x80: return ZMUX;
}
- throw new Error();
+ throw new Error("c() => " + cval);
}
public void b(boolean registered) { dev.mode4(1, row, col, 3, !registered); }
public void f(boolean registered) { dev.mode4(1, row, col, 2, !registered); }
public boolean yo() { return (dev.mode4(1, row, col) & 0x02) != 0; }
public void xo(boolean center) { dev.mode4(1, row, col, 1, center); }
public void yo(boolean center) { dev.mode4(1, row, col, 0, center); }
- public boolean b() { return (dev.mode4(1, row, col) >> 3)!=1; }
- public boolean f() { return (dev.mode4(1, row, col) >> 2)!=1; }
- public boolean x() { return (dev.mode4(1, row, col) >> 1)==1; }
- public boolean y() { return (dev.mode4(1, row, col) >> 0)==1; }
+ public boolean b() { return (dev.mode4(1, row, col) & (1 << 3)) == 0; }
+ public boolean f() { return (dev.mode4(1, row, col) & (1 << 2)) == 0; }
+ public boolean x() { return (dev.mode4(1, row, col) & (1 << 1)) != 0; }
+ public boolean y() { return (dev.mode4(1, row, col) & (1 << 0)) != 0; }
public int oe() {
switch (dev.mode4(0x02, row, col) & 0x3) {
}
public int wi() {
- int who = dev.mode4(0x03, row, col) & 0xff;
+ int who = dev.mode4(0x03, row, col) & 0xEC;
switch(who) {
case (1<<5): return L4;
case (1<<6): return L3;
case (1<<7): return L2;
case (1<<3): return L1;
case (1<<2): return L0;
+ case (1<<0): return NONE; /* huh? */
case (0): return NONE;
default: throw new RuntimeException("invalid argument: " + who);
}
}
public int zi() {
- switch(dev.mode4(0x02, row, col) & 0xff) {
+ switch(dev.mode4(0x02, row, col) & 0xDB) {
case (1<<7): return L4;
case (1<<5): return L3;
case (1<<4): return L2;
case (1<<3): return L1;
case (1<<2): return L0;
+ case (1<<0): return NONE; /* huh? */
case 0: return NONE;
- default: throw new RuntimeException("invalid argument");
+ default: throw new RuntimeException("invalid argument: zi=="+(dev.mode4(0x02, row, col) & 0xDB));
}
}
--- /dev/null
+package edu.berkeley.obits.gui;
+
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
+import edu.berkeley.obits.*;
+import edu.berkeley.obits.device.atmel.*;
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+import java.awt.color.*;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+
+/** Graphics */
+public class G {
+
+ public final Graphics2D g;
+
+ public G(Graphics2D g) { this.g = g; }
+ public G(Graphics g) { this((Graphics2D)g); }
+
+ public void line(Point2D p1, Point2D p2) { line(new P(p1), new P(p2)); }
+
+ public void line(P p1, P p2) { line(p1.x, p1.y, p2.x, p2.y); }
+ public void line(double x, double y, P p2) { line(x, y, p2.x, p2.y); }
+ public void line(P p1, double x, double y) { line(p1.x, p1.y, x, y); }
+ public void line(double x1, double y1, double x2, double y2) {
+ g.draw(new Line2D.Double(x1, y1, x2, y2));
+ }
+
+ public void color(Color c) { g.setColor(c); }
+ public void color(int color) {
+ g.setColor(new Color((color >> 16) & 0xff,
+ (color >> 8) & 0xff,
+ (color >> 0) & 0xff
+ ));
+ }
+
+}
--- /dev/null
+package edu.berkeley.obits.gui;
+
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
+import edu.berkeley.obits.*;
+import edu.berkeley.obits.device.atmel.*;
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+import java.awt.color.*;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+
+public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListener {
+
+ Graphics2D g;
+ G gg;
+
+ public static int SIZE = 92;
+ public static int RINGS = 3;
+ public static int BEVEL = 5;
+ public static int CORE_SIZE = 64;
+ public static int CORE_OFFSET = 10;
+ public static int HOFF = 52;
+
+ public static int RED = 0xff0000;
+ public static int BLUE = 0x0000ff;
+
+ public static final P YLUT_OUTPUT_POINT = new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + 41 - 3);
+ public static final P XLUT_OUTPUT_POINT = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + 41 - 3);
+
+ At40k at40k;
+
+ private HashSet<Cell> cells = new HashSet<Cell>();
+ private Cell[][] ca = new Cell[128][];
+
+ public static final Color nonselectedcell = new Color(0xcc, 0xcc, 0xcc);
+ public static final Color selectedcell = new Color(0x44, 0x44, 0xff);
+
+ public Gui(At40k at40k) {
+ this.at40k = at40k;
+ for(int i=0; i<ca.length; i++)
+ ca[i] = new Cell[128];
+ for(int x=0; x<7; x++)
+ for(int y=0; y<7; y++)
+ new Cell(x,y, at40k.cell(x+7, y+7));
+ }
+
+
+ public class Cell {
+ At40k.Cell cell;
+ boolean in = false;
+ int _x, _y;
+ public Cell(int x, int y, At40k.Cell cell) {
+ _x = x;
+ _y = y;
+ ca[_x][_y] = this;
+ this.cell = cell;
+ cells.add(this);
+ }
+ public void draw() {
+ gg.color(in ? selectedcell : nonselectedcell);
+ g.fillRect(0, 0, SIZE, SIZE);
+
+ drawHwires();
+ drawVwires();
+ drawLocal();
+
+ AffineTransform t = g.getTransform();
+ g.transform(rotateInnerTransform());
+ drawMux();
+ drawRegister();
+ drawInternalRouting();
+ drawBuffer();
+ g.setTransform(t);
+
+ drawGates();
+ drawBorder();
+ }
+ public void drawBuffer() {
+ if (!cell.out_relevant()) return;
+ gg.color(Color.black);
+ gg.line(21, 64, 28, 60);
+ gg.line(21, 64, 28, 68);
+ gg.line(28, 60, 28, 68);
+
+ gg.color(Color.magenta);
+ if (cell.oe() == V4) {
+ gg.line(16, 53, 25, 53);
+ gg.line(25, 53, 25, 62);
+ } else if (cell.oe() == H4) {
+ gg.line(25, 76, 25, 67);
+ }
+
+ }
+ public void drawHwires() {
+ gg.color(Color.magenta);
+ for(int i=0; i<5; i++)
+ if (cell.hwire(i).isDriven())
+ gg.line(0, SIZE-(2*(1+RINGS)+2*i), SIZE, SIZE-(2*(1+RINGS)+2*i));
+ int plane = cell.zi();
+ if (plane >= L0 && plane <= L4 && cell.hx(plane)) {
+ P p1 = new P(38, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
+ route(new P(84, 84 - 2*(plane-L0)), p1, 3);
+ p1 = new P(64, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
+ route(new P(84, 84 - 2*(plane-L0)), p1, 3);
+ }
+ plane = cell.wi();
+ if (plane >= L0 && plane <= L4 && cell.hx(plane)) {
+ P p1 = new P(38, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
+ route(new P(84, 84 - 2*(plane-L0)), p1, 3);
+ p1 = rotateInner(new P(64, 18));
+ if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
+ route(new P(84, 84 - 2*(plane-L0)), p1, 3);
+ }
+ }
+ public void drawVwires() {
+ gg.color(Color.magenta);
+ for(int i=0; i<5; i++)
+ if (cell.vwire(i).isDriven())
+ gg.line(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE);
+ int plane = cell.zi();
+ if (plane >= L0 && plane <= L4 && cell.vx(plane)) {
+ P p1 = new P(38, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
+ route(new P(17 - 2*(plane-L0), 8), p1, 3);
+ p1 = new P(64, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
+ route(new P(17 - 2*(plane-L0), 8), p1, 3);
+ }
+ plane = cell.wi();
+ if (plane >= L0 && plane <= L4 && cell.vx(plane)) {
+ P p1 = new P(38, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_xlut_relevant() && cell.xlut_relevant())
+ route(new P(17 - 2*(plane-L0), 8), p1, 3);
+ p1 = new P(64, 18);
+ p1 = rotateInner(p1);
+ if (cell.zi_to_ylut_relevant() && cell.ylut_relevant())
+ route(new P(17 - 2*(plane-L0), 8), p1, 3);
+ }
+ }
+ public void drawInternalRouting() {
+ gg.color(new Color(0, 107, 51));
+ if (cell.fb_relevant()) {
+ if (cell.f()) {
+ gg.line(51, 74, 37, 74);
+ gg.line(37, 74, 50, 12);
+ } else if (cell.c() == XLUT) {
+ gg.line(32, 52, 50, 52);
+ gg.line(50, 52, 50, 12);
+ } else if (cell.c() == YLUT) {
+ gg.line(68, 52, 50, 52);
+ gg.line(50, 52, 50, 12);
+ } else {
+ gg.line(50, 56, 41, 56);
+ gg.line(41, 56, 50, 12);
+ }
+ if (cell.xlut_relevant()) {
+ gg.line(52, 12, XLUT_OUTPUT_POINT.getX(), 12);
+ gg.line(XLUT_OUTPUT_POINT.getX(), 12, XLUT_OUTPUT_POINT.getX(), 32);
+ }
+ if (cell.ylut_relevant()) {
+ gg.line(52, 12, YLUT_OUTPUT_POINT.getX(), 12);
+ gg.line(YLUT_OUTPUT_POINT.getX(), 12, YLUT_OUTPUT_POINT.getX(), 32);
+ }
+ }
+ }
+
+ public void drawLocal() {
+ if (!cell.ylut_relevant() && !cell.xlut_relevant()) return;
+ P in = new P(HOFF, 0);
+ P join = new P(HOFF, CORE_OFFSET);
+ in = rotateOuter(in);
+ join = rotateInner(join);
+ int rot = rot();
+ switch(rot) {
+ case 0: case 2:
+ join = new P(in.getX(), join.getY());
+ break;
+ case 1: case 3:
+ join = new P(join.getX(), in.getY());
+ break;
+ }
+
+ P xi = null;
+ P xi2 = null;
+ gg.color(new Color(0xff, 0x00, 0x00));
+ int xring = 4;
+ if (cell.xi_relevant() && cell.xlut_relevant())
+ switch(cell.xi()) {
+ case NW:
+ xi = new P(0+2*xring, SIZE-2*xring);
+ xi2 = new P(-BEVEL, SIZE+BEVEL);
+ xi = translate(xi, 0, -3);
+ xi2 = translate(xi2, 0, -3);
+ gg.line(xi2, xi);
+ break;
+
+ case SW:
+ xi = new P(0+2*xring, 0+2*xring);
+ xi2 = new P(-BEVEL, -BEVEL);
+ xi = translate(xi, 0, 3);
+ xi2 = translate(xi2, 0, 3);
+ gg.line(xi2, xi);
+ break;
+
+ case NE:
+ xi = new P(SIZE-2*xring, SIZE-2*xring);
+ xi2 = new P(SIZE+BEVEL, SIZE+BEVEL);
+ xi = translate(xi, 0, -3);
+ xi2 = translate(xi2, 0, -3);
+ gg.line(xi2, xi);
+ break;
+
+ case SE:
+ xi = new P(SIZE-2*xring, 0+2*xring);
+ xi2 = new P(SIZE+BEVEL, -BEVEL);
+ xi = translate(xi, 0, 3);
+ xi2 = translate(xi2, 0, 3);
+ gg.line(xi2, xi);
+ break;
+ }
+
+ if (cell.xlut_relevant()) {
+ P c;
+ gg.color(BLUE);
+ if (cell.yi_to_xlut_relevant())
+ route(in, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 6, 20)), 5);
+
+ gg.color(RED);
+ if (cell.xi_to_xlut_relevant() && xi != null)
+ route(xi, rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 - CORE_SIZE / 3, 20)), 4);
+
+ P xo = XLUT_OUTPUT_POINT;
+ P xout = new P(SIZE-CORE_OFFSET-CORE_SIZE+17 - 2, CORE_OFFSET + CORE_SIZE - 3);
+ xo = rotateInner(xo);
+ xout = rotateInner(xout);
+ gg.color(new Color(0xff, 0xcc, 0xcc));
+ xring = 6;
+ if (cell.ne() != null && cell.ne().xi()==SW && cell.ne().xi_relevant() && cell.ne().xlut_relevant()) {
+ gg.line(xo, xout);
+ P xoo = new P(SIZE-2*xring, SIZE-2*xring);
+ P xoo2 = new P(SIZE, SIZE);
+ xoo = translate(xoo, -3, 0);
+ xoo2 = translate(xoo2, -3, 0);
+ gg.line(xoo2, xoo);
+ route(xout, xoo, xring);
+ }
+ if (cell.nw() != null && cell.nw().xi()==SE && cell.nw().xi_relevant() && cell.nw().xlut_relevant()) {
+ gg.line(xo, xout);
+ P xoo = new P(0+2*xring, SIZE-2*xring);
+ P xoo2 = new P(0, SIZE);
+ xoo = translate(xoo, 3, 0);
+ xoo2 = translate(xoo2, 3, 0);
+ gg.line(xoo2, xoo);
+ route(xout, xoo, xring);
+ }
+ if (cell.se() != null && cell.se().xi()==NW && cell.se().xi_relevant() && cell.se().xlut_relevant()) {
+ gg.line(xo, xout);
+ P xoo = new P(SIZE-2*xring, 0+2*xring);
+ P xoo2 = new P(SIZE, 0);
+ xoo = translate(xoo, -3, 0);
+ xoo2 = translate(xoo2, -3, 0);
+ gg.line(xoo2, xoo);
+ route(xout, xoo, xring);
+ }
+ if (cell.sw() != null && cell.sw().xi()==NE && cell.sw().xi_relevant() && cell.sw().xlut_relevant()) {
+ gg.line(xo, xout);
+ P xoo = new P(0+2*xring, 0+2*xring);
+ P xoo2 = new P(0, 0);
+ xoo = translate(xoo, 3, 0);
+ xoo2 = translate(xoo2, 3, 0);
+ gg.line(xoo2, xoo);
+ route(xout, xoo, xring);
+ }
+ }
+
+ if (cell.ylut_relevant()) {
+ gg.color(new Color(0x00, 0x00, 0xff));
+ P c;
+ if (cell.yi_to_ylut_relevant()) {
+ c = new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 6, 20);
+ c = rotateInner(c);
+ route(in, c, 5);
+ }
+ gg.color(new Color(0xff, 0x00, 0x00));
+ if (cell.xi_to_ylut_relevant()) {
+ c = rotateInner(new P(SIZE - CORE_OFFSET - CORE_SIZE/2 + CORE_SIZE / 3, 20));
+ if (xi != null)
+ route(xi, c, 4);
+ }
+
+ P yo = rotateInner(YLUT_OUTPUT_POINT);
+ P yout = rotateInner(new P(SIZE-CORE_OFFSET-CORE_SIZE+51 - 2, CORE_OFFSET + CORE_SIZE - 3));
+ gg.color(0xbbbbff);
+ if (cell.north() != null && cell.north().yi()==SOUTH && cell.north().yi_relevant() && cell.north().ylut_relevant()) {
+ gg.line(yo, yout);
+ route(yout, new P(SIZE-40, SIZE+ 0), 2);
+ }
+ if (cell.east() != null && cell.east().yi()==WEST && cell.east().yi_relevant() && cell.east().ylut_relevant()) {
+ gg.line(yo, yout);
+ route(yout, new P(SIZE+ 0, 40), 2);
+ }
+ if (cell.south() != null && cell.south().yi()==NORTH && cell.south().yi_relevant() && cell.south().ylut_relevant()) {
+ gg.line(yo, yout);
+ route(yout, new P( 40, 0), 2);
+ }
+ if (cell.west() != null && cell.west().yi()==EAST && cell.west().yi_relevant() && cell.west().ylut_relevant()) {
+ gg.line(yo, yout);
+ route(yout, new P( 0, SIZE-40), 2);
+ }
+ }
+
+ }
+
+
+ private AffineTransform rotateOuterTransform() {
+ int rot = rot();
+ AffineTransform a = new AffineTransform();
+ a.rotate((Math.PI/2) * rot);
+ switch(rot) {
+ case 0: break;
+ case 1: a.translate(0, -SIZE); break;
+ case 2: a.translate(-SIZE, -SIZE); break;
+ case 3: a.translate(-SIZE, 0); break;
+ }
+ return a;
+ }
+
+ private P rotateOuter(P p) { return p.transform(rotateOuterTransform()); }
+ private P rotateInner(P p) { return p.transform(rotateInnerTransform()); }
+
+ private AffineTransform rotateInnerTransform() {
+ int rot = rot();
+ AffineTransform a = new AffineTransform();
+ a.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
+ a.rotate((Math.PI/2) * rot);
+ switch(rot) {
+ case 0: break;
+ case 1: a.translate(0, -CORE_SIZE); break;
+ case 2: a.translate(-CORE_SIZE, -CORE_SIZE); break;
+ case 3: a.translate(-CORE_SIZE, 0); break;
+ }
+ a.translate(-1 * (SIZE-CORE_SIZE-CORE_OFFSET), -CORE_OFFSET);
+ return a;
+ }
+
+
+ private P project(P p1, int ring) {
+ double north = Math.abs( (SIZE-(ring*2)) - p1.getY() );
+ double south = Math.abs( ( (ring*2)) - p1.getY() );
+ double east = Math.abs( (SIZE-(ring*2)) - p1.getX() );
+ double west = Math.abs( ( (ring*2)) - p1.getX() );
+ if (north < south && north < east && north < west) return new P(p1.x, SIZE-ring*2);
+ else if (south < east && south < west) return new P(p1.x, ring*2);
+ else if (east < west) return new P(SIZE-ring*2, p1.y);
+ else return new P(ring*2, p1.y);
+
+ }
+
+ private void route(P p1, P p2, int ring) {
+ int ringpos = ring * 2;
+ P projected = project(p1, ring);
+ gg.line(p1, projected);
+ p1 = projected;
+
+ projected = project(p2, ring);
+ gg.line(p2, projected);
+ p2 = projected;
+
+ double x1 = p1.getX();
+ double y1 = p1.getY();
+ double x2 = p2.getX();
+ double y2 = p2.getY();
+
+ if (x1==x2 || y1==y2) {
+ gg.line(p1, p2);
+ return;
+ }
+
+ if ((x1==SIZE-ring*2 || x1==ring*2) && !(y1==SIZE-ring*2 || y1==ring*2)) {
+ P p3 = new P(x1, y2 > SIZE/2 ? SIZE-ring*2 : ring*2);
+ gg.line(p1, p3);
+ route(p3, p2, ring);
+ } else if ((y1==SIZE-ring*2 || y1==ring*2) && !(x1==SIZE-ring*2 || x1==ring*2)) {
+ P p3 = new P(x2 > SIZE/2 ? SIZE-ring*2 : ring*2, y1);
+ gg.line(p1, p3);
+ route(p3, p2, ring);
+ } else
+ route(p2, p1, ring);
+
+ }
+
+ private int rot() {
+ int rot = 0;
+ switch(cell.yi()) {
+ case SOUTH: rot = 0; break;
+ case NORTH: rot = 2; break;
+ case EAST: rot = 1; break;
+ case WEST: rot = 3; break;
+ default: {
+ // FIXME: choose based on xin
+ if (cell.north() != null && cell.north().yi()==SOUTH) { rot = 0; break; }
+ if (cell.south() != null && cell.south().yi()==NORTH) { rot = 2; break; }
+ if (cell.east() != null && cell.east().yi()==WEST) { rot = 3; break; }
+ if (cell.west() != null && cell.west().yi()==EAST) { rot = 1; break; }
+ }
+ }
+ return rot;
+ }
+
+ public void drawGates() {
+ AffineTransform t = g.getTransform();
+ try {
+ g.translate(SIZE-CORE_SIZE-CORE_OFFSET, CORE_OFFSET);
+
+ int rot = rot();
+ g.rotate((Math.PI/2) * rot);
+ switch(rot) {
+ case 0: break;
+ case 1: g.translate(0, -CORE_SIZE); break;
+ case 2: g.translate(-CORE_SIZE, -CORE_SIZE); break;
+ case 3: g.translate(-CORE_SIZE, 0); break;
+ }
+
+ //gg.color(Color.gray);
+ //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE);
+ g.scale(1, -1);
+
+ GeneralPath p = new GeneralPath();
+ p.moveTo(29.141f, 36.301f);
+ p.lineTo(29.141f, 36.301f-7.161f);
+ p.curveTo(27.71f, 11.24f, 23.413f, 9.45f, 14.82f, 0.5f);
+ p.curveTo(6.229f, 9.45f, 1.932f, 11.24f, 0.5f, 29.141f);
+ p.lineTo(0.5f, 29.141f+7.161f);
+ float x = 0.5f;
+ float y = 29.141f+7.161f;
+ p.curveTo(5.729f+x, -1.789f+y,
+ 6.444f+x, -2.686f+y,
+ 14.32f+x, -3.58f+y);
+ p.curveTo(22.697f, 33.616f, 23.413f, 34.512f, 29.141f, 36.301f);
+ g.translate(0, -40f);
+ if (cell.xlut_relevant()) {
+ gg.color(Color.white);
+ g.fill(p);
+ gg.color(Color.red);
+ g.draw(p);
+ }
+ g.translate(34f, 0f);
+ if (cell.ylut_relevant()) {
+ gg.color(Color.white);
+ g.fill(p);
+ gg.color(Color.blue);
+ g.draw(p);
+ }
+ } finally {
+ g.setTransform(t);
+ }
+ }
+ public void drawMux() {
+ if (!cell.c_relevant()) return;
+ gg.color(Color.black);
+ if (cell.xlut_relevant() && (cell.c() == ZMUX || cell.c() == XLUT)) {
+ gg.color(new Color(0xff, 0xbb, 0xbb));
+ gg.line(XLUT_OUTPUT_POINT, new P(XLUT_OUTPUT_POINT.getX(), 52));
+ gg.line(new P(XLUT_OUTPUT_POINT.getX(), 52), new P(51, 52));
+ }
+ if (cell.ylut_relevant() && (cell.c() == ZMUX || cell.c() == YLUT)) {
+ gg.color(new Color(0xbb, 0xbb, 0xff));
+ gg.line(YLUT_OUTPUT_POINT, new P(YLUT_OUTPUT_POINT.getX(), 52));
+ gg.line(new P(YLUT_OUTPUT_POINT.getX(), 52), new P(51, 52));
+ }
+ gg.line(51, 52, 51, 51+25);
+ if (cell.c() == ZMUX) {
+ gg.color(Color.black);
+ gg.line(51, 52, 51, 51+25);
+ gg.line(46, 54, 46+2, 54+5);
+ gg.line(46+2, 54+5, 60-2, 54+5);
+ gg.line(60-2, 54+5, 60, 54);
+ gg.line(60, 54, 46, 54);
+ }
+ }
+ public void drawRegister() {
+ if (!cell.register_relevant()) return;
+ gg.color(Color.white);
+ g.fillRect(48, 58, 10, 14);
+ gg.color(Color.black);
+ g.drawRect(48, 58, 10, 14);
+ gg.line(57, 70, 54, 68);
+ gg.line(54, 68, 57, 66);
+ }
+ public void drawBorder() {
+ gg.color(Color.gray);
+ //gg.line(0, BEVEL, BEVEL, 0);
+ gg.line(BEVEL, 0, SIZE-BEVEL, 0);
+ //gg.line(SIZE-BEVEL, 0, SIZE, BEVEL);
+ gg.line(SIZE, BEVEL, SIZE, SIZE-BEVEL);
+ //gg.line(SIZE, SIZE-BEVEL, SIZE-BEVEL, SIZE);
+ gg.line(SIZE-BEVEL, SIZE, BEVEL, SIZE);
+ //gg.line(BEVEL, SIZE, 0, SIZE-BEVEL);
+ gg.line(0, SIZE-BEVEL, 0, BEVEL);
+ }
+ }
+
+ public void _paint(Graphics2D g) {
+
+ this.g = g;
+ this.gg = new G(g);
+ g.setStroke(new BasicStroke((float)0.5));
+
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
+
+ AffineTransform t = g.getTransform();
+ for(Cell c : cells) {
+ g.setTransform(t);
+ g.translate( c._x * SIZE/* + (10 * (c._x/4))*/, c._y * SIZE/* + (10 * (c._y/4))*/);
+ c.draw();
+ }
+ g.setTransform(t);
+
+ g.setTransform(new AffineTransform());
+
+ gg.color(selectedcell);
+ g.fillRect(getWidth() - 200, 0, 200, 100);
+ gg.color(Color.white);
+ g.drawRect(getWidth() - 200, 0, 200, 100);
+
+ Cell newcell = whichCell(mousex, mousey);
+ int line = 10;
+ if (newcell != null && newcell.cell != null) {
+ g.drawString("selected: " + newcell._x + ","+newcell._y,
+ getWidth() - 200 + 10, (line += 15));
+ g.drawString(" xlut: " + AtmelSerial.bin8(newcell.cell.xlut()),
+ getWidth() - 200 + 10, (line += 15));
+ g.drawString(" ylut: " + AtmelSerial.bin8(newcell.cell.ylut()),
+ getWidth() - 200 + 10, (line += 15));
+ String xi = "??";
+ switch(newcell.cell.xi()) {
+ case NW : xi = "NW"; break;
+ case NE : xi = "NE"; break;
+ case SW : xi = "SW"; break;
+ case SE : xi = "SE"; break;
+ }
+ g.drawString(" xi: " + xi, getWidth() - 200 + 10, (line += 15));
+ String yi = "??";
+ switch(newcell.cell.yi()) {
+ case NORTH : yi = "NORTH"; break;
+ case SOUTH : yi = "SOUTH"; break;
+ case EAST : yi = "EAST"; break;
+ case WEST : yi = "WEST"; break;
+ }
+ g.drawString(" yi: " + yi, getWidth() - 200 + 10, (line += 15));
+ }
+ this.g = null;
+ this.gg = null;
+ }
+
+
+ public void clear() {
+ Graphics2D g = (Graphics2D)getGraphics();
+ //gg.color(Color.black);
+ //gg.color(Color.lightGray);
+ g.clearRect(0, 0, getWidth(), getHeight());
+ }
+
+ public static final P translate(P p, int dx, int dy) {
+ return new P(p.getX()+dx, p.getY()+dy);
+ }
+
+ public Cell whichCell(int x, int y) {
+ P p = new P(x,y);
+ try {
+ p = p.inverseTransform(transform);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ int col = ((int)p.getX()) / (SIZE + BEVEL);
+ int row = ((int)p.getY()) / (SIZE + BEVEL);
+ for(Cell c : cells)
+ if (c._x == col && c._y == row)
+ return c;
+ return null;
+ }
+}
--- /dev/null
+package edu.berkeley.obits.gui;
+
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
+import edu.berkeley.obits.*;
+import edu.berkeley.obits.device.atmel.*;
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+import java.awt.color.*;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+
+/** a point, since Java2D's Point2D class sucks rocks */
+public class P {
+
+ public final double x;
+ public final double y;
+
+ public P(double x, double y) { this.x = x; this.y = y; }
+ public P(Point2D p) { this(p.getX(), p.getY()); }
+ public double getX() { return x; }
+ public double getY() { return y; }
+
+ public P transform(AffineTransform a) {
+ Point2D me = new Point2D.Double(x, y);
+ return new P(a.transform(me, me));
+ }
+ public P inverseTransform(AffineTransform a) {
+ try {
+ Point2D me = new Point2D.Double(x, y);
+ return new P(a.inverseTransform(me, me));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
--- /dev/null
+package edu.berkeley.obits.gui;
+
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
+import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
+import edu.berkeley.obits.*;
+import edu.berkeley.obits.device.atmel.*;
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.event.*;
+import java.awt.color.*;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+
+public abstract class ZoomingPanel extends JComponent implements KeyListener, MouseMotionListener {
+
+ double scale = 1.0;
+ double oscale = 1.0;
+ public int dragx = 0;
+ public int dragy = 0;
+ public boolean drag = false;
+ protected int mousex;
+ protected int mousey;
+ protected AffineTransform transform = new AffineTransform();
+ private Point2D recenter;
+ private Point2D recenter2;
+
+ public ZoomingPanel() {
+ setDoubleBuffered(true);
+ addKeyListener(this);
+ addMouseMotionListener(this);
+ }
+
+ public abstract void _paint(Graphics2D g);
+
+ public final void paint(Graphics _g) {
+ Graphics2D g = (Graphics2D)_g;
+ g.scale(scale,scale);
+ g.translate(10, 0);
+ g.scale(1, -1);
+ g.translate(5, -1 * getHeight() + 10);
+
+ transform = g.getTransform();
+
+ Point2D p = new Point2D.Float();
+ if (recenter != null) {
+ transform.transform(recenter, p);
+ transform.preConcatenate(AffineTransform.getTranslateInstance(dragx - p.getX(),
+ dragy - p.getY()));
+ }
+ g.setTransform(transform);
+
+ if (drag) {
+ g.setColor(Color.blue);
+ g.drawLine((int)(recenter.getX() - 10),
+ (int)(recenter.getY() - 10),
+ (int)(recenter.getX() + 10),
+ (int)(recenter.getY() + 10));
+ g.drawLine((int)(recenter.getX() + 10),
+ (int)(recenter.getY() - 10),
+ (int)(recenter.getX() - 10),
+ (int)(recenter.getY() + 10));
+ }
+ _paint(g);
+ }
+
+
+ public void keyTyped(KeyEvent k) {
+ }
+ public void keyReleased(KeyEvent k) {
+ if (k.getKeyCode() == k.VK_ALT) {
+ if (drag) {
+ drag = false;
+ oscale = scale;
+ repaint();
+ }
+ }
+ }
+ public void keyPressed(KeyEvent k) {
+ if (k.getKeyCode() == k.VK_ALT) {
+ drag = true;
+ dragx = mousex;
+ dragy = mousey;
+ recenter = new Point2D.Float(dragx, dragy);
+ try {
+ transform.inverseTransform(recenter, recenter);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ char c = k.getKeyChar();
+ switch(c) {
+ case '+': scale += 0.1; repaint(); return;
+ case '-': scale -= 0.1; repaint(); return;
+ case 'z': scale = 1.0; recenter = null; repaint(); return;
+ }
+ }
+ public void mouseMoved(MouseEvent m) {
+ /*
+ Cell oldcell = whichCell(mousex, mousey);
+ Cell newcell = whichCell(m.getX(), m.getY());
+ System.out.println((oldcell==null ? "old=null" : ("old=" + oldcell._x+","+oldcell._y+" "))+
+ (newcell==null ? "new=null" : ("new=" + newcell._x+","+newcell._y+" ")));
+ if (oldcell != newcell) {
+ if (oldcell != null) oldcell.in = false;
+ if (newcell != null) newcell.in = true;
+ repaint();
+ }
+ */
+ mousex = m.getX();
+ mousey = m.getY();
+ if (drag) {
+ if (mousey > dragy + 5) {
+ scale = 1 / ((1 / oscale) + ((mousey - dragy) / 50.0));
+ } else if (mousey < dragy - 5) {
+ scale = oscale + ((dragy - mousey) / 50.0);
+ } else {
+ scale = oscale;
+ }
+ repaint();
+ }
+ }
+
+
+ public boolean isFocusable() { return true; }
+
+ public void mouseDragged(MouseEvent m) {
+ mouseMoved(m);
+ dragx = m.getX();
+ dragy = m.getY();
+ }
+ public void mousePressed(MouseEvent m) {
+ recenter = new Point2D.Float(m.getX(), m.getY());
+ try {
+ transform.transform(recenter, recenter);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ repaint();
+ }
+ public void mouseEntered(MouseEvent e) { }
+ public void mouseExited(MouseEvent e) { }
+ public void mouseClicked(MouseEvent e) { }
+ public void mouseReleased(MouseEvent e) { }
+}