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:
@ -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
|
||||
|
@ -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
83
fpga/rtl/ulaplus.sv
Normal 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
|
@ -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
|
Reference in New Issue
Block a user