From e28e9f3ac11db036e1b3c71493ecbd14a8d59eac Mon Sep 17 00:00:00 2001 From: Mike Stirling Date: Tue, 2 Aug 2011 22:32:14 +0100 Subject: Fixed missing gate in DISEN which meant that blank lines in modes 3 and 6 weren't blank. Hopefully fixed handling of interlaced sync+video mode in CRTC ready for SAA5050 implementation. --- bbc_micro_de1.qsf | 1 + bbc_micro_de1.vhd | 4 +++- mc6845.vhd | 31 ++++++++++++++++++++++++++----- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/bbc_micro_de1.qsf b/bbc_micro_de1.qsf index fd68838..e5324f6 100644 --- a/bbc_micro_de1.qsf +++ b/bbc_micro_de1.qsf @@ -509,6 +509,7 @@ set_location_assignment PIN_U20 -to SD_nCS set_location_assignment PIN_V20 -to SD_SCLK set_location_assignment PIN_Y20 -to SD_MOSI set_location_assignment PIN_W20 -to SD_MISO +set_global_assignment -name VHDL_FILE saa5050.vhd set_global_assignment -name VHDL_FILE i2s_intf.vhd set_global_assignment -name VHDL_FILE i2c_loader.vhd set_global_assignment -name VHDL_FILE "sn76489-1.0/sn76489_comp_pack-p.vhd" diff --git a/bbc_micro_de1.vhd b/bbc_micro_de1.vhd index b313620..11ac86d 100644 --- a/bbc_micro_de1.vhd +++ b/bbc_micro_de1.vhd @@ -559,6 +559,7 @@ signal display_a : std_logic_vector(14 downto 0); -- "VIDPROC" signals signal vidproc_invert_n : std_logic; +signal vidproc_disen : std_logic; signal r_in : std_logic; signal g_in : std_logic; signal b_in : std_logic; @@ -757,7 +758,7 @@ begin cpu_do, SRAM_DQ(7 downto 0), vidproc_invert_n, - crtc_de, + vidproc_disen, crtc_cursor, r_in, g_in, b_in, r_out, g_out, b_out @@ -1116,6 +1117,7 @@ begin -- VIDPROC vidproc_invert_n <= '1'; + vidproc_disen <= crtc_de and not crtc_ra(3); -- DISEN is masked off by RA(3) for MODEs 3 and 6 r_in <= '0'; -- FIXME: From SAA5050 g_in <= '0'; b_in <= '0'; diff --git a/mc6845.vhd b/mc6845.vhd index d2098c4..30cf333 100644 --- a/mc6845.vhd +++ b/mc6845.vhd @@ -197,6 +197,7 @@ begin -- Horizontal, vertical and address counters process(CLOCK,nRESET) variable ma_row_start : unsigned(13 downto 0); + variable max_scan_line : unsigned(4 downto 0); begin if nRESET = '0' then -- H @@ -220,8 +221,16 @@ begin -- h_total reached h_counter <= (others => '0'); + -- In interlace sync + video mode mask off the LSb of the + -- max scan line address + if r08_interlace(1 downto 0) = "11" then + max_scan_line := r09_max_scan_line_addr(4 downto 1) & "0"; + else + max_scan_line := r09_max_scan_line_addr; + end if; + -- Scan line counter increments, wrapping at max_scan_line_addr - if line_counter = r09_max_scan_line_addr then + if line_counter = max_scan_line then -- Next character row -- FIXME: No support for v_total_adj yet line_counter <= (others => '0'); @@ -250,8 +259,12 @@ begin row_counter <= row_counter + 1; end if; else - -- Next scan line - line_counter <= line_counter + 1; + -- Next scan line. Count in twos in interlaced sync+video mode + if r08_interlace = "11" then + line_counter <= line_counter + 2; + else + line_counter <= line_counter + 1; + end if; end if; -- Memory address preset to row start at the beginning of each @@ -350,15 +363,23 @@ begin -- Address generation process(CLOCK,nRESET) + variable slv_line : std_logic_vector(4 downto 0); begin if nRESET = '0' then RA <= (others => '0'); MA <= (others => '0'); elsif rising_edge(CLOCK) and CLKEN = '1' then + slv_line := std_logic_vector(line_counter); + -- Character row address is just the scan line counter delayed by -- one clock to line up with the syncs. - -- FIXME: Interlace sync + video mode needs special row addressing - RA <= std_logic_vector(line_counter); + if r08_interlace = "11" then + -- In interlace sync and video mode the LSb is determined by the + -- field number. The line counter counts up in 2s in this case. + RA <= slv_line(4 downto 1) & (slv_line(0) or odd_field); + else + RA <= slv_line; + end if; -- Internal memory address delayed by one cycle as well MA <= std_logic_vector(ma_i); end if; -- cgit v1.2.3