diff --git a/Arcade_MiST/Midway MCR 2/Journey_MiST/Journey.qsf b/Arcade_MiST/Midway MCR 2/Journey_MiST/Journey.qsf
index 5d156956..096cfc8c 100644
--- a/Arcade_MiST/Midway MCR 2/Journey_MiST/Journey.qsf
+++ b/Arcade_MiST/Midway MCR 2/Journey_MiST/Journey.qsf
@@ -181,7 +181,7 @@ 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_global_assignment -name ENABLE_SIGNALTAP OFF
-set_global_assignment -name USE_SIGNALTAP_FILE output_files/jo.stp
+set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp1.stp
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Journey_MiST.sv
set_global_assignment -name VHDL_FILE rtl/journey.vhd
set_global_assignment -name VHDL_FILE rtl/satans_hollow_sound_board.vhd
@@ -196,4 +196,7 @@ set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
set_global_assignment -name VHDL_FILE ../../../common/Sound/ym2149/vol_table_array.vhd
set_global_assignment -name VHDL_FILE ../../../common/Sound/ym2149/YM2149.vhd
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
+set_global_assignment -name VHDL_FILE ../../../common/Sound/diskimage_by_byte.vhd
+set_global_assignment -name SYSTEMVERILOG_FILE ../../../common/Sound/wave_sound.sv
+set_global_assignment -name SIGNALTAP_FILE output_files/stp1.stp
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 2/Journey_MiST/meta/Journey.mra b/Arcade_MiST/Midway MCR 2/Journey_MiST/meta/Journey.mra
index c508429d..b626040d 100644
--- a/Arcade_MiST/Midway MCR 2/Journey_MiST/meta/Journey.mra
+++ b/Arcade_MiST/Midway MCR 2/Journey_MiST/meta/Journey.mra
@@ -5,7 +5,7 @@
1984
Bally Midway
Action
- MCR3
+ Journey
journey
diff --git a/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/Journey_MiST.sv b/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/Journey_MiST.sv
index e360448f..974305d4 100644
--- a/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/Journey_MiST.sv
+++ b/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/Journey_MiST.sv
@@ -16,13 +16,15 @@
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//============================================================================
+`default_nettype none
+
module Journey_MiST(
output LED,
output [5:0] VGA_R,
output [5:0] VGA_G,
output [5:0] VGA_B,
- output VGA_HS,
- output VGA_VS,
+ output reg VGA_HS,
+ output reg VGA_VS,
output AUDIO_L,
output AUDIO_R,
input SPI_SCK,
@@ -53,6 +55,7 @@ localparam CONF_STR = {
"O5,Blend,Off,On;",
"O6,Service,Off,On;",
"R2048,Save NVRAM;",
+// "S0U,WAVVHD,Cas Audio:;",
"T0,Reset;",
"V,v1.0.",`BUILD_DATE
};
@@ -95,10 +98,21 @@ wire key_pressed;
wire [7:0] key_code;
wire key_strobe;
+wire [31:0] sd_lba;
+wire sd_rd;
+wire sd_ack;
+wire sd_ack_conf;
+wire [7:0] sd_dout;
+wire sd_dout_strobe;
+wire img_mounted;
+wire [63:0] img_size;
+
user_io #(
- .STRLEN(($size(CONF_STR)>>3)))
-user_io(
+ .STRLEN(($size(CONF_STR)>>3)),
+ .SD_IMAGES(1)
+) user_io(
.clk_sys (clk_sys ),
+ .clk_sd (clk_sys ),
.conf_str (CONF_STR ),
.SPI_CLK (SPI_SCK ),
.SPI_SS_IO (CONF_DATA0 ),
@@ -114,6 +128,23 @@ user_io(
.key_code (key_code ),
.joystick_0 (joystick_0 ),
.joystick_1 (joystick_1 ),
+
+ // SD CARD
+ .sd_lba (sd_lba ),
+ .sd_rd (sd_rd ),
+ .sd_wr (1'b0 ),
+ .sd_ack (sd_ack ),
+ .sd_ack_conf (sd_ack_conf ),
+ .sd_conf (1'b0 ),
+ .sd_sdhc (1'b1 ),
+ .sd_dout (sd_dout ),
+ .sd_dout_strobe (sd_dout_strobe),
+ .sd_din ( ),
+ .sd_din_strobe ( ),
+ .sd_buff_addr ( ),
+ .img_mounted (img_mounted ),
+ .img_size (img_size ),
+
.status (status )
);
@@ -223,6 +254,8 @@ wire hs, vs, cs;
wire blankn;
wire [2:0] g, r, b;
+wire [7:0] output_4;
+
journey journey(
.clock_40(clk_sys),
.reset(reset),
@@ -243,6 +276,8 @@ journey journey(
.input_2 ( input_2 ),
.input_3 ( input_3 ),
.input_4 ( input_4 ),
+
+ .output_4 ( output_4 ),
.cpu_rom_addr ( rom_addr ),
.cpu_rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ),
@@ -259,8 +294,10 @@ journey journey(
wire vs_out;
wire hs_out;
-assign VGA_HS = (~no_csync & scandoublerD & ~ypbpr)? cs : hs_out;
-assign VGA_VS = (~no_csync & scandoublerD & ~ypbpr)? 1'b1 : vs_out;
+always @(posedge clk_sys) begin
+ VGA_HS <= (~no_csync & scandoublerD & ~ypbpr)? cs : hs_out;
+ VGA_VS <= (~no_csync & scandoublerD & ~ypbpr)? 1'b1 : vs_out;
+end
mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
.clk_sys ( clk_sys ),
@@ -286,21 +323,99 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
.ypbpr ( ypbpr )
);
+// Wave sound
+
+wire wav_mounted;
+wire [31:0] wav_addr;
+wire wav_rd;
+wire wav_rd_next;
+wire [7:0] wav_d;
+wire wav_ack;
+
+assign wav_addr[31:28] = 4'h0;
+assign sd_lba[31:23] = 8'h00;
+
+// Bytewise interface to disk images
+diskimage_by_byte waveinterface (
+ .clk(clk_sys),
+ .reset_n(~reset),
+
+ .sd_lba(sd_lba),
+ .sd_rd(sd_rd),
+ .sd_ack(sd_ack),
+ .sd_d(sd_dout),
+ .sd_d_strobe(sd_dout_strobe),
+ .sd_imgsize(img_size),
+ .sd_imgmounted(img_mounted),
+
+ .client_mounted(wav_mounted),
+ .client_addr(wav_addr),
+ .client_rd(wav_rd),
+ .client_rd_next(wav_rd_next),
+ .client_q(wav_d),
+ .client_ack(wav_ack)
+);
+
+// Wave player
+
+wire [15:0] wav_out_l;
+wire [15:0] wav_out_r;
+
+wire playing;
+
+assign playing = wav_mounted && output_4[0];
+
+wave_sound #(.SYSCLOCK(40000000)) waveplayer
+(
+ .I_CLK(clk_sys),
+ .I_RST(reset | img_mounted),
+
+ .I_BASE_ADDR(0),
+ .I_LOOP(1'b1),
+ .I_PAUSE(~playing),
+
+ .O_ADDR(wav_addr),
+ .O_READ(wav_rd),
+ .O_READNEXT(wav_rd_next),
+ .I_DATA(wav_d),
+ .I_READY(wav_ack),
+
+ .O_PCM_L(wav_out_l),
+ .O_PCM_R(wav_out_r)
+);
+
+
+reg [16:0] audio_l_sum;
+reg [16:0] audio_r_sum;
+
+reg [16:0] dac_in_l;
+reg [16:0] dac_in_r;
+
+always @(posedge clk_sys) begin
+
+ audio_l_sum <= {wav_out_l[15],wav_out_l} + {audio_l,1'b0} - 16'h4000;
+ audio_r_sum <= {wav_out_r[15],wav_out_r} + {audio_r,1'b0} - 16'h4000;
+
+ dac_in_l <= {~audio_l_sum[16],audio_l_sum[15:0]};
+ dac_in_r <= {~audio_r_sum[16],audio_r_sum[15:0]};
+end
+
+
dac #(
- .C_bits(16))
+ .C_bits(17))
dac_l(
.clk_i(clk_sys),
.res_n_i(1),
- .dac_i(audio_l),
+ .dac_i(dac_in_l),
.dac_o(AUDIO_L)
);
dac #(
- .C_bits(16))
+ .C_bits(17))
dac_r(
.clk_i(clk_sys),
.res_n_i(1),
- .dac_i(audio_r),
+ .dac_i(dac_in_r),
.dac_o(AUDIO_R)
);
diff --git a/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/journey.vhd b/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/journey.vhd
index 5e251f69..45590d25 100644
--- a/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/journey.vhd
+++ b/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/journey.vhd
@@ -158,6 +158,8 @@ port(
input_2 : in std_logic_vector( 7 downto 0);
input_3 : in std_logic_vector( 7 downto 0);
input_4 : in std_logic_vector( 7 downto 0);
+
+ output_4 : out std_logic_vector( 7 downto 0);
cpu_rom_addr : out std_logic_vector(15 downto 0);
cpu_rom_do : in std_logic_vector(7 downto 0);
@@ -851,6 +853,8 @@ port map(
input_3 => input_3,
input_4 => input_4,
+ output_4 => output_4,
+
separate_audio => separate_audio,
audio_out_l => audio_out_l,
audio_out_r => audio_out_r,
diff --git a/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/satans_hollow_sound_board.vhd b/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/satans_hollow_sound_board.vhd
index 030a6269..41560a17 100644
--- a/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/satans_hollow_sound_board.vhd
+++ b/Arcade_MiST/Midway MCR 2/Journey_MiST/rtl/satans_hollow_sound_board.vhd
@@ -68,6 +68,7 @@ port(
input_2 : in std_logic_vector(7 downto 0);
input_3 : in std_logic_vector(7 downto 0);
input_4 : in std_logic_vector(7 downto 0);
+ output_4 : out std_logic_vector(7 downto 0);
separate_audio : in std_logic;
audio_out_l : out std_logic_vector(15 downto 0);
@@ -446,8 +447,12 @@ begin
iram_1_do <= (others => '0');
iram_2_do <= (others => '0');
iram_3_do <= (others => '0');
+ output_4 <= (others => '0');
else
if rising_edge(clock_snd) then
+ if ssio_iowe = '1' and main_cpu_addr(7 downto 2) = "000001" then -- 0x04 - 0x07
+ output_4 <= ssio_di;
+ end if;
if ssio_iowe = '1' and main_cpu_addr(7 downto 2) = "000111" then -- 0x1C - 0x1F
case main_cpu_addr(1 downto 0) is
when "00" => iram_0_do <= ssio_di;
diff --git a/common/Sound/diskimage_by_byte.vhd b/common/Sound/diskimage_by_byte.vhd
new file mode 100644
index 00000000..dae59452
--- /dev/null
+++ b/common/Sound/diskimage_by_byte.vhd
@@ -0,0 +1,168 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_misc.all;
+use ieee.numeric_std.all;
+
+
+entity diskimage_by_byte is
+generic (
+ lbahigh : integer := 31;
+ lbalow : integer := 9
+);
+port (
+ clk : in std_logic;
+ reset_n : in std_logic;
+ -- Disk image interface
+ sd_lba : out std_logic_vector(lbahigh-lbalow downto 0);
+ sd_rd : out std_logic;
+ sd_ack : in std_logic;
+ sd_d : in std_logic_vector(7 downto 0);
+ sd_d_strobe : in std_logic;
+ sd_imgsize : in std_logic_vector(lbahigh downto 0);
+ sd_imgmounted : in std_logic;
+ -- Word interface
+ client_mounted : out std_logic;
+ client_addr : in std_logic_vector(lbahigh downto 0); -- Offset from start of file, in bytes - but LSB should be zero
+ client_rd : in std_logic;
+ client_rd_next : in std_logic;
+ client_q : out std_logic_vector(7 downto 0);
+ client_ack : out std_logic
+);
+end entity;
+
+architecture rtl of diskimage_by_byte is
+ type bufdata_t is array(0 to 1024) of std_logic_vector(7 downto 0);
+ signal buf : bufdata_t;
+ type states_t is (IDLE,WAITACK,READING,READEND);
+ signal state : states_t;
+ signal fillbuf : std_logic;
+ signal drainbuf : std_logic;
+ signal client_mounted_i : std_logic :='0';
+begin
+
+ sdinterface : block
+ signal imgsize : unsigned(lbahigh downto 0);
+ signal fillidx : unsigned(lbahigh downto 0); -- Byte index into file
+ signal fillbuf_d : std_logic;
+ begin
+
+ client_mounted <= client_mounted_i;
+
+ fillbuf <= fillidx(lbalow);
+
+ process(clk) begin
+ if rising_edge(clk) then
+ if sd_imgmounted='1' then
+ imgsize <= unsigned(sd_imgsize);
+ if or_reduce(sd_imgsize) /= '0' then
+ client_mounted_i <= '1';
+ else
+ client_mounted_i <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ process(clk) begin
+ if rising_edge(clk) then
+
+ case(state) is
+
+ when IDLE =>
+ -- If the read pointer has progressed into the last buffer, read the next sector into the newly-vacated buffer
+ if fillbuf /= drainbuf then
+ if fillidx(lbahigh downto lbalow) '0');
+ sd_lba <= client_addr(lbahigh downto lbalow);
+ sd_rd <= '1';
+ state <= WAITACK;
+ end if;
+
+ when WAITACK =>
+ if sd_ack='1' then
+ sd_rd<='0';
+ state <= READING;
+ end if;
+
+ when READING =>
+ if sd_d_strobe='1' then
+ buf(to_integer(fillidx(lbalow downto 0))) <= sd_d;
+ fillidx <= fillidx+1;
+ end if;
+ if fillbuf /= fillbuf_d then
+ state <= READEND;
+ end if;
+ fillbuf_d<=fillbuf;
+
+ when READEND =>
+ if sd_ack='0' then
+ state <= IDLE;
+ end if;
+
+ when others =>
+ null;
+
+ end case;
+ if reset_n='0' or sd_imgmounted='1' then
+ fillidx<=(others => '0');
+ sd_rd<='0';
+ state <= IDLE;
+ end if;
+ end if;
+ end process;
+ end block;
+
+ clientinterface : block
+ signal drainidx : unsigned(lbahigh downto 0);
+ signal rd_d : std_logic;
+ signal client_ack_i : std_logic;
+ begin
+
+ client_ack <= client_ack_i;
+ drainbuf <= drainidx(lbalow);
+
+ process(clk) begin
+
+ if rising_edge(clk) then
+ client_ack_i <='0';
+
+ if client_rd='1' and client_ack_i='0' then
+ drainidx <= unsigned(client_addr);
+ end if;
+
+ if client_rd = '1' or client_rd_next='1' then -- Latch incoming read requests, and give SM time to respond
+ rd_d <= not client_ack_i;
+ end if;
+
+ if client_ack_i='0' and rd_d='1' and (state=IDLE or fillbuf /= drainbuf) then
+ client_q <= buf(to_integer(drainidx(lbalow downto 0)));
+ drainidx <= drainidx+1;
+ rd_d <= '0';
+ client_ack_i <= '1';
+ end if;
+
+ if sd_imgmounted='1' then
+ rd_d <= '0';
+ drainidx<=(others => '0');
+ end if;
+
+ if reset_n='0' or client_mounted_i='0' then
+ rd_d<='0';
+ client_ack_i<='0';
+ end if;
+
+ end if;
+ end process;
+
+ end block;
+
+end architecture;
+
diff --git a/common/Sound/wave_sound.sv b/common/Sound/wave_sound.sv
new file mode 100644
index 00000000..392195f3
--- /dev/null
+++ b/common/Sound/wave_sound.sv
@@ -0,0 +1,172 @@
+//============================================================================
+// Sound sample player.
+//
+// Author: gaz68 (https://github.com/gaz68)
+// October 2019
+// Adapted by alanswx to parse the wave
+//
+// Adjustments for diskimage interface, and stereo support by
+// Alastair M. Robinson
+//
+//============================================================================
+
+module wave_sound #(parameter SYSCLOCK = 40000000)
+(
+ input I_CLK,
+ input I_RST,
+
+ input [27:0] I_BASE_ADDR,
+ input I_LOOP,
+ input I_PAUSE,
+
+ output [27:0] O_ADDR, // output address to wave ROM
+ output O_READ, // read a byte
+ output O_READNEXT, // read a byte
+ input [7:0] I_DATA, // Data coming back from wave ROM
+ input I_READY, // data is ready
+
+ output [15:0] O_PCM_L,
+ output [15:0] O_PCM_R
+);
+
+reg [27:0] W_DMA_ADDR;
+reg [27:0] END_ADDR;
+reg W_DMA_EN;
+reg inheader;
+reg [15:0] num_channels;
+reg [31:0] sample_rate;
+reg [31:0] byte_rate;
+reg [15:0] block_align;
+reg [15:0] bits_per_sample;
+reg [23:0] data_size;
+reg [27:0] START_ADDR;
+
+reg [7:0] W_SAMPL_LSB;
+reg [15:0] W_SAMPL_L;
+reg [15:0] W_SAMPL_R;
+
+reg [31:0] sum;
+wire[31:0] sum_next = sum + ( stereo ? {sample_rate,1'b0} : sample_rate);
+
+wire stereo = num_channels==16'h2 ? 1'b1 : 1'b0;
+reg channel_toggle;
+
+reg ce_sample;
+always @(posedge I_CLK) begin
+ ce_sample <= 0;
+ sum <= sum_next;
+ if(sum_next >= SYSCLOCK) begin
+ sum <= sum_next - SYSCLOCK;
+ ce_sample <= 1;
+ end
+end
+
+reg read_done = 0;
+always@(posedge I_CLK) begin
+
+ if(I_RST)begin
+ W_DMA_ADDR <= I_BASE_ADDR;
+ W_DMA_EN <= 1'b1;
+ O_READ <= 1'b1;
+ O_READNEXT <= 1'b0;
+ inheader <= 1'b1;
+ read_done <= 1'b0;
+ end
+ else if (W_DMA_EN) begin
+ if (I_READY) begin
+ O_READ <= 0;
+ O_READNEXT <= 0;
+ end
+
+ if (I_READY & ~read_done) begin
+ if (inheader) begin
+ O_READNEXT <= 1'b1;
+ case (W_DMA_ADDR[5:0])
+ 00: ; // R
+ 01: ; // I
+ 02: ; // F
+ 03: ; // F
+ 22: num_channels[7:0] <= I_DATA;
+ 23: num_channels[15:8] <= I_DATA;
+ 24: sample_rate[7:0] <= I_DATA;
+ 25: sample_rate[15:8] <= I_DATA;
+ 26: sample_rate[23:16] <= I_DATA;
+ 27: sample_rate[31:24] <= I_DATA;
+ //28: byte_rate[7:0] <= I_DATA;
+ //29: byte_rate[15:8] <= I_DATA;
+ //30: byte_rate[23:16] <= I_DATA;
+ //31: byte_rate[31:24] <= I_DATA;
+ //32: block_align[7:0] <= I_DATA;
+ //33: block_align[15:8] <= I_DATA;
+ 34: bits_per_sample[7:0] <= I_DATA;
+ 35: bits_per_sample[15:8] <= I_DATA;
+ 40: data_size[7:0] <= I_DATA;
+ 41: data_size[15:8] <= I_DATA;
+ 42: data_size[23:16] <= I_DATA;
+ 43: begin
+// data_size[31:24] <= I_DATA;// AMR - Applied too late
+ //$display("num_channels %x %d\n",num_channels,num_channels);
+ $display("sample_rate %x %d\n",sample_rate,sample_rate);
+ //$display("byte_rate %x %d\n",byte_rate,byte_rate);
+ //$display("block_align%x %d\n",block_align,block_align);
+ $display("bits_per_sample %x %d\n",bits_per_sample,bits_per_sample);
+ $display("data_size %x %d\n",data_size,data_size);
+ $display("data_size %x %d\n",data_size,data_size);
+ $display("data_size %x %d\n",data_size[15:0],data_size[15:0]);
+ END_ADDR <= W_DMA_ADDR + data_size + {I_DATA,24'd0}; // AMR - Merge in MSB
+ START_ADDR <= W_DMA_ADDR + 1'd1;
+ inheader <= 0;
+ O_READ <= 0;
+ O_READNEXT <= 0;
+ read_done <= 1;
+ channel_toggle<=1'b0;
+ end
+ endcase
+ end
+ else if (bits_per_sample != 16) begin
+ if(channel_toggle| !stereo)
+ W_SAMPL_L <= {I_DATA,I_DATA};
+ if(!channel_toggle| !stereo)
+ W_SAMPL_R <= {I_DATA,I_DATA};
+ read_done <= 1;
+ end
+ else if (!W_DMA_ADDR[0]) begin
+ W_SAMPL_LSB <= I_DATA;
+ O_READNEXT <= 1'b1;
+ end
+ else begin
+ if(channel_toggle| !stereo)
+ W_SAMPL_L <= {I_DATA,W_SAMPL_LSB};
+ if(!channel_toggle| !stereo)
+ W_SAMPL_R <= {I_DATA,W_SAMPL_LSB};
+ read_done <= 1;
+ end
+
+ W_DMA_ADDR <= W_DMA_ADDR + 1'd1;
+ end
+
+ if(read_done && ce_sample && !I_PAUSE) begin
+ read_done <= 0;
+ channel_toggle<=~channel_toggle;
+ W_DMA_EN <= ~(W_DMA_ADDR >= END_ADDR);
+ if (W_DMA_ADDR >= END_ADDR && I_LOOP) begin
+ W_DMA_EN <= 1'b1;
+ W_DMA_ADDR <= START_ADDR;
+ O_READ <= 1'b1;
+ end
+ else
+ O_READNEXT <= 1'b1;
+ end
+ end
+
+ if(I_RST || I_PAUSE || !W_DMA_EN) begin
+ W_SAMPL_L <= 0;
+ W_SAMPL_R <= 0;
+ end
+end
+
+assign O_ADDR = W_DMA_ADDR;
+assign O_PCM_L = W_SAMPL_L;
+assign O_PCM_R = W_SAMPL_R;
+
+endmodule