aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stirling <opensource@mikestirling.co.uk>2011-08-04 22:24:36 +0100
committerMike Stirling <opensource@mikestirling.co.uk>2011-08-04 22:24:36 +0100
commite3e37956449ece7134b0386a3f67c304a159373b (patch)
treee4a70da58cbea8feeacde63b71ffd0123b6f719e
parente28e9f3ac11db036e1b3c71493ecbd14a8d59eac (diff)
downloadfpga-bbc-e3e37956449ece7134b0386a3f67c304a159373b.tar.gz
fpga-bbc-e3e37956449ece7134b0386a3f67c304a159373b.tar.bz2
fpga-bbc-e3e37956449ece7134b0386a3f67c304a159373b.zip
Added cursor support and teletext pass-through to video ULA. Fixed a couple of cursor bugs in the CRTC.
-rw-r--r--mc6845.vhd6
-rw-r--r--vidproc.vhd55
2 files changed, 56 insertions, 5 deletions
diff --git a/mc6845.vhd b/mc6845.vhd
index 30cf333..90c1108 100644
--- a/mc6845.vhd
+++ b/mc6845.vhd
@@ -395,7 +395,11 @@ begin
cursor_i <= '0';
cursor_line := '0';
elsif rising_edge(CLOCK) and CLKEN = '1' then
- if ma_i = r14_cursor_h & r15_cursor_l then
+ if h_display = '1' and v_display = '1' and ma_i = r14_cursor_h & r15_cursor_l then
+ if line_counter = 0 then
+ -- Suppress wrap around if last line is > max scan line
+ cursor_line := '0';
+ end if;
if line_counter = r10_cursor_start then
-- First cursor scanline
cursor_line := '1';
diff --git a/vidproc.vhd b/vidproc.vhd
index 485cd15..0825081 100644
--- a/vidproc.vhd
+++ b/vidproc.vhd
@@ -65,6 +65,13 @@ signal delayed_disen : std_logic;
signal clken_pixel : std_logic;
signal clken_counter : unsigned(3 downto 0);
+-- Cursor generation - can span up to 32 pixels
+-- Segments 0 and 1 are 8 pixels wide
+-- Segment 2 is 16 pixels wide
+signal cursor_invert : std_logic;
+signal cursor_active : std_logic;
+signal cursor_counter : unsigned(4 downto 0);
+
begin
-- Synchronous register access, enabled on every clock
process(CLOCK,nRESET)
@@ -145,6 +152,38 @@ begin
end if;
end process;
+ -- Cursor generation
+ cursor_invert <= cursor_active and
+ ((r0_cursor0 and not (cursor_counter(4) or cursor_counter(3))) or
+ (r0_cursor1 and cursor_counter(3) and not cursor_counter(4)) or
+ (r0_cursor2 and cursor_counter(4)));
+ process(CLOCK,nRESET)
+ begin
+ if nRESET = '0' then
+ cursor_active <= '0';
+ cursor_counter <= (others => '0');
+ elsif rising_edge(CLOCK) and CLKEN = '1' then
+ if CURSOR = '1' or cursor_active = '1' then
+ -- Latch cursor
+ cursor_active <= '1';
+
+ -- Reset on counter wrap
+ if cursor_counter = "11111" then
+ cursor_active <= '0';
+ end if;
+
+ -- Increment counter
+ if cursor_active = '0' then
+ -- Reset
+ cursor_counter <= (others => '0');
+ else
+ -- Increment
+ cursor_counter <= cursor_counter + 1;
+ end if;
+ end if;
+ end if;
+ end process;
+
-- Pixel generation
-- The new shift register contents are loaded during
-- cycle 0 (and 8) but will not be read here until the next cycle.
@@ -179,10 +218,18 @@ begin
blue_val := (dot_val(3) and r0_flash) xor not dot_val(2);
-- To output
- -- FIXME: Cursor and INVERT option, teletext
- R <= red_val and delayed_disen;
- G <= green_val and delayed_disen;
- B <= blue_val and delayed_disen;
+ -- FIXME: INVERT option
+ if r0_teletext = '0' then
+ -- Cursor can extend outside the bounds of the screen, so
+ -- it is not affected by DISEN
+ R <= (red_val and delayed_disen) xor cursor_invert;
+ G <= (green_val and delayed_disen) xor cursor_invert;
+ B <= (blue_val and delayed_disen) xor cursor_invert;
+ else
+ R <= R_IN;
+ G <= G_IN;
+ B <= B_IN;
+ end if;
-- Display enable signal delayed by one clock
delayed_disen <= DISEN;