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 edu.berkeley.obits.device.atmel.*;
5 import java.awt.*;
6 import java.awt.event.*;
7 import java.awt.color.*;
8 import org.ibex.util.*;
9 import java.io.*;
10 import java.util.*;
11 import gnu.io.*;
12
13 public class AtmelSerial {
14
15     public static SerialPort detectObitsPort() throws Exception {
16         Enumeration e = CommPortIdentifier.getPortIdentifiers();
17         while(e.hasMoreElements()) {
18             CommPortIdentifier cpi = (CommPortIdentifier)e.nextElement();
19             Log.info(AtmelSerial.class, "trying " + cpi.getName());
20             if (cpi.getName().startsWith("/dev/cu.usbserial-")) return new RXTXPort(cpi.getName());
21             if (cpi.getName().startsWith("/dev/ttyS0")) return new RXTXPort(cpi.getName());
22         }
23         Log.info(AtmelSerial.class, "returning null...");
24         return null;
25     }
26     public static int PIPELEN=20;
27     public static void main(String[] s) throws Exception {
28         AvrDrone device = new AvrDrone(detectObitsPort());
29         At40k at40k = new At40k.At40k10(device);
30         int count = 0;
31         try {
32             long begin = System.currentTimeMillis();
33             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
34             for(String str = br.readLine(); str != null; str = br.readLine()) {
35                 long foo = Long.parseLong(str, 16);
36                 device.mode4((int)(foo >> 24), (int)(foo >> 16), (int)(foo >>  8), (int)(foo >>  0));
37                 count++;
38                 if (count % 100 == 0) Log.info(AtmelSerial.class, "wrote " + count + " configuration octets");
39             }
40             device.flush();
41             long end = System.currentTimeMillis();
42             Log.info(AtmelSerial.class, "finished in " + ((end-begin)/1000) + "s");
43             Thread.sleep(1000);
44             Log.info(AtmelSerial.class, "issuing command");
45
46             //at40k.iob_top(2, true).oe(false);
47             //at40k.iob_top(2, false).oe(false);
48             //at40k.iob_top(1, true).oe(false);
49
50             // this command confirmed to turn *on* led0
51             //at40k.iob_top(1, false).output(0);
52             /*
53             for(int i=0; i<20; i++) {
54                 at40k.iob_bot(i, false).output(0);
55                 at40k.iob_bot(i, true).output(0);
56             }
57             */
58
59             //System.out.println("tick");
60                 //Thread.sleep(3000);
61                 //System.out.println("tick");
62                 //at40k.cell(0x01, 0x17).xlut((byte)0x);
63
64             /*
65             System.out.println(Integer.toString(0xff & at40k.cell(0x01, 0x17).xlut(), 16));
66             System.out.println(Integer.toString(0xff & at40k.cell(0x01, 0x17).ylut(), 16));
67             at40k.cell(0x01, 0x17).ylut((byte)0xff);
68             */
69
70             //at40k.cell(0x01, 0x17).wi(L1);
71             /*
72             System.out.println("a: " + at40k.new SectorWire(true, 0, 4, 0x17).driverRight());
73             System.out.println("b: " + at40k.new SectorWire(true, 1, 4, 0x17).driverRight());
74             At40k.SectorWire h0p0 = at40k.new SectorWire(true, 0, 0, 0x17);
75             At40k.SectorWire h0p1 = at40k.new SectorWire(true, 1, 0, 0x17);
76             At40k.SectorWire h0p2 = at40k.new SectorWire(true, 2, 0, 0x17);
77             At40k.SectorWire h4p0 = at40k.new SectorWire(true, 0, 4, 0x17);
78             At40k.SectorWire h4p1 = at40k.new SectorWire(true, 1, 4, 0x17);
79             At40k.SectorWire h4p2 = at40k.new SectorWire(true, 2, 4, 0x17);
80
81             //h4p1.drives(h0p1, false);
82             //at40k.cell(0x04, 0x17).out(L1, false);
83             //at40k.cell(0x04, 0x17).h(L0, false);
84
85             for(int plane=0; plane<5; plane++) {
86                 at40k.new SectorWire(true, plane,     4, 0x17).drives(at40k.new SectorWire(true, plane,     0, 0x17), false);
87                 at40k.cell(0x04, 0x17).out(plane, false);
88                 at40k.cell(0x04, 0x17).h(plane, false);
89                 at40k.cell(0x01, 0x17).h(plane, false);
90             }
91             try { Thread.sleep(2000); } catch (Exception e) { }
92
93             int plane=0;
94             at40k.new SectorWire(true, plane, 4, 0x17).drives(at40k.new SectorWire(true, plane, 0, 0x17), true);
95             at40k.cell(0x04, 0x17).out(plane, true);
96             at40k.cell(0x04, 0x17).h(plane, true);
97             at40k.cell(0x01, 0x17).h(plane, true);
98             at40k.cell(0x01, 0x17).wi(plane);
99
100             */
101
102             /*
103             System.out.println("xlut is " + hex(at40k.cell(0x04, 0x17).xlut()));
104             System.out.println("ylut is " + hex(at40k.cell(0x04, 0x17).ylut()));
105             At40k.Cell cell = at40k.cell(0x04, 0x17);
106             //cell.xlut(0xff);
107             //cell.f(false);
108             System.out.println(cell.c());
109             cell.c(YLUT);
110             cell.ylut(0x4D);
111             cell.xlut(0x00);
112
113             cell.b(false);
114             cell.f(false);
115             //cell.t(false, false, true);
116             cell.t(false, true, false);
117             cell.out(L3, true);
118             cell.wi(L3);
119
120             cell.yo(false);
121             cell.h(L0, false);
122             cell.h(L1, false);
123             cell.h(L2, false);
124             cell.h(L3, false);
125             cell.h(L4, false);
126
127             for(int i=3; i>=1; i--) {
128                 at40k.cell(i, 0x17).yi(EAST);
129                 at40k.cell(i, 0x17).ylut(0x55);
130                 at40k.cell(i, 0x17).yo(false);
131             }
132             */
133
134             //System.out.println("reading port status: " + Integer.toString(device.readBus() & 0xff, 16));
135
136
137             // blank these out
138             /*
139             at40k.cell(23, 8).ylut(0xff);
140             at40k.cell(23, 11).ylut(0xff);
141             at40k.iob_right(8, true).enableOutput();
142             at40k.iob_right(11, true).enableOutput();
143             */
144             //for(int x=4;  x<=22; x++) swap(at40k.cell(x, 22), NW, NORTH);
145
146
147             // entry cell: just copy X->X Y->Y
148             //at40k.cell(4,23).b(false);
149             //at40k.cell(4,23).yo(false);
150             //at40k.cell(4,23).ylut(at40k.cell(4,23).xlut());
151             //at40k.cell(4,23).xo(false);
152             /*
153             at40k.cell(4,23).xlut(0x55);
154             at40k.cell(4,23).ylut(0x55);
155             */
156             /*
157             at40k.cell(4,23).xlut(0x71);
158             at40k.cell(4,23).ylut(0x44);
159             at40k.cell(4,23).c(YLUT);
160             at40k.cell(4,23).f(false);
161             at40k.cell(4,23).t(false, false, true);
162             */
163
164             //for(int x=6;  x<=23; x++) copy(at40k.cell(x, 23), NW, WEST);  // top row copies to the right
165             /*
166             copy(at40k.cell(5, 22), NW, NORTH);
167             for(int x=6;  x<=22; x++) copy(at40k.cell(x, 22), NW, WEST);  // second top row copies to the right
168             //for(int y=22; y>=10; y--) copy(at40k.cell(23, y), NW, NORTH); // right edge copies down
169             for(int y=21; y>=9;  y--) copy(at40k.cell(22, y), NW, NORTH); // second right edge copies down
170             copy(at40k.cell(23, 9), NW, WEST);                            // second output
171             */
172             /*
173             handshaker(at40k.cell(4,23));
174             at40k.cell(4,23).xi(NW);
175             at40k.cell(4,23).yi(SOUTH);
176
177             //handshaker(at40k.cell(5,23));
178             //at40k.cell(5,23).yi(NORTH);
179
180             at40k.cell(5,23).yi(NORTH);
181             at40k.cell(5,23).xlut(0x55);
182             at40k.cell(5,23).xi(SW);
183             at40k.cell(5,23).ylut(0x55);
184             at40k.cell(5,22).yi(NORTH);
185             at40k.cell(5,22).xlut(0x55);
186
187             bounce(at40k.cell(4,22));
188
189             // cell southeast of entry cell
190             at40k.cell(3,22).xi(NE);      // NW->xin
191             at40k.cell(3,22).ylut(0x33);  // xin->y
192             at40k.cell(3,22).yo(false);   // y->yout
193             copy(at40k.cell(3, 21), NW, NORTH);  // second top row copies to the right
194             copy(at40k.cell(4, 21), NW, EAST);  // second top row copies to the right
195             copy(at40k.cell(5, 21), NW, EAST);  // second top row copies to the right
196             copy(at40k.cell(6, 21), NW, EAST);  // second top row copies to the right
197             copy(at40k.cell(6, 22), NW, SOUTH);  // second top row copies to the right
198             */
199             /*
200             at40k.cell(05,22).xlut(0xff);
201             at40k.cell(05,22).ylut(0xff);
202             at40k.cell(05,22).c(XLUT);
203             at40k.cell(05,22).f(false);
204             at40k.cell(05,22).b(false);
205             at40k.cell(05,22).oe(NONE);
206             at40k.cell(05,22).v(L3, true);
207             at40k.cell(05,22).out(L3, true);
208             */
209             at40k.cell(4,23).ylut(~0xCC);
210             at40k.cell(4,23).xlut(~0xAA);
211             at40k.cell(5,23).ylut(~0xAA);
212             at40k.cell(5,23).xlut(~0xAA);
213             for(int i=6; i<PIPELEN+2; i++) {
214                 at40k.cell(i, 23).ylut(0xAA);
215                 at40k.cell(i, 23).xlut(0xCC);
216                 at40k.cell(i, 23).yi(WEST);
217             }
218             for(int i=4; i<PIPELEN+2; i++) bounce(at40k.cell(i, 21));
219                 
220
221             at40k.cell(4,22).ylut(0xB2);
222             //at40k.cell(5,22).xlut(0x44);
223             at40k.cell(4,22).xi(SE);
224             at40k.cell(4,22).yi(NORTH);
225             at40k.cell(4,22).c(YLUT);
226             at40k.cell(4,22).f(false);
227             at40k.cell(4,22).t(false, false, true);
228             at40k.cell(4,22).yo(false);
229             at40k.cell(4,22).xo(false);
230
231             for(int x=5; x<PIPELEN; x++) {
232                 at40k.cell(x,22).ylut(0xB2);
233                 //at40k.cell(x,22).xlut(0x44);
234                 at40k.cell(x,22).c(YLUT);
235                 at40k.cell(x,22).f(false);
236                 at40k.cell(x,22).t(false, false, true);
237                 at40k.cell(x,22).xi(SE);
238                 at40k.cell(x,22).yi(WEST);
239                 at40k.cell(x,22).yo(false);
240                 at40k.cell(x,22).xo(false);
241             }
242             //at40k.cell(5,22).yi(WEST);
243             at40k.cell(4,22).yi(NORTH);
244             at40k.cell(4,22).ylut(0xAA);
245
246             at40k.cell(PIPELEN,22).c(YLUT);
247             at40k.cell(PIPELEN,22).ylut(0xB2);
248             //at40k.cell(PIPELEN,22).xlut(0x44);
249             at40k.cell(PIPELEN,22).xi(NE);
250             at40k.cell(PIPELEN,22).yi(WEST);
251             at40k.cell(PIPELEN,22).yo(false);
252             at40k.cell(PIPELEN,22).xo(false);
253             at40k.cell(PIPELEN,22).f(false);
254             at40k.cell(PIPELEN,22).t(false, false, true);
255
256             at40k.cell(21,15).yi(WEST);
257             at40k.cell(21,15).ylut(0xAA);
258             at40k.cell(22,15).yi(WEST);
259             at40k.cell(22,15).ylut(0xAA);
260             at40k.cell(23,15).h(3, true);
261             at40k.cell(23,15).yi(L3);
262             at40k.cell(23,15).ylut(0xAA);
263             at40k.iob_right(15, true).enableOutput(WEST);
264             /*
265             at40k.cell(22,11).ylut(0xff);
266             at40k.cell(23,11).yi(L3);
267             //at40k.cell(23,11).yi(WEST);
268             //at40k.cell(23,11).xi(L1);
269             at40k.cell(23,11).ylut(0xAA);
270             at40k.iob_right(11, true).enableOutput(WEST);
271             at40k.cell(23,11).v(L3, true);
272             at40k.cell(23,11).yo(false);
273             //at40k.flush();
274             */
275             int vx=04;
276             int vv=23;
277             /*
278             System.out.println("correct: " + at40k.cell(19,15).hwire(L3) + " drives " + at40k.cell(20,15).hwire(L3));
279             System.out.println("correct: " + at40k.cell(15,15).hwire(L3) + " drives " + at40k.cell(19,15).hwire(L3));
280             System.out.println("correct: " + at40k.cell(11,15).hwire(L3) + " drives " + at40k.cell(15,15).hwire(L3));
281             System.out.println("correct: " + at40k.cell(07,15).hwire(L3) + " drives " + at40k.cell(11,15).hwire(L3));
282
283             at40k.cell(19,15).hwire(L3).drives(at40k.cell(20,15).hwire(L3), true);
284             at40k.cell(15,15).hwire(L3).drives(at40k.cell(19,15).hwire(L3), true);
285             at40k.cell(11,15).hwire(L3).drives(at40k.cell(15,15).hwire(L3), true);
286             at40k.cell(07,15).hwire(L3).drives(at40k.cell(11,15).hwire(L3), true);
287             */
288             //at40k.cell(05,vv).xlut(0xff);
289             //at40k.cell(05,vv).ylut(0xff);
290             /*
291             at40k.cell(vx,vv).c(YLUT);
292             at40k.cell(vx,vv).f(false);
293             at40k.cell(vx,vv).b(false);
294             at40k.cell(vx,vv).oe(NONE);
295             at40k.cell(vx,vv).v(L3, true);
296             at40k.cell(vx,vv).out(L3, true);
297             */
298             /*
299             at40k.cell(vx,15).v(L3, true);
300             at40k.cell(vx,15).h(L3, true);
301             at40k.cell(vx,19).vwire(L3).drives(at40k.cell(vx,15).vwire(L3), true);
302             at40k.cell(vx,23).vwire(L3).drives(at40k.cell(vx,19).vwire(L3), true);
303             */
304
305             //at40k.cell(5,23).ylut(0x00);
306             //at40k.cell(6,22).ylut(0xff);
307             //at40k.cell(22,11).ylut(0xff);
308             /*
309             At40k.Cell cell = at40k.cell(4, 16);
310             cell.xlut(0xff);
311             cell.ylut(0xff);
312             cell.b(false);
313             cell.f(false);
314             cell.c(XLUT);
315             cell.h(L3, true);
316             cell.v(L3, true);
317             cell.out(L3, true);
318             cell.oe(NONE);
319             */
320             //scan(at40k, cell, YLUT, true);
321             //scan(at40k, cell, YLUT, false);
322
323             device.scanFPGA(true);
324             Visualizer v = new Visualizer(at40k, device);
325             v.show();
326             v.setSize(1380, 1080);
327             At40k.Cell cell = at40k.cell(4, 23);
328             Image img = v.createImage(v.getWidth(), v.getHeight());
329             /*
330             int x = 1;
331             int y = 14;
332             cell = at40k.cell(x,y);
333             scan(at40k, cell, YLUT, true);
334             cell.c(YLUT);
335             cell.b(false);
336             cell.f(false);
337             cell.oe(NONE);
338             cell.ylut(0xff);
339             */
340             //int x = 5;
341             //int y = 11;
342
343             //selfTest(device, at40k, v);
344
345             for(int i=0; i<10000; i++) {
346                 v.refresh();
347                 try { Thread.sleep(100); } catch (Exception e) { }
348             }
349             //cell.ylut(0x09);
350
351             //at40k.cell(0x01, 0x17).h(0, false);
352             //at40k.cell(0x01, 0x17).xi(NE);
353             //at40k.cell(0x01, 0x17).ylut((byte)0x55);
354
355             //at40k.cell(0x04, 0x17).xlut((byte)0x10);
356             //at40k.cell(0x04, 0x17).ylut((byte)0x10);
357             //at40k.cell(0x04, 0x17).yo(false);
358             //at40k.cell(0x04, 0x17).xo();
359
360             /*
361             at40k.cell(0x01, 0x17).xi(L0);
362             at40k.cell(0x01, 0x17).h(L0, true);
363             */
364             /*
365             at40k.cell(0x03, 0x17).xlut((byte)0x55);
366             at40k.cell(0x03, 0x17).ylut((byte)0x55);
367             at40k.cell(0x03, 0x17).yi(EAST);
368             at40k.cell(0x03, 0x17).ylut((byte)0x55);
369             at40k.cell(0x03, 0x17).yo(true);
370
371             at40k.cell(0x03, 0x17).f(false);
372             at40k.cell(0x03, 0x17).c(XLUT);
373             at40k.cell(0x03, 0x17).oe(NONE);
374             at40k.cell(0x03, 0x17).out(L0, true);
375
376             at40k.cell(0x02, 0x17).yi(EAST);
377             at40k.cell(0x02, 0x17).ylut((byte)0x55);
378             at40k.cell(0x02, 0x17).yo(false);
379
380             at40k.cell(0x01, 0x17).yi(EAST);
381             at40k.cell(0x01, 0x17).ylut((byte)0x55);
382             at40k.cell(0x01, 0x17).yo(false);
383
384             at40k.cell(0x01, 0x17).h(L0, true);
385             at40k.cell(0x01, 0x17).v(L0, false);
386             */
387             //at40k.cell(0x01, 0x17).yi(L0);
388             //at40k.cell(0x01, 0x17).xi(L0);
389             //at40k.cell(0x01, 0x17).ylut((byte)0x33);
390
391             /*
392             at40k.cell(0x03, 0x17).h(L0, true);
393             at40k.cell(0x03, 0x17).out(L0, true);
394             at40k.cell(0x03, 0x17).c(XLUT);
395             at40k.cell(0x03, 0x17).f(false);
396             */
397             /*
398             at40k.cell(0x01, 0x17).xin(4);
399             at40k.cell(0x01, 0x17).yin(4);
400             at40k.cell(0x01, 0x16).ylut((byte)0x00);
401             device.mode4(2, 0x17, 0x01, 0);
402
403             for(int i=0; i<10; i++) {
404                 Thread.sleep(3000);
405                 System.out.println("tick");
406                 //at40k.cell(0x01, 0x17).xlut((byte)0xFF);
407                 at40k.cell(0x00, 0x17).ylut((byte)0x00);
408                 device.flush();
409                 Thread.sleep(3000);
410                 System.out.println("tick");
411                 //at40k.cell(0x01, 0x17).xlut((byte)0x00);
412                 at40k.cell(0x00, 0x17).ylut((byte)0xFF);
413                 device.flush();
414             }
415             */
416
417
418             /*
419             at40k.iob_top(0, true).output(0);
420             at40k.iob_top(0, true).oe(false);
421             at40k.iob_top(0, true).pullup();
422             device.flush();
423             Thread.sleep(3000);
424
425             Log.info(AtmelSerial.class, "issuing command");
426             at40k.iob_top(1, true).pulldown();
427             device.flush();
428             */
429             Log.info(AtmelSerial.class, "done");
430             System.exit(0);
431         } catch (Exception e) { e.printStackTrace(); }
432     }
433
434     public static void scan(At40k dev, At40k.Cell cell, int source, boolean setup) {
435         if (setup) {
436             if (source != NONE) cell.c(source);
437             cell.b(false);
438             cell.f(false);
439             cell.out(L3, true);
440         }
441         cell.v(L3, setup);
442
443         At40k.SectorWire sw = cell.vwire(L3);
444         //System.out.println("wire is: " + sw);
445         while(sw.row > (12 & ~0x3) && sw.south() != null) {
446             //System.out.println(sw + " -> " + sw.south());
447             sw.drives(sw.south(), setup);
448             sw = sw.south();
449         }
450         while(sw.row < (12 & ~0x3) && sw.north() != null) {
451             //System.out.println(sw + " -> " + sw.north());
452             sw.drives(sw.north(), setup);
453             sw = sw.north();
454         }
455         //cell = dev.cell(19, 15);
456         cell = dev.cell(cell.col, 15);
457         /*
458         System.out.println("cell is " + cell);
459         cell.xlut(0xff);
460         cell.ylut(0xff);
461         cell.b(false);
462         cell.f(false);
463         cell.c(XLUT);
464         cell.out(L3, true);
465         cell.oe(NONE);
466         */
467         cell.h(L3, setup);
468         cell.v(L3, setup);
469         sw = cell.hwire(L3);
470         while(sw.east() != null) {
471             //System.out.println(sw + " -> " + sw.east());
472             sw.drives(sw.east(), setup);
473             sw = sw.east();
474         }
475     }
476
477     public static void copy(At40k.Cell cell, int xdir, int ydir) {
478         cell.xlut((byte)0x33);
479         cell.ylut((byte)0x55);
480         cell.xi(xdir);
481         cell.yi(ydir);
482         cell.xo(false);
483         cell.yo(false);
484     }
485     public static String hex(int x) {
486         return Long.toString(x & 0xffffffffL, 16);
487     }
488
489     public static void bounce(At40k.Cell cell) {
490         cell.xlut((byte)0xCC);
491         cell.ylut((byte)0xCC);
492         cell.xi(NE);
493         cell.yi(NORTH);
494         cell.xo(false);
495         cell.yo(false);
496     }
497     public static void handshaker(At40k.Cell cell) {
498         cell.xlut(0x22);
499         cell.ylut(0x71);
500         cell.c(XLUT);
501         cell.f(false);
502         cell.t(false, false, true);
503     }
504
505     public static class Visualizer extends Frame implements KeyListener, MouseMotionListener, MouseListener {
506         public static final int WIDTH = 40;
507         public static final int HEIGHT = 40;
508         public static final int LW = 15;
509         public static final int LH = 15;
510         public static final Color RED  = new Color(0xaa, 0x55, 0x55);
511         public static final Color BLUE = new Color(0x55, 0x55, 0xaa);
512         private final At40k dev;
513         private final AvrDrone drone;
514         int selx = -1;
515         int sely = -1;
516         public Visualizer(final At40k dev, final AvrDrone drone) {
517             this.dev = dev;
518             this.drone = drone;
519             show();
520             addMouseMotionListener(this);
521             addMouseListener(this);
522             addKeyListener(this);
523             new Thread() {
524                 public void run() {
525                     try {
526                         while(true) {
527                             Thread.sleep(500);
528                             if (!enabled) continue;
529                             keyPressed(null);
530                         }
531                     } catch (Exception e) {
532                         e.printStackTrace();
533                     }
534                 }
535             }.start();
536         }
537         public boolean enabled = false;
538         public void mouseClicked(MouseEvent e) { }
539         public void mouseEntered(MouseEvent e) { }
540         public void mouseExited(MouseEvent e) { }
541         public void mouseReleased(MouseEvent e) {
542         }
543         public void keyTyped(KeyEvent k) {
544         }
545         public void keyReleased(KeyEvent k) {
546         }
547         public void keyPressed(KeyEvent k) {
548             switch(k==null ? '_' : k.getKeyChar()) {
549                 case '1': {
550                     if (selx==-1 || sely==-1) break;
551                     At40k.Cell cell = dev.cell(selx, sely);
552                     cell.xlut(0xff);
553                     cell.ylut(0xff);
554                     drawCell(getGraphics(), selx, sely);
555                     break;
556                 }
557                 case ' ': {
558                     enabled = !enabled;
559                     break;
560                 }
561                 case 'C': {
562                     if (selx==-1 || sely==-1) break;
563                     At40k.Cell cell = dev.cell(selx, sely);
564                     cell.ylut(0xB2);
565                     drawCell(getGraphics(), selx, sely);
566                     break;
567                 }
568                 case '0': {
569                     if (selx==-1 || sely==-1) break;
570                     At40k.Cell cell = dev.cell(selx, sely);
571                     cell.xlut(0x00);
572                     cell.ylut(0x00);
573                     drawCell(getGraphics(), selx, sely);
574                     break;
575                 }
576             } 
577             for(int xx=5; xx<=PIPELEN; xx++) {
578                 final int x = xx;
579                 final At40k.Cell cell = dev.cell(x, 22);
580                 AvrDrone.ByteCallback bc = new AvrDrone.ByteCallback() {
581                         public void call(byte b) throws Exception {
582                             boolean y = (b & 0x80) != 0;
583                             
584                             Graphics g = getGraphics();
585                             g.setFont(new Font("sansserif", Font.BOLD, 24));
586                             g.setColor(Color.white);
587                             g.drawString("0", left(cell) + 12, top(cell) + 30);
588                             g.drawString("1", left(cell) + 12, top(cell) + 30);
589                             //g.setColor(RED);
590                             //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
591                             
592                             //g.drawString((y?"1":"0"), left(cell) + 12, top(cell) + 30);
593                             drawCell(g, x, 22, y?new Color(0xff, 0x99, 0x99):new Color(0x99, 0xff, 0x99));
594                         }
595                     };
596
597                 scan(dev, cell, YLUT, true);
598                 drone.readBus(bc);
599                 scan(dev, cell, YLUT, false);
600             }
601         }
602         public void mousePressed(MouseEvent e) {
603             /*
604             At40k.Cell cell = dev.cell(selx, sely);
605             if (cell==null) return;
606             int old = cell.c();
607             scan(dev, cell, YLUT, true);
608             boolean y = (drone.readBus() & 0x80) != 0;
609             //scan(dev, cell, XLUT, true);
610             //boolean x = (drone.readBus() & 0x80) != 0;
611             scan(dev, cell, YLUT, false);
612             cell.c(old);
613             Graphics g = getGraphics();
614             g.setFont(new Font("sansserif", Font.BOLD, 14));
615             g.setColor(Color.white);
616             //g.drawString("X=0", left(cell) + 10, top(cell) + 20);
617             //g.drawString("X=1", left(cell) + 10, top(cell) + 20);
618             
619             //g.setColor(Color.white);
620             //g.drawString("Y=0", left(cell) + 8, top(cell) + 35);
621             //g.drawString("Y=1", left(cell) + 8, top(cell) + 35);
622             
623             //g.setColor(RED);
624             //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
625             g.setColor(BLUE);
626             g.drawString("Y="+(y?"1":"0"), left(cell) + 8, top(cell) + 35);
627             */
628         }
629
630         public void mouseMoved(MouseEvent e) {
631             int x = e.getX();
632             int y = e.getY();
633             if (selx >= 0 && selx < 24 && sely >= 0 && sely < 24) {
634                 int cx = selx;
635                 int cy = sely;
636                 At40k.Cell cell = dev.cell(cx, cy);
637                 selx = -1;
638                 sely = -1;
639                 drawCell(getGraphics(), cx, cy);
640                 drawSector(getGraphics(), dev.cell(cx, cy).sector());
641             }
642             selx = (x-20)/(WIDTH+2);
643             sely = (23 - (y-20)/(HEIGHT+2))+1;
644             At40k.Cell cell = dev.cell(selx, sely);
645             if (selx >= 0 && selx < 24 && sely >= 0 && sely < 24) {
646                 drawCell(getGraphics(), selx, sely);
647                 drawSector(getGraphics(), dev.cell(selx, sely).sector());
648             }
649         }
650         public void mouseDragged(MouseEvent e) { mousePressed(e); }
651         public void paint(Graphics g) {
652             g.setColor(Color.white);
653             g.fillRect(0, 0, getWidth(), getHeight());
654             for(int x=0; x<24; x++)
655                 for(int y=0; y<24; y++)
656                     drawCell(g,x,y);
657             for(int x=0; x<=23; x+=4)
658                 for(int y=23; y>=0; y-=4) 
659                     drawSector(g, dev.cell(x, y).sector());
660             g.setColor(BLUE);
661             g.drawString("Ready", (5*(WIDTH+2))+20, 40);
662             g.setColor(RED);
663             g.drawString("Send",  (3*(WIDTH+2))+20, 40);
664             g.setColor(BLUE);
665             refresh();
666         }
667         public void refresh() {
668             Graphics g = getGraphics();
669             /*
670             int data = drone.readBus() & 0xff;
671             for(int i=0; i<8; i++) {
672                 g.setColor((data & (1<<i))==0 ? Color.black : Color.green);
673                 g.drawString("D"+i,  (24*(WIDTH+2))+20, ((23-(i+7))*(HEIGHT+2))+60-HEIGHT/2);
674             }
675             */
676         }
677         public static int left(At40k.Cell cell) { return (cell.col)   *(WIDTH+2)+20; }
678         public static int top(At40k.Cell cell)  { return (23-cell.row)*(HEIGHT+2)+60; }
679         public void drawSector(Graphics g, At40k.Sector sector) {
680             g.setColor(Color.gray);
681             ((Graphics2D)g).setStroke(new BasicStroke(1));
682             int px = ((sector.col)*(WIDTH+2))+20-1;
683             int py = ((23-(sector.row+3))*(HEIGHT+2))+60-1;
684             g.drawRect(px, py, (WIDTH+2)*4+2, (HEIGHT+2)*4+2);
685             for(int dir=0; dir<2; dir++) {
686                 boolean h = dir==0;
687                 for(int y=h?sector.row:sector.col; y<(h?sector.row+4:sector.col+4); y++)
688                     for(int plane=0; plane<=4; plane++) {
689                         At40k.Cell cell      = h ? dev.cell(sector.col,   y) : dev.cell(y, sector.row);
690                         At40k.Cell cell_east = h ? dev.cell(sector.col-1, y) : dev.cell(y, sector.row-1);
691                         At40k.Cell cell_west = h ? dev.cell(sector.col+4, y) : dev.cell(y, sector.row+4);
692                         boolean draw = false;
693                         if (h) {
694                             if (cell_east!=null &&
695                                 (cell_east.hwire(plane).drives(cell.hwire(plane)) ||
696                                  cell_east.hwire(plane).drives(cell.hwire(plane))))
697                                 draw = true;
698                             if (cell_west!=null &&
699                                 (cell_west.hwire(plane).drives(cell.hwire(plane)) ||
700                                  cell_west.hwire(plane).drives(cell.hwire(plane))))
701                                 draw = true;
702                         } else {
703                             if (cell_east!=null &&
704                                 (cell_east.vwire(plane).drives(cell.vwire(plane)) ||
705                                  cell_east.vwire(plane).drives(cell.vwire(plane))))
706                                 draw = true;
707                             if (cell_west!=null &&
708                                 (cell_west.vwire(plane).drives(cell.vwire(plane)) ||
709                                  cell_west.vwire(plane).drives(cell.vwire(plane))))
710                                 draw = true;
711                         }
712                         if (!draw)
713                             for(int x=h?sector.col:sector.row; x<(h?sector.col+4:sector.row+4); x++)
714                                 if (((h ? dev.cell(x,y).hx(plane) : dev.cell(y,x).vx(plane))) ||
715                                     (h?dev.cell(x,y).out(plane):dev.cell(y,x).out(plane)))
716                                     draw = true;
717                         if (draw) {
718                             g.setColor(new Color(0xff, 0x00, 0xff));
719                             if (h) {
720                                 g.drawLine(left(cell),
721                                            top(cell)+3,
722                                            left(cell) + 4*(WIDTH+2),
723                                            top(cell)+3
724                                            );
725                             } else {
726                                 g.drawLine(left(cell)+3,
727                                            top(cell) + (HEIGHT+2),
728                                            left(cell)+3,
729                                            top(cell) - 3*(HEIGHT+2)
730                                            );
731                             }
732                         }
733                     }
734             }
735         }
736         public void drawCell(Graphics g, int cx, int cy) { drawCell(g, cx, cy, Color.white); }
737         public void drawCell(Graphics g, int cx, int cy, Color bg) {
738             int x = (cx*(WIDTH+2))+20;
739             int y = ((23-cy)*(HEIGHT+2))+60;
740             if (g.getClipBounds() != null && !g.getClipBounds().intersects(new Rectangle(x, y, x+WIDTH, y+HEIGHT))) return;
741
742             System.out.println("drawcell " + cx + "," + cy);
743             At40k.Cell cell = dev.cell(cx, cy);
744             g.setColor(bg);
745             g.fillRect(x, y, WIDTH, HEIGHT);
746
747             g.setColor((selx==cx && sely==cy) ? Color.red : Color.black);
748             g.drawRect(x, y, WIDTH, HEIGHT);
749
750             //g.setColor((selx==cx && sely==cy) ? Color.red : Color.gray);
751             //g.drawRect(x+(WIDTH-(LW*2))/2-1,    y+(HEIGHT-LW)/2-1, LW*2+1, LH+1);
752
753             g.setColor(RED);
754             //g.fillRect(x+(WIDTH-(LW*2))/2,    y+(HEIGHT-LW)/2, LW,   LH);
755             g.setColor(Color.white);
756             //g.drawString("1", x+(WIDTH-(LW*2))/2,    y+(HEIGHT-LW)/2);
757
758             g.setColor(BLUE);
759             //g.fillRect(x+(WIDTH-(LW*2))/2+LW, y+(HEIGHT-LW)/2, LW,   LH);
760             g.setColor(Color.white);
761             //g.drawString("0", x+(WIDTH-(LW*2))/2+LW,    y+(HEIGHT-LW)/2);
762
763             /*
764               g.setColor(BLUE);
765             ((Graphics2D)g).setStroke(new BasicStroke((float)1));
766             switch(cell.yi()) {
767                 case NORTH: g.drawLine(x+WIDTH/2+5,  y-10,        x+WIDTH/2+5, y+HEIGHT/2); break;
768                 case SOUTH: g.drawLine(x+WIDTH/2-5,  y+HEIGHT+10, x+WIDTH/2-5, y+HEIGHT/2); break;
769                 case EAST:  g.drawLine(x+WIDTH+10, y+HEIGHT/2+5,  x+WIDTH/2, y+HEIGHT/2+5); break;
770                 case WEST:  g.drawLine(x-10,       y+HEIGHT/2-5,  x+WIDTH/2, y+HEIGHT/2-5); break;
771                 case NONE:  break;
772             }
773             g.setColor(RED);
774             ((Graphics2D)g).setStroke(new BasicStroke((float)1));
775             switch(cell.xi()) {
776                 case NW: g.drawLine(x-10+3,       y-10,        x+WIDTH/2+3, y+HEIGHT/2); break;
777                 case SW: g.drawLine(x-10-3,       y+HEIGHT+10, x+WIDTH/2-3, y+HEIGHT/2); break;
778                 case NE: g.drawLine(x+WIDTH+10+3, y-10,        x+WIDTH/2+3, y+HEIGHT/2); break;
779                 case SE: g.drawLine(x+WIDTH+10-3, y+HEIGHT+10, x+WIDTH/2-3, y+HEIGHT/2); break;
780                 case NONE:  break;
781             }
782             ((Graphics2D)g).setStroke(new BasicStroke(1));
783             */
784
785             if (selx==cx && sely==cy) {
786                 int xp = 23 * (WIDTH+2) + 100;
787                 int yp = 100;
788                 g.setColor(Color.white);
789                 g.fillRect(xp, yp, 300, 1000);
790                 g.setColor(Color.black);
791                 g.drawString("Cell " + cx + "," + cy,       xp, (yp+=15));
792                 //g.drawString("X-Lut: " + bin8(cell.xlut()), xp, (yp+=15));
793                 g.drawString("X-Lut: " + cell.printXLut(), xp, (yp+=15));
794                 //g.drawString("Y-Lut: " + bin8(cell.ylut()), xp, (yp+=15));
795                 g.drawString("Y-Lut: " + cell.printYLutX(), xp, (yp+=15));
796             }
797
798             if ((cell.ylut()&0xff)==0xff && (cell.xlut()&0xff)==0xff) {
799                 g.setFont(new Font("sansserif", Font.BOLD, 24));
800                 g.setColor(Color.white);
801                 g.drawString("0", left(cell) + 12, top(cell) + 30);
802                 g.drawString("1", left(cell) + 12, top(cell) + 30);
803                 //g.setColor(RED);
804                 //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
805                 g.setColor(new Color(0x00, 0x00, 0xff));
806                 g.drawString("1", left(cell) + 12, top(cell) + 30);
807             }
808             if ((cell.ylut()&0xff)==0x00 && (cell.xlut()&0xff)==0x00) {
809                 g.setFont(new Font("sansserif", Font.BOLD, 24));
810                 g.setColor(Color.white);
811                 g.drawString("0", left(cell) + 12, top(cell) + 30);
812                 g.drawString("1", left(cell) + 12, top(cell) + 30);
813                 //g.setColor(RED);
814                 //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
815                 g.setColor(new Color(0x00, 0x00, 0xff));
816                 g.drawString("0", left(cell) + 12, top(cell) + 30);
817             }
818             if ((cell.ylut()&0xff)==0xB2) {
819                 System.out.println("muller @ " + cell);
820                 g.setFont(new Font("sansserif", Font.BOLD, 24));
821                 g.setColor(Color.white);
822                 g.drawString("0", left(cell) + 12, top(cell) + 30);
823                 g.drawString("1", left(cell) + 12, top(cell) + 30);
824                 //g.setColor(RED);
825                 //g.drawString("X="+(x?"1":"0"), left(cell) + 10, top(cell) + 20);
826                 g.setColor(new Color(0x00, 0xaa, 0x00));
827                 g.drawString("C", left(cell) + 12, top(cell) + 30);
828             }
829         }
830     }
831
832     private static String pad(int i, String s) { if (s.length()>i) return s; return "0"+pad((i-1),s); }
833     private static String bin8(byte b) {
834         int n = b & 0xff;
835         String ret = "";
836         for(int i=7; i>=0; i--)
837             ret += (n & (1<<i))==0 ? "0" : "1";
838         return ret;
839     }
840
841     public static void selfTest(AvrDrone device, At40k at40k, Visualizer v) {
842         /*
843             int fail = 0;
844             long now = System.currentTimeMillis();
845             for(int x=0; x<24; x++)
846                 for(int y=0; y<24; y++) {
847                     At40k.Cell cell = at40k.cell(x,y);
848                     scan(at40k, cell, YLUT, true);
849                     //v.paint(img.getGraphics());
850                     //v.getGraphics().drawImage(img, 0, 0, null);
851                     cell.ylut(0xff);
852                     boolean a = (device.readBus() & 0x80)!=0;
853                     cell.ylut(0x00);
854                     boolean b = (device.readBus() & 0x80)!=0;
855                     if (a & !b) {
856                         //System.out.println("pass " + x+","+y);
857                         Graphics g = v.getGraphics();
858                         g.setColor(Color.green);
859                         g.drawString("pass", v.left(cell) + 10, v.top(cell) + 20);
860                     } else {
861                         System.out.println("FAIL!!!! " + x+","+y+" => " + a + " " + b);
862                         fail++;
863                         Graphics g = v.getGraphics();
864                         g.setColor(Color.red);
865                         g.drawString("FAIL", v.left(cell) + 10, v.top(cell) + 20);
866                     }
867                     scan(at40k, cell, YLUT, false);
868                 }
869
870             System.out.println("failures: " + fail);
871             System.out.println("scan time: " + (System.currentTimeMillis()-now) + "ms");
872         */
873     }
874
875 }