diff --git a/common/mist/arcade_inputs.v b/common/mist/arcade_inputs.v index 9770913e..30aff5a9 100644 --- a/common/mist/arcade_inputs.v +++ b/common/mist/arcade_inputs.v @@ -31,15 +31,30 @@ module arcade_inputs( output [19:0] player4 ); +// joystick button indices for special functions 0 - no joystick button assigned +parameter COIN1 = 0; +parameter COIN2 = 0; +parameter START1 = 0; +parameter START2 = 0; +parameter START3 = 0; +parameter START4 = 0; + assign controls = { btn_tilt, - btn_coin | btn_coin4_mame, btn_coin | btn_coin3_mame, btn_coin | btn_coin2_mame, btn_coin | btn_coin1_mame, - btn_four_players | btn_start4_mame, btn_three_players | btn_start3_mame, btn_two_players | btn_start2_mame, btn_one_player | btn_start1_mame }; + btn_coin | btn_coin4_mame, btn_coin | btn_coin3_mame, btn_coin | btn_coin2_mame | joy_coin2, btn_coin | btn_coin1_mame | joy_coin1, + btn_four_players | btn_start4_mame | joy_start4, btn_three_players | btn_start3_mame | joy_start3, btn_two_players | btn_start2_mame | joy_start2, btn_one_player | btn_start1_mame | joy_start1 }; wire [19:0] joy0 = joyswap ? joystick_1 : joystick_0; wire [19:0] joy1 = joyswap ? joystick_0 : joystick_1; wire [19:0] joy2 = joystick_2; wire [19:0] joy3 = joystick_3; +wire joy_coin1 = (COIN1 == 0) ? 1'b0 : (joy0[COIN1] | joy1[COIN1] | joy2[COIN1] | joy3[COIN1]); +wire joy_coin2 = (COIN2 == 0) ? 1'b0 : (joy0[COIN2] | joy1[COIN2] | joy2[COIN2] | joy3[COIN2]); +wire joy_start1 = (START1 == 0) ? 1'b0 : (joy0[START1] | joy1[START1] | joy2[START1] | joy3[START1]); +wire joy_start2 = (START2 == 0) ? 1'b0 : (joy0[START2] | joy1[START2] | joy2[START2] | joy3[START2]); +wire joy_start3 = (START3 == 0) ? 1'b0 : (joy0[START3] | joy1[START3] | joy2[START3] | joy3[START3]); +wire joy_start4 = (START4 == 0) ? 1'b0 : (joy0[START4] | joy1[START4] | joy2[START4] | joy3[START4]); + wire [19:0] p1; wire [19:0] p2; wire [19:0] p3; diff --git a/common/mist/mist.vhd b/common/mist/mist.vhd index 2255c8b7..10d8af49 100644 --- a/common/mist/mist.vhd +++ b/common/mist/mist.vhd @@ -90,7 +90,8 @@ generic ( SD_HCNT_WIDTH: integer := 9; COLOR_DEPTH : integer := 6; OSD_AUTO_CE : boolean := true; - SYNC_AND : boolean := false + SYNC_AND : boolean := false; + USE_BLANKS : boolean := false ); port ( clk_sys : in std_logic; @@ -107,6 +108,8 @@ port ( no_csync : in std_logic := '0'; blend : in std_logic := '0'; + HBlank : in std_logic := '0'; + VBlank : in std_logic := '0'; HSync : in std_logic; VSync : in std_logic; R : in std_logic_vector(COLOR_DEPTH-1 downto 0); diff --git a/common/mist/mist_audio.v b/common/mist/mist_audio.v deleted file mode 100644 index 9006e7e1..00000000 --- a/common/mist/mist_audio.v +++ /dev/null @@ -1,36 +0,0 @@ -module mist_audio -( - input clk, - input reset_n, - input [BITS-1:0] audio_inL, - input [BITS-1:0] audio_inR, - output AUDIO_L, - output AUDIO_R -); - -parameter BITS = 16; -parameter STEREO = 0; -parameter SIGNED = 0; - -wire [BITS-1:0] aud_left = ~SIGNED ? audio_inL : {~audio_inL[BITS-1],audio_inL[BITS-2:0]}; -wire [BITS-1:0] aud_right = STEREO ? ~SIGNED ? audio_inR : {~audio_inR[BITS-1],audio_inR[BITS-2:0]} : aud_left; - -dac #( - .C_bits(BITS)) -dacl( - .clk_i(clk), - .res_n_i(reset_n), - .dac_i(aud_left), - .dac_o(AUDIO_L) - ); - -dac #( - .C_bits(BITS)) -dacr( - .clk_i(clk), - .res_n_i(reset_n), - .dac_i(aud_right), - .dac_o(AUDIO_R) - ); - -endmodule diff --git a/common/mist/mist_video.v b/common/mist/mist_video.v index 712b1dff..7e90f157 100644 --- a/common/mist/mist_video.v +++ b/common/mist/mist_video.v @@ -35,6 +35,8 @@ module mist_video input [COLOR_DEPTH-1:0] G, input [COLOR_DEPTH-1:0] B, + input HBlank, + input VBlank, input HSync, input VSync, @@ -53,12 +55,15 @@ parameter SD_HCNT_WIDTH = 9; parameter COLOR_DEPTH = 6; // 1-6 parameter OSD_AUTO_CE = 1'b1; parameter SYNC_AND = 1'b0; // 0 - XOR, 1 - AND +parameter USE_BLANKS = 1'b0; // Honor H/VBlank signals? wire [5:0] SD_R_O; wire [5:0] SD_G_O; wire [5:0] SD_B_O; wire SD_HS_O; wire SD_VS_O; +wire SD_HB_O; +wire SD_VB_O; wire pixel_ena; @@ -69,11 +74,15 @@ scandoubler #(SD_HCNT_WIDTH, COLOR_DEPTH) scandoubler .ce_divider ( ce_divider ), .scanlines ( scanlines ), .pixel_ena ( pixel_ena ), + .hb_in ( HBlank ), + .vb_in ( VBlank ), .hs_in ( HSync ), .vs_in ( VSync ), .r_in ( R ), .g_in ( G ), .b_in ( B ), + .hb_out ( SD_HB_O ), + .vb_out ( SD_VB_O ), .hs_out ( SD_HS_O ), .vs_out ( SD_VS_O ), .r_out ( SD_R_O ), @@ -85,7 +94,7 @@ wire [5:0] osd_r_o; wire [5:0] osd_g_o; wire [5:0] osd_b_o; -osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR, OSD_AUTO_CE) osd +osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR, OSD_AUTO_CE, USE_BLANKS) osd ( .clk_sys ( clk_sys ), .rotate ( rotate ), @@ -96,6 +105,8 @@ osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR, OSD_AUTO_CE) osd .R_in ( SD_R_O ), .G_in ( SD_G_O ), .B_in ( SD_B_O ), + .HBlank ( SD_HB_O ), + .VBlank ( SD_VB_O ), .HSync ( SD_HS_O ), .VSync ( SD_VS_O ), .R_out ( osd_r_o ), @@ -110,7 +121,7 @@ cofi #(6) cofi ( .clk ( clk_sys ), .pix_ce ( pixel_ena ), .enable ( blend ), - .hblank ( ~SD_HS_O ), + .hblank ( USE_BLANKS ? SD_HB_O : ~SD_HS_O ), .hs ( SD_HS_O ), .vs ( SD_VS_O ), .red ( osd_r_o ), diff --git a/common/mist/osd.v b/common/mist/osd.v index 00e2f77e..e7b769e7 100644 --- a/common/mist/osd.v +++ b/common/mist/osd.v @@ -18,6 +18,8 @@ module osd ( input [5:0] R_in, input [5:0] G_in, input [5:0] B_in, + input HBlank, + input VBlank, input HSync, input VSync, @@ -31,6 +33,7 @@ parameter OSD_X_OFFSET = 11'd0; parameter OSD_Y_OFFSET = 11'd0; parameter OSD_COLOR = 3'd0; parameter OSD_AUTO_CE = 1'b1; +parameter USE_BLANKS = 1'b0; localparam OSD_WIDTH = 11'd256; localparam OSD_HEIGHT = 11'd128; @@ -89,13 +92,13 @@ end reg [10:0] h_cnt; reg [10:0] hs_low, hs_high; wire hs_pol = hs_high < hs_low; -wire [10:0] dsp_width = hs_pol ? hs_low : hs_high; +wire [10:0] dsp_width = (hs_pol & !USE_BLANKS) ? hs_low : hs_high; // vertical counter reg [10:0] v_cnt; reg [10:0] vs_low, vs_high; wire vs_pol = vs_high < vs_low; -wire [10:0] dsp_height = vs_pol ? vs_low : vs_high; +wire [10:0] dsp_height = (vs_pol & !USE_BLANKS) ? vs_low : vs_high; wire doublescan = (dsp_height>350); @@ -134,38 +137,53 @@ always @(posedge clk_sys) begin reg vsD; if(ce_pix) begin - // bring hsync into local clock domain - hsD <= HSync; - - // falling edge of HSync - if(!HSync && hsD) begin - h_cnt <= 0; - hs_high <= h_cnt; - end - - // rising edge of HSync - else if(HSync && !hsD) begin - h_cnt <= 0; - hs_low <= h_cnt; - v_cnt <= v_cnt + 1'd1; - end else begin + if (USE_BLANKS) begin h_cnt <= h_cnt + 1'd1; - end + if(HBlank) begin + h_cnt <= 0; + if (h_cnt != 0) begin + hs_high <= h_cnt; + v_cnt <= v_cnt + 1'd1; + end + end + if(VBlank) begin + v_cnt <= 0; + if (v_cnt != 0 && vs_high != v_cnt + 1'd1) vs_high <= v_cnt; + end + end else begin + // bring hsync into local clock domain + hsD <= HSync; - vsD <= VSync; + // falling edge of HSync + if(!HSync && hsD) begin + h_cnt <= 0; + hs_high <= h_cnt; + end - // falling edge of VSync - if(!VSync && vsD) begin - v_cnt <= 0; - // if the difference is only one line, that might be interlaced picture - if (vs_high != v_cnt + 1'd1) vs_high <= v_cnt; - end + // rising edge of HSync + else if(HSync && !hsD) begin + h_cnt <= 0; + hs_low <= h_cnt; + v_cnt <= v_cnt + 1'd1; + end else begin + h_cnt <= h_cnt + 1'd1; + end - // rising edge of VSync - else if(VSync && !vsD) begin - v_cnt <= 0; - // if the difference is only one line, that might be interlaced picture - if (vs_low != v_cnt + 1'd1) vs_low <= v_cnt; + vsD <= VSync; + + // falling edge of VSync + if(!VSync && vsD) begin + v_cnt <= 0; + // if the difference is only one line, that might be interlaced picture + if (vs_high != v_cnt + 1'd1) vs_high <= v_cnt; + end + + // rising edge of VSync + else if(VSync && !vsD) begin + v_cnt <= 0; + // if the difference is only one line, that might be interlaced picture + if (vs_low != v_cnt + 1'd1) vs_low <= v_cnt; + end end end end @@ -203,8 +221,8 @@ always @(posedge clk_sys) begin osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]]; osd_de <= osd_enable && - (HSync != hs_pol) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) && - (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); + ((USE_BLANKS && !HBlank) || (!USE_BLANKS && HSync != hs_pol)) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) && + ((USE_BLANKS && !VBlank) || (!USE_BLANKS && VSync != vs_pol)) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); end end diff --git a/common/mist/scandoubler.v b/common/mist/scandoubler.v index 8c54632b..8f98ff8e 100644 --- a/common/mist/scandoubler.v +++ b/common/mist/scandoubler.v @@ -43,6 +43,8 @@ module scandoubler input [1:0] scanlines, // shifter video interface + input hb_in, + input vb_in, input hs_in, input vs_in, input [COLOR_DEPTH-1:0] r_in, @@ -50,6 +52,8 @@ module scandoubler input [COLOR_DEPTH-1:0] b_in, // output interface + output hb_out, + output vb_out, output hs_out, output vs_out, output [5:0] r_out, @@ -68,13 +72,7 @@ reg [5:0] r; reg [5:0] g; reg [5:0] b; -wire [5:0] r_o; -wire [5:0] g_o; -wire [5:0] b_o; -reg hs_o; -reg vs_o; - -wire [COLOR_DEPTH*3-1:0] sd_mux = bypass ? {r_in, g_in, b_in} : sd_out; +wire [COLOR_DEPTH*3-1:0] sd_mux = bypass ? {r_in, g_in, b_in} : sd_out[COLOR_DEPTH*3-1:0]; always @(*) begin if (COLOR_DEPTH == 6) begin @@ -129,16 +127,21 @@ always @(posedge clk_sys) begin end end -assign r_o = r_mul[11:6]; -assign g_o = g_mul[11:6]; -assign b_o = b_mul[11:6]; - +wire [5:0] r_o = r_mul[11:6]; +wire [5:0] g_o = g_mul[11:6]; +wire [5:0] b_o = b_mul[11:6]; +wire hb_o = hb_sd; +wire vb_o = vb_sd; +reg hs_o; +reg vs_o; // Output multiplexing - -assign r_out = bypass ? r : r_o; -assign g_out = bypass ? g : g_o; -assign b_out = bypass ? b : b_o; +wire blank_out = hb_out | vb_out; +assign r_out = blank_out ? {COLOR_DEPTH{1'b0}} : bypass ? r : r_o; +assign g_out = blank_out ? {COLOR_DEPTH{1'b0}} : bypass ? g : g_o; +assign b_out = blank_out ? {COLOR_DEPTH{1'b0}} : bypass ? b : b_o; +assign hb_out = bypass ? hb_in : hb_o; +assign vb_out = bypass ? vb_in : vb_o; assign hs_out = bypass ? hs_in : hs_o; assign vs_out = bypass ? vs_in : vs_o; @@ -146,14 +149,14 @@ assign pixel_ena = bypass ? ce_x1 : ce_x2; // scan doubler output register -reg [COLOR_DEPTH*3-1:0] sd_out; +reg [3+COLOR_DEPTH*3-1:0] sd_out; // ================================================================== // ======================== the line buffers ======================== // ================================================================== // 2 lines of 2**HCNT_WIDTH pixels 3*COLOR_DEPTH bit RGB -(* ramstyle = "no_rw_check" *) reg [COLOR_DEPTH*3-1:0] sd_buffer[2*2**HCNT_WIDTH]; +(* ramstyle = "no_rw_check" *) reg [3+COLOR_DEPTH*3-1:0] sd_buffer[2*2**HCNT_WIDTH]; // use alternating sd_buffers when storing/reading data reg line_toggle; @@ -174,11 +177,13 @@ wire ce_x1 = (i_div == ce_divider_in); always @(posedge clk_sys) begin reg hsD, vsD; + reg vbD; // Pixel logic on x1 clkena if(ce_x1) begin hcnt <= hcnt + 1'd1; - sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in}; + vbD <= vb_in; + sd_buffer[{line_toggle, hcnt}] <= {vbD & ~vb_in, ~vbD & vb_in, hb_in, r_in, g_in, b_in}; end // Generate pixel clock @@ -217,7 +222,11 @@ end reg [HSCNT_WIDTH:0] sd_synccnt; reg [HCNT_WIDTH-1:0] sd_hcnt; -reg hs_sd; +reg vb_sd = 0; +wire vb_on = sd_out[COLOR_DEPTH*3+1]; +wire vb_off = sd_out[COLOR_DEPTH*3+2]; +reg hb_sd = 0; +reg hs_sd = 0; // Output pixel clock, aligned with output sync: reg [2:0] sd_i_div; @@ -234,14 +243,17 @@ always @(posedge clk_sys) begin // read data from line sd_buffer sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; + + if (vb_on) vb_sd <= 1; + if (vb_off) vb_sd <= 0; + hb_sd <= sd_out[COLOR_DEPTH*3]; end // Framing logic on sysclk sd_synccnt <= sd_synccnt + 1'd1; hsD <= hs_in; - if(hsD && !hs_in) sd_synccnt <= hs_max; - if(sd_synccnt == hs_max) begin + if(sd_synccnt == hs_max || (hsD && !hs_in)) begin sd_synccnt <= 0; sd_hcnt <= 0; end diff --git a/common/mist/sd_card.v b/common/mist/sd_card.v index 88fcbb30..a2493cf5 100644 --- a/common/mist/sd_card.v +++ b/common/mist/sd_card.v @@ -350,7 +350,10 @@ always@(posedge clk_sys) begin RD_STATE_DELAY: if(bit_cnt == 7) begin - if (delay_cnt == 0) begin + if (terminate_cmd) begin + read_state <= RD_STATE_IDLE; + cmd <= 0; + end else if (delay_cnt == 0) begin read_state <= RD_STATE_SEND_TOKEN; end else begin delay_cnt <= delay_cnt - 1'd1; diff --git a/common/mist/user_io.v b/common/mist/user_io.v index 05e114dd..80bf1a87 100644 --- a/common/mist/user_io.v +++ b/common/mist/user_io.v @@ -112,7 +112,6 @@ parameter FEATURES=0; // requested features from the firmware parameter ARCHIE=0; localparam W = $clog2(SD_IMAGES); -localparam PS2_FIFO_BITS = 4; reg [6:0] sbuf; reg [7:0] cmd;