checkpoint
[slipway.git] / src / edu / berkeley / slipway / gui / Gui.java
index 371da77..829479f 100644 (file)
@@ -56,20 +56,29 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
     }
 
     public Gui(Fpslic at40k, FtdiBoard drone) {
+        this(at40k, drone, 24, 24);
+    }
+    public Gui(Fpslic at40k, FtdiBoard drone, int width, int height) {
+        super(drone);
         this.at40k = at40k;
         this.drone = drone;
         for(int i=0; i<ca.length; i++)
             ca[i] = new Cell[128];
-        for(int x=9; x<14; x++)
-            for(int y=19; y<at40k.getHeight(); y++)
+        for(int x=0; x<width; x++)
+            for(int y=0; y<height; y++)
                 new Cell(x,y, at40k.cell(x, y));
 
 
-        new Thread() {
+
+        /*
+          new Thread() {
             public void run() {
+                try { Thread.sleep(2000); } catch (Exception e) { }
                 while(true) scan();
             }
-        }.start();
+            }.start();
+        */
+
 
         /*
         Fpslic.Cell c = at40k.cell(0,0);
@@ -96,25 +105,30 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
             this.cell = cell;
             cells.add(this);
         }
+        public boolean scanme() { 
+            return cell.relevant();
+        }
         public void clear() {
-            gg.color(in ? selectedcell : (scanme ? new Color(0xbb, 0xbb, 0xbb) : nonselectedcell));
+            gg.color(in ? selectedcell : (scanme() ? new Color(0xbb, 0xbb, 0xbb) : nonselectedcell));
             g.fillRect(0, 0, SIZE, SIZE);
         }
         public void draw() {
 
-            drawWires();
-            drawLocal();
-
-            AffineTransform t = g.getTransform();
-
-            drawBuffer();
-            g.transform(rotateInnerTransform());
-            drawMux();
-            drawRegister();
-            drawInternalRouting();
-            g.setTransform(t);
-
-            drawGates();
+            if (cell.relevant() || scanme()) {
+                drawWires();
+                drawLocal();
+                
+                AffineTransform t = g.getTransform();
+                
+                drawBuffer();
+                g.transform(rotateInnerTransform());
+                drawMux();
+                drawRegister();
+                drawInternalRouting();
+                g.setTransform(t);
+                
+                drawGates();
+            }
             drawBorder();
         }
         public void drawBuffer() {
@@ -142,11 +156,13 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         public void drawWires() {
             gg.color(MAGENTA);
             for(int i=0; i<5; i++)
+                if (i!=3)
                 if (cell.hwire(i).isDriven()) {
                     gg.color(cell.out(i) ? ORANGE : MAGENTA);
                     gg.line(0, SIZE-(2*(1+RINGS)+2*i), SIZE, SIZE-(2*(1+RINGS)+2*i));
                 }
             for(int i=0; i<5; i++)
+                if (i!=3)
                 if (cell.vwire(i).isDriven()) {
                     gg.color(cell.out(i) ? ORANGE : MAGENTA);
                     gg.line(2*(1+RINGS)+2*i, 0, 2*(1+RINGS)+2*i, SIZE);
@@ -415,18 +431,27 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
                 //g.drawRect(0, 0, CORE_SIZE, CORE_SIZE);
                 //g.scale(1, -1);
 
-                Gate gate = new Muller();
 
                 g.translate(2,   5f);
-                if (xlut_relevant(cell))
+                if (xlut_relevant(cell) || scanme()) {
+                    Gate gate = getGate(cell.xlut(), true);
                     gate.draw(g,
                               !xknown ? Color.gray : xon ? Color.red : Color.white,
-                              (xon && xknown) ? Color.white : Color.red);
+                              (xon && xknown) ? Color.white : Color.red,
+                              xon ? Color.white : Color.red
+                              );
+                }
+
                 g.translate(34f, 0f);
-                if (cell.ylut_relevant())
+                if (cell.ylut_relevant() || scanme()) {
+                    Gate gate = getGate(cell.ylut(), false);
                     gate.draw(g,
                               !yknown ? Color.gray : yon ? Color.blue : Color.white,
-                              (yon && yknown) ? Color.white : Color.blue);
+                              (yon && yknown) ? Color.white : Color.blue,
+                              yon ? Color.white : Color.blue
+                              );
+                }
+
             } finally {
                 g.setTransform(t);
             }
@@ -540,6 +565,7 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         repaint();
     }
     public void drawKeyboard(Image keyboardImage, Graphics2D g) {
+        /*
                 int width = 300;
                 int height = (keyboardImage.getHeight(null) * width) / keyboardImage.getWidth(null);
                 g.drawImage(keyboardImage,
@@ -548,6 +574,7 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
                             0, 0,
                             keyboardImage.getWidth(null), keyboardImage.getHeight(null),
                             null);
+        */
     }
 
     public void _paint(Graphics2D g) {
@@ -612,7 +639,16 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
                          getWidth() - 200 + 10, (line += 15));
             g.drawString("z-in mux: " + (newcell.cell.zi()==NONE ? "." : ("L"+(newcell.cell.zi()-L0))),
                          getWidth() - 200 + 10, (line += 15));
-            g.drawString("t-in mux: ", getWidth() - 200 + 10, (line += 15));
+
+            String tm = "??";
+            switch(newcell.cell.t()) {
+                case TMUX_FB:       tm = "fb"; break;
+                case TMUX_W_AND_FB: tm = "w&fb"; break;
+                case TMUX_Z:        tm = "z"; break;
+                case TMUX_W_AND_Z:  tm = "w&z"; break;
+                case TMUX_W:        tm = "w"; break;
+            }
+            g.drawString("t-in mux: " + tm, getWidth() - 200 + 10, (line += 15));
 
             g.drawString(" set/rst: " + (newcell.cell.ff_reset_value() ? "reset=SET" : "."),
                          getWidth() - 200 + 10, (line += 15));
@@ -723,13 +759,13 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         for(int x=0; x<at40k.getWidth(); x++)
             for(int y=0; y<at40k.getHeight(); y++)
                 if (ca[x][y] != null)
-                    if (ca[x][y].scanme)
+                    if (ca[x][y].scanme())
                         scan(ca[x][y]);
     }
     public void scan(final Gui.Cell c) {
         try {
             final Fpslic.Cell cell = c.cell;
-            Demo.scan(at40k, cell, NONE, true);
+            scan(at40k, cell, NONE, true);
             boolean safe = !cell.fb_relevant();
             if (cell.xo()) safe = false;
             if (cell.yo()) safe = false;
@@ -741,25 +777,154 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
                 if (cell.xlut_relevant()) {
                     cell.c(XLUT);
                     drone.readBus(new BCB(c, XLUT));
+                } else {
+                    c.xknown = false;
                 }
                 if (cell.ylut_relevant()) {
                     cell.c(YLUT);
                     drone.readBus(new BCB(c, YLUT));
+                } else {
+                    c.yknown = false;
                 }
                 cell.c(oldc);
             } else {
                 switch(cell.c()) {
-                    case XLUT: if (cell.xlut_relevant()) drone.readBus(new BCB(c, XLUT)); break;
-                    case YLUT: if (cell.ylut_relevant()) drone.readBus(new BCB(c, YLUT)); break;
+                    case XLUT:
+                        if (!cell.xlut_relevant()) {
+                            c.xknown = false;
+                        } else {
+                            drone.readBus(new BCB(c, XLUT));
+                        }
+                        /*
+                        if (!cell.yo())
+                        for(Fpslic.Cell c2 : new Fpslic.Cell[] { cell.north(), cell.south(), cell.east(), cell.west() })
+                            if (c2!=null && !c2.relevant()) {
+                                scan(at40k, cell, NONE, false);
+                                c2.yo(cell);
+                                c2.c(YLUT);
+                                scan(at40k, c2, NONE, true);
+                                drone.readBus(new BCB(c, YLUT));
+                                scan(at40k, c2, NONE, false);
+                                c2.yi(NONE);
+                                return;
+                            }
+                        */
+                        c.yknown = false;
+                        break;
+                    case YLUT:
+                        if (!cell.ylut_relevant()) {
+                            c.yknown = false;
+                        } else {
+                            drone.readBus(new BCB(c, YLUT));
+                        }
+                        /*
+                        if (!cell.xo())
+                        for(Fpslic.Cell c2 : new Fpslic.Cell[] { cell.nw(), cell.sw(), cell.ne(), cell.se() })
+                            if (c2!=null && !c2.relevant()) {
+                                scan(at40k, cell, NONE, false);
+                                c2.xo(cell);
+                                scan(at40k, c2, NONE, true);
+                                c2.c(XLUT);
+                                drone.readBus(new BCB(c, XLUT));
+                                scan(at40k, c2, NONE, false);
+                                c2.xi(NONE);
+                                return;
+                            }
+                        */
+                        c.xknown = false;
+                        break;
+                    case ZMUX: {
+                        /*
+                        scan(at40k, cell, NONE, false);
+                        c.xknown = false;
+                        c.yknown = false;
+                        if (!cell.xo())
+                        for(Fpslic.Cell c2 : new Fpslic.Cell[] { cell.nw(), cell.sw(), cell.ne(), cell.se() })
+                            if (c2!=null && !c2.relevant()) {
+                                scan(at40k, cell, NONE, false);
+                                c2.xo(cell);
+                                scan(at40k, c2, NONE, true);
+                                c2.c(XLUT);
+                                drone.readBus(new BCB(c, XLUT));
+                                scan(at40k, c2, NONE, false);
+                                c2.xi(NONE);
+                                return;
+                            }
+                        if (!cell.yo())
+                        for(Fpslic.Cell c2 : new Fpslic.Cell[] { cell.north(), cell.south(), cell.east(), cell.west() })
+                            if (c2!=null && !c2.relevant()) {
+                                c2.yo(cell);
+                                c2.c(YLUT);
+                                scan(at40k, c2, NONE, true);
+                                drone.readBus(new BCB(c, YLUT));
+                                scan(at40k, c2, NONE, false);
+                                c2.yi(NONE);
+                                break;
+                            }
+                        return;
+                        */
+                    }
                 }
                 
             }
-            Demo.scan(at40k, cell, NONE, false);
+            scan(at40k, cell, NONE, false);
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
     }
 
+    public static void scan(Fpslic dev, Fpslic.Cell cell, int source, boolean setup) {
+        if (setup) {
+            if (source != NONE) cell.c(source);
+            if (cell.b()) cell.b(false);
+            if (cell.f()) cell.f(false);
+        }
+        if (cell.out(L3)!=setup) cell.out(L3, setup);
+        if (cell.vx(L3)!=setup) cell.v(L3, setup);
+
+        Fpslic.SectorWire sw = cell.vwire(L3);
+        //System.out.println("wire is: " + sw);
+
+        if (sw.row > (12 & ~0x3) && sw.north()!=null && sw.north().drives(sw))
+            sw.north().drives(sw, false);
+        while(sw.row > (12 & ~0x3) && sw.south() != null) {
+            //System.out.println(sw + " -> " + sw.south());
+            if (sw.drives(sw.south())!=setup) sw.drives(sw.south(), setup);
+            sw = sw.south();
+        }
+        if (sw.row < (12 & ~0x3) && sw.south() != null && sw.south().drives(sw))
+            sw.north().drives(sw, false);
+        while(sw.row < (12 & ~0x3) && sw.north() != null) {
+            //System.out.println(sw + " -> " + sw.north());
+            if (sw.drives(sw.north())!=setup) sw.drives(sw.north(), setup);
+            sw = sw.north();
+        }
+
+        //cell = dev.cell(19, 15);
+        cell = dev.cell(cell.col, 15);
+        /*
+        System.out.println("cell is " + cell);
+        cell.xlut(0xff);
+        cell.ylut(0xff);
+        cell.b(false);
+        cell.f(false);
+        cell.c(XLUT);
+        cell.out(L3, true);
+        cell.oe(NONE);
+        */
+        if (cell.hx(L3) != setup) cell.h(L3, setup);
+        if (cell.vx(L3) != setup) cell.v(L3, setup);
+        sw = cell.hwire(L3);
+
+        if (sw.west()!=null && sw.west().drives(sw)) { sw.west().drives(sw, false); }
+        while(sw.east() != null) {
+            //System.out.println(sw + " -> " + sw.east());
+            if (sw.drives(sw.east())!=setup) sw.drives(sw.east(), setup);
+            sw = sw.east();
+        }
+
+    }
+
 
     int made = 0;
     private class BCB extends FtdiBoard.ByteCallback {
@@ -771,8 +936,6 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         }
         public void call(byte b) throws Exception {
             boolean on = (b & 0x80) != 0;
-            c.xknown = false;
-            c.yknown = false;
             switch(who) {
                 case YLUT:
                     c.yknown = true;
@@ -789,6 +952,28 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         }
     }
 
+    public Gate getGate(byte lut, boolean xlut) {
+        for(Gate g : knownGates)
+            if (g.setLut(lut, xlut))
+                return g;
+        return unknownGate;
+    }
+
+    public Gate unknownGate = new Circle("?");
+    public Gate[] knownGates =
+        new Gate[] {
+            new And(),
+            new Or(),
+            new Circle("0") { public boolean result(boolean x, boolean y, boolean z) { return false; } },
+            new Circle("1") { public boolean result(boolean x, boolean y, boolean z) { return true; } },
+            new Circle("x") { public boolean result(boolean x, boolean y, boolean z) { return x; } },
+            new Circle("y") { public boolean result(boolean x, boolean y, boolean z) { return y; } },
+            new Circle("z") { public boolean result(boolean x, boolean y, boolean z) { return z; } },
+            new Circle("~x") { public boolean result(boolean x, boolean y, boolean z) { return !x; } },
+            new Circle("~y") { public boolean result(boolean x, boolean y, boolean z) { return !y; } },
+            new Circle("~z") { public boolean result(boolean x, boolean y, boolean z) { return !z; } }
+        };
+
     // FIXME: 2-input gates?
     public abstract class Gate {
         public boolean invert_x;
@@ -796,7 +981,7 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         public boolean invert_z;
         public boolean invert_out;
         public abstract boolean result(boolean x, boolean y, boolean z);
-        public void draw(Graphics2D g, Color fill, Color stroke) {
+        public void draw(Graphics2D g, Color fill, Color stroke, Color text) {
             GeneralPath p = new GeneralPath();
             makePath(p);
             g.setColor(fill);
@@ -806,28 +991,36 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
 
             AffineTransform a = g.getTransform();
             g.scale(1, -1);
-            g.setColor(Color.white);
-            if (label() != null) g.drawString(label(), 7, -14);
+            if (label() != null) {
+                g.setColor(text);
+                g.drawString(label(), 7, -14);
+            }
             g.setTransform(a);
         }
         public String label() { return null; }
-        public boolean setLut(int lut) {
+        public boolean setLut(int lut, boolean xlut) {
+            /*
             for(int inverts = 0; inverts < 16; inverts++) {
                 invert_x   = (inverts & 0x1) != 0;
                 invert_y   = (inverts & 0x2) != 0;
                 invert_z   = (inverts & 0x4) != 0;
                 invert_out = (inverts & 0x8) != 0;
+            */
+                boolean good = true;
                 for(int bit=0; bit<8; bit++) {
-                    boolean x = (bit & 0x1) != 0;
-                    boolean y = (bit & 0x2) != 0;
+                    boolean x = xlut ? ((bit & 0x1) != 0) : ((bit & 0x2) != 0);
+                    boolean y = xlut ? ((bit & 0x2) != 0) : ((bit & 0x1) != 0);
                     boolean z = (bit & 0x4) != 0;
                     boolean expect = (lut & (1<<bit)) != 0;
 
                     // FIXME symmetry issues here....
                     boolean result = result(x ^ invert_x, y ^ invert_y, z ^ invert_z) ^ invert_out;
-                    if (result == expect) return true;
+                    if (result != expect) { good = false; break; }
                 }
+                if (good) return true;
+                /*
             }
+                */
             return false;
         }
         public abstract void makePath(GeneralPath gp);
@@ -836,11 +1029,11 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
     public class Or extends Gate {
         public boolean result(boolean x, boolean y, boolean z) { return x || y || z; }
         public String label() { return "+"; }
-        public void draw(Graphics2D g, Color fill, Color stroke) {
+        public void draw(Graphics2D g, Color fill, Color stroke, Color text) {
             AffineTransform at = g.getTransform();
             g.scale(1, -1);
             g.translate(0, -40);
-            super.draw(g, fill, stroke);
+            super.draw(g, fill, stroke, text);
             g.setTransform(at);
         }
         public void makePath(GeneralPath gp) {
@@ -858,6 +1051,22 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
         }
     }
 
+    public class Circle extends Gate {
+        String label;
+        public Circle(String label) { this.label = label; }
+        public boolean result(boolean x, boolean y, boolean z) { return false; }
+        public String label() { return label; }
+        public void makePath(GeneralPath gp) {
+            int S = 30;
+            gp.moveTo(0, S/2);
+            gp.lineTo(S/2, S);
+            gp.lineTo(S, S/2);
+            gp.lineTo(S/2, 0);
+            gp.lineTo(0, S/2);
+            gp.closePath();
+        }
+    }
+
     public class And extends Gate {
         public boolean result(boolean x, boolean y, boolean z) { return x && y && z; }
         public String label() { return "&"; }
@@ -873,8 +1082,8 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
 
     public class Muller extends And {
         public String label() { return "C"; }
-        public void draw(Graphics2D g, Color fill, Color stroke) {
-            super.draw(g, fill, stroke);
+        public void draw(Graphics2D g, Color fill, Color stroke, Color text) {
+            super.draw(g, fill, stroke, text);
             g.setColor(stroke);
             g.drawLine(0, 0, 23, 0);
         }
@@ -883,8 +1092,8 @@ public class Gui extends ZoomingPanel implements KeyListener, MouseMotionListene
     public class Xor extends Or {
         public boolean result(boolean x, boolean y, boolean z) { return x ^ y ^ z; }
         public String label() { return "^"; }
-        public void draw(Graphics2D g, Color fill, Color stroke) {
-            super.draw(g, fill, stroke);
+        public void draw(Graphics2D g, Color fill, Color stroke, Color text) {
+            super.draw(g, fill, stroke, text);
             g.setColor(stroke);
             AffineTransform at = g.getTransform();
             g.scale(1, -1);