mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-02-12 02:27:03 +00:00
Merge pull request #35 from sebdel/master
[NES] Stabilization and MMC1 fixes by Sebdel
This commit is contained in:
@@ -212,9 +212,9 @@ end
|
||||
wire strt = (start_cnt != 0);
|
||||
wire sel = (select_cnt != 0);
|
||||
|
||||
wire [7:0] nes_joy_A = { joyB[0], joyB[1], joyB[2], joyB[3],
|
||||
wire [7:0] nes_joy_A = reset_nes ? 8'd0 : { joyB[0], joyB[1], joyB[2], joyB[3],
|
||||
joyB[7] | strt, joyB[6] | sel, joyB[5], joyB[4] } | kbd_joy0;
|
||||
wire [7:0] nes_joy_B = { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
wire [7:0] nes_joy_B = reset_nes ? 8'd0 : { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
joyA[7], joyA[6], joyA[5], joyA[4] } | kbd_joy1;
|
||||
|
||||
wire clock_locked;
|
||||
@@ -222,14 +222,14 @@ wire [7:0] nes_joy_B = { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
clk clock_21mhz(.inclk0(CLOCK_27[0]), .c0(clk85), .c1(SDRAM_CLK), .locked(clock_locked));
|
||||
|
||||
// initial reset after pll startup
|
||||
// reg [7:0] init_reset_cnt;
|
||||
// wire init_reset = init_reset_cnt != 0;
|
||||
// always @(posedge CLOCK_27[0]) begin
|
||||
// if(!clock_locked)
|
||||
// init_reset_cnt <= 8'd255;
|
||||
// else if(init_reset_cnt != 0)
|
||||
// init_reset_cnt <= init_reset_cnt - 8'd1;
|
||||
// end
|
||||
reg [7:0] download_reset_cnt;
|
||||
wire download_reset = download_reset_cnt != 0;
|
||||
always @(posedge CLOCK_27[0]) begin
|
||||
if(downloading)
|
||||
download_reset_cnt <= 8'd255;
|
||||
else if(download_reset_cnt != 0)
|
||||
download_reset_cnt <= download_reset_cnt - 8'd1;
|
||||
end
|
||||
|
||||
// hold machine in reset until first download starts
|
||||
reg init_reset;
|
||||
@@ -246,12 +246,6 @@ wire [7:0] nes_joy_B = { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
wire clk = clkcnt[1];
|
||||
wire ps2_clk = clkcnt[12];
|
||||
|
||||
|
||||
// Loader
|
||||
wire [7:0] loader_input;
|
||||
wire loader_clk;
|
||||
reg [7:0] loader_btn, loader_btn_2;
|
||||
|
||||
wire [8:0] cycle;
|
||||
wire [8:0] scanline;
|
||||
wire [15:0] sample;
|
||||
@@ -270,21 +264,31 @@ wire [7:0] nes_joy_B = { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
|
||||
reg [1:0] nes_ce;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (joypad_strobe) begin
|
||||
joypad_bits <= nes_joy_A;
|
||||
joypad_bits2 <= nes_joy_B;
|
||||
end
|
||||
if (!joypad_clock[0] && last_joypad_clock[0])
|
||||
joypad_bits <= {1'b0, joypad_bits[7:1]};
|
||||
if (!joypad_clock[1] && last_joypad_clock[1])
|
||||
joypad_bits2 <= {1'b0, joypad_bits2[7:1]};
|
||||
last_joypad_clock <= joypad_clock;
|
||||
always @(posedge clk) begin
|
||||
if (reset_nes) begin
|
||||
joypad_bits <= 8'd0;
|
||||
joypad_bits2 <= 8'd0;
|
||||
last_joypad_clock <= 2'b00;
|
||||
end else begin
|
||||
if (joypad_strobe) begin
|
||||
joypad_bits <= nes_joy_A;
|
||||
joypad_bits2 <= nes_joy_B;
|
||||
end
|
||||
if (!joypad_clock[0] && last_joypad_clock[0])
|
||||
joypad_bits <= {1'b0, joypad_bits[7:1]};
|
||||
if (!joypad_clock[1] && last_joypad_clock[1])
|
||||
joypad_bits2 <= {1'b0, joypad_bits2[7:1]};
|
||||
last_joypad_clock <= joypad_clock;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Loader
|
||||
wire [7:0] loader_input;
|
||||
wire loader_clk;
|
||||
wire [21:0] loader_addr;
|
||||
wire [7:0] loader_write_data;
|
||||
wire loader_reset = !downloading; //loader_conf[0];
|
||||
wire loader_reset = !download_reset; //loader_conf[0];
|
||||
wire loader_write;
|
||||
wire [31:0] mapper_flags;
|
||||
wire loader_done, loader_fail;
|
||||
@@ -292,9 +296,7 @@ wire [7:0] nes_joy_B = { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
loader_addr, loader_write_data, loader_write,
|
||||
mapper_flags, loader_done, loader_fail);
|
||||
|
||||
//TH wire reset_nes = (buttons[1] || !loader_done);
|
||||
wire reset_nes = (init_reset || buttons[1] || arm_reset || reset_osd || downloading);
|
||||
wire run_mem = (nes_ce == 0) && !reset_nes;
|
||||
wire reset_nes = (init_reset || buttons[1] || arm_reset || reset_osd || download_reset);
|
||||
wire run_nes = (nes_ce == 3) && !reset_nes;
|
||||
|
||||
// NES is clocked at every 4th cycle.
|
||||
|
||||
@@ -38,8 +38,10 @@ assign joystick_1 = joy_num ? buttons : 7'b0;
|
||||
always @(posedge reset or posedge clk) begin
|
||||
|
||||
if(reset) begin
|
||||
pressed <= 1'b1;
|
||||
pressed <= 1'b0;
|
||||
e0 <= 1'b0;
|
||||
joy_num <= 1'b0;
|
||||
buttons <= 8'd0;
|
||||
end else begin
|
||||
if (keyb_valid) begin
|
||||
if (keyb_data == 8'HE0)
|
||||
|
||||
@@ -48,7 +48,7 @@ module sdram (
|
||||
);
|
||||
|
||||
// no burst configured
|
||||
localparam RASCAS_DELAY = 3'd3; // tRCD=20ns -> 3 cycles@128MHz
|
||||
localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@85MHz
|
||||
localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
|
||||
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
|
||||
localparam CAS_LATENCY = 3'd3; // 2/3 allowed
|
||||
@@ -70,7 +70,7 @@ localparam STATE_LAST = 4'd15; // last state in cycle
|
||||
|
||||
reg [3:0] q;
|
||||
always @(posedge clk) begin
|
||||
// SDRAM (state machine) clock is 86MHz. Synchronize this to systems 21.477 Mhz clock
|
||||
// SDRAM (state machine) clock is 85MHz. Synchronize this to systems 21.477 Mhz clock
|
||||
// force counter to pass state LAST->FIRST exactly after the rising edge of clkref
|
||||
if(((q == STATE_LAST) && ( clkref == 1)) ||
|
||||
((q == STATE_FIRST) && ( clkref == 0)) ||
|
||||
@@ -82,13 +82,13 @@ end
|
||||
// --------------------------- startup/reset ---------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// wait 1ms (32 8Mhz cycles) after FPGA config is done before going
|
||||
// wait 1ms (85000 cycles) after FPGA config is done before going
|
||||
// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
|
||||
reg [4:0] reset;
|
||||
reg [16:0] reset;
|
||||
always @(posedge clk) begin
|
||||
if(init) reset <= 5'h1f;
|
||||
if(init) reset <= 17'h14c08;
|
||||
else if((q == STATE_LAST) && (reset != 0))
|
||||
reset <= reset - 5'd1;
|
||||
reset <= reset - 17'd1;
|
||||
end
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
@@ -59,16 +59,26 @@ module MMC1(input clk, input ce, input reset,
|
||||
// |++++- Select 16 KB PRG ROM bank (low bit ignored in 32 KB mode)
|
||||
// +----- PRG RAM chip enable (0: enabled; 1: disabled; ignored on MMC1A)
|
||||
reg [4:0] prg_bank;
|
||||
|
||||
reg delay_ctrl; // used to delay fast-write to the control register
|
||||
wire [3:0] last_prg_index = 4'b1111;
|
||||
|
||||
// Update shift register
|
||||
always @(posedge clk) if (reset) begin
|
||||
shift <= 1;
|
||||
control <= 'hC;
|
||||
shift <= 1;
|
||||
control <= 5'b0_11_00;
|
||||
chr_bank_0 <= 0;
|
||||
chr_bank_1 <= 0;
|
||||
prg_bank <= last_prg_index;
|
||||
delay_ctrl <= 0;
|
||||
end else if (ce) begin
|
||||
if (prg_write && prg_ain[15]) begin
|
||||
if (delay_ctrl)
|
||||
delay_ctrl <= delay_ctrl - 1'b1;
|
||||
if (prg_write && prg_ain[15] && !delay_ctrl) begin
|
||||
if (prg_din[7]) begin
|
||||
shift <= 5'b10000;
|
||||
control <= control | 'hC;
|
||||
control <= control | 5'b0_11_00;
|
||||
delay_ctrl <= 1'b1;
|
||||
// $write("MMC1 RESET!\n");
|
||||
end else begin
|
||||
if (shift[0]) begin
|
||||
@@ -88,14 +98,15 @@ module MMC1(input clk, input ce, input reset,
|
||||
end
|
||||
|
||||
// The PRG bank to load. Each increment here is 16kb. So valid values are 0..15.
|
||||
reg [3:0] prgsel;
|
||||
// prg_ain[14] selects bank0 ($8000) or bank1 ($C000)
|
||||
reg [3:0] prgsel;
|
||||
always @* begin
|
||||
casez({control[3:2], prg_ain[14]})
|
||||
3'b0?_?: prgsel = {prg_bank[3:1], prg_ain[14]};
|
||||
3'b10_0: prgsel = 4'b0000;
|
||||
3'b10_1: prgsel = prg_bank[3:0];
|
||||
3'b11_0: prgsel = prg_bank[3:0];
|
||||
3'b11_1: prgsel = 4'b1111;
|
||||
3'b0?_?: prgsel = {prg_bank[3:1], prg_ain[14]}; // Swap 32Kb
|
||||
3'b10_0: prgsel = 4'b0000; // Swap 16Kb at $C000 with access at $8000, so select page 0 (hardcoded)
|
||||
3'b10_1: prgsel = prg_bank[3:0]; // Swap 16Kb at $C000 with $C000 access, so select page based on prg_bank (register 3)
|
||||
3'b11_0: prgsel = prg_bank[3:0]; // Swap 16Kb at $8000 with $8000 access, so select page based on prg_bank (register 3)
|
||||
3'b11_1: prgsel = last_prg_index; // Swap 16Kb at $8000 with $C000 access, so select last page (hardcoded)
|
||||
endcase
|
||||
end
|
||||
wire [21:0] prg_aout_tmp = {4'b00_00, prgsel, prg_ain[13:0]};
|
||||
@@ -104,7 +115,7 @@ module MMC1(input clk, input ce, input reset,
|
||||
reg [4:0] chrsel;
|
||||
always @* begin
|
||||
casez({control[4], chr_ain[12]})
|
||||
2'b0_?: chrsel = {chr_bank_0[4:1], chr_ain[12]};
|
||||
2'b0_?: chrsel = {1'b0, chr_bank_0[3:1], chr_ain[12]};
|
||||
2'b1_0: chrsel = chr_bank_0;
|
||||
2'b1_1: chrsel = chr_bank_1;
|
||||
endcase
|
||||
@@ -197,7 +208,7 @@ module MMC2(input clk, input ce, input reset,
|
||||
reg mirroring;
|
||||
|
||||
reg latch_0, latch_1;
|
||||
|
||||
|
||||
// Update registers
|
||||
always @(posedge clk) if (ce) begin
|
||||
if (prg_write && prg_ain[15]) begin
|
||||
@@ -297,7 +308,7 @@ module MMC3(input clk, input ce, input reset,
|
||||
bank_select <= 0;
|
||||
prg_rom_bank_mode <= 0;
|
||||
chr_a12_invert <= 0;
|
||||
mirroring <= 0;
|
||||
mirroring <= ~flags[14]; // for mapper 206, otherwise it's mapper controlled
|
||||
{irq_enable, irq_reload} <= 0;
|
||||
{irq_latch, counter} <= 0;
|
||||
{ram_enable, ram_protect} <= 0;
|
||||
@@ -1096,8 +1107,16 @@ module Mapper28(input clk, input ce, input reset,
|
||||
|
||||
// Allow writes to 0x5000 only when launching through the proper mapper ID.
|
||||
wire [7:0] mapper = flags[7:0];
|
||||
wire allow_select = (mapper == 8'd28);
|
||||
|
||||
wire allow_select = (mapper == 8'd28);
|
||||
|
||||
wire [7:0] prg_size = flags[13:11] == 0 ? 1 :
|
||||
flags[13:11] == 1 ? 2 :
|
||||
flags[13:11] == 2 ? 4 :
|
||||
flags[13:11] == 3 ? 8 :
|
||||
flags[13:11] == 4 ? 16 :
|
||||
flags[13:11] == 5 ? 32 :
|
||||
flags[13:11] == 6 ? 64 : 128;
|
||||
|
||||
always @(posedge clk) if (reset) begin
|
||||
mode[5:2] <= 0; // NROM mode, 32K mode
|
||||
outer[5:0] <= 6'h3f; // last bank
|
||||
@@ -1109,9 +1128,11 @@ module Mapper28(input clk, input ce, input reset,
|
||||
mode[1:0] <= flags[14] ? 2'b10 : 2'b11;
|
||||
|
||||
// UNROM #2 - Current bank in $8000-$BFFF and fixed top half of outer bank in $C000-$FFFF
|
||||
if (mapper == 2)
|
||||
mode[5:2] <= 4'b1111;
|
||||
|
||||
if (mapper == 2) begin
|
||||
mode[5:4] <= (prg_size == 16)? 2'b11 : 2'b10; // Select 128 or 256Kb PRG ROM
|
||||
mode[3:2] <= 2'b11;
|
||||
end
|
||||
|
||||
// CNROM #3 - Fixed PRG bank, switchable CHR bank.
|
||||
if (mapper == 3)
|
||||
selreg <= 0;
|
||||
|
||||
@@ -93,7 +93,7 @@ endmodule
|
||||
// Data read by PPU will be available on the next clock cycle.
|
||||
// Data read by CPU will be available within at most 2 clock cycles.
|
||||
|
||||
module MemoryMultiplex(input clk, input ce,
|
||||
module MemoryMultiplex(input clk, input ce, input reset,
|
||||
input [21:0] prg_addr, input prg_read, input prg_write, input [7:0] prg_din,
|
||||
input [21:0] chr_addr, input chr_read, input chr_write, input [7:0] chr_din,
|
||||
// Access signals for the SRAM.
|
||||
@@ -108,7 +108,10 @@ module MemoryMultiplex(input clk, input ce,
|
||||
assign memory_read_ppu = chr_read;
|
||||
assign memory_read_cpu = !(chr_read || chr_write) && (prg_read || saved_prg_read);
|
||||
assign memory_dout = chr_write ? chr_din : prg_din;
|
||||
always @(posedge clk) if (ce) begin
|
||||
always @(posedge clk) if (reset) begin
|
||||
saved_prg_read <= 0;
|
||||
saved_prg_write <= 0;
|
||||
end else if (ce) begin
|
||||
if (chr_read || chr_write) begin
|
||||
saved_prg_read <= prg_read || saved_prg_read;
|
||||
saved_prg_write <= prg_write || saved_prg_write;
|
||||
@@ -280,12 +283,14 @@ module NES(input clk, input reset, input ce,
|
||||
end
|
||||
|
||||
// -- Multiplexes CPU and PPU accesses into one single RAM
|
||||
MemoryMultiplex mem(clk, ce, prg_linaddr, prg_read && prg_allow, prg_write && prg_allow, prg_din,
|
||||
MemoryMultiplex mem(clk, ce, reset, prg_linaddr, prg_read && prg_allow, prg_write && prg_allow, prg_din,
|
||||
chr_linaddr, chr_read, chr_write && (chr_allow || vram_ce), chr_from_ppu,
|
||||
memory_addr, memory_read_cpu, memory_read_ppu, memory_write, memory_dout);
|
||||
|
||||
always @* begin
|
||||
if (apu_cs) begin
|
||||
if (reset)
|
||||
from_data_bus <= 0;
|
||||
else if (apu_cs) begin
|
||||
if (joypad1_cs)
|
||||
from_data_bus = {7'b0100000, joypad_data[0]};
|
||||
else if (joypad2_cs)
|
||||
|
||||
@@ -76,9 +76,10 @@ always @(posedge clkv) begin
|
||||
end
|
||||
|
||||
wire [14:0] pixel_v = (!hpicture || !vpicture) ? 15'd0 : mode ? pixel : doubler_pixel;
|
||||
wire [4:0] vga_r = mode ? pixel_v[4:0] : (v[0] & scanlines) ? {1'b0, pixel_v[4:1]} : pixel_v[4:0];
|
||||
wire [4:0] vga_g = mode ? pixel_v[9:5] : (v[0] & scanlines) ? {1'b0, pixel_v[9:6]} : pixel_v[9:5];
|
||||
wire [4:0] vga_b = mode ? pixel_v[14:10] : (v[0] & scanlines) ? {1'b0, pixel_v[14:11]} : pixel_v[14:10];
|
||||
wire darker = !mode && v[0] && scanlines;
|
||||
wire [4:0] vga_r = darker ? {1'b0, pixel_v[4:1]} : pixel_v[4:0];
|
||||
wire [4:0] vga_g = darker ? {1'b0, pixel_v[9:6]} : pixel_v[9:5];
|
||||
wire [4:0] vga_b = darker ? {1'b0, pixel_v[14:11]} : pixel_v[14:10];
|
||||
wire sync_h = ((h >= (512 + 23 + (mode ? 18 : 35))) && (h < (512 + 23 + (mode ? 18 : 35) + 82)));
|
||||
wire sync_v = ((v >= (mode ? 240 + 5 : 480 + 10)) && (v < (mode ? 240 + 14 : 480 + 12)));
|
||||
assign VGA_HS = mode ? ~(sync_h ^ sync_v) : ~sync_h;
|
||||
|
||||
Reference in New Issue
Block a user