OSDN Git Service

vscreen layout changed and improved execution logic.
authorastoria-d <astoria-d@mail.goo.ne.jp>
Sun, 31 Mar 2013 03:30:58 +0000 (12:30 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Sun, 31 Mar 2013 03:30:58 +0000 (12:30 +0900)
code clean up, etc.

emulator/ppucore/dummy-driver2.c
emulator/ppucore/ppucore.c
emulator/ppucore/sprite.h
emulator/ppucore/vga_xfer.c
emulator/ppucore/vram.c
emulator/ppucore/vscreen.c

index 514fcc4..781ed3f 100644 (file)
@@ -120,6 +120,7 @@ static void test_ppu(void) {
     //bg&sprite show
     ppu_ctrl2_set(0x18);
 
+    /*
     for (i = 0; i < 960; i++) 
         set_bgtile(i);
 
@@ -134,6 +135,7 @@ static void test_ppu(void) {
     set_sprite(50, 100, 'd', sa);
     sa.flip_v = 1;
     set_sprite(70, 105, 'd', sa);
+*/
 
     struct timespec begin, end;
     clock_gettime(CLOCK_REALTIME, &begin);
index 6e637e9..1384f96 100644 (file)
@@ -22,7 +22,7 @@ void spr_ram_tbl_set(unsigned short offset, unsigned char data);
 
 int sprite_prefetch1(int srch_line);
 int sprite_prefetch2(int srch_line);
-int load_sprite(int foreground, int x, int y);
+int load_sprite(int background, int x, int y);
 int load_background(int x, int y);
 void vga_xfer(int x, int y);
 void vga_posinit(void);
@@ -118,7 +118,7 @@ static int scan_recovery(void) {
      * Sprite reg:
      * Stores the y-coordinate of the top left of the sprite minus 1
      * */
-    if (scan_x == VSCREEN_WIDTH) {
+    if (scan_x == VSCREEN_WIDTH && scan_y < VSCREEN_HEIGHT) {
         int next_line = (scan_y == VSCAN_MAX - 1 ? 0 : scan_y + 1);
         sprite_prefetch1(next_line);
         sprite_prefetch2(next_line);
@@ -142,7 +142,7 @@ static int clock_ppu(void) {
 
         if (ctrl_reg2.show_sprite) {
             //sprite in the back
-            load_sprite(FALSE, scan_x, scan_y);
+            load_sprite(TRUE, scan_x, scan_y);
         }
         if (ctrl_reg2.show_bg/**/) {
             //back ground image is pre-loaded. load 1 line ahead of drawline.
@@ -150,7 +150,7 @@ static int clock_ppu(void) {
         }
         if (ctrl_reg2.show_sprite) {
             //foreground sprite
-            load_sprite(TRUE, scan_x, scan_y);
+            load_sprite(FALSE, scan_x, scan_y);
         }
         vga_xfer(scan_x, scan_y);
     }
@@ -358,7 +358,7 @@ int ppucore_init(void) {
         return FALSE;
     }
 
-    vga_posinit();
+    //vga_posinit();
 
     return TRUE;
 }
index 2effa6d..bd6b00a 100644 (file)
@@ -9,7 +9,7 @@
 struct sprite_attr {
     unsigned int palette    :2;
     unsigned int unused     :3;
-    unsigned int priority   :1;
+    unsigned int priority   :1;     /*0: foreground, 1:background.*/
     unsigned int flip_h     :1;
     unsigned int flip_v     :1;
 } __attribute__ ((packed));
index 493359b..71cc1b0 100644 (file)
@@ -4,7 +4,7 @@
 #include "ppucore.h"
 
 void vscreenn_dot_get(int x, int y, struct rgb15 *col);
-struct rgb15 *get_vscreen_head(void);
+struct rgb15* get_current_vscreen(void);
 
 #define VSCREEN_WIDTH       (H_SCREEN_TILE_SIZE * TILE_DOT_SIZE)
 #define VSCREEN_HEIGHT      (V_SCREEN_TILE_SIZE * TILE_DOT_SIZE)
@@ -48,62 +48,9 @@ void show_leftside_sprite(void) {
 void show_leftside_bg(void) {
 }
 
-static int vga_y;
-static int vscrn_y, vscrn_y_old;
 static struct rgb15 *vga_col;
-
-void vga_xfer_old(int scanline) {
-    int vscrn_x, vscrn_x_old;
-    int vga_x;
-    struct rgb15 *col_old;
-
-    if (scanline == 0) {
-        vga_y = 0;
-        vscrn_y_old = -1;
-        vga_col = vga_base;
-    }
-
-    vscrn_x_old = -1;
-    col_old = vga_col;
-    while (1) {
-        vscrn_y = vga_y * VSCREEN_HEIGHT / VGA_HEIGHT;
-        if (vscrn_y != scanline)
-            break;
-
-        if (vscrn_y != vscrn_y_old) {
-            for (vga_x = 0; vga_x < VGA_WIDTH; vga_x++) {
-                vscrn_x = vga_x * VSCREEN_WIDTH / VGA_WIDTH;
-                if (vscrn_x != vscrn_x_old) {
-                    vscreenn_dot_get(vscrn_x, vscrn_y, vga_col);
-                }
-                else {
-                    *vga_col = *col_old;
-                }
-
-                vscrn_x_old = vscrn_x;
-                col_old = vga_col;
-                vga_col++;
-            }
-        }
-        else {
-            memcpy(vga_col, col_old, VGA_WIDTH * sizeof (struct rgb15));
-            col_old = vga_col;
-            vga_col += VGA_WIDTH;
-        }
-
-        vga_y++;
-        vscrn_y_old = vscrn_y;
-    }
-}
-
-static struct rgb15 *vs_col, *vs_head;
-static struct rgb15 *vga_col;
-
-void vga_posinit(void) {
-    vs_head = (struct rgb15 *)get_vscreen_head();
-}
-
 void vga_xfer(int vs_x, int vs_y) {
+    struct rgb15 *vs_col;
     int vga_x, vga_y, vga_x_next;
     struct rgb15 *vga_col_next;
 
@@ -111,29 +58,14 @@ void vga_xfer(int vs_x, int vs_y) {
     //x direction scale is 640/256.
     //y direction scale is 480/240
 
-    if (vs_x == 0) {
-        int tile_id, tile_id_y;
-        int inner_y;
-
-        tile_id_y = vs_y / TILE_DOT_SIZE;
-        tile_id = tile_id_y * H_SCREEN_TILE_SIZE;
-        inner_y = vs_y % TILE_DOT_SIZE;
-            
-        vs_col = vs_head + tile_id * TILE_DOT_SIZE * TILE_DOT_SIZE + inner_y * TILE_DOT_SIZE;
-
-        vga_y = vs_y * VGA_HEIGHT / VSCREEN_HEIGHT;
+    vs_col = get_current_vscreen();
+    if (vs_col == NULL)
+        return ;
+    vga_x = vs_x * VGA_WIDTH / VSCREEN_WIDTH;
+    vga_y = vs_y * VGA_HEIGHT / VSCREEN_HEIGHT;
+    if (vs_x == 0) 
         vga_col = vga_base + vga_y * VGA_WIDTH;
-    }
-    else {
-        if (vs_x % TILE_DOT_SIZE) {
-            vs_col++;
-        }
-        else {
-            vs_col += (TILE_DOT_SIZE - 1) * TILE_DOT_SIZE + 1;
-        }
-    }
 
-    vga_x = vs_x * VGA_WIDTH / VSCREEN_WIDTH;
     vga_x_next = (vs_x + 1) * VGA_WIDTH / VSCREEN_WIDTH;
     vga_col_next = vga_col + vga_x_next - vga_x;
 
@@ -145,7 +77,6 @@ void vga_xfer(int vs_x, int vs_y) {
         *(vga_col + VGA_WIDTH) = *vs_col;
         vga_col++;
     }
-
 }
 
 int vga_xfer_init(void) {
index 99f7c94..058ec18 100644 (file)
@@ -398,7 +398,7 @@ void load_attribute(unsigned char bank, int tile_index, struct palette *plt) {
 
 }
 
-void load_spr_attribute(struct sprite_attr sa, struct palette *plt) {
+void load_spr_palette(struct sprite_attr sa, struct palette *plt) {
     unsigned short palette_addr;
     unsigned char pi;
 
index 436b8c8..c5df26d 100644 (file)
 
 void load_attribute(unsigned char bank, int tile_index, struct palette *plt);
 void load_pattern(unsigned char bank, unsigned char ptn_index, struct tile_2* pattern);
-void load_spr_attribute(struct sprite_attr sa, struct palette *plt);
+void load_spr_palette(struct sprite_attr sa, struct palette *plt);
 void sprite0_hit_set(void);
 unsigned char spr_ram_tbl_get(unsigned short offset);
 unsigned char vram_data_get(unsigned short addr);
 void palette_index_to_rgb15(unsigned char index, struct rgb15* rgb);
 
-
 #define TRANSPARENT_PALETTE_ADDR        0x3F10
 
-struct tile_rgb15_line {
-    struct rgb15 d[8];
-};
-
-struct tile_rgb15 {
-    struct tile_rgb15_line l[8];
-};
-
 struct sprite_buf_reg {
     struct palette plt;
     struct tile_2 ptn;
     int sprite_num;
 };
 
-static struct tile_rgb15 *vscreen;
+static struct rgb15 *vscreen;
 
 static unsigned char bg_pattern_bank;
 static unsigned char spr_pattern_bank;
 static unsigned short   bg_name_tbl_base;
 static unsigned char    bg_attr_tbl_bank;
 
-
 #define SPRITE_PREFETCH_CNT     8
 static struct ppu_sprite_reg sprite_temp_buf [SPRITE_PREFETCH_CNT];
 static struct sprite_buf_reg sprite_buf [SPRITE_PREFETCH_CNT];
 static int sprite_hit_cnt;
 static int bg_transparent;
 
-void vscreenn_dot_get(int x, int y, struct rgb15 *col) {
-    int tile_id, tile_id_x, tile_id_y;
-    int inner_x, inner_y;
-    struct tile_rgb15* tile;
-
-    tile_id_x = x / TILE_DOT_SIZE;
-    tile_id_y = y / TILE_DOT_SIZE;
-    tile_id = tile_id_x + tile_id_y * H_SCREEN_TILE_SIZE;
-    tile = vscreen + tile_id;
-
-    inner_x = x % TILE_DOT_SIZE;
-    inner_y = y % TILE_DOT_SIZE;
-    *col = tile->l[inner_y].d[inner_x];
-}
-
-void vscreenn_dot_set(int x, int y, struct rgb15 *col) {
-    int tile_id, tile_id_x, tile_id_y;
-    int inner_x, inner_y;
-    struct tile_rgb15* tile;
-
-    tile_id_x = x / TILE_DOT_SIZE;
-    tile_id_y = y / TILE_DOT_SIZE;
-    tile_id = tile_id_x + tile_id_y * H_SCREEN_TILE_SIZE;
-    tile = vscreen + tile_id;
-
-    inner_x = x % TILE_DOT_SIZE;
-    inner_y = y % TILE_DOT_SIZE;
-    tile->l[inner_y].d[inner_x] = *col;
-}
-
 static int pal_index(struct tile_2 *ptn, int l, int dot_x) {
     switch (dot_x) {
         case 0:
@@ -99,65 +59,24 @@ static int pal_index(struct tile_2 *ptn, int l, int dot_x) {
     }
 }
 
-void set_bgtile(int tile_id) {
-    struct palette plt;
-    struct tile_2 ptn;
-    unsigned char name_index;
-    struct tile_rgb15* set_data;
-    int i,j;
-
-    load_attribute(bg_attr_tbl_bank, tile_id, &plt);
-
-    name_index = vram_data_get(bg_name_tbl_base + tile_id);
-    load_pattern(bg_pattern_bank, name_index, &ptn);
-
-    set_data = vscreen + tile_id;
-    for (i = 0; i < TILE_DOT_SIZE; i++) {
-        //display shows left to right with high bit to low bit
-        for (j = 0; j < 8; j++) {
-            int pi = pal_index(&ptn, i, j);
-            if (pi) {
-                //dprint("%d, %d, colind:%d\n", j, i, pi);
-                set_data->l[i].d[7 - j] = plt.col[pi];
-            }
-            else {
-                //transparent bg color is read from sprite 0x10 color.
-                pi = vram_data_get(TRANSPARENT_PALETTE_ADDR);
-                palette_index_to_rgb15(pi, &set_data->l[i].d[7 - j]);
-                /*
-                set_data->l[i].d[7 - j].r = 0;
-                set_data->l[i].d[7 - j].g = 0;
-                set_data->l[i].d[7 - j].b = 0;
-                */
-            }
-        }
-    }
-
-}
-
-int load_background_old(int scanline) {
-    int i, start, end;
-
-    //load tile must be executed every 8 scanlines only.
-    if (scanline % TILE_DOT_SIZE)
-        return TRUE;
-
-    start = scanline / TILE_DOT_SIZE * H_SCREEN_TILE_SIZE;
-    end = start + H_SCREEN_TILE_SIZE;
-    for (i = start; i < end; i++) {
-        set_bgtile(i);
-    }
-    return TRUE;
-}
-
 static struct palette plt;
 static struct tile_2 ptn;
-static struct tile_rgb15* set_data;
+static struct rgb15* set_data;
+
+struct rgb15* get_current_vscreen(void) {
+    return set_data;
+}
 int load_background(int x, int y) {
     //dprint("load bg x:%d, y:%d...\n", x, y);
 
     int inner_x, inner_y;
 
+    if (x == 0 && y == 0) {
+        set_data = vscreen + x + y * H_SCREEN_TILE_SIZE * TILE_DOT_SIZE;
+    }
+    else {
+        set_data++;
+    }
 
     //tile loading happens every 8 dots only.
     if (x % TILE_DOT_SIZE == 0) {
@@ -172,106 +91,28 @@ int load_background(int x, int y) {
         load_attribute(bg_attr_tbl_bank, tile_id, &plt);
         name_index = vram_data_get(bg_name_tbl_base + tile_id);
         load_pattern(bg_pattern_bank, name_index, &ptn);
-        set_data = vscreen + tile_id;
     }
 
-
-    inner_x = x % TILE_DOT_SIZE;
+    //pattern dot is stored right to left order (little endian.).
+    inner_x = 7 - x % TILE_DOT_SIZE;
     inner_y = y % TILE_DOT_SIZE;
 
     int pi = pal_index(&ptn, inner_y, inner_x);
     if (pi) {
         //dprint("%d, %d, colind:%d\n", j, i, pi);
-        set_data->l[inner_y].d[7 - inner_x] = plt.col[pi];
+        *set_data = plt.col[pi];
         bg_transparent = FALSE;
     }
     else {
         //transparent bg color is read from sprite 0x10 color.
         pi = vram_data_get(TRANSPARENT_PALETTE_ADDR);
-        palette_index_to_rgb15(pi, &set_data->l[inner_y].d[7 - inner_x]);
+        palette_index_to_rgb15(pi, set_data);
         bg_transparent = TRUE;
     }
 
     return TRUE;
 }
 
-
-void set_sprite(int x, int y, int tile_id, struct sprite_attr sa) {
-    struct palette plt;
-    struct tile_2 ptn;
-    int i, j;
-
-    load_spr_attribute(sa, &plt);
-
-    load_pattern(spr_pattern_bank, tile_id, &ptn);
-
-    //display shows left to right with high bit to low bit
-    for (i = 0; i < TILE_DOT_SIZE; i++) {
-        if (sa.flip_h) {
-            if (sa.flip_v) {
-                for (j = 0; j < 8; j++) {
-                    int pi = pal_index(&ptn, i, j);
-                    if (pi)
-                        vscreenn_dot_set(x + j, y + 7 - i, &plt.col[pi]);
-                }
-            }
-            else {
-                for (j = 0; j < 8; j++) {
-                    int pi = pal_index(&ptn, i, j);
-                    if (pi)
-                        vscreenn_dot_set(x + j, y + i, &plt.col[pi]);
-                }
-            }
-        }
-        else {
-            if (sa.flip_v) {
-                for (j = 0; j < 8; j++) {
-                    int pi = pal_index(&ptn, i, j);
-                    if (pi)
-                        vscreenn_dot_set(x + 7 - j, y + 7 - i, &plt.col[pi]);
-                }
-            }
-            else {
-                for (j = 0; j < 8; j++) {
-                    int pi = pal_index(&ptn, i, j);
-                    if (pi)
-                        vscreenn_dot_set(x + 7 - j, y + i, &plt.col[pi]);
-                }
-            }
-        }
-    }
-}
-
-int load_sprite_old(int foreground, int scanline) {
-    int i;
-    struct sprite_attr sa;
-    unsigned char x, y, tile, tmp;
-
-    //sprite priority:
-    //draw lowest priority first, 
-    //high priority late. highest priority comes top.
-    for (i = SPRITE_CNT - 1; i >= 0; i--) {
-        y = spr_ram_tbl_get(4 * i);
-        if (scanline != y)
-            continue;
-
-        tmp = spr_ram_tbl_get(4 * i + 2);
-        memcpy(&sa, &tmp, sizeof(struct sprite_attr));
-        if (sa.priority != foreground)
-            continue;
-
-        tile = spr_ram_tbl_get(4 * i + 1);
-        x = spr_ram_tbl_get(4 * i + 3);
-
-        set_sprite(x, y, tile, sa);
-        if (i == 0) {
-            sprite0_hit_set();
-        }
-    }
-
-    return TRUE;
-}
-
 //prefetch sprite step 1.
 //load sprite temp buffer.
 int sprite_prefetch1(int srch_line) {
@@ -311,13 +152,13 @@ int sprite_prefetch2(int srch_line) {
 
     spr_buf_bottom = sprite_hit_cnt > SPRITE_PREFETCH_CNT ? SPRITE_PREFETCH_CNT : sprite_hit_cnt;
     for (i = 0; i < spr_buf_bottom; i++) {
-        load_spr_attribute(sprite_temp_buf[i].sa, &sprite_buf[i].plt);
+        load_spr_palette(sprite_temp_buf[i].sa, &sprite_buf[i].plt);
         load_pattern(spr_pattern_bank, sprite_temp_buf[i].index, &sprite_buf[i].ptn);
     }
     return spr_buf_bottom;
 }
 
-int load_sprite(int foreground, int x, int y) {
+int load_sprite(int background, int x, int y) {
     int i;
     int spr_buf_bottom;
     int pi;
@@ -332,7 +173,9 @@ int load_sprite(int foreground, int x, int y) {
             int x_in, y_in;
             int draw_x_in, draw_y_in;
 
-            if (sprite_temp_buf[i].sa.priority != foreground)
+            set_data->r = set_data->g = set_data->b = 0;
+
+            if (sprite_temp_buf[i].sa.priority != background)
                 continue;
 
             x_in = x % TILE_DOT_SIZE;
@@ -356,16 +199,18 @@ int load_sprite(int foreground, int x, int y) {
                 }
             }
 
-            //dprint("spr#%d, dot set x:%d, y:%d\n", sprite_temp_buf[i].index, x, y);
             pi = pal_index(&sprite_buf[i].ptn, draw_y_in, draw_x_in);
             if (pi) {
-                vscreenn_dot_set(x, y, &sprite_buf[i].plt.col[pi]);
+                //dprint("spr#%d, id:%d, dot set x:%d, y:%d\n", 
+                 //       sprite_buf[i].sprite_num, sprite_temp_buf[i].index, x, y);
+                *set_data = sprite_buf[i].plt.col[pi];
                 if (sprite_temp_buf[i].sa.priority && sprite_buf[i].sprite_num == 0)
                     sprite0_hit_set();
                 return TRUE;
             }
         }
     }
+    //spr_data->r = spr_data->g = spr_data->b = 0;
 
     return FALSE;
 }
@@ -395,10 +240,6 @@ void set_bg_name_tbl_base(unsigned char sw) {
     bg_attr_tbl_bank = sw;
 }
 
-struct rgb15 *get_vscreen_head(void) {
-    return (struct rgb15 *)vscreen;
-}
-
 int vscreen_init(void) {
     bg_pattern_bank = 0;
     spr_pattern_bank = 0;
@@ -407,11 +248,14 @@ int vscreen_init(void) {
 
     sprite_hit_cnt = 0;
 
-    vscreen = (struct tile_rgb15 *) malloc(
-        sizeof (struct tile_rgb15) * VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE);
+    vscreen = (struct rgb15 *) malloc(
+        sizeof (struct rgb15) * H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE 
+        * TILE_DOT_SIZE * TILE_DOT_SIZE);
     if (vscreen == NULL)
         return FALSE;
-    memset(vscreen, 0, sizeof (struct tile_rgb15) * VIRT_SCREEN_TILE_SIZE * VIRT_SCREEN_TILE_SIZE);
+    memset(vscreen, 0, sizeof (struct rgb15) * H_SCREEN_TILE_SIZE * V_SCREEN_TILE_SIZE 
+        * TILE_DOT_SIZE * TILE_DOT_SIZE);
+    set_data = NULL;
 
     //dprint("tile_1_line:%d tile_2 size:%d\n", sizeof(struct tile_1_line), sizeof(struct tile_2));