// Simple framestore. // 135 MHz 1270/1714 1024/1050 : 79KHz 12.6us : 75 Hz 13ms. // Aim for 1280x1024x75 // 66/2066 = 35kHz using System; using System.Threading; using KiwiSystem; class KiwiFramestore { [Kiwi.OutputBitPort("r")] static int red; [Kiwi.OutputBitPort("g")] static int green; [Kiwi.OutputBitPort("b")] static int blu; [Kiwi.OutputBitPort("hsyn")] static bool hsyn; [Kiwi.OutputBitPort("vsyn")] static int vsyn; [Kiwi.OutputBitPort("led4")] static int led4; [Kiwi.InputBitPort("clear")] static bool clear; const int width = 512, height = 512; [Kiwi.SynchSRAM(0)] static byte [] fstore = new byte [width*height]; static bool vstop, vstart; static int vblank, hblank; static int hctr, vctr, hctr1, vctr1, idx; static volatile int waddr; static volatile byte wdata; static volatile bool toggle; [Kiwi.Remote()] public static byte setget_pixel(uint x, uint y, bool readf, byte wd) { uint addr = (uint)(x * width + y); if (!readf) waddr = (int)addr; wdata = wd; toggle = !toggle; //if (readf>0) // return fstore[addr]; Console.WriteLine("Set pixel ({0},{1}) to {2}", x, y, wdata); return wdata; } static void fstore_process_horiz() { hctr = 0; while(true) { Kiwi.Pause(); led4 = (hctr >> 4) & 1; hsyn = hctr > 1279; hctr = (hctr==1713) ? 0: hctr + 1; hblank = hctr < 100 || hctr >= (100+512) ?1:0; } } static void fstore_process_vert() { vctr = 0; vstart = false; vstop = false; while(true) { if (hctr == 1279) { vstart = vctr == 1023; vstop = vctr == 1049; if (vstart) vsyn = 1; else if (vstop) vsyn = 0; vctr = (vctr==1049) ? 0: vctr + 1; vblank = vctr < 100 || vctr >= (100+512) ?1:0; } Kiwi.Pause(); } } static void fstore_process_counters() { while(true) { Kiwi.NoUnroll(); if (vblank>0) vctr1 = 0; if (hblank>0) hctr1 = 0; else { if (hctr1==511) { hctr1 = 0; vctr1 = (vctr1==511)? 0 : vctr1 + 1; } else hctr1 = hctr1 + 1; } Kiwi.Pause(); } } static byte vd; static void fstore_process_data() { vd = 0; bool old_toggle = false; while(true) { bool blank = (vblank + hblank) > 0; idx = (toggle != old_toggle) ? waddr: vctr1 * width + hctr1; if (toggle != old_toggle) { fstore[idx] = wdata; old_toggle = toggle; } // else if (clear) fstore[idx] <= 0; // else if (rop) readreg <= fstore[idx]; else vd = fstore[idx]; green = (blank?0:1) & (((hctr & 127)!= 0) != ((vctr & 32)!=0) != ((vctr & 2)!=0) ?1:0); red = (blank?0:1) & (((vd & 1) != 0)?1:0); blu = (blank?0:1) & (((vd & 8)!= 0)?1:0); Kiwi.Pause(); } } [Kiwi.HardwareEntryPoint()] public static void Main() { toggle = false; Thread VerticalThread = new Thread(new ThreadStart (fstore_process_vert)); VerticalThread.Start(); Thread CountersThread = new Thread(new ThreadStart (fstore_process_counters)); CountersThread.Start(); Thread DataThread = new Thread(new ThreadStart (fstore_process_data)); DataThread.Start(); fstore_process_horiz(); } }