aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stirling <opensource@mikestirling.co.uk>2011-08-02 22:32:14 +0100
committerMike Stirling <opensource@mikestirling.co.uk>2011-08-02 22:32:14 +0100
commite28e9f3ac11db036e1b3c71493ecbd14a8d59eac (patch)
tree78d3eb0c743da146bdd5a552e332a627d57f3fb8
parentb8eed4413b7d093d8df73dc2c5ffc83462a4a2ed (diff)
downloadfpga-bbc-e28e9f3ac11db036e1b3c71493ecbd14a8d59eac.tar.gz
fpga-bbc-e28e9f3ac11db036e1b3c71493ecbd14a8d59eac.tar.bz2
fpga-bbc-e28e9f3ac11db036e1b3c71493ecbd14a8d59eac.zip
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.
-rw-r--r--bbc_micro_de1.qsf1
-rw-r--r--bbc_micro_de1.vhd4
-rw-r--r--mc6845.vhd31
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;