mirror of
https://github.com/MiSTer-devel/MacPlus_MiSTer.git
synced 2025-02-17 01:31:02 +00:00
82 lines
2.4 KiB
Verilog
82 lines
2.4 KiB
Verilog
// generates 1024x768 (actually 512x768) @ 60Hz, from a 32.5MHz input clock
|
|
module videoTimer(
|
|
input clk,
|
|
input clk_en,
|
|
input [1:0] busCycle,
|
|
input vid_alt,
|
|
output [21:0] videoAddr,
|
|
output reg hsync,
|
|
output reg vsync,
|
|
output _hblank,
|
|
output _vblank,
|
|
output loadPixels
|
|
);
|
|
|
|
// timing data from http://tinyvga.com/vga-timing/1024x768@60Hz
|
|
localparam kVisibleWidth = 128, // (1024/2)/4
|
|
kTotalWidth = 168, // (1344/2)/4
|
|
kVisibleHeightStart = 42,
|
|
kVisibleHeightEnd = 725,
|
|
kTotalHeight = 806,
|
|
kHsyncStart = 131, // (1048/2)/4
|
|
kHsyncEnd = 147, // (1184/2)/4-1
|
|
kVsyncStart = 771,
|
|
kVsyncEnd = 776,
|
|
kPixelLatency = 1; // number of clk8 cycles from xpos==0 to when pixel data actually exits the video shift register
|
|
|
|
// use screen buffer address for a 4MB RAM layout-- it will wrap
|
|
// around to the proper address for 1MB, 512K, and 128K layouts
|
|
localparam kScreenBufferBase = 22'h3FA700;
|
|
localparam startAddr = kVisibleHeightStart/2 * kVisibleWidth/2;
|
|
|
|
reg [7:0] xpos;
|
|
reg [9:0] ypos;
|
|
|
|
wire endline = (xpos == kTotalWidth-1);
|
|
|
|
always @(posedge clk) begin
|
|
if (clk_en) begin
|
|
if (endline)
|
|
xpos <= 0;
|
|
else if (xpos == 0 && busCycle != 0)
|
|
// hold xpos at 0, until xpos and busCycle are in phase
|
|
xpos <= 0;
|
|
else
|
|
xpos <= xpos + 1'b1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (clk_en) begin
|
|
if (endline) begin
|
|
if (ypos == kTotalHeight-1)
|
|
ypos <= 0;
|
|
else
|
|
ypos <= ypos + 1'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (clk_en) begin
|
|
hsync <= ~(xpos >= kHsyncStart+kPixelLatency && xpos <= kHsyncEnd+kPixelLatency);
|
|
vsync <= ~(ypos >= kVsyncStart && ypos <= kVsyncEnd);
|
|
end
|
|
end
|
|
|
|
assign _hblank = ~(xpos >= kVisibleWidth+kPixelLatency);
|
|
assign _vblank = ~(ypos < kVisibleHeightStart || ypos > kVisibleHeightEnd);
|
|
|
|
// The 0,0 address actually starts below kScreenBufferBase, because the Mac screen buffer is
|
|
// not displayed beginning at 0,0, but at 0,kVisibleHeightStart.
|
|
// kVisibleHeightStart divided by 2 to account for vertical pixel doubling.
|
|
// kVisibleWidth divided by 2 because it's the 8MHz visible width times 4 to get actual number of pixels,
|
|
// then divided by 8 bits per byte
|
|
assign videoAddr = kScreenBufferBase - (vid_alt ? 16'h0 : 16'h8000) -
|
|
startAddr[21:0] +
|
|
{ ypos[9:1], xpos[6:2], 1'b0 };
|
|
|
|
assign loadPixels = _vblank == 1'b1 && _hblank == 1'b1 && busCycle == 2'b00;
|
|
|
|
endmodule
|