oam_bus_ce_n : in std_logic;
plt_bus_ce_n : in std_logic;
oam_plt_addr : in std_logic_vector (7 downto 0);
- oam_plt_data : inout std_logic_vector (7 downto 0)
+ oam_plt_data : inout std_logic_vector (7 downto 0);
+ v_bus_busy_n : out std_logic
);
end component;
constant PPUADDR : std_logic_vector(2 downto 0) := "110";
constant PPUDATA : std_logic_vector(2 downto 0) := "111";
+constant PPUVAI : integer := 2; --vram address increment
constant PPUNEN : integer := 7; --nmi enable
constant ST_VBL : integer := 7; --vblank
signal ppu_scroll_y : std_logic_vector (dsize - 1 downto 0);
signal ppu_scroll_cnt : std_logic_vector (0 downto 0);
signal ppu_addr : std_logic_vector (13 downto 0);
+signal ppu_addr_inc1 : std_logic_vector (13 downto 0);
+signal ppu_addr_inc32 : std_logic_vector (13 downto 0);
signal ppu_addr_in : std_logic_vector (13 downto 0);
signal ppu_addr_cnt : std_logic_vector (0 downto 0);
signal ppu_data : std_logic_vector (dsize - 1 downto 0);
-signal read_data : std_logic;
+signal ppu_data_in : std_logic_vector (dsize - 1 downto 0);
+signal ppu_data_out : std_logic_vector (dsize - 1 downto 0);
+signal read_data_n : std_logic;
signal ppu_latch_rst_n : std_logic;
+signal v_bus_busy_n : std_logic;
signal oam_bus_ce_n : std_logic;
signal plt_bus_ce_n : std_logic;
-signal oam_plt_addr : std_logic_vector (7 downto 0);
-signal oam_plt_data : std_logic_vector (7 downto 0);
+signal oam_plt_addr : std_logic_vector (dsize - 1 downto 0);
+signal oam_plt_data : std_logic_vector (dsize - 1 downto 0);
+signal plt_data_out : std_logic_vector (dsize - 1 downto 0);
begin
pos_x, pos_y, nes_r, nes_g, nes_b,
ppu_ctrl, ppu_mask, read_status, ppu_status, ppu_scroll_x, ppu_scroll_y,
r_nw, oam_bus_ce_n, plt_bus_ce_n,
- oam_plt_addr, oam_plt_data);
+ oam_plt_addr, oam_plt_data, v_bus_busy_n);
vga_inst : vga_ctl port map (clk, vga_clk, rst_n,
pos_x, pos_y, nes_r, nes_g, nes_b,
port map (clk_n, ppu_latch_rst_n, ppu_scroll_cnt_ce_n,
'1', (others => '0'), ppu_scroll_cnt);
- ppu_addr_inst : counter_register generic map(14, 1)
- port map (clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr);
+ ppu_addr_inst_inc1 : counter_register generic map(14, 1)
+ port map (clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr_inc1);
+ ppu_addr_inst_inc32 : counter_register generic map(14, 32)
+ port map (clk_n, rst_n, ppu_data_we_n, ppu_addr_we_n, ppu_addr_in, ppu_addr_inc32);
+
+ ppu_addr <= ppu_addr_inc32 when ppu_ctrl(PPUVAI) = '1' else
+ ppu_addr_inc1;
+
ppu_addr_cnt_inst : counter_register generic map (1, 1)
port map (clk_n, ppu_latch_rst_n, ppu_addr_cnt_ce_n,
'1', (others => '0'), ppu_addr_cnt);
ppu_data_inst : d_flip_flop generic map(dsize)
port map (clk_n, rst_n, '1', ppu_data_we_n, cpu_d, ppu_data);
+ ppu_data_in_inst : d_flip_flop generic map(dsize)
+ port map (clk_n, rst_n, '1', ppu_data_we_n, vram_ad, ppu_data_in);
+
+ ppu_data_out_inst : d_flip_flop generic map(dsize)
+ port map (read_data_n, rst_n, '1', '0', ppu_data_in, ppu_data_out);
+
+ plt_data_out_inst : d_flip_flop generic map(dsize)
+ port map (clk_n, rst_n, '1', ppu_data_we_n, oam_plt_data, plt_data_out);
reg_set_p : process (rst_n, ce_n, r_nw, cpu_addr, cpu_d,
ppu_status(ST_VBL), ppu_ctrl(PPUNEN))
begin
- if (rst_n = '0') then
- ppu_latch_rst_n <= '0';
- vblank_n <= '1';
- end if;
if (ppu_status(ST_VBL)'event or ppu_ctrl(PPUNEN)'event) then
if (ppu_status(ST_VBL) = '1' and ppu_ctrl(PPUNEN) = '1') then
end if;
end if;
- if (rst_n = '1' and ce_n = '0') then
+ if (rst_n = '0') then
+ vblank_n <= '1';
+ elsif (rst_n = '1' and ce_n = '0') then
--register set.
if(cpu_addr = PPUCTRL) then
end if;
if(cpu_addr = PPUSTATUS and r_nw = '1') then
- --reading status resets ppu_addr/scroll cnt.
- ppu_latch_rst_n <= '0';
--notify reading status
read_status <= '1';
else
- ppu_latch_rst_n <= '1';
read_status <= '0';
end if;
end if;
if(cpu_addr = PPUADDR) then
- ppu_addr_cnt_ce_n <= '0';
ppu_addr_we_n <= '0';
if (ppu_addr_cnt(0) = '0') then
ppu_addr_in <= cpu_d(5 downto 0) & ppu_addr(7 downto 0);
ppu_addr_in <= ppu_addr(13 downto 8) & cpu_d;
end if;
else
- ppu_addr_cnt_ce_n <= '1';
ppu_addr_we_n <= '1';
end if;
+
+ if (cpu_addr = PPUDATA and r_nw = '1') then
+ read_data_n <= '0';
+ else
+ read_data_n <= '1';
+ end if;
else
ppu_ctrl_we_n <= '1';
ppu_mask_we_n <= '1';
ppu_scroll_y_we_n <= '1';
ppu_scroll_cnt_ce_n <= '1';
ppu_addr_we_n <= '1';
- ppu_addr_cnt_ce_n <= '1';
-
read_status <= '0';
- read_data <= '0';
+ read_data_n <= '1';
end if; --if (rst_n = '1' and ce_n = '0')
end process;
clk_cnt_set_p : process (rst_n, ce_n, r_nw, cpu_addr, cpu_d, clk,
oam_plt_data, vram_ad, ppu_stat_out)
begin
- if (rst_n = '1' and ce_n = '0') then
+ if (rst_n = '0') then
+ ppu_latch_rst_n <= '0';
+ elsif (rst_n = '1' and ce_n = '0') then
--set counter=0 on register write.
if (ce_n'event or r_nw'event or cpu_addr'event or (cpu_d'event and r_nw = '0')) then
ppu_clk_cnt_res_n <= '0';
elsif (ppu_clk_cnt = "00") then
ppu_clk_cnt_res_n <= '1';
end if;
+
+ if (read_status = '1') then
+ --reading status resets ppu_addr/scroll cnt.
+ ppu_latch_rst_n <= '0';
+ else
+ ppu_latch_rst_n <= '1';
+ end if;
--d_print("clk event");
end if;
cpu_d <= (others => 'Z');
oam_addr_ce_n <= '1';
oam_bus_ce_n <= '1';
- end if;
+ end if; --if (cpu_addr = OAMDATA and ppu_clk_cnt = "00") then
--vram address access.
if (cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
+ ppu_addr_cnt_ce_n <= '0';
if (ppu_addr_cnt(0) = '0') then
--load addr high
ale <= '0';
end if;
end if;
elsif (cpu_addr = PPUDATA and ppu_clk_cnt = "01") then
+ ppu_addr_cnt_ce_n <= '1';
--for burst write.
if (ppu_addr(13 downto 8) = "111111") then
oam_plt_addr <= ppu_addr(7 downto 0);
ale <= '1';
end if;
else
+ ppu_addr_cnt_ce_n <= '1';
ale <= '0';
- end if;
+ end if; --if (cpu_addr = PPUADDR and ppu_clk_cnt = "00") then
if (cpu_addr = PPUDATA and ppu_clk_cnt = "00") then
ppu_data_we_n <= '0';
+ vram_a <= ppu_addr(13 downto 8);
if (ppu_addr(13 downto 8) = "111111") then
--case palette tbl.
plt_bus_ce_n <= '0';
if (r_nw = '0') then
vram_ad <= cpu_d;
else
- vram_ad <= (others => 'Z');
- cpu_d <= vram_ad;
+ cpu_d <= ppu_data_out;
end if;
end if;
else
plt_bus_ce_n <= '1';
ppu_data_we_n <= '1';
- rd_n <= '1';
- wr_n <= '1';
- end if;
+ rd_n <= 'Z';
+ wr_n <= 'Z';
+ end if; --if (cpu_addr = PPUDATA and ppu_clk_cnt = "00") then
--sustain cpu output data when reading.
if (cpu_addr = PPUDATA and r_nw = '1' and ppu_clk_cnt /= "00") then
- cpu_d <= ppu_data;
+ if (ppu_addr(13 downto 8) = "111111") then
+ cpu_d <= plt_data_out;
+ else
+ cpu_d <= ppu_data_out;
+ end if;
end if;
if (cpu_addr = OAMDATA and r_nw = '1' and ppu_clk_cnt /= "00") then
cpu_d <= oam_data;
ppu_clk_cnt_res_n <= '0';
oam_bus_ce_n <= '1';
oam_addr_ce_n <= '1';
+ ppu_addr_cnt_ce_n <= '1';
+ ppu_latch_rst_n <= '1';
rd_n <= 'Z';
wr_n <= 'Z';
vram_ad <= (others => 'Z');
vram_a <= (others => 'Z');
cpu_d <= (others => 'Z');
- end if;
+ end if; --if (rst_n = '0') then
end process;
end rtl;