OSDN Git Service

scrolling enabled. now opening demo screen is all displayed correctly. motonesemu-0.1.2
authorastoria-d <astoria-d@mail.goo.ne.jp>
Thu, 4 Apr 2013 01:01:01 +0000 (10:01 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Thu, 4 Apr 2013 01:01:01 +0000 (10:01 +0900)
emulator/ppucore/ppucore.c
emulator/ppucore/vram.c
emulator/ppucore/vscreen.c

index 397fb23..e7b608d 100644 (file)
@@ -134,6 +134,7 @@ static int clock_ppu(void) {
     if (scan_x < VSCREEN_WIDTH && scan_y < VSCREEN_HEIGHT) {
         if (scan_x == 0) {
             status_reg.sprite0_hit = 0;
+            status_reg.sprite_overflow = 0;
             if (scan_y == 0) {
                 //start displaying
                 status_reg.vblank = 0;
@@ -147,7 +148,7 @@ static int clock_ppu(void) {
         }
         if (ctrl_reg2.show_bg/**/) {
             //back ground image is pre-loaded. load 1 line ahead of drawline.
-            load_background(scan_x, scan_y);
+            load_background(scan_x + scroll_reg.x, scan_y + scroll_reg.y);
         }
         if (ctrl_reg2.show_sprite) {
             //foreground sprite
@@ -313,6 +314,11 @@ void sprite0_hit_set(void) {
     status_reg.sprite0_hit = 1;
 }
 
+void sprite_overflow_set(void) {
+    //dprint("sprite0 set...\n");
+    status_reg.sprite_overflow = 1;
+}
+
 int ppucore_init(void) {
     int ret;
 
index 058ec18..cb2cfd6 100644 (file)
@@ -48,6 +48,8 @@ void d4_set(int on_off);
  * */
 
 static unsigned char pattern_tbl_get(unsigned char bank, unsigned short offset) {
+    //bank is masked to fit within 0-1
+    bank &= 0x01;
     if (bank == 0)
         return pattern_tbl0[offset];
     else
@@ -55,6 +57,8 @@ static unsigned char pattern_tbl_get(unsigned char bank, unsigned short offset)
 }
 
 static unsigned char name_tbl_get(unsigned char bank, unsigned short offset) {
+    //bank is masked to fit within 0-3
+    bank &= 0x03;
     if (bank == 0)
         return name_tbl0[offset];
     else if (bank == 1)
@@ -66,6 +70,8 @@ static unsigned char name_tbl_get(unsigned char bank, unsigned short offset) {
 }
 
 static void name_tbl_set(unsigned char bank, unsigned short offset, unsigned char data) {
+    //bank is masked to fit within 0-3
+    bank &= 0x03;
     if (bank == 0)
         name_tbl0[offset] = data;
     else if (bank == 1)
@@ -78,6 +84,8 @@ static void name_tbl_set(unsigned char bank, unsigned short offset, unsigned cha
 
 
 static unsigned char attr_tbl_get(unsigned char bank, unsigned short offset) {
+    //bank is masked to fit within 0-3
+    bank &= 0x03;
     if (bank == 0)
         return attr_tbl0[offset];
     else if (bank == 1)
@@ -89,6 +97,8 @@ static unsigned char attr_tbl_get(unsigned char bank, unsigned short offset) {
 }
 
 static void attr_tbl_set(unsigned char bank, unsigned short offset, unsigned char data) {
+    //bank is masked to fit within 0-3
+    bank &= 0x03;
     if (bank == 0)
         attr_tbl0[offset] = data;
     else if (bank == 1)
index e10995b..3d8cb12 100644 (file)
@@ -12,6 +12,7 @@ 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_palette(struct sprite_attr sa, struct palette *plt);
 void sprite0_hit_set(void);
+void sprite_overflow_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);
@@ -80,8 +81,36 @@ void set_vscreen_pos(int x, int y) {
 int load_background(int x, int y) {
     //dprint("load bg x:%d, y:%d...\n", x, y);
     int inner_x, inner_y;
+    unsigned short name_base;
+    unsigned short attr_bank;
+
+    //TODO name/attr table switch must be set with respect to the cartridge mapper setting.
+    if (x >= VSCREEN_WIDTH) {
+        x -= VSCREEN_WIDTH;
+        if (y >= VSCREEN_HEIGHT) {
+            y -= VSCREEN_HEIGHT;
+            name_base = bg_name_tbl_base + (NAME_TBL_SIZE + ATTR_TBL_SIZE) * 3;
+            attr_bank = bg_attr_tbl_bank + 3;
+        }
+        else {
+            name_base = bg_name_tbl_base + NAME_TBL_SIZE + ATTR_TBL_SIZE;
+            attr_bank = bg_attr_tbl_bank + 1;
+        }
+    }
+    else {
+        if (y >= VSCREEN_HEIGHT) {
+            y -= VSCREEN_HEIGHT;
+            name_base = bg_name_tbl_base + (NAME_TBL_SIZE + ATTR_TBL_SIZE) * 2;
+            attr_bank = bg_attr_tbl_bank + 2;
+        }
+        else {
+            name_base = bg_name_tbl_base;
+            attr_bank = bg_attr_tbl_bank;
+        }
+    }
 
     //tile loading happens every 8 dots only.
+    //TODO must check if the tile is loaded due to the in-draw scrolling??.
     if (x % TILE_DOT_SIZE == 0) {
         int tile_id, tile_id_x, tile_id_y;
         unsigned char name_index;
@@ -91,8 +120,8 @@ int load_background(int x, int y) {
         tile_id = tile_id_x + tile_id_y * H_SCREEN_TILE_SIZE;
 
         //dprint("load tile.\n");
-        load_attribute(bg_attr_tbl_bank, tile_id, &bg_plt);
-        name_index = vram_data_get(bg_name_tbl_base + tile_id);
+        load_attribute(attr_bank, tile_id, &bg_plt);
+        name_index = vram_data_get(name_base + tile_id);
         load_pattern(bg_pattern_bank, name_index, &bg_ptn);
     }
 
@@ -143,6 +172,9 @@ int sprite_prefetch1(int srch_line) {
             sprite_hit_cnt++;
         }
     }
+    if (sprite_hit_cnt > SPRITE_PREFETCH_CNT) {
+        sprite_overflow_set();
+    }
     return sprite_hit_cnt;
 }