diff --git a/Arcade_MiST/Midway MCR 1/Kickman_MiST/Kickman.qsf b/Arcade_MiST/Midway MCR 1/Kickman_MiST/Kickman.qsf index 70ebd29f..79ab876a 100644 --- a/Arcade_MiST/Midway MCR 1/Kickman_MiST/Kickman.qsf +++ b/Arcade_MiST/Midway MCR 1/Kickman_MiST/Kickman.qsf @@ -217,8 +217,6 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/Kickman_MiST.sv set_global_assignment -name VHDL_FILE rtl/kick.vhd set_global_assignment -name VHDL_FILE rtl/kick_sound_board.vhd set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd -set_global_assignment -name VHDL_FILE rtl/ctc_counter.vhd -set_global_assignment -name VHDL_FILE rtl/ctc_controler.vhd set_global_assignment -name VHDL_FILE rtl/spinner.vhd set_global_assignment -name VHDL_FILE rtl/rom/midssio_82s123.vhd set_global_assignment -name VHDL_FILE rtl/rom/kick_sp_bits.vhd @@ -227,6 +225,7 @@ set_global_assignment -name VHDL_FILE rtl/rom/kick_bg_bits_1.vhd set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd +set_global_assignment -name QIP_FILE ../../../common/IO/Z80CTC/z80ctc.qip set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/Kickman_MiST.sv b/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/Kickman_MiST.sv index 73d24a0f..11c3852d 100644 --- a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/Kickman_MiST.sv +++ b/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/Kickman_MiST.sv @@ -50,13 +50,16 @@ module Kickman_MiST( localparam CONF_STR = { "KICKMAN;;", "O2,Rotate Controls,Off,On;", - "O34,Scanlines,Off,25%,50%,75%;", "O5,Blend,Off,On;", "O6,Service,Off,On;", "T0,Reset;", "V,v1.0.",`BUILD_DATE }; +wire rotate = status[2]; +wire blend = status[5]; +wire service = status[6]; + assign LED = ~ioctl_downl; assign SDRAM_CLK = clk_sys; assign SDRAM_CKE = 1; @@ -81,6 +84,10 @@ wire [15:0] audio_l, audio_r; wire hs, vs, cs; wire blankn; wire [3:0] g, r, b; +wire key_pressed; +wire [7:0] key_code; +wire key_strobe; + wire [14:0] rom_addr; wire [15:0] rom_do; wire [13:0] snd_addr; @@ -162,7 +169,7 @@ wire [3:0] spin_angle; spinner spinner ( .clock_40(clk_sys), .reset(reset), - .btn_acc(m_fire), + .btn_acc(m_fireA), .btn_left(m_left), .btn_right(m_right), .ctc_zc_to_2(ctc_zc_to2), @@ -183,14 +190,14 @@ kick kick( .separate_audio(1'b0), .audio_out_l(audio_l), .audio_out_r(audio_r), - .coin1(btn_coin), - .coin2(1'b0), - .start2(btn_two_players), - .start1(btn_one_player), + .coin1(m_coin1), + .coin2(m_coin2), + .start1(m_one_player), + .start2(m_two_players), .kick(m_down), .ctc_zc_to_2(ctc_zc_to2), .spin_angle(spin_angle), - .service(status[6]), + .service(service), .cpu_rom_addr ( rom_addr ), .cpu_rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ), .snd_rom_addr ( snd_addr ), @@ -217,12 +224,12 @@ mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(10)) mist_video( .VGA_B ( VGA_B ), .VGA_VS ( vs_out ), .VGA_HS ( hs_out ), - .rotate ( {1'b1,status[2]} ), + .rotate ( { 1'b1, rotate } ), .ce_divider ( 1'b1 ), - .blend ( status[5] ), + .blend ( blend ), .scandoubler_disable( 1'b1 ), .no_csync ( 1'b1 ), - .scanlines ( status[4:3] ), + .scanlines ( ), .ypbpr ( ypbpr ) ); @@ -265,43 +272,24 @@ dac_r( .dac_o(AUDIO_R) ); -// Rotated Normal -//wire m_up = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_up | joystick_0[3] | joystick_1[3]; -wire m_down = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_down | joystick_0[2] | joystick_1[2]; -wire m_left = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_left | joystick_0[1] | joystick_1[1]; -wire m_right = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_right | joystick_0[0] | joystick_1[0]; -wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4]; -//wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5]; +wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; -reg btn_one_player = 0; -reg btn_two_players = 0; -reg btn_left = 0; -reg btn_right = 0; -reg btn_down = 0; -reg btn_up = 0; -reg btn_fire1 = 0; -//reg btn_fire2 = 0; -//reg btn_fire3 = 0; -reg btn_coin = 0; -wire key_pressed; -wire [7:0] key_code; -wire key_strobe; - -always @(posedge clk_sys) begin - if(key_strobe) begin - case(key_code) - 'h75: btn_up <= key_pressed; // up - 'h72: btn_down <= key_pressed; // down - 'h6B: btn_left <= key_pressed; // left - 'h74: btn_right <= key_pressed; // right - 'h76: btn_coin <= key_pressed; // ESC - 'h05: btn_one_player <= key_pressed; // F1 - 'h06: btn_two_players <= key_pressed; // F2 -// 'h14: btn_fire3 <= key_pressed; // ctrl -// 'h11: btn_fire2 <= key_pressed; // alt - 'h29: btn_fire1 <= key_pressed; // Space - endcase - end -end +arcade_inputs inputs ( + .clk ( clk_sys ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( 2'b11 ), + .joyswap ( 1'b0 ), + .oneplayer ( 1'b1 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) +); endmodule diff --git a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/kick.vhd b/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/kick.vhd index 9c1b3f85..5fb6c1af 100644 --- a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/kick.vhd +++ b/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/kick.vhd @@ -216,30 +216,14 @@ architecture struct of kick is signal cpu_ioreq_n : std_logic; signal cpu_irq_n : std_logic; signal cpu_m1_n : std_logic; - - signal ctc_controler_we : std_logic; - signal ctc_controler_do : std_logic_vector(7 downto 0); - signal ctc_int_ack : std_logic; + signal cpu_int_ack_n : std_logic; - signal ctc_counter_0_we : std_logic; --- signal ctc_counter_0_trg : std_logic; - signal ctc_counter_0_do : std_logic_vector(7 downto 0); - signal ctc_counter_0_int : std_logic; + signal ctc_ce : std_logic; + signal ctc_do : std_logic_vector(7 downto 0); - signal ctc_counter_1_we : std_logic; --- signal ctc_counter_1_trg : std_logic; - signal ctc_counter_1_do : std_logic_vector(7 downto 0); - signal ctc_counter_1_int : std_logic; - - signal ctc_counter_2_we : std_logic; --- signal ctc_counter_2_trg : std_logic; - signal ctc_counter_2_do : std_logic_vector(7 downto 0); - signal ctc_counter_2_int : std_logic; - - signal ctc_counter_3_we : std_logic; - signal ctc_counter_3_trg : std_logic; - signal ctc_counter_3_do : std_logic_vector(7 downto 0); - signal ctc_counter_3_int : std_logic; + signal ctc_counter_1_trg : std_logic; + signal ctc_counter_2_trg : std_logic; + signal ctc_counter_3_trg : std_logic; -- signal cpu_rom_do : std_logic_vector( 7 downto 0); @@ -409,6 +393,10 @@ begin else vs_cnt <= vs_cnt +1; end if; + + if vcnt = 240 then video_vs <= '0'; end if; + if vcnt = 242 then video_vs <= '1'; end if; + else hs_cnt <= hs_cnt + 1; end if; @@ -418,8 +406,8 @@ begin vcnt >= 1 and vcnt < 241 then video_blankn <= '1';end if; - if hs_cnt = 0 then hsync0 <= '0'; - elsif hs_cnt = 47 then hsync0 <= '1'; + if hs_cnt = 0 then hsync0 <= '0'; video_hs <= '0'; + elsif hs_cnt = 47 then hsync0 <= '1'; video_hs <= '1'; end if; if hs_cnt = 0 then hsync1 <= '0'; @@ -566,24 +554,16 @@ cpu_di <= cpu_rom_do when cpu_mreq_n = '0' and cpu_addr(15 downto 12) < X"7" wram_do when cpu_mreq_n = '0' and cpu_addr(15 downto 12) = X"7" else -- 7000-7FFF sp_ram_cache_do when cpu_mreq_n = '0' and cpu_addr(15 downto 9) = "1111000" else -- sprite ram 0xF000-0xF1FF bg_ram_do when cpu_mreq_n = '0' and cpu_addr(15 downto 10) = "111111" else -- video ram 0xFC00-0xFFFF - ctc_controler_do when cpu_ioreq_n = '0' and cpu_m1_n = '0' else -- ctc ctrl (interrupt vector) + ctc_do when cpu_int_ack_n = '0' or ctc_ce = '1' else -- ctc (interrupt vector or counter data) ssio_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 4) = X"0" else - ctc_counter_3_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F3" else - ctc_counter_2_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F2" else - ctc_counter_1_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F1" else - ctc_counter_0_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else X"FF"; ------------------------------------------------------------------------ -- Misc registers : ctc write enable / interrupt acknowledge ------------------------------------------------------------------------ -ctc_counter_3_trg <= '1' when (vcnt = 246 and tv15Khz_mode = '1') or (vcnt = 493 and tv15Khz_mode = '0')else '0'; -ctc_counter_3_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F3" else '0'; -ctc_counter_2_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F2" else '0'; -ctc_counter_1_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F1" else '0'; -ctc_counter_0_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else '0'; -ctc_controler_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else '0'; -- F0 -ctc_int_ack <= '1' when cpu_ioreq_n = '0' and cpu_m1_n = '0' else '0'; +cpu_int_ack_n <= cpu_ioreq_n or cpu_m1_n; +ctc_ce <= '1' when cpu_ioreq_n = '0' and cpu_addr(7 downto 4) = x"F" else '0'; +ctc_counter_3_trg <= '1' when top_frame = '1' and ((vcnt = 246 and tv15Khz_mode = '1') or (vcnt = 493 and tv15Khz_mode = '0')) else '0'; ------------------------------------------ -- write enable / ram access from CPU -- @@ -780,92 +760,28 @@ port map( DO => cpu_do ); --- CTC interrupt controler Z80-CTC (MK3882) -ctc_controler : entity work.ctc_controler -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_controler_we, - int_ack => ctc_int_ack, - - int_pulse_0 => ctc_counter_0_int, - int_pulse_1 => ctc_counter_1_int, - int_pulse_2 => ctc_counter_2_int, - int_pulse_3 => ctc_counter_3_int, - - d_out => ctc_controler_do, - int_n => cpu_irq_n -); - -ctc_counter_0 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_0_we, - - clk_trg => '0', - - d_out => ctc_counter_0_do, - zc_to => open, -- zc/to #0 (pin 7) connected to clk_trg #1 (pin 22) on schematics (seems to be not used) - int_pulse => ctc_counter_0_int - -); - -ctc_counter_1 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_1_we, - - clk_trg => '0', - - d_out => ctc_counter_1_do, - zc_to => open, - int_pulse => ctc_counter_1_int - -); - -ctc_counter_2 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_2_we, - - clk_trg => '0', - - d_out => ctc_counter_2_do, - zc_to => ctc_zc_to_2, -- used for spin angle decoder simulation - int_pulse => ctc_counter_2_int - -); - -ctc_counter_3 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_3_we, - - clk_trg => ctc_counter_3_trg, - - d_out => ctc_counter_3_do, - zc_to => open, - int_pulse => ctc_counter_3_int - +-- Z80-CTC (MK3882) +z80ctc : entity work.z80ctc_top +port map ( + clock => clock_vid, + clock_ena => cpu_ena, + reset => reset, + din => cpu_do, + cpu_din => cpu_di, + dout => ctc_do, + ce_n => not ctc_ce, + cs => cpu_addr(1 downto 0), + m1_n => cpu_m1_n, + iorq_n => cpu_ioreq_n, + rd_n => cpu_rd_n, + int_n => cpu_irq_n, + trg0 => '0', + to0 => ctc_counter_1_trg, + trg1 => ctc_counter_1_trg, + to1 => open, + trg2 => '0', + to2 => ctc_zc_to_2, + trg3 => ctc_counter_3_trg ); -- cpu program ROM 0x0000-0x6FFF diff --git a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/SolarFox.qsf b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/SolarFox.qsf index 26376919..603df671 100644 --- a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/SolarFox.qsf +++ b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/SolarFox.qsf @@ -217,14 +217,11 @@ set_global_assignment -name SYSTEMVERILOG_FILE rtl/SolarFox_MiST.sv set_global_assignment -name VHDL_FILE rtl/solarfox.vhd set_global_assignment -name VHDL_FILE rtl/solarfox_sound_board.vhd set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd -set_global_assignment -name VHDL_FILE rtl/ctc_counter.vhd -set_global_assignment -name VHDL_FILE rtl/ctc_controler.vhd set_global_assignment -name VHDL_FILE rtl/rom/midssio_82s123.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_sp_bits_4.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_sp_bits_3.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_sp_bits_2.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_sp_bits_1.vhd -set_global_assignment -name VHDL_FILE rtl/rom/sol_sound_cpu.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_bg_bits_2.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_bg_bits_1.vhd set_global_assignment -name VHDL_FILE rtl/rom/sol_sp_bits.vhd @@ -232,6 +229,7 @@ set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd set_global_assignment -name VHDL_FILE rtl/cmos_ram.vhd set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd +set_global_assignment -name QIP_FILE ../../../common/IO/Z80CTC/z80ctc.qip set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/SolarFox_MiST.sv b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/SolarFox_MiST.sv index 1569a8d6..d1eeb357 100644 --- a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/SolarFox_MiST.sv +++ b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/SolarFox_MiST.sv @@ -51,13 +51,16 @@ module SolarFox_MiST( localparam CONF_STR = { "SOLARFOX;;", "O2,Rotate Controls,Off,On;", - "O34,Scanlines,Off,25%,50%,75%;", "O5,Blend,Off,On;", "O6,Service,Off,On;", "T0,Reset;", "V,v1.1.",`BUILD_DATE }; +wire rotate = status[2]; +wire blend = status[5]; +wire service = status[6]; + assign LED = ~ioctl_downl; assign SDRAM_CLK = clk_sys; assign SDRAM_CKE= 1; @@ -82,6 +85,10 @@ wire [15:0] audio_l, audio_r; wire hs, vs, cs; wire blankn; wire [3:0] g, r, b; +wire key_pressed; +wire [7:0] key_code; +wire key_strobe; + wire [14:0] rom_addr; wire [15:0] rom_do; wire [13:0] snd_addr; @@ -171,21 +178,21 @@ solarfox solarfox( .separate_audio(1'b0), .audio_out_l(audio_l), .audio_out_r(audio_r), - .coin1(btn_coin), - .coin2(1'b0), - .fast1(btn_one_player), - .fast2(btn_two_players), - .service(status[6]), - .fire1(m_fire), - .fire2(m_fire), + .coin1(m_coin1), + .coin2(m_coin2), + .fast1(m_one_player), + .fast2(m_two_players), + .service(service), + .fire1(m_fireA), + .fire2(m_fire2A), .left1(m_left), .right1(m_right), .up1(m_up), .down1(m_down), - .left2(m_left), - .right2(m_right), - .up2(m_up), - .down2(m_down), + .left2(m_left2), + .right2(m_right2), + .up2(m_up2), + .down2(m_down2), .cpu_rom_addr ( rom_addr ), .cpu_rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ), .snd_rom_addr ( snd_addr ), @@ -212,12 +219,12 @@ mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(10)) mist_video( .VGA_B ( VGA_B ), .VGA_VS ( vs_out ), .VGA_HS ( hs_out ), - .rotate ( {1'b1,status[2]} ), + .rotate ( { 1'b1, rotate } ), .ce_divider ( 1 ), - .blend ( status[5] ), + .blend ( blend ), .scandoubler_disable( 1'b1 ), .no_csync ( 1'b1 ), - .scanlines ( status[4:3] ), + .scanlines ( ), .ypbpr ( ypbpr ) ); @@ -260,43 +267,24 @@ dac_r( .dac_o(AUDIO_R) ); -// Rotated Normal -wire m_up = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_up | joystick_0[3] | joystick_1[3]; -wire m_down = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_down | joystick_0[2] | joystick_1[2]; -wire m_left = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_left | joystick_0[1] | joystick_1[1]; -wire m_right = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_right | joystick_0[0] | joystick_1[0]; -wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4]; -//wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5]; +wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; -reg btn_one_player = 0; -reg btn_two_players = 0; -reg btn_left = 0; -reg btn_right = 0; -reg btn_down = 0; -reg btn_up = 0; -reg btn_fire1 = 0; -//reg btn_fire2 = 0; -//reg btn_fire3 = 0; -reg btn_coin = 0; -wire key_pressed; -wire [7:0] key_code; -wire key_strobe; - -always @(posedge clk_sys) begin - if(key_strobe) begin - case(key_code) - 'h75: btn_up <= key_pressed; // up - 'h72: btn_down <= key_pressed; // down - 'h6B: btn_left <= key_pressed; // left - 'h74: btn_right <= key_pressed; // right - 'h76: btn_coin <= key_pressed; // ESC - 'h05: btn_one_player <= key_pressed; // F1 - 'h06: btn_two_players <= key_pressed; // F2 -// 'h14: btn_fire3 <= key_pressed; // ctrl -// 'h11: btn_fire2 <= key_pressed; // alt - 'h29: btn_fire1 <= key_pressed; // Space - endcase - end -end +arcade_inputs inputs ( + .clk ( clk_sys ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( 2'b11 ), + .joyswap ( 1'b0 ), + .oneplayer ( 1'b1 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) +); endmodule diff --git a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/ctc_controler.vhd b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/ctc_controler.vhd deleted file mode 100644 index 1ff9961d..00000000 --- a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/ctc_controler.vhd +++ /dev/null @@ -1,106 +0,0 @@ ---------------------------------------------------------------------------------- --- Z80-CTC controler by Dar (darfpga@aol.fr) (19/10/2019) --- http://darfpga.blogspot.fr ---------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; -use ieee.numeric_std.all; - -entity ctc_controler is -port( - clock : in std_logic; - clock_ena : in std_logic; - reset : in std_logic; - - d_in : in std_logic_vector( 7 downto 0); - load_data : in std_logic; - int_ack : in std_logic; - - int_pulse_0 : in std_logic; - int_pulse_1 : in std_logic; - int_pulse_2 : in std_logic; - int_pulse_3 : in std_logic; - - d_out : out std_logic_vector( 7 downto 0); - int_n : out std_logic - -); -end ctc_controler; - -architecture struct of ctc_controler is - - signal int_vector : std_logic_vector(4 downto 0); - - signal wait_for_time_constant : std_logic; - signal load_data_r : std_logic; -- make sure load_data toggles to get one new data - - signal int_reg_0 : std_logic; - signal int_reg_1 : std_logic; - signal int_reg_2 : std_logic; - signal int_reg_3 : std_logic; - - signal int_ack_r : std_logic; - -begin - -int_n <= '0' when (int_reg_0 or int_reg_1 or int_reg_2 or int_reg_3) = '1' else '1'; - -d_out <= int_vector & "000" when int_reg_0 = '1' else - int_vector & "010" when int_reg_1 = '1' else - int_vector & "100" when int_reg_2 = '1' else - int_vector & "110" when int_reg_3 = '1' else (others => '0'); - -process (reset, clock) -begin - - if reset = '1' then -- hardware and software reset - wait_for_time_constant <= '0'; - int_reg_0 <= '0'; - int_reg_1 <= '0'; - int_reg_2 <= '0'; - int_reg_3 <= '0'; - load_data_r <= load_data; - int_vector <= (others => '0'); - else - if rising_edge(clock) then - if clock_ena = '1' then - - load_data_r <= load_data; - int_ack_r <= int_ack; - - if load_data = '1' and load_data_r = '0' then - - if wait_for_time_constant = '1' then - wait_for_time_constant <= '0'; - else - if d_in(0) = '1' then -- check if its a control world - wait_for_time_constant <= d_in(2); --- if d_in(1) = '1' then -- software reset --- wait_for_time_constant <= '0'; --- end if; - else -- its an interrupt vector - int_vector <= d_in(7 downto 3); - end if; - end if; - - end if; - - if int_pulse_0 = '1' then int_reg_0 <= '1'; end if; - if int_pulse_1 = '1' then int_reg_1 <= '1'; end if; - if int_pulse_2 = '1' then int_reg_2 <= '1'; end if; - if int_pulse_3 = '1' then int_reg_3 <= '1'; end if; - - if int_ack_r = '1' and int_ack = '0' then - if int_reg_0 = '1' then int_reg_0 <= '0'; - elsif int_reg_1 = '1' then int_reg_1 <= '0'; - elsif int_reg_2 = '1' then int_reg_2 <= '0'; - elsif int_reg_3 = '1' then int_reg_3 <= '0'; end if; - end if; - - end if; - end if; - end if; -end process; - -end struct; diff --git a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/ctc_counter.vhd b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/ctc_counter.vhd deleted file mode 100644 index 25f9a797..00000000 --- a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/ctc_counter.vhd +++ /dev/null @@ -1,152 +0,0 @@ ---------------------------------------------------------------------------------- --- Z80-CTC counter by Dar (darfpga@aol.fr) (19/10/2019) --- http://darfpga.blogspot.fr ---------------------------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; -use ieee.numeric_std.all; - -entity ctc_counter is -port( - clock : in std_logic; - clock_ena : in std_logic; - reset : in std_logic; - - d_in : in std_logic_vector( 7 downto 0); - load_data : in std_logic; - - clk_trg : in std_logic; - - d_out : out std_logic_vector(7 downto 0); - zc_to : out std_logic; - int_pulse : out std_logic - - ); -end ctc_counter; - -architecture struct of ctc_counter is - - signal control_word : std_logic_vector(7 downto 0); - signal wait_for_time_constant : std_logic; - signal time_constant_loaded : std_logic; - signal restart_on_next_clock : std_logic; - signal restart_on_next_trigger : std_logic; - - signal prescale_max : std_logic_vector(7 downto 0); - signal prescale_in : std_logic_vector(7 downto 0) := (others => '0'); - signal count_max : std_logic_vector(8 downto 0); - signal count_in : std_logic_vector(8 downto 0) := (others => '0'); - signal zc_to_in : std_logic; - signal clk_trg_r : std_logic; - signal trigger : std_logic; - signal count_ena : std_logic; - signal load_data_r : std_logic; -- make sure load_data toggles to get one new data - -begin - -prescale_max <= - (others => '0') when control_word(6) = '1' else -- counter mode (prescale max = 0) - X"0F" when control_word(6 downto 5) = "00" else -- timer mode prescale 16 - X"FF"; -- timer mode prescale 256 - -trigger <= - '1' when (clk_trg = '0' and clk_trg_r = '1' and control_word(4) = '0') or -- falling edge - (clk_trg = '1' and clk_trg_r = '0' and control_word(4) = '1') else '0'; -- rising edge - -d_out <= count_in(7 downto 0); - -zc_to <= zc_to_in; -int_pulse <= zc_to_in when control_word(7) = '1' else '0'; - -process (reset, clock) -begin - - if reset = '1' then -- hardware reset - count_ena <= '0'; - wait_for_time_constant <= '0'; - time_constant_loaded <= '0'; - restart_on_next_clock <= '0'; - restart_on_next_trigger <= '0'; - count_in <= (others=> '0'); - zc_to_in <= '0'; - clk_trg_r <= clk_trg; - else - if rising_edge(clock) then - if clock_ena = '1' then - - clk_trg_r <= clk_trg; - load_data_r <= load_data; - - if (restart_on_next_trigger = '1' and trigger = '1') or (restart_on_next_clock = '1') then - restart_on_next_clock <= '0'; - restart_on_next_trigger <= '0'; - count_ena <= '1'; - count_in <= count_max; - prescale_in <= prescale_max; - end if; - - if load_data = '1' and load_data_r = '0' then - - if wait_for_time_constant = '1' then - wait_for_time_constant <= '0'; - time_constant_loaded <= '1'; - - if d_in = X"00" then - count_max <= '1'&X"00"; - else - count_max <= '0'&d_in; - end if; - - if control_word(6) = '0' and count_ena = '0' then -- in timer mode, if count was stooped - if control_word(3) = '0' then -- auto start when time_constant loaded - restart_on_next_clock <= '1'; - else -- wait for trigger to start - restart_on_next_trigger <= '1'; - end if; - end if; - - else -- not waiting for time constant - - if d_in(0) = '1' then -- check if its a control world - control_word <= d_in; - wait_for_time_constant <= d_in(2); - restart_on_next_clock <= '0'; - restart_on_next_trigger <= '0'; - - if d_in(1) = '1' then -- software reset - count_ena <= '0'; - time_constant_loaded <= '0'; - zc_to_in <= '0'; --- zc_to_in_r <= '0'; - clk_trg_r <= clk_trg; - end if; - end if; - - end if; - - end if; -- end load data - - -- counter - zc_to_in <= '0'; - if ((control_word(6) = '1' and trigger = '1' ) or - (control_word(6) = '0' and count_ena = '1') ) and time_constant_loaded = '1' then - if prescale_in = 0 then - prescale_in <= '0'&prescale_max(7 downto 1); -- test divide by 2 ! - if count_in = 0 then - zc_to_in <= '1'; - count_in <= count_max; - else - count_in <= count_in - '1'; - end if; - else - prescale_in <= prescale_in - '1'; - end if; - end if; - - end if; - end if; - end if; -end process; - -end struct; diff --git a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/solarfox.vhd b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/solarfox.vhd index 81713b8c..7e7db917 100644 --- a/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/solarfox.vhd +++ b/Arcade_MiST/Midway MCR 1/SolarFox_MiST/rtl/solarfox.vhd @@ -219,33 +219,17 @@ architecture struct of solarfox is signal cpu_ioreq_n : std_logic; signal cpu_irq_n : std_logic; signal cpu_m1_n : std_logic; - - signal ctc_controler_we : std_logic; - signal ctc_controler_do : std_logic_vector(7 downto 0); - signal ctc_int_ack : std_logic; + signal cpu_int_ack_n : std_logic; - signal ctc_counter_0_we : std_logic; --- signal ctc_counter_0_trg : std_logic; - signal ctc_counter_0_do : std_logic_vector(7 downto 0); - signal ctc_counter_0_int : std_logic; + signal ctc_ce : std_logic; + signal ctc_do : std_logic_vector(7 downto 0); + + signal ctc_counter_1_trg : std_logic; + signal ctc_counter_2_trg : std_logic; + signal ctc_counter_3_trg : std_logic; - signal ctc_counter_1_we : std_logic; --- signal ctc_counter_1_trg : std_logic; - signal ctc_counter_1_do : std_logic_vector(7 downto 0); - signal ctc_counter_1_int : std_logic; - - signal ctc_counter_2_we : std_logic; --- signal ctc_counter_2_trg : std_logic; - signal ctc_counter_2_do : std_logic_vector(7 downto 0); - signal ctc_counter_2_int : std_logic; - - signal ctc_counter_3_we : std_logic; - signal ctc_counter_3_trg : std_logic; - signal ctc_counter_3_do : std_logic_vector(7 downto 0); - signal ctc_counter_3_int : std_logic; - -- signal cpu_rom_do : std_logic_vector( 7 downto 0); - + signal wram_we : std_logic; signal wram_do : std_logic_vector( 7 downto 0); @@ -413,6 +397,10 @@ begin else vs_cnt <= vs_cnt +1; end if; + + if vcnt = 240 then video_vs <= '0'; end if; + if vcnt = 242 then video_vs <= '1'; end if; + else hs_cnt <= hs_cnt + 1; end if; @@ -422,8 +410,8 @@ begin vcnt >= 1 and vcnt < 241 then video_blankn <= '1';end if; - if hs_cnt = 0 then hsync0 <= '0'; - elsif hs_cnt = 47 then hsync0 <= '1'; + if hs_cnt = 0 then hsync0 <= '0'; video_hs <= '0'; + elsif hs_cnt = 47 then hsync0 <= '1'; video_hs <= '1'; end if; if hs_cnt = 0 then hsync1 <= '0'; @@ -492,24 +480,16 @@ cpu_di <= cpu_rom_do when cpu_mreq_n = '0' and cpu_addr(15 downto 12) < X"7" wram_do when cpu_mreq_n = '0' and cpu_addr(15 downto 12) = X"7" else -- 7000-7FFF sp_ram_cache_do when cpu_mreq_n = '0' and cpu_addr(15 downto 9) = "1111000" else -- sprite ram 0xF000-0xF1FF bg_ram_do when cpu_mreq_n = '0' and cpu_addr(15 downto 10) = "111111" else -- video ram 0xFC00-0xFFFF - ctc_controler_do when cpu_ioreq_n = '0' and cpu_m1_n = '0' else -- ctc ctrl (interrupt vector) + ctc_do when cpu_int_ack_n = '0' or ctc_ce = '1' else -- ctc (interrupt vector or counter data) ssio_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 4) = X"0" else - ctc_counter_3_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F3" else - ctc_counter_2_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F2" else - ctc_counter_1_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F1" else - ctc_counter_0_do when cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else X"FF"; ------------------------------------------------------------------------ -- Misc registers : ctc write enable / interrupt acknowledge ------------------------------------------------------------------------ -ctc_counter_3_trg <= '1' when (vcnt = 246 and tv15Khz_mode = '1') or (vcnt = 493 and tv15Khz_mode = '0')else '0'; -ctc_counter_3_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F3" else '0'; -ctc_counter_2_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F2" else '0'; -ctc_counter_1_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F1" else '0'; -ctc_counter_0_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else '0'; -ctc_controler_we <= '1' when cpu_wr_n = '0' and cpu_ioreq_n = '0' and cpu_addr(7 downto 0) = X"F0" else '0'; -- only channel 0 receive int vector -ctc_int_ack <= '1' when cpu_ioreq_n = '0' and cpu_m1_n = '0' else '0'; +cpu_int_ack_n <= cpu_ioreq_n or cpu_m1_n; +ctc_ce <= '1' when cpu_ioreq_n = '0' and cpu_addr(7 downto 4) = x"F" else '0'; +ctc_counter_3_trg <= '1' when top_frame = '1' and ((vcnt = 246 and tv15Khz_mode = '1') or (vcnt = 493 and tv15Khz_mode = '0')) else '0'; ------------------------------------------ -- write enable / ram access from CPU -- @@ -706,92 +686,28 @@ port map( DO => cpu_do ); --- CTC interrupt controler Z80-CTC (MK3882) -ctc_controler : entity work.ctc_controler -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_controler_we, - int_ack => ctc_int_ack, - - int_pulse_0 => ctc_counter_0_int, - int_pulse_1 => ctc_counter_1_int, - int_pulse_2 => ctc_counter_2_int, - int_pulse_3 => ctc_counter_3_int, - - d_out => ctc_controler_do, - int_n => cpu_irq_n -); - -ctc_counter_0 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_0_we, - - clk_trg => '0', - - d_out => ctc_counter_0_do, - zc_to => open, -- zc/to #0 (pin 7) connected to clk_trg #1 (pin 22) on schematics (seems to be not used) - int_pulse => ctc_counter_0_int - -); - -ctc_counter_1 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_1_we, - - clk_trg => '0', - - d_out => ctc_counter_1_do, - zc_to => open, - int_pulse => ctc_counter_1_int - -); - -ctc_counter_2 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_2_we, - - clk_trg => '0', - - d_out => ctc_counter_2_do, - zc_to => open, - int_pulse => ctc_counter_2_int - -); - -ctc_counter_3 : entity work.ctc_counter -port map( - clock => clock_vid, - clock_ena => cpu_ena, - reset => reset, - - d_in => cpu_do, - load_data => ctc_counter_3_we, - - clk_trg => ctc_counter_3_trg, - - d_out => ctc_counter_3_do, - zc_to => open, - int_pulse => ctc_counter_3_int - +-- Z80-CTC (MK3882) +z80ctc : entity work.z80ctc_top +port map ( + clock => clock_vid, + clock_ena => cpu_ena, + reset => reset, + din => cpu_do, + cpu_din => cpu_di, + dout => ctc_do, + ce_n => not ctc_ce, + cs => cpu_addr(1 downto 0), + m1_n => cpu_m1_n, + iorq_n => cpu_ioreq_n, + rd_n => cpu_rd_n, + int_n => cpu_irq_n, + trg0 => '0', + to0 => ctc_counter_1_trg, + trg1 => ctc_counter_1_trg, + to1 => open, + trg2 => '0', + to2 => open, + trg3 => ctc_counter_3_trg ); -- cpu program ROM 0x0000-0x6FFF diff --git a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/ctc_controler.vhd b/common/IO/Z80CTC/ctc_controler.vhd similarity index 63% rename from Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/ctc_controler.vhd rename to common/IO/Z80CTC/ctc_controler.vhd index 1ff9961d..d7aa41ba 100644 --- a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/ctc_controler.vhd +++ b/common/IO/Z80CTC/ctc_controler.vhd @@ -12,11 +12,12 @@ port( clock : in std_logic; clock_ena : in std_logic; reset : in std_logic; - + d_in : in std_logic_vector( 7 downto 0); load_data : in std_logic; int_ack : in std_logic; - + int_end : in std_logic; -- RETI detected + int_pulse_0 : in std_logic; int_pulse_1 : in std_logic; int_pulse_2 : in std_logic; @@ -24,14 +25,13 @@ port( d_out : out std_logic_vector( 7 downto 0); int_n : out std_logic - ); end ctc_controler; architecture struct of ctc_controler is signal int_vector : std_logic_vector(4 downto 0); - + signal wait_for_time_constant : std_logic; signal load_data_r : std_logic; -- make sure load_data toggles to get one new data @@ -39,18 +39,21 @@ architecture struct of ctc_controler is signal int_reg_1 : std_logic; signal int_reg_2 : std_logic; signal int_reg_3 : std_logic; - + + signal int_in_service : std_logic_vector(3 downto 0); + signal int_ack_r : std_logic; + signal int_end_r : std_logic; begin - + int_n <= '0' when (int_reg_0 or int_reg_1 or int_reg_2 or int_reg_3) = '1' else '1'; d_out <= int_vector & "000" when int_reg_0 = '1' else int_vector & "010" when int_reg_1 = '1' else int_vector & "100" when int_reg_2 = '1' else int_vector & "110" when int_reg_3 = '1' else (others => '0'); - + process (reset, clock) begin @@ -60,17 +63,19 @@ begin int_reg_1 <= '0'; int_reg_2 <= '0'; int_reg_3 <= '0'; - load_data_r <= load_data; + int_in_service <= (others => '0'); + load_data_r <= '0'; int_vector <= (others => '0'); - else + else if rising_edge(clock) then if clock_ena = '1' then - + load_data_r <= load_data; int_ack_r <= int_ack; - + int_end_r <= int_end; + if load_data = '1' and load_data_r = '0' then - + if wait_for_time_constant = '1' then wait_for_time_constant <= '0'; else @@ -78,26 +83,35 @@ begin wait_for_time_constant <= d_in(2); -- if d_in(1) = '1' then -- software reset -- wait_for_time_constant <= '0'; --- end if; +-- end if; else -- its an interrupt vector int_vector <= d_in(7 downto 3); - end if; + end if; end if; end if; - - if int_pulse_0 = '1' then int_reg_0 <= '1'; end if; - if int_pulse_1 = '1' then int_reg_1 <= '1'; end if; - if int_pulse_2 = '1' then int_reg_2 <= '1'; end if; - if int_pulse_3 = '1' then int_reg_3 <= '1'; end if; - if int_ack_r = '1' and int_ack = '0' then - if int_reg_0 = '1' then int_reg_0 <= '0'; - elsif int_reg_1 = '1' then int_reg_1 <= '0'; - elsif int_reg_2 = '1' then int_reg_2 <= '0'; - elsif int_reg_3 = '1' then int_reg_3 <= '0'; end if; + if int_pulse_0 = '1' and int_in_service(0) = '0' then int_reg_0 <= '1'; end if; + if int_pulse_1 = '1' and int_in_service(1 downto 0) = "00" then int_reg_1 <= '1'; end if; + if int_pulse_2 = '1' and int_in_service(2 downto 0) = "000" then int_reg_2 <= '1'; end if; + if int_pulse_3 = '1' and int_in_service(3 downto 0) = "0000" then int_reg_3 <= '1'; end if; + + if int_ack_r = '0' and int_ack = '1' then + if int_reg_0 = '1' then int_reg_0 <= '0'; int_in_service(0) <= '1'; + elsif int_reg_1 = '1' then int_reg_1 <= '0'; int_in_service(1) <= '1'; + elsif int_reg_2 = '1' then int_reg_2 <= '0'; int_in_service(2) <= '1'; + elsif int_reg_3 = '1' then int_reg_3 <= '0'; int_in_service(3) <= '1'; + end if; end if; - + + if int_end_r = '0' and int_end = '1' then + if int_in_service(0) = '1' then int_in_service(0) <= '0'; + elsif int_in_service(1) = '1' then int_in_service(1) <= '0'; + elsif int_in_service(2) = '1' then int_in_service(2) <= '0'; + elsif int_in_service(3) = '1' then int_in_service(3) <= '0'; + end if; + end if; + end if; end if; end if; diff --git a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/ctc_counter.vhd b/common/IO/Z80CTC/ctc_counter.vhd similarity index 82% rename from Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/ctc_counter.vhd rename to common/IO/Z80CTC/ctc_counter.vhd index 25f9a797..58409ca2 100644 --- a/Arcade_MiST/Midway MCR 1/Kickman_MiST/rtl/ctc_counter.vhd +++ b/common/IO/Z80CTC/ctc_counter.vhd @@ -12,16 +12,16 @@ port( clock : in std_logic; clock_ena : in std_logic; reset : in std_logic; - + d_in : in std_logic_vector( 7 downto 0); load_data : in std_logic; - - clk_trg : in std_logic; - + + clk_trg : in std_logic; + d_out : out std_logic_vector(7 downto 0); zc_to : out std_logic; int_pulse : out std_logic - + ); end ctc_counter; @@ -35,30 +35,30 @@ architecture struct of ctc_counter is signal prescale_max : std_logic_vector(7 downto 0); signal prescale_in : std_logic_vector(7 downto 0) := (others => '0'); - signal count_max : std_logic_vector(8 downto 0); - signal count_in : std_logic_vector(8 downto 0) := (others => '0'); + signal count_max : std_logic_vector(7 downto 0); + signal count_in : std_logic_vector(7 downto 0) := (others => '0'); signal zc_to_in : std_logic; + signal clk_trg_in : std_logic; signal clk_trg_r : std_logic; signal trigger : std_logic; signal count_ena : std_logic; signal load_data_r : std_logic; -- make sure load_data toggles to get one new data - + begin prescale_max <= (others => '0') when control_word(6) = '1' else -- counter mode (prescale max = 0) X"0F" when control_word(6 downto 5) = "00" else -- timer mode prescale 16 X"FF"; -- timer mode prescale 256 - -trigger <= - '1' when (clk_trg = '0' and clk_trg_r = '1' and control_word(4) = '0') or -- falling edge - (clk_trg = '1' and clk_trg_r = '0' and control_word(4) = '1') else '0'; -- rising edge - + +clk_trg_in <= clk_trg xor control_word(4); +trigger <= '1' when clk_trg_in = '0' and clk_trg_r = '1' else '0'; + d_out <= count_in(7 downto 0); zc_to <= zc_to_in; int_pulse <= zc_to_in when control_word(7) = '1' else '0'; - + process (reset, clock) begin @@ -70,34 +70,29 @@ begin restart_on_next_trigger <= '0'; count_in <= (others=> '0'); zc_to_in <= '0'; - clk_trg_r <= clk_trg; - else + clk_trg_r <= '0'; + else if rising_edge(clock) then if clock_ena = '1' then - clk_trg_r <= clk_trg; + clk_trg_r <= clk_trg_in; load_data_r <= load_data; - - if (restart_on_next_trigger = '1' and trigger = '1') or (restart_on_next_clock = '1') then + + if (restart_on_next_trigger = '1' and trigger = '1') or (restart_on_next_clock = '1') then restart_on_next_clock <= '0'; restart_on_next_trigger <= '0'; count_ena <= '1'; count_in <= count_max; prescale_in <= prescale_max; end if; - + if load_data = '1' and load_data_r = '0' then if wait_for_time_constant = '1' then wait_for_time_constant <= '0'; time_constant_loaded <= '1'; - - if d_in = X"00" then - count_max <= '1'&X"00"; - else - count_max <= '0'&d_in; - end if; - + count_max <= d_in; + if control_word(6) = '0' and count_ena = '0' then -- in timer mode, if count was stooped if control_word(3) = '0' then -- auto start when time_constant loaded restart_on_next_clock <= '1'; @@ -105,15 +100,19 @@ begin restart_on_next_trigger <= '1'; end if; end if; - + if control_word(6) = '1' then -- in trigger mode reload the counter immediately, + -- otherwise the first period will undefined + prescale_in <= (others => '0'); + count_in <= d_in; + end if; else -- not waiting for time constant - + if d_in(0) = '1' then -- check if its a control world control_word <= d_in; wait_for_time_constant <= d_in(2); restart_on_next_clock <= '0'; restart_on_next_trigger <= '0'; - + if d_in(1) = '1' then -- software reset count_ena <= '0'; time_constant_loaded <= '0'; @@ -122,28 +121,28 @@ begin clk_trg_r <= clk_trg; end if; end if; - + end if; - + end if; -- end load data - + -- counter zc_to_in <= '0'; if ((control_word(6) = '1' and trigger = '1' ) or - (control_word(6) = '0' and count_ena = '1') ) and time_constant_loaded = '1' then + (control_word(6) = '0' and count_ena = '1') ) and time_constant_loaded = '1' then if prescale_in = 0 then - prescale_in <= '0'&prescale_max(7 downto 1); -- test divide by 2 ! - if count_in = 0 then + prescale_in <= prescale_max; + if count_in = 1 then zc_to_in <= '1'; count_in <= count_max; else - count_in <= count_in - '1'; + count_in <= count_in - '1'; end if; else prescale_in <= prescale_in - '1'; end if; end if; - + end if; end if; end if; diff --git a/common/IO/Z80CTC/z80ctc.qip b/common/IO/Z80CTC/z80ctc.qip new file mode 100644 index 00000000..6a3ed4fd --- /dev/null +++ b/common/IO/Z80CTC/z80ctc.qip @@ -0,0 +1,4 @@ +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) z80ctc_top.vhd ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ctc_controler.vhd ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ctc_counter.vhd ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) z80ctc_top.vhd ] diff --git a/common/IO/Z80CTC/z80ctc_top.vhd b/common/IO/Z80CTC/z80ctc_top.vhd new file mode 100644 index 00000000..b9efaca9 --- /dev/null +++ b/common/IO/Z80CTC/z80ctc_top.vhd @@ -0,0 +1,185 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +-- Z80-CTC (MK3882) top-level +entity z80ctc_top is +port( + clock : in std_logic; + clock_ena : in std_logic; + reset : in std_logic; + + din : in std_logic_vector(7 downto 0); + dout : out std_logic_vector(7 downto 0); + cpu_din : in std_logic_vector(7 downto 0); -- mirror the input to the cpu, for RETI detection + + ce_n : in std_logic; + cs : in std_logic_vector(1 downto 0); + m1_n : in std_logic; + iorq_n : in std_logic; + rd_n : in std_logic; + int_n : out std_logic; + + trg0 : in std_logic; + to0 : out std_logic; + + trg1 : in std_logic; + to1 : out std_logic; + + trg2 : in std_logic; + to2 : out std_logic; + + trg3 : in std_logic + ); +end z80ctc_top; + +architecture struct of z80ctc_top is + + signal cpu_int_ack_n : std_logic; + + signal ctc_controler_we : std_logic; + signal ctc_controler_do : std_logic_vector(7 downto 0); + signal ctc_int_ack : std_logic; + signal ctc_int_ack_phase : std_logic_vector(1 downto 0); + + signal ctc_counter_0_we : std_logic; + signal ctc_counter_0_do : std_logic_vector(7 downto 0); + signal ctc_counter_0_int : std_logic; + + signal ctc_counter_1_we : std_logic; + signal ctc_counter_1_do : std_logic_vector(7 downto 0); + signal ctc_counter_1_int : std_logic; + + signal ctc_counter_2_we : std_logic; + signal ctc_counter_2_do : std_logic_vector(7 downto 0); + signal ctc_counter_2_int : std_logic; + + signal ctc_counter_3_we : std_logic; + signal ctc_counter_3_do : std_logic_vector(7 downto 0); + signal ctc_counter_3_int : std_logic; + +begin + +process (clock, reset) +begin + if reset = '1' then + ctc_int_ack_phase <= "00"; + elsif rising_edge(clock) then + -- decode ED4D (reti) + if clock_ena = '1' and rd_n = '0' and m1_n = '0' then + case ctc_int_ack_phase is + when "00" => if cpu_din = x"ED" then ctc_int_ack_phase <= "01"; end if; + when "01" => if cpu_din = x"4D" then ctc_int_ack_phase <= "11"; elsif cpu_din /= x"ED" then ctc_int_ack_phase <= "00"; end if; + when "11" => if cpu_din = x"ED" then ctc_int_ack_phase <= "01"; elsif cpu_din /= x"4D" then ctc_int_ack_phase <= "00"; end if; + when others => ctc_int_ack_phase <= "00"; + end case; + end if; + end if; +end process; + +ctc_int_ack <= '1' when ctc_int_ack_phase = "11" else '0'; +cpu_int_ack_n <= iorq_n or m1_n; + +ctc_controler_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "00" else '0'; +ctc_counter_0_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "00" else '0'; +ctc_counter_1_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "01" else '0'; +ctc_counter_2_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "10" else '0'; +ctc_counter_3_we <= '1' when ce_n = '0' and iorq_n = '0' and m1_n = '1' and rd_n = '1' and cs = "11" else '0'; + +dout <= ctc_controler_do when cpu_int_ack_n = '0' else + ctc_counter_0_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "00" else + ctc_counter_1_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "01" else + ctc_counter_2_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "10" else + ctc_counter_3_do when iorq_n = '0' and m1_n = '1' and rd_n = '0' and cs = "11" else + x"FF"; + +-- CTC interrupt controler Z80-CTC (MK3882) +ctc_controler : entity work.ctc_controler +port map( + clock => clock, + clock_ena => clock_ena, + reset => reset, + + d_in => din, + load_data => ctc_controler_we, + int_ack => cpu_int_ack_n, + int_end => ctc_int_ack, + + int_pulse_0 => ctc_counter_0_int, + int_pulse_1 => ctc_counter_1_int, + int_pulse_2 => ctc_counter_2_int, + int_pulse_3 => ctc_counter_3_int, + + d_out => ctc_controler_do, + int_n => int_n +); + +ctc_counter_0 : entity work.ctc_counter +port map( + clock => clock, + clock_ena => clock_ena, + reset => reset, + + d_in => din, + load_data => ctc_counter_0_we, + + clk_trg => trg0, + + d_out => ctc_counter_0_do, + zc_to => to0, + int_pulse => ctc_counter_0_int + +); + +ctc_counter_1 : entity work.ctc_counter +port map( + clock => clock, + clock_ena => clock_ena, + reset => reset, + + d_in => din, + load_data => ctc_counter_1_we, + + clk_trg => trg1, + + d_out => ctc_counter_1_do, + zc_to => to1, + int_pulse => ctc_counter_1_int + +); + +ctc_counter_2 : entity work.ctc_counter +port map( + clock => clock, + clock_ena => clock_ena, + reset => reset, + + d_in => din, + load_data => ctc_counter_2_we, + + clk_trg => trg2, + + d_out => ctc_counter_2_do, + zc_to => to2, + int_pulse => ctc_counter_2_int + +); + +ctc_counter_3 : entity work.ctc_counter +port map( + clock => clock, + clock_ena => clock_ena, + reset => reset, + + d_in => din, + load_data => ctc_counter_3_we, + + clk_trg => trg3, + + d_out => ctc_counter_3_do, + zc_to => open, + int_pulse => ctc_counter_3_int + +); +end struct;