OSDN Git Service

ppu test merged.
authorastoria-d <astoria-d@mail.goo.ne.jp>
Sun, 17 Jul 2016 06:56:11 +0000 (15:56 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Sun, 17 Jul 2016 06:56:11 +0000 (15:56 +0900)
15 files changed:
.gitignore
de1_nes/de1_nes.qsf
de1_nes/de1_nes.vhd
de1_nes/dummy-mos6502.vhd
de1_nes/mem/ram.vhd
de1_nes/ppu/vga_ppu.vhd
de1_nes/simulation/modelsim/de1_nes_run_msim_gate_vhdl.do
de1_nes/simulation/modelsim/de1_nes_run_msim_rtl_vhdl.do
doc/mos6502-clock.xlsx [new file with mode: 0644]
doc/mos6502-ppu.xlsx
tools/nes-image/Makefile
tools/nes-image/dd-img.sh
tools/regression-test/Makefile
tools/regression-test/dd-img.sh
tools/regression-test/regression.asm

index e23bf05..ec0c828 100644 (file)
@@ -18,9 +18,4 @@ ref-sdr-sdram-vhdl.zip
 DE1_control_panel
 ~$*
 *.lnk
-<<<<<<< HEAD
-bin2hex*
-=======
-cc65/
-
->>>>>>> bc7cef00d67db16adec9f9c03eeacb3e3a09bbdf
+desktop.ini
index 1967905..e668f4b 100644 (file)
@@ -81,19 +81,21 @@ set_global_assignment -name VHDL_FILE mem/ram.vhd
 set_global_assignment -name VHDL_FILE apu/apu.vhd\r
 \r
 #ppu block...\r
-set_global_assignment -name VHDL_FILE mem/chr_rom.vhd\r
-set_global_assignment -name VHDL_FILE ppu/ppu.vhd\r
-set_global_assignment -name VHDL_FILE ppu/ppu_registers.vhd\r
-set_global_assignment -name VHDL_FILE ppu/vga_ppu.vhd\r
+#set_global_assignment -name VHDL_FILE ppu/ppu_registers.vhd\r
+#set_global_assignment -name VHDL_FILE mem/chr_rom.vhd\r
+#set_global_assignment -name VHDL_FILE ppu/ppu.vhd\r
+#set_global_assignment -name VHDL_FILE ppu/vga_ppu.vhd\r
+\r
+set_global_assignment -name VHDL_FILE "dummy-ppu.vhd"\r
 \r
 #cpu block...\r
-#set_global_assignment -name VHDL_FILE mem/prg_rom.vhd\r
-#set_global_assignment -name VHDL_FILE cpu/alu.vhd\r
-#set_global_assignment -name VHDL_FILE cpu/cpu_registers.vhd\r
-#set_global_assignment -name VHDL_FILE cpu/decoder.vhd\r
-#set_global_assignment -name VHDL_FILE cpu/mos6502.vhd\r
+set_global_assignment -name VHDL_FILE mem/prg_rom.vhd\r
+set_global_assignment -name VHDL_FILE cpu/alu.vhd\r
+set_global_assignment -name VHDL_FILE cpu/cpu_registers.vhd\r
+set_global_assignment -name VHDL_FILE cpu/decoder.vhd\r
+set_global_assignment -name VHDL_FILE cpu/mos6502.vhd\r
 \r
-set_global_assignment -name VHDL_FILE "dummy-mos6502.vhd"\r
+#set_global_assignment -name VHDL_FILE "dummy-mos6502.vhd"\r
 set_global_assignment -name VHDL_FILE de1_nes.vhd\r
 \r
 #need this config to program active serial mode...\r
index 2fdf12b..4d4bfd3 100644 (file)
@@ -328,7 +328,7 @@ begin
     cpu_inst : mos6502 generic map (data_size, addr_size) 
         port map (
     dbg_instruction_dummy,
-    dbg_int_d_bus,
+    dbg_int_d_bus_dummy,
     dbg_exec_cycle_dummy,
     dbg_ea_carry,
  --   dbg_index_bus,
@@ -362,7 +362,7 @@ begin
         dbg_ppu_ce_n                                        ,
         dbg_ppu_ctrl, dbg_ppu_mask, dbg_ppu_status          ,
         dbg_ppu_addr                                        ,
-        dbg_ppu_data, dbg_ppu_scrl_x_dummy, dbg_ppu_scrl_y        ,
+        dbg_ppu_data, dbg_ppu_scrl_x_dummy, dbg_ppu_scrl_y_dummy        ,
 
         dbg_ppu_clk                      ,
         dbg_vga_clk                      ,
@@ -446,10 +446,11 @@ begin
 -----------------------------------------------------------\r
 \r
 --    dbg_exec_cycle(2 downto 1) <= dbg_vga_x(9 downto 8);\r
---    dbg_int_d_bus <= dbg_vga_x(7 downto 0);\r
+    dbg_int_d_bus(4 downto 0) <= dbg_s_oam_addr(4 downto 0);\r
+    dbg_ppu_scrl_y <= dbg_s_oam_data;\r
     dbg_exec_cycle(0) <= dbg_nes_x(8);\r
     dbg_instruction <= dbg_nes_x(7 downto 0);\r
---    dbg_exec_cycle(3) <= dbg_emu_ppu_clk;\r
+    dbg_exec_cycle(3) <= dbg_emu_ppu_clk;\r
 \r
     dbg_exec_cycle(4) <= dbg_nes_y(8);\r
     dbg_status <= dbg_nes_y(7 downto 0);\r
@@ -477,8 +478,6 @@ begin
     dbg_vram_a  <= vram_a ;\r
 \r
     dbg_sp(7 downto 6) <= dbg_ppu_clk_cnt;\r
-    dbg_sp(5 downto 0) <= v_addr (13 downto 8);\r
-    dbg_x <= v_addr (7 downto 0);\r
 \r
     dbg_nmi <= nmi_n;\r
 --    nmi_n <= dummy_nmi;\r
index de2768e..bf1f638 100644 (file)
@@ -58,6 +58,8 @@ begin
     variable nmi_oam_x : integer range 0 to 255;\r
     variable nmi_scl_y : integer range 0 to 255;\r
 \r
+    variable ref_cnt : integer range 0 to 120;\r
+\r
 procedure io_out (ad: in integer; dt : in integer) is\r
 begin\r
     r_nw <= '0';\r
@@ -90,6 +92,7 @@ end;
             nmi_step_cnt := 0;\r
             nmi_oam_x := 0;\r
             nmi_scl_y := 200;\r
+            ref_cnt := 0;\r
 \r
         elsif (rising_edge(input_clk)) then\r
 \r
@@ -199,7 +202,7 @@ end;
                         else\r
                             io_brk;\r
                             if (plt_step_cnt > 30 * cpu_io_multi) then\r
-                                global_step_cnt := global_step_cnt + 1;\r
+                                global_step_cnt := global_step_cnt + 3;\r
                             end if;\r
                         end if;\r
                         plt_step_cnt := plt_step_cnt + 1;\r
@@ -253,7 +256,7 @@ end;
 \r
                         else\r
                             io_brk;\r
-                            if (nt_step_cnt > 17 * cpu_io_multi) then\r
+                            if (nt_step_cnt > 5 * cpu_io_multi) then\r
                                 global_step_cnt := global_step_cnt + 1;\r
                             end if;\r
                         end if;\r
@@ -267,7 +270,7 @@ end;
                             io_out(16#2003#, 16#00#);\r
                         elsif (spr_step_cnt = 1 * cpu_io_multi) then\r
                             --set sprite data: y=02\r
-                            io_out(16#2004#, 16#13#);\r
+                            io_out(16#2004#, 16#01#);\r
                         elsif (spr_step_cnt = 2 * cpu_io_multi) then\r
                             --tile=0x4d (ascii 'M')\r
                             io_out(16#2004#, 16#4d#);\r
@@ -280,7 +283,7 @@ end;
 \r
                         elsif (spr_step_cnt = 5 * cpu_io_multi) then\r
                             --set sprite data: y=50\r
-                            io_out(16#2004#, 16#32#);\r
+                            io_out(16#2004#, 8);\r
                         elsif (spr_step_cnt = 6 * cpu_io_multi) then\r
                             --tile=0x4d (ascii 'O')\r
                             io_out(16#2004#, 16#4f#);\r
@@ -319,7 +322,7 @@ end;
 \r
                         else\r
                             io_brk;\r
-                            if (spr_step_cnt > 4 * cpu_io_multi) then\r
+                            if (spr_step_cnt > 8 * cpu_io_multi) then\r
                                 global_step_cnt := global_step_cnt + 2;\r
                             end if;\r
                         end if;\r
@@ -335,7 +338,8 @@ end;
                                 ch := 16#41# + i;\r
                             end if;\r
 \r
-                            if (i < 64) then\r
+                            --if (i < 64) then\r
+                            if (i < 10) then\r
                                 --set dma value on the ram.\r
                                 if    (dma_step_cnt = (0 + j) * cpu_io_multi) then\r
                                     io_out(16#0200# + j, i);\r
@@ -415,16 +419,21 @@ end;
                             elsif (nmi_step_cnt = 2 * cpu_io_multi) then\r
                                 --scroll x=0\r
 --                                io_out(16#2005#, nmi_scl_y);\r
+                                io_brk;\r
                             elsif (nmi_step_cnt = 3 * cpu_io_multi) then\r
                                 --scroll y++\r
 --                                io_out(16#2005#, nmi_scl_y);\r
+                                io_brk;\r
                             else\r
-                                nmi_oam_x := nmi_oam_x + 1;\r
+                                if (ref_cnt = 0) then\r
+                                    nmi_oam_x := nmi_oam_x + 1;\r
+                                end if;\r
                                 if (nmi_step_cnt mod 10 = 0) then\r
                                     nmi_scl_y := nmi_scl_y + 1;\r
                                 end if;\r
                                 io_brk;\r
                                 if (nmi_step_cnt > 3 * cpu_io_multi) then\r
+                                    ref_cnt := ref_cnt + 1;\r
                                     global_step_cnt := global_step_cnt + 1;\r
                                 end if;\r
                             end if;\r
index d1b1825..b9f18b5 100644 (file)
@@ -125,11 +125,18 @@ signal cnt_clk      : std_logic;
 signal cnt_rst_n    : std_logic;
 signal clk_cnt      : std_logic_vector(5 downto 0);
 
+--cpu clock = base clock / 24 = 2.08 MHz (480 ns / cycle)
+--ppu clock = base clock / 8
+--vga clock = base clock / 2
+--mem clock = base clock
+
 begin
 
     cnt_clk <= not clk;
-    cnt_rst_n <= not ce_n;
-
+    cnt_rst_n <= '1' when ce_n = '0' and we_n = '0' else
+                 '0';
+--counter grows at most 0 .to 23
+--counter width=6 is enough.
     counter_inst : counter_register generic map (6, 1)
             port map (cnt_clk, cnt_rst_n, '0', '1', (others => '0'), clk_cnt);
 
index 734be44..170559a 100644 (file)
@@ -83,313 +83,6 @@ component counter_register
     );\r
 end component;\r
 \r
-component ppu_render\r
-    port (  \r
-    signal dbg_ppu_clk                      : out std_logic;\r
-    signal dbg_nes_x                        : out std_logic_vector (8 downto 0);\r
-    signal dbg_nes_y                        : out std_logic_vector (8 downto 0);\r
-    signal dbg_disp_nt, dbg_disp_attr       : out std_logic_vector (7 downto 0);\r
-    signal dbg_disp_ptn_h, dbg_disp_ptn_l   : out std_logic_vector (15 downto 0);\r
-    signal dbg_plt_ce_rn_wn                 : out std_logic_vector (2 downto 0);\r
-    signal dbg_plt_addr                     : out std_logic_vector (4 downto 0);\r
-    signal dbg_plt_data                     : out std_logic_vector (7 downto 0);\r
-    signal dbg_p_oam_ce_rn_wn               : out std_logic_vector (2 downto 0);\r
-    signal dbg_p_oam_addr                   : out std_logic_vector (7 downto 0);\r
-    signal dbg_p_oam_data                   : out std_logic_vector (7 downto 0);\r
-    signal dbg_s_oam_ce_rn_wn               : out std_logic_vector (2 downto 0);\r
-    signal dbg_s_oam_addr                   : out std_logic_vector (4 downto 0);\r
-    signal dbg_s_oam_data                   : out std_logic_vector (7 downto 0);\r
-    \r
-            ppu_clk     : in std_logic;\r
-            mem_clk     : in std_logic;\r
-            rst_n       : in std_logic;\r
-            rd_n        : out std_logic;\r
-            wr_n        : out std_logic;\r
-            ale         : out std_logic;\r
-            vram_ad     : inout std_logic_vector (7 downto 0);\r
-            vram_a      : out std_logic_vector (13 downto 8);\r
-            cur_x       : in std_logic_vector (8 downto 0);\r
-            cur_y       : in std_logic_vector (8 downto 0);\r
-            r           : out std_logic_vector (3 downto 0);\r
-            g           : out std_logic_vector (3 downto 0);\r
-            b           : out std_logic_vector (3 downto 0);\r
-            ppu_ctrl        : in std_logic_vector (7 downto 0);\r
-            ppu_mask        : in std_logic_vector (7 downto 0);\r
-            read_status     : in std_logic;\r
-            ppu_status      : out std_logic_vector (7 downto 0);\r
-            ppu_scroll_x    : in std_logic_vector (7 downto 0);\r
-            ppu_scroll_y    : in std_logic_vector (7 downto 0);\r
-            \r
-            r_nw            : in std_logic;\r
-            oam_bus_ce_n    : in std_logic;\r
-            plt_bus_ce_n    : in std_logic;\r
-            oam_plt_addr    : in std_logic_vector (7 downto 0);\r
-            oam_plt_data    : inout std_logic_vector (7 downto 0);\r
-            v_bus_busy_n    : out std_logic\r
-    );\r
-end component;\r
-\r
---------- screen constant -----------\r
-constant VGA_W          : integer := 640;\r
-constant VGA_H          : integer := 480;\r
-constant VGA_W_MAX      : integer := 800;\r
-constant VGA_H_MAX      : integer := 525;\r
-constant H_SP           : integer := 95;\r
-constant H_BP           : integer := 48;\r
-constant H_FP           : integer := 15;\r
-constant V_SP           : integer := 2;\r
-constant V_BP           : integer := 33;\r
-constant V_FP           : integer := 10;\r
-\r
---------- signal declaration -----------\r
-signal vga_x        : std_logic_vector (9 downto 0);\r
-signal vga_y        : std_logic_vector (9 downto 0);\r
-signal x_res_n      : std_logic;\r
-signal y_res_n      : std_logic;\r
-signal y_en_n       : std_logic;\r
-signal cnt_clk      : std_logic;\r
-\r
-signal emu_ppu_clk      : std_logic;\r
-signal emu_ppu_clk_n    : std_logic;\r
-signal count11_res_n     : std_logic;\r
-signal count11           : std_logic_vector(3 downto 0);\r
-signal nes_x        : std_logic_vector (8 downto 0);\r
-signal nes_y        : std_logic_vector (8 downto 0);\r
-\r
----DE1 base clock 50 MHz\r
----motones sim project uses following clock.\r
---cpu clock = base clock / 24 = 2.08 MHz (480 ns / cycle)\r
---ppu clock = base clock / 8\r
---vga clock = base clock / 2\r
---sdram clock = 135 MHz\r
-\r
-begin\r
-    dbg_vga_x <= vga_x;\r
-    dbg_vga_y <= vga_y;\r
-    dbg_vga_clk <= vga_clk;\r
-    \r
-    cnt_clk <= not vga_clk;\r
-    \r
-    --vga position counter\r
-    x_inst : counter_register generic map (10, 1)\r
-            port map (cnt_clk , x_res_n, '0', '1', (others => '0'), vga_x);\r
-    y_inst : counter_register generic map (10, 1)\r
-            port map (cnt_clk , y_res_n, y_en_n, '1', (others => '0'), vga_y);\r
-    vga_out_p : process (rst_n, vga_clk)\r
-    begin\r
-        if (rst_n = '0') then\r
-            h_sync_n <= '0';\r
-            v_sync_n <= '0';\r
-            x_res_n <= '0';\r
-            y_res_n <= '0';\r
-        elsif (rising_edge(vga_clk)) then\r
-            --xmax = 799\r
-            if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
-                x_res_n <= '0';\r
-                y_en_n <= '0';\r
-                --ymax=524\r
-                if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then\r
-                    y_res_n <= '0';\r
-                else\r
-                    y_res_n <= '1';\r
-                end if;\r
-            else\r
-                x_res_n <= '1';\r
-                y_en_n <= '1';\r
-                y_res_n <= '1';\r
-            end if;\r
-\r
-            --sync signal assert.\r
-            if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and \r
-                vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then\r
-                h_sync_n <= '0';\r
-            else\r
-                h_sync_n <= '1';\r
-            end if;\r
-\r
-            if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and \r
-                vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then\r
-                v_sync_n <= '0';\r
-            else\r
-                v_sync_n <= '1';\r
-            end if;\r
-\r
-        end if;\r
-    end process;\r
-\r
-    --emulate ppu clock that is synchronized with vga clock\r
-    count11_inst : counter_register generic map (4, 1)\r
-            port map (cnt_clk, count11_res_n, '0', '1', (others => '0'), count11);\r
-    nes_x_inst : counter_register generic map (9, 1)\r
-            port map (emu_ppu_clk , x_res_n, '0', '1', (others => '0'), nes_x);\r
-    nes_y <= vga_y(9 downto 1);\r
-\r
-    res_p : process (rst_n, vga_clk)\r
-    begin\r
-        if (rst_n = '0') then\r
-            count11_res_n <= '0';\r
-        elsif (rising_edge(vga_clk)) then\r
-            if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
-                count11_res_n <= '0';\r
-            elsif (count11 = "1011") then\r
-                count11_res_n <= '0';\r
-            else\r
-                count11_res_n <= '1';\r
-            end if;\r
-        end if;\r
-    end process;\r
-\r
-    emu_clk_p : process (rst_n, mem_clk)\r
-    begin\r
-        if (rst_n = '0') then\r
-            emu_ppu_clk <= '0';\r
-        elsif (rising_edge(mem_clk)) then\r
-            if (vga_x < conv_std_logic_vector(680, 10) or \r
-                vga_x > conv_std_logic_vector(760, 10) ) then\r
-                if (count11 = "0001" or count11 = "0011" or count11 = "0101" or count11 = "0111"\r
-                    or count11 = "1010" or count11 = "1100") then\r
-                    emu_ppu_clk <= '0';\r
-                else\r
-                    emu_ppu_clk <= '1';\r
-                end if;\r
-            else\r
-                if (count11(0) = '1') then\r
-                    emu_ppu_clk <= '0';\r
-                else\r
-                    emu_ppu_clk <= '1';\r
-                end if;\r
-            end if;\r
-        end if;\r
-    end process;\r
-\r
-    ---emulated ppu clock adjustment.\r
-    emu_ppu_clk_n <= not emu_ppu_clk;\r
-    ppu_render_inst : ppu_render\r
-        port map (\r
-        dbg_emu_ppu_clk                      ,\r
-        dbg_nes_x                        ,\r
-        dbg_nes_y                        ,\r
-        dbg_disp_nt, dbg_disp_attr       ,\r
-        dbg_disp_ptn_h, dbg_disp_ptn_l   ,\r
-        dbg_plt_ce_rn_wn                 ,\r
-        dbg_plt_addr                    ,\r
-        dbg_plt_data                    ,\r
-        dbg_p_oam_ce_rn_wn              ,\r
-        dbg_p_oam_addr                  ,\r
-        dbg_p_oam_data                  ,\r
-        dbg_s_oam_ce_rn_wn              ,\r
-        dbg_s_oam_addr                  ,\r
-        dbg_s_oam_data                  ,\r
-        \r
-                emu_ppu_clk ,\r
-                mem_clk     ,\r
-                rst_n       ,\r
-                rd_n        ,\r
-                wr_n        ,\r
-                ale         ,\r
-                vram_ad     ,\r
-                vram_a      ,\r
-                nes_x       ,\r
-                nes_y       ,\r
-                r           ,\r
-                g           ,\r
-                b           ,\r
-                ppu_ctrl        ,\r
-                ppu_mask        ,\r
-                read_status     ,\r
-                ppu_status      ,\r
-                ppu_scroll_x    ,\r
-                ppu_scroll_y    ,\r
-                r_nw            ,\r
-                oam_bus_ce_n    ,\r
-                plt_bus_ce_n    ,\r
-                oam_plt_addr    ,\r
-                oam_plt_data    ,\r
-                v_bus_busy_n    \r
-        );\r
-\r
-end rtl;\r
-\r
-\r
-\r
----------------------------------------------------------------\r
----------------------------------------------------------------\r
------------------------- PPU VGA Renderer ---------------------\r
----------------------------------------------------------------\r
----------------------------------------------------------------\r
-\r
-library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.std_logic_arith.conv_std_logic_vector;\r
-use ieee.std_logic_unsigned.all;\r
-use work.motonesfpga_common.all;\r
-\r
-entity ppu_render is \r
-    port (  \r
-    signal dbg_ppu_clk                      : out std_logic;\r
-    signal dbg_nes_x                        : out std_logic_vector (8 downto 0);\r
-    signal dbg_nes_y                        : out std_logic_vector (8 downto 0);\r
-    signal dbg_disp_nt, dbg_disp_attr       : out std_logic_vector (7 downto 0);\r
-    signal dbg_disp_ptn_h, dbg_disp_ptn_l   : out std_logic_vector (15 downto 0);\r
-    signal dbg_plt_ce_rn_wn                 : out std_logic_vector (2 downto 0);\r
-    signal dbg_plt_addr                     : out std_logic_vector (4 downto 0);\r
-    signal dbg_plt_data                     : out std_logic_vector (7 downto 0);\r
-    signal dbg_p_oam_ce_rn_wn               : out std_logic_vector (2 downto 0);\r
-    signal dbg_p_oam_addr                   : out std_logic_vector (7 downto 0);\r
-    signal dbg_p_oam_data                   : out std_logic_vector (7 downto 0);\r
-    signal dbg_s_oam_ce_rn_wn               : out std_logic_vector (2 downto 0);\r
-    signal dbg_s_oam_addr                   : out std_logic_vector (4 downto 0);\r
-    signal dbg_s_oam_data                   : out std_logic_vector (7 downto 0);\r
-    \r
-            ppu_clk     : in std_logic;\r
-            mem_clk     : in std_logic;\r
-            rst_n       : in std_logic;\r
-\r
-            rd_n        : out std_logic;\r
-            wr_n        : out std_logic;\r
-            ale         : out std_logic;\r
-            vram_ad     : inout std_logic_vector (7 downto 0);\r
-            vram_a      : out std_logic_vector (13 downto 8);\r
-\r
-            --current drawing position 340 x 261\r
-            cur_x       : in std_logic_vector (8 downto 0);\r
-            cur_y       : in std_logic_vector (8 downto 0);\r
-            r           : out std_logic_vector (3 downto 0);\r
-            g           : out std_logic_vector (3 downto 0);\r
-            b           : out std_logic_vector (3 downto 0);\r
-\r
-            ppu_ctrl        : in std_logic_vector (7 downto 0);\r
-            ppu_mask        : in std_logic_vector (7 downto 0);\r
-            read_status     : in std_logic;\r
-            ppu_status      : out std_logic_vector (7 downto 0);\r
-            ppu_scroll_x    : in std_logic_vector (7 downto 0);\r
-            ppu_scroll_y    : in std_logic_vector (7 downto 0);\r
-\r
-            r_nw            : in std_logic;\r
-            oam_bus_ce_n    : in std_logic;\r
-            plt_bus_ce_n    : in std_logic;\r
-            oam_plt_addr    : in std_logic_vector (7 downto 0);\r
-            oam_plt_data    : inout std_logic_vector (7 downto 0);\r
-            v_bus_busy_n    : out std_logic\r
-    );\r
-end ppu_render;\r
-\r
-architecture rtl of ppu_render is\r
-\r
-component counter_register\r
-    generic (\r
-        dsize       : integer := 8;\r
-        inc         : integer := 1\r
-    );\r
-    port (  clk         : in std_logic;\r
-            rst_n       : in std_logic;\r
-            ce_n        : in std_logic;\r
-            we_n        : in std_logic;\r
-            d           : in std_logic_vector(dsize - 1 downto 0);\r
-            q           : out std_logic_vector(dsize - 1 downto 0)\r
-    );\r
-end component;\r
-\r
 component shift_register\r
     generic (\r
         dsize : integer := 8;\r
@@ -457,16 +150,28 @@ component ram_ctrl
         );\r
 end component;\r
 \r
+--------- VGA screen constant -----------\r
+constant VGA_W          : integer := 640;\r
+constant VGA_H          : integer := 480;\r
+constant VGA_W_MAX      : integer := 800;\r
+constant VGA_H_MAX      : integer := 525;\r
+constant H_SP           : integer := 95;\r
+constant H_BP           : integer := 48;\r
+constant H_FP           : integer := 15;\r
+constant V_SP           : integer := 2;\r
+constant V_BP           : integer := 33;\r
+constant V_FP           : integer := 10;\r
+\r
 --nes screen size is emulated to align with the vga timing...\r
 constant X_SIZE       : integer := 9;\r
 constant dsize        : integer := 8;\r
 constant asize        : integer := 14;\r
-constant HSCAN_MAX    : integer := 341;\r
-constant VSCAN_MAX    : integer := 262;\r
-constant HSCAN        : integer := 257;\r
+constant HSCAN        : integer := 256;\r
 constant VSCAN        : integer := 240;\r
-constant HSCAN_NEXT_START    : integer := 320;\r
-constant HSCAN_NEXT_EXTRA    : integer := 336;\r
+constant HSCAN_NEXT_START    : integer := 377;\r
+constant VSCAN_NEXT_START    : integer := 262;\r
+constant HSCAN_SPR_MAX       : integer := 321;\r
+constant HSCAN_OAM_EVA_START       : integer := 64;\r
 \r
 \r
 constant PPUBNA    : integer := 1;  --base name address\r
@@ -493,89 +198,29 @@ constant ST_SOF     : integer := 5;  --sprite overflow
 constant ST_SP0     : integer := 6;  --sprite 0 hits\r
 constant ST_VBL     : integer := 7;  --vblank\r
 \r
-subtype nes_color_data  is std_logic_vector (11 downto 0);\r
-type nes_color_array    is array (0 to 63) of nes_color_data;\r
---ref: http://hlc6502.web.fc2.com/NesPal2.htm\r
-constant nes_color_palette : nes_color_array := (\r
-        conv_std_logic_vector(16#777#, 12), \r
-        conv_std_logic_vector(16#20b#, 12), \r
-        conv_std_logic_vector(16#20b#, 12), \r
-        conv_std_logic_vector(16#61a#, 12), \r
-        conv_std_logic_vector(16#927#, 12), \r
-        conv_std_logic_vector(16#b13#, 12), \r
-        conv_std_logic_vector(16#a30#, 12), \r
-        conv_std_logic_vector(16#740#, 12), \r
-        conv_std_logic_vector(16#450#, 12), \r
-        conv_std_logic_vector(16#360#, 12), \r
-        conv_std_logic_vector(16#360#, 12), \r
-        conv_std_logic_vector(16#364#, 12), \r
-        conv_std_logic_vector(16#358#, 12), \r
-        conv_std_logic_vector(16#000#, 12), \r
-        conv_std_logic_vector(16#000#, 12), \r
-        conv_std_logic_vector(16#000#, 12),\r
-        conv_std_logic_vector(16#bbb#, 12), \r
-        conv_std_logic_vector(16#46f#, 12), \r
-        conv_std_logic_vector(16#44f#, 12), \r
-        conv_std_logic_vector(16#94f#, 12), \r
-        conv_std_logic_vector(16#d4c#, 12), \r
-        conv_std_logic_vector(16#d46#, 12), \r
-        conv_std_logic_vector(16#e50#, 12), \r
-        conv_std_logic_vector(16#c70#, 12), \r
-        conv_std_logic_vector(16#880#, 12), \r
-        conv_std_logic_vector(16#5a0#, 12), \r
-        conv_std_logic_vector(16#4a1#, 12), \r
-        conv_std_logic_vector(16#4a6#, 12), \r
-        conv_std_logic_vector(16#49c#, 12), \r
-        conv_std_logic_vector(16#000#, 12), \r
-        conv_std_logic_vector(16#000#, 12), \r
-        conv_std_logic_vector(16#000#, 12),\r
-        conv_std_logic_vector(16#fff#, 12), \r
-        conv_std_logic_vector(16#6af#, 12), \r
-        conv_std_logic_vector(16#58f#, 12), \r
-        conv_std_logic_vector(16#a7f#, 12), \r
-        conv_std_logic_vector(16#f6f#, 12), \r
-        conv_std_logic_vector(16#f6b#, 12), \r
-        conv_std_logic_vector(16#f73#, 12), \r
-        conv_std_logic_vector(16#fa0#, 12), \r
-        conv_std_logic_vector(16#ed2#, 12), \r
-        conv_std_logic_vector(16#9e0#, 12), \r
-        conv_std_logic_vector(16#7f4#, 12), \r
-        conv_std_logic_vector(16#7e9#, 12), \r
-        conv_std_logic_vector(16#6de#, 12), \r
-        conv_std_logic_vector(16#777#, 12), \r
-        conv_std_logic_vector(16#000#, 12), \r
-        conv_std_logic_vector(16#000#, 12),\r
-        conv_std_logic_vector(16#fff#, 12), \r
-        conv_std_logic_vector(16#9df#, 12), \r
-        conv_std_logic_vector(16#abf#, 12), \r
-        conv_std_logic_vector(16#cbf#, 12), \r
-        conv_std_logic_vector(16#ebf#, 12), \r
-        conv_std_logic_vector(16#fbe#, 12), \r
-        conv_std_logic_vector(16#fcb#, 12), \r
-        conv_std_logic_vector(16#fda#, 12), \r
-        conv_std_logic_vector(16#ff9#, 12), \r
-        conv_std_logic_vector(16#cf8#, 12), \r
-        conv_std_logic_vector(16#afa#, 12), \r
-        conv_std_logic_vector(16#afc#, 12), \r
-        conv_std_logic_vector(16#aff#, 12), \r
-        conv_std_logic_vector(16#aaa#, 12), \r
-        conv_std_logic_vector(16#000#, 12), \r
-        conv_std_logic_vector(16#000#, 12)\r
-        );\r
+--------- signal declaration -----------\r
+signal vga_x        : std_logic_vector (9 downto 0);\r
+signal vga_y        : std_logic_vector (9 downto 0);\r
+signal x_res_n      : std_logic;\r
+signal y_res_n      : std_logic;\r
+signal y_en_n       : std_logic;\r
+signal vga_clk_n    : std_logic;\r
+\r
+signal emu_ppu_clk      : std_logic;\r
+signal emu_ppu_clk_n    : std_logic;\r
+signal count1       : std_logic_vector (0 downto 0);\r
+signal nes_x        : std_logic_vector (8 downto 0);\r
+signal nes_y        : std_logic_vector (8 downto 0);\r
 \r
-signal ppu_clk_n        : std_logic;\r
 \r
---timing adjust\r
-signal bg_io_cnt        : std_logic_vector(0 downto 0);\r
-signal spr_io_cnt       : std_logic_vector(0 downto 0);\r
+------- render instance ----------------\r
 \r
 --vram i/o\r
-signal io_oe_n          : std_logic;\r
+signal io_cnt_rst_n     : std_logic;\r
+signal io_cnt           : std_logic_vector(0 downto 0);\r
+signal al_oe_n          : std_logic;\r
 signal ah_oe_n          : std_logic;\r
 \r
-signal cnt_x_res_n   : std_logic;\r
-signal bg_cnt_res_n  : std_logic;\r
-\r
 --bg prefetch position (scroll + 16 cycle ahead of current pos)\r
 --511 x 239 (or 255 x 479)\r
 signal prf_x            : std_logic_vector(X_SIZE - 1 downto 0);\r
@@ -632,13 +277,12 @@ signal s_oam_data           : std_logic_vector (dsize - 1 downto 0);
 \r
 signal p_oam_cnt_res_n  : std_logic;\r
 signal p_oam_cnt_ce_n   : std_logic;\r
-signal p_oam_cnt_wrap_n : std_logic;\r
-signal p_oam_cnt        : std_logic_vector (dsize - 1 downto 0);\r
+signal p_oam_cnt        : std_logic_vector (dsize downto 0);\r
 signal p_oam_addr_in    : std_logic_vector (dsize - 1 downto 0);\r
 signal oam_ev_status    : std_logic_vector (2 downto 0);\r
 \r
 signal s_oam_cnt_ce_n   : std_logic;\r
-signal s_oam_cnt        : std_logic_vector (4 downto 0);\r
+signal s_oam_cnt        : std_logic_vector (5 downto 0);\r
 \r
 --oam evaluation status\r
 constant EV_STAT_COMP       : std_logic_vector (2 downto 0) := "000";\r
@@ -672,10 +316,160 @@ signal spr_ptn_in       : std_logic_vector (dsize - 1 downto 0);
 signal sprite0_evaluated    : std_logic;\r
 signal sprite0_displayed    : std_logic;\r
 \r
+\r
+subtype nes_color_data  is std_logic_vector (11 downto 0);\r
+type nes_color_array    is array (0 to 63) of nes_color_data;\r
+--ref: http://hlc6502.web.fc2.com/NesPal2.htm\r
+constant nes_color_palette : nes_color_array := (\r
+        conv_std_logic_vector(16#777#, 12), \r
+        conv_std_logic_vector(16#20b#, 12), \r
+        conv_std_logic_vector(16#20b#, 12), \r
+        conv_std_logic_vector(16#61a#, 12), \r
+        conv_std_logic_vector(16#927#, 12), \r
+        conv_std_logic_vector(16#b13#, 12), \r
+        conv_std_logic_vector(16#a30#, 12), \r
+        conv_std_logic_vector(16#740#, 12), \r
+        conv_std_logic_vector(16#450#, 12), \r
+        conv_std_logic_vector(16#360#, 12), \r
+        conv_std_logic_vector(16#360#, 12), \r
+        conv_std_logic_vector(16#364#, 12), \r
+        conv_std_logic_vector(16#358#, 12), \r
+        conv_std_logic_vector(16#000#, 12), \r
+        conv_std_logic_vector(16#000#, 12), \r
+        conv_std_logic_vector(16#000#, 12),\r
+        conv_std_logic_vector(16#bbb#, 12), \r
+        conv_std_logic_vector(16#46f#, 12), \r
+        conv_std_logic_vector(16#44f#, 12), \r
+        conv_std_logic_vector(16#94f#, 12), \r
+        conv_std_logic_vector(16#d4c#, 12), \r
+        conv_std_logic_vector(16#d46#, 12), \r
+        conv_std_logic_vector(16#e50#, 12), \r
+        conv_std_logic_vector(16#c70#, 12), \r
+        conv_std_logic_vector(16#880#, 12), \r
+        conv_std_logic_vector(16#5a0#, 12), \r
+        conv_std_logic_vector(16#4a1#, 12), \r
+        conv_std_logic_vector(16#4a6#, 12), \r
+        conv_std_logic_vector(16#49c#, 12), \r
+        conv_std_logic_vector(16#000#, 12), \r
+        conv_std_logic_vector(16#000#, 12), \r
+        conv_std_logic_vector(16#000#, 12),\r
+        conv_std_logic_vector(16#fff#, 12), \r
+        conv_std_logic_vector(16#6af#, 12), \r
+        conv_std_logic_vector(16#58f#, 12), \r
+        conv_std_logic_vector(16#a7f#, 12), \r
+        conv_std_logic_vector(16#f6f#, 12), \r
+        conv_std_logic_vector(16#f6b#, 12), \r
+        conv_std_logic_vector(16#f73#, 12), \r
+        conv_std_logic_vector(16#fa0#, 12), \r
+        conv_std_logic_vector(16#ed2#, 12), \r
+        conv_std_logic_vector(16#9e0#, 12), \r
+        conv_std_logic_vector(16#7f4#, 12), \r
+        conv_std_logic_vector(16#7e9#, 12), \r
+        conv_std_logic_vector(16#6de#, 12), \r
+        conv_std_logic_vector(16#777#, 12), \r
+        conv_std_logic_vector(16#000#, 12), \r
+        conv_std_logic_vector(16#000#, 12),\r
+        conv_std_logic_vector(16#fff#, 12), \r
+        conv_std_logic_vector(16#9df#, 12), \r
+        conv_std_logic_vector(16#abf#, 12), \r
+        conv_std_logic_vector(16#cbf#, 12), \r
+        conv_std_logic_vector(16#ebf#, 12), \r
+        conv_std_logic_vector(16#fbe#, 12), \r
+        conv_std_logic_vector(16#fcb#, 12), \r
+        conv_std_logic_vector(16#fda#, 12), \r
+        conv_std_logic_vector(16#ff9#, 12), \r
+        conv_std_logic_vector(16#cf8#, 12), \r
+        conv_std_logic_vector(16#afa#, 12), \r
+        conv_std_logic_vector(16#afc#, 12), \r
+        conv_std_logic_vector(16#aff#, 12), \r
+        conv_std_logic_vector(16#aaa#, 12), \r
+        conv_std_logic_vector(16#000#, 12), \r
+        conv_std_logic_vector(16#000#, 12)\r
+        );\r
+\r
+---DE1 base clock 50 MHz\r
+---motones sim project uses following clock.\r
+--cpu clock = base clock / 24 = 2.08 MHz (480 ns / cycle)\r
+--ppu clock = base clock / 8\r
+--vga clock = base clock / 2\r
+\r
 begin\r
-    dbg_ppu_clk <= ppu_clk;\r
-    dbg_nes_x <= cur_x;\r
-    dbg_nes_y <= cur_y;\r
+    dbg_vga_x <= vga_x;\r
+    dbg_vga_y <= vga_y;\r
+    dbg_vga_clk <= vga_clk;\r
+    dbg_emu_ppu_clk <= emu_ppu_clk;\r
+\r
+    vga_clk_n <= not vga_clk;\r
+    \r
+    --vga position counter\r
+    vga_x_inst : counter_register generic map (10, 1)\r
+            port map (vga_clk, x_res_n, '0', '1', (others => '0'), vga_x);\r
+    vga_y_inst : counter_register generic map (10, 1)\r
+            port map (vga_clk, y_res_n, y_en_n, '1', (others => '0'), vga_y);\r
+    vga_out_p : process (rst_n, vga_clk)\r
+    begin\r
+        if (rst_n = '0') then\r
+            h_sync_n <= '0';\r
+            v_sync_n <= '0';\r
+            x_res_n <= '0';\r
+            y_res_n <= '0';\r
+        elsif (rising_edge(vga_clk)) then\r
+            --xmax = 799\r
+            if (vga_x = conv_std_logic_vector(VGA_W_MAX, 10)) then\r
+                x_res_n <= '0';\r
+                y_en_n <= '0';\r
+                --ymax=524\r
+                if (vga_y = conv_std_logic_vector(VGA_H_MAX, 10)) then\r
+                    y_res_n <= '0';\r
+                else\r
+                    y_res_n <= '1';\r
+                end if;\r
+            else\r
+                x_res_n <= '1';\r
+                y_en_n <= '1';\r
+                y_res_n <= '1';\r
+            end if;\r
+\r
+            --sync signal assert.\r
+            if (vga_x >= conv_std_logic_vector((VGA_W + H_FP) , 10) and \r
+                vga_x < conv_std_logic_vector((VGA_W + H_FP + H_SP) , 10)) then\r
+                h_sync_n <= '0';\r
+            else\r
+                h_sync_n <= '1';\r
+            end if;\r
+\r
+            if (vga_y >= conv_std_logic_vector((VGA_H + V_FP) , 10) and \r
+                vga_y < conv_std_logic_vector((VGA_H + V_FP + V_SP) , 10)) then\r
+                v_sync_n <= '0';\r
+            else\r
+                v_sync_n <= '1';\r
+            end if;\r
+\r
+        end if;\r
+    end process;\r
+\r
+    --nes position counter\r
+    count1_inst : counter_register generic map (1, 1)\r
+            port map (vga_clk , rst_n, '0', '1', (others => '0'), count1);\r
+    emu_ppu_clk <= not count1(0);\r
+    emu_ppu_clk_n <= count1(0);\r
+    nes_x <= vga_x(9 downto 1);\r
+    --debug purpose, accelarate the clock...\r
+    nes_y <= vga_y(9 downto 1);\r
+    --nes_y <= vga_y(8 downto 0);\r
+\r
+------------------------------------------------------------------------\r
+------------------------------------------------------------------------\r
+------------------------------------------------------------------------\r
+------------------------------------------------------------------------\r
+------------------------ ppu render instance... ------------------------\r
+------------------------------------------------------------------------\r
+------------------------------------------------------------------------\r
+------------------------------------------------------------------------\r
+------------------------------------------------------------------------\r
+\r
+    dbg_nes_x <= nes_x;\r
+    dbg_nes_y <= nes_y;\r
     dbg_disp_nt <= disp_nt;\r
     dbg_disp_attr <= disp_attr;\r
     dbg_disp_ptn_h <= disp_ptn_h;\r
@@ -688,175 +482,237 @@ begin
     dbg_p_oam_data                   <= p_oam_data;\r
     dbg_s_oam_ce_rn_wn               <= s_oam_ram_ce_n & s_oam_r_n & s_oam_w_n;\r
     dbg_s_oam_addr                   <= s_oam_addr;\r
-    dbg_s_oam_data                   <= p_oam_data;\r
-\r
-\r
-    ppu_clk_n <= not ppu_clk;\r
-\r
-    ale <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
-                cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
-           not spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
-                cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
-           'Z';\r
-\r
-    rd_n <= bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
-                cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
-           not spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
-                cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+    dbg_s_oam_data                   <= s_oam_data;\r
+\r
+    -----------------------------------------\r
+    ---vram access signals\r
+    -----------------------------------------\r
+    reset_p : process (rst_n, emu_ppu_clk)\r
+    begin\r
+        if (rst_n = '0') then\r
+            io_cnt_rst_n <= '0';\r
+        else\r
+            if (falling_edge(emu_ppu_clk)) then\r
+                if (nes_x >= conv_std_logic_vector(VGA_W_MAX / 2 - 1, X_SIZE)) then io_cnt_rst_n <= '0';\r
+                else io_cnt_rst_n <= '1';\r
+                end if; \r
+            end if;\r
+        end if;\r
+    end process;\r
+\r
+    io_cnt_inst : counter_register generic map (1, 1)\r
+            port map (emu_ppu_clk, io_cnt_rst_n, '0', '1', (others => '0'), io_cnt);\r
+\r
+    ale <= \r
+            not io_cnt(0) when (\r
+                ((ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+                (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)))) else\r
             'Z';\r
-    wr_n <= '1' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else\r
+    rd_n <= \r
+            not io_cnt(0) when (\r
+                ((ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+                (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)))) else\r
             'Z';\r
-    io_oe_n <= not bg_io_cnt(0) when ppu_mask(PPUSBG) = '1' and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
-                cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
-           spr_io_cnt(0) when ppu_mask(PPUSSP) = '1' and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
-                cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) else\r
+    wr_n <= \r
+            '1' when (\r
+                ((ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+                (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)))) else\r
+            'Z';\r
+    al_oe_n <= \r
+            io_cnt(0) when (\r
+                ((ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+                (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)))) else\r
                '1';\r
-    ah_oe_n <= '0' when (ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
-                (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) else\r
-              '1';\r
+    ah_oe_n <= \r
+            '0' when (\r
+                ((ppu_mask(PPUSBG) = '1' or ppu_mask(PPUSSP) = '1') and\r
+                (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)))) else\r
+            '1';\r
     v_bus_busy_n <= ah_oe_n;\r
 \r
-    bg_io_cnt_inst : counter_register generic map (1, 1)\r
-            port map (ppu_clk, bg_cnt_res_n, '0', '1', (others => '0'), bg_io_cnt);\r
-    spr_io_cnt_inst : counter_register generic map (1, 1)\r
-            port map (ppu_clk, cnt_x_res_n, '0', '1', (others => '0'), spr_io_cnt);\r
+    -----------------------------------------\r
+    --vram i/o\r
+    -----------------------------------------\r
+    vram_io_buf : tri_state_buffer generic map (dsize)\r
+            port map (al_oe_n, vram_addr(dsize - 1 downto 0), vram_ad);\r
+\r
+    vram_a_buf : tri_state_buffer generic map (6)\r
+            port map (ah_oe_n, vram_addr(asize - 1 downto dsize), vram_a);\r
 \r
-    ---bg prefetch x pos is 16 + scroll cycle ahead of current pos.\r
-    prf_x <= cur_x + ppu_scroll_x + "000010000" \r
-                    when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) else\r
-             cur_x + ppu_scroll_x + "010111011"; -- +16 -341\r
+    -----------------------------------------\r
+    ---primary oam implementation...\r
+    -----------------------------------------\r
+    p_oam_ram_ce_n_in <= \r
+                    '0' when oam_bus_ce_n = '0' else\r
+                    '0' when ppu_mask(PPUSSP) = '1' and\r
+                         (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                         nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)) and\r
+                         nes_x > conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE) and \r
+                         nes_x <= conv_std_logic_vector(HSCAN, X_SIZE) else\r
+                    '1';\r
+    p_oam_addr <= oam_plt_addr when oam_bus_ce_n = '0' else\r
+                p_oam_addr_in when ppu_mask(PPUSSP) = '1' and \r
+                         (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                         nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)) and\r
+                         nes_x > conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE) and \r
+                         nes_x <= conv_std_logic_vector(HSCAN, X_SIZE) else\r
+                (others => 'Z');\r
+    p_oam_r_n <= not r_nw when oam_bus_ce_n = '0' else\r
+                '0' when ppu_mask(PPUSSP) = '1' and \r
+                         (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                         nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE)) and\r
+                         nes_x > conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE) and \r
+                         nes_x <= conv_std_logic_vector(HSCAN, X_SIZE) else\r
+                '1';\r
+    p_oam_w_n <= r_nw when oam_bus_ce_n = '0' else\r
+                '1';\r
+    oam_d_buf_w : tri_state_buffer generic map (dsize)\r
+            port map (p_oam_w_n, oam_plt_data, p_oam_data);\r
+    oam_d_buf_r : tri_state_buffer generic map (dsize)\r
+            port map (p_oam_r_n, p_oam_data, oam_plt_data);\r
+\r
+    p_oam_ram_ctl : ram_ctrl\r
+            port map (mem_clk, p_oam_ram_ce_n_in, p_oam_r_n, p_oam_w_n, p_oam_ram_ce_n);\r
+    primary_oam_inst : ram generic map (dsize, dsize)\r
+            port map (mem_clk, p_oam_ram_ce_n, p_oam_r_n, p_oam_w_n, p_oam_addr, p_oam_data);\r
 \r
-    prf_y <= cur_y + ppu_scroll_y\r
-                    when cur_x < conv_std_logic_vector(HSCAN, X_SIZE) and\r
-                         cur_y < conv_std_logic_vector(VSCAN, X_SIZE) else\r
-             cur_y + ppu_scroll_y + "000000001" \r
-                    when cur_y < conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE) else\r
-             "000000000"; \r
+    -----------------------------------------\r
+    ---secondary oam implementation\r
+    -----------------------------------------\r
+    --primary oam copy count\r
+    p_oam_cnt_inst : counter_register generic map (dsize + 1, 4)\r
+            port map (emu_ppu_clk_n, p_oam_cnt_res_n, p_oam_cnt_ce_n, '1', (others => '0'), p_oam_cnt);\r
+    --primary oam copy count\r
+    s_oam_cnt_inst : counter_register generic map (6, 1)\r
+            port map (emu_ppu_clk_n, p_oam_cnt_res_n, s_oam_cnt_ce_n, '1', (others => '0'), s_oam_cnt);\r
+    --secondary oam pattern index.\r
+    s_oam_addr_cpy_inst : counter_register generic map (5, 1)\r
+            port map (emu_ppu_clk_n, p_oam_cnt_res_n, s_oam_addr_cpy_ce_n, \r
+                    '1', (others => '0'), s_oam_addr_cpy);\r
 \r
-    nt_inst : d_flip_flop generic map(dsize)\r
-            port map (ppu_clk_n, rst_n, '1', nt_we_n, vram_ad, disp_nt);\r
+    s_oam_ram_ce_n_in <= \r
+                      --enabled on clear only.\r
+                      '0' when ppu_mask(PPUSSP) = '1' and nes_x(0) = '0' and\r
+                                nes_x <= conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE) else\r
+                      --enabled on copy only.\r
+                      '0' when ppu_mask(PPUSSP) = '1' and nes_x(0) = '0' and\r
+                                nes_x > conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE) and\r
+                                nes_x <= conv_std_logic_vector(HSCAN, X_SIZE) else\r
+                      --enabled all the time for reference.\r
+                      '0' when ppu_mask(PPUSSP) = '1' and\r
+                                nes_x > conv_std_logic_vector(HSCAN, X_SIZE) and\r
+                                nes_x <= conv_std_logic_vector(HSCAN_SPR_MAX, X_SIZE) and\r
+                                s_oam_addr_cpy_n = '0' else\r
+                      '1';\r
+\r
+    s_oam_ram_ctl : ram_ctrl\r
+            port map (mem_clk, s_oam_ram_ce_n_in, s_oam_r_n, s_oam_w_n, s_oam_ram_ce_n);\r
+    secondary_oam_inst : ram generic map (5, dsize)\r
+            port map (mem_clk, s_oam_ram_ce_n, s_oam_r_n, s_oam_w_n, s_oam_addr, s_oam_data);\r
 \r
-    at_inst : d_flip_flop generic map(dsize)\r
-            port map (ppu_clk_n, rst_n, '1', attr_we_n, vram_ad, attr_val);\r
+    --sprite y tmp val\r
+    spr_y_inst : d_flip_flop generic map(dsize)\r
+            port map (emu_ppu_clk_n, p_oam_cnt_res_n, '1', spr_y_we_n, s_oam_data, spr_y_tmp);\r
+    --sprite pattern tmp val\r
+    spr_tile_inst : d_flip_flop generic map(dsize)\r
+            port map (emu_ppu_clk_n, p_oam_cnt_res_n, '1', spr_tile_we_n, s_oam_data, spr_tile_tmp);\r
 \r
-    disp_at_inst : shift_register generic map(dsize, 2)\r
-            port map (ppu_clk_n, rst_n, attr_ce_n, disp_attr_we_n, attr_val, disp_attr);\r
 \r
-    --chr rom data's bit is stored in opposite direction.\r
-    --reverse bit when loading...\r
-    ptn_l_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+    --reverse bit when NOT SPRHFL is set (.nes file format bit endian).\r
+    spr_ptn_in <= vram_ad when spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRHFL) = '1' else\r
+                (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
                  vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
-    ptn_h_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
-                 vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7)) & \r
-                disp_ptn_h (dsize downto 1);\r
-\r
-    ptn_l_inst : d_flip_flop generic map(dsize)\r
-            port map (ppu_clk_n, rst_n, '1', ptn_l_we_n, ptn_l_in, ptn_l_val);\r
-\r
-    disp_ptn_l_in <= ptn_l_val & disp_ptn_l (dsize downto 1);\r
-    disp_ptn_l_inst : shift_register generic map(dsize * 2, 1)\r
-            port map (ppu_clk_n, rst_n, '0', ptn_h_we_n, disp_ptn_l_in, disp_ptn_l);\r
+    --oam array instances...\r
+    spr_inst : for i in 0 to 7 generate\r
+        spr_x_inst : counter_register generic map(dsize, 16#ff#)\r
+                port map (emu_ppu_clk_n, rst_n, spr_x_ce_n(i), spr_x_we_n(i), s_oam_data, spr_x_cnt(i));\r
 \r
-    ptn_h_inst : shift_register generic map(dsize * 2, 1)\r
-            port map (ppu_clk_n, rst_n, '0', ptn_h_we_n, ptn_h_in, disp_ptn_h);\r
+        spr_attr_inst : d_flip_flop generic map(dsize)\r
+                port map (emu_ppu_clk_n, rst_n, '1', spr_attr_we_n(i), s_oam_data, spr_attr(i));\r
 \r
-    --vram i/o\r
-    vram_io_buf : tri_state_buffer generic map (dsize)\r
-            port map (io_oe_n, vram_addr(dsize - 1 downto 0), vram_ad);\r
+        spr_ptn_l_inst : shift_register generic map(dsize, 1)\r
+                port map (emu_ppu_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_l_we_n(i), spr_ptn_in, spr_ptn_l(i));\r
 \r
-    vram_a_buf : tri_state_buffer generic map (6)\r
-            port map (ah_oe_n, vram_addr(asize - 1 downto dsize), vram_a);\r
+        spr_ptn_h_inst : shift_register generic map(dsize, 1)\r
+                port map (emu_ppu_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_h_we_n(i), spr_ptn_in, spr_ptn_h(i));\r
+    end generate;\r
 \r
+    -----------------------------------------\r
     ---palette ram\r
+    -----------------------------------------\r
     r_n <= not r_nw;\r
 \r
-    plt_ram_ce_n_in <= ppu_clk when plt_bus_ce_n = '0' and r_nw = '0' else \r
+    plt_ram_ce_n_in <= '0' when plt_bus_ce_n = '0' and r_nw = '0' else \r
                     '0' when plt_bus_ce_n = '0' and r_nw = '1' else\r
                     '0' when ppu_mask(PPUSBG) = '1' and \r
-                            (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and \r
-                            (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+                            (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and \r
+                            (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
                     '1';\r
 \r
     plt_addr <= oam_plt_addr(4 downto 0) when plt_bus_ce_n = '0' else\r
                 "1" & spr_attr(0)(1 downto 0) & spr_ptn_h(0)(0) & spr_ptn_l(0)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(0) = "00000000" and \r
                         (spr_ptn_h(0)(0) or spr_ptn_l(0)(0)) = '1' else\r
                 "1" & spr_attr(1)(1 downto 0) & spr_ptn_h(1)(0) & spr_ptn_l(1)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(1) = "00000000" and \r
                         (spr_ptn_h(1)(0) or spr_ptn_l(1)(0)) = '1' else\r
                 "1" & spr_attr(2)(1 downto 0) & spr_ptn_h(2)(0) & spr_ptn_l(2)(0)\r
                     when ppu_mask(PPUSSP) = '1' and \r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(2) = "00000000" and\r
                         (spr_ptn_h(2)(0) or spr_ptn_l(2)(0)) = '1' else\r
                 "1" & spr_attr(3)(1 downto 0) & spr_ptn_h(3)(0) & spr_ptn_l(3)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(3) = "00000000" and\r
                         (spr_ptn_h(3)(0) or spr_ptn_l(3)(0)) = '1' else\r
                 "1" & spr_attr(4)(1 downto 0) & spr_ptn_h(4)(0) & spr_ptn_l(4)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(4) = "00000000" and\r
                         (spr_ptn_h(4)(0) or spr_ptn_l(4)(0)) = '1' else\r
                 "1" & spr_attr(5)(1 downto 0) & spr_ptn_h(5)(0) & spr_ptn_l(5)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(5) = "00000000" and\r
                         (spr_ptn_h(5)(0) or spr_ptn_l(5)(0)) = '1' else\r
                 "1" & spr_attr(6)(1 downto 0) & spr_ptn_h(6)(0) & spr_ptn_l(6)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(6) = "00000000" and\r
                         (spr_ptn_h(6)(0) or spr_ptn_l(6)(0)) = '1' else\r
                 "1" & spr_attr(7)(1 downto 0) & spr_ptn_h(7)(0) & spr_ptn_l(7)(0)\r
                     when ppu_mask(PPUSSP) = '1' and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) and\r
                         spr_x_cnt(7) = "00000000" and\r
                         (spr_ptn_h(7)(0) or spr_ptn_l(7)(0)) = '1' else\r
                 "0" & disp_attr(1 downto 0) & disp_ptn_h(0) & disp_ptn_l(0) \r
-                    when ppu_mask(PPUSBG) = '1' and cur_y(4) = '0' and\r
+                    when ppu_mask(PPUSBG) = '1' and nes_y(4) = '0' and\r
                         ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
                 "0" & disp_attr(5 downto 4) & disp_ptn_h(0) & disp_ptn_l(0)\r
-                    when ppu_mask(PPUSBG) = '1' and cur_y(4) = '1' and\r
+                    when ppu_mask(PPUSBG) = '1' and nes_y(4) = '1' and\r
                         ((disp_ptn_h(0) or disp_ptn_l(0)) = '1') and\r
-                        (cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
+                        (nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE)) else\r
                 ---else: no output color >> universal bg color output.\r
                 --0x3f00 is the universal bg palette.\r
                 (others => '0');    \r
@@ -875,354 +731,135 @@ begin
     palette_inst : palette_ram generic map (5, dsize)\r
             port map (mem_clk, plt_ram_ce_n, plt_r_n, plt_w_n, plt_addr, plt_data);\r
 \r
-    ---primary oam\r
-    p_oam_ram_ce_n_in <= ppu_clk when oam_bus_ce_n = '0' and r_nw = '0' else\r
-                    '0' when oam_bus_ce_n = '0' and r_nw = '1' else\r
-                    '0' when ppu_mask(PPUSSP) = '1' and\r
-                             cur_x > conv_std_logic_vector(64, X_SIZE) and\r
-                             cur_x <= conv_std_logic_vector(256, X_SIZE) and\r
-                             p_oam_cnt_wrap_n = '1' else\r
-                    '1';\r
-    p_oam_addr <= oam_plt_addr when oam_bus_ce_n = '0' else\r
-                p_oam_addr_in when ppu_mask(PPUSSP) = '1' and \r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                        cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                         cur_x > conv_std_logic_vector(64, X_SIZE) and \r
-                         cur_x <= conv_std_logic_vector(256, X_SIZE) else\r
-                (others => 'Z');\r
-    p_oam_r_n <= not r_nw when oam_bus_ce_n = '0' else\r
-                '0' when ppu_mask(PPUSSP) = '1' and \r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                        cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE)) and\r
-                         cur_x > conv_std_logic_vector(64, X_SIZE) and \r
-                         cur_x <= conv_std_logic_vector(256, X_SIZE) else\r
-                '1';\r
-    p_oam_w_n <= r_nw when oam_bus_ce_n = '0' else\r
-                '1';\r
-    oam_d_buf_w : tri_state_buffer generic map (dsize)\r
-            port map (p_oam_w_n, oam_plt_data, p_oam_data);\r
-    oam_d_buf_r : tri_state_buffer generic map (dsize)\r
-            port map (p_oam_r_n, p_oam_data, oam_plt_data);\r
-\r
-    p_oam_ram_ctl : ram_ctrl\r
-            port map (mem_clk, p_oam_ram_ce_n_in, p_oam_r_n, p_oam_w_n, p_oam_ram_ce_n);\r
-    primary_oam_inst : ram generic map (dsize, dsize)\r
-            port map (mem_clk, p_oam_ram_ce_n, p_oam_r_n, p_oam_w_n, p_oam_addr, p_oam_data);\r
-\r
-    ---secondary oam\r
-    p_oam_cnt_inst : counter_register generic map (dsize, 4)\r
-            port map (ppu_clk_n, p_oam_cnt_res_n, p_oam_cnt_ce_n, '1', (others => '0'), p_oam_cnt);\r
-    s_oam_cnt_inst : counter_register generic map (5, 1)\r
-            port map (ppu_clk_n, p_oam_cnt_res_n, s_oam_cnt_ce_n, '1', (others => '0'), s_oam_cnt);\r
-    s_oam_addr_cpy_inst : counter_register generic map (5, 1)\r
-            port map (ppu_clk_n, p_oam_cnt_res_n, s_oam_addr_cpy_ce_n, \r
-                    '1', (others => '0'), s_oam_addr_cpy);\r
-\r
-    s_oam_ram_ce_n_in <= ppu_clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and\r
-                                cur_x > "000000001" and\r
-                                cur_x <= conv_std_logic_vector(64, X_SIZE) else\r
-                      ppu_clk when ppu_mask(PPUSSP) = '1' and cur_x(0) = '1' and\r
-                                cur_x > conv_std_logic_vector(64, X_SIZE) and\r
-                                cur_x <= conv_std_logic_vector(256, X_SIZE) and\r
-                                p_oam_cnt_wrap_n = '1' else\r
-                      '0' when ppu_mask(PPUSSP) = '1' and\r
-                                cur_x > conv_std_logic_vector(256, X_SIZE) and\r
-                                cur_x <= conv_std_logic_vector(320, X_SIZE) and\r
-                                s_oam_addr_cpy_n = '0' else\r
-                      '1';\r
-\r
-    s_oam_ram_ctl : ram_ctrl\r
-            port map (mem_clk, s_oam_ram_ce_n_in, s_oam_r_n, s_oam_w_n, s_oam_ram_ce_n);\r
-    secondary_oam_inst : ram generic map (5, dsize)\r
-            port map (mem_clk, s_oam_ram_ce_n, s_oam_r_n, s_oam_w_n, s_oam_addr, s_oam_data);\r
-\r
-    spr_y_inst : d_flip_flop generic map(dsize)\r
-            port map (ppu_clk_n, p_oam_cnt_res_n, '1', spr_y_we_n, s_oam_data, spr_y_tmp);\r
-    spr_tile_inst : d_flip_flop generic map(dsize)\r
-            port map (ppu_clk_n, p_oam_cnt_res_n, '1', spr_tile_we_n, s_oam_data, spr_tile_tmp);\r
-\r
-\r
-   --reverse bit when NOT SPRHFL is set (.nes file format bit endian).\r
-   spr_ptn_in <= vram_ad when spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRHFL) = '1' else\r
-                (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
-                 vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
-    --array instances...\r
-    spr_inst : for i in 0 to 7 generate\r
-        spr_x_inst : counter_register generic map(dsize, 16#ff#)\r
-                port map (ppu_clk_n, rst_n, spr_x_ce_n(i), spr_x_we_n(i), s_oam_data, spr_x_cnt(i));\r
-\r
-        spr_attr_inst : d_flip_flop generic map(dsize)\r
-                port map (ppu_clk_n, rst_n, '1', spr_attr_we_n(i), s_oam_data, spr_attr(i));\r
-\r
-        spr_ptn_l_inst : shift_register generic map(dsize, 1)\r
-                port map (ppu_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_l_we_n(i), spr_ptn_in, spr_ptn_l(i));\r
-\r
-        spr_ptn_h_inst : shift_register generic map(dsize, 1)\r
-                port map (ppu_clk_n, rst_n, spr_ptn_ce_n(i), spr_ptn_h_we_n(i), spr_ptn_in, spr_ptn_h(i));\r
-    end generate;\r
-\r
-    pos_p : process (rst_n, ppu_clk)\r
-    begin\r
-        if (rst_n = '0') then\r
-            cnt_x_res_n <= '0';\r
-            bg_cnt_res_n <= '0';\r
-        elsif (ppu_clk'event and ppu_clk = '0') then\r
-            if (cur_x = conv_std_logic_vector(HSCAN_MAX - 1, X_SIZE)) then\r
-                --x pos reset.\r
-                cnt_x_res_n <= '0';\r
-            else\r
-                cnt_x_res_n <= '1';\r
-            end if;\r
-\r
-            if (ppu_scroll_x(0) = '0' and cur_x = conv_std_logic_vector(HSCAN, X_SIZE)) then\r
-                bg_cnt_res_n <= '0';\r
-            elsif (ppu_scroll_x(0) = '1' and cur_x = conv_std_logic_vector(HSCAN - 1, X_SIZE)) then\r
-                bg_cnt_res_n <= '0';\r
-            else\r
-                bg_cnt_res_n <= '1';\r
-            end if;\r
-        end if; --if (rst_n = '0') then\r
-    end process;\r
-\r
-    clk_p : process (rst_n, ppu_clk)\r
-\r
-procedure output_rgb is\r
-variable pl_addr : integer;\r
-variable pl_index : integer;\r
-begin\r
-    if (rst_n = '0') then\r
-        b <= (others => '0');\r
-        g <= (others => '0');\r
-        r <= (others => '0');\r
-    else\r
-        if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-            (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
-            --if or if not bg/sprite is shown, output color anyway \r
-            --sinse universal bg color is included..\r
-            pl_index := conv_integer(plt_data(5 downto 0));\r
-            b <= nes_color_palette(pl_index) (11 downto 8);\r
-            g <= nes_color_palette(pl_index) (7 downto 4);\r
-            r <= nes_color_palette(pl_index) (3 downto 0);\r
-        else\r
-            b <= (others => '0');\r
-            g <= (others => '0');\r
-            r <= (others => '0');\r
-        end if;\r
-    end if;\r
-end;\r
-\r
-procedure set_sp0_hit is\r
-begin\r
-    if (rst_n = '0') then\r
-        ppu_status(ST_SP0) <= '0';\r
-    else\r
-        if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-            (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
-            if (sprite0_displayed = '1' \r
-                and (ppu_mask(PPUSSP) = '1' and (spr_x_cnt(0) & (spr_ptn_h(0)(0) or spr_ptn_l(0)(0)) = "000000001"))\r
-                and (ppu_mask(PPUSBG) = '1' and ((disp_ptn_h(0) or disp_ptn_l(0)) = '1'))\r
-                    ) then\r
-                --raise sprite 0 hit.\r
-                ppu_status(ST_SP0) <= '1';\r
-            end if;\r
-        else\r
-            ppu_status(ST_SP0) <= '0';\r
-        end if;\r
-    end if;\r
-end;\r
-\r
+    -----------------------------------------\r
+    ---sprite main process\r
+    -----------------------------------------\r
+    spr_main_p : process (rst_n, emu_ppu_clk)\r
     begin\r
         if (rst_n = '0') then\r
-            nt_we_n <= '1';\r
-            ppu_status <= (others => '0');\r
+            s_oam_addr <= (others => 'Z');\r
             s_oam_data <= (others => 'Z');\r
-        else\r
-\r
-            if (ppu_clk'event and ppu_clk = '1') then\r
-\r
-                --fetch bg pattern and display.\r
-                if (ppu_mask(PPUSBG) = '1' and \r
-                        (cur_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
-                        cur_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                        cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
-                    --visible area bg image\r
-\r
-                    d_print("*");\r
-                    d_print("cur_x: " & conv_hex16(conv_integer(cur_x)));\r
-                    d_print("cur_y: " & conv_hex16(conv_integer(cur_y)));\r
-\r
-                    ----fetch next tile byte.\r
-                    if (prf_x (2 downto 0) = "001") then\r
-                        --vram addr is incremented every 8 cycle.\r
-                        --name table at 0x2000\r
-                        vram_addr(9 downto 0) \r
-                            <= prf_y(dsize - 1 downto 3) \r
-                                & prf_x(dsize - 1 downto 3);\r
-                        vram_addr(asize - 1 downto 10) <= "10" & ppu_ctrl(PPUBNA downto 0) \r
-                                                        + ("000" & prf_x(dsize));\r
-                    ----fetch attr table byte.\r
-                    elsif (prf_x (4 downto 0) = "00011") then\r
-                        --attribute table is loaded every 32 cycle.\r
-                        --attr table at 0x23c0\r
-                        vram_addr(dsize - 1 downto 0) <= "11000000" +\r
-                                ("00" & prf_y(7 downto 5) & prf_x(7 downto 5));\r
-                        vram_addr(asize - 1 downto dsize) <= "10" &\r
-                                ppu_ctrl(PPUBNA downto 0) & "11"\r
-                                    + ("000" & prf_x(dsize) & "00");\r
-                    ----fetch pattern table low byte.\r
-                    elsif (prf_x (2 downto 0) = "101") then\r
-                         --vram addr is incremented every 8 cycle.\r
-                         vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
-                                              disp_nt(dsize - 1 downto 0) \r
-                                                    & "0"  & prf_y(2  downto 0);\r
-                    ----fetch pattern table high byte.\r
-                    elsif (prf_x (2 downto 0) = "111") then\r
-                         --vram addr is incremented every 8 cycle.\r
-                         vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
-                                              disp_nt(dsize - 1 downto 0) \r
-                                                    & "0"  & prf_y(2 downto 0) + "00000000001000";\r
-                    end if;\r
-\r
-                    ----fetch next tile byte.\r
-                    if (prf_x (2 downto 0) = "010") then\r
-                        nt_we_n <= '0';\r
-                    else\r
-                        nt_we_n <= '1';\r
-                    end if;\r
-\r
-                    ----fetch attr table byte.\r
-                    if (prf_x (4 downto 0) = "00100") then\r
-                        attr_we_n <= '0';\r
-                    else\r
-                        attr_we_n <= '1';\r
-                    end if;\r
-                    if (prf_x (4 downto 0) = "10000") then\r
-                        disp_attr_we_n <= '0';\r
-                    else\r
-                        disp_attr_we_n <= '1';\r
-                    end if;\r
-                    ---attribute is shifted every 16 bit.\r
-                    if (prf_x (3 downto 0) = "0000") then\r
-                        attr_ce_n <= '0';\r
-                    else\r
-                        attr_ce_n <= '1';\r
-                    end if;\r
 \r
-                    ----fetch pattern table low byte.\r
-                    if (prf_x (2 downto 0) = "110") then\r
-                         ptn_l_we_n <= '0';\r
-                    else\r
-                         ptn_l_we_n <= '1';\r
-                    end if;\r
+            s_oam_r_n <= '1';\r
+            s_oam_w_n <= '1';\r
+            p_oam_cnt_res_n <= '1';\r
+            p_oam_cnt_ce_n <= '1';\r
+            s_oam_cnt_ce_n <= '1';\r
+            oam_ev_status <= EV_STAT_COMP;\r
+            p_oam_addr_in <= (others => 'Z');\r
+\r
+            s_oam_addr_cpy_n <= '1';\r
+            spr_y_we_n <= '1';\r
+            spr_tile_we_n <= '1';\r
+            spr_x_we_n <= (others => '1');\r
+            spr_attr_we_n <= (others => '1');\r
+            spr_ptn_l_we_n <= (others => '1');\r
+            spr_ptn_h_we_n <= (others => '1');\r
+            s_oam_addr_cpy_ce_n <= '1';\r
+            spr_x_ce_n <= (others => '1');\r
+            spr_ptn_ce_n <= (others => '1');\r
+\r
+            sprite0_evaluated <= '0';\r
+            sprite0_displayed <= '0';\r
 \r
-                    ----fetch pattern table high byte.\r
-                    if (prf_x (2 downto 0) = "000") then\r
-                         ptn_h_we_n <= '0';\r
-                    else\r
-                         ptn_h_we_n <= '1';\r
-                    end if;\r
+        else\r
 \r
-                else\r
-                    nt_we_n <= '1';\r
-                    attr_we_n <= '1';\r
-                    disp_attr_we_n <= '1';\r
-                    attr_ce_n <= '1';\r
-                    ptn_l_we_n <= '1';\r
-                    ptn_h_we_n <= '1';\r
-                end if;--if (ppu_mask(PPUSBG) = '1') and\r
+            if (rising_edge(emu_ppu_clk)) then\r
 \r
-                --fetch sprite and display.\r
                 if (ppu_mask(PPUSSP) = '1' and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                        cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                        nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE))) then\r
                     --secondary oam clear\r
-                    if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE)) then\r
-                        if (cur_x(0) = '0') then\r
-                            --write secondary oam on even cycle\r
-                            s_oam_r_n <= '1';\r
-                            s_oam_w_n <= '0';\r
-                            s_oam_addr <= cur_x(5 downto 1);\r
-                            s_oam_data <= (others => '1');\r
+                    if (nes_x <= conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE)) then\r
+                        if (nes_x(0) = '1') then\r
+                            --odd cycle is set address.\r
+                            --even cycle is write data.\r
+                            s_oam_addr <= nes_x(5 downto 1);\r
                         end if;\r
+                        s_oam_r_n <= '1';\r
+                        s_oam_w_n <= '0';\r
+                        s_oam_data <= (others => '1');\r
                         p_oam_cnt_res_n <= '0';\r
                         p_oam_cnt_ce_n <= '1';\r
                         s_oam_cnt_ce_n <= '1';\r
-                        p_oam_cnt_wrap_n <= '1';\r
                         oam_ev_status <= EV_STAT_COMP;\r
 \r
                     --sprite evaluation and secondary oam copy.\r
-                    elsif (cur_x > conv_std_logic_vector(64, X_SIZE) and \r
-                            cur_x <= conv_std_logic_vector(256, X_SIZE)) then\r
+                    elsif (nes_x > conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE) and \r
+                            nes_x <= conv_std_logic_vector(HSCAN, X_SIZE)) then\r
                         p_oam_cnt_res_n <= '1';\r
+                        s_oam_r_n <= '1';\r
 \r
                         --TODO: sprite evaluation is simplified!!\r
                         --not complying the original NES spec at\r
                         --http://wiki.nesdev.com/w/index.php/PPU_sprite_evaluation\r
                         --e.g., when overflow happens, it just ignore subsequent entry.\r
-                        --old secondary sprite entry.\r
-                        if (p_oam_cnt = "00000000" and cur_x > conv_std_logic_vector(192, X_SIZE)) then\r
-                            p_oam_cnt_wrap_n <= '0';\r
-                        end if;\r
-\r
-                        --odd cycle copy from primary oam\r
-                        if (cur_x(0) = '1') then\r
-                            if (oam_ev_status = EV_STAT_COMP) then\r
-                                p_oam_addr_in <= p_oam_cnt;\r
-                                p_oam_cnt_ce_n <= '1';\r
-                                s_oam_cnt_ce_n <= '1';\r
-                            elsif (oam_ev_status = EV_STAT_CP1) then\r
-                                p_oam_addr_in <= p_oam_cnt + "00000001";\r
-                                s_oam_cnt_ce_n <= '1';\r
-\r
-                            elsif (oam_ev_status = EV_STAT_CP2) then\r
-                                p_oam_addr_in <= p_oam_cnt + "00000010";\r
-                                s_oam_cnt_ce_n <= '1';\r
-\r
-                            elsif (oam_ev_status = EV_STAT_CP3) then\r
-                                oam_ev_status <= EV_STAT_PRE_COMP;\r
-                                p_oam_addr_in <= p_oam_cnt + "00000011";\r
-                                s_oam_cnt_ce_n <= '1';\r
-                            end if;\r
+                        if (s_oam_cnt(5) = '1' or p_oam_cnt(8) = '1') then\r
+                            s_oam_cnt_ce_n <= '1';\r
+                            s_oam_w_n <= '1';\r
+                            s_oam_addr <= (others => 'Z');\r
+                            s_oam_data <= (others => 'Z');\r
                         else\r
-                        --even cycle copy to secondary oam (if y is in range.)\r
-                            s_oam_r_n <= '1';\r
-                            s_oam_w_n <= '0';\r
-                            s_oam_addr <= s_oam_cnt;\r
-                            s_oam_data <= p_oam_data;\r
-\r
-                            if (oam_ev_status = EV_STAT_COMP) then\r
-                                --check y range.\r
-                                if (cur_y < "000000110" and p_oam_data <= cur_y + "000000001") or \r
-                                    (cur_y >= "000000110" and p_oam_data <= cur_y + "000000001" and \r
-                                             p_oam_data >= cur_y - "000000110") then\r
-                                    oam_ev_status <= EV_STAT_CP1;\r
-                                    s_oam_cnt_ce_n <= '0';\r
-                                    --copy remaining oam entry.\r
+                            --odd cycle copy from primary oam\r
+                            if (nes_x(0) = '1') then\r
+                                s_oam_w_n <= '1';\r
+                                if (oam_ev_status = EV_STAT_COMP) then\r
+                                    p_oam_addr_in <= p_oam_cnt(7 downto 0);\r
                                     p_oam_cnt_ce_n <= '1';\r
-                                    \r
-                                    --check sprite 0 is used.\r
-                                    if (p_oam_cnt = "00000000") then\r
-                                        sprite0_evaluated <= '1';\r
+                                    s_oam_cnt_ce_n <= '1';\r
+                                elsif (oam_ev_status = EV_STAT_CP1) then\r
+                                    p_oam_addr_in <= p_oam_cnt(7 downto 0) + "00000001";\r
+                                    s_oam_cnt_ce_n <= '1';\r
+\r
+                                elsif (oam_ev_status = EV_STAT_CP2) then\r
+                                    p_oam_addr_in <= p_oam_cnt(7 downto 0) + "00000010";\r
+                                    s_oam_cnt_ce_n <= '1';\r
+\r
+                                elsif (oam_ev_status = EV_STAT_CP3) then\r
+                                    oam_ev_status <= EV_STAT_PRE_COMP;\r
+                                    p_oam_addr_in <= p_oam_cnt(7 downto 0) + "00000011";\r
+                                    s_oam_cnt_ce_n <= '1';\r
+                                end if;\r
+                            else\r
+                            --even cycle copy to secondary oam (if y is in range.)\r
+\r
+                                s_oam_w_n <= '0';\r
+                                s_oam_addr <= s_oam_cnt(4 downto 0);\r
+                                s_oam_data <= p_oam_data;\r
+\r
+                                if (oam_ev_status = EV_STAT_COMP) then\r
+                                    --check y range.\r
+                                    if (nes_y < "000000110" and p_oam_data <= nes_y + "000000001") or \r
+                                        (nes_y >= "000000110" and p_oam_data <= nes_y + "000000001" and \r
+                                                 p_oam_data >= nes_y - "000000110") then\r
+                                        oam_ev_status <= EV_STAT_CP1;\r
+                                        s_oam_cnt_ce_n <= '0';\r
+                                        --copy remaining oam entry.\r
+                                        p_oam_cnt_ce_n <= '1';\r
+                                        \r
+                                        --check sprite 0 is used.\r
+                                        if (p_oam_cnt(7 downto 0) = "00000000") then\r
+                                            sprite0_evaluated <= '1';\r
+                                        end if;\r
+                                    else\r
+                                        --goto next entry\r
+                                        p_oam_cnt_ce_n <= '0';\r
                                     end if;\r
-                                else\r
-                                    --goto next entry\r
+                                elsif (oam_ev_status = EV_STAT_CP1) then\r
+                                    s_oam_cnt_ce_n <= '0';\r
+                                    oam_ev_status <= EV_STAT_CP2;\r
+                                elsif (oam_ev_status = EV_STAT_CP2) then\r
+                                    s_oam_cnt_ce_n <= '0';\r
+                                    oam_ev_status <= EV_STAT_CP3;\r
+                                elsif (oam_ev_status = EV_STAT_CP3) then\r
+                                    s_oam_cnt_ce_n <= '0';\r
+                                elsif (oam_ev_status = EV_STAT_PRE_COMP) then\r
+                                    oam_ev_status <= EV_STAT_COMP;\r
+                                    s_oam_cnt_ce_n <= '0';\r
                                     p_oam_cnt_ce_n <= '0';\r
                                 end if;\r
-                            elsif (oam_ev_status = EV_STAT_CP1) then\r
-                                s_oam_cnt_ce_n <= '0';\r
-                                oam_ev_status <= EV_STAT_CP2;\r
-                            elsif (oam_ev_status = EV_STAT_CP2) then\r
-                                s_oam_cnt_ce_n <= '0';\r
-                                oam_ev_status <= EV_STAT_CP3;\r
-                            elsif (oam_ev_status = EV_STAT_CP3) then\r
-                                s_oam_cnt_ce_n <= '0';\r
-                            elsif (oam_ev_status = EV_STAT_PRE_COMP) then\r
-                                oam_ev_status <= EV_STAT_COMP;\r
-                                s_oam_cnt_ce_n <= '0';\r
-                                p_oam_cnt_ce_n <= '0';\r
-                            end if;\r
-                        end if;--if (cur_x(0) = '1') then\r
+                            end if;--if (nes_x(0) = '1') then\r
+                        end if;--(s_oam_cnt(5) = '1' or p_oam_cnt(8) = '') then\r
 \r
                         --prepare for next step\r
                         s_oam_addr_cpy_n <= '1';\r
@@ -1234,8 +871,8 @@ end;
                         spr_ptn_h_we_n <= "11111111";\r
 \r
                     --sprite pattern fetch\r
-                    elsif (cur_x > conv_std_logic_vector(256, X_SIZE) and \r
-                            cur_x <= conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) then\r
+                    elsif (nes_x > conv_std_logic_vector(HSCAN, X_SIZE) and \r
+                            nes_x < conv_std_logic_vector(HSCAN_SPR_MAX, X_SIZE)) then\r
 \r
                         s_oam_addr_cpy_n <= '0';\r
                         s_oam_r_n <= '0';\r
@@ -1243,7 +880,7 @@ end;
                         s_oam_addr <= s_oam_addr_cpy;\r
 \r
                         ----fetch y-cordinate from secondary oam\r
-                        if (cur_x (2 downto 0) = "001" ) then\r
+                        if (nes_x (2 downto 0) = "001" ) then\r
                             s_oam_addr_cpy_ce_n <= '0';\r
                             spr_y_we_n <= '0';\r
                         else\r
@@ -1251,64 +888,36 @@ end;
                         end if;\r
 \r
                         ----fetch tile number\r
-                        if (cur_x (2 downto 0) = "010" ) then\r
+                        if (nes_x (2 downto 0) = "010" ) then\r
                             spr_tile_we_n <= '0';\r
                         else\r
                             spr_tile_we_n <= '1';\r
                         end if;\r
 \r
                         ----fetch attribute\r
-                        if (cur_x (2 downto 0) = "011" ) then\r
+                        if (nes_x (2 downto 0) = "011" ) then\r
                             spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
                         else\r
                             spr_attr_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
-                        end if;--if (cur_x (2 downto 0) = "010" ) then\r
+                        end if;--if (nes_x (2 downto 0) = "010" ) then\r
 \r
                         ----fetch x-cordinate\r
-                        if (cur_x (2 downto 0) = "100" ) then\r
+                        if (nes_x (2 downto 0) = "100" ) then\r
                             s_oam_addr_cpy_ce_n <= '1';\r
                             spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
                         else\r
                             spr_x_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
                         end if;\r
 \r
-                        ----fetch pattern table low byte.\r
-                        if (cur_x (2 downto 0) = "101" ) then\r
-                            if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
-                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
-                                            spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
-                                            (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0));\r
-                            else\r
-                                --flip sprite vertically.\r
-                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
-                                            spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
-                                            (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010");\r
-                            end if;\r
-                        end if;\r
-\r
-                        if (cur_x (2 downto 0) = "110" ) then\r
+                        --pattern tbl low vale.\r
+                        if (nes_x (2 downto 0) = "110" ) then\r
                             spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
                         else\r
                             spr_ptn_l_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '1';\r
                         end if;\r
 \r
-                        ----fetch pattern table high byte.\r
-                        if (cur_x (2 downto 0) = "111" ) then\r
-                            if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
-                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
-                                            spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
-                                            (cur_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0))\r
-                                                + "00000000001000";\r
-                            else\r
-                                --flip sprite vertically.\r
-                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
-                                            spr_tile_tmp(dsize - 1 downto 0) & "0"  & \r
-                                            (spr_y_tmp(2 downto 0) - cur_y(2 downto 0) - "010")\r
-                                                + "00000000001000";\r
-                            end if;\r
-                        end if;\r
-\r
-                        if (cur_x (2 downto 0) = "000") then\r
+                        --pattern tbl high vale.\r
+                        if (nes_x (2 downto 0) = "000") then\r
                             spr_ptn_h_we_n(conv_integer(s_oam_addr_cpy(4 downto 2))) <= '0';\r
                             s_oam_addr_cpy_ce_n <= '0';\r
                         else\r
@@ -1320,16 +929,16 @@ end;
                             sprite0_displayed <= '1';\r
                         end if;\r
 \r
-                    elsif (cur_x > conv_std_logic_vector(320, X_SIZE)) then\r
+                    elsif (nes_x > conv_std_logic_vector(HSCAN_SPR_MAX, X_SIZE)) then\r
                         --clear last write enable.\r
                         spr_ptn_h_we_n <= "11111111";\r
-                    end if;--if (cur_x /= "000000000" and cur_x <= conv_std_logic_vector(64, X_SIZE))\r
+                    end if;--if (nes_x <= conv_std_logic_vector(HSCAN_OAM_EVA_START, X_SIZE))\r
 \r
                     --display sprite.\r
-                    if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
-                        (cur_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+                    if ((nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
                         --start counter.\r
-                        if (cur_x = "000000000") then\r
+                        if (nes_x = "000000000") then\r
                             spr_x_ce_n <= "00000000";\r
                         end if;\r
 \r
@@ -1343,16 +952,132 @@ end;
                     else\r
                         spr_x_ce_n <= "11111111";\r
                         spr_ptn_ce_n <= "11111111";\r
-                    end if; --if ((cur_x < conv_std_logic_vector(HSCAN, X_SIZE)) \r
+                    end if; --if ((nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) \r
                 else\r
                     --sprite evaluation are cleared during the blank line.\r
                     sprite0_evaluated <= '0';\r
                     sprite0_displayed <= '0';\r
                 end if; --if (ppu_mask(PPUSSP) = '1') \r
-                        --(cur_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
-                        --cur_y = conv_std_logic_vector(VSCAN_MAX - 1, X_SIZE))) then\r
+                        --(nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                        --nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE))) then\r
                 \r
+            end if; --if (rising_edge(emu_ppu_clk)) then\r
+\r
+        end if;--if (rst_n = '0') then\r
+    end process;\r
+\r
+    vaddr_p : process (rst_n, emu_ppu_clk)\r
+    begin\r
+        if (rst_n = '0') then\r
+            vram_addr <= (others => 'Z');\r
+        else\r
+            if (rising_edge(emu_ppu_clk)) then\r
+                --fetch sprite and display.\r
+                if (ppu_mask(PPUSSP) = '1' and\r
+                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                        nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE))) then\r
+\r
+                    --sprite pattern fetch.\r
+                    if (nes_x > conv_std_logic_vector(HSCAN, X_SIZE) and \r
+                        nes_x <= conv_std_logic_vector(HSCAN_SPR_MAX, X_SIZE)) then\r
+                        \r
+                        ----fetch pattern table low byte.\r
+                        if (nes_x (2 downto 0) = "101" ) then\r
+                            if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
+                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+                                            spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+                                            (nes_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0));\r
+                            else\r
+                                --flip sprite vertically.\r
+                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+                                            spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+                                            (spr_y_tmp(2 downto 0) - nes_y(2 downto 0) - "010");\r
+                            end if;\r
+                        \r
+                        ----fetch pattern table high byte.\r
+                        elsif (nes_x (2 downto 0) = "111" ) then\r
+                            if (spr_attr(conv_integer(s_oam_addr_cpy(4 downto 2)))(SPRVFL) = '0') then\r
+                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+                                            spr_tile_tmp(dsize - 1 downto 0) & "0" & \r
+                                            (nes_y(2 downto 0) + "001" - spr_y_tmp(2 downto 0))\r
+                                                + "00000000001000";\r
+                            else\r
+                                --flip sprite vertically.\r
+                                vram_addr <= "0" & ppu_ctrl(PPUSPA) & \r
+                                            spr_tile_tmp(dsize - 1 downto 0) & "0"  & \r
+                                            (spr_y_tmp(2 downto 0) - nes_y(2 downto 0) - "010")\r
+                                                + "00000000001000";\r
+                            end if;\r
+                        end if;\r
+\r
+                    else\r
+                        vram_addr <= (others => 'Z');\r
+                    end if; --if (nes_x > conv_std_logic_vector(HSCAN, X_SIZE) and \r
+                                --nes_x <= conv_std_logic_vector(HSCAN_SPR_MAX, X_SIZE)) then\r
+\r
+                else\r
+                    vram_addr <= (others => 'Z');\r
+                end if; --if (ppu_mask(PPUSSP) = '1') \r
+                        --(nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+                        --nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE))) then\r
+            end if; --if (rising_edge(emu_ppu_clk)) then\r
+        end if;--if (rst_n = '0') then\r
+    end process;\r
+\r
+\r
+    output_p : process (rst_n, emu_ppu_clk)\r
+\r
+procedure output_rgb is\r
+variable pl_addr : integer;\r
+variable pl_index : integer;\r
+begin\r
+    if (rst_n = '0') then\r
+        b <= (others => '0');\r
+        g <= (others => '0');\r
+        r <= (others => '0');\r
+    else\r
+        if ((nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+            (nes_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+            --if or if not bg/sprite is shown, output color anyway \r
+            --sinse universal bg color is included..\r
+            pl_index := conv_integer(plt_data(5 downto 0));\r
+            b <= nes_color_palette(pl_index) (11 downto 8);\r
+            g <= nes_color_palette(pl_index) (7 downto 4);\r
+            r <= nes_color_palette(pl_index) (3 downto 0);\r
+        else\r
+            b <= (others => '0');\r
+            g <= (others => '0');\r
+            r <= (others => '0');\r
+        end if;\r
+    end if;\r
+end;\r
+\r
+procedure set_sp0_hit is\r
+begin\r
+    if (rst_n = '0') then\r
+        ppu_status(ST_SP0) <= '0';\r
+    else\r
+        if ((nes_x < conv_std_logic_vector(HSCAN, X_SIZE)) and\r
+            (nes_y < conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+            if (sprite0_displayed = '1' \r
+                and (ppu_mask(PPUSSP) = '1' and (spr_x_cnt(0) & (spr_ptn_h(0)(0) or spr_ptn_l(0)(0)) = "000000001"))\r
+                and (ppu_mask(PPUSBG) = '1' and ((disp_ptn_h(0) or disp_ptn_l(0)) = '1'))\r
+                    ) then\r
+                --raise sprite 0 hit.\r
+                ppu_status(ST_SP0) <= '1';\r
+            end if;\r
+        else\r
+            ppu_status(ST_SP0) <= '0';\r
+        end if;\r
+    end if;\r
+end;\r
 \r
+    begin\r
+        if (rst_n = '0') then\r
+            ppu_status <= (others => '0');\r
+        else\r
+\r
+            if (rising_edge(emu_ppu_clk)) then\r
                 --output visible area only.\r
                 output_rgb;\r
 \r
@@ -1361,22 +1086,159 @@ end;
                 ppu_status(ST_SOF) <= '0';\r
                 set_sp0_hit;\r
 \r
-                if ((cur_y > conv_std_logic_vector(VSCAN, X_SIZE))) then\r
+                if ((nes_y > conv_std_logic_vector(VSCAN, X_SIZE))) then\r
                     --vblank start\r
                     ppu_status(ST_VBL) <= '1';\r
                 else\r
                     --vblank end\r
                     ppu_status(ST_VBL) <= '0';\r
                 end if;\r
-            end if; --if (clk'event and clk = '1') then\r
-\r
+                \r
 --            if (read_status'event and read_status = '1') then\r
 --                --reading ppu status clears vblank bit.\r
 --                ppu_status(ST_VBL) <= '0';\r
 --            end if;\r
 \r
+            end if; --if (rising_edge(emu_ppu_clk)) then\r
         end if;--if (rst_n = '0') then\r
     end process;\r
 \r
+--    ---bg prefetch x pos is 16 + scroll cycle ahead of current pos.\r
+--    prf_x <= nes_x + ppu_scroll_x + "000010000" \r
+--                    when nes_x < conv_std_logic_vector(HSCAN, X_SIZE) else\r
+--             nes_x + ppu_scroll_x + "010111011"; -- +16 -341\r
+--\r
+--    prf_y <= nes_y + ppu_scroll_y\r
+--                    when nes_x < conv_std_logic_vector(HSCAN, X_SIZE) and\r
+--                         nes_y < conv_std_logic_vector(VSCAN, X_SIZE) else\r
+--             nes_y + ppu_scroll_y + "000000001" \r
+--                    when nes_y < conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE) else\r
+--             "000000000"; \r
+--\r
+--    nt_inst : d_flip_flop generic map(dsize)\r
+--            port map (ppu_clk_n, rst_n, '1', nt_we_n, vram_ad, disp_nt);\r
+--\r
+--    at_inst : d_flip_flop generic map(dsize)\r
+--            port map (ppu_clk_n, rst_n, '1', attr_we_n, vram_ad, attr_val);\r
+--\r
+--    disp_at_inst : shift_register generic map(dsize, 2)\r
+--            port map (ppu_clk_n, rst_n, attr_ce_n, disp_attr_we_n, attr_val, disp_attr);\r
+--\r
+--    --chr rom data's bit is stored in opposite direction.\r
+--    --reverse bit when loading...\r
+--    ptn_l_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+--                 vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7));\r
+--    ptn_h_in <= (vram_ad(0) & vram_ad(1) & vram_ad(2) & vram_ad(3) & \r
+--                 vram_ad(4) & vram_ad(5) & vram_ad(6) & vram_ad(7)) & \r
+--                disp_ptn_h (dsize downto 1);\r
+--\r
+--    ptn_l_inst : d_flip_flop generic map(dsize)\r
+--            port map (ppu_clk_n, rst_n, '1', ptn_l_we_n, ptn_l_in, ptn_l_val);\r
+--\r
+--    disp_ptn_l_in <= ptn_l_val & disp_ptn_l (dsize downto 1);\r
+--    disp_ptn_l_inst : shift_register generic map(dsize * 2, 1)\r
+--            port map (ppu_clk_n, rst_n, '0', ptn_h_we_n, disp_ptn_l_in, disp_ptn_l);\r
+--\r
+--    ptn_h_inst : shift_register generic map(dsize * 2, 1)\r
+--            port map (ppu_clk_n, rst_n, '0', ptn_h_we_n, ptn_h_in, disp_ptn_h);\r
+--\r
+\r
+\r
+\r
+\r
+--            nt_we_n <= '1';\r
+\r
+--                --fetch bg pattern and display.\r
+--                if (ppu_mask(PPUSBG) = '1' and \r
+--                        (nes_x <= conv_std_logic_vector(HSCAN, X_SIZE) or\r
+--                        nes_x > conv_std_logic_vector(HSCAN_NEXT_START, X_SIZE)) and\r
+--                        (nes_y < conv_std_logic_vector(VSCAN, X_SIZE) or \r
+--                        nes_y = conv_std_logic_vector(VSCAN_NEXT_START, X_SIZE))) then\r
+--                    --visible area bg image\r
+--\r
+--                    d_print("*");\r
+--                    d_print("nes_x: " & conv_hex16(conv_integer(nes_x)));\r
+--                    d_print("nes_y: " & conv_hex16(conv_integer(nes_y)));\r
+--\r
+--                    ----fetch next tile byte.\r
+--                    if (prf_x (2 downto 0) = "001") then\r
+--                        --vram addr is incremented every 8 cycle.\r
+--                        --name table at 0x2000\r
+--                        vram_addr(9 downto 0) \r
+--                            <= prf_y(dsize - 1 downto 3) \r
+--                                & prf_x(dsize - 1 downto 3);\r
+--                        vram_addr(asize - 1 downto 10) <= "10" & ppu_ctrl(PPUBNA downto 0) \r
+--                                                        + ("000" & prf_x(dsize));\r
+--                    ----fetch attr table byte.\r
+--                    elsif (prf_x (4 downto 0) = "00011") then\r
+--                        --attribute table is loaded every 32 cycle.\r
+--                        --attr table at 0x23c0\r
+--                        vram_addr(dsize - 1 downto 0) <= "11000000" +\r
+--                                ("00" & prf_y(7 downto 5) & prf_x(7 downto 5));\r
+--                        vram_addr(asize - 1 downto dsize) <= "10" &\r
+--                                ppu_ctrl(PPUBNA downto 0) & "11"\r
+--                                    + ("000" & prf_x(dsize) & "00");\r
+--                    ----fetch pattern table low byte.\r
+--                    elsif (prf_x (2 downto 0) = "101") then\r
+--                         --vram addr is incremented every 8 cycle.\r
+--                         vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
+--                                              disp_nt(dsize - 1 downto 0) \r
+--                                                    & "0"  & prf_y(2  downto 0);\r
+--                    ----fetch pattern table high byte.\r
+--                    elsif (prf_x (2 downto 0) = "111") then\r
+--                         --vram addr is incremented every 8 cycle.\r
+--                         vram_addr <= "0" & ppu_ctrl(PPUBPA) & \r
+--                                              disp_nt(dsize - 1 downto 0) \r
+--                                                    & "0"  & prf_y(2 downto 0) + "00000000001000";\r
+--                    end if;\r
+--\r
+--                    ----fetch next tile byte.\r
+--                    if (prf_x (2 downto 0) = "010") then\r
+--                        nt_we_n <= '0';\r
+--                    else\r
+--                        nt_we_n <= '1';\r
+--                    end if;\r
+--\r
+--                    ----fetch attr table byte.\r
+--                    if (prf_x (4 downto 0) = "00100") then\r
+--                        attr_we_n <= '0';\r
+--                    else\r
+--                        attr_we_n <= '1';\r
+--                    end if;\r
+--                    if (prf_x (4 downto 0) = "10000") then\r
+--                        disp_attr_we_n <= '0';\r
+--                    else\r
+--                        disp_attr_we_n <= '1';\r
+--                    end if;\r
+--                    ---attribute is shifted every 16 bit.\r
+--                    if (prf_x (3 downto 0) = "0000") then\r
+--                        attr_ce_n <= '0';\r
+--                    else\r
+--                        attr_ce_n <= '1';\r
+--                    end if;\r
+--\r
+--                    ----fetch pattern table low byte.\r
+--                    if (prf_x (2 downto 0) = "110") then\r
+--                         ptn_l_we_n <= '0';\r
+--                    else\r
+--                         ptn_l_we_n <= '1';\r
+--                    end if;\r
+--\r
+--                    ----fetch pattern table high byte.\r
+--                    if (prf_x (2 downto 0) = "000") then\r
+--                         ptn_h_we_n <= '0';\r
+--                    else\r
+--                         ptn_h_we_n <= '1';\r
+--                    end if;\r
+--\r
+--                else\r
+--                    nt_we_n <= '1';\r
+--                    attr_we_n <= '1';\r
+--                    disp_attr_we_n <= '1';\r
+--                    attr_ce_n <= '1';\r
+--                    ptn_l_we_n <= '1';\r
+--                    ptn_h_we_n <= '1';\r
+--                end if;--if (ppu_mask(PPUSBG) = '1') and\r
+\r
 end rtl;\r
 \r
index 0c47241..3c791d1 100644 (file)
@@ -26,16 +26,16 @@ add wave -label cpu_clk       sim:/testbench_motones_sim/sim_board/dbg_cpu_clk
 add wave -label r_nw       sim:/testbench_motones_sim/sim_board/dbg_r_nw\r
 add wave -label addr       -radix hex sim:/testbench_motones_sim/sim_board/dbg_addr\r
 add wave -label d_io       -radix hex sim:/testbench_motones_sim/sim_board/dbg_d_io\r
-add wave -label instruction -radix hex sim:/testbench_motones_sim/sim_board/dbg_instruction\r
+#add wave -label instruction -radix hex sim:/testbench_motones_sim/sim_board/dbg_instruction\r
 \r
 \r
-add wave -divider ce-pins\r
-add wave -label rom_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(5)\r
-add wave -label ram_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(6)\r
+#add wave -divider ce-pins\r
+#add wave -label rom_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(5)\r
+#add wave -label ram_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(6)\r
 \r
 #add wave -radix hex sim:/testbench_motones_sim/sim_board/dbg_int_d_bus\r
-add wave -label exec_cycle -radix hex sim:/testbench_motones_sim/sim_board/dbg_exec_cycle\r
-add wave -label ea_carry   -radix decimal -unsigned  sim:/testbench_motones_sim/sim_board/dbg_ea_carry     \r
+#add wave -label exec_cycle -radix hex sim:/testbench_motones_sim/sim_board/dbg_exec_cycle\r
+#add wave -label ea_carry   -radix decimal -unsigned  sim:/testbench_motones_sim/sim_board/dbg_ea_carry     \r
 #add wave -label wait_a58_branch_next -radix hex sim:/testbench_motones_sim/sim_board/dbg_wait_a58_branch_next     \r
 \r
 \r
@@ -60,17 +60,18 @@ add wave -label ppu_mask  -radix hex sim:/testbench_motones_sim/sim_board/dbg_pp
 add wave -label ppu_status   -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_status\r
 add wave -label ppu_addr -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_addr\r
 add wave -label ppu_data -radix hex sim:/testbench_motones_sim/sim_board/dbg_ppu_data\r
-add wave -label ppu_scrl_x -radix decimal -unsigned  sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x\r
-add wave -label ppu_scrl_y -radix decimal -unsigned  sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y\r
+#add wave -label ppu_scrl_x -radix decimal -unsigned  sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x\r
+#add wave -label ppu_scrl_y -radix decimal -unsigned  sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y\r
 \r
 \r
 add wave -divider vga_pos\r
+add wave -label emu_ppu_clk     sim:/testbench_motones_sim/sim_board/dbg_exec_cycle(3)\r
 add wave -label nes_x           -radix decimal -unsigned  {sim:/testbench_motones_sim/sim_board/dbg_exec_cycle(0) & \r
                                                            sim:/testbench_motones_sim/sim_board/dbg_instruction(7 downto 0)}\r
 add wave -label nes_y           -radix decimal -unsigned  {sim:/testbench_motones_sim/sim_board/dbg_exec_cycle(4) & \r
                                                            sim:/testbench_motones_sim/sim_board/dbg_status(7 downto 0)}\r
-add wave -label dbg_disp_nt     -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_nt\r
-add wave -label dbg_disp_attr   -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_attr\r
+#add wave -label dbg_disp_nt     -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_nt\r
+#add wave -label dbg_disp_attr   -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_attr\r
 #add wave -label dbg_disp_ptn_h  -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_h\r
 #add wave -label dbg_disp_ptn_l  -radix hex sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_l\r
 \r
@@ -78,9 +79,10 @@ add wave -divider vram
 add wave -label ale sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(0)\r
 add wave -label rd_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(1)\r
 add wave -label wr_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(2)\r
-add wave -label nt0_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(3)\r
+#add wave -label nt0_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_x(3)\r
 \r
-add wave  -radix hex -label v_addr {sim:/testbench_motones_sim/sim_board/dbg_sp(5 downto 0)}\r
+add wave  -radix hex -label v_addr  {sim:/testbench_motones_sim/sim_board/dbg_vram_a(13 downto 8) & \r
+                                     sim:/testbench_motones_sim/sim_board/dbg_vram_ad(7 downto 0)}\r
 add wave  -radix hex -label vram_ad sim:/testbench_motones_sim/sim_board/dbg_vram_ad\r
 \r
 #add wave -label plt_ce_n sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y(5)\r
@@ -96,6 +98,8 @@ add wave  -radix hex -label vram_ad sim:/testbench_motones_sim/sim_board/dbg_vra
 add wave -divider oam\r
 add wave  -radix hex -label p_oam_addr {sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_l (7 downto 0)}\r
 add wave  -radix hex -label p_oam_data {sim:/testbench_motones_sim/sim_board/dbg_disp_ptn_l (15 downto 8)}\r
+add wave  -radix hex -label s_oam_addr {sim:/testbench_motones_sim/sim_board/dbg_int_d_bus (4 downto 0)}\r
+add wave  -radix hex -label s_oam_data sim:/testbench_motones_sim/sim_board/dbg_ppu_scrl_y\r
 \r
 #add wave -divider vga_out\r
 #add wave -label h_sync_n    sim:/testbench_motones_sim/sim_board/v_sync_n\r
@@ -113,7 +117,9 @@ wave zoom full
 \r
 #wave zoom range 3339700 ps 5138320 ps\r
 \r
-run 100 us\r
+run 120 us\r
+run 200 us\r
+#run 30 us\r
 \r
 ##wave addcursor 907923400 ps\r
 \r
index 4f3ec78..dc6dfc8 100644 (file)
@@ -96,23 +96,26 @@ add wave -label nes_x -radix decimal -unsigned sim:/testbench_motones_sim/sim_bo
 #add wave -label vga_y -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/vga_y\r
 add wave -label nes_y -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/nes_y\r
 \r
-\r
-add wave -label cur_x -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/cur_x\r
-add wave -label prf_x -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/prf_x\r
-add wave -label cur_y -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/cur_y\r
-add wave -label prf_y -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/prf_y\r
-\r
-add wave -label disp_nt -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/disp_nt\r
-add wave -label disp_attr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/disp_attr\r
-add wave -label attr_val -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/attr_val\r
+add wave -label ale sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ale\r
+add wave -label rd_n sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/rd_n\r
+add wave -label wr_n sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/wr_n\r
+\r
+#add wave -label cur_x -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/cur_x\r
+#add wave -label prf_x -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/prf_x\r
+#add wave -label cur_y -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/cur_y\r
+#add wave -label prf_y -radix decimal -unsigned sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/prf_y\r
+#\r
+#add wave -label disp_nt -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/disp_nt\r
+#add wave -label disp_attr -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/disp_attr\r
+#add wave -label attr_val -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/vga_render_inst/ppu_render_inst/attr_val\r
 \r
 \r
 #add wave -radix hex sim:/testbench_motones_sim/sim_board/ppu_inst/nes_r \\r
 #sim:/testbench_motones_sim/sim_board/ppu_inst/nes_g \\r
 #sim:/testbench_motones_sim/sim_board/ppu_inst/nes_b\r
 \r
-add wave -label h_sync_n sim:/testbench_motones_sim/sim_board/ppu_inst/h_sync_n\r
-add wave -label v_sync_n sim:/testbench_motones_sim/sim_board/ppu_inst/v_sync_n\r
+#add wave -label h_sync_n sim:/testbench_motones_sim/sim_board/ppu_inst/h_sync_n\r
+#add wave -label v_sync_n sim:/testbench_motones_sim/sim_board/ppu_inst/v_sync_n\r
 \r
 \r
 \r
@@ -133,7 +136,7 @@ view structure
 view signals\r
 \r
 run 8 us\r
-run 6000 us\r
+run 1000 us\r
 wave zoom full\r
 #run 10000 us\r
 \r
diff --git a/doc/mos6502-clock.xlsx b/doc/mos6502-clock.xlsx
new file mode 100644 (file)
index 0000000..d2ab11f
Binary files /dev/null and b/doc/mos6502-clock.xlsx differ
index 8e3d34b..986ab30 100644 (file)
Binary files a/doc/mos6502-ppu.xlsx and b/doc/mos6502-ppu.xlsx differ
index c2fafd0..c34120f 100644 (file)
@@ -9,7 +9,7 @@ all :
 \r
     \r
 run : all\r
-       VirtuaNES.exe $(IMAGE)\r
+       VirtuaNES.exe $(IMAGE).nes\r
 \r
 \r
 clean :\r
index a19570a..b297f89 100644 (file)
@@ -20,7 +20,7 @@ echo "processing...."
 dd if=$in_file of=$out_file1 bs=16 skip=1 count=2048 2> /dev/null
 dd if=$in_file of=$out_file2 bs=16 skip=2049 2> /dev/null
 
-bin2hex ${in_name}-prg.bin sample1-prg.hex
-bin2hex ${in_name}-chr.bin sample1-chr.hex
+objcopy -I binary -O ihex $in_name-prg.bin sample1-prg.hex
+objcopy -I binary -O ihex $in_name-chr.bin sample1-chr.hex
 
 echo "done."
index d865238..390c137 100644 (file)
@@ -9,7 +9,7 @@ all :   $(OBJECTS) $(LIBRARIES)
        ./dd-img.sh regression\r
        cp regression.nes ../../de1_nes/simulation/modelsim/rom-file.nes\r
        cp sample1-chr.hex ../../de1_nes/\r
-       cp sample1-prg.hex ../../de1_nes/\r
+       cp sample1-prg-8k.hex ../../de1_nes/sample1-prg.hex\r
 \r
     \r
 run : all\r
index 32fe828..d7d66e4 100755 (executable)
@@ -19,10 +19,12 @@ echo "processing...."
 
 dd if=$in_file of=$out_file1 bs=16 skip=1 count=2048 2> /dev/null
 dd if=$in_file of=$out_file2 bs=16 skip=2049 2> /dev/null
-#4k img creation
-dd if=$in_name-prg.bin of=$in_name-prg-8k.bin bs=512 count=16
 
-bin2hex $in_name-prg-8k.bin sample1-prg.hex
-bin2hex $in_name-chr.bin sample1-chr.hex
+objcopy -I binary -O ihex $in_name-prg.bin sample1-prg.hex
+objcopy -I binary -O ihex $in_name-chr.bin sample1-chr.hex
+
+#8k img creation
+dd if=$in_name-prg.bin of=$in_name-prg-8k.bin bs=512 count=16
+objcopy -I binary -O ihex $in_name-prg-8k.bin sample1-prg-8k.hex
 
 echo "done."
index 12dacd5..92d9465 100644 (file)
     jsr init_global\r
     jsr init_ppu\r
 \r
-    lda ad_start_msg\r
-    sta $00\r
-    lda ad_start_msg+1\r
-    sta $01\r
-    jsr print_ln\r
-    jsr print_ln\r
-    jsr print_ln\r
-    jsr print_ln\r
-    jsr print_ln\r
-    jsr print_ln\r
+;    lda ad_start_msg\r
+;    sta $00\r
+;    lda ad_start_msg+1\r
+;    sta $01\r
+;    jsr print_ln\r
+;    jsr print_ln\r
+;    jsr print_ln\r
+;    jsr print_ln\r
+;    jsr print_ln\r
+;    jsr print_ln\r
+;\r
+;    ;;test start...\r
+;    jsr addr_test\r
+;    jsr single_inst_test\r
+;    jsr a2_inst_test\r
+;    jsr a3_inst_test\r
+;    jsr a4_inst_test\r
+;    jsr a5_inst_test\r
+;    jsr status_test\r
+;    jsr ppu_test\r
+;\r
+;    jsr pg_border_test\r
+;    jsr dma_test\r
 \r
-    ;;test start...\r
-    jsr addr_test\r
-    jsr single_inst_test\r
-    jsr a2_inst_test\r
-    jsr a3_inst_test\r
-    jsr a4_inst_test\r
-    jsr a5_inst_test\r
-    jsr status_test\r
-    jsr ppu_test\r
-\r
-    jsr pg_border_test\r
-    jsr dma_test\r
+    jsr simple_dma_test\r
 \r
 .endproc\r
 \r
@@ -678,9 +680,13 @@ nmi_test:
 .endproc\r
 \r
 .proc update_scroll\r
-    lda #$00\r
+    lda scroll_x\r
+    inc scroll_x\r
+    inc scroll_x\r
+    clc\r
+    adc 1\r
+;;    lda #$00\r
     sta $2005\r
-    sta scroll_x\r
 \r
     ldx scroll_y\r
     inx\r
@@ -688,7 +694,7 @@ nmi_test:
     bne :+\r
     ldx #0\r
 :\r
-    ldx #80\r
+;;    ldx #80\r
     stx $2005\r
     stx scroll_y\r
 \r
@@ -3226,7 +3232,7 @@ ad_single_test:
 \r
 ;;ppu test flag.\r
 use_ppu:\r
-    .byte   $01\r
+    .byte   $00\r
 \r
 full_dma_test:\r
     .byte   $01\r