Skip to content

Commit 3975fdf

Browse files
author
Mike Stirling
committedJul 12, 2011
Initial commit. Some modules imported from experimental 6502 platform. Project added for Quartus 9.1
0 parents  commit 3975fdf

10 files changed

+3575
-0
lines changed
 

‎CII_Starter_pin_assignments.csv

+449
Large diffs are not rendered by default.

‎README

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
T65 implementation from http://www.fpgaarcade.com/resources/T65_v302.zip
2+

‎T65/T65.vhd

+551
Large diffs are not rendered by default.

‎T65/T65_ALU.vhd

+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
-- ****
2+
-- T65(b) core. In an effort to merge and maintain bug fixes ....
3+
--
4+
--
5+
-- Ver 300 Bugfixes by ehenciak added
6+
-- MikeJ March 2005
7+
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
8+
--
9+
-- ****
10+
--
11+
-- 6502 compatible microprocessor core
12+
--
13+
-- Version : 0245
14+
--
15+
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
16+
--
17+
-- All rights reserved
18+
--
19+
-- Redistribution and use in source and synthezised forms, with or without
20+
-- modification, are permitted provided that the following conditions are met:
21+
--
22+
-- Redistributions of source code must retain the above copyright notice,
23+
-- this list of conditions and the following disclaimer.
24+
--
25+
-- Redistributions in synthesized form must reproduce the above copyright
26+
-- notice, this list of conditions and the following disclaimer in the
27+
-- documentation and/or other materials provided with the distribution.
28+
--
29+
-- Neither the name of the author nor the names of other contributors may
30+
-- be used to endorse or promote products derived from this software without
31+
-- specific prior written permission.
32+
--
33+
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34+
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
35+
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36+
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
37+
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38+
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39+
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40+
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41+
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42+
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43+
-- POSSIBILITY OF SUCH DAMAGE.
44+
--
45+
-- Please report bugs to the author, but before you do so, please
46+
-- make sure that this is not a derivative work and that
47+
-- you have the latest version of this file.
48+
--
49+
-- The latest version of this file can be found at:
50+
-- http://www.opencores.org/cvsweb.shtml/t65/
51+
--
52+
-- Limitations :
53+
--
54+
-- File history :
55+
--
56+
-- 0245 : First version
57+
--
58+
59+
library IEEE;
60+
use IEEE.std_logic_1164.all;
61+
use IEEE.numeric_std.all;
62+
use work.T65_Pack.all;
63+
64+
entity T65_ALU is
65+
port(
66+
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
67+
Op : in std_logic_vector(3 downto 0);
68+
BusA : in std_logic_vector(7 downto 0);
69+
BusB : in std_logic_vector(7 downto 0);
70+
P_In : in std_logic_vector(7 downto 0);
71+
P_Out : out std_logic_vector(7 downto 0);
72+
Q : out std_logic_vector(7 downto 0)
73+
);
74+
end T65_ALU;
75+
76+
architecture rtl of T65_ALU is
77+
78+
-- AddSub variables (temporary signals)
79+
signal ADC_Z : std_logic;
80+
signal ADC_C : std_logic;
81+
signal ADC_V : std_logic;
82+
signal ADC_N : std_logic;
83+
signal ADC_Q : std_logic_vector(7 downto 0);
84+
signal SBC_Z : std_logic;
85+
signal SBC_C : std_logic;
86+
signal SBC_V : std_logic;
87+
signal SBC_N : std_logic;
88+
signal SBC_Q : std_logic_vector(7 downto 0);
89+
90+
begin
91+
92+
process (P_In, BusA, BusB)
93+
variable AL : unsigned(6 downto 0);
94+
variable AH : unsigned(6 downto 0);
95+
variable C : std_logic;
96+
begin
97+
AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7);
98+
AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
99+
100+
-- pragma translate_off
101+
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
102+
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
103+
-- pragma translate_on
104+
105+
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
106+
ADC_Z <= '1';
107+
else
108+
ADC_Z <= '0';
109+
end if;
110+
111+
if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then
112+
AL(6 downto 1) := AL(6 downto 1) + 6;
113+
end if;
114+
115+
C := AL(6) or AL(5);
116+
AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7);
117+
118+
ADC_N <= AH(4);
119+
ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7));
120+
121+
-- pragma translate_off
122+
if is_x(std_logic_vector(AH)) then AH := "0000000"; end if;
123+
-- pragma translate_on
124+
125+
if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then
126+
AH(6 downto 1) := AH(6 downto 1) + 6;
127+
end if;
128+
129+
ADC_C <= AH(6) or AH(5);
130+
131+
ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
132+
end process;
133+
134+
process (Op, P_In, BusA, BusB)
135+
variable AL : unsigned(6 downto 0);
136+
variable AH : unsigned(5 downto 0);
137+
variable C : std_logic;
138+
begin
139+
C := P_In(Flag_C) or not Op(0);
140+
AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6);
141+
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6);
142+
143+
-- pragma translate_off
144+
if is_x(std_logic_vector(AL)) then AL := "0000000"; end if;
145+
if is_x(std_logic_vector(AH)) then AH := "000000"; end if;
146+
-- pragma translate_on
147+
148+
if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then
149+
SBC_Z <= '1';
150+
else
151+
SBC_Z <= '0';
152+
end if;
153+
154+
SBC_C <= not AH(5);
155+
SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7));
156+
SBC_N <= AH(4);
157+
158+
if P_In(Flag_D) = '1' then
159+
if AL(5) = '1' then
160+
AL(5 downto 1) := AL(5 downto 1) - 6;
161+
end if;
162+
AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6);
163+
if AH(5) = '1' then
164+
AH(5 downto 1) := AH(5 downto 1) - 6;
165+
end if;
166+
end if;
167+
168+
SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1));
169+
end process;
170+
171+
process (Op, P_In, BusA, BusB,
172+
ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q,
173+
SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q)
174+
variable Q_t : std_logic_vector(7 downto 0);
175+
begin
176+
-- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC
177+
-- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC
178+
P_Out <= P_In;
179+
Q_t := BusA;
180+
case Op(3 downto 0) is
181+
when "0000" =>
182+
-- ORA
183+
Q_t := BusA or BusB;
184+
when "0001" =>
185+
-- AND
186+
Q_t := BusA and BusB;
187+
when "0010" =>
188+
-- EOR
189+
Q_t := BusA xor BusB;
190+
when "0011" =>
191+
-- ADC
192+
P_Out(Flag_V) <= ADC_V;
193+
P_Out(Flag_C) <= ADC_C;
194+
Q_t := ADC_Q;
195+
when "0101" | "1101" =>
196+
-- LDA
197+
when "0110" =>
198+
-- CMP
199+
P_Out(Flag_C) <= SBC_C;
200+
when "0111" =>
201+
-- SBC
202+
P_Out(Flag_V) <= SBC_V;
203+
P_Out(Flag_C) <= SBC_C;
204+
Q_t := SBC_Q;
205+
when "1000" =>
206+
-- ASL
207+
Q_t := BusA(6 downto 0) & "0";
208+
P_Out(Flag_C) <= BusA(7);
209+
when "1001" =>
210+
-- ROL
211+
Q_t := BusA(6 downto 0) & P_In(Flag_C);
212+
P_Out(Flag_C) <= BusA(7);
213+
when "1010" =>
214+
-- LSR
215+
Q_t := "0" & BusA(7 downto 1);
216+
P_Out(Flag_C) <= BusA(0);
217+
when "1011" =>
218+
-- ROR
219+
Q_t := P_In(Flag_C) & BusA(7 downto 1);
220+
P_Out(Flag_C) <= BusA(0);
221+
when "1100" =>
222+
-- BIT
223+
P_Out(Flag_V) <= BusB(6);
224+
when "1110" =>
225+
-- DEC
226+
Q_t := std_logic_vector(unsigned(BusA) - 1);
227+
when "1111" =>
228+
-- INC
229+
Q_t := std_logic_vector(unsigned(BusA) + 1);
230+
when others =>
231+
end case;
232+
233+
case Op(3 downto 0) is
234+
when "0011" =>
235+
P_Out(Flag_N) <= ADC_N;
236+
P_Out(Flag_Z) <= ADC_Z;
237+
when "0110" | "0111" =>
238+
P_Out(Flag_N) <= SBC_N;
239+
P_Out(Flag_Z) <= SBC_Z;
240+
when "0100" =>
241+
when "1100" =>
242+
P_Out(Flag_N) <= BusB(7);
243+
if (BusA and BusB) = "00000000" then
244+
P_Out(Flag_Z) <= '1';
245+
else
246+
P_Out(Flag_Z) <= '0';
247+
end if;
248+
when others =>
249+
P_Out(Flag_N) <= Q_t(7);
250+
if Q_t = "00000000" then
251+
P_Out(Flag_Z) <= '1';
252+
else
253+
P_Out(Flag_Z) <= '0';
254+
end if;
255+
end case;
256+
257+
Q <= Q_t;
258+
end process;
259+
260+
end;

‎T65/T65_MCode.vhd

+1,052
Large diffs are not rendered by default.

‎T65/T65_Pack.vhd

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
-- ****
2+
-- T65(b) core. In an effort to merge and maintain bug fixes ....
3+
--
4+
--
5+
-- Ver 300 Bugfixes by ehenciak added
6+
-- MikeJ March 2005
7+
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
8+
--
9+
-- ****
10+
--
11+
-- 65xx compatible microprocessor core
12+
--
13+
-- Version : 0246
14+
--
15+
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
16+
--
17+
-- All rights reserved
18+
--
19+
-- Redistribution and use in source and synthezised forms, with or without
20+
-- modification, are permitted provided that the following conditions are met:
21+
--
22+
-- Redistributions of source code must retain the above copyright notice,
23+
-- this list of conditions and the following disclaimer.
24+
--
25+
-- Redistributions in synthesized form must reproduce the above copyright
26+
-- notice, this list of conditions and the following disclaimer in the
27+
-- documentation and/or other materials provided with the distribution.
28+
--
29+
-- Neither the name of the author nor the names of other contributors may
30+
-- be used to endorse or promote products derived from this software without
31+
-- specific prior written permission.
32+
--
33+
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34+
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
35+
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36+
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
37+
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38+
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39+
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40+
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41+
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42+
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43+
-- POSSIBILITY OF SUCH DAMAGE.
44+
--
45+
-- Please report bugs to the author, but before you do so, please
46+
-- make sure that this is not a derivative work and that
47+
-- you have the latest version of this file.
48+
--
49+
-- The latest version of this file can be found at:
50+
-- http://www.opencores.org/cvsweb.shtml/t65/
51+
--
52+
-- Limitations :
53+
--
54+
-- File history :
55+
--
56+
57+
library IEEE;
58+
use IEEE.std_logic_1164.all;
59+
60+
package T65_Pack is
61+
62+
constant Flag_C : integer := 0;
63+
constant Flag_Z : integer := 1;
64+
constant Flag_I : integer := 2;
65+
constant Flag_D : integer := 3;
66+
constant Flag_B : integer := 4;
67+
constant Flag_1 : integer := 5;
68+
constant Flag_V : integer := 6;
69+
constant Flag_N : integer := 7;
70+
71+
component T65_MCode
72+
port(
73+
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816
74+
IR : in std_logic_vector(7 downto 0);
75+
MCycle : in std_logic_vector(2 downto 0);
76+
P : in std_logic_vector(7 downto 0);
77+
LCycle : out std_logic_vector(2 downto 0);
78+
ALU_Op : out std_logic_vector(3 downto 0);
79+
Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P
80+
Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA
81+
Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH
82+
Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel
83+
BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj
84+
BreakAtNA : out std_logic;
85+
ADAdd : out std_logic;
86+
AddY : out std_logic;
87+
PCAdd : out std_logic;
88+
Inc_S : out std_logic;
89+
Dec_S : out std_logic;
90+
LDA : out std_logic;
91+
LDP : out std_logic;
92+
LDX : out std_logic;
93+
LDY : out std_logic;
94+
LDS : out std_logic;
95+
LDDI : out std_logic;
96+
LDALU : out std_logic;
97+
LDAD : out std_logic;
98+
LDBAL : out std_logic;
99+
LDBAH : out std_logic;
100+
SaveP : out std_logic;
101+
Write : out std_logic
102+
);
103+
end component;
104+
105+
component T65_ALU
106+
port(
107+
Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816
108+
Op : in std_logic_vector(3 downto 0);
109+
BusA : in std_logic_vector(7 downto 0);
110+
BusB : in std_logic_vector(7 downto 0);
111+
P_In : in std_logic_vector(7 downto 0);
112+
P_Out : out std_logic_vector(7 downto 0);
113+
Q : out std_logic_vector(7 downto 0)
114+
);
115+
end component;
116+
117+
end;

‎bbc_micro.qpf

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# -------------------------------------------------------------------------- #
2+
#
3+
# Copyright (C) 1991-2009 Altera Corporation
4+
# Your use of Altera Corporation's design tools, logic functions
5+
# and other software and tools, and its AMPP partner logic
6+
# functions, and any output files from any of the foregoing
7+
# (including device programming or simulation files), and any
8+
# associated documentation or information are expressly subject
9+
# to the terms and conditions of the Altera Program License
10+
# Subscription Agreement, Altera MegaCore Function License
11+
# Agreement, or other applicable license agreement, including,
12+
# without limitation, that your use is for the sole purpose of
13+
# programming logic devices manufactured by Altera and sold by
14+
# Altera or its authorized distributors. Please refer to the
15+
# applicable agreement for further details.
16+
#
17+
# -------------------------------------------------------------------------- #
18+
#
19+
# Quartus II
20+
# Version 9.1 Build 222 10/21/2009 SJ Web Edition
21+
# Date created = 20:48:44 July 12, 2011
22+
#
23+
# -------------------------------------------------------------------------- #
24+
25+
QUARTUS_VERSION = "9.1"
26+
DATE = "20:48:44 July 12, 2011"
27+
28+
# Revisions
29+
30+
PROJECT_REVISION = "bbc_micro_de1"

‎bbc_micro_de1.qsf

+503
Large diffs are not rendered by default.

‎mc6845.vhd

+419
Large diffs are not rendered by default.

‎vidproc.vhd

+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
-- BBC Micro "VIDPROC" Video ULA
2+
--
3+
-- Synchronous implementation for FPGA
4+
--
5+
-- (C) 2011 Mike Stirling
6+
--
7+
library IEEE;
8+
use IEEE.STD_LOGIC_1164.ALL;
9+
use IEEE.NUMERIC_STD.ALL;
10+
11+
entity vidproc is
12+
port (
13+
CLOCK : in std_logic;
14+
-- Clock enable qualifies display cycles (interleaved with CPU cycles)
15+
CLKEN : in std_logic;
16+
nRESET : in std_logic;
17+
18+
-- Clock enable output to CRTC
19+
CLKEN_CRTC : out std_logic;
20+
21+
-- Bus interface
22+
ENABLE : in std_logic;
23+
A0 : in std_logic;
24+
-- CPU data bus (for register writes)
25+
DI_CPU : in std_logic_vector(7 downto 0);
26+
-- Display RAM data bus (for display data fetch)
27+
DI_RAM : in std_logic_vector(7 downto 0);
28+
29+
-- Control interface
30+
nINVERT : in std_logic;
31+
DISEN : in std_logic;
32+
CURSOR : in std_logic;
33+
34+
-- Video in (teletext mode)
35+
R_IN : in std_logic;
36+
G_IN : in std_logic;
37+
B_IN : in std_logic;
38+
39+
-- Video out
40+
R : out std_logic;
41+
G : out std_logic;
42+
B : out std_logic
43+
);
44+
end entity;
45+
46+
architecture rtl of vidproc is
47+
-- Write-only registers
48+
signal r0_cursor0 : std_logic;
49+
signal r0_cursor1 : std_logic;
50+
signal r0_cursor2 : std_logic;
51+
signal r0_crtc_2mhz : std_logic;
52+
signal r0_pixel_rate : std_logic_vector(1 downto 0);
53+
signal r0_teletext : std_logic;
54+
signal r0_flash : std_logic;
55+
56+
type palette_t is array(0 to 15) of std_logic_vector(3 downto 0);
57+
signal palette : palette_t;
58+
59+
-- Pixel shift register
60+
signal shiftreg : std_logic_vector(7 downto 0);
61+
-- Delayed display enable
62+
signal delayed_disen : std_logic;
63+
64+
-- Internal clock enable generation
65+
signal clken_pixel : std_logic;
66+
signal clken_counter : unsigned(3 downto 0);
67+
68+
begin
69+
-- Synchronous register access, enabled on every clock
70+
process(CLOCK,nRESET)
71+
begin
72+
if nRESET = '0' then
73+
r0_cursor0 <= '0';
74+
r0_cursor1 <= '0';
75+
r0_cursor2 <= '0';
76+
r0_crtc_2mhz <= '0';
77+
r0_pixel_rate <= "00";
78+
r0_teletext <= '0';
79+
r0_flash <= '0';
80+
81+
for colour in 0 to 15 loop
82+
palette(colour) <= (others => '0');
83+
end loop;
84+
elsif rising_edge(CLOCK) then
85+
if ENABLE = '1' then
86+
if A0 = '0' then
87+
-- Access control register
88+
r0_cursor0 <= DI_CPU(7);
89+
r0_cursor1 <= DI_CPU(6);
90+
r0_cursor2 <= DI_CPU(5);
91+
r0_crtc_2mhz <= DI_CPU(4);
92+
r0_pixel_rate <= DI_CPU(3 downto 2);
93+
r0_teletext <= DI_CPU(1);
94+
r0_flash <= DI_CPU(0);
95+
else
96+
-- Access palette register
97+
palette(to_integer(unsigned(DI_CPU(7 downto 4)))) <= DI_CPU(3 downto 0);
98+
end if;
99+
end if;
100+
end if;
101+
end process;
102+
103+
-- Clock enable generation.
104+
-- Pixel clock can be divided by 1,2,4 or 8 depending on the value
105+
-- programmed at r0_pixel_rate
106+
-- 00 = /8, 01 = /4, 10 = /2, 11 = /1
107+
clken_pixel <=
108+
CLKEN when r0_pixel_rate = "11" else
109+
(CLKEN and not clken_counter(0)) when r0_pixel_rate = "10" else
110+
(CLKEN and not (clken_counter(0) or clken_counter(1))) when r0_pixel_rate = "01" else
111+
(CLKEN and not (clken_counter(0) or clken_counter(1) or clken_counter(2)));
112+
113+
-- The CRT controller is always enabled in the 15th cycle, so that the result
114+
-- is ready for latching into the shift register in cycle 0. If 2 MHz mode is
115+
-- selected then the CRTC is also enabled in the 7th cycle
116+
CLKEN_CRTC <= CLKEN and
117+
clken_counter(0) and clken_counter(1) and clken_counter(2) and
118+
(clken_counter(3) or r0_crtc_2mhz);
119+
120+
process(CLOCK,nRESET)
121+
begin
122+
if nRESET = '0' then
123+
clken_counter <= (others => '0');
124+
elsif rising_edge(CLOCK) and CLKEN = '1' then
125+
-- Increment internal cycle counter during each video clock
126+
clken_counter <= clken_counter + 1;
127+
end if;
128+
end process;
129+
130+
-- Fetch control
131+
process(CLOCK,nRESET)
132+
begin
133+
if nRESET = '0' then
134+
shiftreg <= (others => '0');
135+
elsif rising_edge(CLOCK) and clken_pixel = '1' then
136+
if clken_counter = "0000" or
137+
(clken_counter = "1000" and r0_crtc_2mhz = '1') then
138+
-- Fetch next byte from RAM into shift register. This always occurs in
139+
-- cycle 0, and also in cycle 8 if the CRTC is clocked at double rate.
140+
shiftreg <= DI_RAM;
141+
else
142+
-- Clock shift register and input '1' at LSB
143+
shiftreg <= shiftreg(6 downto 0) & "1";
144+
end if;
145+
end if;
146+
end process;
147+
148+
-- Pixel generation
149+
-- The new shift register contents are loaded during
150+
-- cycle 0 (and 8) but will not be read here until the next cycle.
151+
-- By running this process on every single video tick instead of at
152+
-- the pixel rate we ensure that the resulting delay is minimal and
153+
-- constant (running this at the pixel rate would cause
154+
-- the display to move slightly depending on which mode was selected).
155+
process(CLOCK,nRESET)
156+
variable palette_a : std_logic_vector(3 downto 0);
157+
variable dot_val : std_logic_vector(3 downto 0);
158+
variable red_val : std_logic;
159+
variable green_val : std_logic;
160+
variable blue_val : std_logic;
161+
begin
162+
if nRESET = '0' then
163+
R <= '0';
164+
G <= '0';
165+
B <= '0';
166+
delayed_disen <= '0';
167+
elsif rising_edge(CLOCK) and CLKEN = '1' then
168+
-- Look up dot value in the palette. Bits are as follows:
169+
-- bit 3 - FLASH
170+
-- bit 2 - Not BLUE
171+
-- bit 1 - Not GREEN
172+
-- bit 0 - Not RED
173+
palette_a := shiftreg(7) & shiftreg(5) & shiftreg(3) & shiftreg(1);
174+
dot_val := palette(to_integer(unsigned(palette_a)));
175+
176+
-- Apply flash inversion if required
177+
red_val := (dot_val(3) and r0_flash) xor not dot_val(0);
178+
green_val := (dot_val(3) and r0_flash) xor not dot_val(1);
179+
blue_val := (dot_val(3) and r0_flash) xor not dot_val(2);
180+
181+
-- To output
182+
-- FIXME: Cursor and INVERT option, teletext
183+
R <= red_val and delayed_disen;
184+
G <= green_val and delayed_disen;
185+
B <= blue_val and delayed_disen;
186+
187+
-- Display enable signal delayed by one clock
188+
delayed_disen <= DISEN;
189+
end if;
190+
end process;
191+
end architecture;
192+

0 commit comments

Comments
 (0)
Please sign in to comment.