Update YM2149 to latest version.

This commit is contained in:
sorgelig
2018-08-22 03:41:30 +08:00
parent dfa92d61b0
commit 7ee1d8a53f
2 changed files with 104 additions and 127 deletions

View File

@ -38,14 +38,6 @@
// 1 0 write value // 1 0 write value
// 1 1 set address // 1 1 set address
// //
// Registers description
// R0, R1, R2, R4, R4, R5 - Tone Generator Control
// R6 - Noise Generator Control
// R7 - Mixer Control-I/O Enable
// R10, R11, R12 - Amplitude Control
// R13, R14, R15 - Envelope Generator Control
// R13, R14 - Envelope Period Control
// R15 - Envelope Shape/Cycle Control
module ym2149 module ym2149
( (
@ -73,41 +65,38 @@ module ym2149
); );
assign ACTIVE = ~ymreg[7][5:0]; assign ACTIVE = ~ymreg[7][5:0];
assign IOA_out = ymreg[14]; assign IOA_out = ymreg[14];
assign IOB_out = ymreg[15]; assign IOB_out = ymreg[15];
reg ena_div;
reg ena_div_noise;
reg [7:0] addr; reg [7:0] addr;
reg [7:0] ymreg[16]; reg [7:0] ymreg[16];
reg env_ena;
reg [4:0] env_vol;
wire [7:0] volTableAy[16] = // Write to PSG
'{8'h00, 8'h03, 8'h04, 8'h06, reg env_reset;
8'h0a, 8'h0f, 8'h15, 8'h22, always @(posedge CLK) begin
8'h28, 8'h41, 8'h5b, 8'h72, if(RESET) begin
8'h90, 8'hb5, 8'hd7, 8'hff ymreg <= '{default:0};
}; ymreg[7] <= '1;
addr <= '0;
env_reset <= 0;
end else begin
env_reset <= 0;
if(BDIR) begin
if(BC) addr <= DI;
else if(!addr[7:4]) begin
ymreg[addr[3:0]] <= DI;
env_reset <= (addr == 13);
end
end
end
end
wire [7:0] volTableYm[32] = // Read from PSG
'{8'h00, 8'h01, 8'h01, 8'h02,
8'h02, 8'h03, 8'h03, 8'h04,
8'h06, 8'h07, 8'h09, 8'h0a,
8'h0c, 8'h0e, 8'h11, 8'h13,
8'h17, 8'h1b, 8'h20, 8'h25,
8'h2c, 8'h35, 8'h3e, 8'h47,
8'h54, 8'h66, 8'h77, 8'h88,
8'ha1, 8'hc0, 8'he0, 8'hff
};
// Read from AY
assign DO = dout; assign DO = dout;
reg [7:0] dout; reg [7:0] dout;
always_comb begin always_comb begin
if(addr[7:4]) dout <= 8'hFF; dout = 8'hFF;
else begin if(~BDIR & BC & !addr[7:4]) begin
case(addr[3:0]) case(addr[3:0])
0: dout = ymreg[0]; 0: dout = ymreg[0];
1: dout = ymreg[1][3:0]; 1: dout = ymreg[1][3:0];
@ -123,12 +112,15 @@ always_comb begin
11: dout = ymreg[11]; 11: dout = ymreg[11];
12: dout = ymreg[12]; 12: dout = ymreg[12];
13: dout = ymreg[13][3:0]; 13: dout = ymreg[13][3:0];
14: dout = (ymreg[7][6] ? ymreg[14] : IOA_in); 14: dout = ymreg[7][6] ? ymreg[14] : IOA_in;
15: dout = (ymreg[7][7] ? ymreg[15] : IOB_in); 15: dout = ymreg[7][7] ? ymreg[15] : IOB_in;
endcase endcase
end end
end end
reg ena_div;
reg ena_div_noise;
// p_divider // p_divider
always @(posedge CLK) begin always @(posedge CLK) begin
reg [3:0] cnt_div; reg [3:0] cnt_div;
@ -150,7 +142,7 @@ always @(posedge CLK) begin
end end
reg noise_gen_op; reg [2:0] noise_gen_op;
// p_noise_gen // p_noise_gen
always @(posedge CLK) begin always @(posedge CLK) begin
@ -166,9 +158,9 @@ always @(posedge CLK) begin
end else begin end else begin
noise_gen_cnt <= noise_gen_cnt + 1'd1; noise_gen_cnt <= noise_gen_cnt + 1'd1;
end end
noise_gen_op <= poly17[0]; noise_gen_op <= {3{poly17[0]}};
end else begin end else begin
noise_gen_op <= 0; noise_gen_op <= ymreg[7][5:3];
noise_gen_cnt <= 0; noise_gen_cnt <= 0;
end end
end end
@ -200,7 +192,7 @@ always @(posedge CLK) begin
tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1; tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1;
end end
end else begin end else begin
tone_gen_op[i] <= 0; tone_gen_op[i] <= ymreg[7][i];
tone_gen_cnt[i] <= 0; tone_gen_cnt[i] <= 0;
end end
end end
@ -208,6 +200,7 @@ always @(posedge CLK) begin
end end
end end
reg env_ena;
wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0; wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0;
//p_envelope_freq //p_envelope_freq
@ -227,14 +220,14 @@ always @(posedge CLK) begin
end end
end end
reg [4:0] env_vol;
wire is_bot = (env_vol == 5'b00000); wire is_bot = (env_vol == 5'b00000);
wire is_bot_p1 = (env_vol == 5'b00001); wire is_bot_p1 = (env_vol == 5'b00001);
wire is_top_m1 = (env_vol == 5'b11110); wire is_top_m1 = (env_vol == 5'b11110);
wire is_top = (env_vol == 5'b11111); wire is_top = (env_vol == 5'b11111);
always @(posedge CLK) begin always @(posedge CLK) begin
reg old_BDIR;
reg env_reset;
reg env_hold; reg env_hold;
reg env_inc; reg env_inc;
@ -260,39 +253,7 @@ always @(posedge CLK) begin
// //
// 1 1 1 1 /___ // 1 1 1 1 /___
if(RESET) begin if(env_reset | RESET) begin
ymreg[0] <= '0;
ymreg[1] <= '0;
ymreg[2] <= '0;
ymreg[3] <= '0;
ymreg[4] <= '0;
ymreg[5] <= '0;
ymreg[6] <= '0;
ymreg[7] <= '1;
ymreg[8] <= '0;
ymreg[9] <= '0;
ymreg[10] <= '0;
ymreg[11] <= '0;
ymreg[12] <= '0;
ymreg[13] <= '0;
ymreg[14] <= '0;
ymreg[15] <= '0;
addr <= '0;
env_vol <= '0;
end else begin
old_BDIR <= BDIR;
if(~old_BDIR & BDIR) begin
if(BC) addr <= DI;
else if(!addr[7:4])begin
ymreg[addr[3:0]] <= DI;
env_reset <= (addr == 13);
end
end
end
if(CE) begin
if(env_reset) begin
env_reset <= 0;
// load initial state // load initial state
if(!ymreg[13][2]) begin // attack if(!ymreg[13][2]) begin // attack
env_vol <= 5'b11111; env_vol <= 5'b11111;
@ -302,8 +263,8 @@ always @(posedge CLK) begin
env_inc <= 1; // +1 env_inc <= 1; // +1
end end
env_hold <= 0; env_hold <= 0;
end else begin end
else if(CE) begin
if (env_ena) begin if (env_ena) begin
if (!env_hold) begin if (!env_hold) begin
if (env_inc) env_vol <= (env_vol + 5'b00001); if (env_inc) env_vol <= (env_vol + 5'b00001);
@ -341,14 +302,30 @@ always @(posedge CLK) begin
end end
end end
end end
reg [5:0] A,B,C;
always @(posedge CLK) begin
A <= {MODE, ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | noise_gen_op[0])) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]}};
B <= {MODE, ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | noise_gen_op[1])) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]}};
C <= {MODE, ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | noise_gen_op[2])) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]}};
end end
wire [4:0] A = ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | noise_gen_op)) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]}; wire [7:0] volTable[64] = '{
wire [4:0] B = ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | noise_gen_op)) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]}; //YM2149
wire [4:0] C = ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | noise_gen_op)) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]}; 8'h00, 8'h01, 8'h01, 8'h02, 8'h02, 8'h03, 8'h03, 8'h04,
8'h06, 8'h07, 8'h09, 8'h0a, 8'h0c, 8'h0e, 8'h11, 8'h13,
8'h17, 8'h1b, 8'h20, 8'h25, 8'h2c, 8'h35, 8'h3e, 8'h47,
8'h54, 8'h66, 8'h77, 8'h88, 8'ha1, 8'hc0, 8'he0, 8'hff,
assign CHANNEL_A = MODE ? volTableAy[A[4:1]] : volTableYm[A]; //AY8910
assign CHANNEL_B = MODE ? volTableAy[B[4:1]] : volTableYm[B]; 8'h00, 8'h00, 8'h03, 8'h03, 8'h04, 8'h04, 8'h06, 8'h06,
assign CHANNEL_C = MODE ? volTableAy[C[4:1]] : volTableYm[C]; 8'h0a, 8'h0a, 8'h0f, 8'h0f, 8'h15, 8'h15, 8'h22, 8'h22,
8'h28, 8'h28, 8'h41, 8'h41, 8'h5b, 8'h5b, 8'h72, 8'h72,
8'h90, 8'h90, 8'hb5, 8'hb5, 8'hd7, 8'hd7, 8'hff, 8'hff
};
assign CHANNEL_A = volTable[A];
assign CHANNEL_B = volTable[B];
assign CHANNEL_C = volTable[C];
endmodule endmodule

View File

@ -94,7 +94,7 @@ ym2149 ym2149
.CE(ce_psg), .CE(ce_psg),
.RESET(RESET), .RESET(RESET),
.BDIR(WE), .BDIR(WE),
.BC(~A0), .BC(~A0 | ~WE),
.DI(DI), .DI(DI),
.DO(psg_dout), .DO(psg_dout),
.CHANNEL_A(CHANNEL_A), .CHANNEL_A(CHANNEL_A),