1
0
mirror of https://github.com/UzixLS/zx-sizif-xxs.git synced 2025-07-19 07:11:28 +03:00

refactor: rename screen->video, memcontrol->mem, cpucontrol->cpu

no functional changes
This commit is contained in:
Eugene Lozovoy
2024-01-03 19:05:12 +03:00
parent 48ad108e9c
commit 948f4190f3
16 changed files with 384 additions and 398 deletions

View File

@ -6,6 +6,7 @@ endpackage
interface cpu_bus();
reg [15:0] a_raw;
reg [15:0] a;
reg [7:0] d;
reg iorq;
@ -15,8 +16,6 @@ interface cpu_bus();
reg rd;
reg wr;
reg [15:0] a_reg;
reg [7:0] d_reg;
wire ioreq;
wire memreq;
endinterface

34
fpga/rtl/cpucontrol.sv → fpga/rtl/cpu.sv Executable file → Normal file
View File

@ -1,5 +1,5 @@
import common::*;
module cpucontrol(
module cpu(
input rst_n,
input clk28,
input clk14,
@ -12,16 +12,16 @@ module cpucontrol(
input [8:0] vc,
input [8:0] hc,
input screen_contention,
input [2:0] rampage128,
input video_contention,
input [2:0] ram_page128,
input machine_t machine,
input turbo_t turbo,
input init_done_in,
output reg n_rstcpu,
output reg n_rstcpu_out,
output reg clkcpu,
output clkcpu_ck,
output clkwait,
output clkcpu_stall,
output reg n_int,
output n_int_next,
output snow
@ -29,19 +29,19 @@ module cpucontrol(
/* CONTENTION */
wire iorq_contended = bus.iorq && (~bus.a_reg[0] || (~bus.a_reg[1] && ~bus.a[15] && bus.wr)) && (machine != MACHINE_S3);
wire iorq_contended = bus.iorq && (~bus.a[0] || (~bus.a[1] && ~bus.a_raw[15] && bus.wr)) && (machine != MACHINE_S3);
reg mreq_delayed, iorq_delayed;
always @(negedge clk28) if (clkcpu_ck)
mreq_delayed <= bus.mreq;
always @(negedge clk28) if (clkcpu_ck)
iorq_delayed <= bus.iorq && ~bus.a_reg[0];
wire contention_mem_page = (machine == MACHINE_S3)? rampage128[2] : rampage128[0];
wire contention_mem_addr = bus.a[14] & (~bus.a[15] | (bus.a[15] & contention_mem_page));
iorq_delayed <= bus.iorq && ~bus.a[0];
wire contention_mem_page = (machine == MACHINE_S3)? ram_page128[2] : ram_page128[0];
wire contention_mem_addr = bus.a_raw[14] & (~bus.a_raw[15] | (bus.a_raw[15] & contention_mem_page));
wire contention_mem = iorq_delayed == 1'b0 && mreq_delayed == 1'b0 && contention_mem_addr;
wire contention_io = iorq_delayed == 1'b0 && iorq_contended;
wire contention0 = screen_contention && (contention_mem || contention_io);
wire contention0 = video_contention && (contention_mem || contention_io);
wire contention = clkcpu && contention0 && turbo == TURBO_NONE && (machine == MACHINE_S48 || machine == MACHINE_S128 || machine == MACHINE_S3);
assign snow = bus.a[14] && ~bus.a[15] && bus.rfsh && (machine == MACHINE_S48 || machine == MACHINE_S128);
assign snow = bus.a_raw[14] && ~bus.a_raw[15] && bus.rfsh && (machine == MACHINE_S48 || machine == MACHINE_S128);
/* CLOCK */
@ -60,10 +60,10 @@ end
reg clkcpu_prev;
assign clkcpu_ck = clkcpu && !clkcpu_prev;
assign clkwait = contention || (|turbo_wait[3:1]);
assign clkcpu_stall = contention || (|turbo_wait[3:1]);
always @(posedge clk28) begin
clkcpu_prev <= clkcpu;
if (clkwait)
if (clkcpu_stall)
clkcpu <= clkcpu;
else if (turbo == TURBO_14)
clkcpu <= clk14;
@ -112,15 +112,15 @@ end
/* RESET */
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
n_rstcpu <= 0;
n_rstcpu_out <= 0;
else if (!init_done_in)
n_rstcpu <= 0;
n_rstcpu_out <= 0;
`ifdef TESTBENCH
else if (hc[4])
n_rstcpu <= 1'b1;
n_rstcpu_out <= 1'b1;
`endif
else if (vc[8])
n_rstcpu <= 1'b1;
n_rstcpu_out <= 1'b1;
end

View File

@ -19,8 +19,8 @@ module divmmc(
output reg sd_cs,
input rammap,
input magic_mode,
input magic_map,
input mask_hooks,
input mask_nmi_hook,
output reg [3:0] page,
output map,
@ -31,31 +31,30 @@ module divmmc(
);
reg automap0;
reg automap_next;
reg automap0, automap_next;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
automap_next <= 0;
automap0 <= 0;
end
else if (bus.m1 && bus.memreq && !magic_map) begin
else if (bus.m1 && bus.memreq && !mask_hooks) begin
if (!en_hooks || !en || rammap) begin
automap_next <= 0;
end
else if (bus.a_reg[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
else if (bus.a[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
automap_next <= 0;
end
else if (
bus.a_reg == 16'h0000 || // power-on/reset/rst0/software restart
bus.a_reg == 16'h0008 || // syntax error
bus.a_reg == 16'h0038 || // im1 interrupt/rst #38
(bus.a_reg == 16'h0066 && !magic_mode) || // nmi routine
bus.a_reg == 16'h04C6 || // tape save routine
bus.a_reg == 16'h0562 // tape load and verify routine
(bus.a == 16'h0000) || // power-on/reset/rst0/software restart
(bus.a == 16'h0008) || // syntax error
(bus.a == 16'h0038) || // im1 interrupt/rst #38
(bus.a == 16'h0066 && !mask_nmi_hook) || // nmi routine
(bus.a == 16'h04C6) || // tape save routine
(bus.a == 16'h0562) // tape load and verify routine
) begin
automap_next <= 1'b1;
end
else if (bus.a_reg[15:8] == 8'h3D) begin // tr-dos mapping area
else if (bus.a[15:8] == 8'h3D) begin // tr-dos mapping area
automap_next <= 1'b1;
automap0 <= 1'b1;
end
@ -66,15 +65,15 @@ always @(posedge clk28 or negedge rst_n) begin
end
// #3Dxx entrypoint is critical for timings, so we're arming 'map' signal as soon as possible
assign automap = automap0 || (bus.m1 && bus.memreq && !magic_map && en_hooks && en && !rammap && bus.a_reg[15:8] == 8'h3D);
assign automap = automap0 || (bus.m1 && bus.memreq && !mask_hooks && en_hooks && en && !rammap && bus.a[15:8] == 8'h3D);
reg conmem, mapram;
wire port_e3_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hE3;
wire port_e7_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hE7;
wire port_eb_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hEB;
wire port_57_cs = en_zc && bus.ioreq && bus.a_reg[7:0] == 8'h57;
wire port_77_cs = en_zc && bus.ioreq && bus.a_reg[7:0] == 8'h77;
wire port_e3_cs = en && bus.ioreq && bus.a[7:0] == 8'hE3;
wire port_e7_cs = en && bus.ioreq && bus.a[7:0] == 8'hE7;
wire port_eb_cs = en && bus.ioreq && bus.a[7:0] == 8'hEB;
wire port_57_cs = en_zc && bus.ioreq && bus.a[7:0] == 8'h57;
wire port_77_cs = en_zc && bus.ioreq && bus.a[7:0] == 8'h77;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
page <= 0;
@ -84,15 +83,15 @@ always @(posedge clk28 or negedge rst_n) begin
end
else begin
if (port_e3_cs && bus.wr) begin
page <= bus.d_reg[3:0];
mapram <= bus.d_reg[6] | mapram;
conmem <= bus.d_reg[7];
page <= bus.d[3:0];
mapram <= bus.d[6] | mapram;
conmem <= bus.d[7];
end
if (port_e7_cs && bus.wr) begin
sd_cs <= bus.d_reg[0];
sd_cs <= bus.d[0];
end
else if (port_77_cs && bus.wr) begin
sd_cs <= bus.d_reg[1] | ~bus.d_reg[0];
sd_cs <= bus.d[1] | ~bus.d[0];
end
end
end
@ -138,7 +137,7 @@ always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
spi_reg <= 0;
else if ((port_eb_cs || port_57_cs) && bus.wr)
spi_reg <= bus.d_reg;
spi_reg <= bus.d;
else if (spi_cnt[3] == 1'b0 && ck7)
spi_reg[7:0] <= {spi_reg[6:0], sd_miso};
end
@ -151,12 +150,12 @@ end
assign map = automap | conmem;
assign ram =
(automap && bus.a[13]) ||
(conmem && bus.a[13]) ||
(automap && bus.a_raw[13]) ||
(conmem && bus.a_raw[13]) ||
(!conmem && automap && mapram);
assign ramwr_mask =
!bus.a[15] && !bus.a[14] &&
(!bus.a[13] || page == 4'b0011) &&
!bus.a_raw[15] && !bus.a_raw[14] &&
(!bus.a_raw[13] || page == 4'b0011) &&
!conmem && automap && mapram;
assign d_out_active = zc_rd | spi_rd;

View File

@ -32,14 +32,16 @@ module magic(
output reg soundrive_en
);
localparam magic_on_start = 1'b1;
reg magic_unmap_next;
reg magic_map_next;
reg magic_map0;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
n_nmi <= 1'b1;
magic_mode <= 1'b1;
magic_map0 <= 1'b1;
magic_mode <= magic_on_start;
magic_map0 <= magic_on_start;
magic_map_next <= 0;
magic_unmap_next <= 0;
end
@ -50,11 +52,11 @@ always @(posedge clk28 or negedge rst_n) begin
magic_mode <= 1'b1;
end
if (magic_map0 && bus.memreq && bus.rd && bus.a_reg == 16'hf000 && !magic_map_next) begin
if (magic_map0 && bus.memreq && bus.rd && bus.a == 16'hf000 && !magic_map_next) begin
magic_unmap_next <= 1'b1;
magic_mode <= 1'b0;
end
else if (magic_map0 && bus.memreq && bus.rd && bus.a_reg == 16'hf008) begin
else if (magic_map0 && bus.memreq && bus.rd && bus.a == 16'hf008) begin
magic_unmap_next <= 1'b1;
magic_map_next <= 1'b1;
end
@ -62,7 +64,7 @@ always @(posedge clk28 or negedge rst_n) begin
magic_map0 <= 1'b0;
magic_unmap_next <= 1'b0;
end
else if (magic_mode && bus.m1 && bus.memreq && (bus.a_reg == 16'h0066 || magic_map_next)) begin
else if (magic_mode && bus.m1 && bus.memreq && (bus.a == 16'h0066 || magic_map_next)) begin
n_nmi <= 1'b1;
magic_map0 <= 1'b1;
magic_map_next <= 1'b0;
@ -71,11 +73,11 @@ always @(posedge clk28 or negedge rst_n) begin
end
// this signal is critical for timings, so we're arming it as soon as possible
assign magic_map = magic_map0 || (magic_mode && bus.m1 && bus.memreq && (bus.a_reg == 16'h0066 || magic_map_next) && !magic_unmap_next);
assign magic_map = magic_map0 || (magic_mode && bus.m1 && bus.memreq && (bus.a == 16'h0066 || magic_map_next) && !magic_unmap_next);
/* MAGIC CONFIG */
wire config_cs = magic_map && bus.ioreq && bus.a_reg[7:0] == 8'hFF;
wire config_cs = magic_map && bus.ioreq && bus.a[7:0] == 8'hFF;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
magic_reboot <= 0;
@ -91,16 +93,16 @@ always @(posedge clk28 or negedge rst_n) begin
covox_en <= 1'b1;
soundrive_en <= 1'b1;
end
else if (config_cs && bus.wr) case (bus.a_reg[15:8])
8'h01: {magic_reboot, magic_beeper} <= bus.d_reg[1:0];
8'h02: machine <= machine_t'(bus.d_reg[2:0]);
8'h03: turbo <= turbo_t'(bus.d_reg[2:0]);
8'h04: panning <= panning_t'(bus.d_reg[1:0]);
8'h07: joy_sinclair <= bus.d_reg[0];
8'h08: ay_en <= bus.d_reg[0];
8'h09: {zc_en, divmmc_en} <= bus.d_reg[1:0];
8'h0a: ulaplus_en <= bus.d_reg[0];
8'h0b: {soundrive_en, covox_en} <= bus.d_reg[1:0];
else if (config_cs && bus.wr) case (bus.a[15:8])
8'h01: {magic_reboot, magic_beeper} <= bus.d[1:0];
8'h02: machine <= machine_t'(bus.d[2:0]);
8'h03: turbo <= turbo_t'(bus.d[2:0]);
8'h04: panning <= panning_t'(bus.d[1:0]);
8'h07: joy_sinclair <= bus.d[0];
8'h08: ay_en <= bus.d[0];
8'h09: {zc_en, divmmc_en} <= bus.d[1:0];
8'h0A: ulaplus_en <= bus.d[0];
8'h0B: {soundrive_en, covox_en} <= bus.d[1:0];
endcase
end
@ -110,7 +112,7 @@ always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
config_rd <= 0;
else
config_rd <= config_cs && bus.rd && bus.a_reg[15:8] == 8'h00;
config_rd <= config_cs && bus.rd && bus.a[15:8] == 8'h00;
end

106
fpga/rtl/mem.sv Normal file
View File

@ -0,0 +1,106 @@
import common::*;
module mem(
input clk28,
cpu_bus bus,
output [18:0] va,
inout [7:0] vd,
output n_vrd,
output n_vwr,
input machine_t machine,
input magic_map,
input [2:0] ram_page128,
input rom_page128,
input [2:0] port_1ffd,
input [4:0] port_dffd,
input [2:0] ram_pageext,
input div_ram,
input div_map,
input div_ramwr_mask,
input [3:0] div_page,
input snow,
input video_page,
input video_read_req,
input [14:0] video_read_addr,
input [16:0] rom2ram_ram_address,
input rom2ram_ram_wren,
input [7:0] rom2ram_dataout,
input magic_dout_active,
input [7:0] magic_dout,
input up_dout_active,
input [7:0] up_dout,
input div_dout_active,
input [7:0] div_dout,
input turbosound_dout_active,
input [7:0] turbosound_dout,
input ports_dout_active,
input [7:0] ports_dout
);
/* VA[18:13] map
* 00xxxx 112Kb of roms
* 00111x 16Kb of magic ram
* 01xxxx 128Kb of divmmc memory
* 10xxxx 128Kb of extended ram (via port dffd)
* 11xxxx 128Kb of main ram
*/
reg romreq, ramreq, ramreq_wr;
reg [18:13] va_18_13;
wire [15:0] a = bus.a_raw[15:0];
always @(negedge clk28) begin
romreq = bus.mreq && a[15:14] == 2'b00 &&
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd[4] && !port_1ffd[0]));
ramreq = bus.mreq && !romreq;
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
if (romreq) va_18_13 =
(magic_map) ? {5'd2, 1'b0} :
(div_map) ? {5'd2, 1'b1} :
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rom_page128 == 1'b0) ? {5'd4, a[13]} :
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rom_page128 == 1'b1) ? {5'd5, a[13]} :
(machine == MACHINE_S3 && port_1ffd[2] == 1'b1 && rom_page128 == 1'b0) ? {5'd6, a[13]} :
(machine == MACHINE_S48) ? {5'd3, a[13]} :
(rom_page128 == 1'b1) ? {5'd1, a[13]} :
{5'd0, a[13]} ;
else va_18_13 =
(magic_map && a[15:14] == 2'b11) ? {2'b00, 3'b111, a[13]} :
(magic_map) ? {3'b111, video_page, a[14:13]} :
(div_map && a[15:13] == 3'b001) ? {2'b01, div_page} :
(div_map && a[15:14] == 2'b00) ? {2'b01, 4'b0011} :
(port_dffd[3] & a[15]) ? {2'b11, a[14], a[15], a[14], a[13]} :
(port_dffd[3] & a[14]) ? {1'b1, ~ram_pageext[0], ram_page128, a[13]} :
(port_1ffd[2] == 1'b0 && port_1ffd[0] == 1'b1) ? {2'b11, port_1ffd[1], a[15], a[14], a[13]} :
(port_1ffd == 3'b101) ? {2'b11, ~(a[15] & a[14]), a[15], a[14], a[13]} :
(port_1ffd == 3'b111) ? {2'b11, ~(a[15] & a[14]), (a[15] | a[14]), a[14], a[13]} :
(a[15:14] == 2'b11) ? {1'b1, ~ram_pageext[0], ram_page128, a[13]} :
{2'b11, a[14], a[15], a[14], a[13]} ;
end
assign n_vrd = (((bus.mreq && bus.rd) || video_read_req) && !rom2ram_ram_wren)? 1'b0 : 1'b1;
assign n_vwr = ((ramreq_wr && bus.wr && !video_read_req) || rom2ram_ram_wren)? 1'b0 : 1'b1;
assign va[18:0] =
(rom2ram_ram_wren) ? {2'b00, rom2ram_ram_address} :
(video_read_req && snow) ? {3'b111, video_page, video_read_addr[14:8], {8{1'bz}}} :
(video_read_req) ? {3'b111, video_page, video_read_addr} :
{va_18_13, {13{1'bz}}};
assign vd[7:0] =
~n_vrd ? {8{1'bz}} :
bus.wr ? {8{1'bz}} :
rom2ram_ram_wren ? rom2ram_dataout :
magic_dout_active ? magic_dout :
up_dout_active ? up_dout :
div_dout_active ? div_dout :
turbosound_dout_active ? turbosound_dout :
ports_dout_active ? ports_dout :
(bus.m1 && bus.iorq) ? 8'hFF :
bus.rd ? 8'hFF :
{8{1'bz}} ;
endmodule

View File

@ -1,107 +0,0 @@
import common::*;
module memcontrol(
input clk28,
cpu_bus bus,
output [18:0] va,
inout [7:0] vd,
output n_vrd,
output n_vwr,
input machine_t machine,
input screenpage,
input screen_fetch,
input screen_fetch_up,
input snow,
input [14:0] screen_addr,
input magic_map,
input [2:0] rampage128,
input rompage128,
input [2:0] port_1ffd,
input [4:0] port_dffd,
input [2:0] rampage_ext,
input divmmc_en,
input div_ram,
input div_map,
input div_ramwr_mask,
input [3:0] div_page,
input [16:0] rom2ram_ram_address,
input rom2ram_ram_wren,
input [7:0] rom2ram_dataout,
input magic_dout_active,
input [7:0] magic_dout,
input up_dout_active,
input [7:0] up_dout,
input div_dout_active,
input [7:0] div_dout,
input turbosound_dout_active,
input [7:0] turbosound_dout,
input ports_dout_active,
input [7:0] ports_dout
);
/* VA[18:13] map
* 00xxxx 112Kb of roms
* 00111x 16Kb of magic ram
* 01xxxx 128Kb of divmmc memory
* 10xxxx 128Kb of extended ram (via port dffd)
* 11xxxx 128Kb of main ram
*/
reg romreq, ramreq, ramreq_wr;
reg [18:13] va_18_13;
always @(negedge clk28) begin
romreq = bus.mreq && bus.a[15:14] == 2'b00 &&
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd[4] && !port_1ffd[0]));
ramreq = bus.mreq && !romreq;
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
if (romreq) va_18_13 = {2'd0,
magic_map? {3'd2, 1'b0} :
div_map? {3'd2, 1'b1} :
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b0)? {3'd4, bus.a[13]} :
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b1)? {3'd5, bus.a[13]} :
(machine == MACHINE_S3 && port_1ffd[2] == 1'b1 && rompage128 == 1'b0)? {3'd6, bus.a[13]} :
(machine == MACHINE_S48)? {3'd3, bus.a[13]} :
(rompage128 == 1'b1)? {3'd1, bus.a[13]} :
{3'd0, bus.a[13]} };
else va_18_13 =
magic_map & bus.a[15] & bus.a[14]? {2'b00, 3'b111, bus.a[13]} :
magic_map? {3'b111, screenpage, bus.a[14:13]} :
div_map & ~bus.a[15] & ~bus.a[14] & bus.a[13]? {2'b01, div_page} :
div_map & ~bus.a[15] & ~bus.a[14]? {2'b01, 4'b0011} :
port_dffd[3] & bus.a[15]? {2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} :
port_dffd[3] & bus.a[14]? {1'b1, ~rampage_ext[0], rampage128, bus.a[13]} :
(port_1ffd[2] == 1'b0 && port_1ffd[0] == 1'b1)? {2'b11, port_1ffd[1], bus.a[15], bus.a[14], bus.a[13]} :
(port_1ffd == 3'b101)? {2'b11, ~(bus.a[15] & bus.a[14]), bus.a[15], bus.a[14], bus.a[13]} :
(port_1ffd == 3'b111)? {2'b11, ~(bus.a[15] & bus.a[14]), (bus.a[15] | bus.a[14]), bus.a[14], bus.a[13]} :
bus.a[15] & bus.a[14]? {1'b1, ~rampage_ext[0], rampage128, bus.a[13]} :
{2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} ;
end
assign n_vrd = (((bus.mreq && bus.rd) || screen_fetch) && !rom2ram_ram_wren)? 1'b0 : 1'b1;
assign n_vwr = ((ramreq_wr && bus.wr && !screen_fetch) || rom2ram_ram_wren)? 1'b0 : 1'b1;
assign va[18:0] =
rom2ram_ram_wren? {2'b00, rom2ram_ram_address} :
screen_fetch && snow? {3'b111, screenpage, screen_addr[14:8], {8{1'bz}}} :
screen_fetch? {3'b111, screenpage, screen_addr} :
{va_18_13, {13{1'bz}}};
assign vd[7:0] =
~n_vrd? {8{1'bz}} :
bus.wr? {8{1'bz}} :
rom2ram_ram_wren? rom2ram_dataout :
magic_dout_active? magic_dout :
up_dout_active? up_dout :
div_dout_active? div_dout :
turbosound_dout_active? turbosound_dout :
ports_dout_active? ports_dout :
(bus.m1 && bus.iorq)? 8'hFF :
bus.rd? 8'hFF :
{8{1'bz}};
endmodule

View File

@ -20,10 +20,10 @@ module ports(
output reg tape_out,
output reg beeper,
output reg [2:0] border,
output reg screenpage,
output reg rompage128,
output reg [2:0] rampage128,
output reg [2:0] rampage_ext,
output reg video_page,
output reg rom_page128,
output reg [2:0] ram_page128,
output reg [2:0] ram_pageext,
output reg [2:0] port_1ffd,
output reg [4:0] port_dffd
@ -37,12 +37,12 @@ always @(posedge clk28 or negedge rst_n) begin
port_ff_rd <= 0;
else
port_ff_rd <= bus.rd && bus.ioreq && !magic_map && port_ff_active &&
(machine != MACHINE_S3) && (machine != MACHINE_PENT || bus.a_reg[7:0] == 8'hFF);
(machine != MACHINE_S3) && (machine != MACHINE_PENT || bus.a[7:0] == 8'hFF);
end
/* PORT #FE */
wire port_fe_cs = bus.ioreq && bus.a_reg[0] == 0;
wire port_fe_cs = bus.ioreq && bus.a[0] == 0;
reg port_fe_rd;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
@ -60,9 +60,9 @@ always @(negedge clk28 or negedge rst_n) begin
border <= 0;
end
else if (port_fe_cs && bus.wr) begin
beeper <= bus.d_reg[4];
tape_out <= bus.d_reg[3];
border <= bus.d_reg[2:0];
beeper <= bus.d[4];
tape_out <= bus.d[3];
border <= bus.d[2:0];
end
end
@ -72,8 +72,8 @@ always @(posedge clk28 or negedge rst_n) begin
end
else if (en_sinclair) begin
kd0 <= kd
& (bus.a_reg[12] == 0? {~kempston_data[1], ~kempston_data[0], ~kempston_data[2], ~kempston_data[3], ~kempston_data[4]} : 5'b11111) // 6-0 keys
& (bus.a_reg[15] == 0? {1'b1, ~kempston_data[6], ~kempston_data[5], 2'b11} : 5'b11111 ) ; // b-space keys
& (bus.a[12] == 0? {~kempston_data[1], ~kempston_data[0], ~kempston_data[2], ~kempston_data[3], ~kempston_data[4]} : 5'b11111) // 6-0 keys
& (bus.a[15] == 0? {1'b1, ~kempston_data[6], ~kempston_data[5], 2'b11} : 5'b11111 ) ; // b-space keys
end
else begin
kd0 <= kd;
@ -83,49 +83,49 @@ end
/* PORT #7FFD */
reg lock_7ffd;
wire port_7ffd_cs = bus.ioreq && bus.a_reg[1] == 0 && bus.a_reg[15] == 0 &&
(bus.a_reg[14] == 1'b1 || (!magic_map && machine != MACHINE_S3)) &&
wire port_7ffd_cs = bus.ioreq && bus.a[1] == 0 && bus.a[15] == 0 &&
(bus.a[14] == 1'b1 || (!magic_map && machine != MACHINE_S3)) &&
(machine != MACHINE_S48 || magic_map) &&
(lock_7ffd == 0 || port_dffd[4] == 1'b1);
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
rampage128 <= 0;
screenpage <= 0;
rompage128 <= 0;
ram_page128 <= 0;
video_page <= 0;
rom_page128 <= 0;
lock_7ffd <= 0;
end
else if (port_7ffd_cs && bus.wr) begin
rampage128 <= bus.d_reg[2:0];
screenpage <= bus.d_reg[3];
rompage128 <= bus.d_reg[4];
lock_7ffd <= bus.d_reg[5];
ram_page128 <= bus.d[2:0];
video_page <= bus.d[3];
rom_page128 <= bus.d[4];
lock_7ffd <= bus.d[5];
end
end
/* PORT #DFFD */
wire port_dffd_cs = bus.ioreq && bus.a_reg == 16'hDFFD && (machine == MACHINE_PENT || magic_map);
wire port_dffd_cs = bus.ioreq && bus.a == 16'hDFFD && (machine == MACHINE_PENT || magic_map);
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
rampage_ext <= 0;
ram_pageext <= 0;
port_dffd <= 0;
end
else if (port_dffd_cs && bus.wr) begin
rampage_ext <= bus.d_reg[2:0];
port_dffd <= bus.d_reg[4:0];
ram_pageext <= bus.d[2:0];
port_dffd <= bus.d[4:0];
end
end
/* PORT #1FFD */
wire port_1ffd_cs = bus.ioreq && bus.a_reg[15:12] == 4'b0001 && !bus.a_reg[1] &&
wire port_1ffd_cs = bus.ioreq && bus.a[15:12] == 4'b0001 && !bus.a[1] &&
(machine == MACHINE_S3 || magic_map);
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
port_1ffd <= 0;
end
else if (port_1ffd_cs && bus.wr) begin
port_1ffd <= bus.d_reg[2:0];
port_1ffd <= bus.d[2:0];
end
end
@ -136,7 +136,7 @@ always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
kempston_rd <= 0;
else
kempston_rd <= en_kempston && bus.ioreq && bus.rd && bus.a_reg[5:0] == 6'h1F;
kempston_rd <= en_kempston && bus.ioreq && bus.rd && bus.a[5:0] == 6'h1F;
end

View File

@ -14,12 +14,12 @@ module soundrive(
output reg [7:0] ch_r1
);
wire covox_cs = en_covox && bus.ioreq && bus.a_reg[7:0] == 8'hFB;
wire specdrum_cs = en_specdrum && bus.ioreq && bus.a_reg[7:0] == 8'hDF;
wire soundrive_a_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h0F;
wire soundrive_b_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h1F;
wire soundrive_c_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h4F;
wire soundrive_d_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h5F;
wire covox_cs = en_covox && bus.ioreq && bus.a[7:0] == 8'hFB;
wire specdrum_cs = en_specdrum && bus.ioreq && bus.a[7:0] == 8'hDF;
wire soundrive_a_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h0F;
wire soundrive_b_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h1F;
wire soundrive_c_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h4F;
wire soundrive_d_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h5F;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
@ -30,13 +30,13 @@ always @(posedge clk28 or negedge rst_n) begin
end
else begin
if ((covox_cs || specdrum_cs || soundrive_a_cs) && bus.wr)
ch_l0 <= bus.d_reg;
ch_l0 <= bus.d;
if ((covox_cs || specdrum_cs || soundrive_b_cs) && bus.wr)
ch_l1 <= bus.d_reg;
ch_l1 <= bus.d;
if ((covox_cs || specdrum_cs || soundrive_c_cs) && bus.wr)
ch_r0 <= bus.d_reg;
ch_r0 <= bus.d;
if ((covox_cs || specdrum_cs || soundrive_d_cs) && bus.wr)
ch_r1 <= bus.d_reg;
ch_r1 <= bus.d;
end
end

View File

@ -58,36 +58,30 @@ wire ps2_key_reset, ps2_key_pause;
wire [2:0] border;
wire magic_reboot, magic_beeper;
wire up_active;
wire clkwait;
wire [2:0] rampage128;
wire clkcpu_stall;
wire [2:0] ram_page128;
wire init_done;
wire screen_fetch, screen_fetch_next;
wire video_read_req, video_read_req_next;
/* CPU BUS */
cpu_bus bus();
reg bus_memreq, bus_ioreq;
wire mem_bus_valid = !video_read_req && !video_read_req_next;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
bus_ioreq <= 0;
bus_memreq <= 0;
end
else if (!screen_fetch && !screen_fetch_next) begin
bus.a_reg <= {a[15:13], va[12:0]};
bus.d_reg <= vd;
bus_ioreq <= n_iorq == 1'b0 && n_m1 == 1'b1;
bus_memreq <= n_mreq == 1'b0 && n_rfsh == 1'b1;
end
else begin
if (n_iorq)
bus_ioreq <= 0;
if (n_mreq)
bus_memreq <= 0;
bus.a <= mem_bus_valid? {a[15:13], va[12:0]} : bus.a;
bus.d <= mem_bus_valid? vd : bus.d;
bus_ioreq <= (mem_bus_valid | bus_ioreq) & ~n_iorq & n_m1;
bus_memreq <= (mem_bus_valid | bus_memreq) & ~n_mreq & n_rfsh;
end
end
always @(posedge clk168) begin
bus.a <= {a[15:13], va[12:0]};
bus.d <= vd;
bus.a_raw <= {a[15:13], va[12:0]};
bus.iorq <= ~n_iorq;
bus.mreq <= ~n_mreq;
bus.m1 <= ~n_m1;
@ -106,25 +100,23 @@ always @(posedge clk28) begin
end
/* SCREEN CONTROLLER */
wire blink;
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0]};
/* VIDEO CONTROLLER */
wire [5:0] r, g, b;
wire hsync, vsync, csync0;
wire screen_contention, port_ff_active;
wire [14:0] screen_addr;
wire video_contention, port_ff_active;
wire [14:0] video_read_addr;
wire [5:0] up_ink_addr, up_paper_addr;
wire [7:0] up_ink, up_paper;
wire [7:0] up_ink_data, up_paper_data;
wire [8:0] vc, hc;
wire [7:0] port_ff_data;
wire clk14, clk7, clk35, ck14, ck7, ck35;
screen screen0(
video video0(
.rst_n(usrrst_n),
.clk28(clk28),
.machine(machine),
.turbo(turbo),
.border(screen_border),
.border({border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0]}),
.r(r),
.g(g),
@ -133,20 +125,19 @@ screen screen0(
.vsync(vsync),
.hsync(hsync),
.fetch_allow((!bus.iorq && !bus.mreq) || bus.rfsh || (clkwait && turbo == TURBO_NONE)),
.fetch(screen_fetch),
.addr(screen_addr),
.fetch_next(screen_fetch_next),
.fetch_data(bus.d),
.read_allow((!bus.iorq && !bus.mreq) || bus.rfsh || (clkcpu_stall && turbo == TURBO_NONE)),
.read_req(video_read_req),
.read_req_next(video_read_req_next),
.read_req_addr(video_read_addr),
.read_data(vd),
.up_en(up_active),
.up_ink_addr(up_ink_addr),
.up_ink_data(up_ink_data),
.up_paper_addr(up_paper_addr),
.up_ink(up_ink),
.up_paper(up_paper),
.up_paper_data(up_paper_data),
.contention(screen_contention),
.blink(blink),
.contention(video_contention),
.port_ff_active(port_ff_active),
.port_ff_data(port_ff_data),
@ -184,7 +175,7 @@ ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
.clk(clk28),
.ps2_clk_in(ps2_clk),
.ps2_dat_in(ps2_dat),
.zxkb_addr(bus.a_reg[15:8]),
.zxkb_addr(bus.a[15:8]),
.zxkb_data(ps2_kd),
.key_magic(ps2_key_magic),
.key_reset(ps2_key_reset),
@ -199,7 +190,7 @@ ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
/* CPU CONTROLLER */
wire n_int_next, clkcpu_ck, snow;
cpucontrol cpucontrol0(
cpu cpu0(
.rst_n(usrrst_n),
.clk28(clk28),
.clk14(clk14),
@ -212,16 +203,16 @@ cpucontrol cpucontrol0(
.vc(vc),
.hc(hc),
.rampage128(rampage128),
.ram_page128(ram_page128),
.machine(machine),
.turbo(turbo),
.screen_contention(screen_contention),
.video_contention(video_contention),
.init_done_in(init_done),
.n_rstcpu(n_rstcpu),
.n_rstcpu_out(n_rstcpu),
.clkcpu(clkcpu),
.clkcpu_ck(clkcpu_ck),
.clkwait(clkwait),
.clkcpu_stall(clkcpu_stall),
.n_int(n_int),
.n_int_next(n_int_next),
.snow(snow)
@ -275,9 +266,9 @@ magic magic0(
wire [7:0] ports_dout;
wire ports_dout_active;
wire beeper, tape_out;
wire screenpage;
wire rompage128;
wire [2:0] rampage_ext;
wire video_page;
wire rom_page128;
wire [2:0] ram_pageext;
wire [2:0] port_1ffd;
wire [4:0] port_dffd;
ports ports0 (
@ -302,10 +293,10 @@ ports ports0 (
.tape_out(tape_out),
.beeper(beeper),
.border(border),
.screenpage(screenpage),
.rompage128(rompage128),
.rampage128(rampage128),
.rampage_ext(rampage_ext),
.video_page(video_page),
.rom_page128(rom_page128),
.ram_page128(ram_page128),
.ram_pageext(ram_pageext),
.port_1ffd(port_1ffd),
.port_dffd(port_dffd)
);
@ -338,7 +329,7 @@ turbosound turbosound0(
/* COVOX & SOUNDRIVE */
wire [7:0] soundrive_l0, soundrive_l1, soundrive_r0, soundrive_r1;
soundrive soundrive0(
.rst_n(usrrst_n),
.rst_n(n_rstcpu),
.clk28(clk28),
.en_covox(covox_en),
.en_specdrum(covox_en),
@ -405,8 +396,8 @@ divmmc divmmc0(
.sd_cs(sd_cs),
.rammap(port_dffd[4] | port_1ffd[0]),
.magic_mode(magic_mode),
.magic_map(magic_map),
.mask_hooks(magic_map),
.mask_nmi_hook(magic_mode),
.page(div_page),
.map(div_map),
@ -430,10 +421,10 @@ ulaplus ulaplus0(
.d_out_active(up_dout_active),
.active(up_active),
.ink_addr(up_ink_addr),
.paper_addr(up_paper_addr),
.ink(up_ink),
.paper(up_paper)
.read_addr1(up_ink_addr),
.read_data1(up_ink_data),
.read_addr2(up_paper_addr),
.read_data2(up_paper_data)
);
@ -483,7 +474,7 @@ asmi asmi0(
/* MEMORY CONTROLLER */
memcontrol memcontrol0(
mem mem0(
.clk28(clk28),
.bus(bus),
.va(va),
@ -492,25 +483,26 @@ memcontrol memcontrol0(
.n_vwr(n_vwr),
.machine(machine),
.screenpage(screenpage),
.screen_fetch(screen_fetch),
.snow(snow),
.screen_addr(screen_addr),
.magic_map(magic_map),
.rampage128(rampage128),
.rompage128(rompage128),
.ram_page128(ram_page128),
.rom_page128(rom_page128),
.port_1ffd(port_1ffd),
.port_dffd(port_dffd),
.rampage_ext(rampage_ext),
.divmmc_en(divmmc_en),
.ram_pageext(ram_pageext),
.div_ram(div_ram),
.div_map(div_map),
.div_ramwr_mask(div_ramwr_mask),
.div_page(div_page),
.snow(snow),
.video_page(video_page),
.video_read_req(video_read_req),
.video_read_addr(video_read_addr),
.rom2ram_ram_address(rom2ram_ram_address),
.rom2ram_ram_wren(rom2ram_ram_wren),
.rom2ram_dataout(rom2ram_dataout),
.magic_dout_active(magic_dout_active),
.magic_dout(magic_dout),
.up_dout_active(up_dout_active),

View File

@ -27,8 +27,8 @@ module turbosound(
reg ay_bdir;
reg ay_bc1;
reg ay_sel;
wire port_bffd = en && bus.ioreq && bus.a_reg[15] == 1'b1 && bus.a_reg[1] == 0;
wire port_fffd = en && bus.ioreq && bus.a_reg[15] == 1'b1 && bus.a_reg[14] == 1'b1 && bus.a_reg[1] == 0;
wire port_bffd = en && bus.ioreq && bus.a[15] == 1'b1 && bus.a[1] == 0;
wire port_fffd = en && bus.ioreq && bus.a[15] == 1'b1 && bus.a[14] == 1'b1 && bus.a[1] == 0;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
ay_bc1 <= 0;
@ -40,8 +40,8 @@ always @(posedge clk28 or negedge rst_n) begin
ay_bdir <= port_bffd && bus.wr;
if (!en_ts)
ay_sel <= 0;
else if (bus.ioreq && port_fffd && bus.wr && bus.d_reg[7:3] == 5'b11111)
ay_sel <= bus.d_reg[0];
else if (bus.ioreq && port_fffd && bus.wr && bus.d[7:3] == 5'b11111)
ay_sel <= bus.d[0];
end
end
@ -65,7 +65,7 @@ YM2149 ym2149_0(
.A8(~ay_sel),
.BDIR(ay_bdir),
.BC(ay_bc1),
.DI(bus.d_reg),
.DI(bus.d),
.DO(ay_dout0),
.SEL(1'b0),
.MODE(1'b1),
@ -80,7 +80,7 @@ YM2149 ym2149_1(
.A8(ay_sel),
.BDIR(ay_bdir),
.BC(ay_bc1),
.DI(bus.d_reg),
.DI(bus.d),
.DO(ay_dout1),
.SEL(1'b0),
.MODE(1'b0),

View File

@ -9,15 +9,16 @@ module ulaplus(
output d_out_active,
output reg active,
input [5:0] ink_addr,
input [5:0] paper_addr,
output reg [7:0] ink,
output reg [7:0] paper
input [5:0] read_addr1,
output reg [7:0] read_data1,
input [5:0] read_addr2,
output reg [7:0] read_data2
);
wire port_bf3b_cs = en && bus.ioreq && bus.a_reg == 16'hbf3b;
wire port_ff3b_cs = en && bus.ioreq && bus.a_reg == 16'hff3b;
wire port_bf3b_cs = en && bus.ioreq && bus.a == 16'hbf3b;
wire port_ff3b_cs = en && bus.ioreq && bus.a == 16'hff3b;
reg port_ff3b_rd;
wire [7:0] port_ff3b_data = {7'b0000000, active};
@ -33,9 +34,9 @@ always @(posedge clk28 or negedge rst_n) begin
end
else begin
if (port_bf3b_cs && bus.wr)
addr_reg <= bus.d_reg;
addr_reg <= bus.d;
if (port_ff3b_cs && bus.wr && addr_reg == 8'b01000000)
active <= bus.d_reg[0];
active <= bus.d[0];
write_req <= {write_req[0], port_ff3b_cs && bus.wr && addr_reg[7:6] == 2'b00};
port_ff3b_rd <= port_ff3b_cs && bus.rd;
@ -48,9 +49,9 @@ end
wire write_req0 = write_req[0] && !write_req[1];
reg read_step;
wire [5:0] ram_a = write_req0? addr_reg[5:0] : read_step? ink_addr : paper_addr;
wire [5:0] ram_a = write_req0? addr_reg[5:0] : read_step? read_addr2 : read_addr1;
wire [7:0] ram_q;
ulaplus_ram pallete(ram_q, ram_a, bus.d_reg, write_req0, clk28);
ulaplus_ram pallete(ram_q, ram_a, bus.d, write_req0, clk28);
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
@ -61,9 +62,9 @@ end
always @(posedge clk28) begin
if (read_step)
paper <= ram_q;
read_data1 <= ram_q;
else
ink <= ram_q;
read_data2 <= ram_q;
end

174
fpga/rtl/screen.sv → fpga/rtl/video.sv Executable file → Normal file
View File

@ -1,6 +1,5 @@
`include "util.vh"
import common::*;
module screen(
module video(
input rst_n,
input clk28,
@ -15,23 +14,22 @@ module screen(
output reg hsync,
output reg csync,
input fetch_allow,
output reg fetch,
output fetch_next,
output [14:0] addr,
input [7:0] fetch_data,
input read_allow,
output reg read_req,
output read_req_next,
output [14:0] read_req_addr,
input [7:0] read_data,
output contention,
output blink,
output reg even_line,
output port_ff_active,
output [7:0] port_ff_data,
input up_en,
output [5:0] up_ink_addr,
input [7:0] up_ink_data,
output [5:0] up_paper_addr,
input [7:0] up_ink,
input [7:0] up_paper,
input [7:0] up_paper_data,
output [8:0] hc_out,
output [8:0] vc_out,
@ -43,7 +41,21 @@ module screen(
output ck35
);
/* SCREEN CONTROLLER */
reg [8:0] vc;
reg [10:0] hc0;
wire [8:0] hc = hc0[10:2];
assign vc_out = vc;
assign hc_out = hc;
assign clk14 = hc0[0];
assign clk7 = hc0[1];
assign clk35 = hc0[2];
assign ck14 = hc0[0];
assign ck7 = hc0[0] & hc0[1];
assign ck35 = hc0[0] & hc0[1] & hc0[2];
/* SYNC SIGNALS */
localparam H_AREA = 256;
localparam V_AREA = 192;
localparam SCREEN_DELAY = 13;
@ -81,20 +93,6 @@ localparam V_SYNC_PENT = 8;
localparam V_TBORDER_PENT = 64;
localparam V_TOTAL_PENT = V_AREA + V_BBORDER_PENT + V_SYNC_PENT + V_TBORDER_PENT;
reg [8:0] vc;
reg [10:0] hc0;
wire [8:0] hc = hc0[10:2];
assign vc_out = vc;
assign hc_out = hc;
assign clk14 = hc0[0];
assign clk7 = hc0[1];
assign clk35 = hc0[2];
assign ck14 = hc0[0];
assign ck7 = hc0[0] & hc0[1];
assign ck35 = hc0[0] & hc0[1] & hc0[2];
wire hc0_reset =
(machine == MACHINE_S48)?
hc0 == (H_TOTAL_S48<<2) - 1'b1 :
@ -111,14 +109,11 @@ wire vc_reset =
vc == V_TOTAL_PENT - 1'b1 ;
wire hsync0 =
(machine == MACHINE_S48)?
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) &&
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) :
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) && (hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) :
(machine == MACHINE_S128 || machine == MACHINE_S3)?
(hc >= (H_AREA + H_RBORDER_S128 + H_BLANK1_S128)) &&
(hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128)) :
(hc >= (H_AREA + H_RBORDER_S128 + H_BLANK1_S128)) && (hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128)) :
// Pentagon
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) &&
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) ;
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) && (hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) ;
wire vsync0 =
(machine == MACHINE_S48)?
(vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48)) :
@ -140,7 +135,6 @@ wire blank =
((hc >= (H_AREA + H_RBORDER_PENT)) &&
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT + H_BLANK2_PENT))) ;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
hc0 <= 0;
@ -160,9 +154,8 @@ always @(posedge clk28 or negedge rst_n) begin
end
end
reg [4:0] blink_cnt;
assign blink = blink_cnt[$bits(blink_cnt)-1];
wire blink = blink_cnt[$bits(blink_cnt)-1];
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
blink_cnt <= 0;
@ -181,12 +174,25 @@ always @(posedge clk28 or negedge rst_n) begin
end
/* SCREEN CONTROLLER */
wire screen_show = (vc < V_AREA) && (hc0 >= (SCREEN_DELAY<<2) - 1) && (hc0 < ((H_AREA + SCREEN_DELAY)<<2) - 1);
wire screen_update = hc0[4:0] == 5'b10011;
wire border_update = (hc0[4:0] == 5'b10011) || (machine == MACHINE_PENT && ck7);
wire bitmap_shift = hc0[1:0] == 2'b11;
wire next_addr = hc0[4:0] == 5'b10000;
reg screen_read, up_read;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
screen_read <= 0;
up_read <= 0;
end
else begin
screen_read <= (vc < V_AREA) && (hc0 > 15) && (hc0 < (H_AREA<<2) + 17);
up_read <= screen_read && (screen_update || up_read);
end
end
reg [7:0] vaddr;
reg [7:3] haddr;
always @(posedge clk28 or negedge rst_n) begin
@ -200,71 +206,59 @@ always @(posedge clk28 or negedge rst_n) begin
end
end
reg loading, loading_up;
reg [7:0] bitmap, attr, bitmap_next, attr_next;
reg [7:0] up_ink, up_paper;
reg [1:0] read_cnt;
localparam READ_CYCLES = 2'd2;
assign read_req_next = screen_read && (read_allow || (|read_cnt && read_cnt != READ_CYCLES && turbo == TURBO_14));
reg read_step;
assign read_req_addr = (read_step == 1'd0)?
{ 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } :
{ 5'b10110, vaddr[7:3], haddr[7:3] };
assign up_ink_addr = up_read? { attr_next[7:6], 1'b0, attr_next[2:0] } : { 3'b0, border[2:0] };
assign up_paper_addr = up_read? { attr_next[7:6], 1'b1, attr_next[5:3] } : { 3'b0, border[2:0] };
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
loading <= 0;
loading_up <= 0;
read_req <= 0;
read_step <= 0;
read_cnt <= 0;
attr_next <= 0;
bitmap_next <= 0;
end
else begin
loading <= (vc < V_AREA) && (hc0 > 15) && (hc0 < (H_AREA<<2) + 17);
loading_up <= loading && (screen_update || loading_up);
read_req <= read_req_next;
if (read_cnt == READ_CYCLES) begin
if (read_step == 1'd1)
attr_next <= read_data;
if (read_step == 1'd0)
bitmap_next <= read_data;
read_step <= read_step + 1'b1;
read_cnt <= 0;
end
else if (read_req && read_req_next && !next_addr) begin
read_cnt <= read_cnt + 1'b1;
end
else begin
read_cnt <= 0;
end
end
end
wire [7:0] attr_border = {2'b00, border[2:0], border[2:0]};
reg [7:0] bitmap, attr, bitmap_next, attr_next;
reg [7:0] up_ink0, up_paper0;
reg [1:0] fetch_cnt;
localparam FETCH_CYCLES = 2'd2;
assign fetch_next = loading && (fetch_allow || (|fetch_cnt && fetch_cnt != FETCH_CYCLES && turbo == TURBO_14));
reg fetch_step;
wire fetch_bitmap = fetch && fetch_step == 1'd0 && fetch_cnt == FETCH_CYCLES;
wire fetch_attr = fetch && fetch_step == 1'd1 && fetch_cnt == FETCH_CYCLES;
assign addr = (fetch_step == 1'd0)?
{ 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } :
{ 5'b10110, vaddr[7:3], haddr[7:3] };
assign up_ink_addr = loading_up? { attr_next[7:6], 1'b0, attr_next[2:0] } : { 3'b0, attr_border[2:0] };
assign up_paper_addr = loading_up? { attr_next[7:6], 1'b1, attr_next[5:3] } : { 3'b0, attr_border[2:0] };
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
fetch <= 0;
fetch_step <= 0;
fetch_cnt <= 0;
attr <= 0;
bitmap <= 0;
attr_next <= 0;
bitmap_next <= 0;
up_ink0 <= 0;
up_paper0 <= 0;
up_ink <= 0;
up_paper <= 0;
end
else begin
fetch <= fetch_next;
if (fetch_cnt == FETCH_CYCLES) begin
if (fetch_step == 1'd1)
attr_next <= fetch_data;
if (fetch_step == 1'd0)
bitmap_next <= fetch_data;
fetch_step <= fetch_step + 1'b1;
fetch_cnt <= 0;
end
else if (fetch && fetch_next && !next_addr) begin
fetch_cnt <= fetch_cnt + 1'b1;
end
else begin
fetch_cnt <= 0;
end
if (screen_show && screen_update)
attr <= attr_next;
else if (!screen_show && border_update)
attr <= attr_border;
attr <= {2'b00, border[2:0], border[2:0]};
if (screen_update)
bitmap <= bitmap_next;
@ -272,9 +266,9 @@ always @(posedge clk28 or negedge rst_n) begin
bitmap <= {bitmap[6:0], 1'b0};
if (screen_update)
up_ink0 <= up_ink;
up_ink <= up_ink_data;
if (screen_update)
up_paper0 <= up_paper;
up_paper <= up_paper_data;
end
end
@ -282,7 +276,7 @@ end
/* ATTRIBUTE PORT */
wire port_ff_attr = (machine == MACHINE_PENT) || hc[3:1] == 3'h6 || hc[3:1] == 3'h0;
wire port_ff_bitmap = (hc[3] && hc[1]);
assign port_ff_active = loading && (port_ff_attr || port_ff_bitmap);
assign port_ff_active = screen_read && (port_ff_attr || port_ff_bitmap);
assign port_ff_data =
port_ff_attr? attr_next :
port_ff_bitmap? bitmap_next :
@ -291,15 +285,15 @@ assign port_ff_data =
assign contention = (vc < V_AREA) && (hc < H_AREA) && (hc[2] || hc[3]);
/* RGBS generation */
/* RGBS OUTPUT */
wire pixel = bitmap[7];
always @(posedge clk28) begin
if (blank)
{g, r, b} = 0;
else if (up_en) begin
g[5:3] = pixel? up_ink0[7:5] : up_paper0[7:5];
r[5:3] = pixel? up_ink0[4:2] : up_paper0[4:2];
b[5:4] = pixel? up_ink0[1:0] : up_paper0[1:0];
g[5:3] = pixel? up_ink[7:5] : up_paper[7:5];
r[5:3] = pixel? up_ink[4:2] : up_paper[4:2];
b[5:4] = pixel? up_ink[1:0] : up_paper[1:0];
g[2:0] = g[5:3];
r[2:0] = r[5:3];
b[3:0] = {b[5:4], b[5:4]};

View File

@ -1,7 +1,7 @@
create_clock -period 28MHz -name {clk28} [get_ports {clk_in}]
create_generated_clock -name {clkcpu} -divide_by 2 -source [get_ports {clk_in}] [get_registers {cpucontrol:cpucontrol0|clkcpu}]
create_generated_clock -name {hc0[1]} -divide_by 4 -source [get_ports {clk_in}] [get_registers {screen:screen0|hc0[1]}]
create_generated_clock -name {clkcpu} -divide_by 2 -source [get_ports {clk_in}] [get_registers {cpu:cpu0|clkcpu}]
create_generated_clock -name {hc0[1]} -divide_by 4 -source [get_ports {clk_in}] [get_registers {video:video0|hc0[1]}]
derive_pll_clocks
derive_clocks -period 14MHz
@ -9,12 +9,12 @@ derive_clocks -period 14MHz
set_multicycle_path -from {vencode:*|*} -to {vencode:*|*} -setup 4
set_multicycle_path -from {vencode:*|*} -to {vencode:*|*} -hold 3
# One screen read cycle = ~71ns. SRAM speed = 55ns
# One video read cycle = ~71ns. SRAM speed = 55ns
# So we have about 16ns to setup control signals (n_vrd, n_vwr, va - 10ns) and read back data (vd - 6ns)
set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vrd] 10ns
set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vwr] 10ns
set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports va[*]] 10ns
set_max_delay -from [get_ports vd[*]] -to [get_pins -compatibility_mode screen0|*] 6ns
set_max_delay -from [get_pins -compatibility_mode video0|*] -to [get_ports n_vrd] 10ns
set_max_delay -from [get_pins -compatibility_mode video0|*] -to [get_ports n_vwr] 10ns
set_max_delay -from [get_pins -compatibility_mode video0|*] -to [get_ports va[*]] 10ns
set_max_delay -from [get_ports vd[*]] -to [get_pins -compatibility_mode video0|*] 6ns
set_false_path -from * -to [get_ports {snd_l}]
set_false_path -from * -to [get_ports {snd_r}]

View File

@ -171,12 +171,12 @@ set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd
set_global_assignment -name VERILOG_INCLUDE_FILE ../rtl/ps2_codes.vh
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/video.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpu.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mem.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
set_global_assignment -name VERILOG_FILE ../rtl/ps2.v

View File

@ -170,12 +170,12 @@ set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd
set_global_assignment -name VERILOG_INCLUDE_FILE ../rtl/ps2_codes.vh
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/video.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpu.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mem.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
set_global_assignment -name VERILOG_FILE ../rtl/ps2.v

View File

@ -170,12 +170,12 @@ set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd
set_global_assignment -name VERILOG_INCLUDE_FILE ../rtl/ps2_codes.vh
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/video.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpu.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mem.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
set_global_assignment -name VERILOG_FILE ../rtl/ps2.v