Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/nes_mappers.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCluster <clusterrr@clusterrr.com>2015-08-07 00:03:47 +0300
committerCluster <clusterrr@clusterrr.com>2015-08-07 00:03:47 +0300
commit6439f48d9a59cc4da4589c1dd9a4a082ef8e239c (patch)
treeff6688e1e845dfb08fb2463c44abacf610fd8095
first commit
-rw-r--r--1 (MMC1)/MMC1.v154
-rw-r--r--105 (NES-EVENT)/NES-EVENT.v156
-rw-r--r--11 (Color Dreams)/ColorDreams.v54
-rw-r--r--118 (TxSROM)/TxSROM.v149
-rw-r--r--13 (CPROM)/CPROM.v56
-rw-r--r--2 (UxROM)/UxROM.v56
-rw-r--r--22 (VRC2a)/VRC2a.v63
-rw-r--r--225 (Multiroms)/Mapper225.v95
-rw-r--r--228 (Cheetah Men II)/Mapper228.v103
-rw-r--r--23 (VRC2b)/VRC2b.v67
-rw-r--r--3 (CNROM)/CNROM.v55
-rw-r--r--34/Mapper34.v101
-rw-r--r--4 (MMC3)/MMC3.v160
-rw-r--r--66 (GxROM)/GxROM.v58
-rw-r--r--7 (AxROM)/AxROM.v53
-rw-r--r--71 (CodeMasters)/CodeMasters.v81
-rw-r--r--79 (NINA)/NINA.v56
17 files changed, 1517 insertions, 0 deletions
diff --git a/1 (MMC1)/MMC1.v b/1 (MMC1)/MMC1.v
new file mode 100644
index 0000000..f1452ec
--- /dev/null
+++ b/1 (MMC1)/MMC1.v
@@ -0,0 +1,154 @@
+// MMC1B mapper
+
+module MMC1 # (parameter USE_CHR_RAM = 0)
+(
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output reg [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output reg [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output reg ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [5:0] load;
+ reg [4:0] control;
+ reg [4:0] prg_bank;
+ reg [4:0] chr0_bank;
+ reg [4:0] chr1_bank;
+ reg [3:0] clock, reset_clock;
+ reg reseted;
+ reg started;
+
+ assign cpu_wr_out = cpu_rw_in;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13]
+ && m2 && romsel && !prg_bank[4]); // prg_bank[4] ignored for MMC1A (mapper 155)
+ assign led = ~romsel;
+
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+
+ assign ppu_sram_ce = USE_CHR_RAM ? ppu_addr_in[13] : 1'b1;
+ assign ppu_flash_ce = USE_CHR_RAM ? 1'b1 : ppu_addr_in[13];
+
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+ assign irq = 1'bz;
+
+ initial begin
+ started = 0;
+ end
+
+ always @ (posedge romsel)
+ begin
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1) // reset vector
+ begin
+ control <= 5'b01100;
+ prg_bank <= 0;
+ end
+ */
+ if (!started)
+ begin
+ control <= 5'b01100;
+ prg_bank <= 0;
+ started <= 1;
+ end
+ if (cpu_rw_in == 0)
+ begin
+ if (cpu_data_in[7] == 1) // reset
+ begin
+ load <= 6'b100000;
+ control[3:2] <= 2'b11;
+ reset_clock <= clock;
+ reseted <= 1;
+ end
+ // stupid workaround for Bill & Ted's Excellent Video Game Adventure which uses "INC $FFFF"
+ else if (reseted == 0 || !(clock == reset_clock || clock == reset_clock+1))
+ //else
+ begin
+ reseted <= 0;
+ load = {cpu_data_in[0], load[5:1]};
+ if (load[0] == 1)
+ begin
+ case (cpu_addr_in[14:13])
+ 2'b00: control <= load[5:1];
+ 2'b01: chr0_bank <= load[5:1];
+ 2'b10: chr1_bank <= load[5:1];
+ 2'b11: prg_bank <= load[5:1];
+ endcase
+ load = 6'b100000;
+ end
+ end
+ end
+ end
+
+ always @ (*) // mirroring control
+ begin
+ case (control[1:0])
+ 2'b00: ppu_ciram_a10 <= 0;
+ 2'b01: ppu_ciram_a10 <= 1;
+ 2'b10: ppu_ciram_a10 <= ppu_addr_in[10]; // verical mirroring
+ 2'b11: ppu_ciram_a10 <= ppu_addr_in[11]; // horizontal mirroring
+ endcase
+ end
+
+ always @ (*) // CPU memory mapping
+ begin
+ // workaround for games that requires power-up state
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1) // reset vector
+ begin
+ cpu_addr_out[18:12] <= {5'b11111, cpu_addr_in[13:12]}; // fixed to the last bank
+ end else
+ begin
+ */
+ case (control[3:2])
+ 2'b00: cpu_addr_out[18:12] <= {1'b0, prg_bank[3:1], cpu_addr_in[14:12]}; // 32KB bank mode
+ 2'b01: cpu_addr_out[18:12] <= {1'b0, prg_bank[3:1], cpu_addr_in[14:12]}; // 32KB bank mode
+ 2'b10: if (cpu_addr_in[14] == 0) // $8000-$BFFF
+ cpu_addr_out[18:12] <= {5'b00000, cpu_addr_in[13:12]}; // fixed to the first bank
+ else // $C000-$FFFF
+ cpu_addr_out[18:12] <= {1'b0, prg_bank[3:0], cpu_addr_in[13:12]}; // 16KB bank selected
+ 2'b11: if (cpu_addr_in[14] == 0) // $8000-$BFFF
+ cpu_addr_out[18:12] <= {1'b0, prg_bank[3:0], cpu_addr_in[13:12]}; // 16KB bank selected
+ else // $C000-$FFFF
+ cpu_addr_out[18:12] <= {5'b11111, cpu_addr_in[13:12]}; // fixed to the last bank
+ endcase
+ //end
+ end
+
+ always @ (*) // PPU memory mapping
+ begin
+ case (control[4])
+ 0: ppu_addr_out[18:10] <= {2'b00, chr0_bank[4:1], ppu_addr_in[12:10]}; // 8KB bank mode
+ 1: if (ppu_addr_in[12] == 0) // 4KB bank mode
+ ppu_addr_out[18:10] <= {2'b00, chr0_bank, ppu_addr_in[11:10]}; // first bank
+ else
+ ppu_addr_out[18:10] <= {2'b00, chr1_bank, ppu_addr_in[11:10]}; // second bank
+ endcase
+ end
+
+ always @ (posedge m2)
+ begin
+ clock = clock+1;
+ end
+endmodule
diff --git a/105 (NES-EVENT)/NES-EVENT.v b/105 (NES-EVENT)/NES-EVENT.v
new file mode 100644
index 0000000..f4787ae
--- /dev/null
+++ b/105 (NES-EVENT)/NES-EVENT.v
@@ -0,0 +1,156 @@
+// NES-EVENT cartridge
+// (c) Cluster, 2015
+// http://clusterrr.com
+
+module NES_EVENT # (
+/*
+ DIP switches: 0 - closed, 1 - opened
+ OOOO - 5.001
+ OOOC - 5.316
+ OOCO - 5.629
+ OOCC - 5.942
+ OCOO - 6.254
+ OCOC - 6.567
+ OCCO - 6.880
+ OCCC - 7.193
+ COOO - 7.505
+ COOC - 7.818
+ COCO - 8.131
+ COCC - 8.444
+ CCOO - 8.756
+ CCOC - 9.070
+ CCCO - 9.318
+ CCCC - 9.695
+*/
+ parameter DIP_SWITCH_4 = 1
+ parameter DIP_SWITCH_3 = 0,
+ parameter DIP_SWITCH_2 = 1,
+ parameter DIP_SWITCH_1 = 1,
+)
+(
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output reg [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output reg [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output reg ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output reg irq
+);
+ reg [5:0] load;
+ reg [4:0] control;
+ reg [4:0] prg_bank;
+ reg [4:0] chr0_bank;
+ reg [29:0] timer;
+
+ assign cpu_wr_out = cpu_rw_in;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13]
+ && m2 && romsel && !prg_bank[4]); // prg_bank[4] ignored for MMC1A (mapper 155)
+ assign led = ~chr0_bank[4]; // led is on when timer is on
+
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+
+ assign ppu_sram_ce = ppu_addr_in[13];
+ assign ppu_flash_ce = 1;
+
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ initial
+ begin
+ control <= 5'b01100; // MMC1, состояние после ресета
+ chr0_bank <= 5'b10000; // первый чип и первый банк
+ prg_bank <= 0;
+ load = 6'b100000;
+ timer = 0;
+ end
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ if (cpu_data_in[7] == 1) // ресет
+ begin
+ load = 6'b100000;
+ control[3:2] <= 2'b11;
+ end else begin
+ load = {cpu_data_in[0], load[5:1]};
+ if (load[0] == 1)
+ begin
+ case (cpu_addr_in[14:13])
+ 2'b00: control <= load[5:1];
+ 2'b01: chr0_bank <= load[5:1];
+ //2'b10: chr1_bank <= load[5:1];
+ 2'b11: prg_bank <= load[5:1];
+ endcase
+ load = 6'b100000;
+ end
+ end
+ end
+ end
+
+ always @ (posedge m2)
+ begin
+ if (chr0_bank[4] == 1) // сброс таймера
+ begin
+ timer = {1'b0, DIP_SWITCH_4[0], DIP_SWITCH_3[0], DIP_SWITCH_2[0], DIP_SWITCH_1[0], 25'b0000000000000000000000000};
+ irq <= 1'bZ;
+ end else // отсчёт!
+ begin
+ timer = timer + 1;
+ if (timer == 30'b111111111111111111111111111111)
+ irq <= 0; // время вышло!
+ end
+ end
+
+ always @ (*) // управление зеркалированием
+ begin
+ case (control[1:0])
+ 2'b00: ppu_ciram_a10 <= 0;
+ 2'b01: ppu_ciram_a10 <= 1;
+ 2'b10: ppu_ciram_a10 <= ppu_addr_in[10]; // вертикальный мирроринг
+ 2'b11: ppu_ciram_a10 <= ppu_addr_in[11]; // горизонтальный мирроринг
+ endcase
+ end
+
+ always @ (*) // Переключение CPU банков
+ begin
+ if (chr0_bank[3] == 0) // первый 128K чип
+ begin
+ cpu_addr_out[18:12] <= {2'b00, chr0_bank[2:1], cpu_addr_in[14:12]}; // 32KB режим
+ end else begin // второй 128K чип
+ case (control[3:2])
+ 2'b00: cpu_addr_out[18:12] <= {2'b01, prg_bank[2:1], cpu_addr_in[14:12]}; // 32KB режим
+ 2'b01: cpu_addr_out[18:12] <= {2'b01, prg_bank[2:1], cpu_addr_in[14:12]}; // 32KB режим
+ 2'b10: if (cpu_addr_in[14] == 0) // $8000-$BFFF
+ cpu_addr_out[18:12] <= {5'b01000, cpu_addr_in[13:12]}; // всегда первый банк
+ else // $C000-$FFFF
+ cpu_addr_out[18:12] <= {2'b01, prg_bank[2:0], cpu_addr_in[13:12]}; // 16KB режим
+ 2'b11: if (cpu_addr_in[14] == 0) // $8000-$BFFF
+ cpu_addr_out[18:12] <= {2'b01, prg_bank[2:0], cpu_addr_in[13:12]}; // 16KB режим
+ else // $C000-$FFFF
+ cpu_addr_out[18:12] <= {5'b01111, cpu_addr_in[13:12]}; // Всегда последний банк во втором 128K чипе
+ endcase
+ end
+ end
+
+endmodule
diff --git a/11 (Color Dreams)/ColorDreams.v b/11 (Color Dreams)/ColorDreams.v
new file mode 100644
index 0000000..29c0396
--- /dev/null
+++ b/11 (Color Dreams)/ColorDreams.v
@@ -0,0 +1,54 @@
+module ColorDreams # (parameter MIRRORING_VERTICAL = 1)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [7:0] bank;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = {bank[1:0], cpu_addr_in[14:12]};
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ assign ppu_addr_out[18:10] = {bank[7:4], ppu_addr_in[12:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = MIRRORING_VERTICAL ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ bank = cpu_data_in;
+ end
+endmodule
diff --git a/118 (TxSROM)/TxSROM.v b/118 (TxSROM)/TxSROM.v
new file mode 100644
index 0000000..e1a8cf5
--- /dev/null
+++ b/118 (TxSROM)/TxSROM.v
@@ -0,0 +1,149 @@
+// TxSROM (MMC3 alternative wiring)
+module TxSROM # (parameter USE_CHR_RAM = 1)
+(
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output reg [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output reg [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output reg ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [2:0] bank_select;
+ reg prg_mode;
+ reg chr_mode;
+ reg [7:0] r [0:7];
+ //reg mirroring;
+ reg [7:6] ram_protect;
+ reg [7:0] irq_latch;
+ reg [7:0] irq_counter;
+ reg [1:0] a12_low_time;
+ reg irq_reload;
+ reg irq_reload_clear;
+ reg irq_enabled;
+ reg irq_ready;
+
+ assign cpu_wr_out = cpu_rw_in && !ram_protect[6];
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = !(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel && ram_protect[7]);
+ assign led = ~romsel;
+
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+
+ // Enable CHR RAM or CHR ROM
+ assign ppu_sram_ce = USE_CHR_RAM ? ppu_addr_in[13] : 1'b1;
+ assign ppu_flash_ce = USE_CHR_RAM ? 1'b1 : ppu_addr_in[13];
+
+ assign ppu_ciram_ce = !ppu_addr_in[13];
+
+ // Mirroring control
+ //assign ppu_ciram_a10 = mirroring ? ppu_addr_in[11] : ppu_addr_in[10];
+
+ // Fire IRQ if need
+ assign irq = (irq_ready && irq_counter == 0) ? 1'b0 : 1'bZ;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ case ({cpu_addr_in[14:13], cpu_addr_in[0]})
+ 3'b000: begin // $8000-$9FFE, even
+ bank_select <= cpu_data_in[2:0];
+ prg_mode <= cpu_data_in[6];
+ chr_mode <= cpu_data_in[7];
+ end
+ 3'b001: r[bank_select] <= cpu_data_in; // $8001-$9FFF, odd
+ //3'b010: mirroring <= cpu_data_in[0]; // $A000-$BFFE, even
+ 3'b011: ram_protect <= cpu_data_in[7:6]; // $A001-$BFFF, odd
+ 3'b100: irq_latch <= cpu_data_in; // $C000-$DFFE, even
+ 3'b101: irq_reload <= 1; // $C001-$DFFF, odd
+ 3'b110: irq_enabled <= 0; // $E000-$FFFE, even
+ 3'b111: irq_enabled <= 1; // $E001-$FFFF, odd
+ endcase
+ end
+ if (irq_reload_clear)
+ irq_reload <= 0;
+ end
+
+ // PRG banking
+ always @ (*)
+ begin
+ case ({cpu_addr_in[14:13], prg_mode})
+ 3'b000: cpu_addr_out[18:13] <= r[6][5:0];
+ 3'b001: cpu_addr_out[18:13] <= 6'b111110;
+ 3'b010,
+ 3'b011: cpu_addr_out[18:13] <= r[7][5:0];
+ 3'b100: cpu_addr_out[18:13] <= 6'b111110;
+ 3'b101: cpu_addr_out[18:13] <= r[6][5:0];
+ default: cpu_addr_out[18:13] <= 6'b111111;
+ endcase
+ cpu_addr_out[12] <= cpu_addr_in[12];
+ end
+
+ // CHR banking
+ always @ (*)
+ begin
+ if (ppu_addr_in[12] == chr_mode)
+ begin
+ ppu_addr_out[16:10] <= {r[ppu_addr_in[11]][7:1], ppu_addr_in[10]};
+ ppu_ciram_a10 <= r[ppu_addr_in[11]][7];
+ end else begin
+ ppu_addr_out[16:10] <= r[2+ppu_addr_in[11:10]];
+ ppu_ciram_a10 <= r[2+ppu_addr_in[11:10]][7];
+ end;
+ ppu_addr_out[18] <= 0;
+ end
+
+ // Renable IRQ only when PPU A12 is low
+ always @ (*)
+ begin
+ if (!irq_enabled)
+ irq_ready <= 0;
+ else if (irq_enabled && !ppu_addr_in[12])
+ irq_ready <= 1;
+ end
+
+ // IRQ counter
+ always @ (posedge ppu_addr_in[12])
+ begin
+ if (a12_low_time == 3)
+ begin
+ if ((irq_reload && !irq_reload_clear) || (irq_counter == 0))
+ begin
+ irq_counter <= irq_latch;
+ if (irq_reload) irq_reload_clear <= 1;
+ end else
+ irq_counter = irq_counter-1;
+ end
+ if (!irq_reload) irq_reload_clear <= 0;
+ end
+
+ // A12 must be low for 3 rises of M2
+ always @ (posedge m2)
+ begin
+ if (ppu_addr_in[12] == 0 & a12_low_time < 3)
+ a12_low_time <= a12_low_time + 1;
+ if (ppu_addr_in[12] == 1)
+ a12_low_time <= 0;
+ end
+endmodule
diff --git a/13 (CPROM)/CPROM.v b/13 (CPROM)/CPROM.v
new file mode 100644
index 0000000..1f8ad57
--- /dev/null
+++ b/13 (CPROM)/CPROM.v
@@ -0,0 +1,56 @@
+// CPROM
+// Requires 16 of CHR RAM! Revision 1.2 only
+module CPROM
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [1:0] ppu_bank;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = cpu_addr_in[14:12];
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ //assign ppu_addr_out[18:10] = ppu_addr_in[12] ? {ppu_bank, ppu_addr_in[11:10]} : ppu_addr_in[11:10];
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_sram_ce = ppu_addr_in[13];
+ assign ppu_flash_ce = 1;
+ assign ppu_ciram_a10 = ppu_addr_in[10]; // Always vertical
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ ppu_bank <= cpu_data_in[1:0];
+ end
+endmodule
diff --git a/2 (UxROM)/UxROM.v b/2 (UxROM)/UxROM.v
new file mode 100644
index 0000000..8061c6a
--- /dev/null
+++ b/2 (UxROM)/UxROM.v
@@ -0,0 +1,56 @@
+// UxROM
+module UxROM # (parameter MIRRORING_VERTICAL = 0)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [3:0] cpu_bank;
+
+ assign led = cpu_rw_in && ppu_wr_in;
+
+ assign cpu_addr_out[18:14] = cpu_addr_in[14] ? {5'b11111} : {1'b0, cpu_bank};
+ assign cpu_addr_out[13:12] = cpu_addr_in[13:12];
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ //assign ppu_addr_out[18:10] = ppu_addr_in[13:10];
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_sram_ce = ppu_addr_in[13];
+ assign ppu_flash_ce = 1;
+ assign ppu_ciram_a10 = MIRRORING_VERTICAL ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ cpu_bank <= cpu_data_in[3:0];
+ end
+endmodule
diff --git a/22 (VRC2a)/VRC2a.v b/22 (VRC2a)/VRC2a.v
new file mode 100644
index 0000000..c933e51
--- /dev/null
+++ b/22 (VRC2a)/VRC2a.v
@@ -0,0 +1,63 @@
+module VRC2a
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [7:0] prg_bank [0:1];
+ reg [1:0] mirroring;
+ reg [3:0] chr_bank [0:15];
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = cpu_addr_in[14] ? {5'b11111, cpu_addr_in[13:12]} : {1'b0, prg_bank[cpu_addr_in[13]][4:0], cpu_addr_in[12]} ;
+ assign cpu_wr_out = cpu_rw_in;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel);
+
+ assign ppu_addr_out[18:10] = {chr_bank[{ppu_addr_in[12:10], 1'b1}], chr_bank[{ppu_addr_in[12:10], 1'b0}][3:1]} ;
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = mirroring[1] ? mirroring[0] : (mirroring[0] ? ppu_addr_in[11] : ppu_addr_in[10]);
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ case (cpu_addr_in[14:12])
+ 3'b000: prg_bank[0] <= cpu_data_in; // $8000
+ 3'b010: prg_bank[1] <= cpu_data_in; // $A000
+ 3'b001: mirroring <= cpu_data_in[1:0]; // $9000
+ default: chr_bank[{cpu_addr_in[14:12]-2'b11,cpu_addr_in[0],cpu_addr_in[1]}] <= cpu_data_in[3:0];
+ endcase
+ end
+ end
+endmodule
diff --git a/225 (Multiroms)/Mapper225.v b/225 (Multiroms)/Mapper225.v
new file mode 100644
index 0000000..0d47998
--- /dev/null
+++ b/225 (Multiroms)/Mapper225.v
@@ -0,0 +1,95 @@
+module Mapper225
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output reg [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [5:0] chr_bank;
+ reg prg_mode;
+ reg [5:0] prg_bank;
+ reg mirroring;
+
+ assign led = ~romsel;
+
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel);
+
+ assign ppu_addr_out[18:10] = {chr_bank, ppu_addr_in[12:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = !mirroring ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ // uselsess
+ initial
+ begin
+ chr_bank <= 0;
+ prg_mode <= 0;
+ prg_bank <= 0;
+ mirroring <= 0;
+ end
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ chr_bank <= cpu_addr_in[5:0];
+ prg_bank <= cpu_addr_in[11:6];
+ prg_mode <= cpu_addr_in[12];
+ mirroring <= cpu_addr_in[13];
+ end
+
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1) // reset vector
+ begin
+ chr_bank <= 0;
+ prg_mode <= 0;
+ prg_bank <= 0;
+ mirroring <= 0;
+ end
+ */
+ end
+
+ always @ (*)
+ begin
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1 && romsel == 0)
+ cpu_addr_out[18:12] = cpu_addr_in[14:12];
+ else begin
+ */
+ if (cpu_addr_in[14] == 0 || prg_mode)
+ cpu_addr_out[18:14] = prg_bank;
+ else
+ cpu_addr_out[18:14] = prg_bank+1;
+ cpu_addr_out[13:12] = cpu_addr_in[13:12];
+ //end
+ end
+endmodule
diff --git a/228 (Cheetah Men II)/Mapper228.v b/228 (Cheetah Men II)/Mapper228.v
new file mode 100644
index 0000000..c060e5c
--- /dev/null
+++ b/228 (Cheetah Men II)/Mapper228.v
@@ -0,0 +1,103 @@
+module Mapper228
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output reg [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [5:0] chr_bank;
+ reg prg_mode;
+ reg [4:0] prg_bank;
+ reg [1:0] prg_chip;
+ reg mirroring;
+
+ assign led = ~romsel;
+
+ /*
+ assign cpu_addr_out[18:12] = {
+ ((romsel == 0 && cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1) ? 4'b0000 : prg_bank[4:1])
+ , cpu_addr_in[14]^prg_mode, cpu_addr_in[13:12]};
+ */
+ assign cpu_wr_out = cpu_rw_in;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel);
+
+ assign ppu_addr_out[18:10] = {chr_bank, ppu_addr_in[12:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = !mirroring ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ initial
+ begin
+ chr_bank <= 0;
+ prg_mode <= 0;
+ prg_bank <= 0;
+ prg_chip <= 0;
+ mirroring <= 0;
+ end
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ chr_bank <= {cpu_addr_in[3:0], cpu_data_in[1:0]};
+ prg_mode <= cpu_addr_in[5];
+ prg_bank <= cpu_addr_in[10:6];
+ prg_chip <= cpu_addr_in[12:11];
+ mirroring <= cpu_addr_in[13];
+ end
+
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1) // reset vector
+ begin
+ chr_bank <= 0;
+ prg_mode <= 0;
+ prg_bank <= 0;
+ prg_chip <= 0;
+ mirroring <= 0;
+ end
+ */
+ end
+
+ always @ (*)
+ begin
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1 && romsel == 0)
+ cpu_addr_out[18:12] = cpu_addr_in[14:12];
+ else begin
+ */
+ if (cpu_addr_in[14] == 0 || prg_mode)
+ cpu_addr_out[18:14] = prg_bank;
+ else
+ cpu_addr_out[18:14] = prg_bank+1;
+ cpu_addr_out[13:12] = cpu_addr_in[13:12];
+// end
+ end
+endmodule
diff --git a/23 (VRC2b)/VRC2b.v b/23 (VRC2b)/VRC2b.v
new file mode 100644
index 0000000..5d8d21c
--- /dev/null
+++ b/23 (VRC2b)/VRC2b.v
@@ -0,0 +1,67 @@
+module VRC2b
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [7:0] prg_bank [0:1];
+ reg [1:0] mirroring;
+ reg [3:0] chr_bank [0:15];
+
+ wire a_hi, a_low;
+ assign a_hi = cpu_addr_in[1] | cpu_addr_in[3] | cpu_addr_in[5] | cpu_addr_in[7];
+ assign a_low = cpu_addr_in[0] | cpu_addr_in[2] | cpu_addr_in[4] | cpu_addr_in[6];
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = cpu_addr_in[14] ? {5'b11111, cpu_addr_in[13:12]} : {1'b0, prg_bank[cpu_addr_in[13]][4:0], cpu_addr_in[12]} ;
+ assign cpu_wr_out = cpu_rw_in;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel);
+
+ assign ppu_addr_out[18:10] = {chr_bank[{ppu_addr_in[12:10], 1'b1}], chr_bank[{ppu_addr_in[12:10], 1'b0}]} ;
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = mirroring[1] ? mirroring[0] : (mirroring[0] ? ppu_addr_in[11] : ppu_addr_in[10]);
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ case (cpu_addr_in[14:12])
+ 3'b000: prg_bank[0] <= cpu_data_in; // $8000
+ 3'b010: prg_bank[1] <= cpu_data_in; // $A000
+ 3'b001: mirroring <= {a_hi, a_low}; // $9000
+ default: chr_bank[{cpu_addr_in[14:12]-2'b11, a_hi, a_low}] <= cpu_data_in[3:0];
+ endcase
+ end
+ end
+endmodule
diff --git a/3 (CNROM)/CNROM.v b/3 (CNROM)/CNROM.v
new file mode 100644
index 0000000..f7c2cb1
--- /dev/null
+++ b/3 (CNROM)/CNROM.v
@@ -0,0 +1,55 @@
+// CNROM
+module CNROM # (parameter MIRRORING_VERTICAL = 1)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [1:0] ppu_bank;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = cpu_addr_in[14:12];
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ assign ppu_addr_out[18:10] = {ppu_bank, ppu_addr_in[12:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = 1;
+ assign ppu_sram_ce = 1;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_ciram_a10 = MIRRORING_VERTICAL ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ ppu_bank <= cpu_data_in[1:0];
+ end
+endmodule
diff --git a/34/Mapper34.v b/34/Mapper34.v
new file mode 100644
index 0000000..97409aa
--- /dev/null
+++ b/34/Mapper34.v
@@ -0,0 +1,101 @@
+ module Mapper34 # (parameter MIRRORING_VERTICAL = 0)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [1:0] prg_bank;
+ reg [3:0] chr_bank [0:1];
+ reg use_chr_ram;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = {prg_bank, cpu_addr_in[14:12]};
+ assign cpu_wr_out = cpu_rw_in;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = ~(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel);
+
+ assign ppu_addr_out[18:10] = {chr_bank[ppu_addr_in[12]], ppu_addr_in[11:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = use_chr_ram ? 1 : ppu_addr_in[13];
+ assign ppu_sram_ce = use_chr_ram ? ppu_addr_in[13] : 1;
+ assign ppu_ciram_a10 = MIRRORING_VERTICAL ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ reg started;
+
+ initial
+ begin
+ started <= 0;
+ end
+
+ always @ (negedge m2)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ if (romsel == 0) // BNROM
+ begin
+ prg_bank <= cpu_data_in[1:0];
+ chr_bank[0] <= 0;
+ chr_bank[1] <= 1;
+ use_chr_ram <= 1;
+ end else
+ begin // NINA-001
+ case (cpu_addr_in[14:0])
+ 15'b111111111111101: prg_bank <= {1'b0, cpu_data_in[0]}; // $7FFD
+ 15'b111111111111110, // $7FFE
+ 15'b111111111111111: // $7FFF
+ begin
+ chr_bank[cpu_addr_in[0]] <= cpu_data_in[3:0];
+ use_chr_ram <= 0;
+ end
+ endcase
+ end
+ end
+
+ if (!started)
+ begin
+ prg_bank <= 0;
+ chr_bank[0] <= 0;
+ chr_bank[1] <= 1;
+ use_chr_ram <= 1; // use CHR RAM until CHR bank not selected
+ started <= 1;
+ end
+
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && romsel == 0 && cpu_rw_in == 1) // reset vector
+ begin
+ prg_bank <= 0;
+ chr_bank[0] <= 0;
+ chr_bank[1] <= 1;
+ use_chr_ram <= 1; // use CHR RAM until CHR bank not selected
+ end
+ */
+ end
+endmodule
diff --git a/4 (MMC3)/MMC3.v b/4 (MMC3)/MMC3.v
new file mode 100644
index 0000000..ad4357c
--- /dev/null
+++ b/4 (MMC3)/MMC3.v
@@ -0,0 +1,160 @@
+// MMC3 mapper
+module MMC3 # (parameter USE_CHR_RAM = 1)
+(
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output reg [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output reg [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output reg irq
+);
+ reg [2:0] bank_select;
+ reg prg_mode;
+ reg chr_mode;
+ reg [7:0] r [0:7];
+ reg mirroring;
+ reg [7:6] ram_protect;
+ reg [7:0] irq_latch;
+ reg [7:0] irq_counter;
+ reg [2:0] a12_low_time;
+ reg irq_reload;
+ reg irq_reload_clear;
+ reg irq_enabled;
+ reg irq_value;
+ reg irq_ready;
+ reg started;
+
+ assign cpu_wr_out = cpu_rw_in || ram_protect[6];
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = !(cpu_addr_in[14] && cpu_addr_in[13] && m2 && romsel && ram_protect[7]);
+ assign led = ~romsel;
+
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+
+ // Enable CHR RAM or CHR ROM
+ assign ppu_sram_ce = USE_CHR_RAM ? ppu_addr_in[13] : 1'b1;
+ assign ppu_flash_ce = USE_CHR_RAM ? 1'b1 : ppu_addr_in[13];
+
+ assign ppu_ciram_ce = !ppu_addr_in[13];
+
+ // Mirroring control
+ assign ppu_ciram_a10 = mirroring ? ppu_addr_in[11] : ppu_addr_in[10];
+
+ initial
+ begin
+ irq_enabled = 0;
+ irq_ready = 0;
+ end
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ case ({cpu_addr_in[14:13], cpu_addr_in[0]})
+ 3'b000: begin // $8000-$9FFE, even
+ bank_select <= cpu_data_in[2:0];
+ prg_mode <= cpu_data_in[6];
+ chr_mode <= cpu_data_in[7];
+ end
+ 3'b001: r[bank_select] <= cpu_data_in; // $8001-$9FFF, odd
+ 3'b010: mirroring <= cpu_data_in[0]; // $A000-$BFFE, even
+ 3'b011: ram_protect <= cpu_data_in[7:6]; // $A001-$BFFF, odd
+ 3'b100: irq_latch <= cpu_data_in; // $C000-$DFFE, even
+ 3'b101: irq_reload <= 1; // $C001-$DFFF, odd
+ 3'b110: irq_enabled <= 0; // $E000-$FFFE, even
+ 3'b111: irq_enabled <= 1; // $E001-$FFFF, odd
+ endcase
+ end
+ if (irq_reload_clear)
+ irq_reload <= 0;
+ end
+
+ // PRG banking
+ always @ (*)
+ begin
+ case ({cpu_addr_in[14:13], prg_mode})
+ 3'b000: cpu_addr_out[18:13] <= r[6][5:0];
+ 3'b001: cpu_addr_out[18:13] <= 6'b111110;
+ 3'b010,
+ 3'b011: cpu_addr_out[18:13] <= r[7][5:0];
+ 3'b100: cpu_addr_out[18:13] <= 6'b111110;
+ 3'b101: cpu_addr_out[18:13] <= r[6][5:0];
+ default: cpu_addr_out[18:13] <= 6'b111111;
+ endcase
+ cpu_addr_out[12] <= cpu_addr_in[12];
+ end
+
+ // CHR banking
+ always @ (*)
+ begin
+ if (ppu_addr_in[12] == chr_mode)
+ ppu_addr_out[17:10] <= {r[ppu_addr_in[11]][7:1], ppu_addr_in[10]};
+ else
+ ppu_addr_out[17:10] <= r[2+ppu_addr_in[11:10]];
+ ppu_addr_out[18] <= 0;
+ end
+
+ // Renable IRQ only when PPU A12 is low
+ always @ (*)
+ begin
+ if (!irq_enabled)
+ begin
+ irq_ready = 0;
+ irq <= 1'bZ;
+ end else if (irq_enabled && !irq_value)
+ irq_ready = 1;
+ else if (irq_ready && irq_value)
+ irq <= 1'b0;
+ end
+
+ // IRQ counter
+ always @ (posedge ppu_addr_in[12])
+ begin
+ if (a12_low_time == 3)
+ begin
+ //irq_counter_last = irq_counter;
+ if ((irq_reload && !irq_reload_clear) || (irq_counter == 0))
+ begin
+ irq_counter = irq_latch;
+ if (irq_reload) irq_reload_clear <= 1;
+ end else
+ irq_counter = irq_counter-1;
+ if (irq_counter == 0 && irq_enabled)
+ irq_value = 1;
+ else
+ irq_value = 0;
+ end
+ if (!irq_reload) irq_reload_clear <= 0;
+ end
+
+ // A12 must be low for 3 rises of M2
+ always @ (posedge m2, posedge ppu_addr_in[12])
+ begin
+ if (ppu_addr_in[12])
+ a12_low_time <= 0;
+ else if (a12_low_time < 3)
+ a12_low_time <= a12_low_time + 1;
+ end
+
+endmodule
diff --git a/66 (GxROM)/GxROM.v b/66 (GxROM)/GxROM.v
new file mode 100644
index 0000000..6487467
--- /dev/null
+++ b/66 (GxROM)/GxROM.v
@@ -0,0 +1,58 @@
+module GxROM # (parameter MIRRORING_VERTICAL = 1)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [1:0] prg_bank;
+ reg [1:0] chr_bank;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = {prg_bank, cpu_addr_in[14:12]};
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ assign ppu_addr_out[18:10] = {chr_bank, ppu_addr_in[12:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = MIRRORING_VERTICAL ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ begin
+ chr_bank = cpu_data_in[1:0];
+ prg_bank = cpu_data_in[5:4];
+ end
+ end
+endmodule
diff --git a/7 (AxROM)/AxROM.v b/7 (AxROM)/AxROM.v
new file mode 100644
index 0000000..4ee93ac
--- /dev/null
+++ b/7 (AxROM)/AxROM.v
@@ -0,0 +1,53 @@
+module AxROM
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [7:0] bank;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = {bank[2:0], cpu_addr_in[14:12]};
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_flash_ce = 1;
+ assign ppu_sram_ce = ppu_addr_in[13];
+ assign ppu_ciram_a10 = bank[4];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0)
+ bank = cpu_data_in;
+ end
+endmodule
diff --git a/71 (CodeMasters)/CodeMasters.v b/71 (CodeMasters)/CodeMasters.v
new file mode 100644
index 0000000..e44ce86
--- /dev/null
+++ b/71 (CodeMasters)/CodeMasters.v
@@ -0,0 +1,81 @@
+// CodeMasters mapper
+module CodeMasters # (parameter MIRRORING_VERTICAL = 1)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [3:0] cpu_bank;
+ reg [1:0] mirroring;
+ reg started;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:14] = cpu_addr_in[14] ? {5'b11111} : {1'b0, cpu_bank};
+ assign cpu_addr_out[13:12] = cpu_addr_in[13:12];
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ //assign ppu_addr_out[18:10] = ppu_addr_in[13:10];
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = ppu_wr_in;
+ assign ppu_sram_ce = ppu_addr_in[13];
+ assign ppu_flash_ce = 1;
+ assign ppu_ciram_a10 = mirroring[1] ? mirroring[0] : (mirroring[0] ? ppu_addr_in[10] : ppu_addr_in[11]);
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ initial
+ begin
+ started <= 0;
+ end
+
+ always @ (posedge romsel)
+ begin
+ if (cpu_rw_in == 0 && cpu_addr_in[14] == 1)
+ cpu_bank <= cpu_data_in[3:0];
+
+ if (cpu_rw_in == 0 && cpu_addr_in[14:12] == 3'b001) // allow to select mirroring for Fire Hawk
+ begin
+ mirroring = {1'b1, cpu_data_in[4]};
+ end
+
+ if (!started)
+ begin
+ mirroring = {1'b0, MIRRORING_VERTICAL}; // reset mirroring
+ started <= 1;
+ end
+
+ /*
+ if (cpu_addr_in[14:1] == 14'b11111111111110 && cpu_rw_in == 1) // reset vector
+ begin
+ mirroring = {1'b0, MIRRORING_VERTICAL}; // reset mirroring
+ end
+ */
+ end
+endmodule
diff --git a/79 (NINA)/NINA.v b/79 (NINA)/NINA.v
new file mode 100644
index 0000000..0441f2a
--- /dev/null
+++ b/79 (NINA)/NINA.v
@@ -0,0 +1,56 @@
+module NINA # (parameter MIRRORING_VERTICAL = 1)
+ (
+ output led,
+
+ input m2,
+ input romsel,
+ input cpu_rw_in,
+ output [18:12] cpu_addr_out,
+ input [14:0] cpu_addr_in,
+ input [7:0] cpu_data_in,
+ output cpu_wr_out,
+ output cpu_rd_out,
+ output cpu_flash_ce,
+ output cpu_sram_ce,
+
+ input ppu_rd_in,
+ input ppu_wr_in,
+ input [13:10] ppu_addr_in,
+ output [18:10] ppu_addr_out,
+ output ppu_rd_out,
+ output ppu_wr_out,
+ output ppu_flash_ce,
+ output ppu_sram_ce,
+ output ppu_ciram_a10,
+ output ppu_ciram_ce,
+
+ output irq
+);
+ reg [3:0] bank;
+
+ assign led = ~romsel;
+
+ assign cpu_addr_out[18:12] = {bank[3], cpu_addr_in[14:12]};
+ assign cpu_wr_out = 1;
+ assign cpu_rd_out = ~cpu_rw_in;
+ assign cpu_flash_ce = romsel;
+ assign cpu_sram_ce = 1;
+
+ assign ppu_addr_out[18:10] = {bank[2:0], ppu_addr_in[12:10]};
+ assign ppu_rd_out = ppu_rd_in;
+ assign ppu_wr_out = 1;
+ assign ppu_flash_ce = ppu_addr_in[13];
+ assign ppu_sram_ce = 1;
+ assign ppu_ciram_a10 = MIRRORING_VERTICAL ? ppu_addr_in[10] : ppu_addr_in[11];
+ assign ppu_ciram_ce = ~ppu_addr_in[13];
+
+ assign irq = 1'bz;
+
+ always @ (negedge m2)
+ begin
+ if ({cpu_addr_in[14:13], cpu_addr_in[8]} == 3'b101 && romsel == 1 && cpu_rw_in == 0)
+ begin
+ bank <= cpu_data_in[3:0];
+ end
+ end
+endmodule