]>
Commit | Line | Data |
---|---|---|
1 | `define ADDR_NR21 16'hFF16 | |
2 | `define ADDR_NR22 16'hFF17 | |
3 | `define ADDR_NR23 16'hFF18 | |
4 | `define ADDR_NR24 16'hFF19 | |
5 | ||
6 | module Sound2( | |
7 | input core_clk, | |
8 | input wr, | |
9 | input rd, | |
10 | input [15:0] addr, | |
11 | inout [7:0] data, | |
12 | input cntclk, | |
13 | input lenclk, | |
14 | input en, | |
15 | output [3:0] snd_data | |
16 | ); | |
17 | ||
18 | /* can be optimized as register file */ | |
19 | reg [7:0] nr21 = 0, nr22 = 0, nr23 = 0, nr24 = 0; | |
20 | reg [10:0] counter = 0; | |
21 | reg [4:0] lencnt = 0; | |
22 | reg [3:0] delta = 4'b1111; | |
23 | reg [2:0] dutycnt; | |
24 | reg [3:0] snd_out = 0; | |
25 | ||
26 | assign snd_data = en ? snd_out : 0; | |
27 | ||
28 | reg rdlatch; | |
29 | reg [15:0] addrlatch; | |
30 | ||
31 | assign data = rdlatch ? | |
32 | addrlatch == `ADDR_NR21 ? nr21 : | |
33 | addrlatch == `ADDR_NR22 ? nr22 : | |
34 | addrlatch == `ADDR_NR23 ? nr23 : | |
35 | addrlatch == `ADDR_NR24 ? nr24 : 8'bzzzzzzzz | |
36 | : 8'bzzzzzzzz; | |
37 | ||
38 | always @ (posedge core_clk) begin | |
39 | rdlatch <= rd; | |
40 | addrlatch <= addr; | |
41 | if(en && wr) begin | |
42 | case(addr) | |
43 | `ADDR_NR21: nr21 <= data; | |
44 | `ADDR_NR22: nr22 <= data; | |
45 | `ADDR_NR23: nr23 <= data; | |
46 | `ADDR_NR24: nr24 <= data; | |
47 | endcase | |
48 | end | |
49 | else if(!en) begin | |
50 | nr21 <= 8'h3F; | |
51 | nr22 <= 8'h00; | |
52 | nr23 <= 8'hFF; | |
53 | nr24 <= 8'hBF; | |
54 | end | |
55 | end | |
56 | ||
57 | always @ (posedge cntclk) begin | |
58 | if(counter) | |
59 | counter <= counter - 1; | |
60 | else begin | |
61 | counter <= ~{nr24[2:0],nr23} + 1; /* possible A */ | |
62 | dutycnt <= dutycnt + 1; | |
63 | end | |
64 | ||
65 | case (nr21[7:6]) | |
66 | 2'b00: snd_out <= dutycnt ? 0 : delta; /* probable A */ | |
67 | 2'b01: snd_out <= (dutycnt[2:1] == 2'b0) ? delta : 0; | |
68 | 2'b10: snd_out <= dutycnt[2] ? delta : 0; | |
69 | 2'b11: snd_out <= (dutycnt[2:1] == 2'b0) ? 0 : delta; | |
70 | endcase | |
71 | end | |
72 | ||
73 | always @ (posedge lenclk) begin | |
74 | if(lencnt) | |
75 | lencnt <= lencnt - 1; /* possible A */ | |
76 | else | |
77 | lencnt <= ~nr21[4:0] + 1; | |
78 | end | |
79 | ||
80 | endmodule |