aboutsummaryrefslogtreecommitdiffstats
path: root/mc6845.vhd
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 /mc6845.vhd
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.
Diffstat (limited to 'mc6845.vhd')
-rw-r--r--mc6845.vhd31
1 files changed, 26 insertions, 5 deletions
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;