checkpoint
[slipway.git] / src / edu / berkeley / obits / AtmelSerial.java
1 package edu.berkeley.obits;
2
3 import static edu.berkeley.obits.device.atmel.AtmelDevice.Constants.*;
4 import static edu.berkeley.obits.device.atmel.AtmelDevice.Util.*;
5 import edu.berkeley.obits.device.atmel.*;
6 import java.awt.*;
7 import java.awt.event.*;
8 import java.awt.color.*;
9 import org.ibex.util.*;
10 import java.io.*;
11 import java.util.*;
12 import gnu.io.*;
13
14 public class AtmelSerial {
15
16     //public static boolean mullers = false;
17     public static boolean mullers = true;
18     public static int masterx = 1;
19     public static SerialPort detectObitsPort() throws Exception {
20         Enumeration e = CommPortIdentifier.getPortIdentifiers();
21         while(e.hasMoreElements()) {
22             CommPortIdentifier cpi = (CommPortIdentifier)e.nextElement();
23             Log.info(AtmelSerial.class, "trying " + cpi.getName());
24             if (cpi.getName().startsWith("/dev/cu.usbserial-")) return new RXTXPort(cpi.getName());
25             if (cpi.getName().startsWith("/dev/ttyS0")) return new RXTXPort(cpi.getName());
26         }
27         Log.info(AtmelSerial.class, "returning null...");
28         return null;
29     }
30     public static int PIPELEN=20;
31     public static void main(String[] s) throws Exception {
32         AvrDrone device = new AvrDrone(detectObitsPort());
33         At40k at40k = new At40k.At40k10(device);
34         int count = 0;
35         try {
36             long begin = System.currentTimeMillis();
37             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
38             for(String str = br.readLine(); str != null; str = br.readLine()) {
39                 long foo = Long.parseLong(str, 16);
40                 device.mode4((int)(foo >> 24), (int)(foo >> 16), (int)(foo >>  8), (int)(foo >>  0));
41                 count++;
42                 if (count % 100 == 0) Log.info(AtmelSerial.class, "wrote " + count + " configuration octets");
43             }
44             device.flush();
45             long end = System.currentTimeMillis();
46             Log.info(AtmelSerial.class, "finished in " + ((end-begin)/1000) + "s");
47             Thread.sleep(1000);
48             Log.info(AtmelSerial.class, "issuing command");
49
50             //at40k.iob_top(2, true).oe(false);
51             //at40k.iob_top(2, false).oe(false);
52             //at40k.iob_top(1, true).oe(false);
53
54             // this command confirmed to turn *on* led0
55             //at40k.iob_top(1, false).output(0);
56             /*
57             for(int i=0; i<20; i++) {
58                 at40k.iob_bot(i, false).output(0);
59                 at40k.iob_bot(i, true).output(0);
60             }
61             */
62
63             //System.out.println("tick");
64                 //Thread.sleep(3000);
65                 //System.out.println("tick");
66                 //at40k.cell(0x01, 0x17).xlut((byte)0x);
67
68             /*
69             System.out.println(Integer.toString(0xff & at40k.cell(0x01, 0x17).xlut(), 16));
70             System.out.println(Integer.toString(0xff & at40k.cell(0x01, 0x17).ylut(), 16));
71             at40k.cell(0x01, 0x17).ylut((byte)0xff);
72             */
73
74             //at40k.cell(0x01, 0x17).wi(L1);
75             /*
76             System.out.println("a: " + at40k.new SectorWire(true, 0, 4, 0x17).driverRight());
77             System.out.println("b: " + at40k.new SectorWire(true, 1, 4, 0x17).driverRight());
78             At40k.SectorWire h0p0 = at40k.new SectorWire(true, 0, 0, 0x17);
79             At40k.SectorWire h0p1 = at40k.new SectorWire(true, 1, 0, 0x17);
80             At40k.SectorWire h0p2 = at40k.new SectorWire(true, 2, 0, 0x17);
81             At40k.SectorWire h4p0 = at40k.new SectorWire(true, 0, 4, 0x17);
82             At40k.SectorWire h4p1 = at40k.new SectorWire(true, 1, 4, 0x17);
83             At40k.SectorWire h4p2 = at40k.new SectorWire(true, 2, 4, 0x17);
84
85             //h4p1.drives(h0p1, false);
86             //at40k.cell(0x04, 0x17).out(L1, false);
87             //at40k.cell(0x04, 0x17).h(L0, false);
88
89             for(int plane=0; plane<5; plane++) {
90                 at40k.new SectorWire(true, plane,     4, 0x17).drives(at40k.new SectorWire(true, plane,     0, 0x17), false);
91                 at40k.cell(0x04, 0x17).out(plane, false);
92                 at40k.cell(0x04, 0x17).h(plane, false);
93                 at40k.cell(0x01, 0x17).h(plane, false);
94             }
95             try { Thread.sleep(2000); } catch (Exception e) { }
96
97             int plane=0;
98             at40k.new SectorWire(true, plane, 4, 0x17).drives(at40k.new SectorWire(true, plane, 0, 0x17), true);
99             at40k.cell(0x04, 0x17).out(plane, true);
100             at40k.cell(0x04, 0x17).h(plane, true);
101             at40k.cell(0x01, 0x17).h(plane, true);
102             at40k.cell(0x01, 0x17).wi(plane);
103
104             */
105
106             /*
107             System.out.println("xlut is " + hex(at40k.cell(0x04, 0x17).xlut()));
108             System.out.println("ylut is " + hex(at40k.cell(0x04, 0x17).ylut()));
109             At40k.Cell cell = at40k.cell(0x04, 0x17);
110             //cell.xlut(0xff);
111             //cell.f(false);
112             System.out.println(cell.c());
113             cell.c(YLUT);
114             cell.ylut(0x4D);
115             cell.xlut(0x00);
116
117             cell.b(false);
118             cell.f(false);
119             //cell.t(false, false, true);
120             cell.t(false, true, false);
121             cell.out(L3, true);
122             cell.wi(L3);
123
124             cell.yo(false);
125             cell.h(L0, false);
126             cell.h(L1, false);
127             cell.h(L2, false);
128             cell.h(L3, false);
129             cell.h(L4, false);
130
131             for(int i=3; i>=1; i--) {
132                 at40k.cell(i, 0x17).yi(EAST);
133                 at40k.cell(i, 0x17).ylut(0x55);
134                 at40k.cell(i, 0x17).yo(false);
135             }
136             */
137
138             //System.out.println("reading port status: " + Integer.toString(device.readBus() & 0xff, 16));
139
140
141             // blank these out
142             /*
143             at40k.cell(23, 8).ylut(0xff);
144             at40k.cell(23, 11).ylut(0xff);
145             at40k.iob_right(8, true).enableOutput();
146             at40k.iob_right(11, true).enableOutput();
147             */
148             //for(int x=4;  x<=22; x++) swap(at40k.cell(x, 22), NW, NORTH);
149
150
151             // entry cell: just copy X->X Y->Y
152             //at40k.cell(4,23).b(false);
153             //at40k.cell(4,23).yo(false);
154             //at40k.cell(4,23).ylut(at40k.cell(4,23).xlut());
155             //at40k.cell(4,23).xo(false);
156             /*
157             at40k.cell(4,23).xlut(0x55);
158             at40k.cell(4,23).ylut(0x55);
159             */
160             /*
161             at40k.cell(4,23).xlut(0x71);
162             at40k.cell(4,23).ylut(0x44);
163             at40k.cell(4,23).c(YLUT);
164             at40k.cell(4,23).f(false);
165             at40k.cell(4,23).t(false, false, true);
166             */
167
168             //for(int x=6;  x<=23; x++) copy(at40k.cell(x, 23), NW, WEST);  // top row copies to the right
169             /*
170             copy(at40k.cell(5, 22), NW, NORTH);
171             for(int x=6;  x<=22; x++) copy(at40k.cell(x, 22), NW, WEST);  // second top row copies to the right
172             //for(int y=22; y>=10; y--) copy(at40k.cell(23, y), NW, NORTH); // right edge copies down
173             for(int y=21; y>=9;  y--) copy(at40k.cell(22, y), NW, NORTH); // second right edge copies down
174             copy(at40k.cell(23, 9), NW, WEST);                            // second output
175             */
176             /*
177             handshaker(at40k.cell(4,23));
178             at40k.cell(4,23).xi(NW);
179             at40k.cell(4,23).yi(SOUTH);
180
181             //handshaker(at40k.cell(5,23));
182             //at40k.cell(5,23).yi(NORTH);
183
184             at40k.cell(5,23).yi(NORTH);
185             at40k.cell(5,23).xlut(0x55);
186             at40k.cell(5,23).xi(SW);
187             at40k.cell(5,23).ylut(0x55);
188             at40k.cell(5,22).yi(NORTH);
189             at40k.cell(5,22).xlut(0x55);
190
191             bounce(at40k.cell(4,22));
192
193             // cell southeast of entry cell
194             at40k.cell(3,22).xi(NE);      // NW->xin
195             at40k.cell(3,22).ylut(0x33);  // xin->y
196             at40k.cell(3,22).yo(false);   // y->yout
197             copy(at40k.cell(3, 21), NW, NORTH);  // second top row copies to the right
198             copy(at40k.cell(4, 21), NW, EAST);  // second top row copies to the right
199             copy(at40k.cell(5, 21), NW, EAST);  // second top row copies to the right
200             copy(at40k.cell(6, 21), NW, EAST);  // second top row copies to the right
201             copy(at40k.cell(6, 22), NW, SOUTH);  // second top row copies to the right
202             */
203             /*
204             at40k.cell(05,22).xlut(0xff);
205             at40k.cell(05,22).ylut(0xff);
206             at40k.cell(05,22).c(XLUT);
207             at40k.cell(05,22).f(false);
208             at40k.cell(05,22).b(false);
209             at40k.cell(05,22).oe(NONE);
210             at40k.cell(05,22).v(L3, true);
211             at40k.cell(05,22).out(L3, true);
212             */
213             /*
214             at40k.cell(4,23).ylut(~0xCC);
215             at40k.cell(4,23).xlut(~0xAA);
216             at40k.cell(5,23).ylut(~0xAA);
217             at40k.cell(5,23).xlut(~0xAA);
218             for(int i=6; i<PIPELEN+2; i++) {
219                 at40k.cell(i, 23).ylut(0xAA);
220                 at40k.cell(i, 23).xlut(0xCC);
221                 at40k.cell(i, 23).yi(WEST);
222             }
223             */
224
225             System.out.println("doit");
226             if (mullers) doitx(at40k, device);
227             //System.out.println("counter");
228             //counter(at40k, device);
229
230             at40k.cell(21,15).yi(WEST);
231             at40k.cell(21,15).ylut(0xAA);
232
233             at40k.cell(22,15).yi(WEST);
234             at40k.cell(22,15).ylut(0xAA);
235
236             at40k.cell(23,15).h(3, true);
237             at40k.cell(23,15).yi(L3);
238             at40k.cell(23,15).ylut(0xAA);
239             at40k.iob_right(15, true).enableOutput(WEST);
240             //for(int x=5; x<PIPELEN; x++) {
241             //at40k.cell(x,23).hwire(L0).drives(at40k.cell(x,23).hwire(L0).east());
242             //}
243
244             /*
245             at40k.cell(22,11).ylut(0xff);
246             at40k.cell(23,11).yi(L3);
247             //at40k.cell(23,11).yi(WEST);
248             //at40k.cell(23,11).xi(L1);
249             at40k.cell(23,11).ylut(0xAA);
250             at40k.iob_right(11, true).enableOutput(WEST);
251             at40k.cell(23,11).v(L3, true);
252             at40k.cell(23,11).yo(false);
253             //at40k.flush();
254             */
255             int vx=04;
256             int vv=23;
257             /*
258             System.out.println("correct: " + at40k.cell(19,15).hwire(L3) + " drives " + at40k.cell(20,15).hwire(L3));
259             System.out.println("correct: " + at40k.cell(15,15).hwire(L3) + " drives " + at40k.cell(19,15).hwire(L3));
260             System.out.println("correct: " + at40k.cell(11,15).hwire(L3) + " drives " + at40k.cell(15,15).hwire(L3));
261             System.out.println("correct: " + at40k.cell(07,15).hwire(L3) + " drives " + at40k.cell(11,15).hwire(L3));
262
263             at40k.cell(19,15).hwire(L3).drives(at40k.cell(20,15).hwire(L3), true);
264             at40k.cell(15,15).hwire(L3).drives(at40k.cell(19,15).hwire(L3), true);
265             at40k.cell(11,15).hwire(L3).drives(at40k.cell(15,15).hwire(L3), true);
266             at40k.cell(07,15).hwire(L3).drives(at40k.cell(11,15).hwire(L3), true);
267             */
268             //at40k.cell(05,vv).xlut(0xff);
269             //at40k.cell(05,vv).ylut(0xff);
270             /*
271             at40k.cell(vx,vv).c(YLUT);
272             at40k.cell(vx,vv).f(false);
273             at40k.cell(vx,vv).b(false);
274             at40k.cell(vx,vv).oe(NONE);
275             at40k.cell(vx,vv).v(L3, true);
276             at40k.cell(vx,vv).out(L3, true);
277             */
278             /*
279             at40k.cell(vx,15).v(L3, true);
280             at40k.cell(vx,15).h(L3, true);
281             at40k.cell(vx,19).vwire(L3).drives(at40k.cell(vx,15).vwire(L3), true);
282             at40k.cell(vx,23).vwire(L3).drives(at40k.cell(vx,19).vwire(L3), true);
283             */
284
285             //at40k.cell(5,23).ylut(0x00);
286             //at40k.cell(6,22).ylut(0xff);
287             //at40k.cell(22,11).ylut(0xff);
288             /*
289             At40k.Cell cell = at40k.cell(4, 16);
290             cell.xlut(0xff);
291             cell.ylut(0xff);
292             cell.b(false);
293             cell.f(false);
294             cell.c(XLUT);
295             cell.h(L3, true);
296             cell.v(L3, true);
297             cell.out(L3, true);
298             cell.oe(NONE);
299             */
300             //scan(at40k, cell, YLUT, true);
301             //scan(at40k, cell, YLUT, false);
302
303             //device.scanFPGA(true);
304             Visualizer v = new Visualizer(at40k, device);
305             v.show();
306             v.setSize(1380, 1080);
307             At40k.Cell cell = at40k.cell(4, 23);
308             Image img = v.createImage(v.getWidth(), v.getHeight());
309             /*
310             int x = 1;
311             int y = 14;
312             cell = at40k.cell(x,y);
313             scan(at40k, cell, YLUT, true);
314             cell.c(YLUT);
315             cell.b(false);
316             cell.f(false);
317             cell.oe(NONE);
318             cell.ylut(0xff);
319             */
320             //int x = 5;
321             //int y = 11;
322
323             //selfTest(device, at40k, v);
324             System.out.println("save: " + AvrDrone.save + " of " + (AvrDrone.saveof*5));
325
326             at40k.iob_top(0, true).enableInput();
327             copy(at40k.cell(0, 23), NORTH, NORTH);
328             at40k.iob_bot(0, true).enableOutput(NORTH);
329
330             for(int i=0; i<10000; i++) {
331                 v.refresh();
332                 try { Thread.sleep(100); } catch (Exception e) { }
333             }
334             //cell.ylut(0x09);
335
336             //at40k.cell(0x01, 0x17).h(0, false);
337             //at40k.cell(0x01, 0x17).xi(NE);
338             //at40k.cell(0x01, 0x17).ylut((byte)0x55);
339
340             //at40k.cell(0x04, 0x17).xlut((byte)0x10);
341             //at40k.cell(0x04, 0x17).ylut((byte)0x10);
342             //at40k.cell(0x04, 0x17).yo(false);
343             //at40k.cell(0x04, 0x17).xo();
344
345             /*
346             at40k.cell(0x01, 0x17).xi(L0);
347             at40k.cell(0x01, 0x17).h(L0, true);
348             */
349             /*
350             at40k.cell(0x03, 0x17).xlut((byte)0x55);
351             at40k.cell(0x03, 0x17).ylut((byte)0x55);
352             at40k.cell(0x03, 0x17).yi(EAST);
353             at40k.cell(0x03, 0x17).ylut((byte)0x55);
354             at40k.cell(0x03, 0x17).yo(true);
355
356             at40k.cell(0x03, 0x17).f(false);
357             at40k.cell(0x03, 0x17).c(XLUT);
358             at40k.cell(0x03, 0x17).oe(NONE);
359             at40k.cell(0x03, 0x17).out(L0, true);
360
361             at40k.cell(0x02, 0x17).yi(EAST);
362             at40k.cell(0x02, 0x17).ylut((byte)0x55);
363             at40k.cell(0x02, 0x17).yo(false);
364
365             at40k.cell(0x01, 0x17).yi(EAST);
366             at40k.cell(0x01, 0x17).ylut((byte)0x55);
367             at40k.cell(0x01, 0x17).yo(false);
368
369             at40k.cell(0x01, 0x17).h(L0, true);
370             at40k.cell(0x01, 0x17).v(L0, false);
371             */
372             //at40k.cell(0x01, 0x17).yi(L0);
373             //at40k.cell(0x01, 0x17).xi(L0);
374             //at40k.cell(0x01, 0x17).ylut((byte)0x33);
375
376             /*
377             at40k.cell(0x03, 0x17).h(L0, true);
378             at40k.cell(0x03, 0x17).out(L0, true);
379             at40k.cell(0x03, 0x17).c(XLUT);
380             at40k.cell(0x03, 0x17).f(false);
381             */
382             /*
383             at40k.cell(0x01, 0x17).xin(4);
384             at40k.cell(0x01, 0x17).yin(4);
385             at40k.cell(0x01, 0x16).ylut((byte)0x00);
386             device.mode4(2, 0x17, 0x01, 0);
387
388             for(int i=0; i<10; i++) {
389                 Thread.sleep(3000);
390                 System.out.println("tick");
391                 //at40k.cell(0x01, 0x17).xlut((byte)0xFF);
392                 at40k.cell(0x00, 0x17).ylut((byte)0x00);
393                 device.flush();
394                 Thread.sleep(3000);
395                 System.out.println("tick");
396                 //at40k.cell(0x01, 0x17).xlut((byte)0x00);
397                 at40k.cell(0x00, 0x17).ylut((byte)0xFF);
398                 device.flush();
399             }
400             */
401
402
403             /*
404             at40k.iob_top(0, true).output(0);
405             at40k.iob_top(0, true).oe(false);
406             at40k.iob_top(0, true).pullup();
407             device.flush();
408             Thread.sleep(3000);
409
410             Log.info(AtmelSerial.class, "issuing command");
411             at40k.iob_top(1, true).pulldown();
412             device.flush();
413             */
414             Log.info(AtmelSerial.class, "done");
415             System.exit(0);
416         } catch (Exception e) { e.printStackTrace(); }
417     }
418
419     public static void scan(At40k dev, At40k.Cell cell, int source, boolean setup) {
420         if (setup) {
421             if (source != NONE) cell.c(source);
422             if (cell.b()) cell.b(false);
423             if (cell.f()) cell.f(false);
424             if (!cell.out(L3)) cell.out(L3, true);
425         }
426         if (cell.vx(L3)!=setup) cell.v(L3, setup);
427
428         At40k.SectorWire sw = cell.vwire(L3);
429         //System.out.println("wire is: " + sw);
430
431         if (sw.row > (12 & ~0x3) && sw.north()!=null && sw.north().drives(sw))
432             sw.north().drives(sw, false);
433         while(sw.row > (12 & ~0x3) && sw.south() != null) {
434             //System.out.println(sw + " -> " + sw.south());
435             if (sw.drives(sw.south())!=setup) sw.drives(sw.south(), setup);
436             sw = sw.south();
437         }
438         if (sw.row < (12 & ~0x3) && sw.south() != null && sw.south().drives(sw))
439             sw.north().drives(sw, false);
440         while(sw.row < (12 & ~0x3) && sw.north() != null) {
441             //System.out.println(sw + " -> " + sw.north());
442             if (sw.drives(sw.north())!=setup) sw.drives(sw.north(), setup);
443             sw = sw.north();
444         }
445
446         //cell = dev.cell(19, 15);
447         cell = dev.cell(cell.col, 15);
448         /*
449         System.out.println("cell is " + cell);
450         cell.xlut(0xff);
451         cell.ylut(0xff);
452         cell.b(false);
453         cell.f(false);
454         cell.c(XLUT);
455         cell.out(L3, true);
456         cell.oe(NONE);
457         */
458         if (cell.hx(L3) != setup) cell.h(L3, setup);
459         if (cell.vx(L3) != setup) cell.v(L3, setup);
460         sw = cell.hwire(L3);
461
462         if (sw.west()!=null && sw.west().drives(sw)) { sw.west().drives(sw, false); }
463         while(sw.east() != null) {
464             //System.out.println(sw + " -> " + sw.east());
465             if (sw.drives(sw.east())!=setup) sw.drives(sw.east(), setup);
466             sw = sw.east();
467         }
468
469     }
470
471     public static void copy(At40k.Cell c, int xdir, int ydir) {
472         switch(xdir) {
473             case NW: case NE: case SW: case SE: {
474                 c.xi(xdir);
475                 c.xlut(LUT_SELF);
476                 break;
477             }
478             case NORTH: case SOUTH: case EAST: case WEST: {
479                 c.yi(xdir);
480                 c.xlut(LUT_OTHER);
481                 break;
482             }
483             case NONE: break;
484             default: throw new Error();
485         }
486         switch(ydir) {
487             case NW: case NE: case SW: case SE: {
488                 c.xi(ydir);
489                 c.ylut(LUT_OTHER);
490                 break;
491             }
492             case NORTH: case SOUTH: case EAST: case WEST: {
493                 c.yi(ydir);
494                 c.ylut(LUT_SELF);
495                 break;
496             }
497             case NONE: break;
498             default: throw new Error();
499         }
500         c.xo(false);
501         c.yo(false);
502     }
503     public static String hex(int x) {
504         return Long.toString(x & 0xffffffffL, 16);
505     }
506
507     public static void handshaker(At40k.Cell cell) {
508         cell.xlut(0x22);
509         cell.ylut(0x71);
510         cell.c(XLUT);
511         cell.f(false);
512         cell.t(false, false, true);
513     }
514
515     public static class Visualizer extends Frame implements KeyListener, MouseMotionListener, MouseListener {
516         public static final int WIDTH = 40;
517         public static final int HEIGHT = 40;
518         public static final int LW = 15;
519         public static final int LH = 15;
520         public static final Color RED  = new Color(0xaa, 0x55, 0x55);
521         public static final Color BLUE = new Color(0x55, 0x55, 0xaa);
522         private final At40k dev;
523         private final AvrDrone drone;
524         int selx = -1;
525         int sely = -1;
526         public Visualizer(final At40k dev, final AvrDrone drone) {
527             this.dev = dev;
528             this.drone = drone;
529             show();
530             addMouseMotionListener(this);
531             addMouseListener(this);
532             addKeyListener(this);
533             new Thread() {
534                 public void run() {
535                     try {
536                         while(true) {
537                             Thread.sleep(500);
538                             if (!enabled) continue;
539                             /*
540                             At40k.Cell cell = dev.cell(21, 22);
541                             cell.xlut(0xff);
542                             cell.ylut(0xff);
543                             */
544                             keyPressed(null);
545                             /*
546                             cell.xlut(0x00);
547                             cell.ylut(0x00);
548                             */
549                         }
550                     } catch (Exception e) {
551                         e.printStackTrace();
552                     }
553                 }
554             }.start();
555         }
556         public boolean enabled = false;
557         public void mouseClicked(MouseEvent e) { }
558         public void mouseEntered(MouseEvent e) { }
559         public void mouseExited(MouseEvent e) { }
560         public void mouseReleased(MouseEvent e) {
561         }
562         public void keyTyped(KeyEvent k) {
563         }
564         public void keyReleased(KeyEvent k) {
565         }
566         public void keyPressed(KeyEvent keyevent) {
567             boolean scan = false;
568             switch(keyevent==null ? '_' : keyevent.getKeyChar()) {
569                 case '1': {
570                     if (selx==-1 || sely==-1) break;
571                     At40k.Cell cell = dev.cell(selx, sely);
572                     cell.xlut(0xff);
573                     cell.ylut(0xff);
574                     drawCell(getGraphics(), selx, sely);
575                     break;
576                 }
577                 case 'i': {
578                     System.out.println("interrupt_count: " + drone.readCount());
579                     break;
580                 }
581                 case 'x': {
582                     masterx+=2;
583                     if (mullers) {
584                         if (masterx <= 22) {
585                             int mx = masterx;
586                             System.out.println("low => " + mx);
587                             copy(dev.cell(mx, yofs-2), NORTH, NORTH);
588                             copy(dev.cell(mx, yofs-3), NORTH, NORTH);
589                             //dev.cell(mx, yofs-3).ylut(~dev.cell(mx, yofs-3).ylut());
590                             //dev.cell(mx, yofs-3).xlut(~dev.cell(mx, yofs-3).xlut());
591                         } else {
592                             int mx = 23-(masterx-23);
593                             System.out.println("high => " + mx);
594                             copy(dev.cell(mx, yofs), NW, NW);//NORTH, NORTH);
595                             copy(dev.cell(mx, yofs-1), NORTH, NORTH);
596                             //for(int x=mx-1; x>=1; x--)
597                             //copy(dev.cell(x, yofs), EAST, EAST);
598                             for(int y=yofs+1; y<=23; y++)
599                                 copy(dev.cell(1, y), SOUTH, SOUTH);
600                             //dev.cell(mx, yofs-1).ylut(~dev.cell(mx, yofs-1).ylut());
601                             //dev.cell(mx, yofs-1).xlut(~dev.cell(mx, yofs-1).xlut());
602                         }
603                     } else {
604                         if (masterx <= 22) {
605                             int mx = masterx;
606                             System.out.println("low => " + mx);
607                             copy(dev.cell(mx, yofs-2), SOUTH, SOUTH);
608                             copy(dev.cell(mx, yofs-3), NORTH, NORTH);
609                             dev.cell(mx, yofs-3).ylut(~dev.cell(mx, yofs-3).ylut());
610                             dev.cell(mx, yofs-3).xlut(~dev.cell(mx, yofs-3).xlut());
611                         } else {
612                             int mx = 23-(masterx-23);
613                             System.out.println("high => " + mx);
614                             copy(dev.cell(mx, yofs), SOUTH, SOUTH);
615                             /*
616                             copy(dev.cell(mx, yofs-1), NORTH, NORTH);
617                             */
618                             copy(dev.cell(mx, yofs-1), NORTH, SW);
619                             boolean left = true;
620                             At40k.Cell lc = null;
621                             for(int k=0; k<10; k++) {
622                                 int y = yofs-2-(k*2);
623                                 copy(dev.cell(left?(mx-1):mx, y),        SOUTH, left?NE:NW);
624                                 copy(lc = dev.cell(left?(mx-1):mx, y-1), NORTH, left?SE:SW); 
625                                 left = !left;
626                             }
627                             copy(lc, NORTH, NORTH);
628
629                             //for(int x=mx-1; x>=1; x--)
630                             //copy(dev.cell(x, yofs), EAST, EAST);
631                             //for(int y=yofs+1; y<=23; y++)
632                             //copy(dev.cell(1, y), SOUTH, SOUTH);
633
634                             if (mx<21) {
635                                 dev.cell(mx+2, yofs).ylut(0x00);
636                                 dev.cell(mx+2, yofs).xlut(0x00);
637                             }
638
639                             /*
640                             dev.cell(mx, yofs-1).ylut(~LUT_Z);
641                             dev.cell(mx, yofs-1).xlut(LUT_Z);
642                             loopback(dev.cell(mx, yofs-1), YLUT);
643                             */
644                             dev.cell(mx, yofs).ylut(~LUT_SELF);
645                             dev.cell(mx, yofs).xlut(~LUT_OTHER);
646                         }
647                     }
648                     break;
649                 }
650                 case ' ': {
651                     //enabled = !enabled;
652                     scan = true;
653                     break;
654                 }
655                 case '4': {
656                     //enabled = !enabled;
657                     try {
658                         for(int cap=0; cap<15; cap++) {
659                             drain(dev, drone);
660                             try { Thread.sleep(100); } catch (Exception e) { }
661                             //showit(dev, drone, this);
662                             fill(dev, drone, cap);
663                             drone.readCount();
664                             long now = System.currentTimeMillis();
665                             try { Thread.sleep(4000); } catch (Exception e) { }
666                             int count = drone.readCount();
667                             long now2 = System.currentTimeMillis();
668                             System.out.println(cap + " ,  " + (((float)count * (2*2*2*2*2*2*2*2*2*1000))/(now2-now)));
669                         }
670                     } catch (Exception e) { e.printStackTrace(); }
671                     break;
672                 }
673                 case 'C': {
674                     if (selx==-1 || sely==-1) break;
675                     At40k.Cell cell = dev.cell(selx, sely);
676                     cell.ylut(0xB2);
677                     drawCell(getGraphics(), selx, sely);
678                     break;
679                 }
680                 case '0': {
681                     if (selx==-1 || sely==-1) break;
682                     At40k.Cell cell = dev.cell(selx, sely);
683                     cell.xlut(0x00);
684                     cell.ylut(0x00);
685                     drawCell(getGraphics(), selx, sely);
686                     break;
687                 }
688             } 
689             if (!scan) return;
690             showit(dev, drone, this);
691         }
692         public void mousePressed(MouseEvent e) {
693             final At40k.Cell cell = dev.cell(selx, sely);
694             if (cell==null) return;
695             final int old = cell.c();
696             AvrDrone.ByteCallback bc = new AvrDrone.ByteCallback() {
697                     public void call(byte b) throws Exception {
698                         boolean y = (b & 0x80) != 0;
699                         //cell.c(old);
700                         Graphics g = getGraphics();
701                         g.setFont(new Font("sansserif", Font.BOLD, 14));
702                         g.setColor(Color.white);
703                         //g.drawString("X=0", left(cell) + 10, top(cell) + 20);
704                         //g.drawString("X=1", left(cell) + 10, top(cell) + 20);
705                         //g.setColor(Color.white);
706                         //g.drawString("Y=0", left(cell) + 8, top(cell) + 35);
707                         //g.drawString("Y=1", left(cell) + 8, top(cell) + 35);
708                         //g.setColor(RED);
709                         //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
710                         String v = (cell.c()==YLUT ? "Y" : cell.c()==XLUT ? "X" : "C");
711                         g.drawString(v+"="+(y?"0":"1"), left(cell) + 8, top(cell) + 35);
712                         g.setColor(BLUE);
713                         g.drawString(v+"="+(y?"1":"0"), left(cell) + 8, top(cell) + 35);
714                     } };
715             scan(dev, cell, NONE, true);
716             drone.readBus(bc);
717             //scan(dev, cell, XLUT, true);
718             //boolean x = (drone.readBus() & 0x80) != 0;
719             scan(dev, cell, NONE, false);
720         }
721
722         public void mouseMoved(MouseEvent e) {
723             int x = e.getX();
724             int y = e.getY();
725             if (selx >= 0 && selx < 24 && sely >= 0 && sely < 24) {
726                 int cx = selx;
727                 int cy = sely;
728                 At40k.Cell cell = dev.cell(cx, cy);
729                 selx = -1;
730                 sely = -1;
731                 /*
732                 drawCell(getGraphics(), cx, cy);
733                 drawSector(getGraphics(), dev.cell(cx, cy).sector());
734                 */
735             }
736             selx = (x-20)/(WIDTH+2);
737             sely = (23 - (y-20)/(HEIGHT+2))+1;
738             /*
739             At40k.Cell cell = dev.cell(selx, sely);
740             if (selx >= 0 && selx < 24 && sely >= 0 && sely < 24) {
741                 drawCell(getGraphics(), selx, sely);
742                 drawSector(getGraphics(), dev.cell(selx, sely).sector());
743             }
744             */
745         }
746         public void mouseDragged(MouseEvent e) { mousePressed(e); }
747         public void paint(Graphics g) {
748             System.out.println("paintall");
749             g.setColor(Color.white);
750             g.fillRect(0, 0, getWidth(), getHeight());
751             g.setFont(new Font("sansserif", Font.BOLD, 24));
752             for(int x=0; x<24; x++)
753                 for(int y=0; y<24; y++)
754                     drawCell(g,x,y);
755             for(int x=0; x<=23; x+=4)
756                 for(int y=23; y>=0; y-=4) 
757                     drawSector(g, dev.cell(x, y).sector());
758             /*
759             g.setColor(BLUE);
760             g.drawString("Ready", (5*(WIDTH+2))+20, 40);
761             g.setColor(RED);
762             g.drawString("Send",  (3*(WIDTH+2))+20, 40);
763             g.setColor(BLUE);
764             */
765             refresh();
766         }
767         public void refresh() {
768             Graphics g = getGraphics();
769             /*
770             int data = drone.readBus() & 0xff;
771             for(int i=0; i<8; i++) {
772                 g.setColor((data & (1<<i))==0 ? Color.black : Color.green);
773                 g.drawString("D"+i,  (24*(WIDTH+2))+20, ((23-(i+7))*(HEIGHT+2))+60-HEIGHT/2);
774             }
775             */
776         }
777         public static int left(At40k.Cell cell) { return (cell.col)   *(WIDTH+2)+20; }
778         public static int top(At40k.Cell cell)  { return (23-cell.row)*(HEIGHT+2)+60; }
779         public void drawSector(Graphics g, At40k.Sector sector) {
780             g.setColor(Color.gray);
781             ((Graphics2D)g).setStroke(new BasicStroke(1));
782             int px = ((sector.col)*(WIDTH+2))+20-1;
783             int py = ((23-(sector.row+3))*(HEIGHT+2))+60-1;
784             g.drawRect(px, py, (WIDTH+2)*4+2, (HEIGHT+2)*4+2);
785             /*
786             for(int dir=0; dir<2; dir++) {
787                 boolean h = dir==0;
788                 for(int y=h?sector.row:sector.col; y<(h?sector.row+4:sector.col+4); y++)
789                     for(int plane=0; plane<=4; plane++) {
790                         At40k.Cell cell      = h ? dev.cell(sector.col,   y) : dev.cell(y, sector.row);
791                         At40k.Cell cell_east = h ? dev.cell(sector.col-1, y) : dev.cell(y, sector.row-1);
792                         At40k.Cell cell_west = h ? dev.cell(sector.col+4, y) : dev.cell(y, sector.row+4);
793                         boolean draw = false;
794                         if (h) {
795                             if (cell_east!=null &&
796                                 (cell_east.hwire(plane).drives(cell.hwire(plane)) ||
797                                  cell_east.hwire(plane).drives(cell.hwire(plane))))
798                                 draw = true;
799                             if (cell_west!=null &&
800                                 (cell_west.hwire(plane).drives(cell.hwire(plane)) ||
801                                  cell_west.hwire(plane).drives(cell.hwire(plane))))
802                                 draw = true;
803                         } else {
804                             if (cell_east!=null &&
805                                 (cell_east.vwire(plane).drives(cell.vwire(plane)) ||
806                                  cell_east.vwire(plane).drives(cell.vwire(plane))))
807                                 draw = true;
808                             if (cell_west!=null &&
809                                 (cell_west.vwire(plane).drives(cell.vwire(plane)) ||
810                                  cell_west.vwire(plane).drives(cell.vwire(plane))))
811                                 draw = true;
812                         }
813                         if (!draw)
814                             for(int x=h?sector.col:sector.row; x<(h?sector.col+4:sector.row+4); x++)
815                                 if (((h ? dev.cell(x,y).hx(plane) : dev.cell(y,x).vx(plane))) ||
816                                     (h?dev.cell(x,y).out(plane):dev.cell(y,x).out(plane)))
817                                     draw = true;
818                         if (draw) {
819                             g.setColor(new Color(0xff, 0x00, 0xff));
820                             if (h) {
821                                 g.drawLine(left(cell),
822                                            top(cell)+3,
823                                            left(cell) + 4*(WIDTH+2),
824                                            top(cell)+3
825                                            );
826                             } else {
827                                 g.drawLine(left(cell)+3,
828                                            top(cell) + (HEIGHT+2),
829                                            left(cell)+3,
830                                            top(cell) - 3*(HEIGHT+2)
831                                            );
832                             }
833                         }
834                     }
835             }
836             */
837         }
838         public void drawCell(Graphics g, int cx, int cy) {
839             int x = (cx*(WIDTH+2))+20;
840             int y = ((23-cy)*(HEIGHT+2))+60;
841             if (g.getClipBounds() != null && !g.getClipBounds().intersects(new Rectangle(x, y, x+WIDTH, y+HEIGHT))) return;
842             drawCell(g, cx, cy, Color.white);
843         }
844         public void drawCell(Graphics g, int cx, int cy, Color bg) {
845             int x = (cx*(WIDTH+2))+20;
846             int y = ((23-cy)*(HEIGHT+2))+60;
847
848             //System.out.println("drawcell " + cx + "," + cy);
849             At40k.Cell cell = dev.cell(cx, cy);
850             g.setColor(bg);
851             g.fillRect(x, y, WIDTH, HEIGHT);
852
853             g.setColor((selx==cx && sely==cy) ? Color.red : Color.black);
854             g.drawRect(x, y, WIDTH, HEIGHT);
855
856             //g.setColor((selx==cx && sely==cy) ? Color.red : Color.gray);
857             //g.drawRect(x+(WIDTH-(LW*2))/2-1,    y+(HEIGHT-LW)/2-1, LW*2+1, LH+1);
858
859             //g.setColor(RED);
860             //g.fillRect(x+(WIDTH-(LW*2))/2,    y+(HEIGHT-LW)/2, LW,   LH);
861             //g.setColor(Color.white);
862             //g.drawString("1", x+(WIDTH-(LW*2))/2,    y+(HEIGHT-LW)/2);
863
864             //g.setColor(BLUE);
865             //g.fillRect(x+(WIDTH-(LW*2))/2+LW, y+(HEIGHT-LW)/2, LW,   LH);
866             //g.setColor(Color.white);
867             //g.drawString("0", x+(WIDTH-(LW*2))/2+LW,    y+(HEIGHT-LW)/2);
868
869             /*
870               g.setColor(BLUE);
871             ((Graphics2D)g).setStroke(new BasicStroke((float)1));
872             switch(cell.yi()) {
873                 case NORTH: g.drawLine(x+WIDTH/2+5,  y-10,        x+WIDTH/2+5, y+HEIGHT/2); break;
874                 case SOUTH: g.drawLine(x+WIDTH/2-5,  y+HEIGHT+10, x+WIDTH/2-5, y+HEIGHT/2); break;
875                 case EAST:  g.drawLine(x+WIDTH+10, y+HEIGHT/2+5,  x+WIDTH/2, y+HEIGHT/2+5); break;
876                 case WEST:  g.drawLine(x-10,       y+HEIGHT/2-5,  x+WIDTH/2, y+HEIGHT/2-5); break;
877                 case NONE:  break;
878             }
879             g.setColor(RED);
880             ((Graphics2D)g).setStroke(new BasicStroke((float)1));
881             switch(cell.xi()) {
882                 case NW: g.drawLine(x-10+3,       y-10,        x+WIDTH/2+3, y+HEIGHT/2); break;
883                 case SW: g.drawLine(x-10-3,       y+HEIGHT+10, x+WIDTH/2-3, y+HEIGHT/2); break;
884                 case NE: g.drawLine(x+WIDTH+10+3, y-10,        x+WIDTH/2+3, y+HEIGHT/2); break;
885                 case SE: g.drawLine(x+WIDTH+10-3, y+HEIGHT+10, x+WIDTH/2-3, y+HEIGHT/2); break;
886                 case NONE:  break;
887             }
888             ((Graphics2D)g).setStroke(new BasicStroke(1));
889             */
890             /*
891             if (selx==cx && sely==cy) {
892                 int xp = 23 * (WIDTH+2) + 100;
893                 int yp = 100;
894                 g.setColor(Color.white);
895                 g.fillRect(xp, yp, 300, 1000);
896                 g.setColor(Color.black);
897                 g.drawString("Cell " + cx + "," + cy,       xp, (yp+=15));
898                 //g.drawString("X-Lut: " + bin8(cell.xlut()), xp, (yp+=15));
899                 g.drawString("X-Lut: " + cell.printXLut(), xp, (yp+=15));
900                 //g.drawString("Y-Lut: " + bin8(cell.ylut()), xp, (yp+=15));
901                 g.drawString("Y-Lut: " + cell.printYLutX(), xp, (yp+=15));
902             }
903             */
904             if ((cell.ylut()&0xff)==0xff && (cell.xlut()&0xff)==0xff) {
905                 g.setColor(new Color(0x00, 0x00, 0xff));
906                 g.drawString("1", left(cell) + 12, top(cell) + 30);
907             }
908             if ((cell.ylut()&0xff)==0x00 && (cell.xlut()&0xff)==0x00) {
909                 g.setColor(new Color(0x00, 0x00, 0xff));
910                 g.drawString("0", left(cell) + 12, top(cell) + 30);
911             }
912             if ((cell.ylut()&0xff)==0xB2) {
913                 //System.out.println("muller @ " + cell);
914                 //g.setColor(RED);
915                 //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
916                 g.setColor(new Color(0x00, 0xaa, 0x00));
917                 g.drawString("C", left(cell) + 12, top(cell) + 30);
918             }
919
920         }
921     }
922
923     private static String pad(int i, String s) { if (s.length()>i) return s; return "0"+pad((i-1),s); }
924     private static String bin8(byte b) {
925         int n = b & 0xff;
926         String ret = "";
927         for(int i=7; i>=0; i--)
928             ret += (n & (1<<i))==0 ? "0" : "1";
929         return ret;
930     }
931
932     public static void selfTest(AvrDrone device, At40k at40k, Visualizer v) {
933         /*
934             int fail = 0;
935             long now = System.currentTimeMillis();
936             for(int x=0; x<24; x++)
937                 for(int y=0; y<24; y++) {
938                     At40k.Cell cell = at40k.cell(x,y);
939                     scan(at40k, cell, YLUT, true);
940                     //v.paint(img.getGraphics());
941                     //v.getGraphics().drawImage(img, 0, 0, null);
942                     cell.ylut(0xff);
943                     boolean a = (device.readBus() & 0x80)!=0;
944                     cell.ylut(0x00);
945                     boolean b = (device.readBus() & 0x80)!=0;
946                     if (a & !b) {
947                         //System.out.println("pass " + x+","+y);
948                         Graphics g = v.getGraphics();
949                         g.setColor(Color.green);
950                         g.drawString("pass", v.left(cell) + 10, v.top(cell) + 20);
951                     } else {
952                         System.out.println("FAIL!!!! " + x+","+y+" => " + a + " " + b);
953                         fail++;
954                         Graphics g = v.getGraphics();
955                         g.setColor(Color.red);
956                         g.drawString("FAIL", v.left(cell) + 10, v.top(cell) + 20);
957                     }
958                     scan(at40k, cell, YLUT, false);
959                 }
960
961             System.out.println("failures: " + fail);
962             System.out.println("scan time: " + (System.currentTimeMillis()-now) + "ms");
963         */
964     }
965     
966     public static void bounce(At40k.Cell cell, int xi, int yi) {
967         cell.xlut((byte)0xCC);
968         cell.ylut((byte)0xCC);
969         cell.xi(xi);
970         cell.yi(yi);
971         cell.xo(false);
972         cell.yo(false);
973     }
974     public static void muller(At40k.Cell cell, int xi, int yi) {
975         cell.ylut(0xB2);
976         cell.c(YLUT);
977         cell.f(false);
978         cell.t(false, false, true);
979         cell.xi(xi);
980         cell.yi(yi);
981         cell.yo(false);
982         cell.xo(false);
983     }
984
985     /** watches for a rising/falling edge on Yin, emits a pulse on Xout */
986     public static void pulse_detect(At40k.Cell c, int in, boolean falling) {
987         c.ylut(0x00);
988         c.xlut(0x00);
989         switch(in) {
990             case NW: case NE: case SW: case SE: {
991                 c.xi(in);
992                 loopback(c, XLUT);
993                 if (!falling) c.ylut(lutSwap(0x0C)); /* x & !z */
994                 else          c.ylut(lutSwap(0x30)); /* !x & z */
995                 c.xlut(LUT_SELF);
996                 break;
997             }
998             case NORTH: case SOUTH: case EAST: case WEST: {
999                 c.yi(in);
1000                 loopback(c, YLUT);
1001                 if (!falling) c.xlut(0x0C); /* y & !z */
1002                 else          c.xlut(0x30); /* !y & z */
1003                 c.ylut(LUT_SELF);
1004                 break;
1005             }
1006             default: throw new Error();
1007         }
1008     }
1009
1010     /** watches for a pulse on Xin, copies value of Yin */
1011     public static void pulse_copy(At40k.Cell cell, int xi, int yi, boolean invert) {
1012         loopback(cell, YLUT);
1013         if (!invert) cell.ylut(0xB8);   /* yo = x ?  yi : z => 1011 1000 */
1014         else         cell.ylut(0x74);   /* yo = x ? !yi : z => 0111 0100 */
1015         if (!invert) cell.xlut(lutSwap(0xB8));   /* yo = x ?  yi : z => 1011 1000 */
1016         else         cell.xlut(lutSwap(0x74));   /* yo = x ? !yi : z => 0111 0100 */
1017         cell.xi(xi);
1018         cell.yi(yi);
1019     }
1020
1021     public static void loopback(At40k.Cell cell, int cin) {
1022         cell.f(false);
1023         cell.b(false);
1024         cell.t(false, false, true);
1025         cell.yo(false);
1026         cell.xo(false);
1027         cell.c(cin);
1028     }
1029     public static void doit(At40k at40k, AvrDrone device) throws Exception {
1030
1031         At40k.Cell led = at40k.cell(1, 23);
1032         led.v(L2, true);
1033         led.h(L2, false);
1034         led.yi(L2);
1035         led.ylut(~LUT_SELF);
1036         led.xlut(LUT_SELF);
1037         led.yo(false);
1038
1039         At40k.Cell c = at40k.cell(1, 22);
1040         c.out(L1, true);
1041         c.out(L0, true);
1042         c.oe(V4);
1043         c.ylut(0xff);
1044         c.h(L1, true);
1045         c.h(L0, false);
1046
1047         c.v(L0, /*false*/true);
1048
1049         c.v(L1, true);
1050         c.f(false);
1051         c.b(false);
1052         c.c(YLUT);
1053
1054         for(int i=0; i<4; i++) at40k.cell(i, 20).h(L0, false);
1055         At40k.Cell z = at40k.cell(1, 20);
1056         z.out(L0, true);
1057         z.xlut(0xff);
1058         z.c(XLUT);
1059         z.yi(L0);
1060         z.ylut(~LUT_SELF);
1061         z.v(L0, true);
1062         //z.h(L0, true);
1063         z.h(L0, false);
1064         z.f(false);
1065         z.b(false);
1066         z.hwire(L0).east().drives(z.hwire(L0), false);
1067         z.hwire(L1).east().drives(z.hwire(L1), false);
1068         z.vwire(L0).south().drives(z.vwire(L0), false);
1069         z.vwire(L1).south().drives(z.vwire(L1), false);
1070         z.oe(H4);
1071
1072         z = at40k.cell(0, 20);
1073         z.oe(NONE);
1074         z.out(L0, true);
1075         z.out(L1, true);
1076         z.out(L2, true);
1077         //z.out(L3, true);
1078         z.out(L4, true);
1079         z.h(L0, true);
1080         z.h(L1, true);
1081         z.h(L2, true);
1082         //z.h(L3, true);
1083         z.h(L4, true);
1084         z.f(false);
1085         z.b(false);
1086         z.yi(EAST);
1087         z.ylut(LUT_SELF);
1088         z.c(YLUT);
1089
1090         for(int y=20; y<=22; y++)
1091             for(int x=2; x<=5; x++) {
1092                 c = at40k.cell(x, y);
1093                 copy(c, NW, WEST);
1094             }
1095
1096         //c = at40k.cell(2, 22);
1097         //c.h(L0, true);
1098         //c.yi(L0);
1099
1100         c = at40k.cell(1, 21);
1101         c.v(L0, true);
1102         c.v(L2, true);
1103         c.yi(L0);
1104         c.out(L2, true);
1105         c.ylut(LUT_SELF);
1106         c.c(YLUT);
1107         c.b(false);
1108         c.f(false);
1109         c.oe(NONE);
1110         c.yo(false);
1111
1112         
1113
1114         c = at40k.cell(13, 22);
1115         c.xlut(LUT_OTHER | 0xF0);
1116         c.c(XLUT);
1117         c.t(false, false, true);
1118         c.b(false);
1119         c.f(false);
1120         c.ylut(0xF0);
1121         c.yi(EAST);
1122         c.yo(false);
1123         /*
1124         // this gate detects a rising edge on its Xin (delayed copy on Yin); when viewed, it inverts its state
1125         c = at40k.cell(14, 22);
1126         c.ylut(0x00);
1127         c.c(XLUT);
1128         c.f(false);
1129         c.b(false);
1130         c.t(false, false, true);
1131         c.xi(SE);
1132         c.yi(SOUTH);
1133         c.yo(false);
1134         c.xo(false);
1135         c.ylut(0xA6); // (x & !z) ? ~y : y
1136         c.xlut(LUT_SELF); 
1137
1138         c = at40k.cell(14, 20);
1139         c.ylut(LUT_OTHER);
1140         c.xi(NE);
1141         c = at40k.cell(14, 21);
1142         c.ylut(LUT_SELF);
1143         c.xi(SOUTH);
1144
1145         c = at40k.cell(13, 22);
1146         c.xlut(0x00);
1147         c.xlut(LUT_OTHER);// | 0xF0);
1148 */
1149         //c = at40k.cell(13, 22);
1150         //copy(c, NW, EAST);
1151         /*
1152         c.ylut(0x00);
1153         c.c(YLUT);
1154         c.f(false);
1155         c.b(false);
1156         c.t(false, false, true);
1157         c.xi(SE);
1158         c.yi(NORTH);
1159         c.yo(false);
1160         c.xo(false);
1161         c.ylut(0x54);  // (x || z) & !y
1162         */
1163
1164         /*        
1165         c = at40k.cell(2, 21);
1166         c.ylut(0x00);
1167         c.c(YLUT);
1168         c.f(false);
1169         c.b(false);
1170         c.t(false, false, true);
1171         c.xi(SE);
1172         c.yi(WEST);
1173         c.yo(false);
1174         c.xo(false);
1175         c.ylut(0xE8);
1176  
1177        //at40k.cell(2, 21).xlut(0xF0);
1178
1179         at40k.cell(3, 22).ylut(LUT_OTHER);
1180         at40k.cell(3, 22).xi(SW);
1181         */
1182         //at40k.iob_top(5, true).enableOutput(SOUTH);
1183         //at40k.iob_top(5, false).enableOutput(SE);
1184     }
1185
1186     public static int yofs = mullers ? 19 : 22;
1187     public static void counter(At40k at40k, AvrDrone device) throws Exception {
1188         // watch for rising edge from south, emit pulse on Xout (to NE)
1189         //copy(at40k.cell(16,23), SW, WEST);
1190         
1191         for(int x=22; x>=1; x-=2) {
1192             pulse_detect(at40k.cell(x, yofs), SE,      false);
1193             pulse_detect(at40k.cell(x, yofs-1), EAST,    true);
1194             pulse_copy(at40k.cell(x-1, yofs), SE, SOUTH, false);
1195             pulse_copy(at40k.cell(x-1, yofs-1), NE, NORTH, true);
1196
1197             //pulse_detect(at40k.cell(15, 22), NORTH, false);
1198             //pulse_detect(at40k.cell(16, 22), NW,    true);
1199             //pulse_copy(at40k.cell(16, 21), NW, WEST, false);
1200             //pulse_copy(at40k.cell(15, 21), NE, EAST, true);
1201         }
1202         for(int x=23; x>1; x-=2) {
1203             pulse_detect(at40k.cell(x-1, yofs-2), SW,    false);
1204             pulse_detect(at40k.cell(x-1, yofs-3), WEST,  true);
1205             pulse_copy(at40k.cell(x, yofs-2), SW, SOUTH, false);
1206             pulse_copy(at40k.cell(x, yofs-3), NW, NORTH, true);
1207
1208             //pulse_detect(at40k.cell(15, 22), NORTH, false);
1209             //pulse_detect(at40k.cell(16, 22), NW,    true);
1210             //pulse_copy(at40k.cell(16, 21), NW, WEST, false);
1211             //pulse_copy(at40k.cell(15, 21), NE, EAST, true);
1212         }
1213         copy(at40k.cell(1, yofs-2), SOUTH, SOUTH);
1214         copy(at40k.cell(1, yofs-3), NORTH, NORTH);
1215         at40k.cell(1, yofs-3).ylut(~at40k.cell(1, yofs-3).ylut());
1216         at40k.cell(1, yofs-3).xlut(~at40k.cell(1, yofs-3).xlut());
1217
1218         copy(at40k.cell(23, yofs), SOUTH, SOUTH);
1219         copy(at40k.cell(23, yofs-1), SOUTH, SOUTH);
1220
1221         for(int i=23; i>yofs; i--) copy(at40k.cell(1, i), SOUTH, SOUTH);
1222
1223         //at40k.iob_top(1, true).slew(SLOW);
1224         //at40k.iob_top(1, false).slew(SLOW);
1225
1226     }
1227     public static void fill(At40k at40k, AvrDrone device, int num) throws Exception {
1228         //muller(at40k.cell(PIPELEN,22), NE, WEST);
1229         At40k.Cell a = at40k.cell(10,22);
1230         At40k.Cell b = at40k.cell(11,22);
1231         a.ylut(0x00);
1232         for(int i=0; i<num; i++) {
1233             //System.out.println(i);
1234             b.lut(0xff, 0xff);
1235             device.flush();
1236             try { Thread.sleep(1); } catch (Exception e) { }
1237             b.lut(0x00, 0x00);
1238             device.flush();
1239             try { Thread.sleep(1); } catch (Exception e) { }
1240         }
1241         b.ylut(0xB2);
1242         a.ylut(0xB2);
1243     }
1244     public static void showit(At40k dev, AvrDrone drone, final Visualizer vis) {
1245         final long then = System.currentTimeMillis();
1246         final Graphics g = vis.getGraphics();
1247         g.setFont(new Font("sansserif", Font.BOLD, 24));
1248         final Color red = new Color(0xff, 0x99, 0x99);
1249         final Color green = new Color(0x99, 0xff, 0x99);
1250         for(int xx=0; xx<=22; xx++) {
1251             for(int yy=23; yy>=0; yy--) {
1252                 //for(int xx=5; xx<=PIPELEN-1; xx++) {
1253                 //for(int yy=21; yy<=22; yy++) {
1254                 final int x = xx;
1255                 final int y = yy;
1256                 final At40k.Cell cell = dev.cell(x, y);
1257                 if ((cell.ylut()&0xff)!=0xB2) continue;
1258                 AvrDrone.ByteCallback bc = new AvrDrone.ByteCallback() {
1259                         public void call(byte b) throws Exception {
1260                             boolean v = (b & 0x80) != 0;
1261                             vis.drawCell(g, x, y, v?red:green);
1262                             //if (x==PIPELEN-1 && y==22) System.out.println("time: " + (System.currentTimeMillis()-then));
1263                         }
1264                     };
1265                 scan(dev, cell, NONE, true);
1266                 drone.readBus(bc);
1267                 //scan(dev, cell, YLUT, false);
1268                 cell.v(L3, false);
1269                 dev.cell(x, 15).h(L3, false);
1270                 dev.cell(x, 15).v(L3, false);
1271             }
1272         }
1273     }
1274     public static void drain(At40k at40k, AvrDrone device) throws Exception {
1275         At40k.Cell a = at40k.cell(10,22);
1276         At40k.Cell b = at40k.cell(11,22);
1277         a.lut(0x00, 0x00);
1278         b.lut(0x00, 0x00);
1279         for(int i=0; i<30; i++) {
1280             //System.out.println(i);
1281             a.lut(0xff, 0xff);
1282             device.flush();
1283             try { Thread.sleep(1); } catch (Exception e) { }
1284             a.lut(0x00, 0x00);
1285             device.flush();
1286             try { Thread.sleep(1); } catch (Exception e) { }
1287         }
1288         b.ylut(0xB2);
1289         a.ylut(0xB2);
1290     }
1291     public static void doitx(At40k at40k, AvrDrone device) throws Exception {
1292         for(int i=5; i<PIPELEN+1; i++) bounce(at40k.cell(i, 23), SE,                     SOUTH);
1293         for(int x=5; x<PIPELEN;   x++) muller(at40k.cell(x, 22), x==PIPELEN-1 ? SE : NE, WEST);
1294         
1295         bounce(at40k.cell(PIPELEN,  21), NW, WEST);
1296         
1297         for(int x=5; x<PIPELEN;   x++) muller(at40k.cell(x, 21), SW,                     x==PIPELEN-1 ? NORTH : EAST);
1298         for(int x=4; x<PIPELEN+1; x++) bounce(at40k.cell(x, 20), NW,                     NORTH);
1299         
1300         bounce(at40k.cell(4, 22), SE, EAST);
1301         //muller(at40k.cell(4PIPELEN-1,21), SW, NORTH);
1302         
1303         //muller(at40k.cell(4,22), NE, WEST);
1304         //at40k.cell(4,22).ylut(0xEE);
1305         muller(at40k.cell(5, 22), NE, SOUTH);
1306         muller(at40k.cell(5, 21), NW, EAST);
1307         /*
1308         for(int x=4; x>=0; x--) {
1309             at40k.cell(x, 21).ylut(0xAA);
1310             at40k.cell(x, 21).yi(EAST);
1311             at40k.cell(x, 21).yo(false);
1312         }
1313
1314         at40k.cell(0, 22).ylut(0xAA);
1315         at40k.cell(0, 22).yi(SOUTH);
1316         at40k.cell(0, 22).yo(false);
1317
1318         at40k.cell(0, 23).ylut(~0xAA);
1319         at40k.cell(0, 23).xlut(~0xcc);
1320         at40k.cell(0, 23).yi(SOUTH);
1321         at40k.cell(0, 23).yo(false);
1322         */
1323         for(int x=3; x<=23; x+=2) {
1324             pulse_detect(at40k.cell(x-1, 19), SW,    false);
1325             pulse_detect(at40k.cell(x-1, 18), WEST,  true);
1326             pulse_copy(at40k.cell(x, 19), SW, SOUTH, false);
1327             pulse_copy(at40k.cell(x, 18), NW, NORTH, true);
1328
1329             if (x<17) {
1330                 pulse_detect(at40k.cell(x-1, 16), SW,    false);
1331                 pulse_detect(at40k.cell(x-1, 15), WEST,  true);
1332                 pulse_copy(at40k.cell(x, 16), SW, SOUTH, false);
1333                 pulse_copy(at40k.cell(x, 15), NW, NORTH, true);
1334             }
1335             //pulse_detect(at40k.cell(15, 22), NORTH, false);
1336             //pulse_detect(at40k.cell(16, 22), NW,    true);
1337             //pulse_copy(at40k.cell(16, 21), NW, WEST, false);
1338             //pulse_copy(at40k.cell(15, 21), NE, EAST, true);
1339         }
1340         for(int x=14; x>=1; x--)
1341             copy(at40k.cell(x, 17), EAST, EAST);
1342         for(int x=4; x>=0; x--)
1343             copy(at40k.cell(x, 21), EAST, EAST);
1344         copy(at40k.cell(13, 17), SOUTH, SOUTH);
1345
1346         copy(at40k.cell(0, 20), NORTH, NORTH);
1347         copy(at40k.cell(0, 19), NORTH, NORTH);
1348         copy(at40k.cell(0, 18), NORTH, NORTH);
1349         copy(at40k.cell(0, 17), NORTH, NORTH);
1350         copy(at40k.cell(0, 16), NORTH, NORTH);
1351         copy(at40k.cell(1, 16), WEST, WEST);
1352         copy(at40k.cell(1, 15), NORTH, NORTH);
1353
1354         copy(at40k.cell(1, 20), SOUTH, SOUTH);
1355         copy(at40k.cell(1, 19), SOUTH, SOUTH);
1356         copy(at40k.cell(1, 18), SOUTH, SOUTH);
1357
1358         for(int y=20; y<=23; y++)
1359             copy(at40k.cell(23, y), SOUTH, SOUTH);
1360
1361
1362         //for(int x=19; x<=23; x++)
1363         //copy(at40k.cell(x, 0), WEST, WEST);
1364         //copy(at40k.cell(18, 19), NW, NW);
1365         //at40k.iob_top(5, true).enableOutput(SOUTH);
1366         //at40k.iob_top(5, false).enableOutput(SOUTH);
1367     }
1368 }