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