From 413267ed323bc05480a4a98612859c4870658e6a Mon Sep 17 00:00:00 2001 From: Falk Rehwagen Date: Sat, 7 Oct 2017 16:45:43 +0200 Subject: [PATCH] Revert "Fixing Issue #3: side register handling for floppy controller." This reverts commit d86ed7fff5ecd2d016b529b9667bee8199616c09. --- src/vhdl/bitplane.vhdl | 107 +++++------------ src/vhdl/bitplanes.vhdl | 224 ++++++++++++----------------------- src/vhdl/vicii_sprites.vhdl | 1 - src/vhdl/viciv.vhdl | 228 +++++++----------------------------- 4 files changed, 151 insertions(+), 409 deletions(-) diff --git a/src/vhdl/bitplane.vhdl b/src/vhdl/bitplane.vhdl index 9e1fcf0dc..b37b5f468 100644 --- a/src/vhdl/bitplane.vhdl +++ b/src/vhdl/bitplane.vhdl @@ -31,8 +31,6 @@ entity bitplane is ---------------------------------------------------------------------- pixelclock : in STD_LOGIC; - reset : in std_logic; - advance_pixel : in std_logic; sixteen_colour_mode : in std_logic; @@ -60,14 +58,6 @@ architecture behavioural of bitplane is begin process (pixelclock) - variable v_bb_valid_h : std_logic := '0'; - variable v_bb_valid_2 : std_logic := '0'; - variable v_bb_valid_3 : std_logic := '0'; - variable v_byte_bits_available : integer range 0 to 8 := 0; - variable v_byte_buffer_head : std_logic_vector(7 downto 0); - variable v_byte_buffer_2 : std_logic_vector(7 downto 0); - variable v_byte_buffer_3 : std_logic_vector(7 downto 0); - begin if pixelclock'event and pixelclock = '1' then @@ -76,91 +66,58 @@ begin -- pixels are required on successive clocks. This keeps the logic -- somewhat simpler. - if reset='1' then - bb_valid_h <= '0'; - bb_valid_2 <= '0'; - bb_valid_3 <= '0'; - else - -- Request more data if our buffer is not full. - if (bb_valid_h='0' or bb_valid_2='0' or bb_valid_3='0') then + if (bb_valid_h='0' or bb_valid_2='0' or bb_valid_3='0') + and (data_in_valid='0') then data_request <= '1'; else data_request <= '0'; end if; - v_bb_valid_h := bb_valid_h; - v_bb_valid_2 := bb_valid_2; - v_bb_valid_3 := bb_valid_3; - v_byte_bits_available := byte_bits_available; - v_byte_buffer_head := byte_buffer_head; - v_byte_buffer_2 := byte_buffer_2; - v_byte_buffer_3 := byte_buffer_3; - -- Accept new data if available if data_in_valid='1' then - if bb_valid_h='0' then - v_byte_buffer_head := std_logic_vector(data_in); - v_bb_valid_h := '1'; - v_byte_bits_available := 8; - elsif bb_valid_2='0' then - v_byte_buffer_2 := std_logic_vector(data_in); - v_bb_valid_2 := '1'; - elsif bb_valid_3='0' then - v_byte_buffer_3 := std_logic_vector(data_in); - v_bb_valid_3 := '1'; - end if; + byte_buffer_3 <= std_logic_vector(data_in); + bb_valid_3 <= '1'; end if; + -- Shuffle buffer down as required + if bb_valid_h='0' and bb_valid_2='1' then + byte_buffer_head <= byte_buffer_2; + byte_bits_available <= 8; + bb_valid_h <= '1'; + if bb_valid_3='1' then + byte_buffer_head <= byte_buffer_2; + bb_valid_2 <= '1'; + bb_valid_3 <= '0'; + else + bb_valid_2 <= '0'; + end if; + end if; + + -- Supply pixels as required if advance_pixel='1' then if sixteen_colour_mode='0' then - if v_byte_bits_available > 0 then - v_byte_bits_available := v_byte_bits_available - 1; - pixel_out <= v_byte_buffer_head(7); - v_byte_buffer_head(7 downto 1) := v_byte_buffer_head(6 downto 0); - v_byte_buffer_head(0) := '0'; - --pixel_out <= '1'; - if v_byte_bits_available = 0 then - -- We are using the last bit, so mark byte as empty. - v_bb_valid_h := '0'; - if v_bb_valid_2='1' then - -- Shuffle buffer down as required - v_byte_buffer_head := byte_buffer_2; - v_byte_bits_available := 8; - v_bb_valid_h := '1'; - if v_bb_valid_3='1' then - v_byte_buffer_2 := byte_buffer_3; - v_bb_valid_2 := '1'; - v_bb_valid_3 := '0'; - else - v_bb_valid_2 := '0'; - end if; - end if; - end if; + byte_bits_available <= byte_bits_available - 1; + byte_buffer_head(7 downto 1) <= byte_buffer_head(6 downto 0); + byte_buffer_head(0) <= '0'; + pixel_out <= byte_buffer_head(7); + if byte_bits_available = 1 then + -- We are using the last bit, so mark byte as empty. + bb_valid_h <= '0'; end if; else - v_byte_bits_available := v_byte_bits_available - 4; - v_byte_buffer_head(7 downto 4) := v_byte_buffer_head(3 downto 0); - v_byte_buffer_head(3 downto 0) := x"0"; - if v_byte_bits_available < 4 then + byte_bits_available <= byte_bits_available - 4; + byte_buffer_head(7 downto 4) <= byte_buffer_head(3 downto 0); + byte_buffer_head(3 downto 0) <= x"0"; + if byte_bits_available < 4 then -- We are using the last bit, so mark byte as empty. - v_bb_valid_h := '0'; + bb_valid_h <= '0'; end if; - pixel16_out <= unsigned(v_byte_buffer_head(7 downto 4)); + pixel16_out <= unsigned(byte_buffer_head(7 downto 4)); end if; - - end if; - bb_valid_h <= v_bb_valid_h; - bb_valid_2 <= v_bb_valid_2; - bb_valid_3 <= v_bb_valid_3; - byte_bits_available <= v_byte_bits_available; - byte_buffer_head <= v_byte_buffer_head; - byte_buffer_2 <= v_byte_buffer_2; - byte_buffer_3 <= v_byte_buffer_3; end if; end if; - end process; end behavioural; diff --git a/src/vhdl/bitplanes.vhdl b/src/vhdl/bitplanes.vhdl index c14b0ab35..1f74f65dd 100644 --- a/src/vhdl/bitplanes.vhdl +++ b/src/vhdl/bitplanes.vhdl @@ -95,7 +95,6 @@ entity bitplanes is signal is_sprite_out : out std_logic; signal sprite_map_out : out std_logic_vector(7 downto 0); signal sprite_fg_map_out : out std_logic_vector(7 downto 0) - ); @@ -110,8 +109,6 @@ architecture behavioural of bitplanes is ---------------------------------------------------------------------- pixelclock : in STD_LOGIC; - reset : in std_logic; - advance_pixel : in std_logic; sixteen_colour_mode : in std_logic; @@ -125,16 +122,17 @@ architecture behavioural of bitplanes is end component; - component ram8x4096 IS + + component ram9x4k IS PORT ( - clk : IN STD_LOGIC; - cs : IN STD_LOGIC; - w : IN std_logic; - write_address : IN integer range 0 to 4095; - wdata : IN unsigned(7 DOWNTO 0); - address : IN integer range 0 to 4095; - rdata : OUT unsigned(7 DOWNTO 0) - ); + clka : IN STD_LOGIC; + wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0); + addraa : IN STD_LOGIC_VECTOR(11 DOWNTO 0); + dina : IN STD_LOGIC_VECTOR(8 DOWNTO 0); + clkb : IN STD_LOGIC; + addrb : IN STD_LOGIC_VECTOR(11 DOWNTO 0); + doutb : OUT STD_LOGIC_VECTOR(8 DOWNTO 0) + ); END component; signal y_last : yposition; @@ -143,13 +141,8 @@ architecture behavioural of bitplanes is signal y_top : std_logic := '0'; signal x_in_bitplanes : std_logic := '0'; signal bitplane_drawing : std_logic := '0'; - signal bitplane_drawing_next : std_logic := '0'; - signal bitplane_x_start : xposition := 23; - signal bitplane_x_start_h640 : xposition := 54; - signal bitplane_x_start_h1280 : xposition := 54; - signal bitplane_y_start : yposition := 51; - signal bitplane_y_start_h640 : yposition := 51; - signal bitplane_y_start_h1820 : xposition := 51; + signal bitplane_x_start : xposition := 30; + signal bitplane_y_start : yposition := 30; signal bitplanes_answer_data_request_timeout : integer range 0 to 255 := 0; signal bitplane_mode : std_logic; @@ -159,15 +152,13 @@ architecture behavioural of bitplanes is type bdo is array(0 to 7) of spritedatabytenumber; signal bitplane_data_offsets : bdo; - signal bitplanedatabuffer_cs : std_logic := '1'; signal bitplanedatabuffer_write : std_logic := '0'; - signal bitplanedatabuffer_wdata : unsigned(7 downto 0); + signal bitplanedatabuffer_wdata : unsigned(8 downto 0); signal bitplanedatabuffer_waddress : unsigned(11 downto 0); - signal bitplanedatabuffer_rdata : unsigned(7 downto 0); + signal bitplanedatabuffer_rdata : unsigned(8 downto 0); signal bitplanedatabuffer_address : unsigned(11 downto 0); -- Signals into and out of bitplane pixel engines - signal bitplanes_reset : std_logic_vector(7 downto 0) := "00000000"; signal bitplanes_advance_pixel : std_logic_vector(7 downto 0) := "00000000"; signal bitplanes_sixteen_colour_mode : std_logic_vector(7 downto 0) := "00000000"; signal bitplanes_data_in_valid : std_logic_vector(7 downto 0) := "00000000"; @@ -178,33 +169,25 @@ architecture behavioural of bitplanes is signal bitplanes_pixel16_out : nybl_array_8; type bitplane_offsets_8 is array(0 to 7) of integer range 0 to 511; signal bitplanes_byte_numbers : bitplane_offsets_8; - signal bitplanes_byte_number : integer range 0 to 511; - signal bitplanedata_fetch_column : integer range 0 to 511; signal bitplanedata_fetching : std_logic := '0'; signal bitplanedata_fetch_bitplane : integer range 0 to 7; - signal current_data_fetch : integer range 0 to 8; - signal fetch_ongoing : std_logic := '0'; - signal bitplanes_column_done : std_logic := '0'; - - signal pixel_out_count : integer range 0 to 255 := 0; - begin -- behavioural -- 4K buffer for holding buffered bitplane data for rendering. -- 8 bitplanes x 512 bytes = 4KB. -- This is plenty, since we actually only read 80 bytes max per bitplane per -- line (actually upto 320 bytes per line when using bitplanes in 16-colour mode) - bitplanedatabuffer: component ram8x4096 - port map (clk => pixelclock, - w => bitplanedatabuffer_write, - wdata => bitplanedatabuffer_wdata, - write_address => to_integer(bitplanedatabuffer_waddress), - - cs => bitplanedatabuffer_cs, - address => to_integer(bitplanedatabuffer_address), - rdata => bitplanedatabuffer_rdata + bitplanedatabuffer: component ram9x4k + port map (clka => pixelclock, + wea(0) => bitplanedatabuffer_write, + dina => std_logic_vector(bitplanedatabuffer_wdata), + addraa => std_logic_vector(bitplanedatabuffer_waddress), + + clkb => pixelclock, + addrb => std_logic_vector(bitplanedatabuffer_address), + unsigned(doutb) => bitplanedatabuffer_rdata ); generate_bitplanes: @@ -213,7 +196,6 @@ begin -- behavioural bitplane_inst : bitplane port map ( pixelclock => pixelclock, - reset => bitplanes_reset(index), advance_pixel => bitplanes_advance_pixel(index), sixteen_colour_mode => bitplanes_sixteen_colour_mode(index), data_in_valid => bitplanes_data_in_valid(index), @@ -228,11 +210,20 @@ begin -- behavioural -- type : sequential -- inputs : pixelclock, -- outputs: colour, is_sprite_out - main: process (pixelclock) is - variable v_x_in : integer; - variable v_bitplane_y_start : integer; - variable v_bitplane_x_start : integer; + main: process (pixelclock) begin -- process main + if ioclock'event and ioclock = '1' then + -- Allow writing to bitplane buffer memory directly for debugging + -- (will be overridden if VIC-IV data pipeline is feeding us data) + -- @IO:GS $FFBF000 - $FFBFFFF - DEBUG allow writing directly to the bitplane data buffer. Will be removed in production. + if fastio_write='1' and fastio_address(19 downto 12) = x"BF" then + bitplanedatabuffer_waddress(11 downto 0) + <= fastio_address(11 downto 0); + bitplanedatabuffer_wdata(8) <= '0'; + bitplanedatabuffer_wdata(7 downto 0) <= fastio_wdata; + bitplanedatabuffer_write <= '1'; + end if; + end if; if pixelclock'event and pixelclock = '1' then -- rising clock edge -- Copy sprite colission status out @@ -250,28 +241,8 @@ begin -- behavioural sprite_bytenumber_out <= sprite_bytenumber_in; sprite_data_out <= sprite_data_in; sprite_number_for_data_out <= sprite_number_for_data_in; - - bitplanes_column_done <= '0'; - if bitplanes_column_done = '1' then - - fetch_ongoing <= '0'; - end if; - if bitplane_h640='1' then - v_x_in := x640_in; - v_bitplane_y_start := bitplane_y_start_h640; - v_bitplane_x_start := bitplane_x_start_h640; - elsif bitplane_h1280='1' then - v_x_in := x1280_in; - v_bitplane_y_start := bitplane_y_start_h1820; - v_bitplane_x_start := bitplane_x_start_h1280; - else - v_x_in := x_in; - v_bitplane_y_start := bitplane_y_start; - v_bitplane_x_start := bitplane_x_start; - end if; - - if (sprite_datavalid_in = '1') and (sprite_spritenumber_in > 7) then + if sprite_datavalid_in = '1' and (sprite_spritenumber_in > 7) then -- Record sprite data report "BITPLANES:" & " byte $" & to_hstring(sprite_data_in) @@ -289,6 +260,7 @@ begin -- behavioural <= to_unsigned(sprite_spritenumber_in mod 8, 3); bitplanedatabuffer_waddress(8 downto 0) <= to_unsigned(sprite_bytenumber_in, 9); + bitplanedatabuffer_wdata(8) <= '0'; bitplanedatabuffer_wdata(7 downto 0) <= sprite_data_in; bitplanedatabuffer_write <= '1'; end if; @@ -309,34 +281,29 @@ begin -- behavioural is_background_out <= is_background_in; -- Work out if we need to fetch a byte - bitplanes_advance_pixel <= "00000000"; bitplanedata_fetching <= '0'; - - if current_data_fetch > 0 then - - bitplanedata_fetching <= '1'; - bitplanedata_fetch_bitplane <= current_data_fetch - 1; - bitplanedatabuffer_address(11 downto 9) <= to_unsigned(current_data_fetch - 1,3); - bitplanedatabuffer_address(8 downto 0) <= to_unsigned(bitplanes_byte_number,9); - bitplanedata_fetch_column <= bitplanes_byte_number; - current_data_fetch <= current_data_fetch - 1; - - elsif (bitplanes_data_request(7) = '1') and (fetch_ongoing = '0') then - - fetch_ongoing <= '1'; - - -- start new fetch of column - bitplanes_byte_number <= bitplanes_byte_numbers(0); - bitplanes_byte_numbers(0) <= bitplanes_byte_numbers(0) + 1; - -- ent_data_fetch <= 8; -- triggers fetching data in the next cycle - - bitplanedata_fetching <= '1'; - bitplanedata_fetch_bitplane <= 7; - bitplanedatabuffer_address(11 downto 9) <= to_unsigned(7,3); - bitplanedatabuffer_address(8 downto 0) <= to_unsigned(bitplanes_byte_numbers(0),9); - bitplanedata_fetch_column <= bitplanes_byte_number; - current_data_fetch <= 7; - + if bitplanes_answer_data_request_timeout = 0 then + for i in 7 downto 0 loop + if bitplanes_data_request(i) = '1' then + bitplanedatabuffer_address(11 downto 9) <= to_unsigned(i,3); + bitplanedatabuffer_address(8 downto 0) + <= to_unsigned(bitplanes_byte_numbers(i),9); + bitplanedata_fetch_bitplane <= i; + if bitplanes_byte_numbers(i) < 511 then + bitplanes_byte_numbers(i) <= bitplanes_byte_numbers(i) + 1; + else + bitplanes_byte_numbers(i) <= 0; + end if; + -- Only fetch the byte if we have not reached the end of the bitplane + if bitplanes_byte_numbers(i) < 320 then + bitplanedata_fetching <= '1'; + end if; + end if; + end loop; + else + -- Reduce timeout before we honour bitplane fetch requests + bitplanes_answer_data_request_timeout + <= bitplanes_answer_data_request_timeout - 1; end if; -- Pass fetched data to bitplanes if data is available @@ -344,28 +311,29 @@ begin -- behavioural if bitplanedata_fetching = '1' then bitplanes_data_in <= bitplanedatabuffer_rdata(7 downto 0); bitplanes_data_in_valid(bitplanedata_fetch_bitplane) <= '1'; - - if(bitplanedata_fetch_bitplane = 0) then - fetch_ongoing <= '0'; - end if; end if; -- Work out when we start drawing the bitplane y_last <= y_in; - if y_in = (v_bitplane_y_start + bitplanes_y_start) then + if y_last = bitplane_y_start then y_top <= '1'; report "asserting y_top"; + -- Start requesting pixels from bitplanes to empty their buffers. + bitplanes_advance_pixel <= "11111111"; + -- Allow enough cycles to flush the buffers in single-colour (C65) bitplane mode + bitplanes_answer_data_request_timeout <= 64; else y_top <= '0'; end if; + bitplanes_advance_pixel <= "00000000"; -- XXX: Bitplane output is delayed by one physical pixel here. -- This means that the bitplanes needs to be fed the x value one pixel clock -- early, or bitplanes will be offset by one physical pixel. -- Also, we need to have a 640 and 1280 pixel clock to do -- higher-resolution bitplanes for full C65 compatibility. -- None of the above has yet been done. - if v_x_in = (v_bitplane_x_start + to_integer(signed(std_logic_vector(bitplanes_x_start)))) + if x_in = bitplane_x_start and (y_top='1' or bitplane_drawing='1') then x_left <= '1'; x_in_bitplanes <= '1'; @@ -373,80 +341,35 @@ begin -- behavioural else x_left <= '0'; end if; - - if bitplane_h640 = '1' then - if v_x_in > (v_bitplane_x_start + to_integer(signed(std_logic_vector(bitplanes_x_start))) + 640) then - x_in_bitplanes <= '0'; - end if; - elsif bitplane_h1280 = '1' then - if v_x_in > (v_bitplane_x_start + to_integer(signed(std_logic_vector(bitplanes_x_start))) + 1280) then - x_in_bitplanes <= '0'; - end if; - else - if v_x_in > (v_bitplane_x_start + to_integer(signed(std_logic_vector(bitplanes_x_start))) + 320) then - x_in_bitplanes <= '0'; - end if; - end if; -- Clear bitplane byte numbers at the start of each raster. - if v_x_in = 0 then + if x_in = 0 then for i in 7 downto 0 loop bitplanes_byte_numbers(i) <= 0; - if y_in <= (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start)))) then - bitplane_data_offsets(i) <= 0; - else - - if bitplane_h640 = '1' then - bitplane_data_offsets(i) <= integer((y_in - (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))))) mod 8) + - integer(((y_in - (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))))) / 8)) * 640; - elsif bitplane_h1280 = '1' then - bitplane_data_offsets(i) <= integer((y_in - (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))))) mod 8) + - integer(((y_in - (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))))) / 8)) * 1280; - else - bitplane_data_offsets(i) <= integer((y_in - (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))))) mod 8) + - integer(((y_in - (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))))) / 8)) * 320; - end if; - end if; end loop; - - x_in_bitplanes <= '0'; - bitplanes_reset <= "11111111"; - bitplanes_data_in_valid <= "00000000"; - bitplanes_advance_pixel <= "11111111"; - fetch_ongoing <= '0'; - else - bitplanes_reset <= "00000000"; end if; -- Start drawing once we hit the top of the bitplanes. -- Note: the logic here means that bitplanes must be enabled at this -- point, or they will not be shown at all on the frame! if (y_top = '1') and (bitplane_mode_in = '1') then - bitplane_drawing_next <= '1'; - report "bitplane_drawing asserted."; - else - bitplane_drawing_next <= '0'; - end if; - - if bitplane_drawing_next = '1' then bitplane_drawing <= '1'; + report "bitplane_drawing asserted."; end if; - -- Always stop drawing bitplanes at raster 255 (just a little into the -- lower border). - if y_in = (v_bitplane_y_start + to_integer(signed(std_logic_vector(bitplanes_y_start))) + 200) then + if y_in = 255 then bitplane_drawing <= '0'; report "bitplane_drawing cleared."; end if; - if (v_x_in /= x_last) and (bitplane_drawing='1') and (x_in_bitplanes='1') then + if (x_in /= x_last) and (bitplane_drawing='1') then -- Request first or next pixel from each bitplane. -- We now fetch enough bytes for 16-colour bitplanes to be at full resolution. bitplanes_advance_pixel <= "11111111"; end if; - x_last <= v_x_in; pixel_out <= pixel_in; - if (bitplane_mode='1') and (x_in_bitplanes='1') and (bitplane_drawing='1') then + if (bitplane_mode='1') and (border_in='0') and (bitplane_drawing='1') then -- Display bitplanes, and set foreground based on bitplane 2 -- (but not for 16-colour bitplanes) report "bitplane pixel"; @@ -472,8 +395,9 @@ begin -- behavioural is_foreground_out <= bitplane_complements(i); end if; end if; - end loop; + end loop; end if; + is_sprite_out <= is_sprite_in; sprite_colour_out <= sprite_colour_in; end if; diff --git a/src/vhdl/vicii_sprites.vhdl b/src/vhdl/vicii_sprites.vhdl index f0eda3b26..de96e32de 100644 --- a/src/vhdl/vicii_sprites.vhdl +++ b/src/vhdl/vicii_sprites.vhdl @@ -986,7 +986,6 @@ begin sprite_bytenumber_in => sprite_bytenumber_0_bp, sprite_spritenumber_in => sprite_spritenumber_0_bp, sprite_data_in => sprite_data_0_bp, - -- and to pass it out to the next sprite sprite_datavalid_out => sprite_datavalid_out, sprite_bytenumber_out => sprite_bytenumber_out, diff --git a/src/vhdl/viciv.vhdl b/src/vhdl/viciv.vhdl index 595ea2928..761f6cc1a 100644 --- a/src/vhdl/viciv.vhdl +++ b/src/vhdl/viciv.vhdl @@ -356,7 +356,6 @@ architecture Behavioral of viciv is signal vicii_2mhz_internal : std_logic := '1'; signal viciii_fast_internal : std_logic := '1'; signal viciv_fast_internal : std_logic := '1'; - signal viciv_bitplane_chargen_on : std_logic := '0'; -- last value written to key register signal reg_key : unsigned(7 downto 0) := x"00"; @@ -450,14 +449,9 @@ architecture Behavioral of viciv is -- whole frame. This is really just to make testing through simulation quicker -- since a whole frame takes ~20 minutes to simulate). signal vicii_ycounter : unsigned(8 downto 0) := to_unsigned(0,9); -- 263+1 - signal vicii_ycounter_v400 : unsigned(9 downto 0) := to_unsigned(0,10); signal last_vicii_ycounter : unsigned(8 downto 0) := to_unsigned(0,9); signal vicii_ycounter_phase : unsigned(3 downto 0) := (others => '0'); signal vicii_ycounter_max_phase : unsigned(3 downto 0) := (others => '0'); - signal vicii_ycounter_phase_v400 : unsigned(3 downto 0) := (others => '0'); - signal vicii_ycounter_max_phase_v400 : unsigned(3 downto 0) := (others => '0'); - signal vicii_ycounter_phase_v400 : unsigned(3 downto 0) := (others => '0'); - signal vicii_ycounter_max_phase_v400 : unsigned(3 downto 0) := (others => '0'); -- Is the VIC-II virtual raster number the active one for interrupts, or -- are we comparing to physical rasters? This is decided by which register -- gets written to last. @@ -635,9 +629,8 @@ architecture Behavioral of viciv is signal chargen_x_scale : unsigned(7 downto 0) := x"19"; signal chargen_x_scale_drive : unsigned(7 downto 0); signal sprite_x_scale : unsigned(7 downto 0) := x"19"; - signal sprite_x_scale_640 : unsigned(7 downto 0) := x"16"; -- 640 mode sprite scale -- Each character pixel will be (n+1) pixels high - signal chargen_y_scale : unsigned(7 downto 0) := x"01"; -- x"04" + signal chargen_y_scale : unsigned(7 downto 0) := x"02"; -- x"04" -- smooth scrolling position in natural pixels. -- Set in the same way as the border signal x_chargen_start : unsigned(13 downto 0) := to_unsigned(to_integer(frame_h_front),14); @@ -693,8 +686,8 @@ architecture Behavioral of viciv is signal bitplane_enables : std_logic_vector(7 downto 0) := "00000000"; signal bitplane_complements : std_logic_vector(7 downto 0) := "00000000"; signal bitplane_sixteen_colour_mode_flags : std_logic_vector(7 downto 0) := "00000000"; - signal bitplanes_x_start : unsigned(7 downto 0) := to_unsigned(0,8); - signal bitplanes_y_start : unsigned(7 downto 0) := to_unsigned(0,8); + signal bitplanes_x_start : unsigned(7 downto 0) := to_unsigned(30,8); + signal bitplanes_y_start : unsigned(7 downto 0) := to_unsigned(30,8); signal dat_x : unsigned(7 downto 0) := x"00"; signal dat_y : unsigned(7 downto 0) := x"00"; signal bitplane_addresses : sprite_vector_8; @@ -1631,6 +1624,7 @@ begin chargen_x_scale <= chargen_x_scale_1280; virtual_row_width <= to_unsigned(160,16); end if; + if reg_v400='0' then -- set vertical borders based on twentyfourlines if twentyfourlines='0' then border_y_top <= to_unsigned(to_integer(single_top_border_200),12); @@ -1647,7 +1641,6 @@ begin y_chargen_start <= to_unsigned(to_integer(single_top_border_200) -ssy_table_200(3) +ssy_table_200(to_integer(vicii_y_smoothscroll)),12); - if reg_v400='0' then chargen_y_scale <= to_unsigned(to_integer(chargen_y_scale_200)-1,8); else if twentyfourlines='0' then @@ -1668,13 +1661,8 @@ begin chargen_y_scale <= to_unsigned(to_integer(chargen_y_scale_400)-1,8); end if; - if reg_h640='1' then - screen_ram_base(13 downto 11) <= reg_d018_screen_addr(3 downto 1); - screen_ram_base(10 downto 0) <= (others => '0'); - else - screen_ram_base(13 downto 10) <= reg_d018_screen_addr; - screen_ram_base(9 downto 0) <= (others => '0'); - end if; + screen_ram_base(13 downto 10) <= reg_d018_screen_addr; + screen_ram_base(9 downto 0) <= (others => '0'); -- Sprites fetch from screen ram base + $3F8 (or +$7F8 in VIC-III 80 -- column mode). -- In 80 column mode the screen base must be on a 2K boundary on the @@ -1903,7 +1891,7 @@ begin -- @IO:C65 $D03A - Bitplane 7 address elsif register_number >= 51 and register_number <= 58 then -- @IO:C65 $D033-$D03A - VIC-III Bitplane addresses - bitplane_number := to_integer(register_number(3 downto 0)) - 3; + bitplane_number := to_integer(register_number(3 downto 0)-"001"); fastio_rdata <= std_logic_vector(bitplane_addresses(bitplane_number)); -- @IO:C65 $D03B - Set bits to NOT bitplane contents elsif register_number=59 then @@ -1914,12 +1902,8 @@ begin -- @IO:C65 $D03D - Bitplane Y elsif register_number=61 then fastio_rdata <= std_logic_vector(dat_y); - -- @IO:C65 $D03E - Horizontal position (screen verniers?) - elsif register_number=62 then - fastio_rdata <= std_logic_vector(bitplanes_x_start); - -- @IO:C65 $D03F - Vertical position (screen verniers?) - elsif register_number=63 then - fastio_rdata <= std_logic_vector(bitplanes_y_start); + -- $D03E - Horizontal position (screen verniers?) + -- $D03F - Vertical position (screen verniers?) -- $D040 - $D047 DAT memory ports for bitplanes 0 through 7 -- XXX: Deprecated old addresses for some VIC-IV features currently occupy @@ -2187,15 +2171,15 @@ begin report "SPRITE: VIC-II sprite " & integer'image(sprite_number_for_data_rx) & " = " & integer'image(sprite_data_offset_rx); --- sprite_data_offsets(sprite_number_for_data_rx) <= sprite_data_offset_rx; --- -- Ask for the next one (8 sprites + 8 C65 bitplanes) --- if sprite_number_counter = 15 then --- sprite_number_counter <= 0; --- sprite_number_for_data_tx <= 0; --- else --- sprite_number_counter <= sprite_number_counter + 1; --- sprite_number_for_data_tx <= sprite_number_for_data_tx + 1; --- end if; + sprite_data_offsets(sprite_number_for_data_rx) <= sprite_data_offset_rx; + -- Ask for the next one (8 sprites + 8 C65 bitplanes) + if sprite_number_counter = 15 then + sprite_number_counter <= 0; + sprite_number_for_data_tx <= 0; + else + sprite_number_counter <= sprite_number_counter + 1; + sprite_number_for_data_tx <= sprite_number_for_data_tx + 1; + end if; -- $DD00 video bank bits if fastio_write='1' @@ -2492,8 +2476,8 @@ begin -- @IO:C65 $D03A - Bitplane 7 address elsif register_number >= 51 and register_number <= 58 then -- @IO:C65 $D033-$D03A - VIC-III Bitplane addresses - --bitplane_number := to_integer(register_number(3 downto 0)) - 3; - bitplane_addresses(to_integer(register_number)-51) <= unsigned(fastio_wdata); + bitplane_number := to_integer(register_number(3 downto 0)-"001"); + bitplane_addresses(bitplane_number) <= unsigned(fastio_wdata); -- @IO:C65 $D03B - Set bits to NOT bitplane contents elsif register_number=59 then bitplane_complements <= fastio_wdata; @@ -2503,13 +2487,6 @@ begin -- @IO:C65 $D03D - Bitplane Y elsif register_number=61 then dat_y <= unsigned(fastio_wdata); elsif register_number=64 then - -- @IO:C65 $D03E - Bitplane X Offset - elsif register_number=62 then - bitplanes_x_start <= unsigned(fastio_wdata); - -- @IO:C65 $D03F - Bitplane Y Offset - elsif register_number=63 then - bitplanes_y_start <= unsigned(fastio_wdata); - elsif register_number=64 then -- @IO:GS $D040 DEPRECATED - VIC-IV characters per logical text row (LSB) virtual_row_width(7 downto 0) <= unsigned(fastio_wdata); elsif register_number=65 then @@ -2841,15 +2818,6 @@ begin begin if rising_edge(pixelclock) and all_pause='0' then - sprite_data_offsets(sprite_number_for_data_rx) <= sprite_data_offset_rx; - -- Ask for the next one (8 sprites + 8 C65 bitplanes) - if sprite_number_counter = 15 then - sprite_number_counter <= 0; - sprite_number_for_data_tx <= 0; - else - sprite_number_counter <= sprite_number_counter + 1; - sprite_number_for_data_tx <= sprite_number_for_data_tx + 1; - -- Output the logical pixel number assuming H640 output -- (Used for Matrix Mode and visual keyboard compositers, so that -- they know how the actual mode is laid out). @@ -3006,11 +2974,7 @@ begin & " (raw = " & to_hstring(vicii_xcounter_sub); if xcounter /= to_integer(frame_width) then xcounter <= xcounter + 1; - if reg_h640 = '0' then - vicii_xcounter_sub <= vicii_xcounter_sub + sprite_x_scale; - else - vicii_xcounter_sub <= vicii_xcounter_sub + sprite_x_scale_640; - end if; + vicii_xcounter_sub <= vicii_xcounter_sub + sprite_x_scale; else -- End of raster reached. -- Bump raster number and start next raster. @@ -3028,11 +2992,7 @@ begin -- XXX - Why were we adding 2 here? Have removed this, as VIC-II -- rasters were too tall. PGS. vicii_ycounter_scale <= vicii_ycounter_scale_minus_zero; - if reg_h640 = '0' then - vicii_xcounter_sub <= x"f153"; - else - vicii_xcounter_sub <= x"ff30"; - end if; + vicii_xcounter_sub <= x"f154"; chargen_x_sub <= (others => '0'); raster_buffer_read_address <= (others => '0'); chargen_active <= '0'; @@ -3051,48 +3011,6 @@ begin vicii_ycounter_phase <= vicii_ycounter_phase + 1; end if; - if vicii_ycounter_phase_v400 = vicii_ycounter_max_phase_v400 then - vicii_ycounter_v400 <= vicii_ycounter_v400 + 1; - vicii_ycounter_phase_v400 <= (others => '0'); - -- Set number of physical rasters per VIC-II raster based on region - -- of screen. - if vicii_ycounter_v400 >= 50 and vicii_ycounter_v400 < 450 then - if vicii_ycounter_v400(0) = '0' then - vicii_ycounter_max_phase_v400 <= to_unsigned(2,4); - else - vicii_ycounter_max_phase_v400 <= to_unsigned(1,4); - end if; - elsif vicii_ycounter_V400 = 450 then - vicii_ycounter_max_phase_v400 <= to_unsigned(0,4); - elsif vicii_ycounter_v400 = 314 then - vicii_ycounter_max_phase_v400 <= to_unsigned(1,4); - end if; - else - -- In the middle of a VIC-II logical raster, so just increase phase. - vicii_ycounter_phase_v400 <= vicii_ycounter_phase_v400 + 1; - end if; - - if vicii_ycounter_phase_v400 = vicii_ycounter_max_phase_v400 then - vicii_ycounter_v400 <= vicii_ycounter_v400 + 1; - vicii_ycounter_phase_v400 <= (others => '0'); - -- Set number of physical rasters per VIC-II raster based on region - -- of screen. - if vicii_ycounter_v400 >= 50 and vicii_ycounter_v400 < 450 then - if vicii_ycounter_v400(0) = '0' then - vicii_ycounter_max_phase_v400 <= to_unsigned(2,4); - else - vicii_ycounter_max_phase_v400 <= to_unsigned(1,4); - end if; - elsif vicii_ycounter_V400 = 450 then - vicii_ycounter_max_phase_v400 <= to_unsigned(0,4); - elsif vicii_ycounter_v400 = 314 then - vicii_ycounter_max_phase_v400 <= to_unsigned(1,4); - end if; - else - -- In the middle of a VIC-II logical raster, so just increase phase. - vicii_ycounter_phase_v400 <= vicii_ycounter_phase_v400 + 1; - end if; - -- Make VIC-II triggered raster interrupts edge triggered, since one -- emulated VIC-II raster is ~63*48 = ~3,000 cycles, and many C64 -- raster routines may finish in that time, and might get confused if @@ -3124,11 +3042,8 @@ begin -- Reset VIC-II raster counter to first raster for top of frame -- (the preceeding rasters occur during vertical flyback, in case they -- have interrupts triggered on them). - vicii_ycounter_phase <= to_unsigned(1,3); + vicii_ycounter_phase <= (others => '0'); vicii_ycounter <= vicii_first_raster; - vicii_ycounter_v400 <= (others =>'0'); - vicii_ycounter_phase_v400 <= to_unsigned(1,4); - end if; end if; if vertical_flyback = '1' then @@ -3330,20 +3245,12 @@ begin next_card_number <= first_card_of_row; screen_row_current_address <= screen_row_address; - -- Now check if we have tipped over from one logical pixel row to another. - if chargen_y_sub=chargen_y_scale then - chargen_y <= chargen_y + 1; - report "bumping chargen_y to " & integer'image(to_integer(chargen_y)) severity note; - if chargen_y = "111" then - bump_screen_row_address<='1'; - end if; - if (chargen_y_scale=x"02") and (chargen_y(0)='1') then - chargen_y_sub <= "00001"; - else - chargen_y_sub <= (others => '0'); - end if; - else - chargen_y_sub <= chargen_y_sub + 1; + -- Now check if we have tipped over from one logical pixel row to another. + if chargen_y_sub=chargen_y_scale then + chargen_y <= chargen_y + 1; + report "bumping chargen_y to " & integer'image(to_integer(chargen_y)) severity note; + if chargen_y = "111" then + bump_screen_row_address<='1'; end if; chargen_y_sub <= (others => '0'); else @@ -3373,7 +3280,7 @@ begin viciv_outofframe <= (not indisplay_t3); if indisplay_t3='1' then - if inborder_t2='1' or blank='1' or (bitplane_mode='1' and viciv_bitplane_chargen_on='0') then + if inborder_t2='1' or blank='1' then pixel_colour <= border_colour; report "VICIV: Drawing border" severity note; elsif chargen_active='0' then @@ -3468,7 +3375,7 @@ begin -- Use palette bank 3 for "palette ROM" colours (C64 default colours -- should be placed there for C65 compatibility). - if postsprite_pixel_colour(7 downto 4) = x"0" and reg_palrom='0' then + if postsprite_pixel_colour(7 downto 4) = x"0" and reg_palrom='1' then palette_address <= "11" & std_logic_vector(postsprite_pixel_colour); else palette_address(7 downto 0) <= std_logic_vector(postsprite_pixel_colour); @@ -3504,14 +3411,6 @@ begin vga_buffer_blue(7 downto 4) <= unsigned(palette_rdata(11 downto 8)); vga_buffer_blue(3 downto 0) <= unsigned(palette_rdata(15 downto 12)); - --vga_buffer_red <= unsigned(postsprite_pixel_colour); - --vga_buffer_green <= unsigned(postsprite_pixel_colour); - --vga_buffer_blue <= unsigned(postsprite_pixel_colour); - - --vga_buffer_red <= unsigned(postsprite_pixel_colour); - --vga_buffer_green <= unsigned(postsprite_pixel_colour); - --vga_buffer_blue <= unsigned(postsprite_pixel_colour); - rgb_is_background2 <= rgb_is_background; composite_bg_red <= unsigned(alias_palette_rdata(31 downto 24)); @@ -3667,15 +3566,9 @@ begin end if; -- Pre-calculate some expressions to flatten logic in critical path - if reg_h640='1' then - bitmap_glyph_data_address - <= (character_set_address(16)&character_set_address(14 downto 13)&"0"&"0"&x"000") - + (to_integer(screen_ram_buffer_read_address)+to_integer(first_card_of_row))*8+to_integer(chargen_y); - else - bitmap_glyph_data_address - <= (character_set_address(16 downto 13)&"0"&x"000") - + (to_integer(screen_ram_buffer_read_address)+to_integer(first_card_of_row))*8+to_integer(chargen_y); - end if; + bitmap_glyph_data_address + <= (character_set_address(16 downto 13)&"0"&x"000") + + (to_integer(screen_ram_buffer_read_address)+to_integer(first_card_of_row))*8+to_integer(chargen_y); virtual_row_width_minus1 <= virtual_row_width - 1; report "raster_fetch_state = " & vic_chargen_fsm'image(raster_fetch_state); @@ -3752,11 +3645,7 @@ begin character_number <= (others => '0'); card_of_row <= (others => '0'); - if bitplane_mode='0' or viciv_bitplane_chargen_on='1' then - raster_fetch_state <= FetchNextCharacter; - else - raster_fetch_state <= EndOfCharGen; - end if; + raster_fetch_state <= FetchNextCharacter; when FetchNextCharacter => -- Fetch next character -- All we can expect here is that character_number is correctly set. @@ -4273,7 +4162,7 @@ begin end if; -- Interlacing selects which of two bitplane address register -- fields to use - if (reg_v400='1') and (vicii_ycounter_v400(0)='0') then + if (reg_v400='1') and (vicii_ycounter(0)='1') then -- Use odd scan set sprite_pointer_address(15 downto 13) <= bitplane_addresses(sprite_fetch_sprite_number mod 8) @@ -4293,11 +4182,7 @@ begin sprite_fetch_sprite_number <= sprite_fetch_sprite_number + 1; raster_fetch_state <= SpritePointerFetch; else - --sprite_data_address <= sprite_pointer_address; - --sprite_data_address(12 downto 0) <= to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),13); - - raster_fetch_state <= SpritePointerCompute; - --raster_fetch_state <= SpritePointerFetch2; + raster_fetch_state <= SpriteDataFetch2; end if; end if; when SpritePointerFetch2 => @@ -4315,27 +4200,15 @@ begin -- sprite_data_offsets() value for the sprite if sprite_fetch_sprite_number < 8 then sprite_data_address(16) <= '0'; - sprite_data_address(15) <= sprite_pointer_address(15); - sprite_data_address(14) <= sprite_pointer_address(14); + sprite_data_address(15) <= screen_ram_base(15); + sprite_data_address(14) <= screen_ram_base(14); sprite_data_address(13 downto 0) <= (ramdata_drive&"000000") + to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),14); -- sprite_data_address(5 downto 0) <= to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),6); report "SPRITE: sprite #" & integer'image(sprite_fetch_sprite_number) & " pointer value = $" & to_hstring(ramdata_drive); else - --sprite_data_address <= sprite_pointer_address; - --sprite_data_address(12 downto 0) <= to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),13); - -- sprite_data_address(16) <= '0'; - -- sprite_data_address(15) <= sprite_pointer_address(15); - -- sprite_data_address(14) <= sprite_pointer_address(14); - -- sprite_data_address(13 downto 0) <= (ramdata_drive&"000000") + to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),14); - if (reg_h640='1' or reg_h1280='1') then - sprite_data_address(16 downto 14) <= sprite_pointer_address(16 downto 14); - sprite_data_address(13 downto 0) <= to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),14); - else - sprite_data_address(16 downto 13) <= sprite_pointer_address(16 downto 13); - sprite_data_address(12 downto 0) <= to_unsigned(sprite_data_offsets(sprite_fetch_sprite_number),13); - end if; + sprite_data_address <= sprite_pointer_address; end if; raster_fetch_state <= SpriteDataFetch; when SpriteDataFetch => @@ -4344,11 +4217,7 @@ begin & " data from $" & to_hstring("000"&sprite_data_address(16 downto 0)); ramaddress <= sprite_data_address; - if sprite_fetch_sprite_number < 8 then - sprite_data_address(16 downto 0) <= sprite_data_address(16 downto 0) + 1; - else - sprite_data_address(16 downto 0) <= sprite_data_address(16 downto 0) + 8; - end if; + sprite_data_address(16 downto 0) <= sprite_data_address(16 downto 0) + 1; raster_fetch_state <= SpriteDataFetch2; when SpriteDataFetch2 => report "SPRITE: fetching sprite #" @@ -4357,30 +4226,23 @@ begin to_hstring(ramdata) & " from $" & to_hstring("000"&sprite_data_address(16 downto 0)) & " for byte number " & integer'image(sprite_fetch_byte_number); - if sprite_fetch_sprite_number < 8 then - sprite_data_address(16 downto 0) <= sprite_data_address(16 downto 0) + 1; - else - sprite_data_address(16 downto 0) <= sprite_data_address(16 downto 0) + 8; - end if; + sprite_data_address(16 downto 0) <= sprite_data_address(16 downto 0) + 1; ramaddress <= sprite_data_address; + sprite_fetch_byte_number <= sprite_fetch_byte_number + 1; -- Schedule pushing fetched sprite/bitplane byte to next cycle when -- the data will be available in ramdata_drive sprite_fetch_drive <= '1'; - sprite_fetch_byte_number_drive <= sprite_fetch_byte_number; sprite_fetch_sprite_number_drive <= sprite_fetch_sprite_number; - sprite_fetch_byte_number <= sprite_fetch_byte_number + 1; - - -- XXX - always fetches 8 bytes of sprite data instead of 3, even if -- sprite is not set to 64 pixels wide mode. This wastes a little -- raster time. -- Bitplanes are also fetched using the sprite fetch pipeline, so we fetch -- more bytes for those, according to the bitplane width. - --if ((sprite_fetch_byte_number = 7) and (sprite_fetch_sprite_number < 8)) - if (sprite_fetch_byte_number = max_sprite_fetch_byte_number) + if ((sprite_fetch_byte_number = 7) and (sprite_fetch_sprite_number < 8)) + or (sprite_fetch_byte_number = max_sprite_fetch_byte_number) then sprite_fetch_byte_number <= 0; sprite_fetch_sprite_number <= sprite_fetch_sprite_number + 1;