Advertisement
NovaYoshi

powerpak.v

May 18th, 2016
360
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 10.13 KB | None | 0 0
  1. `default_nettype none
  2.  
  3. `define MAPxx MAP03       //MAP03.MAP           CNROM
  4. //`define MAPxx MAP04       //MAP04.MAP         MMC3
  5. //`define MAPxx MAPVRC4     //MAP15,17,19.MAP   VRC4
  6. //`define MAPxx MAPVRC6     //MAP18,1A.MAP      VRC6
  7. //`define MAPxx MAP45       //MAP45.MAP         Sunsoft 5B "Gimmick"
  8. //`define MAPxx MAPN106     //MAP13.MAP         Namco-106
  9. //`define MAPxx MAPFDS      //F.MAP               Famicom disk system
  10.  
  11. module powerpak(
  12.     input CLK_20M,
  13.     output BOOT_ENABLE,
  14.     input NES_M2,
  15.     output NES_IRQ,
  16.     input [13:0] NES_CHR_A,
  17.     inout [7:0] NES_CHR_D,
  18.     input NES_CHR_RD,
  19.     input NES_CHR_WR,
  20.     output NES_CIRAM_CE,
  21.     input NES_PRG_CE,
  22.     inout [7:0] NES_PRG_D,
  23.     input [14:0] NES_PRG_A,
  24.     input NES_PRG_RW,
  25.     output RAM_CHR_CE,
  26.     output [18:0] RAM_CHR_A, //3..9 unconnected (ignore warnings)
  27.     output RAM_PRG_OE,
  28.     output RAM_PRG_WE,
  29.     output [18:13] RAM_PRG_A,
  30.     inout [7:0] RAM_PRG_D,
  31.     output WRAM_PRG_OE,
  32.     output WRAM_PRG_WE,
  33.     output EXP6
  34. );
  35.     wire m2, clk20;
  36.     wire chrram_we, chrram_oe, wram_oe, wram_we, prgram_we, prgram_oe, neschr_oe;
  37.     wire nesprg_oe, nesprg_we, nesprg_ce, neschr_rd, neschr_wr, ciram_ce;
  38.     wire [15:0] prgain;
  39.     wire [13:0] chrain;
  40.     wire [18:10] ramchraout;
  41.     wire [18:13] ramprgaout;
  42.     wire [7:0] ramprgdin;
  43.     wire [7:0] nesprgdin;
  44.     wire [7:0] nesprgdout;
  45.     wire [7:0] neschrdin;
  46.     wire [7:0] neschrdout;
  47.  
  48.     wire irq;
  49.     wire cfg_boot;              //powerpak boot rom enable (disable game rom)
  50.     wire [18:12] cfg_chrmask;   //CHR size mask
  51.     wire [18:13] cfg_prgmask;   //PRG size mask
  52.     wire cfg_vertical;          //mirror flag from .NES header
  53.     wire cfg_fourscreen;        //4-way mirror flag from .NES header
  54.     wire cfg_chrram;            //game has no chr rom (allow writes)
  55.     wire reset;
  56.  
  57.     //needed for Dirty Harry (MMC3) and Paperboy (CNROM)
  58.     //D7,D5 low during 4016/7 read fixes controller input problems
  59.     //wire readpad=(prgain[15:1]=='b0100_0000_0001_011) & nesprg_we & ~m2;
  60.     //wire [7:0] openbus={!readpad, 1'b1, !readpad, 5'b11111};
  61.    
  62.     IBUFG b00(.I(NES_CHR_RD),.O(neschr_rd));
  63.     IBUFG b01(.I(NES_M2),.O(m2));
  64.     IBUFG b02(.I(CLK_20M),.O(clk20));
  65.     IBUFG b03(.I(NES_CHR_WR),.O(neschr_wr));
  66.     IOBUF b04[7:0](.I(1'b0),.O(ramprgdin),.T(nesprgdin | {8{~wram_we & ~prgram_we}}), .IO(RAM_PRG_D));
  67.     IOBUF b05[7:0](.I(1'b0),.O(neschrdin),.T(neschrdout | {8{~neschr_oe}}),.IO(NES_CHR_D));
  68.     IOBUF b06[7:0](.I(1'b0),.O(nesprgdin),.T(nesprgdout | {8{~nesprg_oe}}),.IO(NES_PRG_D));
  69.     //IOBUF b06[7:0](.I(1'b0),.O(nesprgdin),.T(openbus & (nesprgdout | {8{~nesprg_oe}})),.IO(NES_PRG_D));
  70.     OBUFT b07(.I(1'b0),.O(BOOT_ENABLE),.T(cfg_boot));
  71.     OBUFT b08(.I(1'b0),.O(WRAM_PRG_WE),.T(~wram_we));
  72.     OBUFT b09(.I(1'b0),.O(WRAM_PRG_OE),.T(~wram_oe));
  73.     OBUFT b10(.I(1'b0),.O(RAM_PRG_WE),.T(~prgram_we));
  74.     OBUFT b11(.I(1'b0),.O(RAM_PRG_OE),.T(~prgram_oe));
  75.     OBUFT b12(.I(1'b0),.O(NES_IRQ),.T(~irq));
  76.     OBUFT b13(.I(1'b0),.O(NES_CIRAM_CE),.T(~ciram_ce));
  77.     OBUFT b14(.I(1'b0),.O(RAM_CHR_CE),.T(~(chrram_we | chrram_oe)));
  78.     OBUFT b15[2:0](.I(1'b0),.O(RAM_CHR_A[2:0]),.T(chrain[2:0]));
  79.     OBUFT b16[18:10](.I(1'b0),.O(RAM_CHR_A[18:10]),.T(ramchraout[18:10]));
  80.     OBUFT b17[18:13](.I(1'b0),.O(RAM_PRG_A[18:13]),.T(ramprgaout[18:13]));
  81.     IBUF b18(.I(NES_PRG_RW),.O(nesprg_we));
  82.     IBUF b19[13:0](.I(NES_CHR_A),.O(chrain));
  83.     IBUF b20(.I(NES_PRG_CE),.O(nesprg_ce));
  84.     IBUF b21[14:0](.I(NES_PRG_A),.O(prgain[14:0]));
  85.     assign prgain[15]=!nesprg_ce;
  86.  
  87.     reg [1:0] m2buf;
  88.     always@(posedge clk20)
  89.         m2buf<={m2buf[0],m2};
  90.     wire m2_n = ~m2 & ~m2buf[1];    // m2 with a delayed falling edge, to deal with addressing glitches
  91.  
  92.     `MAPxx mapper (     //all signals active high
  93.         m2,                 //in:   6502 M2 clock
  94.         m2_n,               //in:
  95.         clk20,              //in:   20MHz clock from powerpak
  96.         reset,              //in:
  97.         ~nesprg_we,         //in:
  98.         nesprg_oe,          //out:
  99.         ~neschr_rd,         //in:
  100.         ~neschr_wr,         //in:
  101.         prgain,             //in:
  102.         chrain,             //in:
  103.         nesprgdin,          //in:
  104.         ramprgdin,          //in:   from prgram or wram
  105.         nesprgdout,         //out:
  106.         neschrdout,         //out:
  107.         neschr_oe,          //out:
  108.         chrram_we,          //out:
  109.         chrram_oe,          //out:
  110.         wram_oe,            //out:
  111.         wram_we,            //out:
  112.         prgram_we,          //out:
  113.         prgram_oe,          //out:
  114.         ramchraout,         //out:
  115.         ramprgaout,         //out:
  116.         irq,                //out:
  117.         ciram_ce,           //out:
  118.         EXP6,               //out:  audio
  119.         //powerpak config registers
  120.         cfg_boot,           //in:   powerpak boot rom enable (disable prg ram)
  121.         cfg_chrmask,        //in:   CHR size mask
  122.         cfg_prgmask,        //in:   PRG size mask
  123.         cfg_vertical,       //in:   mirror flag from .NES header
  124.         cfg_fourscreen,     //in:   4-way mirror flag from .NES header
  125.         cfg_chrram          //in:   game has no chr rom (allow writes)
  126.     );
  127.  
  128.     powerpak_cfg ppc(
  129.         clk20, m2, ~nesprg_we, prgain, nesprgdin, reset,
  130.         cfg_chrram, cfg_prgmask, cfg_chrmask, cfg_vertical, cfg_fourscreen, cfg_boot
  131.     );
  132.  
  133. endmodule
  134.  
  135.  
  136. // powerpak control regs ($42X0 - $42X7)
  137. module powerpak_cfg(
  138.     input clk20,
  139.     input m2,
  140.     input nesprg_we,
  141.     input [15:0] ain,
  142.     input [7:0] nes_din,
  143.  
  144.     output reset,
  145.     output reg chrramen,
  146.     output reg [5:0] prgmask,
  147.     output reg [6:0] chrmask,
  148.     output reg vertical,
  149.     output reg fourscreen,
  150.     output reg booten
  151. );
  152.     wire write42XX=(ain[15:8]==8'h42) & nesprg_we;
  153.  
  154.     always@(posedge m2) begin
  155.         if(write42XX) case(ain[2:0])
  156.             0: prgmask <= nes_din[5:0];
  157.             1: {chrramen, chrmask} <= nes_din;
  158.             2: {fourscreen, vertical} <= {nes_din[3], nes_din[0]};
  159.             //3:                    //arcade
  160.             //4:                    //gamegenie
  161.             //7:                    //booten
  162.         endcase
  163.     end
  164.  
  165.     //-----------------------------
  166.  
  167.     reg [11:0] resetcount1;
  168.     reg [24:12] resetcount2;    //split counter up to keep older versions of XST from failing
  169.  
  170.     always@(posedge clk20, posedge m2)
  171.         if(m2)
  172.             {resetcount1,resetcount2}<=0;
  173.         else begin
  174.             resetcount1<=resetcount1+1;
  175.             if(resetcount1=='hfff)
  176.                 resetcount2<=resetcount2+1;
  177.         end
  178.     always@(posedge m2, posedge resetcount2[24])
  179.         if(resetcount2[24])        //switch to powerpak BIOS when reset is held for a while
  180.             booten=1;
  181.         else if((ain[2:0]==7) & write42XX)
  182.             booten=nes_din[0];
  183.  
  184.     //mapper reset=button pushed or booten flag modified.
  185.     assign reset=resetcount1[5] | (!m2 & write42XX & ain[2:0]==7);
  186.  
  187. endmodule
  188.  
  189. // powerpak BIOS uses game genie to store the save type so it can be checked after reset.
  190. // GG_ENABLE=0: disable game genie, only output sram flag (frees up a lot of resources)
  191. module gamegenie #(parameter GG_ENABLE=1) (
  192.     input m2,
  193.     input reset,
  194.     input nesprg_we,
  195.     input [15:0] ain,
  196.     input [7:0] nes_din,
  197.     input [7:0] ram_din,
  198.     output reg [7:0] nes_dout,
  199.     output config_rd        //set when sram flag is being read (addr5 match)
  200. );
  201.     reg [4:0] compare;
  202.     reg [7:0] cmp0, cmp1, cmp2, cmp3, cmp4;
  203.     reg [7:0] data0, data1, data2, data3, data4, data5;
  204.     reg [15:0] addr0, addr1, addr2, addr3, addr4, addr5;
  205.     reg [4:0] count;
  206.  
  207.     wire gg_write=nesprg_we & {ain[15:8],ain[2:0]}=='b0100_0010_100;       // 42X4
  208.     always@(posedge m2, posedge reset)
  209.         if(reset) count<=0;
  210.         else if(gg_write) count<=count+1;
  211.  
  212.     always@(posedge m2) begin
  213.         if(gg_write) case(count)
  214.             0:data0<=nes_din;
  215.             1:compare[0]<=nes_din[0];
  216.             2:cmp0<=nes_din;
  217.             3:addr0[7:0]<=nes_din;
  218.             4:addr0[15:8]<=nes_din;
  219.             5:data1<=nes_din;
  220.             6:compare[1]<=nes_din[0];
  221.             7:cmp1<=nes_din;
  222.             8:addr1[7:0]<=nes_din;
  223.             9:addr1[15:8]<=nes_din;
  224.             10:data2<=nes_din;
  225.             11:compare[2]<=nes_din[0];
  226.             12:cmp2<=nes_din;
  227.             13:addr2[7:0]<=nes_din;
  228.             14:addr2[15:8]<=nes_din;
  229.             15:data3<=nes_din;
  230.             16:compare[3]<=nes_din[0];
  231.             17:cmp3<=nes_din;
  232.             18:addr3[7:0]<=nes_din;
  233.             19:addr3[15:8]<=nes_din;
  234.             20:data4<=nes_din;
  235.             21:compare[4]<=nes_din[0];
  236.             22:cmp4<=nes_din;
  237.             23:addr4[7:0]<=nes_din;
  238.             24:addr4[15:8]<=nes_din;
  239.             25:data5<=nes_din;
  240.             //26
  241.             //27
  242.             28:addr5[7:0]<=nes_din;
  243.             29:addr5[15:8]<=nes_din;
  244.         endcase
  245.     end
  246.  
  247.     wire match0=(addr0==ain) & addr0[15] & (!compare[0] | (ram_din==cmp0));
  248.     wire match1=(addr1==ain) & addr1[15] & (!compare[1] | (ram_din==cmp1));
  249.     wire match2=(addr2==ain) & addr2[15] & (!compare[2] | (ram_din==cmp2));
  250.     wire match3=(addr3==ain) & addr3[15] & (!compare[3] | (ram_din==cmp3));
  251.     wire match4=(addr4==ain) & addr4[15] & (!compare[4] | (ram_din==cmp4));
  252.     wire match5=(addr5==ain);   //normally $4208 (sram flag stored in data5)
  253.  
  254.     always@* begin
  255.         if(!GG_ENABLE)
  256.             nes_dout=data5;     //mapper is responsible for muxing output
  257.         else case(1)
  258.             match0: nes_dout=data0;
  259.             match1: nes_dout=data1;
  260.             match2: nes_dout=data2;
  261.             match3: nes_dout=data3;
  262.             match4: nes_dout=data4;
  263.             match5: nes_dout=data5;
  264.             default: nes_dout=ram_din;
  265.         endcase
  266.     end
  267.     assign config_rd=!m2 & ~nesprg_we & match5;
  268.  
  269. endmodule
  270.  
  271. module pdm #(parameter BITS=8) (
  272.     input clk,
  273.     input [BITS-1:0] level,
  274.     output out
  275. );
  276.     reg [BITS-1:0] c;
  277.     reg [BITS-1:0] swap;
  278.     integer k;
  279.     always@*
  280.         for(k=0;k<BITS;k=k+1)
  281.             swap[k]=c[BITS-1-k];
  282.  
  283.     always@(posedge clk)
  284.         c<=c+1;
  285.     assign out=swap<level;
  286. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement