mirror of
https://github.com/UzixLS/zx-sizif-xxs.git
synced 2025-07-19 07:11:28 +03:00
153 lines
3.7 KiB
Systemverilog
Executable File
153 lines
3.7 KiB
Systemverilog
Executable File
import common::*;
|
|
module ports(
|
|
input rst_n,
|
|
input clk28,
|
|
input en_kempston,
|
|
input en_sinclair,
|
|
|
|
cpu_bus bus,
|
|
output [7:0] d_out,
|
|
output d_out_active,
|
|
|
|
input machine_t machine,
|
|
input port_ff_active,
|
|
input [7:0] port_ff_data,
|
|
input [4:0] kd,
|
|
input [7:0] kempston_data,
|
|
input magic_map,
|
|
input tape_in,
|
|
|
|
output reg tape_out,
|
|
output reg beeper,
|
|
output reg [2:0] border,
|
|
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
|
|
|
|
);
|
|
|
|
|
|
/* PORT #FF */
|
|
reg port_ff_rd;
|
|
always @(posedge clk28 or negedge rst_n) begin
|
|
if (!rst_n)
|
|
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[7:0] == 8'hFF);
|
|
end
|
|
|
|
|
|
/* PORT #FE */
|
|
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)
|
|
port_fe_rd <= 0;
|
|
else
|
|
port_fe_rd <= port_fe_cs && bus.rd;
|
|
end
|
|
|
|
reg [4:0] kd0;
|
|
wire [7:0] port_fe_data = {1'b1, tape_in, 1'b1, kd0};
|
|
always @(negedge clk28 or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
beeper <= 0;
|
|
tape_out <= 0;
|
|
border <= 0;
|
|
end
|
|
else if (port_fe_cs && bus.wr) begin
|
|
beeper <= bus.d[4];
|
|
tape_out <= bus.d[3];
|
|
border <= bus.d[2:0];
|
|
end
|
|
end
|
|
|
|
always @(posedge clk28 or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
kd0 <= 5'b11111;
|
|
end
|
|
else if (en_sinclair) begin
|
|
kd0 <= kd
|
|
& (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;
|
|
end
|
|
end
|
|
|
|
|
|
/* PORT #7FFD */
|
|
reg lock_7ffd;
|
|
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
|
|
ram_page128 <= 0;
|
|
video_page <= 0;
|
|
rom_page128 <= 0;
|
|
lock_7ffd <= 0;
|
|
end
|
|
else if (port_7ffd_cs && bus.wr) begin
|
|
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 == 16'hDFFD && (machine == MACHINE_PENT || magic_map);
|
|
always @(posedge clk28 or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
ram_pageext <= 0;
|
|
port_dffd <= 0;
|
|
end
|
|
else if (port_dffd_cs && bus.wr) begin
|
|
ram_pageext <= bus.d[2:0];
|
|
port_dffd <= bus.d[4:0];
|
|
end
|
|
end
|
|
|
|
|
|
/* PORT #1FFD */
|
|
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[2:0];
|
|
end
|
|
end
|
|
|
|
|
|
/* KEMPSTON */
|
|
reg kempston_rd;
|
|
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[5:0] == 6'h1F;
|
|
end
|
|
|
|
|
|
/* BUS CONTROLLER */
|
|
assign d_out_active = port_fe_rd | port_ff_rd | kempston_rd;
|
|
|
|
assign d_out =
|
|
kempston_rd? kempston_data :
|
|
port_fe_rd? port_fe_data :
|
|
port_ff_data ;
|
|
|
|
|
|
endmodule
|