Add Alternate Frame Buffer Support

This commit is contained in:
techav 2021-04-19 20:45:11 -05:00
parent 57436785a2
commit 85a3cc95d9
2 changed files with 66 additions and 15 deletions

View File

@ -22,6 +22,9 @@ module cpusnoop (
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
);
@ -33,6 +36,8 @@ module cpusnoop (
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
@ -44,24 +49,25 @@ module cpusnoop (
S5 = 5;
// when cpu addresses the framebuffer, set our enable signal
/* framebuffer starts $5900 below the top of RAM
* ramSize is used to mask the cpuAddr bits [21:19] to select the amount
/* 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 bufferStart ramTop+1 ramSize Valid? Installed SIMMs
* $7 $3fa700 $400000 4.0MB Y [ 1MB 1MB ][ 1MB 1MB ]
* $6 $37a700 $380000 3.5MB N
* $5 $2fa700 $300000 3.0MB N
* $4 $27a700 $280000 2.5MB Y [ 1MB 1MB ][256kB 256kB]
* $3 $1fa700 $200000 2.0MB Y [ 1MB 1MB ][ --- --- ]
* $2 $17a700 $180000 1.5MB N
* $1 $0fa700 $100000 1.0MB Y [256kB 256kB][256kB 256kB]
* $0 $07a700 $080000 0.5MB Y [256kB 256kB][ --- --- ]
* 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(ramSize == cpuAddr[20:18] && cpuAddr[22:21] == 2'b00 && cpuAddr[17:14] == 4'b1111) begin
if(ramSize == cpuAddr[20:18] && cpuAddr[22:21] == 2'b00 && cpuAddr[17:15] == 3'b111) begin
cpuBufSel <= 1'b1;
end else begin
cpuBufSel <= 1'b0;
@ -72,8 +78,13 @@ module cpusnoop (
always @(negedge pixClock or negedge nReset) begin
if(!nReset) cpuCycleEnded <= 0;
else if(cycleState == S2) cpuCycleEnded <= 0;
else if(ncpuUDS == 1 && ncpuLDS == 1 && (cycleState == S3 || cycleState == S4 || cycleState == S5)) cpuCycleEnded <= 1;
else cpuCycleEnded <= cpuCycleEnded;
else if(ncpuUDS == 1
&& ncpuLDS == 1
&& (cycleState == S3
|| cycleState == S4
|| cycleState == S5)) begin
cpuCycleEnded <= 1;
end else cpuCycleEnded <= cpuCycleEnded;
end
// CPU Write to VRAM state machine
@ -89,7 +100,11 @@ module cpusnoop (
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
if(ncpuAS == 0
&& cpuBufSel == 1
&& cpuRnW == 0
&& (ncpuLDS == 0
|| ncpuUDS == 0)) begin
pendWriteHi <= !ncpuUDS;
pendWriteLo <= !ncpuLDS;
dataCacheHi <= cpuData[15:8];
@ -109,8 +124,25 @@ module cpusnoop (
// 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[10:7] == 4'hF
|| cpuAddr[10:7] == 4'h1)) 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
@ -189,10 +221,16 @@ module cpusnoop (
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(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
@ -207,4 +245,6 @@ module cpusnoop (
end
end
assign vidBufSelOut = vidBufSel;
endmodule

View File

@ -18,6 +18,8 @@ module sevga (
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
@ -35,6 +37,9 @@ 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;
@ -84,6 +89,9 @@ cpusnoop cpusnp(
.vramAddr(cpuVramAddr),
.vramDataOut(cpuVramData),
.nvramWE(nvramWEpre),
.nvramCE0(nvramCE0pre),
.nvramCE1(nvramCE1pre),
.vidBufSelOut(vidBufSel),
.ramSize(ramSize)
);
@ -107,6 +115,9 @@ always_comb begin
vidVramData <= vramData;
end
assign nvramCE0 = (nvramWEpre | nvramCE0pre) & (nvramOE | vidBufSel);
assign nvramCE1 = (nvramWEpre | nvramCE1pre) & (nvramOE | !vidBufSel);
assign nvramWE = nvramWEpre | pixClk;
endmodule