mirror of
https://github.com/mist-devel/mist-board.git
synced 2026-01-27 04:11:51 +00:00
[NES] Add NTSC RGBS mode.
This commit is contained in:
@@ -132,14 +132,15 @@ wire [1:0] switches;
|
||||
// it to control the menu on the OSD
|
||||
parameter CONF_STR = {
|
||||
"NES;NES;",
|
||||
"O1,HQ2X,OFF,ON;",
|
||||
"O1,HQ2X(VGA-Only),OFF,ON;",
|
||||
"T2,Start;",
|
||||
"T3,Select;",
|
||||
"T4,Reset;"
|
||||
};
|
||||
|
||||
parameter CONF_STR_LEN = 8+15+9+10+9;
|
||||
parameter CONF_STR_LEN = 8+25+9+10+9;
|
||||
wire [7:0] status;
|
||||
wire scandoubler_disable;
|
||||
|
||||
user_io #(.STRLEN(CONF_STR_LEN)) user_io(
|
||||
.conf_str ( CONF_STR ),
|
||||
@@ -152,6 +153,7 @@ user_io #(.STRLEN(CONF_STR_LEN)) user_io(
|
||||
|
||||
.SWITCHES (switches ),
|
||||
.BUTTONS (buttons ),
|
||||
.scandoubler_disable(scandoubler_disable),
|
||||
|
||||
.JOY0 (joyA ),
|
||||
.JOY1 (joyB ),
|
||||
@@ -163,12 +165,6 @@ user_io #(.STRLEN(CONF_STR_LEN)) user_io(
|
||||
.ps2_clk ( )
|
||||
);
|
||||
|
||||
wire [4:0] nes_r;
|
||||
wire [4:0] nes_g;
|
||||
wire [4:0] nes_b;
|
||||
wire nes_hs;
|
||||
wire nes_vs;
|
||||
|
||||
// if "Start" or "Select" are selected from the menu keep them set for half a second
|
||||
// status 2 and 3 are start and select from the OSD
|
||||
reg [23:0] select_cnt;
|
||||
@@ -193,29 +189,7 @@ wire [7:0] nes_joy_A = { joyB[0], joyB[1], joyB[2], joyB[3],
|
||||
joyB[7] | strt, joyB[6] | sel, joyB[5], joyB[4] };
|
||||
wire [7:0] nes_joy_B = { joyA[0], joyA[1], joyA[2], joyA[3],
|
||||
joyA[7], joyA[6], joyA[5], joyA[4] };
|
||||
|
||||
osd #(0,0,4) osd (
|
||||
.pclk ( clk ),
|
||||
|
||||
// spi for OSD
|
||||
.sdi ( SPI_DI ),
|
||||
.sck ( SPI_SCK ),
|
||||
.ss ( SPI_SS3 ),
|
||||
|
||||
.red_in ( { nes_r, 1'b0} ),
|
||||
.green_in ( { nes_g, 1'b0} ),
|
||||
.blue_in ( { nes_b, 1'b0} ),
|
||||
.hs_in ( nes_hs ),
|
||||
.vs_in ( nes_vs ),
|
||||
|
||||
.red_out ( VGA_R ),
|
||||
.green_out ( VGA_G ),
|
||||
.blue_out ( VGA_B ),
|
||||
.hs_out ( VGA_HS ),
|
||||
.vs_out ( VGA_VS )
|
||||
);
|
||||
|
||||
|
||||
wire clock_locked;
|
||||
wire clk85;
|
||||
clk clock_21mhz(.inclk0(CLOCK_27[0]), .c0(clk85), .c1(SDRAM_CLK), .locked(clock_locked));
|
||||
@@ -250,10 +224,6 @@ osd #(0,0,4) osd (
|
||||
wire loader_clk;
|
||||
reg [7:0] loader_btn, loader_btn_2;
|
||||
|
||||
// NES Palette -> RGB332 conversion
|
||||
reg [14:0] pallut[0:63];
|
||||
initial $readmemh("../src/nes_palette.txt", pallut);
|
||||
|
||||
wire [8:0] cycle;
|
||||
wire [8:0] scanline;
|
||||
wire [15:0] sample;
|
||||
@@ -385,20 +355,30 @@ data_io data_io (
|
||||
.d ( loader_input )
|
||||
);
|
||||
|
||||
wire [14:0] doubler_pixel;
|
||||
wire doubler_sync;
|
||||
wire [9:0] vga_hcounter, doubler_x;
|
||||
wire [9:0] vga_vcounter;
|
||||
|
||||
VgaDriver vga(clk, nes_hs, nes_vs, nes_r, nes_g, nes_b, vga_hcounter, vga_vcounter, doubler_x, doubler_pixel, doubler_sync, 1'b0);
|
||||
|
||||
wire [14:0] pixel_in = pallut[color];
|
||||
Hq2x hq2x(clk, pixel_in, !status[1], // enabled
|
||||
scanline[8], // reset_frame
|
||||
(cycle[8:3] == 42), // reset_line
|
||||
doubler_x, // 0-511 for line 1, or 512-1023 for line 2.
|
||||
doubler_sync, // new frame has just started
|
||||
doubler_pixel); // pixel is outputted
|
||||
wire nes_hs;
|
||||
wire nes_vs;
|
||||
|
||||
VgaDriver vga(
|
||||
.clk(clk),
|
||||
.sdi(SPI_DI),
|
||||
.sck(SPI_SCK),
|
||||
.ss(SPI_SS3),
|
||||
.color(color),
|
||||
.sync_frame(scanline[8]),
|
||||
.sync_line((cycle[8:3] == 42)),
|
||||
.mode(scandoubler_disable),
|
||||
.vga_smooth(!status[1]),
|
||||
.border(1'b0),
|
||||
|
||||
.vga_h(nes_hs),
|
||||
.vga_v(nes_vs),
|
||||
.VGA_R(VGA_R),
|
||||
.VGA_G(VGA_G),
|
||||
.VGA_B(VGA_B)
|
||||
);
|
||||
|
||||
assign VGA_HS = scandoubler_disable ? ~(nes_hs ^ nes_vs) : nes_hs;
|
||||
assign VGA_VS = scandoubler_disable ? 1'b1 : nes_vs;
|
||||
|
||||
assign AUDIO_R = audio;
|
||||
assign AUDIO_L = audio;
|
||||
|
||||
@@ -34,6 +34,7 @@ module user_io #(parameter STRLEN=0) (
|
||||
output [7:0] JOY1,
|
||||
output [1:0] BUTTONS,
|
||||
output [1:0] SWITCHES,
|
||||
output scandoubler_disable,
|
||||
|
||||
output reg [7:0] status,
|
||||
|
||||
@@ -48,12 +49,13 @@ reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||||
reg [7:0] byte_cnt; // counts bytes
|
||||
reg [7:0] joystick0;
|
||||
reg [7:0] joystick1;
|
||||
reg [3:0] but_sw;
|
||||
reg [4:0] but_sw;
|
||||
|
||||
assign JOY0 = joystick0;
|
||||
assign JOY1 = joystick1;
|
||||
assign BUTTONS = but_sw[1:0];
|
||||
assign SWITCHES = but_sw[3:2];
|
||||
assign scandoubler_disable = but_sw[4];
|
||||
|
||||
// this variant of user_io is for 8 bit cores (type == a4) only
|
||||
wire [7:0] core_type = 8'ha4;
|
||||
@@ -164,7 +166,7 @@ always@(posedge SPI_CLK or posedge SPI_SS_IO) begin
|
||||
|
||||
if(byte_cnt != 0) begin
|
||||
if(cmd == 8'h01)
|
||||
but_sw <= { sbuf[2:0], SPI_MOSI };
|
||||
but_sw <= { sbuf[3:0], SPI_MOSI };
|
||||
|
||||
if(cmd == 8'h02)
|
||||
joystick0 <= { sbuf, SPI_MOSI };
|
||||
|
||||
@@ -1,47 +1,96 @@
|
||||
// Copyright (c) 2012-2013 Ludvig Strigeus
|
||||
// This program is GPL Licensed. See COPYING for the full license.
|
||||
|
||||
module VgaDriver(input clk,
|
||||
output reg vga_h, output reg vga_v,
|
||||
output reg [4:0] vga_r, output reg[4:0] vga_g, output reg[4:0] vga_b,
|
||||
output [9:0] vga_hcounter,
|
||||
output [9:0] vga_vcounter,
|
||||
output [9:0] next_pixel_x, // The pixel we need NEXT cycle.
|
||||
input [14:0] pixel, // Pixel for current cycle.
|
||||
input sync,
|
||||
input border);
|
||||
module VgaDriver(
|
||||
input clk,
|
||||
input [5:0] color, // Pixel for current cycle.
|
||||
input sync_frame,
|
||||
input sync_line,
|
||||
input mode,
|
||||
input vga_smooth,
|
||||
input border,
|
||||
|
||||
input sck,
|
||||
input ss,
|
||||
input sdi,
|
||||
|
||||
output reg vga_h,
|
||||
output reg vga_v,
|
||||
output [5:0] VGA_R,
|
||||
output [5:0] VGA_G,
|
||||
output [5:0] VGA_B
|
||||
);
|
||||
|
||||
// NES Palette -> RGB555 conversion
|
||||
reg [15:0] pallut[0:63];
|
||||
initial $readmemh("nes_palette.txt", pallut);
|
||||
wire [14:0] pixel = pallut[color][14:0];
|
||||
|
||||
// Horizontal and vertical counters
|
||||
reg [9:0] h, v;
|
||||
wire hpicture = (h < 512); // 512 lines of picture
|
||||
wire hsync_on = (h == 512 + 23 + 35); // HSync ON, 23+35 pixels front porch
|
||||
wire hsync_off = (h == 512 + 23 + 35 + 82); // Hsync off, 82 pixels sync
|
||||
wire hpicture = (h < 512); // 512 lines of picture
|
||||
wire hsync_on = (h == 512 + 23 + (mode ? 18 : 35)); // HSync ON, 23+35 pixels front porch
|
||||
wire hsync_off = (h == 512 + 23 + (mode ? 18 : 35) + 82); // Hsync off, 82 pixels sync
|
||||
wire hend = (h == 681); // End of line, 682 pixels.
|
||||
|
||||
wire vpicture = (v < 480); // 480 lines of picture
|
||||
wire vsync_on = hsync_on && (v == 480 + 10); // Vsync ON, 10 lines front porch.
|
||||
wire vsync_off = hsync_on && (v == 480 + 12); // Vsync OFF, 2 lines sync signal
|
||||
wire vend = (v == 523); // End of picture, 524 lines. (Should really be 525 according to NTSC spec)
|
||||
wire vpicture = (v < (480 >> mode)); // 480 lines of picture
|
||||
wire vsync_on = hsync_on && (v == (mode ? 240 + 5 : 480 + 10)); // Vsync ON, 10 lines front porch.
|
||||
wire vsync_off = hsync_on && (v == (mode ? 240 + 14 : 480 + 12)); // Vsync OFF, 2 lines sync signal
|
||||
wire vend = (v == (523 >> mode)); // End of picture, 524 lines. (Should really be 525 according to NTSC spec)
|
||||
wire inpicture = hpicture && vpicture;
|
||||
assign vga_hcounter = h;
|
||||
assign vga_vcounter = v;
|
||||
wire [9:0] new_h = (hend || sync) ? 0 : h + 1;
|
||||
assign next_pixel_x = {sync ? 1'b0 : hend ? !v[0] : v[0], new_h[8:0]};
|
||||
wire [9:0] new_h = (hend || (mode ? sync_frame : doubler_sync)) ? 10'd0 : h + 10'd1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
wire [14:0] doubler_pixel;
|
||||
wire doubler_sync;
|
||||
|
||||
Hq2x hq2x(clk, pixel, vga_smooth, // enabled
|
||||
sync_frame, // reset_frame
|
||||
sync_line, // reset_line
|
||||
{doubler_sync ? 1'b0 : hend ? !v[0] : v[0], new_h[8:0]}, // 0-511 for line 1, or 512-1023 for line 2.
|
||||
doubler_sync, // new frame has just started
|
||||
doubler_pixel); // pixel is outputted
|
||||
|
||||
reg clk2 = 1'b0;
|
||||
always @(posedge clk) clk2 <= ~clk2;
|
||||
wire clkv = mode ? clk2 : clk;
|
||||
|
||||
osd #(10'd0,10'd0,3'd4) osd (
|
||||
.pclk(clkv),
|
||||
|
||||
.sck(sck),
|
||||
.sdi(sdi),
|
||||
.ss(ss),
|
||||
|
||||
.red_in ({vga_r, 1'b0}),
|
||||
.green_in({vga_g, 1'b0}),
|
||||
.blue_in ({vga_b, 1'b0}),
|
||||
.hs_in(vga_h),
|
||||
.vs_in(vga_v),
|
||||
|
||||
.red_out(VGA_R),
|
||||
.green_out(VGA_G),
|
||||
.blue_out(VGA_B)
|
||||
);
|
||||
|
||||
reg [4:0] vga_r;
|
||||
reg [4:0] vga_g;
|
||||
reg [4:0] vga_b;
|
||||
|
||||
always @(posedge clkv) begin
|
||||
h <= new_h;
|
||||
if (sync) begin
|
||||
if(mode ? sync_frame : doubler_sync) begin
|
||||
vga_v <= 1;
|
||||
vga_h <= 1;
|
||||
v <= 0;
|
||||
end else begin
|
||||
vga_h <= hsync_on ? 0 : hsync_off ? 1 : vga_h;
|
||||
vga_h <= hsync_on ? 1'b0 : hsync_off ? 1'b1 : vga_h;
|
||||
if (hend)
|
||||
v <= vend ? 0 : v + 1;
|
||||
vga_v <= vsync_on ? 0 : vsync_off ? 1 : vga_v;
|
||||
vga_r <= pixel[4:0];
|
||||
vga_g <= pixel[9:5];
|
||||
vga_b <= pixel[14:10];
|
||||
if (border && (h == 0 || h == 511 || v == 0 || v == 479)) begin
|
||||
v <= vend ? 10'd0 : v + 10'd1;
|
||||
vga_v <= vsync_on ? 1'b0 : vsync_off ? 1'b1 : vga_v;
|
||||
vga_r <= mode ? pixel[4:0] : doubler_pixel[4:0];
|
||||
vga_g <= mode ? pixel[9:5] : doubler_pixel[9:5];
|
||||
vga_b <= mode ? pixel[14:10] : doubler_pixel[14:10];
|
||||
if (border && (h == 0 || h == 511 || v == 0 || v == (479 >> mode))) begin
|
||||
vga_r <= 4'b1111;
|
||||
vga_g <= 4'b1111;
|
||||
vga_b <= 4'b1111;
|
||||
|
||||
Reference in New Issue
Block a user