ARP responder
[fpgaboy.git] / Sound2.v
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
This page took 0.02066 seconds and 4 git commands to generate.