mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-18 14:51:25 +03:00
Update YM2149 to latest version.
This commit is contained in:
@ -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
|
||||||
(
|
(
|
||||||
@ -72,42 +64,39 @@ module ym2149
|
|||||||
output [7:0] IOB_out
|
output [7:0] IOB_out
|
||||||
);
|
);
|
||||||
|
|
||||||
assign ACTIVE = ~ymreg[7][5:0];
|
assign ACTIVE = ~ymreg[7][5:0];
|
||||||
|
assign IOA_out = ymreg[14];
|
||||||
|
assign IOB_out = ymreg[15];
|
||||||
|
|
||||||
assign IOA_out = ymreg[14];
|
reg [7:0] addr;
|
||||||
assign IOB_out = ymreg[15];
|
reg [7:0] ymreg[16];
|
||||||
|
|
||||||
reg ena_div;
|
// Write to PSG
|
||||||
reg ena_div_noise;
|
reg env_reset;
|
||||||
reg [7:0] addr;
|
always @(posedge CLK) begin
|
||||||
reg [7:0] ymreg[16];
|
if(RESET) begin
|
||||||
reg env_ena;
|
ymreg <= '{default:0};
|
||||||
reg [4:0] env_vol;
|
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] volTableAy[16] =
|
// Read from PSG
|
||||||
'{8'h00, 8'h03, 8'h04, 8'h06,
|
|
||||||
8'h0a, 8'h0f, 8'h15, 8'h22,
|
|
||||||
8'h28, 8'h41, 8'h5b, 8'h72,
|
|
||||||
8'h90, 8'hb5, 8'hd7, 8'hff
|
|
||||||
};
|
|
||||||
|
|
||||||
wire [7:0] volTableYm[32] =
|
|
||||||
'{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,82 +253,49 @@ always @(posedge CLK) begin
|
|||||||
//
|
//
|
||||||
// 1 1 1 1 /___
|
// 1 1 1 1 /___
|
||||||
|
|
||||||
if(RESET) begin
|
if(env_reset | RESET) begin
|
||||||
ymreg[0] <= '0;
|
// load initial state
|
||||||
ymreg[1] <= '0;
|
if(!ymreg[13][2]) begin // attack
|
||||||
ymreg[2] <= '0;
|
env_vol <= 5'b11111;
|
||||||
ymreg[3] <= '0;
|
env_inc <= 0; // -1
|
||||||
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
|
|
||||||
if(!ymreg[13][2]) begin // attack
|
|
||||||
env_vol <= 5'b11111;
|
|
||||||
env_inc <= 0; // -1
|
|
||||||
end else begin
|
|
||||||
env_vol <= 5'b00000;
|
|
||||||
env_inc <= 1; // +1
|
|
||||||
end
|
|
||||||
env_hold <= 0;
|
|
||||||
end else begin
|
end else begin
|
||||||
|
env_vol <= 5'b00000;
|
||||||
|
env_inc <= 1; // +1
|
||||||
|
end
|
||||||
|
env_hold <= 0;
|
||||||
|
end
|
||||||
|
else if(CE) begin
|
||||||
|
if (env_ena) begin
|
||||||
|
if (!env_hold) begin
|
||||||
|
if (env_inc) env_vol <= (env_vol + 5'b00001);
|
||||||
|
else env_vol <= (env_vol + 5'b11111);
|
||||||
|
end
|
||||||
|
|
||||||
if (env_ena) begin
|
// envelope shape control.
|
||||||
if (!env_hold) begin
|
if(!ymreg[13][3]) begin
|
||||||
if (env_inc) env_vol <= (env_vol + 5'b00001);
|
if(!env_inc) begin // down
|
||||||
else env_vol <= (env_vol + 5'b11111);
|
if(is_bot_p1) env_hold <= 1;
|
||||||
end
|
end else if (is_top) env_hold <= 1;
|
||||||
|
end else if(ymreg[13][0]) begin // hold = 1
|
||||||
// envelope shape control.
|
if(!env_inc) begin // down
|
||||||
if(!ymreg[13][3]) begin
|
if(ymreg[13][1]) begin // alt
|
||||||
if(!env_inc) begin // down
|
if(is_bot) env_hold <= 1;
|
||||||
if(is_bot_p1) env_hold <= 1;
|
end else if(is_bot_p1) env_hold <= 1;
|
||||||
end else if (is_top) env_hold <= 1;
|
end else if(ymreg[13][1]) begin // alt
|
||||||
end else if(ymreg[13][0]) begin // hold = 1
|
if(is_top) env_hold <= 1;
|
||||||
if(!env_inc) begin // down
|
end else if(is_top_m1) env_hold <= 1;
|
||||||
if(ymreg[13][1]) begin // alt
|
end else if(ymreg[13][1]) begin // alternate
|
||||||
if(is_bot) env_hold <= 1;
|
if(env_inc == 1'b0) begin // down
|
||||||
end else if(is_bot_p1) env_hold <= 1;
|
if(is_bot_p1) env_hold <= 1;
|
||||||
end else if(ymreg[13][1]) begin // alt
|
if(is_bot) begin
|
||||||
if(is_top) env_hold <= 1;
|
env_hold <= 0;
|
||||||
end else if(is_top_m1) env_hold <= 1;
|
env_inc <= 1;
|
||||||
end else if(ymreg[13][1]) begin // alternate
|
end
|
||||||
if(env_inc == 1'b0) begin // down
|
end else begin
|
||||||
if(is_bot_p1) env_hold <= 1;
|
if(is_top_m1) env_hold <= 1;
|
||||||
if(is_bot) begin
|
if(is_top) begin
|
||||||
env_hold <= 0;
|
env_hold <= 0;
|
||||||
env_inc <= 1;
|
env_inc <= 0;
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
if(is_top_m1) env_hold <= 1;
|
|
||||||
if(is_top) begin
|
|
||||||
env_hold <= 0;
|
|
||||||
env_inc <= 0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -343,12 +303,29 @@ always @(posedge CLK) begin
|
|||||||
end
|
end
|
||||||
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]};
|
reg [5:0] A,B,C;
|
||||||
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]};
|
always @(posedge CLK) begin
|
||||||
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]};
|
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
|
||||||
|
|
||||||
assign CHANNEL_A = MODE ? volTableAy[A[4:1]] : volTableYm[A];
|
wire [7:0] volTable[64] = '{
|
||||||
assign CHANNEL_B = MODE ? volTableAy[B[4:1]] : volTableYm[B];
|
//YM2149
|
||||||
assign CHANNEL_C = MODE ? volTableAy[C[4:1]] : volTableYm[C];
|
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,
|
||||||
|
|
||||||
|
//AY8910
|
||||||
|
8'h00, 8'h00, 8'h03, 8'h03, 8'h04, 8'h04, 8'h06, 8'h06,
|
||||||
|
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
|
||||||
|
@ -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),
|
||||||
|
Reference in New Issue
Block a user