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

ulaplus fixes

This commit is contained in:
UzixLS
2021-05-05 13:33:57 +03:00
parent 15a72f502e
commit 10b2901112
4 changed files with 152 additions and 91 deletions

View File

@ -6,12 +6,10 @@ module screen(
cpu_bus bus,
output [14:0] screen_addr,
output [5:0] up_addr,
input clkwait,
input timings_t timings,
input [2:0] border,
input up_en,
output reg [2:0] r,
output reg [2:0] g,
@ -21,10 +19,15 @@ module screen(
output reg csync,
output read,
output read_up,
output blink,
output load,
output reg [7:0] attr_next,
input up_en,
output [5:0] up_ink_addr,
output [5:0] up_paper_addr,
input [7:0] up_ink,
input [7:0] up_paper,
output [8:0] hc_out,
output [8:0] vc_out,
@ -151,6 +154,7 @@ always @(posedge clk28 or negedge rst_n) begin
end
end
reg [4:0] blink_cnt;
assign blink = blink_cnt[$bits(blink_cnt)-1];
always @(posedge clk28 or negedge rst_n) begin
@ -160,33 +164,30 @@ always @(posedge clk28 or negedge rst_n) begin
blink_cnt <= blink_cnt + 1'b1;
end
wire [7:0] attr_border = {2'b00, border, 3'b000};
reg [7:0] bitmap, attr, bitmap_next;
reg [7:0] up_ink, up_paper, up_ink_next, up_paper_next;
wire pixel = bitmap[7];
reg screen_read;
assign read = screen_read;
reg [1:0] screen_read_step;
wire screen_read_step_reset = hc0[4:0] == 5'b11111 || hc0_reset;
wire bitmap_read = screen_read && screen_read_step == 2'd0;
wire attr_read = screen_read && screen_read_step == 2'd1;
wire up_ink_read = screen_read && screen_read_step == 2'd2;
wire up_paper_read = screen_read && screen_read_step == 2'd3;
assign read_up = up_ink_read || up_paper_read;
reg screen_read_step;
wire bitmap_read = screen_read && screen_read_step == 1'd1;
wire attr_read = screen_read && screen_read_step == 1'd0;
assign screen_addr = bitmap_read?
{ 2'b10, vc[7:6], vc[2:0], vc[5:3], hc[7:3] } :
{ 5'b10110, vc[7:3], hc[7:3] };
assign up_addr = up_ink_read?
{ attr_next[7:6], 1'b0, attr_next[2:0] } :
{ attr_next[7:6], 1'b1, attr_next[5:3] };
wire screen_load = (vc < V_AREA) && (hc < H_AREA || hc0_reset);
assign load = screen_load;
wire screen_show = (vc < V_AREA) && (hc0 >= (SCREEN_DELAY<<2) - 2) && (hc0 < ((H_AREA + SCREEN_DELAY)<<2) - 2);
wire screen_update = vc < V_AREA && hc <= H_AREA && hc != 0 && hc0[4:0] == 5'b11110;
wire border_update = !screen_show && ((timings == TIMINGS_PENT && ck7) || hc0[4:0] == 5'b11110);
wire bitmap_shift = hc0[1:0] == 2'b10;
wire screen_read_next = (screen_load || up_en) && ((!bus.iorq && !bus.mreq && !bus.m1) || bus.rfsh || clkwait);
wire screen_read_next = screen_load && ((!bus.iorq && !bus.mreq && !bus.m1) || bus.rfsh || clkwait);
reg [7:0] up_ink0, up_paper0;
assign up_ink_addr = { attr_next[7:6], 1'b0, attr_next[2:0] };
assign up_paper_addr = { attr_next[7:6], 1'b1, attr_next[5:3] };
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
@ -196,22 +197,12 @@ always @(posedge clk28 or negedge rst_n) begin
bitmap <= 0;
attr_next <= 0;
bitmap_next <= 0;
up_ink <= 0;
up_paper <= 0;
up_ink_next <= 0;
up_paper_next <= 0;
end
else begin
if (ck14) begin
screen_read <= screen_read_next;
if (screen_read && screen_read_step[0] && !up_en)
screen_read_step <= 0;
else if (!screen_load && up_en)
screen_read_step <= 2'd3;
else if (screen_read_step_reset)
screen_read_step <= 0;
else if (screen_read)
if (screen_read)
screen_read_step <= screen_read_step + 1'b1;
screen_read <= screen_read_next;
if (attr_read)
attr_next <= bus.d;
@ -219,10 +210,6 @@ always @(posedge clk28 or negedge rst_n) begin
attr_next <= attr_border;
if (bitmap_read)
bitmap_next <= bus.d;
if (up_ink_read)
up_ink_next <= bus.d;
if (up_paper_read)
up_paper_next <= bus.d;
end
if (border_update)
@ -234,22 +221,23 @@ always @(posedge clk28 or negedge rst_n) begin
bitmap <= bitmap_next;
else if (bitmap_shift)
bitmap <= {bitmap[6:0], 1'b0};
if (screen_update)
up_ink <= up_ink_next;
up_ink0 <= up_ink;
if (screen_update || (!screen_show && !screen_load))
up_paper <= up_paper_next;
up_paper0 <= up_paper;
end
end
wire pixel = bitmap[7];
always @(posedge clk28) begin
if (blank)
{g, r, b} = 0;
else if (up_en) begin
g = pixel? up_ink[7:5] : up_paper[7:5];
r = pixel? up_ink[4:2] : up_paper[4:2];
b[2:1] = pixel? up_ink[1:0] : up_paper[1:0];
g = pixel? up_ink0[7:5] : up_paper0[7:5];
r = pixel? up_ink0[4:2] : up_paper0[4:2];
b[2:1] = pixel? up_ink0[1:0] : up_paper0[1:0];
b[0] = |b[2:1];
end
else begin
@ -262,4 +250,5 @@ always @(posedge clk28) begin
hsync = ~hsync0;
end
endmodule

View File

@ -22,7 +22,7 @@ module zx_ula(
output reg n_int,
output n_nmi,
output reg [5:0] vdac,
output reg [5:0] luma,
output reg [2:0] chroma,
output reg csync,
@ -102,15 +102,16 @@ assign ps2_data = (ps2_dat_out == 0)? 1'b0 : 1'bz;
/* SCREEN CONTROLLER */
reg [2:0] border;
reg up_en;
reg magic_beeper;
wire blink;
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0] ^ (pause & blink)};
reg [2:0] r, g, b;
reg hsync;
wire blink;
reg magic_beeper;
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0] ^ (pause & blink)};
reg up_en;
wire [5:0] up_ink_addr, up_paper_addr;
wire [7:0] up_ink, up_paper;
wire screen_read, screen_load, screen_read_up;
wire [14:0] screen_addr;
wire [5:0] screen_up_addr;
wire [7:0] attr_next;
wire [8:0] vc, hc;
wire clk14, clk7, clk35, ck14, ck7, ck35;
@ -120,12 +121,10 @@ screen screen0(
.bus(bus),
.screen_addr(screen_addr),
.up_addr(screen_up_addr),
.clkwait(clkwait),
.timings(timings),
.border(screen_border),
.up_en(up_en),
.r(r),
.g(g),
@ -135,10 +134,15 @@ screen screen0(
.blink(blink),
.read(screen_read),
.read_up(screen_read_up),
.load(screen_load),
.attr_next(attr_next),
.up_en(up_en),
.up_ink_addr(up_ink_addr),
.up_paper_addr(up_paper_addr),
.up_ink(up_ink),
.up_paper(up_paper),
.vc_out(vc),
.hc_out(hc),
.clk14(clk14),
@ -152,7 +156,7 @@ screen screen0(
/* VIDEO OUTPUT */
always @*
vdac <= {g[2], r[2], b[2], g[1], r[1], b[1]};
luma <= {g[2], r[2], b[2], g[1], r[1], b[1]};
reg [2:0] chroma0;
chroma_gen #(.CLK_FREQ(40_000_000)) chroma_gen1(
@ -390,37 +394,23 @@ assign sd_mosi = sd_mosi0;
/* ULAPLUS */
wire port_bf3b_cs = !extlock && bus.ioreq && bus.a == 16'hbf3b;
wire port_ff3b_cs = !extlock && bus.ioreq && bus.a == 16'hff3b;
reg port_ff3b_rd;
wire [7:0] port_ff3b_data = {7'b0000000, up_en};
reg [7:0] up_addr_reg;
reg up_write_req;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
port_ff3b_rd <= 1'b0;
up_en <= 1'b0;
up_write_req <= 1'b0;
up_addr_reg <= 1'b0;
end
else begin
port_ff3b_rd <= port_ff3b_cs && n_rd == 1'b0;
if (n_wr == 1'b0) begin
if (port_bf3b_cs)
up_addr_reg <= bus.d;
if (port_ff3b_cs) begin
if (up_addr_reg == 8'b01000000)
up_en <= bus.d[0];
else if (up_addr_reg[7:6] == 2'b00)
up_write_req <= 1'b1;
end
end
else begin
up_write_req <= 0;
end
end
end
wire up_dout_active;
wire [7:0] up_dout;
ulaplus ulaplus0(
.rst_n(rst_n & usrrst_n),
.clk28(clk28),
.en(!extlock),
.bus(bus),
.d_out(up_dout),
.d_out_active(up_dout_active),
.active(up_en),
.ink_addr(up_ink_addr),
.paper_addr(up_paper_addr),
.ink(up_ink),
.paper(up_paper)
);
/* MEMORY INITIALIZER */
@ -479,7 +469,7 @@ always @(posedge clk28 or negedge rst_n) begin
else begin
romreq = bus.mreq && !bus.rfsh && bus.a[14] == 0 && bus.a[15] == 0 &&
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd_d4 && !port_1ffd[0]));
ramreq = (bus.mreq && !bus.rfsh && !romreq) || up_write_req;
ramreq = bus.mreq && !bus.rfsh && !romreq;
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
end
end
@ -489,7 +479,7 @@ assign n_vwr = ((ramreq_wr && bus.wr && !screen_read) || rom2ram_ram_wren)? 1'b0
/* VA[18:13] map
* 00xxxx 128Kb of roms
* 00111x 16Kb of magic ram and ulaplus
* 00111x 16Kb of magic ram
* 01xxxx 128Kb of divmmc memory
* 10xxxx 128Kb of extended ram (via port dffd)
* 11xxxx 128Kb of main ram
@ -526,16 +516,14 @@ end
assign va[18:0] =
rom2ram_ram_wren? {2'b00, rom2ram_ram_address} :
screen_read && screen_read_up? {2'b00, 3'b111, 8'b11111111, screen_up_addr} :
screen_read && snow? {3'b111, screenpage, screen_addr[14:8], bus.a[7:0]} :
screen_read && snow? {3'b111, screenpage, screen_addr[14:8], {8{1'bz}}} :
screen_read? {3'b111, screenpage, screen_addr} :
up_write_req? {2'b00, 3'b111, 8'b11111111, up_addr_reg[5:0]} :
romreq? {2'b00, rom_a[16:14], bus.a[13], {13{1'bz}}} :
{ram_a[18:13], {13{1'bz}}};
assign vd[7:0] =
rom2ram_ram_wren? rom2ram_dataout :
port_ff3b_rd? port_ff3b_data :
up_dout_active? up_dout :
div_dout_active? div_dout :
turbosound_dout_active? turbosound_dout :
ports_dout_active? ports_dout :

83
fpga/rtl/ulaplus.sv Normal file
View File

@ -0,0 +1,83 @@
module ulaplus(
input rst_n,
input clk28,
input en,
cpu_bus bus,
output [7:0] d_out,
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
);
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};
reg [7:0] addr_reg;
reg [1:0] write_req;
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) begin
active <= 0;
addr_reg <= 0;
write_req <= 0;
port_ff3b_rd <= 0;
end
else begin
if (port_bf3b_cs && bus.wr)
addr_reg <= bus.d;
if (port_ff3b_cs && bus.wr && addr_reg == 8'b01000000)
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;
end
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 [7:0] ram_q;
ram pallete(ram_q, ram_a, bus.d, write_req0, clk28);
always @(posedge clk28 or negedge rst_n) begin
if (!rst_n)
read_step <= 0;
else
read_step <= !read_step;
end
always @(posedge clk28) begin
if (read_step)
paper <= ram_q;
else
ink <= ram_q;
end
assign d_out = port_ff3b_data;
assign d_out_active = port_ff3b_rd;
endmodule
module ram(q, a, d, we, clk);
output[7:0] q;
input [7:0] d;
input [5:0] a;
input we, clk;
reg [7:0] mem [0:63];
always @(posedge clk) begin
if (we)
mem[a] <= d;
q <= mem[a];
end
endmodule

View File

@ -100,12 +100,12 @@ set_location_assignment PIN_22 -to chroma[0]
set_location_assignment PIN_23 -to chroma[1]
set_location_assignment PIN_24 -to chroma[2]
set_location_assignment PIN_25 -to csync
set_location_assignment PIN_26 -to vdac[5]
set_location_assignment PIN_27 -to vdac[4]
set_location_assignment PIN_28 -to vdac[3]
set_location_assignment PIN_29 -to vdac[2]
set_location_assignment PIN_34 -to vdac[1]
set_location_assignment PIN_35 -to vdac[0]
set_location_assignment PIN_26 -to luma[5]
set_location_assignment PIN_27 -to luma[4]
set_location_assignment PIN_28 -to luma[3]
set_location_assignment PIN_29 -to luma[2]
set_location_assignment PIN_34 -to luma[1]
set_location_assignment PIN_35 -to luma[0]
set_location_assignment PIN_36 -to snd_l
set_location_assignment PIN_37 -to snd_r
set_location_assignment PIN_38 -to sd_cd
@ -178,4 +178,5 @@ set_global_assignment -name CDF_FILE output/zx_ula.cdf
set_global_assignment -name QIP_FILE ip/pll.qip
set_global_assignment -name QIP_FILE ip/rom2ram.qip
set_global_assignment -name QIP_FILE ip/asmi.qip
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top