1
0
mirror of https://github.com/UzixLS/zx-sizif-xxs.git synced 2025-07-18 23:01:40 +03:00
Files
zx-sizif-xxs/fpga/rtl/ports.sv
2024-01-03 19:05:12 +03:00

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