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