Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `default_nettype none
- `define MAPxx MAP03 //MAP03.MAP CNROM
- //`define MAPxx MAP04 //MAP04.MAP MMC3
- //`define MAPxx MAPVRC4 //MAP15,17,19.MAP VRC4
- //`define MAPxx MAPVRC6 //MAP18,1A.MAP VRC6
- //`define MAPxx MAP45 //MAP45.MAP Sunsoft 5B "Gimmick"
- //`define MAPxx MAPN106 //MAP13.MAP Namco-106
- //`define MAPxx MAPFDS //F.MAP Famicom disk system
- module powerpak(
- input CLK_20M,
- output BOOT_ENABLE,
- input NES_M2,
- output NES_IRQ,
- input [13:0] NES_CHR_A,
- inout [7:0] NES_CHR_D,
- input NES_CHR_RD,
- input NES_CHR_WR,
- output NES_CIRAM_CE,
- input NES_PRG_CE,
- inout [7:0] NES_PRG_D,
- input [14:0] NES_PRG_A,
- input NES_PRG_RW,
- output RAM_CHR_CE,
- output [18:0] RAM_CHR_A, //3..9 unconnected (ignore warnings)
- output RAM_PRG_OE,
- output RAM_PRG_WE,
- output [18:13] RAM_PRG_A,
- inout [7:0] RAM_PRG_D,
- output WRAM_PRG_OE,
- output WRAM_PRG_WE,
- output EXP6
- );
- wire m2, clk20;
- wire chrram_we, chrram_oe, wram_oe, wram_we, prgram_we, prgram_oe, neschr_oe;
- wire nesprg_oe, nesprg_we, nesprg_ce, neschr_rd, neschr_wr, ciram_ce;
- wire [15:0] prgain;
- wire [13:0] chrain;
- wire [18:10] ramchraout;
- wire [18:13] ramprgaout;
- wire [7:0] ramprgdin;
- wire [7:0] nesprgdin;
- wire [7:0] nesprgdout;
- wire [7:0] neschrdin;
- wire [7:0] neschrdout;
- wire irq;
- wire cfg_boot; //powerpak boot rom enable (disable game rom)
- wire [18:12] cfg_chrmask; //CHR size mask
- wire [18:13] cfg_prgmask; //PRG size mask
- wire cfg_vertical; //mirror flag from .NES header
- wire cfg_fourscreen; //4-way mirror flag from .NES header
- wire cfg_chrram; //game has no chr rom (allow writes)
- wire reset;
- //needed for Dirty Harry (MMC3) and Paperboy (CNROM)
- //D7,D5 low during 4016/7 read fixes controller input problems
- //wire readpad=(prgain[15:1]=='b0100_0000_0001_011) & nesprg_we & ~m2;
- //wire [7:0] openbus={!readpad, 1'b1, !readpad, 5'b11111};
- IBUFG b00(.I(NES_CHR_RD),.O(neschr_rd));
- IBUFG b01(.I(NES_M2),.O(m2));
- IBUFG b02(.I(CLK_20M),.O(clk20));
- IBUFG b03(.I(NES_CHR_WR),.O(neschr_wr));
- IOBUF b04[7:0](.I(1'b0),.O(ramprgdin),.T(nesprgdin | {8{~wram_we & ~prgram_we}}), .IO(RAM_PRG_D));
- IOBUF b05[7:0](.I(1'b0),.O(neschrdin),.T(neschrdout | {8{~neschr_oe}}),.IO(NES_CHR_D));
- IOBUF b06[7:0](.I(1'b0),.O(nesprgdin),.T(nesprgdout | {8{~nesprg_oe}}),.IO(NES_PRG_D));
- //IOBUF b06[7:0](.I(1'b0),.O(nesprgdin),.T(openbus & (nesprgdout | {8{~nesprg_oe}})),.IO(NES_PRG_D));
- OBUFT b07(.I(1'b0),.O(BOOT_ENABLE),.T(cfg_boot));
- OBUFT b08(.I(1'b0),.O(WRAM_PRG_WE),.T(~wram_we));
- OBUFT b09(.I(1'b0),.O(WRAM_PRG_OE),.T(~wram_oe));
- OBUFT b10(.I(1'b0),.O(RAM_PRG_WE),.T(~prgram_we));
- OBUFT b11(.I(1'b0),.O(RAM_PRG_OE),.T(~prgram_oe));
- OBUFT b12(.I(1'b0),.O(NES_IRQ),.T(~irq));
- OBUFT b13(.I(1'b0),.O(NES_CIRAM_CE),.T(~ciram_ce));
- OBUFT b14(.I(1'b0),.O(RAM_CHR_CE),.T(~(chrram_we | chrram_oe)));
- OBUFT b15[2:0](.I(1'b0),.O(RAM_CHR_A[2:0]),.T(chrain[2:0]));
- OBUFT b16[18:10](.I(1'b0),.O(RAM_CHR_A[18:10]),.T(ramchraout[18:10]));
- OBUFT b17[18:13](.I(1'b0),.O(RAM_PRG_A[18:13]),.T(ramprgaout[18:13]));
- IBUF b18(.I(NES_PRG_RW),.O(nesprg_we));
- IBUF b19[13:0](.I(NES_CHR_A),.O(chrain));
- IBUF b20(.I(NES_PRG_CE),.O(nesprg_ce));
- IBUF b21[14:0](.I(NES_PRG_A),.O(prgain[14:0]));
- assign prgain[15]=!nesprg_ce;
- reg [1:0] m2buf;
- always@(posedge clk20)
- m2buf<={m2buf[0],m2};
- wire m2_n = ~m2 & ~m2buf[1]; // m2 with a delayed falling edge, to deal with addressing glitches
- `MAPxx mapper ( //all signals active high
- m2, //in: 6502 M2 clock
- m2_n, //in:
- clk20, //in: 20MHz clock from powerpak
- reset, //in:
- ~nesprg_we, //in:
- nesprg_oe, //out:
- ~neschr_rd, //in:
- ~neschr_wr, //in:
- prgain, //in:
- chrain, //in:
- nesprgdin, //in:
- ramprgdin, //in: from prgram or wram
- nesprgdout, //out:
- neschrdout, //out:
- neschr_oe, //out:
- chrram_we, //out:
- chrram_oe, //out:
- wram_oe, //out:
- wram_we, //out:
- prgram_we, //out:
- prgram_oe, //out:
- ramchraout, //out:
- ramprgaout, //out:
- irq, //out:
- ciram_ce, //out:
- EXP6, //out: audio
- //powerpak config registers
- cfg_boot, //in: powerpak boot rom enable (disable prg ram)
- cfg_chrmask, //in: CHR size mask
- cfg_prgmask, //in: PRG size mask
- cfg_vertical, //in: mirror flag from .NES header
- cfg_fourscreen, //in: 4-way mirror flag from .NES header
- cfg_chrram //in: game has no chr rom (allow writes)
- );
- powerpak_cfg ppc(
- clk20, m2, ~nesprg_we, prgain, nesprgdin, reset,
- cfg_chrram, cfg_prgmask, cfg_chrmask, cfg_vertical, cfg_fourscreen, cfg_boot
- );
- endmodule
- // powerpak control regs ($42X0 - $42X7)
- module powerpak_cfg(
- input clk20,
- input m2,
- input nesprg_we,
- input [15:0] ain,
- input [7:0] nes_din,
- output reset,
- output reg chrramen,
- output reg [5:0] prgmask,
- output reg [6:0] chrmask,
- output reg vertical,
- output reg fourscreen,
- output reg booten
- );
- wire write42XX=(ain[15:8]==8'h42) & nesprg_we;
- always@(posedge m2) begin
- if(write42XX) case(ain[2:0])
- 0: prgmask <= nes_din[5:0];
- 1: {chrramen, chrmask} <= nes_din;
- 2: {fourscreen, vertical} <= {nes_din[3], nes_din[0]};
- //3: //arcade
- //4: //gamegenie
- //7: //booten
- endcase
- end
- //-----------------------------
- reg [11:0] resetcount1;
- reg [24:12] resetcount2; //split counter up to keep older versions of XST from failing
- always@(posedge clk20, posedge m2)
- if(m2)
- {resetcount1,resetcount2}<=0;
- else begin
- resetcount1<=resetcount1+1;
- if(resetcount1=='hfff)
- resetcount2<=resetcount2+1;
- end
- always@(posedge m2, posedge resetcount2[24])
- if(resetcount2[24]) //switch to powerpak BIOS when reset is held for a while
- booten=1;
- else if((ain[2:0]==7) & write42XX)
- booten=nes_din[0];
- //mapper reset=button pushed or booten flag modified.
- assign reset=resetcount1[5] | (!m2 & write42XX & ain[2:0]==7);
- endmodule
- // powerpak BIOS uses game genie to store the save type so it can be checked after reset.
- // GG_ENABLE=0: disable game genie, only output sram flag (frees up a lot of resources)
- module gamegenie #(parameter GG_ENABLE=1) (
- input m2,
- input reset,
- input nesprg_we,
- input [15:0] ain,
- input [7:0] nes_din,
- input [7:0] ram_din,
- output reg [7:0] nes_dout,
- output config_rd //set when sram flag is being read (addr5 match)
- );
- reg [4:0] compare;
- reg [7:0] cmp0, cmp1, cmp2, cmp3, cmp4;
- reg [7:0] data0, data1, data2, data3, data4, data5;
- reg [15:0] addr0, addr1, addr2, addr3, addr4, addr5;
- reg [4:0] count;
- wire gg_write=nesprg_we & {ain[15:8],ain[2:0]}=='b0100_0010_100; // 42X4
- always@(posedge m2, posedge reset)
- if(reset) count<=0;
- else if(gg_write) count<=count+1;
- always@(posedge m2) begin
- if(gg_write) case(count)
- 0:data0<=nes_din;
- 1:compare[0]<=nes_din[0];
- 2:cmp0<=nes_din;
- 3:addr0[7:0]<=nes_din;
- 4:addr0[15:8]<=nes_din;
- 5:data1<=nes_din;
- 6:compare[1]<=nes_din[0];
- 7:cmp1<=nes_din;
- 8:addr1[7:0]<=nes_din;
- 9:addr1[15:8]<=nes_din;
- 10:data2<=nes_din;
- 11:compare[2]<=nes_din[0];
- 12:cmp2<=nes_din;
- 13:addr2[7:0]<=nes_din;
- 14:addr2[15:8]<=nes_din;
- 15:data3<=nes_din;
- 16:compare[3]<=nes_din[0];
- 17:cmp3<=nes_din;
- 18:addr3[7:0]<=nes_din;
- 19:addr3[15:8]<=nes_din;
- 20:data4<=nes_din;
- 21:compare[4]<=nes_din[0];
- 22:cmp4<=nes_din;
- 23:addr4[7:0]<=nes_din;
- 24:addr4[15:8]<=nes_din;
- 25:data5<=nes_din;
- //26
- //27
- 28:addr5[7:0]<=nes_din;
- 29:addr5[15:8]<=nes_din;
- endcase
- end
- wire match0=(addr0==ain) & addr0[15] & (!compare[0] | (ram_din==cmp0));
- wire match1=(addr1==ain) & addr1[15] & (!compare[1] | (ram_din==cmp1));
- wire match2=(addr2==ain) & addr2[15] & (!compare[2] | (ram_din==cmp2));
- wire match3=(addr3==ain) & addr3[15] & (!compare[3] | (ram_din==cmp3));
- wire match4=(addr4==ain) & addr4[15] & (!compare[4] | (ram_din==cmp4));
- wire match5=(addr5==ain); //normally $4208 (sram flag stored in data5)
- always@* begin
- if(!GG_ENABLE)
- nes_dout=data5; //mapper is responsible for muxing output
- else case(1)
- match0: nes_dout=data0;
- match1: nes_dout=data1;
- match2: nes_dout=data2;
- match3: nes_dout=data3;
- match4: nes_dout=data4;
- match5: nes_dout=data5;
- default: nes_dout=ram_din;
- endcase
- end
- assign config_rd=!m2 & ~nesprg_we & match5;
- endmodule
- module pdm #(parameter BITS=8) (
- input clk,
- input [BITS-1:0] level,
- output out
- );
- reg [BITS-1:0] c;
- reg [BITS-1:0] swap;
- integer k;
- always@*
- for(k=0;k<BITS;k=k+1)
- swap[k]=c[BITS-1-k];
- always@(posedge clk)
- c<=c+1;
- assign out=swap<level;
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement