1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-06 16:14:42 +00:00

Merge pull request #89 from gyurco/gameboy

Gameboy + C64 updates
This commit is contained in:
gyurco
2019-03-19 09:49:14 +01:00
committed by GitHub
18 changed files with 952 additions and 588 deletions

View File

@@ -238,68 +238,84 @@ set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[15]
# Fitter Assignments
# ==================
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[13]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[14]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[15]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_BA[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_BA[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQML
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQMH
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nRAS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCAS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nWE
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_CKE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[13]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[14]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[15]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_HS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_VS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to LED
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R
@@ -385,4 +401,7 @@ set_global_assignment -name QIP_FILE rtl/mist/rom_reconfig_ntsc.qip
set_global_assignment -name SIGNALTAP_FILE output_files/pll.stp
set_location_assignment PIN_46 -to UART_TX
set_location_assignment PIN_31 -to UART_RX
set_location_assignment PLL_1 -to pll|altpll_component|auto_generated|pll1
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to UART_TX
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@@ -43,11 +43,14 @@ set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|cl
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -5 [get_ports {VGA_*}]
# SDRAM delays
set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] -max 6.4 [get_ports SDRAM_DQ[*]]
set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] -min 3.2 [get_ports SDRAM_DQ[*]]
set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 6.4 [get_ports SDRAM_DQ[*]]
set_input_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min 3.2 [get_ports SDRAM_DQ[*]]
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[1]}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_CLK}]
set_output_delay -clock [get_clocks {pll|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_CLK}]
set_multicycle_path -from {video_mixer:vmixer|scandoubler:scandoubler|Hq2x:Hq2x|*} -to {VGA_*[*]} -setup 4
set_multicycle_path -from {video_mixer:vmixer|scandoubler:scandoubler|Hq2x:Hq2x|*} -to {VGA_*[*]} -hold 3

View File

@@ -86,6 +86,10 @@ entity fpga64_sid_iec is
-- joystick interface
joyA : in unsigned(6 downto 0);
joyB : in unsigned(6 downto 0);
potA_x : in std_logic_vector(7 downto 0);
potA_y : in std_logic_vector(7 downto 0);
potB_x : in std_logic_vector(7 downto 0);
potB_y : in std_logic_vector(7 downto 0);
-- serial port, for connection to pheripherals
serioclk : out std_logic;
@@ -125,6 +129,7 @@ entity fpga64_sid_iec is
-- CIA
cia_mode : in std_logic;
todclk : in std_logic;
disk_num : out std_logic_vector(7 downto 0);
@@ -599,8 +604,14 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID)
sid_do8580_l when second_sid_en='0' else
sid_do8580_r;
pot_x <= X"FF" when ((cia1_pao(7) and JoyA(5)) or (cia1_pao(6) and JoyB(5))) = '0' else X"00";
pot_y <= X"FF" when ((cia1_pao(7) and JoyA(6)) or (cia1_pao(6) and JoyB(6))) = '0' else X"00";
-- CD4066 analogue switch
pot_x <= potA_x when cia1_pao(6) = '1' else
potB_x when cia1_pao(7) = '1' else
x"FF";
pot_y <= potA_y when cia1_pao(6) = '1' else
potB_y when cia1_pao(7) = '1' else
x"FF";
second_sid_en <= '0' when sid_mode(0) = '0' else
'1' when cpuAddr(11 downto 8) = x"4" and cpuAddr(5) = '1' else -- D420
'1' when cpuAddr(11 downto 8) = x"5" else -- D500
@@ -693,7 +704,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID)
cnt_out => cnt1_out,
pc_n => open,
tod => vicVSync,
tod => todclk,
irq_n => irq_cia1
);
@@ -723,7 +734,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID)
cnt_out => cnt2_out,
pc_n => pc2_n,
tod => vicVSync,
tod => todclk,
irq_n => irq_cia2
);

View File

@@ -81,6 +81,7 @@ component sdram is port
(
-- interface to the MT48LC16M16 chip
sd_addr : out std_logic_vector(12 downto 0);
sd_data : inout std_logic_vector(15 downto 0);
sd_cs : out std_logic;
sd_ba : out std_logic_vector(1 downto 0);
sd_we : out std_logic;
@@ -93,6 +94,8 @@ component sdram is port
-- cpu/chipset interface
addr : in std_logic_vector(24 downto 0);
din : in std_logic_vector( 7 downto 0);
dout : out std_logic_vector( 7 downto 0);
refresh : in std_logic;
we : in std_logic;
ce : in std_logic
@@ -196,7 +199,11 @@ component user_io generic(STRLEN : integer := 0 ); port
ps2_kbd_data : out std_logic;
ps2_mouse_clk : out std_logic;
ps2_mouse_data : out std_logic
ps2_mouse_data : out std_logic;
mouse_x : out signed(8 downto 0);
mouse_y : out signed(8 downto 0);
mouse_flags : out std_logic_vector(8 downto 0); -- YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
mouse_strobe : out std_logic
);
end component user_io;
@@ -385,6 +392,10 @@ end component cartridge;
signal joyB_c64 : std_logic_vector(6 downto 0);
signal joyC_c64 : std_logic_vector(6 downto 0);
signal joyD_c64 : std_logic_vector(6 downto 0);
signal potA_x : std_logic_vector(7 downto 0);
signal potA_y : std_logic_vector(7 downto 0);
signal potB_x : std_logic_vector(7 downto 0);
signal potB_y : std_logic_vector(7 downto 0);
signal reset_key : std_logic;
signal cart_detach_key :std_logic; -- cartridge detach key CTRL-D - LCA
@@ -415,7 +426,15 @@ end component cartridge;
signal ps2_clk : std_logic;
signal ps2_dat : std_logic;
signal mouse_en : std_logic;
signal mouse_x : signed( 8 downto 0);
signal mouse_x_pos : signed(10 downto 0);
signal mouse_y : signed( 8 downto 0);
signal mouse_y_pos : signed(10 downto 0);
signal mouse_flags : std_logic_vector(8 downto 0);
signal mouse_btns : std_logic_vector(1 downto 0);
signal mouse_strobe : std_logic;
signal c64_iec_atn_i : std_logic;
signal c64_iec_clk_o : std_logic;
signal c64_iec_data_o : std_logic;
@@ -448,14 +467,17 @@ end component cartridge;
signal c64_data_in16: std_logic_vector(15 downto 0);
alias c64_data_out_int : unsigned is unsigned(c64_data_out);
signal c64_clk : std_logic; -- 31.527mhz (PAL), 32.727mhz(NTSC) clock source
signal clk_ram : std_logic; -- 2 x c64_clk
signal clk_c64 : std_logic; -- 31.527mhz (PAL), 32.727mhz(NTSC) clock source
signal clk_ram : std_logic; -- 2 x clk_c64
signal clk32 : std_logic; -- 32mhz
signal ce_8 : std_logic;
signal ce_4 : std_logic;
signal hq2x160 : std_logic;
signal osdclk : std_logic;
signal clkdiv : std_logic_vector(9 downto 0);
signal todclk : std_logic;
signal toddiv : std_logic_vector(19 downto 0);
signal toddiv3 : std_logic_vector(1 downto 0);
signal ram_ce : std_logic;
signal ram_we : std_logic;
@@ -499,7 +521,7 @@ begin
user_io_d : user_io
generic map (STRLEN => CONF_STR'length)
port map (
clk_sys => c64_clk,
clk_sys => clk_c64,
clk_sd => clk32,
SPI_CLK => SPI_SCK,
@@ -532,12 +554,16 @@ begin
sd_dout_strobe => sd_buff_wr,
img_mounted => sd_change,
ps2_kbd_clk => ps2_clk,
ps2_kbd_data => ps2_dat
ps2_kbd_data => ps2_dat,
mouse_x => mouse_x,
mouse_y => mouse_y,
mouse_flags => mouse_flags,
mouse_strobe => mouse_strobe
);
data_io_d: data_io
port map (
clk_sys => c64_clk,
clk_sys => clk_c64,
SPI_SCK => SPI_SCK,
SPI_SS2 => SPI_SS2,
SPI_DI => SPI_DI,
@@ -564,7 +590,7 @@ begin
mem_ce => not ram_ce,
mem_ce_out => mem_ce,
clk32 => c64_clk,
clk32 => clk_c64,
reset => reset_n,
reset_out => reset_crt,
@@ -597,8 +623,8 @@ begin
);
-- rearrange joystick contacta for c64
joyA_int <= joyA(6 downto 4) & joyA(0) & joyA(1) & joyA(2) & joyA(3);
joyB_int <= joyB(6 downto 4) & joyB(0) & joyB(1) & joyB(2) & joyB(3);
joyA_int <= joyA(6 downto 5) & (joyA(4) or (mouse_en and mouse_btns(0))) & joyA(0) & joyA(1) & joyA(2) & (joyA(3) or (mouse_en and mouse_btns(1)));
joyB_int <= joyB(6 downto 5) & (joyB(4) or (mouse_en and mouse_btns(0))) & joyB(0) & joyB(1) & joyB(2) & (joyB(3) or (mouse_en and mouse_btns(1)));
joyC_c64 <= joyC(6 downto 4) & joyC(0) & joyC(1) & joyC(2) & joyC(3);
joyD_c64 <= joyD(6 downto 4) & joyD(0) & joyD(1) & joyD(2) & joyD(3);
@@ -613,9 +639,9 @@ begin
sdram_ce <= mem_ce when iec_cycle='0' else ioctl_iec_cycle_used;
sdram_we <= not ram_we when iec_cycle='0' else ioctl_iec_cycle_used;
process(c64_clk)
process(clk_c64)
begin
if falling_edge(c64_clk) then
if falling_edge(clk_c64) then
old_download <= ioctl_download;
iec_cycleD <= iec_cycle;
@@ -732,9 +758,9 @@ begin
c64rom_addr <= ioctl_addr(13 downto 0) when ioctl_index = 0 else '1' & ioctl_addr(12 downto 0);
c1541rom_wr <= ioctl_wr when (ioctl_index = 0) and (ioctl_addr(14) = '1') and (ioctl_download = '1') else '0';
process(c64_clk)
process(clk_c64)
begin
if rising_edge(c64_clk) then
if rising_edge(clk_c64) then
clkdiv <= std_logic_vector(unsigned(clkdiv)+1);
if(clkdiv(1 downto 0) = "00") then
ce_8 <= '1';
@@ -836,8 +862,8 @@ begin
pll : entity work.pll_c64
port map(
inclk0 => CLOCK_27,
c0 => c64_clk,
c1 => clk_ram,
c0 => clk_ram,
c1 => clk_c64,
areset => pll_areset,
scanclk => pll_scanclk,
scandata => pll_scandata,
@@ -846,7 +872,7 @@ begin
scandataout => pll_scandataout,
scandone => pll_scandone
);
SDRAM_CLK <= not clk_ram;
SDRAM_CLK <= clk_ram;
-- clock for 1541
pll_2 : entity work.pll
@@ -856,9 +882,9 @@ begin
locked => pll_locked
);
process(c64_clk)
process(clk_c64)
begin
if rising_edge(c64_clk) then
if rising_edge(clk_c64) then
-- Reset by:
-- Button at device, IO controller reboot, OSD or FPGA startup
if status(0)='1' or pll_locked = '0' then
@@ -884,11 +910,6 @@ begin
end if;
end process;
SDRAM_DQ(15 downto 8) <= (others => 'Z') when sdram_we='0' else (others => '0');
SDRAM_DQ(7 downto 0) <= (others => 'Z') when sdram_we='0' else sdram_data_out;
-- read from sdram
c64_data_in <= SDRAM_DQ(7 downto 0);
-- clock is always enabled and memory is never masked as we only
-- use one byte
SDRAM_CKE <= '1';
@@ -897,6 +918,7 @@ begin
sdr: sdram port map(
sd_addr => SDRAM_A,
sd_data => SDRAM_DQ,
sd_ba => SDRAM_BA,
sd_cs => SDRAM_nCS,
sd_we => SDRAM_nWE,
@@ -905,6 +927,8 @@ begin
clk => clk_ram,
addr => sdram_addr,
din => sdram_data_out,
dout => c64_data_in,
init => not pll_locked,
we => sdram_we,
refresh => idle,
@@ -913,7 +937,7 @@ begin
dac : sigma_delta_dac
port map (
clk => c64_clk,
clk => clk_c64,
ldatasum => audio_data_l(17 downto 3),
rdatasum => audio_data_r(17 downto 3),
aleft => AUDIO_L,
@@ -923,7 +947,7 @@ begin
fpga64 : entity work.fpga64_sid_iec
port map(
clk32 => c64_clk,
clk32 => clk_c64,
reset_n => reset_n,
c64gs => status(11),-- not enough BRAM
kbd_clk => not ps2_clk,
@@ -958,6 +982,10 @@ begin
ba => open,
joyA => unsigned(joyA_c64),
joyB => unsigned(joyB_c64),
potA_x => potA_x,
potA_y => potA_y,
potB_x => potB_x,
potB_y => potB_y,
serioclk => open,
ces => ces,
SIDclk => open,
@@ -978,6 +1006,7 @@ begin
pb_in => pb_in,
pb_out => pb_out,
flag2_n => flag2_n,
todclk => todclk,
cia_mode => status(4),
disk_num => open,
c64rom_addr => c64rom_addr,
@@ -987,6 +1016,39 @@ begin
reset_key => reset_key
);
-- paddle pins - mouse or GS controller
potA_x <= '0' & std_logic_vector(mouse_x_pos)(6 downto 1) & '0' when mouse_en = '1'
else x"00" when joyA_c64(5) = '1' else x"FF";
potA_y <= '0' & std_logic_vector(mouse_y_pos)(6 downto 1) & '0' when mouse_en = '1'
else x"00" when joyA_c64(6) = '1' else x"FF";
potB_x <= '0' & std_logic_vector(mouse_x_pos)(6 downto 1) & '0' when mouse_en = '1'
else x"00" when joyB_c64(5) = '1' else x"FF";
potB_y <= '0' & std_logic_vector(mouse_y_pos)(6 downto 1) & '0' when mouse_en = '1'
else x"00" when joyB_c64(6) = '1' else x"FF";
process(clk_c64, reset_n)
variable mov_x: signed(6 downto 0);
variable mov_y: signed(6 downto 0);
begin
if reset_n = '0' then
mouse_x_pos <= (others => '0');
mouse_y_pos <= (others => '0');
mouse_en <= '0';
elsif rising_edge(clk_c64) then
if mouse_strobe = '1' then
mouse_en <= '1';
-- due to limited resolution on the c64 side, limit the mouse movement speed
if mouse_x > 40 then mov_x:="0101000"; elsif mouse_x < -40 then mov_x:= "1011000"; else mov_x := mouse_x(6 downto 0); end if;
if mouse_y > 40 then mov_y:="0101000"; elsif mouse_y < -40 then mov_y:= "1011000"; else mov_y := mouse_y(6 downto 0); end if;
mouse_x_pos <= mouse_x_pos + mov_x;
mouse_y_pos <= mouse_y_pos + mov_y;
mouse_btns <= mouse_flags(1 downto 0);
elsif joya(7 downto 0) /= 0 or joyb(7 downto 0) /= 0 then
mouse_en <= '0';
end if;
end if;
end process;
-- connect user port
process (pa2_out, pb_out, joyC_c64, joyD_c64, UART_RX, status)
begin
@@ -1010,6 +1072,25 @@ begin
end if;
end process;
-- generate TOD clock from stable 32 MHz
process(clk32, reset_n)
begin
if reset_n = '0' then
todclk <= '0';
toddiv <= (others => '0');
elsif rising_edge(clk32) then
toddiv <= toddiv + 1;
if (ntsc_init_mode_d2 = '1' and toddiv = 266665 and toddiv3 = "00") or
(ntsc_init_mode_d2 = '1' and toddiv = 266666 and toddiv3 /= "00") or
toddiv = 319999 then
toddiv <= (others => '0');
todclk <= not todclk;
toddiv3 <= toddiv3 + 1;
if toddiv3 = "10" then toddiv3 <= "00"; end if;
end if;
end if;
end process;
disk_readonly <= status(16);
c64_iec_data_i <= c1541_iec_data_o;
@@ -1019,12 +1100,12 @@ begin
c1541_iec_data_i <= c64_iec_data_o;
c1541_iec_clk_i <= c64_iec_clk_o;
process(c64_clk, reset_n)
process(clk_c64, reset_n)
variable reset_cnt : integer range 0 to 32000000;
begin
if reset_n = '0' then
reset_cnt := 100000;
elsif rising_edge(c64_clk) then
elsif rising_edge(clk_c64) then
if reset_cnt /= 0 then
reset_cnt := reset_cnt - 1;
end if;
@@ -1043,7 +1124,7 @@ begin
clk32 => clk32,
reset => c1541_reset,
c1541rom_clk => c64_clk,
c1541rom_clk => clk_c64,
c1541rom_addr => ioctl_addr(13 downto 0),
c1541rom_data => ioctl_data,
c1541rom_wr => c1541rom_wr,
@@ -1074,7 +1155,7 @@ begin
comp_sync : entity work.composite_sync
port map(
clk32 => c64_clk,
clk32 => clk_c64,
hsync => hsync,
vsync => vsync,
ntsc => ntsc_init_mode,
@@ -1091,9 +1172,9 @@ begin
hq2x <= status(9) xor status(8);
ce_pix_actual <= ce_4 when hq2x160='1' else ce_8;
process(c64_clk)
process(clk_c64)
begin
if rising_edge(c64_clk) then
if rising_edge(clk_c64) then
if((old_vsync = '0') and (vsync_out = '1')) then
if(status(10 downto 8)="010") then
hq2x160 <= '1';

View File

@@ -165,11 +165,11 @@ BEGIN
altpll_component : altpll
GENERIC MAP (
bandwidth_type => "AUTO",
clk0_divide_by => 6,
clk0_divide_by => 3,
clk0_duty_cycle => 50,
clk0_multiply_by => 7,
clk0_phase_shift => "0",
clk1_divide_by => 3,
clk1_divide_by => 6,
clk1_duty_cycle => 50,
clk1_multiply_by => 7,
clk1_phase_shift => "0",
@@ -261,12 +261,12 @@ END SYN;
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "6"
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "3"
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "3"
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "6"
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "31.500000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "63.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "63.000000"
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "31.500000"
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@@ -294,8 +294,8 @@ END SYN;
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "7"
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "7"
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "31.52000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "63.04000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "63.00000000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "32.72700000"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
@@ -341,11 +341,11 @@ END SYN;
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "6"
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "3"
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "7"
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "3"
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "6"
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "7"
-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"

View File

@@ -17,8 +17,8 @@
-- Device Part: -
-- Device Speed Grade: 8
-- PLL Scan Chain: Fast PLL (144 bits)
-- File Name: /home/gyuri/git/mist-board/cores/c64/rtl/mist/pll_c64_ntsc.mif
-- Generated: Sun Feb 10 18:12:08 2019
-- File Name: /home/gyurco/git/mist-board/cores/c64/rtl/mist/pll_c64_ntsc.mif
-- Generated: Mon Mar 18 13:52:51 2019
WIDTH=1;
DEPTH=144;
@@ -82,39 +82,39 @@ CONTENT BEGIN
52 : 0;
53 : 0;
54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s))
55 : 0; -- clk0 counter: High Count = 8 (8 bit(s))
55 : 0; -- clk0 counter: High Count = 4 (8 bit(s))
56 : 0;
57 : 0;
58 : 0;
59 : 1;
60 : 0;
59 : 0;
60 : 1;
61 : 0;
62 : 0;
63 : 0; -- clk0 counter: Odd Division = 0 (1 bit(s))
64 : 0; -- clk0 counter: Low Count = 8 (8 bit(s))
64 : 0; -- clk0 counter: Low Count = 4 (8 bit(s))
65 : 0;
66 : 0;
67 : 0;
68 : 1;
69 : 0;
68 : 0;
69 : 1;
70 : 0;
71 : 0;
72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s))
73 : 0; -- clk1 counter: High Count = 4 (8 bit(s))
73 : 0; -- clk1 counter: High Count = 8 (8 bit(s))
74 : 0;
75 : 0;
76 : 0;
77 : 0;
78 : 1;
77 : 1;
78 : 0;
79 : 0;
80 : 0;
81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s))
82 : 0; -- clk1 counter: Low Count = 4 (8 bit(s))
82 : 0; -- clk1 counter: Low Count = 8 (8 bit(s))
83 : 0;
84 : 0;
85 : 0;
86 : 0;
87 : 1;
86 : 1;
87 : 0;
88 : 0;
89 : 0;
90 : 1; -- clk2 counter: Bypass = 1 (1 bit(s))

View File

@@ -17,8 +17,8 @@
-- Device Part: -
-- Device Speed Grade: 8
-- PLL Scan Chain: Fast PLL (144 bits)
-- File Name: /home/gyuri/git/mist-board/cores/c64/rtl/mist/pll_c64_pal.mif
-- Generated: Sun Feb 10 22:52:34 2019
-- File Name: /home/gyurco/git/mist-board/cores/c64/rtl/mist/pll_c64_pal.mif
-- Generated: Mon Mar 18 13:55:59 2019
WIDTH=1;
DEPTH=144;
@@ -82,41 +82,41 @@ CONTENT BEGIN
52 : 1;
53 : 0;
54 : 0; -- clk0 counter: Bypass = 0 (1 bit(s))
55 : 0; -- clk0 counter: High Count = 9 (8 bit(s))
55 : 0; -- clk0 counter: High Count = 5 (8 bit(s))
56 : 0;
57 : 0;
58 : 0;
59 : 1;
60 : 0;
59 : 0;
60 : 1;
61 : 0;
62 : 1;
63 : 0; -- clk0 counter: Odd Division = 0 (1 bit(s))
64 : 0; -- clk0 counter: Low Count = 9 (8 bit(s))
63 : 1; -- clk0 counter: Odd Division = 1 (1 bit(s))
64 : 0; -- clk0 counter: Low Count = 4 (8 bit(s))
65 : 0;
66 : 0;
67 : 0;
68 : 1;
69 : 0;
68 : 0;
69 : 1;
70 : 0;
71 : 1;
71 : 0;
72 : 0; -- clk1 counter: Bypass = 0 (1 bit(s))
73 : 0; -- clk1 counter: High Count = 5 (8 bit(s))
73 : 0; -- clk1 counter: High Count = 9 (8 bit(s))
74 : 0;
75 : 0;
76 : 0;
77 : 0;
78 : 1;
77 : 1;
78 : 0;
79 : 0;
80 : 1;
81 : 1; -- clk1 counter: Odd Division = 1 (1 bit(s))
82 : 0; -- clk1 counter: Low Count = 4 (8 bit(s))
81 : 0; -- clk1 counter: Odd Division = 0 (1 bit(s))
82 : 0; -- clk1 counter: Low Count = 9 (8 bit(s))
83 : 0;
84 : 0;
85 : 0;
86 : 0;
87 : 1;
86 : 1;
87 : 0;
88 : 0;
89 : 0;
89 : 1;
90 : 1; -- clk2 counter: Bypass = 1 (1 bit(s))
91 : 0; -- clk2 counter: High Count = 0 (8 bit(s))
92 : 0;

View File

@@ -23,8 +23,9 @@
module sdram (
// interface to the MT48LC16M16 chip
output [12:0] sd_addr, // 13 bit multiplexed address bus
output [1:0] sd_ba, // two banks
output reg [12:0] sd_addr, // 13 bit multiplexed address bus
inout reg [15:0] sd_data,
output reg [ 1:0] sd_ba, // two banks
output sd_cs, // a single chip select
output sd_we, // write enable
output sd_ras, // row address select
@@ -34,8 +35,10 @@ module sdram (
input init, // init signal after FPGA config to initialize RAM
input clk, // sdram is accessed at up to 128MHz
// input [15:0] addr, // 25 bit byte address
input [24:0] addr, // 25 bit byte address
input [24:0] addr, // 25 bit byte address
input [ 7:0] din,
output [ 7:0] dout,
input refresh, // refresh cycle
input ce, // cpu/chipset access
input we // cpu/chipset requests write
@@ -56,8 +59,8 @@ localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, B
// ---------------------------------------------------------------------
localparam STATE_IDLE = 3'd0; // first state in cycle
localparam STATE_CMD_START = 3'd1; // state in which a new command can be started
localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY - 3'd1; // 4 command can be continued
localparam STATE_CMD_START = 3'd0; // state in which a new command can be started
localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY; // 2 command can be continued
localparam STATE_LAST = 3'd7; // last state in cycle
reg [2:0] q /* synthesis noprune */;
@@ -104,17 +107,21 @@ localparam CMD_LOAD_MODE = 4'b0000;
reg [3:0] sd_cmd; // current command sent to sd ram
assign dout = sd_data[7:0];
// drive control signals according to current command
assign sd_cs = sd_cmd[3];
assign sd_ras = sd_cmd[2];
assign sd_cas = sd_cmd[1];
assign sd_we = sd_cmd[0];
// assign sd_data = we?{din, din}:16'bZZZZZZZZZZZZZZZZ;
// assign dout = sd_data[7:0];
wire [12:0] reset_addr = (reset == 13)?13'b0010000000000:MODE;
wire [12:0] run_addr = (q == STATE_CMD_START)?addr[20:8]:{ 4'b0010, addr[23], addr[7:0]};
always @(posedge clk) begin
sd_cmd <= CMD_INHIBIT;
sd_cmd <= CMD_INHIBIT;
sd_addr <= (reset != 0)?reset_addr:run_addr;
sd_ba <= addr[22:21];
sd_data <= 16'bZZZZZZZZZZZZZZZZ;
if(reset != 0) begin
if(q == STATE_IDLE) begin
@@ -128,20 +135,9 @@ always @(posedge clk) begin
end else if((q == STATE_CMD_CONT)&&(!refresh)) begin
if(we) sd_cmd <= CMD_WRITE;
else if(ce) sd_cmd <= CMD_READ;
if(we) sd_data <= {din, din};
end
end
end
wire [12:0] reset_addr = (reset == 13)?13'b0010000000000:MODE;
wire [12:0] run_addr =
// (q == STATE_CMD_START)?{ 5'b00000, addr[15:8]}:{ 5'b00100, addr[7:0]};
//(q == STATE_CMD_START)?addr[21:9]:{ 4'b0010, addr[8:0]}; //possibly try this LCA 6mar17
(q == STATE_CMD_START)?addr[20:8]:{ 4'b0010, addr[23], addr[7:0]};
assign sd_addr = (reset != 0)?reset_addr:run_addr;
//assign sd_ba = 2'b00;
assign sd_ba = addr[22:21];
endmodule

View File

@@ -63,12 +63,18 @@ module user_io #(parameter STRLEN=0, parameter PS2DIV=100) (
output reg img_mounted, //rising edge if a new image is mounted
output reg [31:0] img_size, // size of image in bytes
// ps2 keyboard emulation
// ps2 keyboard/mouse emulation
output ps2_kbd_clk,
output reg ps2_kbd_data,
output ps2_mouse_clk,
output reg ps2_mouse_data,
// mouse data
output reg [8:0] mouse_x,
output reg [8:0] mouse_y,
output reg [7:0] mouse_flags, // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
output reg mouse_strobe, // mouse data is valid on mouse_strobe
// serial com port
input [7:0] serial_data,
input serial_strobe
@@ -374,12 +380,17 @@ always @(posedge clk_sys) begin
reg [7:0] acmd;
reg [7:0] abyte_cnt; // counts bytes
reg [7:0] mouse_flags_r;
reg [7:0] mouse_x_r;
//synchronize between SPI and sys clock domains
spi_receiver_strobeD <= spi_receiver_strobe_r;
spi_receiver_strobe <= spi_receiver_strobeD;
spi_transfer_endD <= spi_transfer_end_r;
spi_transfer_end <= spi_transfer_endD;
mouse_strobe <= 0;
if (~spi_transfer_endD & spi_transfer_end) begin
abyte_cnt <= 8'd0;
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
@@ -402,6 +413,15 @@ always @(posedge clk_sys) begin
// store incoming ps2 mouse bytes
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in;
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in;
else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in;
else if (abyte_cnt == 3) begin
// flags: YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
mouse_flags <= mouse_flags_r;
mouse_x <= { mouse_flags_r[4], mouse_x_r };
mouse_y <= { mouse_flags_r[5], spi_byte_in };
mouse_strobe <= 1;
end
end
8'h05: begin
// store incoming ps2 keyboard bytes
@@ -446,6 +466,7 @@ always @(posedge clk_sd) begin
reg spi_transfer_end;
reg spi_receiver_strobeD;
reg spi_transfer_endD;
reg sd_wrD;
reg [7:0] acmd;
reg [7:0] abyte_cnt; // counts bytes
@@ -460,9 +481,12 @@ always @(posedge clk_sd) begin
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
end
if(sd_din_strobe) begin
sd_din_strobe<= 0;
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
sd_din_strobe<= 0;
sd_wrD <= sd_wr;
// fetch the first byte immediately after the write command seen
if (~sd_wrD & sd_wr) begin
sd_buff_addr <= 0;
sd_din_strobe <= 1;
end
img_mounted <= 0;
@@ -473,7 +497,7 @@ always @(posedge clk_sd) begin
sd_ack_conf <= 1'b0;
sd_dout_strobe <= 1'b0;
sd_din_strobe <= 1'b0;
sd_buff_addr<= 0;
sd_buff_addr <= 0;
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
if(~&abyte_cnt)
@@ -482,9 +506,10 @@ always @(posedge clk_sd) begin
if(abyte_cnt == 0) begin
acmd <= spi_byte_in;
// fetch first byte when sectore FPGA->IO command has been seen
if(spi_byte_in == 8'h18)
if(spi_byte_in == 8'h18) begin
sd_din_strobe <= 1'b1;
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
end
if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18))
sd_ack <= 1'b1;
@@ -500,7 +525,10 @@ always @(posedge clk_sd) begin
end
// send sector FPGA -> IO
8'h18: sd_din_strobe <= 1'b1;
8'h18: begin
sd_din_strobe <= 1'b1;
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
end
// send SD config IO -> FPGA
8'h19: begin

View File

@@ -2,6 +2,7 @@
// by Rayne
// Timers & Interrupts are rewritten by slingshot
// Passes all Lorenz CIA Timer tests
// Passes all "new" CIA tests from VICE, except dd0dtest
module mos6526 (
input wire mode, // 0 - 6526 "old", 1 - 8521 "new"
@@ -215,7 +216,11 @@ always @(posedge clk) begin
if (wr)
case (rs)
4'h4: ta_lo <= db_in;
4'h4:
begin
ta_lo <= db_in;
if (timerAoverflow) timer_a <= {ta_hi, db_in};
end
4'h5:
begin
ta_hi <= db_in;
@@ -281,7 +286,11 @@ always @(posedge clk) begin
if (wr)
case (rs)
4'h6: tb_lo <= db_in;
4'h6:
begin
tb_lo <= db_in;
if (timerBoverflow) timer_b <= {tb_hi, db_in};
end
4'h7:
begin
tb_hi <= db_in;

View File

@@ -138,6 +138,123 @@ set_location_assignment PIN_59 -to SDRAM_nCS
set_location_assignment PIN_33 -to SDRAM_CKE
set_location_assignment PIN_43 -to SDRAM_CLK
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[12]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[11]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[10]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[9]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[8]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[15]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[14]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[13]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[12]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[11]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[10]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[9]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[8]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[7]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[6]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[5]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[4]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[3]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[2]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[1]
set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[13]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[14]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[15]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to LED
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L
set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R
set_global_assignment -name ENABLE_SIGNALTAP OFF
set_global_assignment -name USE_SIGNALTAP_FILE output_files/clk.stp
@@ -154,7 +271,6 @@ set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_*
set_global_assignment -name VERILOG_INPUT_VERSION VERILOG_2001
set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON

View File

@@ -115,11 +115,11 @@ wire [7:0] cpu_di =
sel_sc?sc_r: // serial transfer control register
sel_timer?timer_do: // timer registers
sel_video_reg?video_do: // video registers
sel_video_oam?video_do: // video object attribute memory
(sel_video_oam&&!(lcd_mode==3 || lcd_mode==2))?video_do: // video object attribute memory
sel_audio?audio_do: // audio registers
sel_rom?rom_do: // boot rom + cartridge rom
sel_cram?rom_do: // cartridge ram
sel_vram?(isGBC&&vram_bank)?vram1_do:vram_do: // vram (GBC bank 0+1)
(sel_vram&&lcd_mode!=3)?(isGBC&&vram_bank)?vram1_do:vram_do: // vram (GBC bank 0+1)
sel_zpram?zpram_do: // zero page ram
sel_iram?iram_do: // internal ram
sel_ie?{3'b000, ie_r}: // interrupt enable register
@@ -131,7 +131,7 @@ wire cpu_iorq_n;
wire cpu_m1_n;
wire cpu_mreq_n;
wire cpu_clken = isGBC ? !hdma_rd:1'b1; //when hdma is enabled stop CPU (GBC)
wire cpu_clken = isGBC ? !hdma_active:1'b1; //when hdma is enabled stop CPU (GBC)
wire cpu_stop;
GBse cpu (
@@ -278,8 +278,8 @@ wire [7:0] irq_vec =
if_r[4]&&ie_r[4]?8'h60: // input
8'h55;
wire vs = (lcd_mode == 2'b01);
reg vsD, vsD2;
//wire vs = (lcd_mode == 2'b01);
//reg vsD, vsD2;
reg [7:0] inputD, inputD2;
// irq is low when an enable irq is active
@@ -296,9 +296,9 @@ always @(negedge clk_cpu) begin //negedge to trigger interrupt earlier
end
// rising edge on vs
vsD <= vs;
vsD2 <= vsD;
if(vsD && !vsD2) if_r[0] <= 1'b1;
// vsD <= vs;
// vsD2 <= vsD;
if(vblank_irq) if_r[0] <= 1'b1;
// video irq already is a 1 clock event
if(video_irq) if_r[1] <= 1'b1;
@@ -359,7 +359,7 @@ timer timer (
// --------------------------------------------------------------------
// cpu tries to read or write the lcd controller registers
wire video_irq;
wire video_irq,vblank_irq;
wire [7:0] video_do;
wire [12:0] video_addr;
wire [15:0] dma_addr;
@@ -375,6 +375,8 @@ video video (
.irq ( video_irq ),
.vblank_irq ( vblank_irq ),
.cpu_sel_reg ( sel_video_reg ),
.cpu_sel_oam ( sel_video_oam ),
@@ -402,7 +404,7 @@ video video (
);
// total 8k/16k (CGB) vram from $8000 to $9fff
wire cpu_wr_vram = sel_vram && !cpu_wr_n;
wire cpu_wr_vram = sel_vram && !cpu_wr_n && lcd_mode!=3;
reg vram_bank; //0-1 FF4F - VBK
@@ -453,10 +455,12 @@ wire [15:0] hdma_source_addr;
wire [15:0] hdma_target_addr;
wire [7:0] hdma_do;
wire hdma_rd;
wire hdma_active;
hdma hdma(
.reset ( reset ),
.clk ( clk2x ),
.speed ( cpu_speed ),
// cpu register interface
.sel_reg ( sel_hdma ),
@@ -469,6 +473,7 @@ hdma hdma(
// dma connection
.hdma_rd ( hdma_rd ),
.hdma_active ( hdma_active ),
.hdma_source_addr ( hdma_source_addr ),
.hdma_target_addr ( hdma_target_addr )

View File

@@ -1,331 +1,360 @@
module hdma(
input reset,
input clk, // 8 Mhz cpu clock
// cpu register interface
input sel_reg,
input [3:0] addr,
input wr,
output [7:0] dout,
input [7:0] din,
input [1:0] lcd_mode,
// dma connection
output hdma_rd,
output [15:0] hdma_source_addr,
output [15:0] hdma_target_addr
module hdma(
input reset,
input clk, // 8 Mhz cpu clock
input speed, // cpu speed mode use for initial delay
// cpu register interface
input sel_reg,
input [3:0] addr,
input wr,
output [7:0] dout,
input [7:0] din,
input [1:0] lcd_mode,
// dma connection
output reg hdma_rd,
output reg hdma_active,
output [15:0] hdma_source_addr,
output [15:0] hdma_target_addr
);
//ff51-ff55 HDMA1-5 (GBC)
reg [7:0] hdma_source_h; // ff51
reg [3:0] hdma_source_l; // ff52 only top 4 bits used
reg [4:0] hdma_target_h; // ff53 only lowest 5 bits used
reg [3:0] hdma_target_l; // ff54 only top 4 bits used
reg hdma_mode; // ff55 bit 7 - 1=General Purpose DMA 0=H-Blank DMA
reg hdma_enabled; // ff55 !bit 7 when read
reg [7:0] hdma_length; // ff55 bit 6:0 - dma transfer length (hdma_length+1)*16 bytes
reg hdma_active;
// it takes about 8us to transfer a block of 16 bytes. -> 500ns per byte -> 2Mhz
// 32 cycles in Normal Speed Mode, and 64 'fast' cycles in Double Speed Mode
reg [13:0] hdma_cnt;
reg [5:0] hdma_16byte_cnt; //16bytes*4
assign hdma_rd = hdma_active;
assign hdma_source_addr = { hdma_source_h,hdma_source_l,4'd0} + hdma_cnt[13:2];
assign hdma_target_addr = { 3'b100,hdma_target_h,hdma_target_l,4'd0} + hdma_cnt[13:2];
reg [1:0] hdma_state;
parameter active=2'd0,blocksent=2'd1,wait_h=2'd2;
always @(posedge clk) begin
if(reset) begin
hdma_active <= 1'b0;
hdma_state <= wait_h;
hdma_enabled <= 1'b0;
hdma_source_h <= 8'hFF;
hdma_source_l <= 4'hF;
hdma_target_h <= 5'h1F;
hdma_target_l <= 4'hF;
end else begin
if(sel_reg && wr) begin
case (addr)
4'd1: hdma_source_h <= din;
4'd2: hdma_source_l <= din[7:4];
4'd3: hdma_target_h <= din[4:0];
4'd4: hdma_target_l <= din[7:4];
// writing the hdma register engages the dma engine
4'h5: begin
if (hdma_mode == 1 && hdma_enabled && !din[7]) begin //terminate an active H-Blank transfer by writing zero to Bit 7 of FF55
hdma_state <= wait_h;
hdma_active <= 1'b0;
hdma_enabled <= 1'b0;
end else begin //normal trigger
hdma_enabled <= 1'b1;
hdma_mode <= din[7];
hdma_length <= {1'b0,din[6:0]} + 8'd1;
hdma_cnt <= 14'd0;
hdma_16byte_cnt <= 6'h3f;
if (din[7] == 1) hdma_state <= wait_h;
end
end
endcase
end
if (hdma_enabled) begin
if(hdma_mode==0) begin //mode 0 GDMA do the transfer in one go
if(hdma_length != 0) begin
hdma_active <= 1'b1;
hdma_cnt <= hdma_cnt + 1'd1;
hdma_16byte_cnt <= hdma_16byte_cnt - 1'd1;
if (!hdma_16byte_cnt) begin
hdma_length <= hdma_length - 1'd1;
if (hdma_length == 1) begin
hdma_active <= 1'b0;
hdma_enabled <= 1'b0;
hdma_length <= 8'h80; //7f+1
end
end
end
end else begin //mode 1 HDMA transfer 1 block (16bytes) in each H-Blank only
case (hdma_state)
wait_h: begin
if (lcd_mode == 2'b00 ) // Mode 00: h-blank
localparam DELAY_SINGLE = 5'd10;
localparam DELAY_DOUBLE = DELAY_SINGLE/5'd2;
//ff51-ff55 HDMA1-5 (GBC)
reg [7:0] hdma_source_h; // ff51
reg [3:0] hdma_source_l; // ff52 only top 4 bits used
reg [4:0] hdma_target_h; // ff53 only lowest 5 bits used
reg [3:0] hdma_target_l; // ff54 only top 4 bits used
reg hdma_mode; // ff55 bit 7 - 1=General Purpose DMA 0=H-Blank DMA
reg hdma_enabled; // ff55 !bit 7 when read
reg [7:0] hdma_length; // ff55 bit 6:0 - dma transfer length (hdma_length+1)*16 bytes
// it takes about 8us to transfer a block of 16 bytes. -> 500ns per byte -> 2Mhz
// 32 cycles in Normal Speed Mode, and 64 'fast' cycles in Double Speed Mode
reg [13:0] hdma_cnt;
reg [5:0] hdma_16byte_cnt; //16bytes*4
//assign hdma_rd = hdma_active;
assign hdma_source_addr = { hdma_source_h,hdma_source_l,4'd0} + hdma_cnt[13:2];
assign hdma_target_addr = { 3'b100,hdma_target_h,hdma_target_l,4'd0} + hdma_cnt[13:2];
reg [4:0] dma_delay;
reg [1:0] hdma_state;
parameter active=2'd0,blocksent=2'd1,wait_h=2'd2;
always @(posedge clk) begin
if(reset) begin
hdma_active <= 1'b0;
hdma_state <= wait_h;
hdma_enabled <= 1'b0;
hdma_source_h <= 8'hFF;
hdma_source_l <= 4'hF;
hdma_target_h <= 5'h1F;
hdma_target_l <= 4'hF;
dma_delay <= 5'd0;
end else begin
if(sel_reg && wr) begin
case (addr)
4'd1: hdma_source_h <= din;
4'd2: hdma_source_l <= din[7:4];
4'd3: hdma_target_h <= din[4:0];
4'd4: hdma_target_l <= din[7:4];
// writing the hdma register engages the dma engine
4'h5: begin
if (hdma_mode == 1 && hdma_enabled && !din[7]) begin //terminate an active H-Blank transfer by writing zero to Bit 7 of FF55
hdma_state <= wait_h;
hdma_active <= 1'b0;
hdma_rd <= 1'b0;
hdma_enabled <= 1'b0;
end else begin //normal trigger
hdma_enabled <= 1'b1;
hdma_mode <= din[7];
dma_delay <= speed?DELAY_DOUBLE:DELAY_SINGLE;
hdma_length <= {1'b0,din[6:0]} + 8'd1;
hdma_cnt <= 14'd0;
hdma_16byte_cnt <= 6'h3f;
if (din[7] == 1) hdma_state <= wait_h;
end
end
endcase
end
if (hdma_enabled) begin
if(hdma_mode==0) begin //mode 0 GDMA do the transfer in one go after inital delay
hdma_active <= 1'b1;
if (dma_delay>0) begin
dma_delay <= dma_delay - 5'd1;
end else begin
if(hdma_length != 0) begin
hdma_rd <= 1'b1;
hdma_cnt <= hdma_cnt + 1'd1;
hdma_16byte_cnt <= hdma_16byte_cnt - 1'd1;
if (!hdma_16byte_cnt) begin
hdma_length <= hdma_length - 1'd1;
if (hdma_length == 1) begin
hdma_active <= 1'b0;
hdma_rd <= 1'b0;
hdma_enabled <= 1'b0;
hdma_length <= 8'h80; //7f+1
end
end
end
end
end else begin //mode 1 HDMA transfer 1 block (16bytes) in each H-Blank only
case (hdma_state)
wait_h: begin
if (lcd_mode == 2'b00 ) begin // Mode 00: h-blank
dma_delay <= speed?DELAY_DOUBLE:DELAY_SINGLE;
hdma_state <= active;
hdma_16byte_cnt <= 6'h3f;
hdma_active <= 1'b0;
end
blocksent: begin
if (hdma_length == 0) begin //check if finished
hdma_enabled <= 1'b0;
hdma_length <= 8'h80; //7f+1
end
if (lcd_mode == 2'b11) // wait for mode 3, mode before h-blank
hdma_state <= wait_h;
end
active: begin
end
hdma_16byte_cnt <= 6'h3f;
hdma_active <= 1'b0;
hdma_rd <= 1'b0;
end
blocksent: begin
if (hdma_length == 0) begin //check if finished
hdma_enabled <= 1'b0;
hdma_length <= 8'h80; //7f+1
end
if (lcd_mode == 2'b11) // wait for mode 3, mode before h-blank
hdma_state <= wait_h;
end
active: begin
if(hdma_length != 0) begin
hdma_active <= 1'b1;
hdma_cnt <= hdma_cnt + 1'd1;
hdma_16byte_cnt <= hdma_16byte_cnt - 1'd1;
if (!hdma_16byte_cnt) begin
hdma_length <= hdma_length - 1'd1;
hdma_state <= blocksent;
hdma_active <= 1'b0;
end
end else begin
hdma_active <= 1'b0;
hdma_enabled <= 1'b0;
hdma_length <= 8'h80; //7f+1
end
end
endcase
end
end
end
end
wire [7:0] length_m1 = hdma_length - 8'd1;
assign dout = sel_reg?
(addr==4'd5)?hdma_enabled?{1'b0,length_m1[6:0]}:
{1'b1,length_m1[6:0]}:
8'hFF:
8'hFF;
endmodule
`timescale 1 ns/100 ps // time-unit = 1 ns, precision = 100 ps
module hdma_tb;
// duration for each bit = 125 * timescale = 125 * 1 ns = 125ns // 8MHz
localparam period = 125;
reg reset = 1'd1;
reg clk = 1'd0;
// cpu register interface
reg sel_reg = 1'd0;
reg [3:0] addr = 4'd0;
reg wr = 1'd0;
wire [7:0] dout;
reg [7:0] din = 8'd0;
reg [1:0] lcd_mode = 2'd0;
// dma connection
wire hdma_rd;
wire [15:0] hdma_source_addr;
wire [15:0] hdma_target_addr;
hdma hdma(
.reset ( reset ),
.clk ( clk ),
// cpu register interface
.sel_reg ( sel_reg ),
.addr ( addr ),
.wr ( wr ),
.dout ( dout ),
.din ( din ),
.lcd_mode ( lcd_mode ),
// dma connection
.hdma_rd ( hdma_rd ),
.hdma_source_addr ( hdma_source_addr ),
.hdma_target_addr ( hdma_target_addr )
);
always #62 clk <= !clk;
initial begin
reset <= 1'b0;
sel_reg <= 1'b1;
addr <= 4'd4;
#1000
sel_reg <= 1'b1;
addr <= 4'd1; // source h
din <= 8'h20;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
sel_reg <= 1'b1;
addr <= 4'd2; // source l
din <= 8'h40;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
sel_reg <= 1'b1;
addr <= 4'd3; // target h
din <= 8'h82;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
sel_reg <= 1'b1;
addr <= 4'd4; // target l
din <= 8'h00;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
$display("GDMA");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger GDMA with length
din <= 8'h01; // 20h bytes
wr <= 1'd1;
#period
wr <= 1'd0;
#8000
lcd_mode <= 2'd1;
#2000
lcd_mode <= 2'd0;
#8000
$display("HDMA");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger HDMA with length
din <= 8'h82; // 30h bytes
wr <= 1'd1;
#period
wr <= 1'd0;
#16000
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
lcd_mode <= 2'd0;
#16000
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
lcd_mode <= 2'd0;
#16000
sel_reg <= 1'b1;
addr <= 4'd5;
$display("Check FF55");
#1000
$display("HDMA with cancel");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger HDMA with length
din <= 8'h82; // 30h bytes
wr <= 1'd1;
#period
wr <= 1'd0;
#16000
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
$display("canceling");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger HDMA with length
din <= 8'h00; // stop
wr <= 1'd1;
#period
wr <= 1'd0;
#16000
sel_reg <= 1'b1;
addr <= 4'd5;
$display("Check FF55");
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
$display("Test Complete");
end
hdma_active <= 1'b1;
if (dma_delay>0) begin
dma_delay <= dma_delay - 5'd1;
end else begin
hdma_rd <= 1'b1;
hdma_cnt <= hdma_cnt + 1'd1;
hdma_16byte_cnt <= hdma_16byte_cnt - 1'd1;
if (!hdma_16byte_cnt) begin
hdma_length <= hdma_length - 1'd1;
hdma_state <= blocksent;
hdma_active <= 1'b0;
hdma_rd <= 1'b0;
end
end
end else begin
hdma_active <= 1'b0;
hdma_rd <= 1'b0;
hdma_enabled <= 1'b0;
hdma_length <= 8'h80; //7f+1
end
end
endcase
end
end
end
end
wire [7:0] length_m1 = hdma_length - 8'd1;
assign dout = sel_reg?
(addr==4'd5)?hdma_enabled?{1'b0,length_m1[6:0]}:
{1'b1,length_m1[6:0]}:
8'hFF:
8'hFF;
endmodule
`timescale 1 ns/100 ps // time-unit = 1 ns, precision = 100 ps
module hdma_tb;
// duration for each bit = 125 * timescale = 125 * 1 ns = 125ns // 8MHz
localparam period = 125;
reg reset = 1'd1;
reg clk = 1'd0;
reg speed = 1'b0;
// cpu register interface
reg sel_reg = 1'd0;
reg [3:0] addr = 4'd0;
reg wr = 1'd0;
wire [7:0] dout;
reg [7:0] din = 8'd0;
reg [1:0] lcd_mode = 2'd0;
// dma connection
wire hdma_rd;
wire hdma_active;
wire [15:0] hdma_source_addr;
wire [15:0] hdma_target_addr;
hdma hdma(
.reset ( reset ),
.clk ( clk ),
.speed ( speed ),
// cpu register interface
.sel_reg ( sel_reg ),
.addr ( addr ),
.wr ( wr ),
.dout ( dout ),
.din ( din ),
.lcd_mode ( lcd_mode ),
// dma connection
.hdma_rd ( hdma_rd ),
.hdma_active ( hdma_active ),
.hdma_source_addr ( hdma_source_addr ),
.hdma_target_addr ( hdma_target_addr )
);
always #62 clk <= !clk;
initial begin
reset <= 1'b0;
sel_reg <= 1'b1;
addr <= 4'd4;
#1000
sel_reg <= 1'b1;
addr <= 4'd1; // source h
din <= 8'h20;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
sel_reg <= 1'b1;
addr <= 4'd2; // source l
din <= 8'h40;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
sel_reg <= 1'b1;
addr <= 4'd3; // target h
din <= 8'h82;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
sel_reg <= 1'b1;
addr <= 4'd4; // target l
din <= 8'h00;
wr <= 1'd1;
#period
wr <= 1'd0;
#period
$display("GDMA");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger GDMA with length
din <= 8'h01; // 20h bytes
wr <= 1'd1;
#period
wr <= 1'd0;
#8000
lcd_mode <= 2'd1;
#2000
lcd_mode <= 2'd0;
#8000
$display("HDMA");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger HDMA with length
din <= 8'h82; // 30h bytes
wr <= 1'd1;
#period
wr <= 1'd0;
#16000
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
lcd_mode <= 2'd0;
#16000
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
lcd_mode <= 2'd0;
#16000
sel_reg <= 1'b1;
addr <= 4'd5;
$display("Check FF55");
#1000
$display("HDMA with cancel");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger HDMA with length
din <= 8'h82; // 30h bytes
wr <= 1'd1;
#period
wr <= 1'd0;
#16000
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
$display("canceling");
sel_reg <= 1'b1;
addr <= 4'd5; // trigger HDMA with length
din <= 8'h00; // stop
wr <= 1'd1;
#period
wr <= 1'd0;
#16000
sel_reg <= 1'b1;
addr <= 4'd5;
$display("Check FF55");
lcd_mode <= 2'd2;
#2000
lcd_mode <= 2'd3;
#2000
$display("Test Complete");
end
endmodule

View File

@@ -74,7 +74,7 @@ use work.T80_Pack.all;
entity GBse is
generic(
T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
);
port(

View File

@@ -155,7 +155,7 @@ begin
end if;
end process;
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku)
variable Q_t : std_logic_vector(7 downto 0);
variable DAA_Q : unsigned(8 downto 0);
begin

View File

@@ -517,8 +517,10 @@ begin
end if;
when "11111001" =>
-- LD SP,HL
TStates <= "110";
LDSPHL <= '1';
MCycles <= "010";
if MCycle = "010" then
LDSPHL <= '1';
end if;
when "11000101"|"11010101"|"11100101"|"11110101" =>
-- PUSH qq
if Mode = 3 then
@@ -845,34 +847,50 @@ begin
end case;
elsif IntCycle = '1' then
-- INT (IM 2)
if mode = 3 then
MCycles <= "011";
else
MCycles <= "101";
end if;
case to_integer(unsigned(MCycle)) is
when 1 =>
LDZ <= '1';
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
TStates <= "100";
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
TStates <= "100";
Write <= '1';
when 4 =>
Inc_PC <= '1';
LDZ <= '1';
when 5 =>
Jump <= '1';
when others => null;
end case;
if mode = 3 then
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
LDZ <= '1';
TStates <= "110";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
Write <= '1';
when others => null;
end case;
else
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
LDZ <= '1';
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
TStates <= "100";
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
TStates <= "100";
Write <= '1';
when 4 =>
Inc_PC <= '1';
LDZ <= '1';
when 5 =>
Jump <= '1';
when others => null;
end case;
end if;
else
-- NOP
end if;
@@ -1048,7 +1066,11 @@ begin
end case;
else
-- JP cc,nn
MCycles <= "011";
if Mode = 3 then
MCycles <= "100";
else
MCycles <= "011";
end if;
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
@@ -1057,6 +1079,8 @@ begin
Inc_PC <= '1';
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Jump <= '1';
else
MCycles <= "011";
end if;
when others => null;
end case;
@@ -1364,25 +1388,41 @@ begin
-- RST p
if Mode = 3 then
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 3 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 4 =>
Write <= '1';
RstP <= '1';
when others => null;
end case;
else
MCycles <= "011";
end if;
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
Write <= '1';
RstP <= '1';
when others => null;
end case;
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 3 =>
Write <= '1';
RstP <= '1';
when others => null;
end case;
end if;
-- INPUT AND OUTPUT GROUP
when "11011011" =>

View File

@@ -49,10 +49,10 @@ wire resetdiv = cpu_sel && cpu_wr && (cpu_addr == 2'b00); //resetdiv also resets
reg [9:0] clk_div;
always @(posedge clk or posedge resetdiv)
if(resetdiv)
clk_div <= 10'd6;
clk_div <= 10'd2;
else
if (reset)
clk_div <= 10'd6;
clk_div <= 10'd8;
else
clk_div <= clk_div + 10'd1;

View File

@@ -38,6 +38,7 @@ module video (
output lcd_clkena,
output [14:0] lcd_data,
output reg irq,
output reg vblank_irq,
// vram connection
output [1:0] mode,
@@ -57,6 +58,7 @@ module video (
localparam STAGE2 = 9'd250; // oam + disp + pause
localparam OAM_LEN = 80;
localparam OAM_LEN16 = OAM_LEN/16;
localparam MODE3_OFFSET = 8'd16;
wire sprite_pixel_active;
wire [1:0] sprite_pixel_data;
@@ -108,7 +110,7 @@ sprites sprites (
// give dma access to oam
wire [7:0] oam_addr = dma_active?dma_addr[7:0]:cpu_addr;
wire oam_wr = dma_active?(dma_cnt[1:0] == 2):(cpu_wr && cpu_sel_oam);
wire oam_wr = dma_active?(dma_cnt[1:0] == 2):(cpu_wr && cpu_sel_oam && !(mode==3 || mode==2));
wire [7:0] oam_di = dma_active?dma_data:cpu_di;
@@ -140,6 +142,7 @@ wire [7:0] ly = v_cnt;
// ff45 line counter compare
wire lyc_match = (ly == lyc);
reg [7:0] lyc;
reg lyc_changed=0;
reg [7:0] bgp;
reg [7:0] obp0;
@@ -195,12 +198,14 @@ end
// ------------------------------- IRQs -------------------------------
// --------------------------------------------------------------------
always @(posedge clk_reg) begin //TODO: have to check if this is correct
always @(posedge clk_reg) begin
irq <= 1'b0;
vblank_irq <= 1'b0;
//TODO: investigate and fix timing of lyc=ly
// lyc=ly coincidence
if(stat[6] && (h_cnt == 1) && lyc_match)
if(stat[6] && h_cnt == 0 && lyc_match)
irq <= 1'b1;
if(stat[6] && lyc_changed == 1 && h_cnt > 0 && lyc_match)
irq <= 1'b1;
// begin of oam phase
@@ -208,8 +213,11 @@ always @(posedge clk_reg) begin //TODO: have to check if this is correct
irq <= 1'b1;
// begin of vblank
if(stat[4] && (h_cnt == 455) && (v_cnt == 143))
irq <= 1'b1;
if((h_cnt == 455) && (v_cnt == 143)) begin
if (stat[4])
irq <= 1'b1;
vblank_irq <= 1'b1;
end
// begin of hblank
if(stat[3] && (h_cnt == OAM_LEN + 160 + hextra))
@@ -243,6 +251,7 @@ always @(posedge clk_reg) begin
end
end else begin
lyc_changed<=0;
if(cpu_sel_reg && cpu_wr) begin
case(cpu_addr)
8'h40: lcdc <= cpu_di;
@@ -250,7 +259,10 @@ always @(posedge clk_reg) begin
8'h42: scy <= cpu_di;
8'h43: scx <= cpu_di;
// a write to 4 is supposed to reset the v_cnt
8'h45: lyc <= cpu_di;
8'h45: begin
lyc <= cpu_di;
lyc_changed<=1;
end
8'h46: dma <= cpu_di;
8'h47: bgp <= cpu_di;
8'h48: obp0 <= cpu_di;
@@ -264,20 +276,23 @@ always @(posedge clk_reg) begin
bgpi_ai <= cpu_di[7];
end
8'h69: begin
bgpd[bgpi] <= cpu_di;
if (bgpi_ai)
bgpi <= bgpi + 6'h1;
if (mode != 3) begin
bgpd[bgpi] <= cpu_di;
if (bgpi_ai)
bgpi <= bgpi + 6'h1;
end
end
8'h6A: begin
obpi <= cpu_di[5:0];
obpi_ai <= cpu_di[7];
end
8'h6B: begin
obpd[obpi] <= cpu_di;
if (obpi_ai)
obpi <= obpi + 6'h1;
if (mode != 3) begin
obpd[obpi] <= cpu_di;
if (obpi_ai)
obpi <= obpi + 6'h1;
end
end
endcase
end
end
@@ -299,9 +314,9 @@ assign cpu_do =
(cpu_addr == 8'h4b)?wx:
isGBC?
(cpu_addr == 8'h68)?{bgpi_ai,1'd0,bgpi}:
(cpu_addr == 8'h69)?bgpd[bgpi]:
(cpu_addr == 8'h69 && mode != 3)?bgpd[bgpi]:
(cpu_addr == 8'h6a)?{obpi_ai,1'd0,obpi}:
(cpu_addr == 8'h6b)?obpd[obpi]:
(cpu_addr == 8'h6b && mode != 3)?obpd[obpi]:
8'hff:
8'hff;
@@ -351,14 +366,25 @@ wire [14:0] sprite_pix = isGBC?{obpd[sprite_palette_index+1][6:0],obpd[sprite_pa
// - there's a sprite at the current position
// - the sprites prioroty bit is 0, or
// - the sprites priority is 1 and the backrgound color is 00
// - GBC : BG priority is 0
// - GBC : BG priority is 0
// - GBC : BG priority is 1 and the backrgound color is 00
wire bg_piority = isGBC&&stage2_bgp_buffer_pix[stage2_rptr][3];
wire sprite_pixel_visible =
sprite_pixel_active && lcdc_spr_ena && (~bg_piority) &&
((!sprite_pixel_prio) || (stage2_buffer[stage2_rptr] == 2'b00));
wire [1:0] bg_color = stage2_buffer[stage2_rptr];
reg sprite_pixel_visible;
always @(*) begin
sprite_pixel_visible = 1'b0;
if (sprite_pixel_active && lcdc_spr_ena) begin // pixel active and sprites enabled
if (bg_color == 2'b00) // background color = 0
sprite_pixel_visible = 1'b1;
else if (!bg_piority && !sprite_pixel_prio) // sprite has priority enabled and background priority disabled
sprite_pixel_visible = 1'b1;
end
end
always @(posedge clk) begin
if(h_cnt == 455) begin
stage2_wptr <= 8'h00;
@@ -462,9 +488,9 @@ wire vblank = (v_cnt >= 144);
// x scroll & 7 needs one more memory read per line
reg [1:0] hextra_tiles;
wire [7:0] hextra = { 3'b000, hextra_tiles, 3'b000 };
wire [7:0] hextra = { 3'b000, hextra_tiles, 3'b000 }+MODE3_OFFSET;
wire hblank = ((h_cnt < OAM_LEN) || (h_cnt >= 160+OAM_LEN+hextra));
wire oam = (h_cnt < OAM_LEN); // 80 clocks oam
wire oam = (h_cnt <= OAM_LEN); // 80 clocks oam
wire stage2 = ((h_cnt >= STAGE2) && (h_cnt < STAGE2+160)); // output out of stage2
// first valid pixels are delivered 8 clocks after end of hblank
@@ -546,6 +572,7 @@ wire bg_tile_obj_rd = (!vblank) && (!hblank) && (h_cnt[2:1] == 2'b11);
// Mode 10: oam
// Mode 11: oam and vram
assign mode =
(ly <= 144 && h_cnt<4)?2'b00: //AntonioND https://github.com/AntonioND/giibiiadvance/blob/master/docs/TCAGBD.pdf
!lcdc_on?2'b00:
vblank?2'b01:
oam?2'b10:
@@ -565,11 +592,11 @@ wire win_start = lcdc_win_ena && (v_cnt >= wy_r) && de && (wx_r >= 7) && (pcnt =
// each memory access takes two cycles
always @(negedge clk or negedge lcdc_on) begin
always @(negedge clk) begin
if (!lcdc_on) begin // don't increase counters if lcdoff
//reset counters
h_cnt <= 9'd0;
h_cnt <= 9'd6;
v_cnt <= 8'd0;
end else begin