mirror of
https://github.com/techav-homebrew/SE-VGA.git
synced 2025-02-09 22:30:39 +00:00
Cleanup old logic
This commit is contained in:
parent
fca75c2c4c
commit
4302d72405
245
old/cpusnoop.sv
245
old/cpusnoop.sv
@ -1,245 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* CPU Bus Snoop
|
||||
* techav
|
||||
* 2021-04-06
|
||||
******************************************************************************
|
||||
* Watches for writes to frame buffer memory addresses and copies that data
|
||||
* into VRAM
|
||||
*****************************************************************************/
|
||||
|
||||
module cpusnoop (
|
||||
input wire nReset, // System Reset signal
|
||||
input wire pixClock, // 25.175MHz Pixel Clock
|
||||
input logic [2:0] seq, // Sequence count (low 3 bits of hCount)
|
||||
input logic [22:0] cpuAddr, // CPU Address bus
|
||||
input logic [15:0] cpuData, // CPU Data bus
|
||||
input wire ncpuAS, // CPU Address Strobe signal
|
||||
input wire ncpuUDS, // CPU Upper Data Strobe signal
|
||||
input wire ncpuLDS, // CPU Lower Data Strobe signal
|
||||
input wire cpuRnW, // CPU Read/Write select signal
|
||||
input wire cpuClk, // CPU Clock
|
||||
output logic [14:0] vramAddr, // VRAM Address Bus
|
||||
output logic [7:0] vramDataOut,// VRAM Data Bus Output
|
||||
output wire nvramWE, // VRAM Write strobe
|
||||
output wire nvramCE0, // VRAM Main select
|
||||
output wire nvramCE1, // VRAM Alt select
|
||||
output wire vidBufSelOut,// VRAM Video Buffer selection
|
||||
input logic [2:0] ramSize // CPU RAM size selection
|
||||
);
|
||||
|
||||
wire pendWriteLo; // low byte write to VRAM pending
|
||||
wire pendWriteHi; // high byte write to VRAM pending
|
||||
logic [13:0] addrCache; // store address for cpu writes to framebuffer
|
||||
logic [7:0] dataCacheLo; // store data for cpu writes to low byte
|
||||
logic [7:0] dataCacheHi; // store data for cpu writes to high byte
|
||||
wire cpuBufSel; // is CPU accessing frame buffer?
|
||||
logic [2:0] cycleState; // state machine state
|
||||
reg cpuCycleEnded; // mark cpu has ended its cycle
|
||||
reg cpuCycleBufSel; // which frame buffer was selected for the cpu cycle
|
||||
reg vidBufSel; // which frame buffer was selected for video output
|
||||
|
||||
// define state machine states
|
||||
parameter
|
||||
S0 = 0,
|
||||
S1 = 1,
|
||||
S2 = 2,
|
||||
S3 = 3,
|
||||
S4 = 4,
|
||||
S5 = 5;
|
||||
|
||||
// when cpu addresses the framebuffer, set our enable signal
|
||||
/* Main framebuffer starts $5900 below the top of RAM, alt frame buffer is
|
||||
* $8000 below the main frame buffer
|
||||
* ramSize is used to mask the CPU Address bits [21:19] to select the amount
|
||||
* of memory installed in the computer. Not all possible ramSize selections
|
||||
* are valid memory sizes when using 30-pin SIMMs in the Mac SE.
|
||||
* They may be possible using PDS RAM expansion cards.
|
||||
* ramSize mainBuffer altBuffer ramTop+1 ramSize Valid? Installed SIMMs
|
||||
* $7 $3fa700 $3f2700 $400000 4.0MB Y [ 1MB 1MB ][ 1MB 1MB ]
|
||||
* $6 $37a700 $372700 $380000 3.5MB N
|
||||
* $5 $2fa700 $2f2700 $300000 3.0MB N
|
||||
* $4 $27a700 $272700 $280000 2.5MB Y [ 1MB 1MB ][256kB 256kB]
|
||||
* $3 $1fa700 $1f2700 $200000 2.0MB Y [ 1MB 1MB ][ --- --- ]
|
||||
* $2 $17a700 $172700 $180000 1.5MB N
|
||||
* $1 $0fa700 $0f2700 $100000 1.0MB Y [256kB 256kB][256kB 256kB]
|
||||
* $0 $07a700 $072700 $080000 0.5MB Y [256kB 256kB][ --- --- ]
|
||||
*/
|
||||
always_comb begin
|
||||
// remember cpuAddr is shifted right by one since 68000 does not output A0
|
||||
if(cpuAddr[22:21] == 2'b00 // initial constant
|
||||
&& ramSize == cpuAddr[20:18] // ram size selection
|
||||
&& cpuAddr[17:15] == 3'b111 // trailing constant
|
||||
// next bit is main/alt select
|
||||
&& (cpuAddr[13:0] >= 14'h1380 // bottom of buffer range (0x2700>>1)
|
||||
&& cpuAddr[13:0] <= 14'h3e3f) // top of buffer range (0x7C70>>1)
|
||||
) begin
|
||||
cpuBufSel <= 1'b1;
|
||||
end else begin
|
||||
cpuBufSel <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// keep an eye out for cpu ending its cycle
|
||||
always @(negedge pixClock or negedge nReset) begin
|
||||
if(!nReset) cpuCycleEnded <= 0;
|
||||
else if(cycleState == S2) cpuCycleEnded <= 0;
|
||||
else if(ncpuUDS && ncpuLDS
|
||||
&& (cycleState == S3
|
||||
|| cycleState == S4
|
||||
|| cycleState == S5
|
||||
|| cycleState == S1)
|
||||
) begin
|
||||
cpuCycleEnded <= 1;
|
||||
end else cpuCycleEnded <= cpuCycleEnded;
|
||||
end
|
||||
|
||||
// CPU Write to VRAM state machine
|
||||
always @(negedge pixClock or negedge nReset) begin
|
||||
if(!nReset) begin
|
||||
cycleState <= S0;
|
||||
pendWriteHi <= 0;
|
||||
pendWriteLo <= 0;
|
||||
addrCache <= 0;
|
||||
dataCacheHi <= 0;
|
||||
dataCacheLo <= 0;
|
||||
end else begin
|
||||
case (cycleState)
|
||||
S0 : begin
|
||||
// idle state, wait for valid address and ncpuAS asserted
|
||||
if(ncpuAS == 0
|
||||
&& cpuBufSel == 1
|
||||
&& cpuRnW == 0
|
||||
&& (ncpuLDS == 0
|
||||
|| ncpuUDS == 0)) begin
|
||||
pendWriteHi <= !ncpuUDS;
|
||||
pendWriteLo <= !ncpuLDS;
|
||||
dataCacheHi <= cpuData[15:8];
|
||||
dataCacheLo <= cpuData[7:0];
|
||||
// Valid CPU-VRAM cycle, so subtract constant $1380 from the
|
||||
// cpu address and store the result in addrCache register.
|
||||
// Constant $1380 corresponds to $2700 shifted right by 1.
|
||||
// Once the selection bits above are masked out, we're left
|
||||
// with buffer addresses starting at $2700
|
||||
// e.g. with 4MB of RAM, fram buffer starts at $3FA700
|
||||
// buffer address: 0011 1111 1010 0111 0000 0000 = $3FA700
|
||||
// vram addr mask: 0000 0000 0011 1111 1111 1111 - $003FFF
|
||||
// vram address: 0000 0000 0010 0111 0000 0000 = $002700
|
||||
// Since CPU is 16-bit and does not provide A0, our cpuAddr
|
||||
// signals are shifted right by one, so we need to do the same
|
||||
// to our offset before subtracting it from cpuAddr
|
||||
// offset: 0000 0000 0010 0111 0000 0000 = $002700
|
||||
// shifted offset: 0000 0000 0001 0011 1000 0000 = $001380
|
||||
addrCache <= cpuAddr[13:0] - 14'h1380;
|
||||
// The next address bit selects which frame buffer the CPU
|
||||
// is writing to for this cycle. 1 = Main ; 0 = Alt
|
||||
// Invert & save for later
|
||||
cpuCycleBufSel <= !cpuAddr[14];
|
||||
|
||||
cycleState <= S2;
|
||||
end else if(ncpuAS == 0
|
||||
&& cpuRnW == 0
|
||||
&& ncpuUDS == 0
|
||||
&& cpuAddr[22:18] == 5'h1D
|
||||
&& cpuAddr[11:7] == 5'h1F) begin
|
||||
// the CPU is addressing VIA Port A. We need to check what
|
||||
// bit 6 is set to to determine which buffer is selected
|
||||
// for video output. 1 = Main ; 0 = Alt
|
||||
vidBufSel <= !cpuData[14];
|
||||
// now that we've saved the buffer selection, go to state
|
||||
// S5 to wait for the CPU to end the bus cycle.
|
||||
cycleState <= S5;
|
||||
end else begin
|
||||
cycleState <= S0;
|
||||
end
|
||||
end
|
||||
S2 : begin
|
||||
// wait for sequence
|
||||
if(pendWriteLo && !seq[0]) cycleState <= S3;
|
||||
else if (pendWriteHi && !seq[0]) cycleState <= S4;
|
||||
else if (!pendWriteHi && !pendWriteLo) cycleState <= S0; // in case something weird happens
|
||||
else cycleState <= S2;
|
||||
end
|
||||
S3 : begin
|
||||
// write CPU low byte to VRAM
|
||||
if (seq == 0) begin
|
||||
cycleState <= S3; // we shouldn't be here during a read cycle, so delay
|
||||
end else if(pendWriteHi == 1) begin
|
||||
cycleState <= S1; // move on to delay before second write cycle
|
||||
end else begin
|
||||
cycleState <= S5;
|
||||
end
|
||||
pendWriteLo <= 0;
|
||||
end
|
||||
S4 : begin
|
||||
// write CPU high byte to VRAM
|
||||
if (seq == 0) begin
|
||||
cycleState <= S4; // we shouldn't be here during a read cycle, so delay
|
||||
end else begin
|
||||
cycleState <= S5;
|
||||
end
|
||||
pendWriteHi <= 0;
|
||||
end
|
||||
S5 : begin
|
||||
// wait for CPU to negate both ncpuUDS and ncpuLDS
|
||||
if(cpuCycleEnded == 1) begin
|
||||
cycleState <= S0;
|
||||
end else begin
|
||||
cycleState <= S5;
|
||||
end
|
||||
end
|
||||
S1 : begin
|
||||
// delay moving to second write cycle
|
||||
if (!seq[0]) cycleState <= S4;
|
||||
else cycleState <= S1;
|
||||
end
|
||||
default: begin
|
||||
// how did we end up here? reset to S0
|
||||
cycleState <= S0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
// output VRAM address
|
||||
// we actually do an endian swap here assigning the low-order bit of
|
||||
// the VRAM address because the video shift register in the SE loads
|
||||
// a full 16-bit word and shifts out starting with the MSB.
|
||||
// An endian swap here ensures that when we load the VRAM for output
|
||||
// the bits are in the right order.
|
||||
vramAddr[14:1] <= addrCache[13:0];
|
||||
if(cycleState == S4) begin
|
||||
vramAddr[0] <= 0;
|
||||
end else begin
|
||||
vramAddr[0] <= 1;
|
||||
end
|
||||
|
||||
// Assert VRAM Write signal during CPU Cycle states S3 & S4
|
||||
// Also assert VRAM chip enable signals based on which buffer the CPU
|
||||
// addressed for the VRAM write cycle
|
||||
if(seq != 0 && (cycleState == S3 || cycleState == S4)) begin
|
||||
nvramWE <= 0;
|
||||
nvramCE0 <= cpuCycleBufSel;
|
||||
nvramCE1 <= !cpuCycleBufSel;
|
||||
end else begin
|
||||
nvramWE <= 1;
|
||||
nvramCE0 <= 1;
|
||||
nvramCE1 <= 1;
|
||||
end
|
||||
|
||||
// Output our internal data cache registers on CPU Cycle states S3 & S4
|
||||
// Otherwise, just output 0. This will be muxed for the VRAM data bus
|
||||
// in the next module outside of here.
|
||||
if(cycleState == S3) begin
|
||||
vramDataOut <= dataCacheLo;
|
||||
end else if(cycleState == S4) begin
|
||||
vramDataOut <= dataCacheHi;
|
||||
end else begin
|
||||
vramDataOut <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
assign vidBufSelOut = vidBufSel;
|
||||
|
||||
endmodule
|
124
old/se-vga.sv
124
old/se-vga.sv
@ -1,124 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* Top-level module
|
||||
* techav
|
||||
* 2021-04-06
|
||||
******************************************************************************
|
||||
* Pulls together all the smaller modules to form the SE-VGA adapter
|
||||
*****************************************************************************/
|
||||
|
||||
module sevga (
|
||||
input wire nReset, // System reset signal
|
||||
input wire pixClk, // 25.175MHz pixel clock
|
||||
output wire nhSync, // HSync signal
|
||||
output wire nvSync, // VSync signal
|
||||
output wire vidOut, // 1-bit Monochrome video signal
|
||||
|
||||
output logic [14:0] vramAddr, // VRAM Address bus
|
||||
inout logic [7:0] vramData, // VRAM Data bus
|
||||
output wire nvramOE, // VRAM Read strobe
|
||||
output wire nvramWE, // VRAM Write strobe
|
||||
output wire nvramCE0, // VRAM Main chip select signal
|
||||
output wire nvramCE1, // VRAM Alt chip select signal
|
||||
|
||||
input logic [23:1] cpuAddr, // CPU Address bus
|
||||
input logic [15:0] cpuData, // CPU Data bus
|
||||
input wire ncpuAS, // CPU Address Strobe signal
|
||||
input wire ncpuUDS, // CPU Upper Data Strobe signal
|
||||
input wire ncpuLDS, // CPU Lower Data Strobe signal
|
||||
input wire cpuRnW, // CPU Read/Write select signal
|
||||
input logic [2:0] ramSize // Select installed RAM size
|
||||
);
|
||||
|
||||
logic [9:0] hCount;
|
||||
logic [9:0] vCount;
|
||||
wire hActive;
|
||||
wire hSEActive;
|
||||
wire vActive;
|
||||
wire vSEActive;
|
||||
wire nvramWEpre; // VRAM Write signal from cpu snoop
|
||||
wire nvramCE0pre;
|
||||
wire nvramCE1pre;
|
||||
wire vidBufSel;
|
||||
|
||||
logic [14:0] vidVramAddr;
|
||||
logic [14:0] cpuVramAddr;
|
||||
logic [7:0] vidVramData;
|
||||
wire [7:0] cpuVramData;
|
||||
|
||||
// link module that generates all our timing signals
|
||||
vgagen vgatiming(
|
||||
.nReset(nReset),
|
||||
.pixClk(pixClk),
|
||||
.hCount(hCount),
|
||||
.hActive(hActive),
|
||||
.hSEActive(hSEActive),
|
||||
.nhSync(nhSync),
|
||||
.vCount(vCount),
|
||||
.vActive(vActive),
|
||||
.vSEActive(vSEActive),
|
||||
.nvSync(nvSync)
|
||||
);
|
||||
|
||||
// link module that fetches & outputs video data
|
||||
vgaout vidvram(
|
||||
.pixClock(pixClk),
|
||||
.nReset(nReset),
|
||||
.hCount(hCount),
|
||||
.vCount(vCount),
|
||||
.hSEActive(hSEActive),
|
||||
.vSEActive(vSEActive),
|
||||
.vramData(vidVramData),
|
||||
.vramAddr(vidVramAddr),
|
||||
.nvramOE(nvramOE),
|
||||
.vidOut(vidOut)
|
||||
);
|
||||
|
||||
// link module that snoops cpu writes
|
||||
cpusnoop cpusnp(
|
||||
.nReset(nReset),
|
||||
.pixClock(pixClk),
|
||||
.seq(hCount[2:0]),
|
||||
.cpuAddr(cpuAddr),
|
||||
.cpuData(cpuData),
|
||||
.ncpuAS(ncpuAS),
|
||||
.ncpuUDS(ncpuUDS),
|
||||
.ncpuLDS(ncpuLDS),
|
||||
.cpuRnW(cpuRnW),
|
||||
.cpuClk(cpuClk),
|
||||
.vramAddr(cpuVramAddr),
|
||||
.vramDataOut(cpuVramData),
|
||||
.nvramWE(nvramWEpre),
|
||||
.nvramCE0(nvramCE0pre),
|
||||
.nvramCE1(nvramCE1pre),
|
||||
.vidBufSelOut(vidBufSel),
|
||||
.ramSize(ramSize)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
// vramAddr muxing
|
||||
if(nvramWEpre == 1'b0) begin
|
||||
vramAddr <= cpuVramAddr;
|
||||
end else if(nvramOE == 0) begin
|
||||
vramAddr <= vidVramAddr;
|
||||
end else begin
|
||||
vramAddr <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
if(nvramWEpre == 1'b0) begin
|
||||
vramData <= cpuVramData;
|
||||
end else begin
|
||||
vramData <= 8'bZZZZZZZZ;
|
||||
end
|
||||
vidVramData <= vramData;
|
||||
end
|
||||
|
||||
assign nvramCE0 = (nvramWEpre | nvramCE0pre) & (nvramOE | vidBufSel);
|
||||
assign nvramCE1 = (nvramWEpre | nvramCE1pre) & (nvramOE | ~vidBufSel);
|
||||
|
||||
//assign nvramWE = nvramWEpre | pixClk;
|
||||
assign nvramWE = nvramWEpre;
|
||||
|
||||
endmodule
|
@ -1,229 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* Top-level module
|
||||
* techav
|
||||
* 2021-10-16
|
||||
******************************************************************************
|
||||
* Trying again again again
|
||||
*****************************************************************************/
|
||||
|
||||
module sevga (
|
||||
input wire nReset, // System reset signal
|
||||
input wire pixClk, // 65MHz pixel clock
|
||||
output reg nhSync, // HSync signal
|
||||
output reg nvSync, // VSync signal
|
||||
output reg vidOut, // 1-bit Monochrome video signal
|
||||
|
||||
output logic [14:0] vramAddr, // VRAM Address bus
|
||||
inout logic [7:0] vramData, // VRAM Data bus
|
||||
output reg nvramOE, // VRAM Read strobe
|
||||
output reg nvramWE, // VRAM Write strobe
|
||||
output reg nvramCE0, // VRAM Main chip select signal
|
||||
output reg nvramCE1, // VRAM Alt chip select signal
|
||||
|
||||
input wire [23:1] cpuAddr, // CPU Address bus
|
||||
input wire [15:0] cpuData, // CPU Data bus
|
||||
input wire ncpuAS, // CPU Address Strobe signal
|
||||
input wire ncpuUDS, // CPU Upper Data Strobe signal
|
||||
input wire ncpuLDS, // CPU Lower Data Strobe signal
|
||||
input wire cpuRnW, // CPU Read/Write select signal
|
||||
input logic [2:0] ramSize // Select installed RAM size
|
||||
);
|
||||
|
||||
/******************************************************************************
|
||||
* Initial Video Signal Timing
|
||||
* The following functions establish the basic XGA signal timing and
|
||||
* assert the horizontal and vertical sync signals as appropriate.
|
||||
* These functions are the minimum required for a signal presence detect test.
|
||||
*****************************************************************************/
|
||||
|
||||
// Primary sync counters
|
||||
logic [10:0] hCount; // 0..1343
|
||||
logic [9:0] vCount; // 0..805
|
||||
always @(negedge pixClk) begin
|
||||
if(hCount < 1343) hCount <= hCount + 11'h1;
|
||||
else begin
|
||||
hCount <= 0;
|
||||
if(vCount <= 805) vCount <= vCount + 10'h1;
|
||||
else vCount <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// Horizontal sync
|
||||
always @(negedge pixClk) begin
|
||||
if(hCount == 0) nhSync <= 1;
|
||||
else if(hCount == 1052) nhSync <= 0;
|
||||
else if(hCount == 1186) nhSync <= 1;
|
||||
end
|
||||
|
||||
// Vertical sync
|
||||
always @(negedge pixClk) begin
|
||||
if(vCount == 0) nvSync <= 1;
|
||||
else if(vCount == 729) nvSync <= 0;
|
||||
else if(vCount == 734) nvSync <= 0;
|
||||
end
|
||||
|
||||
/******************************************************************************
|
||||
* Useful signals
|
||||
* Here we break out a few useful signals, derived from the timing above, that
|
||||
* will help us elsewhere.
|
||||
*****************************************************************************/
|
||||
|
||||
// Horizontal active
|
||||
reg hActive;
|
||||
always @(negedge pixClk) begin
|
||||
if(hCount == 0) hActive <= 1;
|
||||
else if(hCount == 1023) hActive <= 0;
|
||||
else if(hCount == 1343) hActive <= 1;
|
||||
end
|
||||
|
||||
// Vertical active
|
||||
reg vActive;
|
||||
always @(negedge pixClk) begin
|
||||
if(vCount == 0) vActive <= 1;
|
||||
else if(vCount == 683) vActive <= 0;
|
||||
else if(vCount == 805) vActive <= 1;
|
||||
end
|
||||
|
||||
// Horizontal fetch active
|
||||
// asserted just before active video to enable video data pre-fetch
|
||||
reg fhActive;
|
||||
always @(negedge pixClk) begin
|
||||
if(hCount == 0) fhActive <= 1;
|
||||
else if(hCount == 1022) fhActive <= 0;
|
||||
else if(hCount == 1342) fhActive <= 1;
|
||||
end
|
||||
|
||||
// Vertical fetch active
|
||||
//
|
||||
reg fvActive;
|
||||
always @(negedge pixClk) begin
|
||||
if(vCount == 0) fvActive <= 1;
|
||||
else if(vCount == 684) fvActive <= 0;
|
||||
if(vCount == 805) fvActive <= 1;
|
||||
end
|
||||
|
||||
// combined active signals
|
||||
wire vidActive = hActive & vActive;
|
||||
wire fetchActive = fhActive & fvActive;
|
||||
|
||||
/******************************************************************************
|
||||
* VRAM State Machine
|
||||
* Coordinates VRAM load/store actions
|
||||
*****************************************************************************/
|
||||
|
||||
// rising edge signals: nvramWE, nvramOE, nvramCE[1:0]
|
||||
// falling edge signals: vramAddr, vramData
|
||||
|
||||
// VRAM read signal
|
||||
//always @(posedge pixClk) begin nvramOE <= ~(hCount == 7); end
|
||||
|
||||
// VRAM write signal
|
||||
always @(posedge pixClk) begin
|
||||
if(hCount[3:1] == 0) nvramWE <= 1;
|
||||
else if(hCount[3:1] == 1) nvramWE <= 0;
|
||||
else if(hCount[3:1] == 6) nvramWE <= 1;
|
||||
end
|
||||
|
||||
// VRAM data/address busses
|
||||
always @(negedge pixClk) begin
|
||||
if(hCount[0] && !hCount[1]) begin
|
||||
case(hCount[3:2])
|
||||
3: begin
|
||||
// start read cycle
|
||||
vramData <= 8'hZ;
|
||||
vramAddr[14:6] <= vCount[9:1];
|
||||
vramAddr[5:0] <= hCount[9:4];
|
||||
end
|
||||
default: begin
|
||||
// write slots
|
||||
vramAddr[14:1] <= cpuAddr[14:1] - 14'h1380;
|
||||
if(!ncpuUDSr && !cpuLDSsrv) begin
|
||||
vramAddr[0] <= 0;
|
||||
vramData <= cpuData[15:8];
|
||||
end else if(!ncpuLDSr && !cpuLDSsrv) begin
|
||||
vramAddr[0] <= 1;
|
||||
vramData <= cpuData[7:0];
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// VRAM chip enable signals
|
||||
reg cpuUDSsrv, cpuLDSsrv;
|
||||
always @(posedge pixClk) begin
|
||||
if(hCount[3:1] == 7 && fetchActive) begin
|
||||
nvramCE0 <= vidBufSel;
|
||||
nvramCE1 <= ~vidBufSel;
|
||||
nvramOE <= 0;
|
||||
end else if(!hCount[0] && hCount[1]) begin
|
||||
// write cycle
|
||||
if(!ncpuUDSr && !cpuUDSsrv) begin
|
||||
nvramCE0 <= ~cpuAddr[15];
|
||||
nvramCE1 <= cpuAddr[15];
|
||||
cpuUDSsrv <= 1;
|
||||
end else if(!ncpuLDSr && !cpuLDSsrv) begin
|
||||
nvramCE0 <= ~cpuAddr[15];
|
||||
nvramCE1 <= cpuAddr[15];
|
||||
cpuLDSsrv <= 1;
|
||||
end else begin
|
||||
nvramCE0 <= 1;
|
||||
nvramCE1 <= 1;
|
||||
end
|
||||
nvramOE <= 1;
|
||||
end else begin
|
||||
nvramCE0 <= 1;
|
||||
nvramCE1 <= 1;
|
||||
nvramOE <= 1;
|
||||
end
|
||||
// reset the upper/lower serve signals when cycle ended by CPU
|
||||
if(ncpuLDS) cpuLDSsrv <= 0;
|
||||
if(ncpuUDS) cpuUDSsrv <= 0;
|
||||
end
|
||||
|
||||
// Video data shift register & output
|
||||
reg [7:0] vidShiftr;
|
||||
always @(negedge pixClk) begin
|
||||
if(hCount[3:0] == 4'hF) vidShiftr <= ~vramData;
|
||||
else if(hCount[0]) begin
|
||||
vidShiftr[7:1] <= vidShiftr[6:0];
|
||||
vidShiftr[0] <= 0;
|
||||
end
|
||||
end
|
||||
always_comb begin
|
||||
if(vidActive) vidOut = vidShiftr[7];
|
||||
else vidOut <= 0;
|
||||
end
|
||||
|
||||
/******************************************************************************
|
||||
* CPU Bus Snooping
|
||||
* Watches the CPU bus and aligns its operations with the pixel clock
|
||||
*****************************************************************************/
|
||||
reg ncpuUDSr, ncpuLDSr;
|
||||
always @(negedge pixClk) begin
|
||||
// this condition evaluates true when cpu is writing to video buffer
|
||||
if(!ncpuAS && !cpuRnW
|
||||
&& !cpuAddr[23] && !cpuAddr[22]
|
||||
&& !(cpuAddr[21] ^ ramSize[2])
|
||||
&& !(cpuAddr[20] ^ ramSize[1])
|
||||
&& !(cpuAddr[19] ^ ramSize[0])
|
||||
&& cpuAddr[18] && cpuAddr[17]
|
||||
&& cpuAddr[16]
|
||||
&& ((cpuAddr[14:1] >= 14'h1380)
|
||||
&& (cpuAddr[14:1] < 14'h3E40)))
|
||||
begin
|
||||
if(!ncpuUDS) ncpuUDSr <= 0;
|
||||
else ncpuUDSr <= 1;
|
||||
if(!ncpuLDS) ncpuLDSr <= 0;
|
||||
else ncpuLDSr <= 1;
|
||||
end else begin
|
||||
ncpuUDSr <= 1;
|
||||
ncpuLDSr <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
// hold low for now
|
||||
reg vidBufSel = 0;
|
||||
|
||||
endmodule
|
3971
old/sevga.vwf
3971
old/sevga.vwf
File diff suppressed because it is too large
Load Diff
@ -1,74 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* VGA signal counter
|
||||
* techav
|
||||
* 2021-04-06
|
||||
******************************************************************************
|
||||
* Low-level VGA signal counter
|
||||
*****************************************************************************/
|
||||
|
||||
`ifndef VGACOUNT
|
||||
`define VGACOUNT
|
||||
|
||||
module vgacount (
|
||||
input wire nReset, // system reset signal
|
||||
input wire clock, // counter increment clock
|
||||
output logic [9:0] count, // count output
|
||||
output wire nSync, // sync pulse
|
||||
output wire activeVid, // active video signal
|
||||
output wire activeSE // secondary active video signal (SE)
|
||||
);
|
||||
|
||||
parameter COUNTMAX=800, // Total dot count per line or line count per frame
|
||||
SYNCBEGIN=592, // Dot/Line count where sync pulse begins
|
||||
SYNCEND=688, // Dot/Line count +1 where sync pulse ends
|
||||
ACTBEGIN=576, // Dot/Line count where VGA active video begins
|
||||
ACTEND=736, // Dot/Line count +1 where VGA active video ends
|
||||
SEACTBEGIN=512; // Dot/Line count +1 where SE video window ends
|
||||
|
||||
logic [9:0] counter;
|
||||
|
||||
// primary counter
|
||||
always @(negedge clock or negedge nReset) begin
|
||||
if(nReset == 1'b0) begin
|
||||
counter <= 10'h0;
|
||||
end else begin
|
||||
if (counter < COUNTMAX) begin
|
||||
counter <= counter + 10'h1;
|
||||
end else begin
|
||||
counter <= 10'h0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// combinatorial logic derived from the counters
|
||||
always_comb begin
|
||||
// output the count signals
|
||||
count <= counter;
|
||||
|
||||
// Sync pulse
|
||||
if(count >= SYNCBEGIN && count < SYNCEND) begin
|
||||
nSync <= 1'b0;
|
||||
end else begin
|
||||
nSync <= 1'b1;
|
||||
end
|
||||
|
||||
// VGA active video range
|
||||
if(count >= ACTBEGIN && count < ACTEND) begin
|
||||
activeVid <= 1'b0;
|
||||
end else begin
|
||||
activeVid <= 1'b1;
|
||||
end
|
||||
|
||||
// SE active video window within VGA active video range
|
||||
if(count >= SEACTBEGIN) begin
|
||||
activeSE <= 1'b0;
|
||||
end else begin
|
||||
activeSE <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`endif
|
@ -1,35 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* VGA timing generator
|
||||
* techav
|
||||
* 2021-04-06
|
||||
******************************************************************************
|
||||
* Generates VGA timing signals & counters
|
||||
*****************************************************************************/
|
||||
|
||||
`ifndef VGAGEN
|
||||
`define VGAGEN
|
||||
|
||||
`include "vgacount.sv"
|
||||
|
||||
module vgagen (
|
||||
input wire nReset, // master reset signal
|
||||
input wire pixClk, // 25.175MHz pixel clock
|
||||
output logic [9:0] hCount, // horizontal pixel count
|
||||
output wire hActive, // horizontal VGA active video signal
|
||||
output wire hSEActive, // horizontal SE active video signal
|
||||
output wire nhSync, // horizontal sync pulse signal
|
||||
output logic [9:0] vCount, // vertical line count
|
||||
output wire vActive, // vertical VGA active video signal
|
||||
output wire vSEActive, // vertical SE active video signal
|
||||
output wire nvSync // vertical sync pulse signal
|
||||
);
|
||||
|
||||
// Generate horizontal signal timing
|
||||
vgacount #(800,592,688,576,736,512) hoz(nReset,pixClk,hCount,nhSync,hActive,hSEActive);
|
||||
// Generate vertical signal timing
|
||||
vgacount #(525,421,423,411,456,342) ver(nReset,nhSync,vCount,nvSync,vActive,vSEActive);
|
||||
|
||||
endmodule
|
||||
|
||||
`endif
|
@ -1,68 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* VGA video output
|
||||
* techav
|
||||
* 2021-04-06
|
||||
******************************************************************************
|
||||
* Fetches video data from VRAM and shifts out
|
||||
*****************************************************************************/
|
||||
|
||||
`include "vgashiftout.sv"
|
||||
|
||||
module vgaout (
|
||||
input wire pixClock,
|
||||
input wire nReset,
|
||||
input logic [9:0] hCount,
|
||||
input logic [9:0] vCount,
|
||||
input wire hSEActive,
|
||||
input wire vSEActive,
|
||||
input logic [7:0] vramData,
|
||||
output logic [14:0] vramAddr,
|
||||
output wire nvramOE,
|
||||
output wire vidOut
|
||||
);
|
||||
|
||||
wire vidMuxOut; // pixel data shift out
|
||||
wire vidActive; // combined active video signal
|
||||
|
||||
wire nVidLoad; // Load VRAM data into shifter
|
||||
vgaShiftOut vOut(
|
||||
.nReset(nReset),
|
||||
.clk(pixClock),
|
||||
.nLoad(nVidLoad),
|
||||
.parIn(vramData),
|
||||
.out(vidMuxOut)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
if(hCount[2:0] == 0) nVidLoad <= 0;
|
||||
else nVidLoad <= 1;
|
||||
|
||||
// combined video active signal
|
||||
if(hSEActive == 1'b1 && vSEActive == 1'b1) begin
|
||||
vidActive <= 1'b1;
|
||||
end else begin
|
||||
vidActive <= 1'b0;
|
||||
end
|
||||
|
||||
// video data output
|
||||
if(vidActive == 1'b1) begin
|
||||
vidOut <= ~vidMuxOut;
|
||||
end else begin
|
||||
vidOut <= 1'b0;
|
||||
end
|
||||
|
||||
// vram read signal
|
||||
if(vidActive == 1'b1 && hCount[2:0] == 0) begin
|
||||
nvramOE <= 1'b0;
|
||||
end else begin
|
||||
nvramOE <= 1'b1;
|
||||
end
|
||||
|
||||
// vram address signals
|
||||
// these will be mux'd with cpu addresses externally
|
||||
vramAddr[14:6] <= vCount[8:0];
|
||||
vramAddr[5:0] <= hCount[8:3];
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,84 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* VGA Shift Out
|
||||
* techav
|
||||
* 2021-04-06
|
||||
******************************************************************************
|
||||
* 2-stage shift register for storing & shifting out pixel data
|
||||
*****************************************************************************/
|
||||
|
||||
`ifndef VGASHIFTOUT
|
||||
`define VGASHIFTOUT
|
||||
|
||||
module vgaShiftOut (
|
||||
input wire nReset, clk, nLoad,
|
||||
input logic [7:0] parIn,
|
||||
output wire out
|
||||
);
|
||||
|
||||
reg [8:0] shiftReg;
|
||||
|
||||
always @(negedge clk or negedge nReset) begin
|
||||
if(!nReset) shiftReg <= 0;
|
||||
else begin
|
||||
if(!nLoad) begin
|
||||
shiftReg[8] <= shiftReg[7];
|
||||
shiftReg[7:0] <= parIn;
|
||||
end else begin
|
||||
shiftReg[8:1] <= shiftReg[7:0];
|
||||
shiftReg[0] <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign out = shiftReg[8];
|
||||
|
||||
endmodule
|
||||
|
||||
/*
|
||||
module vgaShiftOut (
|
||||
input wire nReset,
|
||||
input wire clk,
|
||||
input wire shiftEn,
|
||||
input wire nLoad1,
|
||||
input wire nLoad2,
|
||||
input logic [7:0] parIn,
|
||||
output wire out
|
||||
);
|
||||
|
||||
reg [7:0] inReg;
|
||||
reg [7:0] outReg;
|
||||
|
||||
// load data into first stage register on rising edge of pixel clock
|
||||
// if nLoad1 is asserted
|
||||
always @(posedge clk or negedge nReset) begin
|
||||
if(!nReset) inReg <= 0;
|
||||
else if(!nLoad1) inReg <= parIn;
|
||||
end
|
||||
|
||||
// load data into second stage register on falling edge of pixel clock
|
||||
// if nLoad2 is asserted, otherwise if shiftEn is asserted, then shift
|
||||
// video data out. Shift in 0 to fill empty registers
|
||||
always @(negedge clk or negedge nReset) begin
|
||||
if(!nReset) outReg <= 0;
|
||||
else begin
|
||||
if(!nLoad2) outReg <= inReg;
|
||||
else if(shiftEn) begin
|
||||
outReg[7] <= outReg[6];
|
||||
outReg[6] <= outReg[5];
|
||||
outReg[5] <= outReg[4];
|
||||
outReg[4] <= outReg[3];
|
||||
outReg[3] <= outReg[2];
|
||||
outReg[2] <= outReg[1];
|
||||
outReg[1] <= outReg[0];
|
||||
outReg[0] <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// high-order bit of the shift register (second stage) is the serial output
|
||||
assign out = outReg[7];
|
||||
endmodule
|
||||
*/
|
||||
|
||||
`endif
|
@ -1,75 +0,0 @@
|
||||
/******************************************************************************
|
||||
* SE-VGA
|
||||
* VGA Output Test
|
||||
* techav
|
||||
* 2021-05-14
|
||||
******************************************************************************
|
||||
* Test configuration for testily testing testy test hardware.
|
||||
* This is not a part of the actual configuration. It is a separate top-level
|
||||
* entity for testing modules and hardware. Outputs a 512x342 pixel window of
|
||||
* alternating black and white pixels in a 640x480 resolution screen.
|
||||
*****************************************************************************/
|
||||
|
||||
// all the same I's and O's as our proper configuration
|
||||
module vgatest (
|
||||
input wire nReset, // System reset signal
|
||||
input wire pixClk, // 25.175MHz pixel clock
|
||||
output wire nhSync, // HSync signal
|
||||
output wire nvSync, // VSync signal
|
||||
output wire vidOut, // 1-bit Monochrome video signal
|
||||
|
||||
output logic [14:0] vramAddr, // VRAM Address bus
|
||||
//inout logic [7:0] vramData, // VRAM Data bus
|
||||
input logic [7:0] vramData,
|
||||
output wire nvramOE, // VRAM Read strobe
|
||||
output wire nvramWE, // VRAM Write strobe
|
||||
output wire nvramCE0, // VRAM Main chip select signal
|
||||
output wire nvramCE1, // VRAM Alt chip select signal
|
||||
|
||||
input logic [23:1] cpuAddr, // CPU Address bus
|
||||
//input logic [15:0] cpuData, // CPU Data bus
|
||||
output logic [15:0] cpuData,
|
||||
input wire ncpuAS, // CPU Address Strobe signal
|
||||
input wire ncpuUDS, // CPU Upper Data Strobe signal
|
||||
input wire ncpuLDS, // CPU Lower Data Strobe signal
|
||||
input wire cpuRnW, // CPU Read/Write select signal
|
||||
input logic [2:0] ramSize // Select installed RAM size
|
||||
);
|
||||
|
||||
logic [9:0] hCount, vCount;
|
||||
wire hActive, hSEActive;
|
||||
wire vActive, vSEActive;
|
||||
|
||||
vgagen vgatiming(
|
||||
.nReset(nReset),
|
||||
.pixClk(pixClk),
|
||||
.hCount(hCount),
|
||||
.hActive(hActive),
|
||||
.hSEActive(hSEActive),
|
||||
.nhSync(nhSync),
|
||||
.vCount(vCount),
|
||||
.vActive(vActive),
|
||||
.vSEActive(vSEActive),
|
||||
.nvSync(nvSync)
|
||||
);
|
||||
|
||||
reg outTog;
|
||||
|
||||
always @(negedge pixClk or negedge nReset) begin
|
||||
if(nReset == 0) begin
|
||||
outTog <= 0;
|
||||
end else begin
|
||||
outTog <= !outTog;
|
||||
end
|
||||
end
|
||||
|
||||
assign vidOut = outTog & hSEActive & vSEActive;
|
||||
assign vramAddr = 0;
|
||||
assign nvramOE = 1;
|
||||
assign nvramWE = 1;
|
||||
assign nvramCE0 = 1;
|
||||
assign nvramCE1 = 1;
|
||||
assign cpuData[7:0] = ~vramData;
|
||||
assign cpuData[15:8] = vramData;
|
||||
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user