From 6ca083930098ee075c8f61cf2c04d616349959c3 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 31 Jul 2010 19:12:26 +0300 Subject: [PATCH] wiz blitters, fb restore, tweaks --- common/host_fb.c | 119 ++++++++++++++++++++++++----------- common/host_fb.h | 7 ++- common/wiz_video.c | 53 ++++++++++++++++ common/wiz_video_arm.s | 139 +++++++++++++++++++++++++++++++++++++++++ dist/ginge.gpe | 7 ++- dist/ginge.sh | 2 +- loader/Makefile | 3 +- loader/emu.c | 13 ++-- make_wiz.sh | 1 + prep/main.c | 11 ++++ 10 files changed, 307 insertions(+), 48 deletions(-) create mode 100644 common/wiz_video_arm.s diff --git a/common/host_fb.c b/common/host_fb.c index 46467d4..94910ec 100644 --- a/common/host_fb.c +++ b/common/host_fb.c @@ -14,6 +14,7 @@ static int host_stride; #include "fbdev.c" static struct vout_fbdev *fbdev; +static unsigned short host_pal[256]; void *host_video_flip(void) { @@ -42,39 +43,13 @@ int host_video_init(int *stride, int no_dblbuf) return 0; } -#elif defined(WIZ) - -#include "warm.c" -#include "wiz_video.c" - -void *host_video_flip(void) +void host_video_finish(void) { - vout_gp2x_flip(); - host_screen = g_screen_ptr; - return host_screen; + vout_fbdev_finish(fbdev); + fbdev = NULL; } -int host_video_init(int *stride, int no_dblbuf) -{ - int ret; - - host_stride = 320 * 2; - if (stride != 0) - *stride = host_stride; - - ret = vout_gp2x_init(no_dblbuf); - if (ret != 0) - return ret; - - host_video_flip(); - return 0; -} - -#endif - -static unsigned short host_pal[256]; - -static void host_update_pal(unsigned int *pal) +void host_video_update_pal(unsigned int *pal) { unsigned short *dstp = host_pal; int i; @@ -85,15 +60,16 @@ static void host_update_pal(unsigned int *pal) } } -void host_video_blit4(const unsigned char *src, int w, int h, unsigned int *pal) +void host_video_change_bpp(int bpp) +{ +} + +void host_video_blit4(const unsigned char *src, int w, int h) { unsigned short *dst = host_screen; unsigned short *hpal = host_pal; int i, u; - if (pal != NULL) - host_update_pal(pal); - for (i = 0; i < 240; i++, dst += host_stride / 2 - 320) { for (u = 320 / 2; u > 0; u--, src++) { *dst++ = hpal[*src >> 4]; @@ -104,15 +80,12 @@ void host_video_blit4(const unsigned char *src, int w, int h, unsigned int *pal) host_video_flip(); } -void host_video_blit8(const unsigned char *src, int w, int h, unsigned int *pal) +void host_video_blit8(const unsigned char *src, int w, int h) { unsigned short *dst = host_screen; unsigned short *hpal = host_pal; int i, u; - if (pal != NULL) - host_update_pal(pal); - for (i = 0; i < 240; i++, dst += host_stride / 2 - 320) { for (u = 320 / 4; u > 0; u--) { *dst++ = hpal[*src++]; @@ -136,3 +109,73 @@ void host_video_blit16(const unsigned short *src, int w, int h) host_video_flip(); } +#elif defined(WIZ) + +#include "warm.c" +#include "wiz_video.c" + +void *host_video_flip(void) +{ + vout_gp2x_flip(); + host_screen = g_screen_ptr; + return host_screen; +} + +int host_video_init(int *stride, int no_dblbuf) +{ + int ret; + + host_stride = 320 * 2; + if (stride != 0) + *stride = host_stride; + + ret = vout_gp2x_init(no_dblbuf); + if (ret != 0) + return ret; + + vout_gp2x_set_mode(16, !no_dblbuf); + host_video_flip(); + return 0; +} + +void host_video_finish(void) +{ + vout_gp2x_finish(); +} + +void host_video_update_pal(unsigned int *pal) +{ + vout_gp2x_set_palette(pal, 256); +} + +void host_video_change_bpp(int bpp) +{ + vout_gp2x_set_mode(bpp, 1); +} + +#ifdef LOADER +void host_video_blit4(const unsigned char *src, int w, int h) +{ + memcpy(host_screen, src, 320*240/2); // FIXME + host_video_flip(); +} + +void host_video_blit8(const unsigned char *src, int w, int h) +{ + extern void rotated_blit8(void *dst, const void *linesx4); + + rotated_blit8(host_screen, src); + host_video_flip(); +} + +void host_video_blit16(const unsigned short *src, int w, int h) +{ + extern void rotated_blit16(void *dst, const void *linesx4); + + rotated_blit16(host_screen, src); + host_video_flip(); +} +#endif // LOADER + +#endif // WIZ + diff --git a/common/host_fb.h b/common/host_fb.h index edb931b..1fcfdc3 100644 --- a/common/host_fb.h +++ b/common/host_fb.h @@ -1,6 +1,9 @@ int host_video_init(int *stride, int no_dblbuf); +void host_video_finish(void); void *host_video_flip(void); +void host_video_change_bpp(int bpp); +void host_video_update_pal(unsigned int *pal); -void host_video_blit4(const unsigned char *src, int w, int h, unsigned int *pal); -void host_video_blit8(const unsigned char *src, int w, int h, unsigned int *pal); +void host_video_blit4(const unsigned char *src, int w, int h); +void host_video_blit8(const unsigned char *src, int w, int h); void host_video_blit16(const unsigned short *src, int w, int h); diff --git a/common/wiz_video.c b/common/wiz_video.c index 7996ee3..999fc06 100644 --- a/common/wiz_video.c +++ b/common/wiz_video.c @@ -100,6 +100,59 @@ static int vout_gp2x_init(int no_dblbuf) return 0; } +static void vout_gp2x_set_mode(int bpp, int rot) +{ + int rot_cmd[2] = { 0, 0 }; + int code = 0, bytes = 2; + unsigned int r; + int ret; + + rot_cmd[0] = rot ? 6 : 5; + ret = ioctl(fbdev, _IOW('D', 90, int[2]), rot_cmd); + if (ret < 0) + perror("rot ioctl failed"); + + memregl[0x4004>>2] = rot ? 0x013f00ef : 0x00ef013f; + memregl[0x4000>>2] |= 1 << 3; + + switch (bpp) + { + case 8: + code = 0x443a; + bytes = 1; + break; + + case 15: + case 16: + code = 0x4432; + bytes = 2; + break; + + default: + fprintf(stderr, "unhandled bpp request: %d\n", abs(bpp)); + return; + } + + memregl[0x405c>>2] = bytes; + memregl[0x4060>>2] = bytes * (rot ? 240 : 320); + + r = memregl[0x4058>>2]; + r = (r & 0xffff) | (code << 16) | 0x10; + memregl[0x4058>>2] = r; +} + +static void vout_gp2x_set_palette(unsigned int *pal, int len) +{ + /* pollux palette is 16bpp only.. */ + int i; + for (i = 0; i < len; i++) + { + int c = pal[i]; + c = ((c >> 8) & 0xf800) | ((c >> 5) & 0x07c0) | ((c >> 3) & 0x001f); + memregl[0x4070>>2] = (i << 24) | c; + } +} + void vout_gp2x_finish(void) { memregl[0x406C>>2] = fb_paddr[0]; diff --git a/common/wiz_video_arm.s b/common/wiz_video_arm.s new file mode 100644 index 0000000..d538ad1 --- /dev/null +++ b/common/wiz_video_arm.s @@ -0,0 +1,139 @@ +@ vim:filetype=armasm + +@ input: r2-r5 +@ output: r7,r8 +@ trash: r6 +.macro rb_line_low + mov r6, r2, lsl #16 + mov r7, r3, lsl #16 + orr r7, r7, r6, lsr #16 + mov r6, r4, lsl #16 + mov r8, r5, lsl #16 + orr r8, r8, r6, lsr #16 +.endm + +.macro rb_line_hi + mov r6, r2, lsr #16 + mov r7, r3, lsr #16 + orr r7, r6, r7, lsl #16 + mov r6, r4, lsr #16 + mov r8, r5, lsr #16 + orr r8, r6, r8, lsl #16 +.endm + +.global rotated_blit16 @ void *dst, void *linesx4 +rotated_blit16: + stmfd sp!,{r4-r8,lr} + + sub r0, r0, #240*2 @ adjust + mov lr, #240/4 + +rotated_blit_loop16_o: + orr lr, lr, #((320/4)-1) << 16 + add r0, r0, #(240*320)*2 + +rotated_blit_loop16: + ldr r2, [r1, #320*0*2] + ldr r3, [r1, #320*1*2] + ldr r4, [r1, #320*2*2] + ldr r5, [r1, #320*3*2] + rb_line_low + stmia r0, {r7,r8} + sub r0, r0, #240*2 + rb_line_hi + stmia r0, {r7,r8} + sub r0, r0, #240*2 + + ldr r2, [r1, #320*0*2+4] + ldr r3, [r1, #320*1*2+4] + ldr r4, [r1, #320*2*2+4] + ldr r5, [r1, #320*3*2+4] + rb_line_low + stmia r0, {r7,r8} + sub r0, r0, #240*2 + rb_line_hi + stmia r0, {r7,r8} + sub r0, r0, #240*2 + + subs lr, lr, #1<<16 + add r1, r1, #8 + bpl rotated_blit_loop16 + + add lr, lr, #1<<16 + subs lr, lr, #1 + + add r0, r0, #4*2 + add r1, r1, #(320*3)*2 + bgt rotated_blit_loop16_o + + ldmfd sp!,{r4-r8,pc} + + +.global rotated_blit8 @ void *dst, void *linesx4 +rotated_blit8: + stmfd sp!,{r4-r8,lr} + + mov r8, #320 + sub r0, r0, #240 @ adjust + mov lr, #240/4 + +rotated_blit8_loop_o: + orr lr, lr, #((320/4)-1) << 16 + add r0, r0, #(240*320) + +rotated_blit8_loop: + mov r6, r1 + ldr r2, [r6], r8 + ldr r3, [r6], r8 + ldr r4, [r6], r8 + ldr r5, [r6], r8 + + mov r6, r2, lsl #24 + mov r6, r6, lsr #8 + orr r6, r6, r3, lsl #24 + mov r6, r6, lsr #8 + orr r6, r6, r4, lsl #24 + mov r6, r6, lsr #8 + orr r6, r6, r5, lsl #24 + str r6, [r0], #-240 + + and r6, r3, #0xff00 + and r7, r2, #0xff00 + orr r6, r6, r7, lsr #8 + and r7, r4, #0xff00 + orr r6, r6, r7, lsl #8 + and r7, r5, #0xff00 + orr r6, r6, r7, lsl #16 + str r6, [r0], #-240 + + and r6, r4, #0xff0000 + and r7, r2, #0xff0000 + orr r6, r6, r7, lsr #16 + and r7, r3, #0xff0000 + orr r6, r6, r7, lsr #8 + and r7, r5, #0xff0000 + orr r6, r6, r7, lsl #8 + str r6, [r0], #-240 + + mov r6, r5, lsr #24 + mov r6, r6, lsl #8 + orr r6, r6, r4, lsr #24 + mov r6, r6, lsl #8 + orr r6, r6, r3, lsr #24 + mov r6, r6, lsl #8 + orr r6, r6, r2, lsr #24 + str r6, [r0], #-240 + + subs lr, lr, #1<<16 + add r1, r1, #4 + bpl rotated_blit8_loop + + add lr, lr, #1<<16 + subs lr, lr, #1 + + add r0, r0, #4 + add r1, r1, #320*3 + bgt rotated_blit8_loop_o + + ldmfd sp!,{r4-r8,pc} + diff --git a/dist/ginge.gpe b/dist/ginge.gpe index 27521e5..0ca9ad1 100755 --- a/dist/ginge.gpe +++ b/dist/ginge.gpe @@ -1,7 +1,9 @@ #!/bin/sh +unset LD_PRELOAD + /sbin/rmmod warm 2> /dev/null -/sbin/insmod ./warm_2.6.24.ko +/sbin/insmod ./tools/warm_2.6.24.ko # theoretically GP2X apps can make use of more RAM, because # Wiz has 2.6 kernel (larger memory requirements) and larger @@ -9,6 +11,7 @@ mkswap swapfile swapon swapfile -./gp2xmenu +./gp2xmenu --view-game swapoff swapfile +/sbin/rmmod warm 2> /dev/null diff --git a/dist/ginge.sh b/dist/ginge.sh index 66a99e1..69e4b3a 100755 --- a/dist/ginge.sh +++ b/dist/ginge.sh @@ -4,7 +4,7 @@ export FBDEV=/dev/fb1 ofbset -fb $FBDEV -pos 80 0 -size 640 480 -mem 614400 -en 1 fbset -fb $FBDEV -g 320 240 320 480 16 -# make ir runnable from ssh +# make it runnable from ssh if [ -z "$DISPLAY" ]; then export DISPLAY=:0 fi diff --git a/loader/Makefile b/loader/Makefile index 0a28670..b546c7c 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -28,10 +28,11 @@ OBJ += host_pnd.o endif ifdef WIZ CFLAGS += -DWIZ -OBJ += host_wiz.o +OBJ += host_wiz.o wiz_video_arm.o endif vpath %.c = ../common/ +vpath %.s = ../common/ TARGET_S = ginge_sloader TARGET_D = ginge_dyn diff --git a/loader/emu.c b/loader/emu.c index 3ab4b34..993ed55 100644 --- a/loader/emu.c +++ b/loader/emu.c @@ -269,21 +269,26 @@ bad_blit: // FIXME: pass real dimensions to blitters static void mlc_flip(void *src, int bpp) { - u32 *srcp = NULL; + static int old_bpp; // only pass pal to host if it's dirty if (bpp <= 8 && mmsp2.dirty_pal) { - srcp = mmsp2.mlc_stl_pallt_d32; + host_video_update_pal(mmsp2.mlc_stl_pallt_d32); mmsp2.dirty_pal = 0; } + if (bpp != old_bpp) { + host_video_change_bpp(bpp); + old_bpp = bpp; + } + switch (bpp) { case 4: - host_video_blit4(src, 320, 240, srcp); + host_video_blit4(src, 320, 240); break; case 8: - host_video_blit8(src, 320, 240, srcp); + host_video_blit8(src, 320, 240); break; case 16: diff --git a/make_wiz.sh b/make_wiz.sh index 9176fc2..cc8f2b0 100755 --- a/make_wiz.sh +++ b/make_wiz.sh @@ -8,5 +8,6 @@ cp dist/ginge.gpe out_wiz/ cp dist/ginge32.png out_wiz/ginge.png cp dist/ginge_dyn_oabi.sh out_wiz/ginge_dyn.sh cp tools/cramfsck_oabi out_wiz/tools/cramfsck +cp tools/warm_2.6.24.ko out_wiz/tools/ dd if=/dev/zero of=out_wiz/swapfile bs=1M count=16 diff --git a/prep/main.c b/prep/main.c index 8acbef7..a03bc38 100644 --- a/prep/main.c +++ b/prep/main.c @@ -258,6 +258,13 @@ int main(int argc, char *argv[]) return 1; } + if (strcmp(argv[1], "--cleanup") == 0) { + // as loader may crash eny time, restore screen for them menu + host_video_init(NULL, 0); + host_video_finish(); + return 0; + } + if (getcwd(cwd, sizeof(cwd)) == NULL) { err(PFX "failed to get cwd\n"); return 1; @@ -414,6 +421,10 @@ pass: fclose(fin); no_in_script: +#ifdef WIZ + fprintf(fout, "sync\n"); + fprintf(fout, "%sginge_prep --cleanup\n", root_path); +#endif if (rerun_gp2xmenu) { fprintf(fout, "cd %s\n", root_path); fprintf(fout, "exec %s%s\n", root_path, LAUNCHER); -- 2.39.5