diff --git a/sbus-to-ztex-gateware-migen/blit.c b/sbus-to-ztex-gateware-migen/blit.c index 1f12615..088cf6e 100644 --- a/sbus-to-ztex-gateware-migen/blit.c +++ b/sbus-to-ztex-gateware-migen/blit.c @@ -369,7 +369,7 @@ struct cg6_fbc { void from_reset(void) __attribute__ ((noreturn)); // nothrow, static inline void flush_cache(void) { - asm volatile(".word 0x0000500F\n"); // flush the Dcache so that we get updated data + //asm volatile(".word 0x0000500F\n"); // flush the Dcache so that we get updated data } typedef unsigned int unsigned_param_type; @@ -415,6 +415,9 @@ static void bitblit(const unsigned_param_type xs, const unsigned char gxop ); +static void print_hexword(unsigned int v, unsigned int bx, unsigned int by); +static void show_status_on_screen(void); + asm(".global _start\n" "_start:\n" // ".word 0x0000500F\n" // flush cache ; should not be needed after reset @@ -438,6 +441,8 @@ asm(".global _start\n" #define imax(a,b) ((a>b)?(a):(b)) #define imin(a,b) ((afbc_r5_status[0] = a @@ -466,7 +471,6 @@ void from_reset(void) { case CG6_ALU_FILL: // ____ff00 console case CG6_ALU_COPY: // ____cccc equivalent to fill if patterns == 1 (... which is the case with GX_PATTERN_ONES) case ROP_FILL(GX_ROP_CLEAR, GX_ROP_SET): // ____ff00 Draw/GXcopy in X11 - // //case ROP_FILL(GX_ROP_SET, GX_ROP_SET): // ____ffff Draw/GXset in X11 case ROP_BLIT(GX_ROP_CLEAR, GX_ROP_SET): // ____cccc Blit/GXcopy in X11 { switch (mode) { @@ -491,7 +495,7 @@ void from_reset(void) { break; } } break; - case CG6_ALU_FLIP: { // ____5555 console + case CG6_ALU_FLIP: { // ____5555 console -> put ~dst everywhere switch (mode) { case (GX_BLIT_SRC | GX_MODE_COLOR8): // invert @@ -505,7 +509,7 @@ void from_reset(void) { break; } } break; - case ROP_FILL(GX_ROP_NOOP, GX_ROP_INVERT): { // ____55aa Draw/GXxor in X11 + case ROP_FILL(GX_ROP_NOOP, GX_ROP_INVERT): { // ____55aa Draw/GXxor in X11 -> put ~dst if src is 1, put dst if src is 0 switch (mode) { case (GX_BLIT_SRC | GX_MODE_COLOR8 | GX_DRAW_RENDER | GX_BWRITE0_ENABLE | GX_BWRITE1_DISABLE | GX_BREAD_0 | GX_BDISP_0): @@ -537,12 +541,12 @@ void from_reset(void) { case FUN_BLIT: { switch (alu) { - case CG6_ALU_COPY: // ____cccc console - case ROP_BLIT(GX_ROP_CLEAR, GX_ROP_SET): // ____ff00 Blit/GXcopy in X11 + case CG6_ALU_COPY: // ____cccc console -> put the src + case ROP_BLIT(GX_ROP_CLEAR, GX_ROP_SET): // ____ff00 Blit/GXcopy in X11 -> put 1 if src is 1, put 0 if src is 0 (!) { switch (mode) { case (GX_BLIT_SRC | GX_MODE_COLOR8): // console - case (GX_BLIT_SRC | GX_MODE_COLOR8 | GX_DRAW_RENDER | GX_BWRITE0_ENABLE | GX_BWRITE1_DISABLE | GX_BREAD_0 | GX_BDISP_0): // X11 FIXME:planemask? + case (GX_BLIT_SRC | GX_MODE_COLOR8 | GX_DRAW_RENDER | GX_BWRITE0_ENABLE | GX_BWRITE1_DISABLE | GX_BREAD_0 | GX_BDISP_0): { const unsigned_param_type xs = fbc->fbc_x0; const unsigned_param_type ys = fbc->fbc_y0; @@ -563,7 +567,7 @@ void from_reset(void) { break; } } break; - case ROP_BLIT(GX_ROP_SET, GX_ROP_SET): // ____ffff Blit/GXset in X11 + case ROP_BLIT(GX_ROP_SET, GX_ROP_SET): // ____ffff Blit/GXset in X11 -> put 1 everywhere { switch (mode) { case (GX_BLIT_SRC | GX_MODE_COLOR8): // console @@ -588,10 +592,10 @@ void from_reset(void) { break; } } break; - case ROP_BLIT(GX_ROP_NOOP, GX_ROP_INVERT): // ____6666 Blit/GXxor in X11 + case ROP_BLIT(GX_ROP_NOOP, GX_ROP_INVERT): // ____6666 Blit/GXxor in X11 -> xor everywhere { switch (mode) { - case (GX_BLIT_SRC | GX_MODE_COLOR8 | GX_DRAW_RENDER | GX_BWRITE0_ENABLE | GX_BWRITE1_DISABLE | GX_BREAD_0 | GX_BDISP_0): // X11 FIXME:planemask? + case (GX_BLIT_SRC | GX_MODE_COLOR8 | GX_DRAW_RENDER | GX_BWRITE0_ENABLE | GX_BWRITE1_DISABLE | GX_BREAD_0 | GX_BDISP_0): { const unsigned_param_type xs = fbc->fbc_x0; const unsigned_param_type ys = fbc->fbc_y0; @@ -647,7 +651,13 @@ void from_reset(void) { const unsigned int yd = fbc->fbc_next_y0; const unsigned int we = xde - xdsr + 1; const unsigned int xoff = xds - xdsr; - if ((xde >= xds) && (xofffbc_next_font; + unsigned int rbits; + asm("rev8 %0, %1\n" : "=r"(rbits) : "r"(bits)); + *((unsigned int*)dptr) = rbits; + } else if ((xde >= xds) && (xofffbc_next_font; #if 1 unsigned int rbits; @@ -674,7 +684,7 @@ void from_reset(void) { break; } } break; - case (GX_PATTERN_ONES | ROP_OSTP(GX_ROP_CLEAR, GX_ROP_SET)): // console, also X11 OpaqueStipple/GXcopy FIXME:planemask? + case (GX_PATTERN_ONES | ROP_OSTP(GX_ROP_CLEAR, GX_ROP_SET)): // ____fc30 console, also X11 OpaqueStipple/GXcopy FIXME:planemask? { switch (mode) { case (GX_BLIT_NOSRC | GX_MODE_COLOR1): @@ -772,8 +782,12 @@ void from_reset(void) { break; } - // make sure we have nothing left in the cache finish: +#ifdef TRACE_ON_SCREEN + show_status_on_screen(); +#endif + + // make sure we have nothing left in the cache flush_cache(); fbc->fbc_r5_cmd = FUN_DONE; @@ -784,7 +798,7 @@ void from_reset(void) { } #define bitblit_proto_int(a, b, suf) \ - static void bitblit##a##b##suf(const unsigned_param_type xs, \ + static void bitblit##a##b##suf(const unsigned_param_type xs, \ const unsigned_param_type ys, \ const unsigned_param_type wi, \ const unsigned_param_type re, \ @@ -862,7 +876,7 @@ static void bitblit(const unsigned_param_type xs, /* don't bother */ break; case 0x6: // GXxor - rectfill(xd, yd, wi, re, 0); // FIXME: pixelmask + rectfill_pm(xd, yd, wi, re, 0, pm); break; } } @@ -1238,3 +1252,101 @@ static void bitblit_bwd_bwd_copy(const unsigned_param_type xs, } #endif +#ifdef TRACE_ON_SCREEN +#include "blit_font.h" + +static void print_hex(unsigned char v, unsigned char* line_fb); +static void print_hex(unsigned char v, unsigned char* line_fb) { + unsigned int x, y; + const unsigned char *pbits = font + v * 8; + for (y = 0 ; y < 8 ; y++) { // line in char + const unsigned char bits = pbits[y]; + for (x = 0 ; x < 8 ; x++) { // bits in line + unsigned char data = - ((bits>>(7-x))&1); // 0xff or 0x00 + line_fb[x] = data; + } + line_fb += HRES; + } +} + +static void print_hexword(unsigned int v, unsigned int bx, unsigned int by) { + unsigned int i, j; +#if 0 + unsigned int x, y; +#endif + unsigned char* base_fb = (((unsigned char *)BASE_FB) + mul_HRES(by) + bx); + + for (i = 0 ; i < 8 ; i++) { // nibbles in v + unsigned char* line_fb = base_fb; + unsigned int bidx = (v >> (28-i*4) & 0xF); +#if 0 + const unsigned char *pbits = font + bidx * 8; + for (y = 0 ; y < 8 ; y++) { // line in char + const unsigned char bits = pbits[y]; + for (x = 0 ; x < 8 ; x++) { // bits in line + unsigned char data = - ((bits>>(7-x))&1); // 0xff or 0x00 + line_fb[x] = data; + } + line_fb += HRES; + } +#else + print_hex(bidx, line_fb); +#endif + base_fb += 8; + } +} + +static void show_status_on_screen(void) { + struct cg6_fbc* fbc = (struct cg6_fbc*)BASE_FBC; + unsigned int cmd = fbc->fbc_r5_cmd; + unsigned int alu = fbc->fbc_alu; + unsigned int mode = fbc->fbc_mode; + unsigned int bx = 0; + unsigned int by = 768 + ((cmd & 0xF)*32); + unsigned char* base_fb = (((unsigned char *)BASE_FB) + mul_HRES(by) + bx); + + print_hex(cmd & 0xF, base_fb); + bx += 16; + print_hexword(alu, bx, by); + bx += 72; + print_hexword(mode, bx, by); + bx -= 72; + by += 8; + if ((cmd & 0xF) == FUN_DRAW) { + print_hexword(fbc->fbc_arectx_prev, bx, by); + bx += 72; + print_hexword(fbc->fbc_arecty_prev, bx, by); + bx -= 72; + by += 8; + print_hexword(fbc->fbc_arectx, bx, by); + bx += 72; + print_hexword(fbc->fbc_arecty, bx, by); + bx -= 72; + by += 8; + print_hexword(fbc->fbc_pm, bx, by); + bx -= 88; + } else if ((cmd & 0xF) == FUN_BLIT) { + print_hexword(fbc->fbc_x0, bx, by); + bx += 72; + print_hexword(fbc->fbc_y0, bx, by); + bx += 72; + print_hexword(fbc->fbc_x1, bx, by); + bx += 72; + print_hexword(fbc->fbc_y1, bx, by); + bx -= 216; + by += 8; + print_hexword(fbc->fbc_x2, bx, by); + bx += 72; + print_hexword(fbc->fbc_y2, bx, by); + bx += 72; + print_hexword(fbc->fbc_x3, bx, by); + bx += 72; + print_hexword(fbc->fbc_y3, bx, by); + bx -= 216; + by += 8; + print_hexword(fbc->fbc_pm, bx, by); + bx -= 88; + } + print_hexword(fbc->fbc_s, bx, by); +} +#endif diff --git a/sbus-to-ztex-gateware-migen/blit.sh b/sbus-to-ztex-gateware-migen/blit.sh index 6fdc02c..abe81f8 100755 --- a/sbus-to-ztex-gateware-migen/blit.sh +++ b/sbus-to-ztex-gateware-migen/blit.sh @@ -21,4 +21,4 @@ if test "x$1" != "xASM"; then fi $GCC $OPT -c -o blit.o -march=$ARCH -mabi=ilp32 -mstrict-align -fno-builtin-memset -nostdlib -ffreestanding -nostartfiles blit.s && $GCCLINK $OPT -o blit -march=$ARCH -mabi=ilp32 -T blit.lds -nostartfiles blit.o && -$OBJCOPY -O binary -j .text blit blit.raw +$OBJCOPY -O binary -j .text -j .rodata blit blit.raw diff --git a/sbus-to-ztex-gateware-migen/cg6_accel.py b/sbus-to-ztex-gateware-migen/cg6_accel.py index 5498d06..b7cc0b0 100644 --- a/sbus-to-ztex-gateware-migen/cg6_accel.py +++ b/sbus-to-ztex-gateware-migen/cg6_accel.py @@ -25,8 +25,8 @@ class CG6Accel(Module): # AutoCSR ? fbc_incy = Signal(COORD_BITS) fbc_clipminx = Signal(COORD_BITS) fbc_clipminy = Signal(COORD_BITS) - fbc_clipmaxx = Signal(COORD_BITS) - fbc_clipmaxy = Signal(COORD_BITS) + fbc_clipmaxx = Signal(COORD_BITS+1) # need the 13th bit as X11 uses 4096 for clipmaxx (console uses 4095) + fbc_clipmaxy = Signal(COORD_BITS+1) # need the 13th bit as X11 uses 4096 for clipmaxx (console uses 4095) fbc_fg = Signal(8) fbc_bg = Signal(8) fbc_alu = Signal(32) @@ -34,7 +34,7 @@ class CG6Accel(Module): # AutoCSR ? fbc_arectx = Signal(COORD_BITS) fbc_arecty = Signal(COORD_BITS) - # extra stuff for compatibility + # extra stuff for the Vex core fbc_arectx_prev = Signal(COORD_BITS) # after fbc_arecty (600) - R/O fbc_arecty_prev = Signal(COORD_BITS) # after fbc_arectx_prev (601) - R/O fbc_r5_cmd = Signal(32) # to communicate with Vex (602) @@ -44,8 +44,13 @@ class CG6Accel(Module): # AutoCSR ? fbc_next_x1 = Signal(COORD_BITS) fbc_next_y0 = Signal(COORD_BITS) + # do-some-work flags fbc_do_draw = Signal() fbc_do_blit = Signal() + + # for GX global status register fbc_s + GX_FULL_BIT = 29 + GX_INPROGRESS_BIT = 28 font_layout = [ ("font", 32), @@ -54,7 +59,13 @@ class CG6Accel(Module): # AutoCSR ? ("y0", COORD_BITS), ] # depth is because the current 'font' is a bit slow, so we need to buffer a lot... - self.submodules.fbc_fifo_font = SyncFIFOBuffered(width=layout_len(font_layout),depth=1024) + self.submodules.fbc_fifo_font = SyncFIFOBuffered(width=layout_len(font_layout),depth=2048) + + #fifo_overflow = Signal() + #self.comb += fifo_overflow.eq(self.fbc_fifo_font.we & ~self.fbc_fifo_font.writable) + + #draw_blit_overflow = Signal() + fbc_fifo_font_in = Record(font_layout) fbc_fifo_font_out = Record(font_layout) self.comb += [ @@ -67,14 +78,16 @@ class CG6Accel(Module): # AutoCSR ? NextValue(bus.ack, 0), NextState("Idle")) wishbone_fsm.act("Idle", + self.fbc_fifo_font.we.eq(0), If(bus.cyc & bus.stb & bus.we & ~bus.ack, #write - Case(bus.adr[0:10], { + Case(bus.adr[0:11], { "default": [ ], # 0: fbc_config R/O 1: [ NextValue(fbc_mode, bus.dat_w) ], 2: [ NextValue(fbc_clip, bus.dat_w) ], # 3: , pad2 - 4: [ NextValue(fbc_s, bus.dat_w) ], # 0x010 + 4: [ # NextValue(fbc_s, bus.dat_w) + ], # 0x010 # 5: fbc_draw R/O # 6: fbc_blit R/O 7: [ self.fbc_fifo_font.we.eq(1), @@ -147,23 +160,28 @@ class CG6Accel(Module): # AutoCSR ? }), NextValue(bus.ack, 1), ).Elif(bus.cyc & bus.stb & ~bus.we & ~bus.ack, #read - Case(bus.adr[0:10], { + Case(bus.adr[0:11], { "default": [ NextValue(bus.dat_r, 0xDEADBEEF) ], 0: [ NextValue(bus.dat_r, fbc_config) ], 1: [ NextValue(bus.dat_r, fbc_mode) ], 2: [ NextValue(bus.dat_r, fbc_clip) ], # 3: pad2 - 4: [ NextValue(bus.dat_r, fbc_s) ], + 4: [ NextValue(bus.dat_r, fbc_s), + #NextValue(bus.dat_r, Replicate(fbc_s[GX_INPROGRESS_BIT] | fbc_do_draw | fbc_do_blit | self.fbc_fifo_font.readable, 32)) ], + ], # 5: fbc_draw R/O -> start a "draw" on R - 5: [ NextValue(fbc_do_draw, 1), - NextValue(bus.dat_r, 0) + 5: [ NextValue(fbc_do_draw, ~fbc_s[GX_INPROGRESS_BIT]), # ignore command while working + NextValue(bus.dat_r, 0), + #NextValue(draw_blit_overflow, draw_blit_overflow | fbc_do_draw | fbc_do_blit), + #NextValue(draw_blit_overflow, draw_blit_overflow | fbc_s[GX_INPROGRESS_BIT]), ], # 6: fbc_blit R/O -> start a "blit" on R - 6: [ NextValue(fbc_do_blit, 1), - NextValue(bus.dat_r, 0) + 6: [ NextValue(fbc_do_blit, ~fbc_s[GX_INPROGRESS_BIT]), # ignore command while working + NextValue(bus.dat_r, 0), + #NextValue(draw_blit_overflow, draw_blit_overflow | fbc_do_draw | fbc_do_blit), + #NextValue(draw_blit_overflow, draw_blit_overflow | fbc_s[GX_INPROGRESS_BIT]), ], # 7: fbc_font W/O -> start a "font" on W - # 7: [ NextValue(bus.dat_r, fbc_font) ], # 8-31: pad3 32: [ NextValue(bus.dat_r, fbc_x[0]) ], # 0x080 33: [ NextValue(bus.dat_r, fbc_y[0]) ], @@ -232,20 +250,31 @@ class CG6Accel(Module): # AutoCSR ? FUN_FONT_NEXT_REQ_BIT = 29 FUN_FONT_NEXT_DONE_BIT = 28 - # for GX global status register - #GX_FULL_BIT = 29 - GX_INPROGRESS_BIT = 28 - # to hold the Vex in reset # could be sent to fbc_s[GX_INPROGRESS_BIT] ? local_reset = Signal(reset = 1) #timeout_rst = 0xFFFFFFF #timeout = Signal(28, reset = timeout_rst) - pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED") - self.comb += pad_SBUS_DATA_OE_LED.eq(~local_reset); - #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_r5_cmd[1]); # blitting - #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_pm != 0); # planemasking + #pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED") + #self.comb += pad_SBUS_DATA_OE_LED.eq(~local_reset) + #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_r5_cmd[1]) # blitting + #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_pm != 0) # planemasking + #self.comb += pad_SBUS_DATA_OE_LED.eq(fifo_overflow) + #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_s[GX_INPROGRESS_BIT]) + #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_s[GX_INPROGRESS_BIT]) + #self.comb += pad_SBUS_DATA_OE_LED.eq(draw_blit_overflow) + #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_do_draw & fbc_s[GX_INPROGRESS_BIT]) + #self.comb += pad_SBUS_DATA_OE_LED.eq(fbc_do_blit & fbc_s[GX_INPROGRESS_BIT]) + + self.sync += fbc_s[GX_FULL_BIT].eq(fbc_do_draw | fbc_do_blit | self.fbc_fifo_font.readable) + self.sync += fbc_s[27].eq(fbc_do_draw) + self.sync += fbc_s[26].eq(fbc_do_blit) + self.sync += fbc_s[25].eq(self.fbc_fifo_font.readable) + self.sync += fbc_s[24].eq(~local_reset) + #self.sync += fbc_s[0].eq(draw_blit_overflow) + + #fbc_s[GX_FULL_BIT].eq(fbc_do_draw | fbc_do_blit | self.fbc_fifo_font.readable) self.sync += [ self.fbc_fifo_font.re.eq(0), @@ -324,9 +353,9 @@ class CG6Accel(Module): # AutoCSR ? i_iBusWishbone_DAT_MISO = ibus.dat_r, o_iBusWishbone_DAT_MOSI = ibus.dat_w, o_iBusWishbone_SEL = ibus.sel, - i_iBusWishbone_ERR = ibus.err, - o_iBusWishbone_CTI = ibus.cti, - o_iBusWishbone_BTE = ibus.bte, + #i_iBusWishbone_ERR = ibus.err, + #o_iBusWishbone_CTI = ibus.cti, + #o_iBusWishbone_BTE = ibus.bte, o_dBusWishbone_CYC = dbus.cyc, o_dBusWishbone_STB = dbus.stb, i_dBusWishbone_ACK = dbus.ack,