From 02de244c4edde50f724cea8471bb1318901e3636 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Tue, 24 Mar 2020 12:11:45 +0100 Subject: [PATCH 1/2] Get rid of history.db, some Quartus garbage --- .gitignore | 2 +- .../IremM62 Hardware/rtl/history/history.db | Bin 12288 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 Arcade_MiST/IremM62 Hardware/rtl/history/history.db diff --git a/.gitignore b/.gitignore index 58fe2bf3..4526345e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ - build_id.v db +history.db greybox_tmp incremental_db output_files diff --git a/Arcade_MiST/IremM62 Hardware/rtl/history/history.db b/Arcade_MiST/IremM62 Hardware/rtl/history/history.db deleted file mode 100644 index d942bb0710005fb9508c6f2ea8e4cbff52e6b916..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI#Jxjwt7{KwnD83X*x^>8Mqk;y$gwJ zXUqSAdwKFC2lvbLr1PjYm0Gszm(r*!F%eRVTcv~$(vCelhH&}*kl5Ab+d_(q>+iAu zBRoG9e(Ha1`+zzE2q1s}0tg_000IagfB*vjM8L?yX%NWI8&f_v)qAzx)a|NYyjc?J zEL54ki$c{uR41cj8$@o`-)got}FKQyoZA zuNKwE=C!e1eNn!dw#$qD?BcTDxW4|#d5+yQaT9?60tg_000IagfB*srAb Date: Fri, 3 Apr 2020 16:53:52 +0200 Subject: [PATCH 2/2] Zaxxon: add sound (via samples), some updates --- .../Zaxxon_MiST/README.txt | 15 +- .../Zaxxon_MiST/Zaxxon.qsf | 3 +- .../Zaxxon_MiST/meta/Zaxxon.mra | 34 +++ .../Zaxxon_MiST/meta/Zaxxon_sound.mra | 16 ++ .../Zaxxon_MiST/rtl/Zaxxon_MiST.sv | 156 ++++++------ .../Zaxxon_MiST/rtl/sdram.sv | 28 ++- .../Zaxxon_MiST/rtl/zaxxon.vhd | 68 ++--- .../Zaxxon_MiST/rtl/zaxxon_sound.vhd | 237 ++++++++++++++++++ 8 files changed, 443 insertions(+), 114 deletions(-) create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon.mra create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon_sound.mra create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon_sound.vhd diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/README.txt b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/README.txt index a5d13113..29720a5d 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/README.txt +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/README.txt @@ -1,6 +1,17 @@ -- Zaxxon port to MiST --- no sound --- need ZAXXON.ROM on the SD Card +-- +-- Usage: +-- Create ZAXXON.ROM from MAME ROM zaxxon.zip file using the mra utility and the Zaxxon.mra file. +-- Example: mra -A -z /path/to/mame/roms Zaxxon.mra +-- Create the sound ROM file from MAME WAVE ROM zaxxon.zip (rename it to zaxxon_sample.zip) file +-- using the mra utility and the Zaxxon_sound.mra file. +-- Example: mra -A -z /path/to/mame/roms Zaxxon_sound.mra +-- Concatenate the zaxxon.rom and Zaxxound.rom into ZAXXON.ROM. +-- Copy the ZAXXON.ROM file to the root of the SD Card. +-- +-- Sound is optional, if you created the ROM with the samples, then enable sound in the OSD menu! +-- +-- MRA utilty: https://github.com/sebdel/mra-tools-c -- --------------------------------------------------------------------------------- -- DE10_lite Top level for Zaxxon by Dar (darfpga@aol.fr) (23/11/2019) diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/Zaxxon.qsf b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/Zaxxon.qsf index 9cdc4d54..41933ed8 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/Zaxxon.qsf +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/Zaxxon.qsf @@ -41,7 +41,7 @@ # ======================== set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL -set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26" set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" # Pin & Location Assignments @@ -217,6 +217,7 @@ set_global_assignment -name ENABLE_SIGNALTAP OFF set_global_assignment -name USE_SIGNALTAP_FILE output_files/zaxx.stp set_global_assignment -name SYSTEMVERILOG_FILE rtl/Zaxxon_MiST.sv set_global_assignment -name VHDL_FILE rtl/zaxxon.vhd +set_global_assignment -name VHDL_FILE rtl/zaxxon_sound.vhd set_global_assignment -name VERILOG_FILE rtl/pll_mist.v set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv set_global_assignment -name VHDL_FILE rtl/dpram.vhd diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon.mra b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon.mra new file mode 100644 index 00000000..0e85b305 --- /dev/null +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon.mra @@ -0,0 +1,34 @@ + + Zaxxon + 0193 + 202003290000 + 1982 + Sega/Gremlin + Isometric Shoot'em up + Space + zaxxon + zaxxon + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon_sound.mra b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon_sound.mra new file mode 100644 index 00000000..c24af3fa --- /dev/null +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/meta/Zaxxon_sound.mra @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/Zaxxon_MiST.sv b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/Zaxxon_MiST.sv index 5b38f7a8..3c584ec3 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/Zaxxon_MiST.sv +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/Zaxxon_MiST.sv @@ -38,8 +38,11 @@ localparam CONF_STR = { "O5,Blend,Off,On;", "O6,Flip,Off,On;", "O7,Service,Off,On;", + "O8,Sound,Off,On;", + "O9A,Lives,3,5,4,Free ships;", + "OBC,Extra ship,40k,20k,30k,10k;", "T0,Reset;", - "V,v1.0.",`BUILD_DATE + "V,v2.0.",`BUILD_DATE }; wire rotate = status[2]; @@ -47,6 +50,11 @@ wire [1:0] scanlines = status[4:3]; wire blend = status[5]; wire flip = status[6]; wire service = status[7]; +wire sound = status[8]; +wire [1:0] ships = ~status[10:9]; +wire [1:0] extraship = status[12:11]; + +wire [7:0] sw1 = {1'b0, sound, ships, 2'b11, extraship }; // cocktail(1) / sound(1) / ships(2) / N.U.(2) / extra ship (2) assign LED = ~ioctl_downl; assign SDRAM_CLK = clk_sd; @@ -67,9 +75,36 @@ wire [1:0] buttons; wire [1:0] switches; wire [7:0] joystick_0; wire [7:0] joystick_1; +wire key_pressed; +wire key_strobe; +wire [7:0] key_code; wire scandoublerD; wire ypbpr; -wire [15:0] audio_r,audio_l; +wire no_csync; + +user_io #( + .STRLEN(($size(CONF_STR)>>3))) +user_io( + .clk_sys (clk_sys ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +wire [15:0] audio_l; wire hs, vs, cs, hb, vb; wire blankn; wire [2:0] g, r; @@ -78,6 +113,8 @@ wire [14:0] rom_addr; wire [15:0] rom_do; wire [13:0] gfx_addr; wire [15:0] gfx_do; +wire [19:0] wave_addr; +wire [15:0] wave_do; wire ioctl_downl; wire [7:0] ioctl_index; wire ioctl_wr; @@ -87,7 +124,7 @@ wire [7:0] ioctl_dout; // ROM structure // 00000-06FFF CPU ROM 28k u27-u28-u29-u29-u29 // 07000-0EFFF Tiledata 32k u91-u90-u93-u92 -// 0FOOO-0F7FF char1 2k u68 +// 0F000-0F7FF char1 2k u68 // 0F800-0FFFF char2 2k u69 // 10000-05FFF bg 24k u113-u112-u111 // 16000-1BFFF spr 24k u77-u78-u79 @@ -109,7 +146,7 @@ data_io data_io( wire [24:0] gfx_ioctl_addr = ioctl_addr - 16'h7000; reg port1_req, port2_req; -sdram sdram( +sdram #(36) sdram( .*, .init_n ( pll_locked ), .clk ( clk_sd ), @@ -125,6 +162,8 @@ sdram sdram( .cpu1_addr ( ioctl_downl ? 16'hffff : {2'b00, rom_addr[14:1]}), .cpu1_q ( rom_do ), + .snd_addr ( wave_addr[19:1] + 16'he100 ), + .snd_q ( wave_do ), // port2 for gfx .port2_req ( port2_req ), @@ -161,6 +200,8 @@ always @(posedge clk_sd) begin reset <= status[0] | buttons[1] | ~rom_loaded; end +wire dl_wr = ioctl_wr && ioctl_addr < 17'h1c200; + zaxxon zaxxon( .clock_24(clk_sys), .reset(reset), @@ -172,31 +213,35 @@ zaxxon zaxxon( .video_hs(hs), .video_vs(vs), .video_csync(cs), - - .audio_out_r(audio_r), + .audio_out_l(audio_l), - .coin1(btn_coin), - .coin2(btn_coin), - .start2(btn_two_players), - .start1(btn_one_player), + .coin1(m_coin1), + .coin2(m_coin2), + .start2(m_two_players), + .start1(m_one_player), .left(m_left), .right(m_right), .up(m_up), .down(m_down), - .fire(m_fire), + .fire(m_fireA), .service(service), + .sw1_input(sw1), // cocktail(1) / sound(1) / ships(2) / N.U.(2) / extra ship (2) + .sw2_input(8'h33), // coin b(4) / coin a(4) -- "3" => 1c_1c + .flip_screen(flip), - .cpu_rom_addr ( rom_addr ), + .cpu_rom_addr ( rom_addr ), .cpu_rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ), - .map_addr ( gfx_addr ), - .map_do ( gfx_do ), + .map_addr ( gfx_addr ), + .map_do ( gfx_do ), + .wave_addr ( wave_addr ), + .wave_data ( wave_do ), .dl_addr ( ioctl_addr[16:0] ), .dl_data ( ioctl_dout ), - .dl_wr ( ioctl_wr ) + .dl_wr ( dl_wr ) ); mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video( @@ -219,74 +264,37 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video( .rotate ( {flip, rotate} ), .scandoubler_disable(scandoublerD ), .scanlines ( scanlines ), - .ypbpr ( ypbpr ) - ); - -user_io #( - .STRLEN(($size(CONF_STR)>>3))) -user_io( - .clk_sys (clk_sys ), - .conf_str (CONF_STR ), - .SPI_CLK (SPI_SCK ), - .SPI_SS_IO (CONF_DATA0 ), - .SPI_MISO (SPI_DO ), - .SPI_MOSI (SPI_DI ), - .buttons (buttons ), - .switches (switches ), - .scandoubler_disable (scandoublerD ), - .ypbpr (ypbpr ), - .key_strobe (key_strobe ), - .key_pressed (key_pressed ), - .key_code (key_code ), - .joystick_0 (joystick_0 ), - .joystick_1 (joystick_1 ), - .status (status ) + .ypbpr ( ypbpr ), + .no_csync ( no_csync ) ); dac #( .C_bits(16)) -dac_l( +dac( .clk_i(clk_sys), .res_n_i(1), - .dac_i(audio), + .dac_i(audio_l), .dac_o(AUDIO_L) ); -wire m_up = ~rotate ? (flip ? btn_left | joystick_0[1] | joystick_1[1] : btn_right | joystick_0[0] | joystick_1[0]) : btn_up | joystick_0[3] | joystick_1[3]; -wire m_down = ~rotate ? (flip ? btn_right | joystick_0[0] | joystick_1[0] : btn_left | joystick_0[1] | joystick_1[1]) : btn_down | joystick_0[2] | joystick_1[2]; -wire m_left = ~rotate ? (flip ? btn_down | joystick_0[2] | joystick_1[2] : btn_up | joystick_0[3] | joystick_1[3]) : btn_left | joystick_0[1] | joystick_1[1]; -wire m_right = ~rotate ? (flip ? btn_up | joystick_0[3] | joystick_1[3] : btn_down | joystick_0[2] | joystick_1[2]) : btn_right | joystick_0[0] | joystick_1[0]; -wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4]; +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 ( {flip, 1'b1} ), + .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/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/sdram.sv b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/sdram.sv index 2f65ee17..728abae6 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/sdram.sv +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/sdram.sv @@ -48,6 +48,8 @@ module sdram ( input [15:1] cpu1_addr, output reg [15:0] cpu1_q, + input [19:1] snd_addr, + output reg [15:0] snd_q, input port2_req, output reg port2_ack, @@ -61,6 +63,8 @@ module sdram ( output reg [15:0] gfx_q ); +parameter MHZ = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate + localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8 localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved @@ -70,8 +74,8 @@ localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single acc localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; -// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz -localparam RFRSH_CYCLES = 10'd842; +// 64ms/8192 rows = 7.8us +localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10; // --------------------------------------------------------------------- // ------------------------ cycle state machine ------------------------ @@ -147,16 +151,20 @@ assign SDRAM_nWE = sd_cmd[0]; reg [24:1] addr_latch[2]; reg [24:1] addr_latch_next[2]; -reg [15:1] addr_last[2]; +reg [19:1] addr_last[2]; reg [15:1] addr_last2[2]; reg [15:0] din_latch[2]; reg [1:0] oe_latch; reg [1:0] we_latch; reg [1:0] ds[2]; +reg port1_state; +reg port2_state; + localparam PORT_NONE = 2'd0; localparam PORT_CPU1 = 2'd1; -localparam PORT_REQ = 2'd2; +localparam PORT_SND = 2'd2; +localparam PORT_REQ = 2'd3; localparam PORT_GFX = 2'd1; @@ -172,12 +180,15 @@ always @(*) begin if (refresh) begin next_port[0] = PORT_NONE; addr_latch_next[0] = addr_latch[0]; - end else if (port1_req ^ port1_ack) begin + end else if (port1_req ^ port1_state) begin next_port[0] = PORT_REQ; addr_latch_next[0] = { 1'b0, port1_a }; end else if (cpu1_addr != addr_last[PORT_CPU1]) begin next_port[0] = PORT_CPU1; addr_latch_next[0] = { 9'd0, cpu1_addr }; + end else if (snd_addr != addr_last[PORT_SND]) begin + next_port[0] = PORT_SND; + addr_latch_next[0] = { 5'd0, snd_addr }; end else begin next_port[0] = PORT_NONE; addr_latch_next[0] = addr_latch[0]; @@ -186,7 +197,7 @@ end // PORT2: bank 2,3 always @(*) begin - if (port2_req ^ port2_ack) begin + if (port2_req ^ port2_state) begin next_port[1] = PORT_REQ; addr_latch_next[1] = { 1'b1, port2_a }; end else if (gfx_addr != addr_last2[PORT_GFX]) begin @@ -238,11 +249,12 @@ always @(posedge clk) begin sd_cmd <= CMD_ACTIVE; SDRAM_A <= addr_latch_next[0][22:10]; SDRAM_BA <= addr_latch_next[0][24:23]; - addr_last[next_port[0]] <= addr_latch_next[0][15:1]; + addr_last[next_port[0]] <= addr_latch_next[0][19:1]; if (next_port[0] == PORT_REQ) begin { oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we }; ds[0] <= port1_ds; din_latch[0] <= port1_d; + port1_state <= port1_req; end else begin { oe_latch[0], we_latch[0] } <= 2'b10; ds[0] <= 2'b11; @@ -266,6 +278,7 @@ always @(posedge clk) begin { oe_latch[1], we_latch[1] } <= { ~port2_we, port2_we }; ds[1] <= port2_ds; din_latch[1] <= port2_d; + port2_state <= port2_req; end else begin { oe_latch[1], we_latch[1] } <= 2'b10; ds[1] <= 2'b11; @@ -307,6 +320,7 @@ always @(posedge clk) begin case(port[0]) PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end PORT_CPU1: begin cpu1_q <= sd_din; end + PORT_SND: begin snd_q <= sd_din; end default: ; endcase; end diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon.vhd b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon.vhd index 73c43123..57a680bb 100644 --- a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon.vhd +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon.vhd @@ -146,7 +146,9 @@ port( down_c : in std_logic; fire_c : in std_logic; - cocktail : in std_logic; + sw1_input : in std_logic_vector( 7 downto 0); + sw2_input : in std_logic_vector( 7 downto 0); + service : in std_logic; flip_screen : in std_logic; @@ -159,6 +161,10 @@ port( dl_data : in std_logic_vector(7 downto 0); dl_wr : in std_logic; + wave_addr : buffer std_logic_vector(19 downto 0); + wave_rd : out std_logic; + wave_data : in std_logic_vector(15 downto 0); + dbg_cpu_addr : out std_logic_vector(15 downto 0) ); end zaxxon; @@ -289,8 +295,6 @@ architecture struct of zaxxon is signal p1_input : std_logic_vector(7 downto 0); signal p2_input : std_logic_vector(7 downto 0); - signal sw1_input : std_logic_vector(7 downto 0); - signal sw2_input : std_logic_vector(7 downto 0); signal gen_input : std_logic_vector(7 downto 0); signal coin1_r, coin1_mem, coin1_ena : std_logic := '0'; @@ -307,6 +311,10 @@ architecture struct of zaxxon is signal char_color_we : std_logic; signal palette_we : std_logic; + signal port_a, port_a_r : std_logic_vector(7 downto 0); -- i8255 ports + signal port_b, port_b_r : std_logic_vector(7 downto 0); + signal port_c, port_c_r : std_logic_vector(7 downto 0); + begin clock_vid <= clock_24; @@ -462,8 +470,6 @@ end process; --------------------------------- p1_input <= "000" & fire & down & up & left & right ; p2_input <= "000" & fire_c & down_c & up_c & left_c & right_c; -sw1_input <= cocktail&"111"&x"f"; -- cocktail->FF upright->7F -sw2_input <= x"33"; -- coin a/b 1c_1c gen_input <= service & coin2_mem & coin1_mem & '0' & start2 & start1 & "00"; ------------------------------------------ @@ -526,7 +532,12 @@ begin if (cpu_addr and x"E0FF") = x"E0F9" then bg_position(10 downto 8) <= not cpu_do(2 downto 0); end if; -- E0F9 + mirroring 1F00 if (cpu_addr and x"E0FF") = x"E0FA" then bg_color_ref <= cpu_do(0); end if; -- E0FA + mirroring 1F00 if (cpu_addr and x"E0FF") = x"E0FB" then bg_enable <= cpu_do(0); end if; -- E0FB + mirroring 1F00 - + + -- (i8255 trivial mode 0) + if (cpu_addr and x"E0FF") = x"E03C" then port_a <= cpu_do; port_a_r <= port_a; end if; -- E03C + mirroring 1F00 + if (cpu_addr and x"E0FF") = x"E03D" then port_b <= cpu_do; port_b_r <= port_b; end if; -- E03D + mirroring 1F00 + if (cpu_addr and x"E0FF") = x"E03E" then port_c <= cpu_do; port_c_r <= port_c; end if; -- E03E + mirroring 1F00 + end if; if int_on = '0' then @@ -1084,28 +1095,25 @@ port map( ); palette_we <= '1' when dl_wr = '1' and dl_addr(16 downto 8) = "111000000" else '0'; --1C000-1C0FF ---zaxxon_sound_board ---sound_board : entity work.tron_sound_board ---port map( --- clock_40 => clock_40, --- reset => reset, --- --- main_cpu_addr => cpu_addr(7 downto 0), --- --- ssio_iowe => ssio_iowe, --- ssio_di => cpu_do, --- ssio_do => ssio_do, --- --- input_0 => input_0, --- input_1 => input_1, --- input_2 => input_2, --- input_3 => input_3, --- input_4 => input_4, --- --- separate_audio => separate_audio, --- audio_out_l => audio_out_l, --- audio_out_r => audio_out_r, --- --- dbg_cpu_addr => open --dbg_cpu_addr ---); +--zaxxon_sound_board +sound_board : entity work.zaxxon_sound +port map( + clock_24 => clock_24, + reset => reset, + + port_a => port_a, + port_a_r => port_a_r, + port_b => port_b, + port_b_r => port_b_r, + port_c => port_c, + port_c_r => port_c_r, + + audio_out_l => audio_out_l, + audio_out_r => audio_out_r, + + wave_addr => wave_addr, + wave_rd => wave_rd, + wave_data => wave_data +); + end struct; \ No newline at end of file diff --git a/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon_sound.vhd b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon_sound.vhd new file mode 100644 index 00000000..b812e008 --- /dev/null +++ b/Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/zaxxon_sound.vhd @@ -0,0 +1,237 @@ +---------------- +-- Wave player -- +----------------- + +-- Zaxxon sample wav files info header - start/stop addresses as loaded in SDRAM + +--00.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 29970 start: 44 (x0002C) stop: 30014 (x0753E) +--01.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 17798 start: 30058 (x0756A) stop: 47856 (x0BAF0) +--02.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 63596 start: 47900 (x0BB1C) stop:111496 (x1B388) +--03.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 40420 start:111540 (x1B3B4) stop:151960 (x25198) +--04.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 66294 start:152004 (x251C4) stop:218298 (x354BA) +--05.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 56038 start:218342 (x354E6) stop:274380 (x42FCC) +--08.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg:104692 start:274424 (x42FF8) stop:379116 (x5C8EC) +--10.wav e:RIFF n:1 sr:22050 br:44100 al:2 bps:16 lg:168970 start:379160 (x5C918) stop:548130 (x85D22) +--11.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg:154144 start:548174 (x85D4E) stop:702318 (xAB76E) +--20.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 4128 start:702362 (xAB79A) stop:706490 (xAC7BA) +--21.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 6854 start:706534 (xAC7E6) stop:713388 (xAE2AC) +--23.wav e:RIFF n:1 sr:44100 br:88200 al:2 bps:16 lg: 86978 start:713432 (xAE2D8) stop:800410 (xC369A) + +-- 8255 PIA port A B C + +-- PA1/PA0 PLAYER SHIP A/B - Volume 04/05.wav +-- +--#0 - PA7 loop BATTLESHIP 00.wav - boss +--#1 - PA6 loop LASER 01.wav - electric field +--#2 - PA5 retrig BASE MISSILE 02.wav - missile engine +--#3 - PA4 loop HOMING MISSILE 03.wav - homing missile +--#4 - PA3 loop PLAYER SHIP D 04.wav - shuttle engine +--#5 - PA2 loop PLAYER SHIP C 05.wav - within space +--#6 - PB7 retrig CANNON 08.wav - player shot +--#7 - PB5 no retrig M-EXP 10.wav - final explode +--#8 - PB4 retrig S-EXP 11.wav - explode +--#9 - PC3 no retrig ALARM3 20.wav - low fuel +--#10 - PC2 retrig ALARM2 21.wav - enemy locked +--#11 - PC0 retrig SHOT 23.wav - coin / tourelle shot + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.numeric_std.all; + +entity zaxxon_sound is +port( + clock_24 : in std_logic; + reset : in std_logic; + + port_a : in std_logic_vector(7 downto 0); + port_a_r : in std_logic_vector(7 downto 0); -- i8255 ports + port_b : in std_logic_vector(7 downto 0); + port_b_r : in std_logic_vector(7 downto 0); + port_c : in std_logic_vector(7 downto 0); + port_c_r : in std_logic_vector(7 downto 0); + + audio_out_l : out std_logic_vector(15 downto 0); + audio_out_r : out std_logic_vector(15 downto 0); + + wave_addr : buffer std_logic_vector(19 downto 0); + wave_rd : out std_logic; + wave_data : in std_logic_vector(15 downto 0) + ); +end zaxxon_sound; + +architecture struct of zaxxon_sound is + + signal wav_clk_cnt : std_logic_vector(11 downto 0); -- 44kHz divider / sound# counter + + subtype snd_id_t is integer range 0 to 11; + signal snd_id : snd_id_t; + + type snd_addr_t is array(snd_id_t) of std_logic_vector(19 downto 0); + + -- wave current addresses in sdram + signal snd_addrs : snd_addr_t; + + -- wave start addresses in sdram + signal snd_starts : snd_addr_t := ( + x"0002C",x"0756A",x"0BB1C",x"1B3B4",x"251C4",x"354E6", + x"42FF8",x"5C918",x"85D4E",x"AB79A",x"AC7E6",x"AE2D8"); + + -- wave end addresses in sdram + signal snd_stops : snd_addr_t := ( + x"0753E",x"0BAF0",x"1B388",x"25198",x"354BA",x"42FCC", + x"5C8EC",x"85D22",x"AB76E",x"AC7BA",x"AE2AC",x"C369A"); + + type snd_flag_t is array(snd_id_t) of std_logic; + + -- sound playing (once) + signal snd_starteds : snd_flag_t := ( + '0','0','0','0','0','0','0','0','0','0','0','0'); + -- sound to be restarted + signal snd_restarts : snd_flag_t := ( + '0','0','0','0','0','0','0','0','0','0','0','0'); + -- sound playing (loop) + signal snd_continus : snd_flag_t := ( + '0','0','0','0','0','0','0','0','0','0','0','0'); + -- sound sample rate 44/22kHz + signal snd_44k : snd_flag_t := ( + '1','1','1','1','1','1','1','0','1','1','1','1'); + + -- divide 44kHz flag + signal snd_22k_flag : std_logic := '0'; + + -- sum all sound + signal audio_r, audio_sum : signed(19 downto 0); + signal ship_vol, volume : signed( 7 downto 0); + signal audio_vol : signed(23 downto 0); + + +begin + +-- scan sound# from 0-11 +snd_id <= to_integer(unsigned(wav_clk_cnt(8 downto 5))); + +-- apply volume to sdram (wav file) data w.r.t port_a and snd_id +with port_a(1 downto 0) select +ship_vol <= x"10" when "00", + x"20" when "01", + x"30" when "10", + x"40" when others; + +with snd_id select +volume <= ship_vol when 4, + ship_vol when 5, + x"7F" when others; + +audio_vol <= (signed(wave_data) * volume) / 128; + +-- wave player +process (clock_24, reset) +begin + if reset='1' then + wav_clk_cnt <= (others=>'0'); + else + if rising_edge(clock_24) then + + -- sound triggers + snd_continus( 0) <= not port_a(7); -- boss + snd_continus( 1) <= not port_a(6); -- electric field + + snd_starteds( 2) <= snd_starteds( 2) or (not(port_a(5)) and port_a_r(5)); -- missile engine + snd_restarts( 2) <= snd_restarts( 2) or (not(port_a(5)) and port_a_r(5)); + + snd_continus( 3) <= not port_a(4); -- homing missile + snd_continus( 4) <= not port_a(3); -- shuttle engine + snd_continus( 5) <= not port_a(2); -- within space + + snd_starteds( 6) <= snd_starteds( 6) or (not(port_b(7)) and port_b_r(7)); -- player shot + snd_restarts( 6) <= snd_restarts( 6) or (not(port_b(7)) and port_b_r(7)); + + snd_starteds( 7) <= snd_starteds( 7) or (not(port_b(5)) and port_b_r(5)); -- final explode + + snd_starteds( 8) <= snd_starteds( 8) or (not(port_b(4)) and port_b_r(4)); -- explode + snd_restarts( 8) <= snd_restarts( 8) or (not(port_b(4)) and port_b_r(4)); + + snd_starteds( 9) <= snd_starteds( 9) or (not(port_c(3)) and port_c_r(3)); -- low fuel + + snd_starteds(10) <= snd_starteds(10) or (not(port_c(2)) and port_c_r(2)); -- enemy locked + snd_restarts(10) <= snd_restarts(10) or (not(port_c(2)) and port_c_r(2)); + + snd_starteds(11) <= snd_starteds(11) or (not(port_c(0)) and port_c_r(0)); -- coin / tourelle shot + snd_restarts(11) <= snd_restarts(11) or (not(port_c(0)) and port_c_r(0)); + + -- 44.1kHz base tempo / high bits for scanning sound# + if wav_clk_cnt = x"21F" then -- divide 24MHz by 544 => 44.117kHz + wav_clk_cnt <= (others=>'0'); + snd_22k_flag <= not snd_22k_flag; -- divide by 2 => 22.05kHz + + -- latch final audio / reset sum + audio_r <= audio_sum; + audio_sum <= (others => '0'); + else + wav_clk_cnt <= wav_clk_cnt + 1; + end if; + + -- clip audio + if audio_r(19 downto 2) > 32767 then + audio_out_l <= x"7FFF"; + elsif audio_r(19 downto 2) < -32768 then + audio_out_l <= x"8000"; + else + audio_out_l <= std_logic_vector(audio_r(17 downto 2)); + end if; + + -- sdram read trigger (and auto refresh period) + if wav_clk_cnt(4 downto 0) = "00000" then wave_rd <= '1';end if; + if wav_clk_cnt(4 downto 0) = "00010" then wave_rd <= '0';end if; + + -- select only useful cycles (0-11) + -- remaing cycles unsued + if wav_clk_cnt(11 downto 5) <= 11 then + + -- set sdram addr at begining of cycle + if wav_clk_cnt(4 downto 0) = "00000" then + wave_addr <= snd_addrs(snd_id); + end if; + + -- sound# currently playing + if (snd_starteds(snd_id) = '1' or snd_continus(snd_id) = '1' ) then + + -- get sound# sample and update next sound# address + -- (next / restart) + if wav_clk_cnt(4 downto 0) = "10000" then + + audio_sum <= audio_sum + audio_vol(15 downto 0); + + if snd_restarts(snd_id) = '1' then + snd_addrs(snd_id) <= snd_starts(snd_id); + snd_restarts(snd_id) <= '0'; + else + if (snd_44k(snd_id) = '1' or snd_22k_flag = '1') then + snd_addrs(snd_id) <= snd_addrs(snd_id) + 2; + end if; + end if; + end if; + + -- update next sound# address + -- (stop / loop) + if snd_addrs(snd_id) >= snd_stops(snd_id) then + if snd_continus(snd_id) = '1' then + snd_addrs(snd_id) <= snd_starts(snd_id); + else + snd_starteds(snd_id) <= '0'; + end if; + end if; + + else + -- sound# stopped set begin address + snd_addrs(snd_id) <= snd_starts(snd_id); + end if; + + end if; + + end if; + end if; +end process; + +end struct; \ No newline at end of file