diff --git a/Audio/ch_pcma.v b/Audio/ch_pcma.v new file mode 100644 index 0000000..4b4f93a --- /dev/null +++ b/Audio/ch_pcma.v @@ -0,0 +1,135 @@ +module ch_pcma( + input CLK, + input CLK_SAMP, + input nRESET, + input FLAGMASK, + output reg END_FLAG, + input KEYON, KEYOFF, + + input [11:0] JEDI_DOUT, + input [15:0] ADDR_START, + input [15:0] ADDR_STOP, + input [7:0] VOLPAN, // TODO: This :) Also see ADPCM-A total level + output [21:0] ROM_ADDR, + output reg [3:0] DATA, + output reg [9:0] ADPCM_STEP, // 0~768 + input [7:0] ROM_DATA, + output reg [15:0] SAMPLE_OUT +); + + reg RUN; + reg [1:0] ROM_BANK; + reg [19:0] ADDR_CNT; + reg NIBBLE; + reg [11:0] ADPCM_ACC; + + reg SET_FLAG; + reg PREV_FLAGMASK; + + assign ROM_ADDR = { ROM_BANK, ADDR_CNT }; + + always @(posedge CLK) + begin + if (!nRESET) + begin + SET_FLAG <= 0; // ? + PREV_FLAGMASK <= 0; // ? + RUN <= 0; + end + else + begin + + if (KEYON) + begin + ADDR_CNT <= { ADDR_START[11:0], 8'h0 }; + ROM_BANK <= ADDR_START[13:12]; // Should be 4 bits in real YM2610 (16M ROMs max., not 4M) + END_FLAG <= 0; + NIBBLE <= 0; // ? + ADPCM_ACC <= 0; + ADPCM_STEP <= 0; + RUN <= 1; + end + + if (KEYOFF) + RUN <= 0; + + // Get one sample: + if (RUN && CLK_SAMP) + begin + // Edge detect, clear flag + if ((FLAGMASK == 1) && (PREV_FLAGMASK == 0)) + END_FLAG <= 0; + + PREV_FLAGMASK <= FLAGMASK; + + if (ADDR_CNT[19:8] == ADDR_STOP[11:0]) + begin + // Edge detect, set flag if not masked + if (SET_FLAG == 0) + begin + SET_FLAG <= 1; + END_FLAG <= ~FLAGMASK; + end + end + else + begin + SET_FLAG <= 0; + + if (NIBBLE) + begin + DATA <= ROM_DATA[3:0]; + ADDR_CNT <= ADDR_CNT + 1'b1; + end + else + DATA <= ROM_DATA[7:4]; + + ADPCM_ACC <= ADPCM_ACC + JEDI_DOUT; + + case (DATA[2:0]) + 0, 1, 2, 3 : + begin + if (ADPCM_STEP >= 16) + ADPCM_STEP <= ADPCM_STEP - 10'd16; + else + ADPCM_STEP <= 0; + end + 4 : + begin + if (ADPCM_STEP <= (768 - 32)) + ADPCM_STEP <= ADPCM_STEP + 10'd32; + else + ADPCM_STEP <= 768; + end + 5 : + begin + if (ADPCM_STEP <= (768 - 80)) + ADPCM_STEP <= ADPCM_STEP + 10'd80; + else + ADPCM_STEP <= 768; + end + 6 : + begin + if (ADPCM_STEP <= (768 - 112)) + ADPCM_STEP <= ADPCM_STEP + 10'd112; + else + ADPCM_STEP <= 768; + end + 7 : + begin + if (ADPCM_STEP <= (768 - 144)) + ADPCM_STEP <= ADPCM_STEP + 10'd144; + else + ADPCM_STEP <= 768; + end + endcase + + // Sign-extend 12 to 16 + SAMPLE_OUT <= ADPCM_ACC[11] ? { 4'b1111, ADPCM_ACC } : { 4'b0000, ADPCM_ACC }; + + NIBBLE <= ~NIBBLE; + end + end + end + end + +endmodule diff --git a/Audio/ch_pcmb.v b/Audio/ch_pcmb.v new file mode 100644 index 0000000..74c8369 --- /dev/null +++ b/Audio/ch_pcmb.v @@ -0,0 +1,209 @@ +module ch_pcmb( + input CLK, + input TICK_144, + input CLK_SAMP, + input nRESET, + input FLAGMASK, + output reg END_FLAG, + input START, RESET, REPEAT, + + input [7:0] VOL, + input [1:0] PAN, + input [15:0] PCMB_DELTA, + + input [15:0] ADDR_START, + input [15:0] ADDR_STOP, + + output [21:0] ROM_ADDR, + input [7:0] ROM_DATA, + output reg [15:0] SAMPLE_OUT, + output reg ACCESS +); + + reg [1:0] ROM_BANK; + reg [19:0] ADDR_CNT; + reg NIBBLE; + reg signed [15:0] ADPCM_ACC; + reg [3:0] DATA; + reg [9:0] ADPCM_STEP; + + reg SET_FLAG; + reg PREV_FLAGMASK; + + reg DELTA_OVF; + reg [15:0] DELTA_CNT; + + reg RUN; + reg [19:0] SR_1; + reg [19:0] RESULT_B1; + + wire [3:0] TABLE_B1_ADDR; + wire signed [4:0] TABLE_B1_OUT; + reg signed [4:0] TABLE_OUT; + wire [2:0] TABLE_B2_ADDR; // 3:0 but 2x repeat + wire signed [7:0] TABLE_B2_OUT; + + assign ROM_ADDR = { ROM_BANK, ADDR_CNT }; + + pcmb_tables u1(DATA, TABLE_B1_OUT, DATA[2:0], TABLE_B2_OUT); + + always @(posedge CLK) + begin + if (!nRESET) + begin + SET_FLAG <= 0; // ? + PREV_FLAGMASK <= 0; // ? + RUN <= 0; + ACCESS <= 0; // ? + end + else + begin + + // MUL-1 + // Multiplier = smaller + // Init SR_1 with Acc (sign extend !), clear RESULT_B1 + // Acc min/max: -32768/32767 (16bit signed) + // TABLE_OUT min/max: -15/15 (5bit signed) + // RESULT_B1: 16+5-1 = 20 bits + if (TABLE_B1_OUT[0]) + RESULT_B1 <= RESULT_B1 + SR_1; + TABLE_OUT <= TABLE_OUT >>> 1; // ASR + // Cap isn't needed ? + SR_1 <= { SR_1[18:0], 1'b0 }; // LSL + + // MUL-2 + // Multiplier = smaller + // Init SR and MULTIPLIER, clear RESULT + // Acc min/max: 24/24576 (16bit unsigned) + // MULTIPLIER min/max: 57/153 (8bit unsigned) + /* + if (MULTIPLIER[0]) + RESULT <= RESULT + SR; + MULTIPLIER <= { 1'b0, MULTIPLIER[3:1] }; // Shift right + SR <= { SR[2:0], 1'b0 }; // Shift left + */ + + if (RESET) + begin + // ??? + end + + if (START) + begin + ADDR_CNT <= { ADDR_START[11:0], 8'h0 }; + ROM_BANK <= ADDR_START[13:12]; // Should be 4 bits in real YM2610 (16M ROMs max., not 4M) + ADPCM_STEP <= 0; + ADPCM_ACC <= 0; + NIBBLE <= 0; // ? + DELTA_OVF <= 0; + DELTA_CNT <= 0; + END_FLAG <= 0; + RUN <= 1; + ACCESS <= 0; // ? + end + + if (RUN & TICK_144) + begin + { DELTA_OVF, DELTA_CNT } <= DELTA_CNT + PCMB_DELTA; + if (DELTA_OVF) + begin + DELTA_CNT <= 0; + DELTA_OVF <= 0; + ACCESS <= 1; // Probably simpler + end + end + + // Get one sample: + if (RUN && CLK_SAMP) + begin + ACCESS <= 0; // Probably simpler + + // Edge detect, clear flag + if ((FLAGMASK == 1) && (PREV_FLAGMASK == 0)) + END_FLAG <= 0; + + PREV_FLAGMASK <= FLAGMASK; + + if (ADDR_CNT[19:8] == ADDR_STOP[11:0]) + begin + if (REPEAT) + begin + ADDR_CNT <= { ADDR_START[11:0], 8'h0 }; + ROM_BANK <= ADDR_START[13:12]; // Should be 4 bits in real YM2610 (16M ROMs max., not 4M) + ADPCM_STEP <= 0; + ADPCM_ACC <= 0; + NIBBLE <= 0; // ? + end + else + begin + // Edge detect, set flag if not masked + if (SET_FLAG == 0) + begin + SET_FLAG <= 1; + END_FLAG <= ~FLAGMASK; + end + end + end + else + begin + SET_FLAG <= 0; + + if (NIBBLE) + begin + DATA <= ROM_DATA[3:0]; + ADDR_CNT <= ADDR_CNT + 1'b1; + end + else + DATA <= ROM_DATA[7:4]; + + ADPCM_ACC <= ADPCM_ACC + RESULT_B1; + //ADPCM_DELTA <= ADPCM_DELTA + MUL2_OUT; + + case (DATA[2:0]) + 0, 1, 2, 3 : + begin + if (ADPCM_STEP >= 16) + ADPCM_STEP <= ADPCM_STEP - 10'd16; + else + ADPCM_STEP <= 0; + end + 4 : + begin + if (ADPCM_STEP <= (768 - 32)) + ADPCM_STEP <= ADPCM_STEP + 10'd32; + else + ADPCM_STEP <= 768; + end + 5 : + begin + if (ADPCM_STEP <= (768 - 80)) + ADPCM_STEP <= ADPCM_STEP + 10'd80; + else + ADPCM_STEP <= 768; + end + 6 : + begin + if (ADPCM_STEP <= (768 - 112)) + ADPCM_STEP <= ADPCM_STEP + 10'd112; + else + ADPCM_STEP <= 768; + end + 7 : + begin + if (ADPCM_STEP <= (768 - 144)) + ADPCM_STEP <= ADPCM_STEP + 10'd144; + else + ADPCM_STEP <= 768; + end + endcase + + // Sign-extend 12 to 16 + SAMPLE_OUT <= ADPCM_ACC[11] ? { 4'b1111, ADPCM_ACC } : { 4'b0000, ADPCM_ACC }; + + NIBBLE <= ~NIBBLE; + end + end + end + end + +endmodule diff --git a/Audio/jedi.v b/Audio/jedi.v new file mode 100644 index 0000000..094825e --- /dev/null +++ b/Audio/jedi.v @@ -0,0 +1,799 @@ +module jedi_lut ( + output reg [15:0] dout, + input [13:0] address +); + + // Todo: dout could be only 12 bits ? + + always @(address) + begin + case (address) + 14'd0 : dout <= 16'd2; + 14'd1 : dout <= 16'd6; + 14'd2 : dout <= 16'd10; + 14'd3 : dout <= 16'd14; + 14'd4 : dout <= 16'd18; + 14'd5 : dout <= 16'd22; + 14'd6 : dout <= 16'd26; + 14'd7 : dout <= 16'd30; + 14'd8 : dout <= -16'd2; + 14'd9 : dout <= -16'd6; + 14'd10 : dout <= -16'd10; + 14'd11 : dout <= -16'd14; + 14'd12 : dout <= -16'd18; + 14'd13 : dout <= -16'd22; + 14'd14 : dout <= -16'd26; + 14'd15 : dout <= -16'd30; + 14'd16 : dout <= 16'd2; + 14'd17 : dout <= 16'd6; + 14'd18 : dout <= 16'd10; + 14'd19 : dout <= 16'd14; + 14'd20 : dout <= 16'd19; + 14'd21 : dout <= 16'd23; + 14'd22 : dout <= 16'd27; + 14'd23 : dout <= 16'd31; + 14'd24 : dout <= -16'd2; + 14'd25 : dout <= -16'd6; + 14'd26 : dout <= -16'd10; + 14'd27 : dout <= -16'd14; + 14'd28 : dout <= -16'd19; + 14'd29 : dout <= -16'd23; + 14'd30 : dout <= -16'd27; + 14'd31 : dout <= -16'd31; + 14'd32 : dout <= 16'd2; + 14'd33 : dout <= 16'd7; + 14'd34 : dout <= 16'd11; + 14'd35 : dout <= 16'd16; + 14'd36 : dout <= 16'd21; + 14'd37 : dout <= 16'd26; + 14'd38 : dout <= 16'd30; + 14'd39 : dout <= 16'd35; + 14'd40 : dout <= -16'd2; + 14'd41 : dout <= -16'd7; + 14'd42 : dout <= -16'd11; + 14'd43 : dout <= -16'd16; + 14'd44 : dout <= -16'd21; + 14'd45 : dout <= -16'd26; + 14'd46 : dout <= -16'd30; + 14'd47 : dout <= -16'd35; + 14'd48 : dout <= 16'd2; + 14'd49 : dout <= 16'd7; + 14'd50 : dout <= 16'd13; + 14'd51 : dout <= 16'd18; + 14'd52 : dout <= 16'd23; + 14'd53 : dout <= 16'd28; + 14'd54 : dout <= 16'd34; + 14'd55 : dout <= 16'd39; + 14'd56 : dout <= -16'd2; + 14'd57 : dout <= -16'd7; + 14'd58 : dout <= -16'd13; + 14'd59 : dout <= -16'd18; + 14'd60 : dout <= -16'd23; + 14'd61 : dout <= -16'd28; + 14'd62 : dout <= -16'd34; + 14'd63 : dout <= -16'd39; + 14'd64 : dout <= 16'd2; + 14'd65 : dout <= 16'd8; + 14'd66 : dout <= 16'd14; + 14'd67 : dout <= 16'd20; + 14'd68 : dout <= 16'd25; + 14'd69 : dout <= 16'd31; + 14'd70 : dout <= 16'd37; + 14'd71 : dout <= 16'd43; + 14'd72 : dout <= -16'd2; + 14'd73 : dout <= -16'd8; + 14'd74 : dout <= -16'd14; + 14'd75 : dout <= -16'd20; + 14'd76 : dout <= -16'd25; + 14'd77 : dout <= -16'd31; + 14'd78 : dout <= -16'd37; + 14'd79 : dout <= -16'd43; + 14'd80 : dout <= 16'd3; + 14'd81 : dout <= 16'd9; + 14'd82 : dout <= 16'd15; + 14'd83 : dout <= 16'd21; + 14'd84 : dout <= 16'd28; + 14'd85 : dout <= 16'd34; + 14'd86 : dout <= 16'd40; + 14'd87 : dout <= 16'd46; + 14'd88 : dout <= -16'd3; + 14'd89 : dout <= -16'd9; + 14'd90 : dout <= -16'd15; + 14'd91 : dout <= -16'd21; + 14'd92 : dout <= -16'd28; + 14'd93 : dout <= -16'd34; + 14'd94 : dout <= -16'd40; + 14'd95 : dout <= -16'd46; + 14'd96 : dout <= 16'd3; + 14'd97 : dout <= 16'd10; + 14'd98 : dout <= 16'd17; + 14'd99 : dout <= 16'd24; + 14'd100 : dout <= 16'd31; + 14'd101 : dout <= 16'd38; + 14'd102 : dout <= 16'd45; + 14'd103 : dout <= 16'd52; + 14'd104 : dout <= -16'd3; + 14'd105 : dout <= -16'd10; + 14'd106 : dout <= -16'd17; + 14'd107 : dout <= -16'd24; + 14'd108 : dout <= -16'd31; + 14'd109 : dout <= -16'd38; + 14'd110 : dout <= -16'd45; + 14'd111 : dout <= -16'd52; + 14'd112 : dout <= 16'd3; + 14'd113 : dout <= 16'd11; + 14'd114 : dout <= 16'd19; + 14'd115 : dout <= 16'd27; + 14'd116 : dout <= 16'd34; + 14'd117 : dout <= 16'd42; + 14'd118 : dout <= 16'd50; + 14'd119 : dout <= 16'd58; + 14'd120 : dout <= -16'd3; + 14'd121 : dout <= -16'd11; + 14'd122 : dout <= -16'd19; + 14'd123 : dout <= -16'd27; + 14'd124 : dout <= -16'd34; + 14'd125 : dout <= -16'd42; + 14'd126 : dout <= -16'd50; + 14'd127 : dout <= -16'd58; + 14'd128 : dout <= 16'd4; + 14'd129 : dout <= 16'd12; + 14'd130 : dout <= 16'd21; + 14'd131 : dout <= 16'd29; + 14'd132 : dout <= 16'd38; + 14'd133 : dout <= 16'd46; + 14'd134 : dout <= 16'd55; + 14'd135 : dout <= 16'd63; + 14'd136 : dout <= -16'd4; + 14'd137 : dout <= -16'd12; + 14'd138 : dout <= -16'd21; + 14'd139 : dout <= -16'd29; + 14'd140 : dout <= -16'd38; + 14'd141 : dout <= -16'd46; + 14'd142 : dout <= -16'd55; + 14'd143 : dout <= -16'd63; + 14'd144 : dout <= 16'd4; + 14'd145 : dout <= 16'd13; + 14'd146 : dout <= 16'd23; + 14'd147 : dout <= 16'd32; + 14'd148 : dout <= 16'd41; + 14'd149 : dout <= 16'd50; + 14'd150 : dout <= 16'd60; + 14'd151 : dout <= 16'd69; + 14'd152 : dout <= -16'd4; + 14'd153 : dout <= -16'd13; + 14'd154 : dout <= -16'd23; + 14'd155 : dout <= -16'd32; + 14'd156 : dout <= -16'd41; + 14'd157 : dout <= -16'd50; + 14'd158 : dout <= -16'd60; + 14'd159 : dout <= -16'd69; + 14'd160 : dout <= 16'd5; + 14'd161 : dout <= 16'd15; + 14'd162 : dout <= 16'd25; + 14'd163 : dout <= 16'd35; + 14'd164 : dout <= 16'd46; + 14'd165 : dout <= 16'd56; + 14'd166 : dout <= 16'd66; + 14'd167 : dout <= 16'd76; + 14'd168 : dout <= -16'd5; + 14'd169 : dout <= -16'd15; + 14'd170 : dout <= -16'd25; + 14'd171 : dout <= -16'd35; + 14'd172 : dout <= -16'd46; + 14'd173 : dout <= -16'd56; + 14'd174 : dout <= -16'd66; + 14'd175 : dout <= -16'd76; + 14'd176 : dout <= 16'd5; + 14'd177 : dout <= 16'd16; + 14'd178 : dout <= 16'd28; + 14'd179 : dout <= 16'd39; + 14'd180 : dout <= 16'd50; + 14'd181 : dout <= 16'd61; + 14'd182 : dout <= 16'd73; + 14'd183 : dout <= 16'd84; + 14'd184 : dout <= -16'd5; + 14'd185 : dout <= -16'd16; + 14'd186 : dout <= -16'd28; + 14'd187 : dout <= -16'd39; + 14'd188 : dout <= -16'd50; + 14'd189 : dout <= -16'd61; + 14'd190 : dout <= -16'd73; + 14'd191 : dout <= -16'd84; + 14'd192 : dout <= 16'd6; + 14'd193 : dout <= 16'd18; + 14'd194 : dout <= 16'd31; + 14'd195 : dout <= 16'd43; + 14'd196 : dout <= 16'd56; + 14'd197 : dout <= 16'd68; + 14'd198 : dout <= 16'd81; + 14'd199 : dout <= 16'd93; + 14'd200 : dout <= -16'd6; + 14'd201 : dout <= -16'd18; + 14'd202 : dout <= -16'd31; + 14'd203 : dout <= -16'd43; + 14'd204 : dout <= -16'd56; + 14'd205 : dout <= -16'd68; + 14'd206 : dout <= -16'd81; + 14'd207 : dout <= -16'd93; + 14'd208 : dout <= 16'd6; + 14'd209 : dout <= 16'd20; + 14'd210 : dout <= 16'd34; + 14'd211 : dout <= 16'd48; + 14'd212 : dout <= 16'd61; + 14'd213 : dout <= 16'd75; + 14'd214 : dout <= 16'd89; + 14'd215 : dout <= 16'd103; + 14'd216 : dout <= -16'd6; + 14'd217 : dout <= -16'd20; + 14'd218 : dout <= -16'd34; + 14'd219 : dout <= -16'd48; + 14'd220 : dout <= -16'd61; + 14'd221 : dout <= -16'd75; + 14'd222 : dout <= -16'd89; + 14'd223 : dout <= -16'd103; + 14'd224 : dout <= 16'd7; + 14'd225 : dout <= 16'd22; + 14'd226 : dout <= 16'd37; + 14'd227 : dout <= 16'd52; + 14'd228 : dout <= 16'd67; + 14'd229 : dout <= 16'd82; + 14'd230 : dout <= 16'd97; + 14'd231 : dout <= 16'd112; + 14'd232 : dout <= -16'd7; + 14'd233 : dout <= -16'd22; + 14'd234 : dout <= -16'd37; + 14'd235 : dout <= -16'd52; + 14'd236 : dout <= -16'd67; + 14'd237 : dout <= -16'd82; + 14'd238 : dout <= -16'd97; + 14'd239 : dout <= -16'd112; + 14'd240 : dout <= 16'd8; + 14'd241 : dout <= 16'd24; + 14'd242 : dout <= 16'd41; + 14'd243 : dout <= 16'd57; + 14'd244 : dout <= 16'd74; + 14'd245 : dout <= 16'd90; + 14'd246 : dout <= 16'd107; + 14'd247 : dout <= 16'd123; + 14'd248 : dout <= -16'd8; + 14'd249 : dout <= -16'd24; + 14'd250 : dout <= -16'd41; + 14'd251 : dout <= -16'd57; + 14'd252 : dout <= -16'd74; + 14'd253 : dout <= -16'd90; + 14'd254 : dout <= -16'd107; + 14'd255 : dout <= -16'd123; + 14'd256 : dout <= 16'd9; + 14'd257 : dout <= 16'd27; + 14'd258 : dout <= 16'd45; + 14'd259 : dout <= 16'd63; + 14'd260 : dout <= 16'd82; + 14'd261 : dout <= 16'd100; + 14'd262 : dout <= 16'd118; + 14'd263 : dout <= 16'd136; + 14'd264 : dout <= -16'd9; + 14'd265 : dout <= -16'd27; + 14'd266 : dout <= -16'd45; + 14'd267 : dout <= -16'd63; + 14'd268 : dout <= -16'd82; + 14'd269 : dout <= -16'd100; + 14'd270 : dout <= -16'd118; + 14'd271 : dout <= -16'd136; + 14'd272 : dout <= 16'd10; + 14'd273 : dout <= 16'd30; + 14'd274 : dout <= 16'd50; + 14'd275 : dout <= 16'd70; + 14'd276 : dout <= 16'd90; + 14'd277 : dout <= 16'd110; + 14'd278 : dout <= 16'd130; + 14'd279 : dout <= 16'd150; + 14'd280 : dout <= -16'd10; + 14'd281 : dout <= -16'd30; + 14'd282 : dout <= -16'd50; + 14'd283 : dout <= -16'd70; + 14'd284 : dout <= -16'd90; + 14'd285 : dout <= -16'd110; + 14'd286 : dout <= -16'd130; + 14'd287 : dout <= -16'd150; + 14'd288 : dout <= 16'd11; + 14'd289 : dout <= 16'd33; + 14'd290 : dout <= 16'd55; + 14'd291 : dout <= 16'd77; + 14'd292 : dout <= 16'd99; + 14'd293 : dout <= 16'd121; + 14'd294 : dout <= 16'd143; + 14'd295 : dout <= 16'd165; + 14'd296 : dout <= -16'd11; + 14'd297 : dout <= -16'd33; + 14'd298 : dout <= -16'd55; + 14'd299 : dout <= -16'd77; + 14'd300 : dout <= -16'd99; + 14'd301 : dout <= -16'd121; + 14'd302 : dout <= -16'd143; + 14'd303 : dout <= -16'd165; + 14'd304 : dout <= 16'd12; + 14'd305 : dout <= 16'd36; + 14'd306 : dout <= 16'd60; + 14'd307 : dout <= 16'd84; + 14'd308 : dout <= 16'd109; + 14'd309 : dout <= 16'd133; + 14'd310 : dout <= 16'd157; + 14'd311 : dout <= 16'd181; + 14'd312 : dout <= -16'd12; + 14'd313 : dout <= -16'd36; + 14'd314 : dout <= -16'd60; + 14'd315 : dout <= -16'd84; + 14'd316 : dout <= -16'd109; + 14'd317 : dout <= -16'd133; + 14'd318 : dout <= -16'd157; + 14'd319 : dout <= -16'd181; + 14'd320 : dout <= 16'd13; + 14'd321 : dout <= 16'd40; + 14'd322 : dout <= 16'd66; + 14'd323 : dout <= 16'd93; + 14'd324 : dout <= 16'd120; + 14'd325 : dout <= 16'd147; + 14'd326 : dout <= 16'd173; + 14'd327 : dout <= 16'd200; + 14'd328 : dout <= -16'd13; + 14'd329 : dout <= -16'd40; + 14'd330 : dout <= -16'd66; + 14'd331 : dout <= -16'd93; + 14'd332 : dout <= -16'd120; + 14'd333 : dout <= -16'd147; + 14'd334 : dout <= -16'd173; + 14'd335 : dout <= -16'd200; + 14'd336 : dout <= 16'd14; + 14'd337 : dout <= 16'd44; + 14'd338 : dout <= 16'd73; + 14'd339 : dout <= 16'd103; + 14'd340 : dout <= 16'd132; + 14'd341 : dout <= 16'd162; + 14'd342 : dout <= 16'd191; + 14'd343 : dout <= 16'd221; + 14'd344 : dout <= -16'd14; + 14'd345 : dout <= -16'd44; + 14'd346 : dout <= -16'd73; + 14'd347 : dout <= -16'd103; + 14'd348 : dout <= -16'd132; + 14'd349 : dout <= -16'd162; + 14'd350 : dout <= -16'd191; + 14'd351 : dout <= -16'd221; + 14'd352 : dout <= 16'd16; + 14'd353 : dout <= 16'd48; + 14'd354 : dout <= 16'd81; + 14'd355 : dout <= 16'd113; + 14'd356 : dout <= 16'd146; + 14'd357 : dout <= 16'd178; + 14'd358 : dout <= 16'd211; + 14'd359 : dout <= 16'd243; + 14'd360 : dout <= -16'd16; + 14'd361 : dout <= -16'd48; + 14'd362 : dout <= -16'd81; + 14'd363 : dout <= -16'd113; + 14'd364 : dout <= -16'd146; + 14'd365 : dout <= -16'd178; + 14'd366 : dout <= -16'd211; + 14'd367 : dout <= -16'd243; + 14'd368 : dout <= 16'd17; + 14'd369 : dout <= 16'd53; + 14'd370 : dout <= 16'd89; + 14'd371 : dout <= 16'd125; + 14'd372 : dout <= 16'd160; + 14'd373 : dout <= 16'd196; + 14'd374 : dout <= 16'd232; + 14'd375 : dout <= 16'd268; + 14'd376 : dout <= -16'd17; + 14'd377 : dout <= -16'd53; + 14'd378 : dout <= -16'd89; + 14'd379 : dout <= -16'd125; + 14'd380 : dout <= -16'd160; + 14'd381 : dout <= -16'd196; + 14'd382 : dout <= -16'd232; + 14'd383 : dout <= -16'd268; + 14'd384 : dout <= 16'd19; + 14'd385 : dout <= 16'd58; + 14'd386 : dout <= 16'd98; + 14'd387 : dout <= 16'd137; + 14'd388 : dout <= 16'd176; + 14'd389 : dout <= 16'd215; + 14'd390 : dout <= 16'd255; + 14'd391 : dout <= 16'd294; + 14'd392 : dout <= -16'd19; + 14'd393 : dout <= -16'd58; + 14'd394 : dout <= -16'd98; + 14'd395 : dout <= -16'd137; + 14'd396 : dout <= -16'd176; + 14'd397 : dout <= -16'd215; + 14'd398 : dout <= -16'd255; + 14'd399 : dout <= -16'd294; + 14'd400 : dout <= 16'd21; + 14'd401 : dout <= 16'd64; + 14'd402 : dout <= 16'd108; + 14'd403 : dout <= 16'd151; + 14'd404 : dout <= 16'd194; + 14'd405 : dout <= 16'd237; + 14'd406 : dout <= 16'd281; + 14'd407 : dout <= 16'd324; + 14'd408 : dout <= -16'd21; + 14'd409 : dout <= -16'd64; + 14'd410 : dout <= -16'd108; + 14'd411 : dout <= -16'd151; + 14'd412 : dout <= -16'd194; + 14'd413 : dout <= -16'd237; + 14'd414 : dout <= -16'd281; + 14'd415 : dout <= -16'd324; + 14'd416 : dout <= 16'd23; + 14'd417 : dout <= 16'd71; + 14'd418 : dout <= 16'd118; + 14'd419 : dout <= 16'd166; + 14'd420 : dout <= 16'd213; + 14'd421 : dout <= 16'd261; + 14'd422 : dout <= 16'd308; + 14'd423 : dout <= 16'd356; + 14'd424 : dout <= -16'd23; + 14'd425 : dout <= -16'd71; + 14'd426 : dout <= -16'd118; + 14'd427 : dout <= -16'd166; + 14'd428 : dout <= -16'd213; + 14'd429 : dout <= -16'd261; + 14'd430 : dout <= -16'd308; + 14'd431 : dout <= -16'd356; + 14'd432 : dout <= 16'd26; + 14'd433 : dout <= 16'd78; + 14'd434 : dout <= 16'd130; + 14'd435 : dout <= 16'd182; + 14'd436 : dout <= 16'd235; + 14'd437 : dout <= 16'd287; + 14'd438 : dout <= 16'd339; + 14'd439 : dout <= 16'd391; + 14'd440 : dout <= -16'd26; + 14'd441 : dout <= -16'd78; + 14'd442 : dout <= -16'd130; + 14'd443 : dout <= -16'd182; + 14'd444 : dout <= -16'd235; + 14'd445 : dout <= -16'd287; + 14'd446 : dout <= -16'd339; + 14'd447 : dout <= -16'd391; + 14'd448 : dout <= 16'd28; + 14'd449 : dout <= 16'd86; + 14'd450 : dout <= 16'd143; + 14'd451 : dout <= 16'd201; + 14'd452 : dout <= 16'd258; + 14'd453 : dout <= 16'd316; + 14'd454 : dout <= 16'd373; + 14'd455 : dout <= 16'd431; + 14'd456 : dout <= -16'd28; + 14'd457 : dout <= -16'd86; + 14'd458 : dout <= -16'd143; + 14'd459 : dout <= -16'd201; + 14'd460 : dout <= -16'd258; + 14'd461 : dout <= -16'd316; + 14'd462 : dout <= -16'd373; + 14'd463 : dout <= -16'd431; + 14'd464 : dout <= 16'd31; + 14'd465 : dout <= 16'd94; + 14'd466 : dout <= 16'd158; + 14'd467 : dout <= 16'd221; + 14'd468 : dout <= 16'd284; + 14'd469 : dout <= 16'd347; + 14'd470 : dout <= 16'd411; + 14'd471 : dout <= 16'd474; + 14'd472 : dout <= -16'd31; + 14'd473 : dout <= -16'd94; + 14'd474 : dout <= -16'd158; + 14'd475 : dout <= -16'd221; + 14'd476 : dout <= -16'd284; + 14'd477 : dout <= -16'd347; + 14'd478 : dout <= -16'd411; + 14'd479 : dout <= -16'd474; + 14'd480 : dout <= 16'd34; + 14'd481 : dout <= 16'd104; + 14'd482 : dout <= 16'd174; + 14'd483 : dout <= 16'd244; + 14'd484 : dout <= 16'd313; + 14'd485 : dout <= 16'd383; + 14'd486 : dout <= 16'd453; + 14'd487 : dout <= 16'd523; + 14'd488 : dout <= -16'd34; + 14'd489 : dout <= -16'd104; + 14'd490 : dout <= -16'd174; + 14'd491 : dout <= -16'd244; + 14'd492 : dout <= -16'd313; + 14'd493 : dout <= -16'd383; + 14'd494 : dout <= -16'd453; + 14'd495 : dout <= -16'd523; + 14'd496 : dout <= 16'd38; + 14'd497 : dout <= 16'd115; + 14'd498 : dout <= 16'd191; + 14'd499 : dout <= 16'd268; + 14'd500 : dout <= 16'd345; + 14'd501 : dout <= 16'd422; + 14'd502 : dout <= 16'd498; + 14'd503 : dout <= 16'd575; + 14'd504 : dout <= -16'd38; + 14'd505 : dout <= -16'd115; + 14'd506 : dout <= -16'd191; + 14'd507 : dout <= -16'd268; + 14'd508 : dout <= -16'd345; + 14'd509 : dout <= -16'd422; + 14'd510 : dout <= -16'd498; + 14'd511 : dout <= -16'd575; + 14'd512 : dout <= 16'd42; + 14'd513 : dout <= 16'd126; + 14'd514 : dout <= 16'd210; + 14'd515 : dout <= 16'd294; + 14'd516 : dout <= 16'd379; + 14'd517 : dout <= 16'd463; + 14'd518 : dout <= 16'd547; + 14'd519 : dout <= 16'd631; + 14'd520 : dout <= -16'd42; + 14'd521 : dout <= -16'd126; + 14'd522 : dout <= -16'd210; + 14'd523 : dout <= -16'd294; + 14'd524 : dout <= -16'd379; + 14'd525 : dout <= -16'd463; + 14'd526 : dout <= -16'd547; + 14'd527 : dout <= -16'd631; + 14'd528 : dout <= 16'd46; + 14'd529 : dout <= 16'd139; + 14'd530 : dout <= 16'd231; + 14'd531 : dout <= 16'd324; + 14'd532 : dout <= 16'd417; + 14'd533 : dout <= 16'd510; + 14'd534 : dout <= 16'd602; + 14'd535 : dout <= 16'd695; + 14'd536 : dout <= -16'd46; + 14'd537 : dout <= -16'd139; + 14'd538 : dout <= -16'd231; + 14'd539 : dout <= -16'd324; + 14'd540 : dout <= -16'd417; + 14'd541 : dout <= -16'd510; + 14'd542 : dout <= -16'd602; + 14'd543 : dout <= -16'd695; + 14'd544 : dout <= 16'd51; + 14'd545 : dout <= 16'd153; + 14'd546 : dout <= 16'd255; + 14'd547 : dout <= 16'd357; + 14'd548 : dout <= 16'd459; + 14'd549 : dout <= 16'd561; + 14'd550 : dout <= 16'd663; + 14'd551 : dout <= 16'd765; + 14'd552 : dout <= -16'd51; + 14'd553 : dout <= -16'd153; + 14'd554 : dout <= -16'd255; + 14'd555 : dout <= -16'd357; + 14'd556 : dout <= -16'd459; + 14'd557 : dout <= -16'd561; + 14'd558 : dout <= -16'd663; + 14'd559 : dout <= -16'd765; + 14'd560 : dout <= 16'd56; + 14'd561 : dout <= 16'd168; + 14'd562 : dout <= 16'd280; + 14'd563 : dout <= 16'd392; + 14'd564 : dout <= 16'd505; + 14'd565 : dout <= 16'd617; + 14'd566 : dout <= 16'd729; + 14'd567 : dout <= 16'd841; + 14'd568 : dout <= -16'd56; + 14'd569 : dout <= -16'd168; + 14'd570 : dout <= -16'd280; + 14'd571 : dout <= -16'd392; + 14'd572 : dout <= -16'd505; + 14'd573 : dout <= -16'd617; + 14'd574 : dout <= -16'd729; + 14'd575 : dout <= -16'd841; + 14'd576 : dout <= 16'd61; + 14'd577 : dout <= 16'd185; + 14'd578 : dout <= 16'd308; + 14'd579 : dout <= 16'd432; + 14'd580 : dout <= 16'd555; + 14'd581 : dout <= 16'd679; + 14'd582 : dout <= 16'd802; + 14'd583 : dout <= 16'd926; + 14'd584 : dout <= -16'd61; + 14'd585 : dout <= -16'd185; + 14'd586 : dout <= -16'd308; + 14'd587 : dout <= -16'd432; + 14'd588 : dout <= -16'd555; + 14'd589 : dout <= -16'd679; + 14'd590 : dout <= -16'd802; + 14'd591 : dout <= -16'd926; + 14'd592 : dout <= 16'd68; + 14'd593 : dout <= 16'd204; + 14'd594 : dout <= 16'd340; + 14'd595 : dout <= 16'd476; + 14'd596 : dout <= 16'd612; + 14'd597 : dout <= 16'd748; + 14'd598 : dout <= 16'd884; + 14'd599 : dout <= 16'd1020; + 14'd600 : dout <= -16'd68; + 14'd601 : dout <= -16'd204; + 14'd602 : dout <= -16'd340; + 14'd603 : dout <= -16'd476; + 14'd604 : dout <= -16'd612; + 14'd605 : dout <= -16'd748; + 14'd606 : dout <= -16'd884; + 14'd607 : dout <= -16'd1020; + 14'd608 : dout <= 16'd74; + 14'd609 : dout <= 16'd224; + 14'd610 : dout <= 16'd373; + 14'd611 : dout <= 16'd523; + 14'd612 : dout <= 16'd672; + 14'd613 : dout <= 16'd822; + 14'd614 : dout <= 16'd971; + 14'd615 : dout <= 16'd1121; + 14'd616 : dout <= -16'd74; + 14'd617 : dout <= -16'd224; + 14'd618 : dout <= -16'd373; + 14'd619 : dout <= -16'd523; + 14'd620 : dout <= -16'd672; + 14'd621 : dout <= -16'd822; + 14'd622 : dout <= -16'd971; + 14'd623 : dout <= -16'd1121; + 14'd624 : dout <= 16'd82; + 14'd625 : dout <= 16'd246; + 14'd626 : dout <= 16'd411; + 14'd627 : dout <= 16'd575; + 14'd628 : dout <= 16'd740; + 14'd629 : dout <= 16'd904; + 14'd630 : dout <= 16'd1069; + 14'd631 : dout <= 16'd1233; + 14'd632 : dout <= -16'd82; + 14'd633 : dout <= -16'd246; + 14'd634 : dout <= -16'd411; + 14'd635 : dout <= -16'd575; + 14'd636 : dout <= -16'd740; + 14'd637 : dout <= -16'd904; + 14'd638 : dout <= -16'd1069; + 14'd639 : dout <= -16'd1233; + 14'd640 : dout <= 16'd90; + 14'd641 : dout <= 16'd271; + 14'd642 : dout <= 16'd452; + 14'd643 : dout <= 16'd633; + 14'd644 : dout <= 16'd814; + 14'd645 : dout <= 16'd995; + 14'd646 : dout <= 16'd1176; + 14'd647 : dout <= 16'd1357; + 14'd648 : dout <= -16'd90; + 14'd649 : dout <= -16'd271; + 14'd650 : dout <= -16'd452; + 14'd651 : dout <= -16'd633; + 14'd652 : dout <= -16'd814; + 14'd653 : dout <= -16'd995; + 14'd654 : dout <= -16'd1176; + 14'd655 : dout <= -16'd1357; + 14'd656 : dout <= 16'd99; + 14'd657 : dout <= 16'd298; + 14'd658 : dout <= 16'd497; + 14'd659 : dout <= 16'd696; + 14'd660 : dout <= 16'd895; + 14'd661 : dout <= 16'd1094; + 14'd662 : dout <= 16'd1293; + 14'd663 : dout <= 16'd1492; + 14'd664 : dout <= -16'd99; + 14'd665 : dout <= -16'd298; + 14'd666 : dout <= -16'd497; + 14'd667 : dout <= -16'd696; + 14'd668 : dout <= -16'd895; + 14'd669 : dout <= -16'd1094; + 14'd670 : dout <= -16'd1293; + 14'd671 : dout <= -16'd1492; + 14'd672 : dout <= 16'd109; + 14'd673 : dout <= 16'd328; + 14'd674 : dout <= 16'd547; + 14'd675 : dout <= 16'd766; + 14'd676 : dout <= 16'd985; + 14'd677 : dout <= 16'd1204; + 14'd678 : dout <= 16'd1423; + 14'd679 : dout <= 16'd1642; + 14'd680 : dout <= -16'd109; + 14'd681 : dout <= -16'd328; + 14'd682 : dout <= -16'd547; + 14'd683 : dout <= -16'd766; + 14'd684 : dout <= -16'd985; + 14'd685 : dout <= -16'd1204; + 14'd686 : dout <= -16'd1423; + 14'd687 : dout <= -16'd1642; + 14'd688 : dout <= 16'd120; + 14'd689 : dout <= 16'd361; + 14'd690 : dout <= 16'd601; + 14'd691 : dout <= 16'd842; + 14'd692 : dout <= 16'd1083; + 14'd693 : dout <= 16'd1324; + 14'd694 : dout <= 16'd1564; + 14'd695 : dout <= 16'd1805; + 14'd696 : dout <= -16'd120; + 14'd697 : dout <= -16'd361; + 14'd698 : dout <= -16'd601; + 14'd699 : dout <= -16'd842; + 14'd700 : dout <= -16'd1083; + 14'd701 : dout <= -16'd1324; + 14'd702 : dout <= -16'd1564; + 14'd703 : dout <= -16'd1805; + 14'd704 : dout <= 16'd132; + 14'd705 : dout <= 16'd397; + 14'd706 : dout <= 16'd662; + 14'd707 : dout <= 16'd927; + 14'd708 : dout <= 16'd1192; + 14'd709 : dout <= 16'd1457; + 14'd710 : dout <= 16'd1722; + 14'd711 : dout <= 16'd1987; + 14'd712 : dout <= -16'd132; + 14'd713 : dout <= -16'd397; + 14'd714 : dout <= -16'd662; + 14'd715 : dout <= -16'd927; + 14'd716 : dout <= -16'd1192; + 14'd717 : dout <= -16'd1457; + 14'd718 : dout <= -16'd1722; + 14'd719 : dout <= -16'd1987; + 14'd720 : dout <= 16'd145; + 14'd721 : dout <= 16'd437; + 14'd722 : dout <= 16'd728; + 14'd723 : dout <= 16'd1020; + 14'd724 : dout <= 16'd1311; + 14'd725 : dout <= 16'd1603; + 14'd726 : dout <= 16'd1894; + 14'd727 : dout <= 16'd2186; + 14'd728 : dout <= -16'd145; + 14'd729 : dout <= -16'd437; + 14'd730 : dout <= -16'd728; + 14'd731 : dout <= -16'd1020; + 14'd732 : dout <= -16'd1311; + 14'd733 : dout <= -16'd1603; + 14'd734 : dout <= -16'd1894; + 14'd735 : dout <= -16'd2186; + 14'd736 : dout <= 16'd160; + 14'd737 : dout <= 16'd480; + 14'd738 : dout <= 16'd801; + 14'd739 : dout <= 16'd1121; + 14'd740 : dout <= 16'd1442; + 14'd741 : dout <= 16'd1762; + 14'd742 : dout <= 16'd2083; + 14'd743 : dout <= 16'd2403; + 14'd744 : dout <= -16'd160; + 14'd745 : dout <= -16'd480; + 14'd746 : dout <= -16'd801; + 14'd747 : dout <= -16'd1121; + 14'd748 : dout <= -16'd1442; + 14'd749 : dout <= -16'd1762; + 14'd750 : dout <= -16'd2083; + 14'd751 : dout <= -16'd2403; + 14'd752 : dout <= 16'd176; + 14'd753 : dout <= 16'd529; + 14'd754 : dout <= 16'd881; + 14'd755 : dout <= 16'd1234; + 14'd756 : dout <= 16'd1587; + 14'd757 : dout <= 16'd1940; + 14'd758 : dout <= 16'd2292; + 14'd759 : dout <= 16'd2645; + 14'd760 : dout <= -16'd176; + 14'd761 : dout <= -16'd529; + 14'd762 : dout <= -16'd881; + 14'd763 : dout <= -16'd1234; + 14'd764 : dout <= -16'd1587; + 14'd765 : dout <= -16'd1940; + 14'd766 : dout <= -16'd2292; + 14'd767 : dout <= -16'd2645; + 14'd768 : dout <= 16'd194; + 14'd769 : dout <= 16'd582; + 14'd770 : dout <= 16'd970; + 14'd771 : dout <= 16'd1358; + 14'd772 : dout <= 16'd1746; + 14'd773 : dout <= 16'd2134; + 14'd774 : dout <= 16'd2522; + 14'd775 : dout <= 16'd2910; + 14'd776 : dout <= -16'd194; + 14'd777 : dout <= -16'd582; + 14'd778 : dout <= -16'd970; + 14'd779 : dout <= -16'd1358; + 14'd780 : dout <= -16'd1746; + 14'd781 : dout <= -16'd2134; + 14'd782 : dout <= -16'd2522; + 14'd783 : dout <= -16'd2910; + default : dout <= 16'd0; + endcase + end + +endmodule diff --git a/Audio/pcmb_tables.v b/Audio/pcmb_tables.v new file mode 100644 index 0000000..93e26d3 --- /dev/null +++ b/Audio/pcmb_tables.v @@ -0,0 +1,46 @@ +module pcmb_tables( + input [3:0] TABLE_B1_ADDR, + output reg [4:0] TABLE_B1_OUT, + input [2:0] TABLE_B2_ADDR, // 3:0 but 2x repeat + output reg [7:0] TABLE_B2_OUT + ); + + // Todo: Could be made in combi + // Out = ((In & 7) << 1) | 1, neg if In[3] + always @(TABLE_B1_ADDR) + begin + case (TABLE_B1_ADDR) + 4'h0 : TABLE_B1_OUT <= 5'd1; + 4'h1 : TABLE_B1_OUT <= 5'd3; + 4'h2 : TABLE_B1_OUT <= 5'd5; + 4'h3 : TABLE_B1_OUT <= 5'd7; + 4'h4 : TABLE_B1_OUT <= 5'd9; + 4'h5 : TABLE_B1_OUT <= 5'd11; + 4'h6 : TABLE_B1_OUT <= 5'd13; + 4'h7 : TABLE_B1_OUT <= 5'd15; + 4'h8 : TABLE_B1_OUT <= -5'd1; + 4'h9 : TABLE_B1_OUT <= -5'd3; + 4'hA : TABLE_B1_OUT <= -5'd5; + 4'hB : TABLE_B1_OUT <= -5'd7; + 4'hC : TABLE_B1_OUT <= -5'd9; + 4'hD : TABLE_B1_OUT <= -5'd11; + 4'hE : TABLE_B1_OUT <= -5'd13; + 4'hF : TABLE_B1_OUT <= -5'd15; + endcase + end + + always @(TABLE_B2_ADDR) + begin + case (TABLE_B2_ADDR) + 3'h0 : TABLE_B2_OUT <= 8'd57; // Todo: Reduce + 3'h1 : TABLE_B2_OUT <= 8'd57; + 3'h2 : TABLE_B2_OUT <= 8'd57; + 3'h3 : TABLE_B2_OUT <= 8'd57; + 3'h4 : TABLE_B2_OUT <= 8'd77; + 3'h5 : TABLE_B2_OUT <= 8'd102; + 3'h6 : TABLE_B2_OUT <= 8'd128; + 3'h7 : TABLE_B2_OUT <= 8'd153; + endcase + end + +endmodule diff --git a/Audio/ym2610.v b/Audio/ym2610.v index ec92543..35bfab7 100644 --- a/Audio/ym2610.v +++ b/Audio/ym2610.v @@ -1,7 +1,7 @@ `timescale 1ns/1ns module ym2610( - input PHI_S, + input PHI_M, input nRESET, inout [7:0] SDD, @@ -12,19 +12,22 @@ module ym2610( input nRD_RAW, inout [7:0] SDRAD, - output [9:8] SDRA_L, - output [23:20] SDRA_U, + output [5:0] SDRA, output SDRMPX, nSDROE, inout [7:0] SDPAD, - output [11:8] SDPA, + output [3:0] SDPA, output SDPMPX, nSDPOE, output [5:0] ANA, // How many levels ? - output SH1, SH2, OP0, PHI_M // YM3016 stuff + output SH1, SH2, OP0, PHI_S // YM3016 output ); + wire nRD, nWR; + wire BUSY_MMR; + wire clr_run_A, set_run_A, clr_run_B, set_run_B; + // nCS gating - Not sure if it's that simple assign nWR = nCS | nWR_RAW; assign nRD = nCS | nRD_RAW; @@ -38,12 +41,17 @@ module ym2610( reg [7:0] DATA_COPY; reg nWRITE_S; reg [1:0] ADDR_S; - reg [7:0] DATA_S; + reg [7:0] DATA_S; + wire [15:0] ADPCM_OUT; + wire FLAG_A, FLAG_B; + reg [7:0] CLK_144_DIV; + wire TICK_144; // Timer wire [9:0] YMTIMER_TA_LOAD; wire [7:0] YMTIMER_TB_LOAD; - wire [7:0] YMTIMER_CONFIG; + wire [5:0] YMTIMER_CONFIG; + reg FLAG_A_S, FLAG_B_S; // SSG wire [11:0] SSG_FREQ_A; @@ -76,40 +84,28 @@ module ym2610( wire [7:0] FM_PAN13; wire [7:0] FM_PAN24; - // ADPCM-A - wire [7:0] PCMA_KEYON; - wire [5:0] PCMA_MVOL; - wire [7:0] PCMA_VOLPAN_A; - wire [7:0] PCMA_VOLPAN_B; - wire [7:0] PCMA_VOLPAN_C; - wire [7:0] PCMA_VOLPAN_D; - wire [7:0] PCMA_VOLPAN_E; - wire [7:0] PCMA_VOLPAN_F; - wire [15:0] PCMA_START_A; - wire [15:0] PCMA_START_B; - wire [15:0] PCMA_START_C; - wire [15:0] PCMA_START_D; - wire [15:0] PCMA_START_E; - wire [15:0] PCMA_START_F; - wire [15:0] PCMA_STOP_A; - wire [15:0] PCMA_STOP_B; - wire [15:0] PCMA_STOP_C; - wire [15:0] PCMA_STOP_D; - wire [15:0] PCMA_STOP_E; - wire [15:0] PCMA_STOP_F; - - // ADPCM-B - wire [7:0] PCMB_TRIG; - wire [7:6] PCMB_PAN; - wire [15:0] PCMB_START; - wire [15:0] PCMB_STOP; - wire [15:0] PCMB_DELTA; - wire [7:0] PCMB_VOL; - wire [7:0] PCM_FLAGS; + // ADPCM-A + wire [7:0] PCMA_KEYON; + wire [7:0] PCMA_KEYOFF; + wire [5:0] PCMA_MVOL; + wire [7:0] PCMA_VOLPAN_A, PCMA_VOLPAN_B, PCMA_VOLPAN_C, PCMA_VOLPAN_D, PCMA_VOLPAN_E, PCMA_VOLPAN_F; + wire [15:0] PCMA_START_A, PCMA_START_B, PCMA_START_C, PCMA_START_D, PCMA_START_E, PCMA_START_F; + wire [15:0] PCMA_STOP_A, PCMA_STOP_B, PCMA_STOP_C, PCMA_STOP_D, PCMA_STOP_E, PCMA_STOP_F; + + // ADPCM-B + wire [1:0] PCMB_PAN; + wire [15:0] PCMB_START_ADDR; + wire [15:0] PCMB_STOP_ADDR; + wire [15:0] PCMB_DELTA; + wire [7:0] PCMB_TL; + wire PCMB_RESET, PCMB_REPEAT, PCMB_START; + + wire [7:0] ADPCM_FLAGS; + wire [5:0] PCMA_FLAGMASK; + wire PCMA_FLAGMASK_PCMB; // Internal clock generation - // assign RESET = !nRESET; - always @(posedge PHI_S or negedge nRESET) + always @(posedge PHI_M or negedge nRESET) begin if (!nRESET) P1 <= 1'b0; @@ -117,6 +113,22 @@ module ym2610( P1 <= ~P1; end + assign TICK_144 = (CLK_144_DIV == 143) ? 1'b1 : 1'b0; // 143, not 0. Otherwise timers are goofy + + // TICK_144 gen (CLK/144) + always @(posedge PHI_M) + begin + if (!nRESET) + CLK_144_DIV <= 0; + else + begin + if (CLK_144_DIV < 143) // / 12 / 12 = / 144 + CLK_144_DIV <= CLK_144_DIV + 1'b1; + else + CLK_144_DIV <= 0; + end + end + // CPU interface always @(posedge PHI_S) begin @@ -136,31 +148,59 @@ module ym2610( DATA_COPY <= SDD; end else - begin - if (BUSY_MMR) nWR_COPY <= 1'b1; - if (BUSY && BUSY_MMR_SR == 2'b10) nWR_COPY <= 1'b1; + begin + if (BUSY_MMR) nWR_COPY <= 1'b1; + if (BUSY && BUSY_MMR_SR == 2'b10) BUSY <= 1'b0; end end end + + // Read registers + assign SDD = nRD ? 8'bzzzzzzzz : (SDA == 0) ? { BUSY, 5'h0, FLAG_B_S, FLAG_A_S } : // 4: Timer status + (SDA == 1) ? 8'h0 : // 5: SSG register data + (SDA == 2) ? ADPCM_FLAGS : // 6: ADPCM flags + 8'h0; // 7: Nothing + + always @(posedge PHI_M) + { FLAG_B_S, FLAG_A_S } <= { FLAG_B, FLAG_A }; + always @(posedge P1) {nWRITE_S, ADDR_S, DATA_S} <= {nWR_COPY, ADDR_COPY, DATA_COPY}; - ym_regs YMREGS(PHI_S, nRESET, nWRITE_S, ADDR_S, DATA_S, BUSY_MMR, + ym_regs YMREGS(PHI_M, nRESET, nWRITE_S, ADDR_S, DATA_S, BUSY_MMR, SSG_FREQ_A, SSG_FREQ_B, SSG_FREQ_C, SSG_NOISE, SSG_EN, SSG_VOL_A, SSG_VOL_B, SSG_VOL_C, - SSG_ENV_FREQ, SSG_ENV, - YMTIMER_TA_LOAD, YMTIMER_TB_LOAD, YMTIMER_CONFIG, - PCMA_KEYON, PCMA_MVOL, - PCMA_VOLPAN_A, PCMA_VOLPAN_B, PCMA_VOLPAN_C, PCMA_VOLPAN_D, PCMA_VOLPAN_E, PCMA_VOLPAN_F, - PCMA_START_A, PCMA_START_B, PCMA_START_C, PCMA_START_D, PCMA_START_E, PCMA_START_F, - PCMA_STOP_A, PCMA_STOP_B, PCMA_STOP_C, PCMA_STOP_D, PCMA_STOP_E, PCMA_STOP_F, - PCMB_TRIG, PCMB_PAN, PCMB_START, PCMB_STOP, PCMB_DELTA, PCMB_VOL, PCM_FLAGS + SSG_ENV_FREQ, SSG_ENV, + YMTIMER_TA_LOAD, YMTIMER_TB_LOAD, YMTIMER_CONFIG, + clr_run_A, set_run_A, clr_run_B, set_run_B, + PCMA_KEYON, PCMA_KEYOFF, PCMA_MVOL, + PCMA_VOLPAN_A, PCMA_VOLPAN_B, PCMA_VOLPAN_C, PCMA_VOLPAN_D, PCMA_VOLPAN_E, PCMA_VOLPAN_F, + PCMA_START_A, PCMA_START_B, PCMA_START_C, PCMA_START_D, PCMA_START_E, PCMA_START_F, + PCMA_STOP_A, PCMA_STOP_B, PCMA_STOP_C, PCMA_STOP_D, PCMA_STOP_E, PCMA_STOP_F, + PCMA_FLAGMASK, PCMA_FLAGMASK_PCMB, + PCMB_RESET, PCMB_REPEAT, PCMB_START, + PCMB_PAN, PCMB_START_ADDR, PCMB_STOP_ADDR, PCMB_DELTA, PCMB_TL ); - ym_timer YMTIMER(PHI_S, YMTIMER_TA_LOAD, YMTIMER_TB_LOAD, YMTIMER_CONFIG, nIRQ); - ym_ssg YMSSG(PHI_S, ANA, SSG_FREQ_A, SSG_FREQ_B, SSG_FREQ_C, SSG_NOISE, SSG_EN, SSG_VOL_A, SSG_VOL_B, SSG_VOL_C, + + ym_timers YMTIMER(PHI_M, TICK_144, nRESET, YMTIMER_TA_LOAD, YMTIMER_TB_LOAD, YMTIMER_CONFIG, + clr_run_A, set_run_A, clr_run_B, set_run_B, FLAG_A, FLAG_B, nIRQ); + + ym_ssg YMSSG(PHI_M, ANA, SSG_FREQ_A, SSG_FREQ_B, SSG_FREQ_C, SSG_NOISE, SSG_EN, SSG_VOL_A, SSG_VOL_B, SSG_VOL_C, SSG_ENV_FREQ, SSG_ENV); - ym_fm YMFM(PHI_S); - ym_pcma YMPCMA(PHI_S, SDRAD, SDRA_L, SDRA_U, SDRMPX, nSDROE); - ym_pcmb YMPCMB(PHI_S, SDPAD, SDPA, SDPMPX, nSDPOE); + ym_fm YMFM(PHI_M); + + ym_pcm YMPCM(PHI_M, TICK_144, nRESET, + PCMA_FLAGMASK, PCMA_FLAGMASK_PCMB, + ADPCM_FLAGS, + PCMA_KEYON, PCMA_KEYOFF, + PCMA_MVOL, + PCMA_VOLPAN_A, PCMA_VOLPAN_B, PCMA_VOLPAN_C, PCMA_VOLPAN_D, PCMA_VOLPAN_E, PCMA_VOLPAN_F, + PCMA_START_A, PCMA_STOP_A, PCMA_START_B, PCMA_STOP_B, PCMA_START_C, PCMA_STOP_C, + PCMA_START_D, PCMA_STOP_D, PCMA_START_E, PCMA_STOP_E, PCMA_START_F, PCMA_STOP_F, + SDRAD, SDRA, SDRMPX, nSDROE, + SDPAD, SDPA, SDPMPX, nSDPOE, + ADPCM_OUT, + PCMB_RESET, PCMB_REPEAT, PCMB_START, + PCMB_PAN, PCMB_START_ADDR, PCMB_STOP_ADDR, PCMB_DELTA, PCMB_TL); endmodule diff --git a/Audio/ym_pcm.v b/Audio/ym_pcm.v new file mode 100644 index 0000000..4f3b5ad --- /dev/null +++ b/Audio/ym_pcm.v @@ -0,0 +1,264 @@ +`timescale 1ns/1ns + +module ym_pcm( + input PHI_M, + input TICK_144, + input nRESET, + + input [5:0] PCMA_FLAGMASK, + input PCMA_FLAGMASK_PCMB, + output [7:0] ADPCM_FLAGS, + input [7:0] PCMA_KEYON, + input [7:0] PCMA_KEYOFF, + + input [5:0] PCMA_MVOL, // Todo: use ! + + input [7:0] PCMA_VOLPAN_A, PCMA_VOLPAN_B, PCMA_VOLPAN_C, + input [7:0] PCMA_VOLPAN_D, PCMA_VOLPAN_E, PCMA_VOLPAN_F, + + input [15:0] PCMA_START_A, PCMA_STOP_A, + input [15:0] PCMA_START_B, PCMA_STOP_B, + input [15:0] PCMA_START_C, PCMA_STOP_C, + input [15:0] PCMA_START_D, PCMA_STOP_D, + input [15:0] PCMA_START_E, PCMA_STOP_E, + input [15:0] PCMA_START_F, PCMA_STOP_F, + + inout [7:0] RAD, + output [5:0] RA, + output RMPX, + output nROE, + + inout [7:0] PAD, + output [3:0] PA, + output PMPX, + output nPOE, + + output reg [15:0] SAMPLE_OUT, + + input PCMB_RESET, PCMB_REPEAT, PCMB_START, + input [1:0] PCMB_PAN, + input [15:0] PCMB_START_ADDR, + input [15:0] PCMB_STOP_ADDR, + input [15:0] PCMB_DELTA, + input [7:0] PCMB_TL +); + + wire FLAG_END_PCMB; + + reg CLK_SAMP_TEST; + reg CLK_SAMP_PCMB; + wire CLK_SAMP_A; + wire CLK_SAMP_B; + wire CLK_SAMP_C; + wire CLK_SAMP_D; + wire CLK_SAMP_E; + wire CLK_SAMP_F; + + wire [5:0] FLAGS_END; + wire [21:0] ADDR_A; + wire [21:0] ADDR_B; + wire [21:0] ADDR_C; + wire [21:0] ADDR_D; + wire [21:0] ADDR_E; + wire [21:0] ADDR_F; + wire [21:0] ADDR_PCMB; + wire [7:0] RAD_DOUT; + wire [7:0] PAD_DOUT; + + wire [13:0] JEDI_ADDR; + wire [15:0] JEDI_DOUT; + + wire [9:0] ADPCM_STEP_MUX; + wire [9:0] ADPCM_STEP_A; + wire [9:0] ADPCM_STEP_B; + wire [9:0] ADPCM_STEP_C; + wire [9:0] ADPCM_STEP_D; + wire [9:0] ADPCM_STEP_E; + wire [9:0] ADPCM_STEP_F; + wire [9:0] ADPCM_STEP_PCMB; + + wire [3:0] DATA_MUX; + wire [3:0] DATA_A; + wire [3:0] DATA_B; + wire [3:0] DATA_C; + wire [3:0] DATA_D; + wire [3:0] DATA_E; + wire [3:0] DATA_F; + wire [3:0] DATA_PCMB; + + wire [15:0] SAMPLE_OUT_A; + wire [15:0] SAMPLE_OUT_B; + wire [15:0] SAMPLE_OUT_C; + wire [15:0] SAMPLE_OUT_D; + wire [15:0] SAMPLE_OUT_E; + wire [15:0] SAMPLE_OUT_F; + wire [15:0] SAMPLE_OUT_PCMB; + + reg [3:0] CLK_PCMA; + reg CLK_PCMB; + reg [2:0] SEQ_ACCESS; + reg [5:0] SEQ_ACCESS_B; // Probably simpler + reg [2:0] SEQ_CHANNEL; + + wire [21:0] PCMA_ADDR; + wire [21:0] PCMB_ADDR; + wire ACCESS; + + + + assign ADPCM_FLAGS = { FLAG_END_PCMB, 1'b0, FLAGS_END }; + + assign RAD = nROE ? RAD_DOUT : 8'bzzzzzzzz; + assign PAD = nPOE ? PAD_DOUT : 8'bzzzzzzzz; + + assign JEDI_ADDR = ADPCM_STEP_MUX + DATA_MUX; + + jedi_lut u1(JEDI_DOUT, JEDI_ADDR); + + // ADPCM-A sampling clock selector + assign CLK_SAMP_A = CLK_SAMP_TEST & (SEQ_CHANNEL == 0); + assign CLK_SAMP_B = CLK_SAMP_TEST & (SEQ_CHANNEL == 1); + assign CLK_SAMP_C = CLK_SAMP_TEST & (SEQ_CHANNEL == 2); + assign CLK_SAMP_D = CLK_SAMP_TEST & (SEQ_CHANNEL == 3); + assign CLK_SAMP_E = CLK_SAMP_TEST & (SEQ_CHANNEL == 4); + assign CLK_SAMP_F = CLK_SAMP_TEST & (SEQ_CHANNEL == 5); + + assign PCMA_ADDR = (SEQ_CHANNEL == 0) ? ADDR_A : // Mux + (SEQ_CHANNEL == 1) ? ADDR_B : + (SEQ_CHANNEL == 2) ? ADDR_C : + (SEQ_CHANNEL == 3) ? ADDR_D : + (SEQ_CHANNEL == 4) ? ADDR_E : + (SEQ_CHANNEL == 5) ? ADDR_F : 22'd0; + assign DATA_MUX = (SEQ_CHANNEL == 0) ? DATA_A : // Mux + (SEQ_CHANNEL == 1) ? DATA_B : + (SEQ_CHANNEL == 2) ? DATA_C : + (SEQ_CHANNEL == 3) ? DATA_D : + (SEQ_CHANNEL == 4) ? DATA_E : + (SEQ_CHANNEL == 5) ? DATA_F : 4'd0; + assign ADPCM_STEP_MUX = (SEQ_CHANNEL == 0) ? ADPCM_STEP_A : // Mux + (SEQ_CHANNEL == 1) ? ADPCM_STEP_B : + (SEQ_CHANNEL == 2) ? ADPCM_STEP_C : + (SEQ_CHANNEL == 3) ? ADPCM_STEP_D : + (SEQ_CHANNEL == 4) ? ADPCM_STEP_E : + (SEQ_CHANNEL == 5) ? ADPCM_STEP_F : 10'd0; + + assign RAD_DOUT = (SEQ_ACCESS[2:1] == 0) ? PCMA_ADDR[7:0] : // 0~1 + PCMA_ADDR[17:10]; // 2~3 (4~5, don't care) + assign RA = (SEQ_ACCESS[2:1] == 0) ? { 4'h0, PCMA_ADDR[9:8] } : // 0~1 + { 2'h0, PCMA_ADDR[21:18] }; // 2~3 + assign RMPX = ((SEQ_ACCESS == 1) || (SEQ_ACCESS == 2)) ? 1'b1 : 1'b0; + assign nROE = (SEQ_ACCESS[2] == 1) ? 1'b0 : 1'b1; // 4~5 + + // This should be ok: + assign PAD_DOUT = (SEQ_ACCESS_B[5:1] == 5'b01010) ? PCMB_ADDR[7:0] : // 20~21 + PCMB_ADDR[19:12]; // All the others (don't care) + assign PA = (SEQ_ACCESS_B[5:1] == 5'b010100) ? PCMB_ADDR[11:8] : // 20~21 + { 2'h0, PCMB_ADDR[21:20] }; // All the others (don't care) + assign PMPX = ACCESS ? ((SEQ_ACCESS_B == 21) || (SEQ_ACCESS_B == 22)) ? 1'b1 : 1'b0 : 1'b0; + assign nPOE = ACCESS ? (SEQ_ACCESS_B[5:1] == 5'b01100) ? 1'b0 : 1'b1 : 1'b1; // 24~25 + + always @(posedge PHI_M) + begin + if (!nRESET) + begin + CLK_PCMA <= 0; + CLK_PCMB <= 0; + SEQ_ACCESS <= 0; + SEQ_ACCESS_B <= 0; + SEQ_CHANNEL <= 0; + end + else + begin + + // 4M + CLK_PCMB <= ~CLK_PCMB; + + if (CLK_PCMB) + begin + if ((SEQ_ACCESS_B == 24) && (ACCESS)) CLK_SAMP_PCMB <= 1'b1; // Probably simpler + + if (SEQ_ACCESS_B < 35) // Probably simpler + SEQ_ACCESS_B <= SEQ_ACCESS_B + 1'b1; + else + SEQ_ACCESS_B <= 0; + end + else + CLK_SAMP_PCMB <= 1'b0; + + + // Access slot: 8M / 12 + // Channel slot: 8M / 12 / 6 (6 channels) + // Complete cycle: 8M / 12 / 6 / 6 (6 channels, 6 access slot per channel) + + if (CLK_PCMA < 11) + begin + CLK_PCMA <= CLK_PCMA + 1'b1; + CLK_SAMP_TEST <= 1'b0; + end + else + begin + // Access cycle here + CLK_PCMA <= 0; + + if (SEQ_ACCESS == 4) CLK_SAMP_TEST <= 1'b1; + + if (SEQ_ACCESS < 5) + SEQ_ACCESS <= SEQ_ACCESS + 1'b1; + else + begin + SEQ_ACCESS <= 0; + // Channel done, next + + // Mix + SAMPLE_OUT <= SAMPLE_OUT_A + SAMPLE_OUT_B + SAMPLE_OUT_C + + SAMPLE_OUT_D + SAMPLE_OUT_E + SAMPLE_OUT_F + SAMPLE_OUT_PCMB; + + if (SEQ_CHANNEL < 5) + SEQ_CHANNEL <= SEQ_CHANNEL + 1'b1; + else + begin + // Cycle done, repeat :) + SEQ_CHANNEL <= 0; + end + + end + end + end + end + + ch_pcma CH_1(PHI_M, CLK_SAMP_A, nRESET, + PCMA_FLAGMASK[0], FLAGS_END[0], PCMA_KEYON[0], PCMA_KEYOFF[0], JEDI_DOUT[11:0], + PCMA_START_A, PCMA_STOP_A, PCMA_VOLPAN_A, + ADDR_A, DATA_A, ADPCM_STEP_A, RAD, SAMPLE_OUT_A); + + ch_pcma CH_2(PHI_M, CLK_SAMP_B, nRESET, + PCMA_FLAGMASK[1], FLAGS_END[1], PCMA_KEYON[1], PCMA_KEYOFF[1], JEDI_DOUT[11:0], + PCMA_START_B, PCMA_STOP_B, PCMA_VOLPAN_B, + ADDR_B, DATA_B, ADPCM_STEP_B, RAD, SAMPLE_OUT_B); + + ch_pcma CH_3(PHI_M, CLK_SAMP_C, nRESET, + PCMA_FLAGMASK[2], FLAGS_END[2], PCMA_KEYON[2], PCMA_KEYOFF[2], JEDI_DOUT[11:0], + PCMA_START_C, PCMA_STOP_C, PCMA_VOLPAN_C, + ADDR_C, DATA_C, ADPCM_STEP_C, RAD, SAMPLE_OUT_C); + + ch_pcma CH_4(PHI_M, CLK_SAMP_D, nRESET, + PCMA_FLAGMASK[3], FLAGS_END[3], PCMA_KEYON[3], PCMA_KEYOFF[3], JEDI_DOUT[11:0], + PCMA_START_D, PCMA_STOP_D, PCMA_VOLPAN_D, + ADDR_D, DATA_D, ADPCM_STEP_D, RAD, SAMPLE_OUT_D); + + ch_pcma CH_5(PHI_M, CLK_SAMP_E, nRESET, + PCMA_FLAGMASK[4], FLAGS_END[4], PCMA_KEYON[4], PCMA_KEYOFF[4], JEDI_DOUT[11:0], + PCMA_START_E, PCMA_STOP_E, PCMA_VOLPAN_E, + ADDR_E, DATA_E, ADPCM_STEP_E, RAD, SAMPLE_OUT_E); + + ch_pcma CH_6(PHI_M, CLK_SAMP_F, nRESET, + PCMA_FLAGMASK[5], FLAGS_END[5], PCMA_KEYON[5], PCMA_KEYOFF[5], JEDI_DOUT[11:0], + PCMA_START_F, PCMA_STOP_F, PCMA_VOLPAN_F, + ADDR_F, DATA_F, ADPCM_STEP_F, RAD, SAMPLE_OUT_F); + + ch_pcmb CH_7(PHI_M, TICK_144, CLK_SAMP_PCMB, nRESET, + PCMA_FLAGMASK_PCMB, FLAG_END_PCMB, PCMB_START, PCMB_RESET, PCMB_REPEAT, + PCMB_TL, PCMB_PAN, PCMB_DELTA, PCMB_START_ADDR, PCMB_STOP_ADDR, + PCMB_ADDR, PAD, SAMPLE_OUT_PCMB, ACCESS); + +endmodule diff --git a/Audio/ym_pcma.v b/Audio/ym_pcma.v deleted file mode 100644 index 200e5e8..0000000 --- a/Audio/ym_pcma.v +++ /dev/null @@ -1,26 +0,0 @@ -`timescale 1ns/1ns - -module ym_pcma( - input PHI_S, - inout [7:0] RAD, - output reg [9:8] RA_L, - output reg [23:20] RA_U, - output reg RMPX, - output reg nROE -); - - reg [7:0] ADDRESS; - reg MUX; - - assign RAD = MUX ? ADDRESS : 8'bzzzzzzzz; - - always @(posedge PHI_S) // posedge ? - begin - ADDRESS <= 8'b00000000; - RA_L <= 2'b00; - RA_U <= 4'b0000; - RMPX <= 0; - nROE <= 1; - end - -endmodule diff --git a/Audio/ym_pcmb.v b/Audio/ym_pcmb.v deleted file mode 100644 index bf40bbb..0000000 --- a/Audio/ym_pcmb.v +++ /dev/null @@ -1,24 +0,0 @@ -`timescale 1ns/1ns - -module ym_pcmb( - input PHI_S, - inout [7:0] PAD, - output reg [11:8] PA, - output reg PMPX, - output reg nPOE -); - - reg [7:0] ADDRESS; - reg MUX; - - assign PAD = MUX ? ADDRESS : 8'bzzzzzzzz; - - always @(posedge PHI_S) // posedge ? - begin - ADDRESS <= 8'b00000000; - PA <= 4'b0000; - PMPX <= 0; - nPOE <= 1; - end - -endmodule diff --git a/Audio/ym_regs.v b/Audio/ym_regs.v index ee900e7..a4f790f 100644 --- a/Audio/ym_regs.v +++ b/Audio/ym_regs.v @@ -1,11 +1,12 @@ `timescale 1ns/1ns module ym_regs( - input PHI_S, - input nRESET, - input nWRITE_S, - input [1:0] ADDR_S, - input [7:0] DATA_S, + input PHI_M, + input nRESET, + + input nWRITE_S, + input [1:0] ADDR_S, + input [7:0] DATA_S, output reg BUSY_MMR, // SSG @@ -23,10 +24,12 @@ module ym_regs( // Timer output reg [9:0] YMTIMER_TA_LOAD, output reg [7:0] YMTIMER_TB_LOAD, - output reg [7:0] YMTIMER_CONFIG, + output reg [5:0] YMTIMER_CONFIG, + output reg clr_run_A, set_run_A, clr_run_B, set_run_B, - // ADPCM-A - output reg [7:0] PCMA_KEYON, + // ADPCM-A + output reg [7:0] PCMA_KEYON, + output reg [7:0] PCMA_KEYOFF, output reg [5:0] PCMA_MVOL, output reg [7:0] PCMA_VOLPAN_A, output reg [7:0] PCMA_VOLPAN_B, @@ -45,23 +48,24 @@ module ym_regs( output reg [15:0] PCMA_STOP_C, output reg [15:0] PCMA_STOP_D, output reg [15:0] PCMA_STOP_E, - output reg [15:0] PCMA_STOP_F, + output reg [15:0] PCMA_STOP_F, + output reg [5:0] PCMA_FLAGMASK, + output reg PCMA_FLAGMASK_PCMB, - // ADPCM-B - output reg [7:0] PCMB_TRIG, - output reg [7:6] PCMB_PAN, - output reg [15:0] PCMB_START, - output reg [15:0] PCMB_STOP, - output reg [15:0] PCMB_DELTA, - output reg [7:0] PCMB_VOL, - output reg [7:0] PCM_FLAGS + // ADPCM-B + output reg PCMB_RESET, PCMB_REPEAT, PCMB_START, + output reg [1:0] PCMB_PAN, + output reg [15:0] PCMB_START_ADDR, + output reg [15:0] PCMB_STOP_ADDR, + output reg [15:0] PCMB_DELTA, + output reg [7:0] PCMB_TL ); - // Internal - reg [7:0] REG1_ADDR; - reg [7:0] REG2_ADDR; + // Internal - Seems there's only one address register + 1-bit reg to select part A/B + reg [7:0] REG_ADDR; + reg PART; - // FM + // FM (todo) reg [3:0] FM_LFO; reg [7:0] FM_KEYON; reg [6:0] FM_DTMUL[3:0]; @@ -81,127 +85,191 @@ module ym_regs( reg [7:0] FM_PAN24; - always @(posedge PHI_S) + always @(posedge PHI_M) begin if (!nRESET) begin // Registers init - REG1_ADDR <= 8'h0; - BUSY_MMR <= 1'b0; - // Todo: See timers... + // Registers inits + BUSY_MMR <= 0; + REG_ADDR <= 0; // ? + PART <= 0; // ? + PCMA_FLAGMASK <= 0; + PCMA_FLAGMASK_PCMB <= 0; + PCMA_KEYON <= 0; + PCMA_KEYOFF <= 0; + PCMA_MVOL <= 0; + PCMA_VOLPAN_A <= 0; + PCMA_VOLPAN_B <= 0; + PCMA_VOLPAN_C <= 0; + PCMA_VOLPAN_D <= 0; + PCMA_VOLPAN_E <= 0; + PCMA_VOLPAN_F <= 0; + PCMA_START_A <= 0; + PCMA_START_B <= 0; + PCMA_START_C <= 0; + PCMA_START_D <= 0; + PCMA_START_E <= 0; + PCMA_START_F <= 0; + PCMA_STOP_A <= 0; + PCMA_STOP_B <= 0; + PCMA_STOP_C <= 0; + PCMA_STOP_D <= 0; + PCMA_STOP_E <= 0; + PCMA_STOP_F <= 0; + + PCMB_RESET <= 0; + PCMB_REPEAT <= 0; + PCMB_START <= 0; + PCMB_PAN <= 0; + + // Timers + { YMTIMER_TA_LOAD, YMTIMER_TB_LOAD } <= 18'd0; + YMTIMER_CONFIG <= 6'd0; + { clr_run_A, clr_run_B, set_run_A, set_run_B } <= 4'b1100; end else begin - if (!nWRITE_S && !BUSY_MMR) + if (!nWRITE_S && !BUSY_MMR) begin // CPU write BUSY_MMR <= 1'b1; - if (!ADDR_S[0]) // Set register address - begin - if (!ADDR_S[1]) // Common address register for both parts ? - begin + if (!ADDR_S[0]) // Set address + begin + REG_ADDR <= DATA_S; + PART <= ADDR_S[1]; + if (!ADDR_S[1]) $display("YM2610 part A address register %H", DATA_S); // DEBUG - REG1_ADDR <= DATA_S; - end else - begin - $display("YM2610 part B address register %H", DATA_S); // DEBUG - REG2_ADDR <= DATA_S; - end + $display("YM2610 part B address register %H", DATA_S); // DEBUG end else // Set register data begin - if (!ADDR_S[1]) + if (ADDR_S[1] == PART) // This is correct, ADDR_S[1] needs to match set PART value begin - $display("YM2610 part A set register %H to %H", REG1_ADDR, DATA_S); // DEBUG - case (REG1_ADDR) - 8'h00: SSG_FREQ_A[7:0] <= DATA_S; - 8'h01: SSG_FREQ_A[11:8] <= DATA_S[3:0]; - 8'h02: SSG_FREQ_B[7:0] <= DATA_S; - 8'h03: SSG_FREQ_B[11:8] <= DATA_S[3:0]; - 8'h04: SSG_FREQ_C[7:0] <= DATA_S; - 8'h05: SSG_FREQ_C[11:8] <= DATA_S[3:0]; - 8'h06: SSG_NOISE <= DATA_S[4:0]; - 8'h07: SSG_EN <= DATA_S[5:0]; - 8'h08: SSG_VOL_A <= DATA_S[4:0]; - 8'h09: SSG_VOL_B <= DATA_S[4:0]; - 8'h0A: SSG_VOL_C <= DATA_S[4:0]; - 8'h0B: SSG_ENV_FREQ[7:0] <= DATA_S; - 8'h0C: SSG_ENV_FREQ[15:8] <= DATA_S; - 8'h0D: SSG_ENV <= DATA_S[4:0]; - - 8'h10: PCMB_TRIG <= DATA_S; - 8'h11: PCMB_PAN <= DATA_S[7:6]; - 8'h12: PCMB_START[7:0] <= DATA_S; - 8'h13: PCMB_START[15:8] <= DATA_S; - 8'h14: PCMB_STOP[7:0] <= DATA_S; - 8'h15: PCMB_STOP[15:8] <= DATA_S; - 8'h19: PCMB_DELTA[7:0] <= DATA_S; - 8'h1A: PCMB_DELTA[15:8] <= DATA_S; - 8'h1B: PCMB_VOL <= DATA_S; - 8'h1C: PCM_FLAGS <= DATA_S; - - 8'h22: FM_LFO <= DATA_S[3:0]; - 8'h24: YMTIMER_TA_LOAD[7:0] <= DATA_S; - 8'h25: YMTIMER_TA_LOAD[9:8] <= DATA_S[1:0]; - 8'h26: YMTIMER_TB_LOAD <= DATA_S; - 8'h27: YMTIMER_CONFIG <= DATA_S; - - // FM: Todo - - // Default needed - endcase - end - else - begin - $display("YM2610 part B set register %H to %H", REG2_ADDR, DATA_S); // DEBUG - casez (REG2_ADDR) - 8'h00: PCMA_KEYON <= DATA_S; - 8'h01: PCMA_MVOL <= DATA_S[5:0]; - - 8'b00001000: PCMA_VOLPAN_A <= DATA_S; - 8'b00001001: PCMA_VOLPAN_B <= DATA_S; - 8'b00001010: PCMA_VOLPAN_C <= DATA_S; - 8'b00001011: PCMA_VOLPAN_D <= DATA_S; - 8'b00001100: PCMA_VOLPAN_E <= DATA_S; - 8'b00001101: PCMA_VOLPAN_F <= DATA_S; - - 8'b00010000: PCMA_START_A[7:0] <= DATA_S; - 8'b00010001: PCMA_START_A[7:0] <= DATA_S; - 8'b00010010: PCMA_START_A[7:0] <= DATA_S; - 8'b00010011: PCMA_START_A[7:0] <= DATA_S; - 8'b00010100: PCMA_START_A[7:0] <= DATA_S; - 8'b00010101: PCMA_START_A[7:0] <= DATA_S; - - 8'b00011000: PCMA_START_A[15:8] <= DATA_S; - 8'b00011001: PCMA_START_B[15:8] <= DATA_S; - 8'b00011010: PCMA_START_C[15:8] <= DATA_S; - 8'b00011011: PCMA_START_D[15:8] <= DATA_S; - 8'b00011100: PCMA_START_E[15:8] <= DATA_S; - 8'b00011101: PCMA_START_F[15:8] <= DATA_S; - - 8'b00100000: PCMA_STOP_A[7:0] <= DATA_S; - 8'b00100001: PCMA_STOP_B[7:0] <= DATA_S; - 8'b00100010: PCMA_STOP_C[7:0] <= DATA_S; - 8'b00100011: PCMA_STOP_D[7:0] <= DATA_S; - 8'b00100100: PCMA_STOP_E[7:0] <= DATA_S; - 8'b00100101: PCMA_STOP_F[7:0] <= DATA_S; - - 8'b00101000: PCMA_STOP_A[15:8] <= DATA_S; - 8'b00101001: PCMA_STOP_B[15:8] <= DATA_S; - 8'b00101010: PCMA_STOP_C[15:8] <= DATA_S; - 8'b00101011: PCMA_STOP_D[15:8] <= DATA_S; - 8'b00101100: PCMA_STOP_E[15:8] <= DATA_S; - 8'b00101101: PCMA_STOP_F[15:8] <= DATA_S; - - // Default needed - endcase + if (!ADDR_S[1]) + begin + $display("YM2610 part A set register %H to %H", REG_ADDR, DATA_S); // DEBUG + case (REG_ADDR) + 8'h00: SSG_FREQ_A[7:0] <= DATA_S; + 8'h01: SSG_FREQ_A[11:8] <= DATA_S[3:0]; + 8'h02: SSG_FREQ_B[7:0] <= DATA_S; + 8'h03: SSG_FREQ_B[11:8] <= DATA_S[3:0]; + 8'h04: SSG_FREQ_C[7:0] <= DATA_S; + 8'h05: SSG_FREQ_C[11:8] <= DATA_S[3:0]; + 8'h06: SSG_NOISE <= DATA_S[4:0]; + 8'h07: SSG_EN <= DATA_S[5:0]; + 8'h08: SSG_VOL_A <= DATA_S[4:0]; + 8'h09: SSG_VOL_B <= DATA_S[4:0]; + 8'h0A: SSG_VOL_C <= DATA_S[4:0]; + 8'h0B: SSG_ENV_FREQ[7:0] <= DATA_S; + 8'h0C: SSG_ENV_FREQ[15:8] <= DATA_S; + 8'h0D: SSG_ENV <= DATA_S[4:0]; + + 8'h10: + begin + PCMB_RESET <= DATA_S[0]; + PCMB_REPEAT <= DATA_S[4]; + PCMB_START <= DATA_S[7]; + end + 8'h11: PCMB_PAN <= DATA_S[7:6]; + 8'h12: PCMB_START_ADDR[7:0] <= DATA_S; + 8'h13: PCMB_START_ADDR[15:8] <= DATA_S; + 8'h14: PCMB_STOP_ADDR[7:0] <= DATA_S; + 8'h15: PCMB_STOP_ADDR[15:8] <= DATA_S; + 8'h19: PCMB_DELTA[7:0] <= DATA_S; + 8'h1A: PCMB_DELTA[15:8] <= DATA_S; + 8'h1B: PCMB_TL <= DATA_S; + + 8'h1C: + begin + PCMA_FLAGMASK <= DATA_S[5:0]; + PCMA_FLAGMASK_PCMB <= DATA_S[7]; + end + + 8'h24: YMTIMER_TA_LOAD[7:0] <= DATA_S; + 8'h25: YMTIMER_TA_LOAD[9:8] <= DATA_S[1:0]; + 8'h26: YMTIMER_TB_LOAD <= DATA_S; + 8'h27: + begin + // CSM <= DATA_S[7]; + + YMTIMER_CONFIG <= DATA_S[5:0]; + clr_run_A <= ~DATA_S[0]; + set_run_A <= DATA_S[0]; + clr_run_B <= ~DATA_S[1]; + set_run_B <= DATA_S[1]; + end + + // FM: Todo + + // Default needed + endcase + end + else + begin + $display("YM2610 part B set register %H to %H", REG_ADDR, DATA_S); // DEBUG + case (REG_ADDR) + 8'h00: + begin + if (!DATA_S[7]) + PCMA_KEYON <= DATA_S; + else + PCMA_KEYOFF <= DATA_S; + end + 8'h01: PCMA_MVOL <= DATA_S[5:0]; + + 8'b00001000: PCMA_VOLPAN_A <= DATA_S; + 8'b00001001: PCMA_VOLPAN_B <= DATA_S; + 8'b00001010: PCMA_VOLPAN_C <= DATA_S; + 8'b00001011: PCMA_VOLPAN_D <= DATA_S; + 8'b00001100: PCMA_VOLPAN_E <= DATA_S; + 8'b00001101: PCMA_VOLPAN_F <= DATA_S; + + 8'b00010000: PCMA_START_A[7:0] <= DATA_S; + 8'b00010001: PCMA_START_B[7:0] <= DATA_S; + 8'b00010010: PCMA_START_C[7:0] <= DATA_S; + 8'b00010011: PCMA_START_D[7:0] <= DATA_S; + 8'b00010100: PCMA_START_E[7:0] <= DATA_S; + 8'b00010101: PCMA_START_F[7:0] <= DATA_S; + + 8'b00011000: PCMA_START_A[15:8] <= DATA_S; + 8'b00011001: PCMA_START_B[15:8] <= DATA_S; + 8'b00011010: PCMA_START_C[15:8] <= DATA_S; + 8'b00011011: PCMA_START_D[15:8] <= DATA_S; + 8'b00011100: PCMA_START_E[15:8] <= DATA_S; + 8'b00011101: PCMA_START_F[15:8] <= DATA_S; + + 8'b00100000: PCMA_STOP_A[7:0] <= DATA_S; + 8'b00100001: PCMA_STOP_B[7:0] <= DATA_S; + 8'b00100010: PCMA_STOP_C[7:0] <= DATA_S; + 8'b00100011: PCMA_STOP_D[7:0] <= DATA_S; + 8'b00100100: PCMA_STOP_E[7:0] <= DATA_S; + 8'b00100101: PCMA_STOP_F[7:0] <= DATA_S; + + 8'b00101000: PCMA_STOP_A[15:8] <= DATA_S; + 8'b00101001: PCMA_STOP_B[15:8] <= DATA_S; + 8'b00101010: PCMA_STOP_C[15:8] <= DATA_S; + 8'b00101011: PCMA_STOP_D[15:8] <= DATA_S; + 8'b00101100: PCMA_STOP_E[15:8] <= DATA_S; + 8'b00101101: PCMA_STOP_F[15:8] <= DATA_S; + + // Default needed + endcase + end end end end else - begin - BUSY_MMR <= 1'b0; // DEBUG + begin + BUSY_MMR <= 0; // DEBUG + YMTIMER_CONFIG[5:4] <= 2'd0; + YMTIMER_CONFIG[1:0] <= 2'd0; + PCMA_KEYON <= 0; // ? + PCMA_KEYOFF <= 0; // ? + PCMB_RESET <= 0; // ? + PCMB_START <= 0; // ? + { clr_run_A, clr_run_B, set_run_A, set_run_B } <= 4'd0; end end end diff --git a/Audio/ym_timer.v b/Audio/ym_timer.v index 58bab88..698d7d8 100644 --- a/Audio/ym_timer.v +++ b/Audio/ym_timer.v @@ -1,17 +1,51 @@ -`timescale 1ns/1ns - -module ym_timer( - input PHI_S, - input [9:0] YMTIMER_TA_LOAD, - input [7:0] YMTIMER_TB_LOAD, - input [7:0] YMTIMER_CONFIG, - output reg nIRQ -); - - - always @(posedge PHI_S) // ? - begin - nIRQ <= 1'b1; // Todo - end - -endmodule +`timescale 1ns/1ns + +module ym_timer #(parameter cnt_width = 8, mult_width = 1) ( + input CLK, + input TICK_144, + input nRESET, + input [cnt_width-1:0] LOAD_VALUE, + input LOAD, + input CLR_FLAG, + input SET_RUN, + input CLR_RUN, + output reg OVF_FLAG, + output reg OVF +); + + reg RUN; + reg [mult_width-1:0] MULT; + reg [cnt_width-1:0] CNT; + reg [mult_width+cnt_width-1:0] NEXT, INIT; + + always @(posedge CLK) + begin + if (CLR_RUN || !nRESET) + RUN <= 0; + else if (SET_RUN || LOAD) + RUN <= 1; + + if (CLR_FLAG || !nRESET) + OVF_FLAG <= 0; + else if (OVF) + OVF_FLAG <= 1; + + if (TICK_144) + begin + if (LOAD) + begin + MULT <= { (mult_width){1'b0} }; + CNT <= LOAD_VALUE; + end + else if (RUN) + { CNT, MULT } <= OVF ? INIT : NEXT; + end + end + + always @(*) + begin + { OVF, NEXT } <= { 1'b0, CNT, MULT } + 1'b1; + INIT <= { LOAD_VALUE, { (mult_width){1'b0} } }; + end + +endmodule diff --git a/Audio/ym_timers.v b/Audio/ym_timers.v new file mode 100644 index 0000000..23d0079 --- /dev/null +++ b/Audio/ym_timers.v @@ -0,0 +1,44 @@ +`timescale 1ns/1ns + +module ym_timers( + input CLK, + input TICK_144, + input nRESET, + input [9:0] YMTIMER_TA_LOAD, + input [7:0] YMTIMER_TB_LOAD, + input [5:0] YMTIMER_CONFIG, + input clr_run_A, set_run_A, clr_run_B, set_run_B, + output FLAG_A, FLAG_B, + output nIRQ +); + + // Z80 IRQ gen + assign nIRQ = ~((FLAG_A & YMTIMER_CONFIG[2]) | (FLAG_B & YMTIMER_CONFIG[3])); + + ym_timer #(.mult_width(1), .cnt_width(10)) timer_A ( + .CLK ( CLK ), + .TICK_144 ( TICK_144 ), + .nRESET ( nRESET ), + .LOAD_VALUE ( YMTIMER_TA_LOAD ), + .LOAD ( YMTIMER_CONFIG[0] ), + .CLR_FLAG ( YMTIMER_CONFIG[4] ), + .SET_RUN ( set_run_A ), + .CLR_RUN ( clr_run_A ), + .OVF_FLAG ( FLAG_A ), + .OVF ( ) // Todo overflow_A + ); + + ym_timer #(.mult_width(4), .cnt_width(8)) timer_B ( + .CLK ( CLK ), + .TICK_144 ( TICK_144 ), + .nRESET ( nRESET ), + .LOAD_VALUE ( YMTIMER_TB_LOAD ), + .LOAD ( YMTIMER_CONFIG[1] ), + .CLR_FLAG ( YMTIMER_CONFIG[5] ), + .SET_RUN ( set_run_B ), + .CLR_RUN ( clr_run_B ), + .OVF_FLAG ( FLAG_B ), + .OVF ( ) // Unused in YM2610 ? + ); + +endmodule diff --git a/Cartridge/pcm.v b/Cartridge/pcm.v new file mode 100644 index 0000000..ac80864 --- /dev/null +++ b/Cartridge/pcm.v @@ -0,0 +1,65 @@ +`timescale 1ns/1ns + +// SNK "PCM" chip (in cartridge) + +module pcm( + input CLK_68KCLKB, + input nSDROE, SDRMPX, + input nSDPOE, SDPMPX, + inout [7:0] SDRAD, + input [9:8] SDRA_L, + input [23:20] SDRA_U, + inout [7:0] SDPAD, + input [11:8] SDPA, + input [7:0] D, + output [23:0] A +); + + reg [1:0] COUNT; + reg [7:0] RDLATCH; + reg [7:0] PDLATCH; + reg [23:0] RALATCH; + reg [23:0] PALATCH; + + always @(posedge CLK_68KCLKB or negedge nSDPOE) + begin + if (!nSDPOE) + COUNT <= 0; + else + if (!COUNT[1]) COUNT <= COUNT + 1'b1; + end + + assign SDRAD = nSDROE ? 8'bzzzzzzzz : RDLATCH; + always @* + if (COUNT[1]) RDLATCH <= D; + + assign SDPAD = nSDPOE ? 8'bzzzzzzzz : PDLATCH; + always @* + if (!nSDPOE) PDLATCH <= D; + + assign A = nSDPOE ? RALATCH[23:0] : PALATCH[23:0]; + + always @(posedge SDRMPX) + begin + RALATCH[7:0] <= SDRAD; + RALATCH[9:8] <= SDRA_L[9:8]; + end + + always @(negedge SDRMPX) + begin + RALATCH[17:10] <= SDRAD; + RALATCH[23:18] <= {SDRA_U[23:20], SDRA_L[9:8]}; + end + + always @(posedge SDPMPX) + begin + PALATCH[7:0] <= SDPAD; + PALATCH[11:8] <= SDPA[11:8]; + end + always @(negedge SDPMPX) + begin + PALATCH[19:12] <= SDPAD; + PALATCH[23:20] <= SDPA[11:8]; + end + +endmodule diff --git a/Cartridge/prog_board.v b/Cartridge/prog_board.v index 43acc69..3c1e3f3 100644 --- a/Cartridge/prog_board.v +++ b/Cartridge/prog_board.v @@ -31,13 +31,13 @@ module prog_board( //assign nPORTOE = nPORTOEL & nPORTOEU; - assign nROMWAIT = 1'b1; + assign nROMWAIT = 1'b1; // Waitstate configuration assign nPWAIT0 = 1'b1; assign nPWAIT1 = 1'b1; - assign PDTACK = 1'b1; // ? + assign PDTACK = 1'b1; // Joy Joy Kid doesn't use PCM - //pcm PCM(RAD, RA_L, RA_U, RMPX, PAD, PA, PMPX, V1_ADDR, V2_ADDR); + //pcm PCM(CLK_68KCLKB, nSDROE, RMPX, nSDPOE, PMPX, RAD, RA_L, RA_U, PAD, PA, V_DATA, V_ADDR); rom_p1 P1(M68K_ADDR[18:1], M68K_DATA, M68K_ADDR[19], nROMOE); @@ -47,24 +47,18 @@ module prog_board( rom_v1 V1(V1_ADDR[18:0], RAD, nROE); rom_v2 V2(V2_ADDR[18:0], PAD, nPOE); - // V ROMs address latches - assign nRMPX = ~RMPX; - assign nPMPX = ~PMPX; - always @(posedge RMPX or posedge nRMPX) - begin - if (RMPX) - V1_ADDR[9:0] <= {RA_L[9:8], RAD[7:0]}; - else - V1_ADDR[23:10] <= {RA_U[23:20], RA_L[9:8], RAD[7:0]}; - end - - always @(posedge PMPX or posedge nPMPX) - begin - if (PMPX) - V2_ADDR[11:0] <= {PA[11:8], PAD[7:0]}; - else - V2_ADDR[23:12] <= {PA[11:8], PAD[7:0]}; - end + // V ROMs address latches (discrete) + always @(posedge RMPX) + V1_ADDR[9:0] <= {RA_L[9:8], RAD}; + + always @(negedge RMPX) + V1_ADDR[23:10] <= {RA_U[23:20], RA_L[9:8], RAD}; + + always @(posedge PMPX) + V2_ADDR[11:0] <= {PA[11:8], PAD}; + + always @(negedge PMPX) + V2_ADDR[23:12] <= {PA[11:8], PAD}; endmodule diff --git a/IO/z80ctrl.v b/IO/z80ctrl.v index 6c1ca9d..eb57f9a 100644 --- a/IO/z80ctrl.v +++ b/IO/z80ctrl.v @@ -14,13 +14,15 @@ module z80ctrl( output nSDZ80CLR, // To NEO-C1 output nSDROM, output nSDMRD, nSDMWR, - output SDRD0, SDRD1, + output nSDRD0, nSDRD1, output n2610CS, output n2610RD, n2610WR, - output nZRAMCS + output nZRAMCS ); reg nNMI_EN; + wire nIORD, nIOWR; + wire nNMI_SET, nNMI_RESET; // $0000~$F7FF: ROM // $F800~$FFFF: RAM diff --git a/Neosim.xise b/Neosim.xise index eae5525..b4bbe21 100644 --- a/Neosim.xise +++ b/Neosim.xise @@ -16,43 +16,43 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - + @@ -60,229 +60,221 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + - - + + - - + + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -290,7 +282,7 @@ - + @@ -298,7 +290,7 @@ - + @@ -306,40 +298,68 @@ - + - + - + - + - + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RAMs/z80ram.v b/RAMs/z80ram.v index 3b3b000..de37d1e 100644 --- a/RAMs/z80ram.v +++ b/RAMs/z80ram.v @@ -21,13 +21,13 @@ module z80ram( end assign #100 DATAOUT = RAMDATA[ADDR]; - assign DATA = (!nCE && !nOE) ? DATAOUT : 8'bzzzzzzzz; + assign DATA = (!nCE && !nOE && nWE) ? DATAOUT : 8'bzzzzzzzz; - always @(nCE or nWE) + always @(*) if (!nCE && !nWE) #20 RAMDATA[ADDR] <= DATA; - always @(nWE or nCE) + always @(*) if (!nWE && !nOE) $display("ERROR: Z80RAM: nOE and nWE are both active !"); diff --git a/Video/hshrink.v b/Video/hshrink.v index feca6aa..047fa13 100644 --- a/Video/hshrink.v +++ b/Video/hshrink.v @@ -1,29 +1,37 @@ `timescale 1ns/1ns module hshrink( - input [3:0] SHRINK, - input [3:0] N, + input [3:0] SHRINK, // Shrink value + input [3:0] N, // Pixel number output USE ); - // Thanks to MAME and Logic Friday :) - // Todo: Is this really a LUT in LSPC ? + // Thanks MAME :) - assign USE = (SHRINK == 15) ? &{N[2:0]} | N[3] : - (SHRINK == 14) ? &{N[3:1]} | &{N[3:2], N[0]} : - (SHRINK == 13) ? &{N[1:0]} | |{N[3:2]} : - (SHRINK == 12) ? N[3] & |{N[2:0]} : - (SHRINK == 11) ? |{N[3:0]} : - (SHRINK == 10) ? &{N[3:0]} : - (SHRINK == 9) ? (N[2] & |{N[1:0]}) | N[3] : - (SHRINK == 8) ? N[3] & (&{N[1:0]} | N[2]) : - (SHRINK == 7) ? 1'b1 : - (SHRINK == 6) ? N[3] : - (SHRINK == 5) ? &{N[2:1]} | N[3] : - (SHRINK == 4) ? &{N[3:1]} : - (SHRINK == 3) ? |{N[3:1]} : - (SHRINK == 2) ? &{N[3:2]} : - (SHRINK == 1) ? |{N[3:2]} : - N[3] & |{N[2:1]}; + reg [15:0] BITMAP; + + always@(*) + begin + case (SHRINK) + 4'h0: BITMAP <= 16'b0000000010000000; + 4'h1: BITMAP <= 16'b0000100010000000; + 4'h2: BITMAP <= 16'b0000100010001000; + 4'h3: BITMAP <= 16'b0010100010001000; + 4'h4: BITMAP <= 16'b0010100010001010; + 4'h5: BITMAP <= 16'b0010101010001010; + 4'h6: BITMAP <= 16'b0010101010101010; + 4'h7: BITMAP <= 16'b1010101010101010; + 4'h8: BITMAP <= 16'b1010101011101010; + 4'h9: BITMAP <= 16'b1011101011101010; + 4'hA: BITMAP <= 16'b1011101011101011; + 4'hB: BITMAP <= 16'b1011101111101011; + 4'hC: BITMAP <= 16'b1011101111101111; + 4'hD: BITMAP <= 16'b1111101111101111; + 4'hE: BITMAP <= 16'b1111101111111111; + 4'hF: BITMAP <= 16'b1111111111111111; + endcase + end + + assign USE = BITMAP[N]; endmodule diff --git a/neogeo.v b/neogeo.v index decd008..680be74 100644 --- a/neogeo.v +++ b/neogeo.v @@ -5,8 +5,7 @@ // furrtek, Charles MacDonald, Kyuusaku, freem and neogeodev contributors ~ 2016 // https://github.com/neogeodev/NeoGeoFPGA-sim -// Todo: Z80 controller (NEO-D0) -// Todo: connect P1_OUT and P2_OUT +// Todo: Palette RAM CPU access (see alpha68k PCB) // Todo: VPA for interrupt ACK (NEO-C1) // Todo: Check watchdog timing @@ -166,10 +165,10 @@ module neogeo( // SFIX / Cart FIX switch assign FIXD = nSYSTEM ? FIXD_SFIX : FIXD_CART; - ym2610 YM(CLK_8M, nRESET, SDD, SDA[1:0], nZ80INT, n2610CS, n2610WR, n2610RD, SDRAD, SDRA_L, SDRA_U, SDRMPX, nSDROE, - SDPAD, SDPA, SDPMPX, nSDPOE, ANA, SH1, SH2, OP0, PHI_M); + ym2610 YM(CLK_8M, nRESET, SDD, SDA[1:0], nZ80INT, n2610CS, n2610WR, n2610RD, SDRAD, {SDRA_U, SDRA_L}, SDRMPX, + nSDROE, SDPAD, SDPA, SDPMPX, nSDPOE, ANA, SH1, SH2, OP0, PHI_S); - ym2i2s YM2I2S(nRESET, CLK_I2S, ANA, SH1, SH2, OP0, PHI_M, I2S_MCLK, I2S_BICK, I2S_SDTI, I2S_LRCK); + ym2i2s YM2I2S(nRESET, CLK_I2S, ANA, SH1, SH2, OP0, PHI_S, I2S_MCLK, I2S_BICK, I2S_SDTI, I2S_LRCK); // MVS only upd4990 RTC(CLK_RTC, 1'b1, 1'b1, RTC_CLK, RTC_DIN, RTC_STROBE, RTC_TP, RTC_DOUT);