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