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