mirror of
https://github.com/MiSTer-devel/MacPlus_MiSTer.git
synced 2025-02-25 08:29:07 +00:00
168 lines
3.6 KiB
Systemverilog
168 lines
3.6 KiB
Systemverilog
//
|
|
//
|
|
// Copyright (c) 2017 Sorgelig
|
|
//
|
|
// This program is GPL Licensed. See COPYING for the full license.
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`timescale 1ns / 1ps
|
|
|
|
//
|
|
// LINE_LENGTH: Length of display line in pixels
|
|
// Usually it's length from HSync to HSync.
|
|
// May be less if line_start is used.
|
|
//
|
|
// HALF_DEPTH: If =1 then color dept is 4 bits per component
|
|
// For half depth 8 bits monochrome is available with
|
|
// mono signal enabled and color = {G, R}
|
|
|
|
module video_mixer
|
|
#(
|
|
parameter LINE_LENGTH = 768,
|
|
parameter HALF_DEPTH = 0
|
|
)
|
|
(
|
|
// master clock
|
|
// it should be multiple by (ce_pix*4).
|
|
input clk_sys,
|
|
|
|
// Pixel clock or clock_enable (both are accepted).
|
|
input ce_pix,
|
|
output ce_pix_out,
|
|
|
|
input scandoubler,
|
|
|
|
// scanlines (00-none 01-25% 10-50% 11-75%)
|
|
input [1:0] scanlines,
|
|
|
|
// High quality 2x scaling
|
|
input hq2x,
|
|
|
|
// color
|
|
input [DWIDTH:0] R,
|
|
input [DWIDTH:0] G,
|
|
input [DWIDTH:0] B,
|
|
|
|
// Monochrome mode (for HALF_DEPTH only)
|
|
input mono,
|
|
|
|
// Positive pulses.
|
|
input HSync,
|
|
input VSync,
|
|
input HBlank,
|
|
input VBlank,
|
|
|
|
// video output signals
|
|
output reg [7:0] VGA_R,
|
|
output reg [7:0] VGA_G,
|
|
output reg [7:0] VGA_B,
|
|
output reg VGA_VS,
|
|
output reg VGA_HS,
|
|
output reg VGA_DE
|
|
);
|
|
|
|
localparam DWIDTH = HALF_DEPTH ? 3 : 7;
|
|
|
|
wire [DWIDTH:0] R_sd;
|
|
wire [DWIDTH:0] G_sd;
|
|
wire [DWIDTH:0] B_sd;
|
|
wire hs_sd, vs_sd, hb_sd, vb_sd, ce_pix_sd;
|
|
|
|
scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) sd
|
|
(
|
|
.*,
|
|
.hs_in(HSync),
|
|
.vs_in(VSync),
|
|
.hb_in(HBlank),
|
|
.vb_in(VBlank),
|
|
.r_in(R),
|
|
.g_in(G),
|
|
.b_in(B),
|
|
|
|
.ce_pix_out(ce_pix_sd),
|
|
.hs_out(hs_sd),
|
|
.vs_out(vs_sd),
|
|
.hb_out(hb_sd),
|
|
.vb_out(vb_sd),
|
|
.r_out(R_sd),
|
|
.g_out(G_sd),
|
|
.b_out(B_sd)
|
|
);
|
|
|
|
wire [DWIDTH:0] rt = (scandoubler ? R_sd : R);
|
|
wire [DWIDTH:0] gt = (scandoubler ? G_sd : G);
|
|
wire [DWIDTH:0] bt = (scandoubler ? B_sd : B);
|
|
|
|
generate
|
|
if(HALF_DEPTH) begin
|
|
wire [7:0] r = mono ? {gt,rt} : {rt,rt};
|
|
wire [7:0] g = mono ? {gt,rt} : {gt,gt};
|
|
wire [7:0] b = mono ? {gt,rt} : {bt,bt};
|
|
end else begin
|
|
wire [7:0] r = rt;
|
|
wire [7:0] g = gt;
|
|
wire [7:0] b = bt;
|
|
end
|
|
endgenerate
|
|
|
|
wire hs = (scandoubler ? hs_sd : HSync);
|
|
wire vs = (scandoubler ? vs_sd : VSync);
|
|
|
|
assign ce_pix_out = scandoubler ? ce_pix_sd : ce_pix;
|
|
|
|
|
|
reg scanline = 0;
|
|
always @(posedge clk_sys) begin
|
|
reg old_hs, old_vs;
|
|
|
|
old_hs <= hs;
|
|
old_vs <= vs;
|
|
|
|
if(old_hs && ~hs) scanline <= ~scanline;
|
|
if(old_vs && ~vs) scanline <= 0;
|
|
end
|
|
|
|
wire hde = scandoubler ? ~hb_sd : ~HBlank;
|
|
wire vde = scandoubler ? ~vb_sd : ~VBlank;
|
|
|
|
always @(posedge clk_sys) begin
|
|
reg old_hde;
|
|
|
|
case(scanlines & {scanline, scanline})
|
|
1: begin // reduce 25% = 1/2 + 1/4
|
|
VGA_R <= {1'b0, r[7:1]} + {2'b00, r[7:2]};
|
|
VGA_G <= {1'b0, g[7:1]} + {2'b00, g[7:2]};
|
|
VGA_B <= {1'b0, b[7:1]} + {2'b00, b[7:2]};
|
|
end
|
|
|
|
2: begin // reduce 50% = 1/2
|
|
VGA_R <= {1'b0, r[7:1]};
|
|
VGA_G <= {1'b0, g[7:1]};
|
|
VGA_B <= {1'b0, b[7:1]};
|
|
end
|
|
|
|
3: begin // reduce 75% = 1/4
|
|
VGA_R <= {2'b00, r[7:2]};
|
|
VGA_G <= {2'b00, g[7:2]};
|
|
VGA_B <= {2'b00, b[7:2]};
|
|
end
|
|
|
|
default: begin
|
|
VGA_R <= r;
|
|
VGA_G <= g;
|
|
VGA_B <= b;
|
|
end
|
|
endcase
|
|
|
|
VGA_VS <= vs;
|
|
VGA_HS <= hs;
|
|
|
|
old_hde <= hde;
|
|
if(~old_hde && hde) VGA_DE <= vde;
|
|
if(old_hde && ~hde) VGA_DE <= 0;
|
|
end
|
|
|
|
endmodule
|