RTC: cleanup.

This commit is contained in:
sorgelig
2018-08-21 21:29:25 +08:00
parent b7f4f640cc
commit c9d6dd85c1
5 changed files with 260 additions and 550 deletions

View File

@ -367,8 +367,7 @@ set_global_assignment -name VERILOG_FILE src/cpu/zmem.v
set_global_assignment -name VERILOG_FILE src/cpu/zmaps.v set_global_assignment -name VERILOG_FILE src/cpu/zmaps.v
set_global_assignment -name VERILOG_FILE src/cpu/zint.v set_global_assignment -name VERILOG_FILE src/cpu/zint.v
set_global_assignment -name VERILOG_FILE src/cpu/zclock.v set_global_assignment -name VERILOG_FILE src/cpu/zclock.v
set_global_assignment -name VHDL_FILE src/rtc/CMOS.vhd set_global_assignment -name VERILOG_FILE src/rtc/mc146818a.v
set_global_assignment -name VHDL_FILE src/rtc/mc146818a.vhd
set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
set_global_assignment -name QIP_FILE src/sound/jt12/jt12.qip set_global_assignment -name QIP_FILE src/sound/jt12/jt12.qip
set_global_assignment -name SYSTEMVERILOG_FILE src/sound/ym2149.sv set_global_assignment -name SYSTEMVERILOG_FILE src/sound/ym2149.sv

View File

@ -1,235 +0,0 @@
-- megafunction wizard: %RAM: 2-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: CMOS.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 11.0 Build 157 04/27/2011 SJ Full Version
-- ************************************************************
--Copyright (C) 1991-2011 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY CMOS IS
PORT
(
clock : IN STD_LOGIC := '1';
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
rdaddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
wraddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
wren : IN STD_LOGIC := '0';
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END CMOS;
ARCHITECTURE SYN OF cmos IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_aclr_b : STRING;
address_reg_b : STRING;
clock_enable_input_a : STRING;
clock_enable_input_b : STRING;
clock_enable_output_b : STRING;
init_file : STRING;
intended_device_family : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
numwords_b : NATURAL;
operation_mode : STRING;
outdata_aclr_b : STRING;
outdata_reg_b : STRING;
power_up_uninitialized : STRING;
read_during_write_mode_mixed_ports : STRING;
widthad_a : NATURAL;
widthad_b : NATURAL;
width_a : NATURAL;
width_b : NATURAL;
width_byteena_a : NATURAL
);
PORT (
address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
clock0 : IN STD_LOGIC ;
data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
wren_a : IN STD_LOGIC ;
address_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;
BEGIN
q <= sub_wire0(7 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_b => "NONE",
address_reg_b => "CLOCK0",
clock_enable_input_a => "BYPASS",
clock_enable_input_b => "BYPASS",
clock_enable_output_b => "BYPASS",
init_file => "src/rtc/CMOS.mif",
intended_device_family => "Cyclone IV E",
lpm_type => "altsyncram",
numwords_a => 256,
numwords_b => 256,
operation_mode => "DUAL_PORT",
outdata_aclr_b => "NONE",
outdata_reg_b => "UNREGISTERED",
power_up_uninitialized => "FALSE",
read_during_write_mode_mixed_ports => "DONT_CARE",
widthad_a => 8,
widthad_b => 8,
width_a => 8,
width_b => 8,
width_byteena_a => 1
)
PORT MAP (
address_a => wraddress,
clock0 => clock,
data_a => data,
wren_a => wren,
address_b => rdaddress,
q_b => sub_wire0
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
-- Retrieval info: PRIVATE: CLRdata NUMERIC "0"
-- Retrieval info: PRIVATE: CLRq NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRrren NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
-- Retrieval info: PRIVATE: CLRwren NUMERIC "0"
-- Retrieval info: PRIVATE: Clock NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clock_B NUMERIC "0"
-- Retrieval info: PRIVATE: ECC NUMERIC "0"
-- Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "2048"
-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING "./src/rtc/CMOS.mif"
-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
-- Retrieval info: PRIVATE: REGdata NUMERIC "1"
-- Retrieval info: PRIVATE: REGq NUMERIC "0"
-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGrren NUMERIC "1"
-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
-- Retrieval info: PRIVATE: REGwren NUMERIC "1"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
-- Retrieval info: PRIVATE: VarWidth NUMERIC "0"
-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8"
-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8"
-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
-- Retrieval info: PRIVATE: enable NUMERIC "0"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
-- Retrieval info: CONSTANT: INIT_FILE STRING "./src/rtc/CMOS.mif"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256"
-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
-- Retrieval info: USED_PORT: rdaddress 0 0 8 0 INPUT NODEFVAL "rdaddress[7..0]"
-- Retrieval info: USED_PORT: wraddress 0 0 8 0 INPUT NODEFVAL "wraddress[7..0]"
-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
-- Retrieval info: CONNECT: @address_a 0 0 8 0 wraddress 0 0 8 0
-- Retrieval info: CONNECT: @address_b 0 0 8 0 rdaddress 0 0 8 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf

248
src/rtc/mc146818a.v Normal file
View File

@ -0,0 +1,248 @@
//-----------------------------------------------------------------[18.10.2014]
// MC146818A REAL-TIME CLOCK PLUS RAM
//-----------------------------------------------------------------------------
// V0.1 05.10.2011 Initial version
// V0.2 06.09.2014 Added General Purpose RAM
module mc146818a
(
input RESET,
input CLK,
input ENA,
input CS,
input [64:0] RTC,
input [31:0] CMOSCfg,
input [7:0] KEYSCANCODE,
input WR,
input [7:0] A,
input [7:0] DI,
output [7:0] DO
);
reg [18:0] pre_scaler =0;
reg [1:0] leap_reg =0;
reg [7:0] seconds_reg =0; // 00
reg [7:0] seconds_alarm_reg =0; // 01
reg [7:0] minutes_reg =0; // 02
reg [7:0] minutes_alarm_reg = 0;// 03
reg [7:0] hours_reg =0; // 04
reg [7:0] hours_alarm_reg ='hff;// 05
reg [7:0] weeks_reg = 1; // 06
reg [7:0] days_reg = 1; // 07
reg [7:0] month_reg = 1; // 08
reg [7:0] year_reg = 0; // 09
reg [7:0] a_reg; // 0A
reg [7:0] b_reg = 8'b00000010; // 0B
reg [7:0] c_reg; // 0C
wire [7:0] CMOS_Dout;
reg [7:0] Dout;
assign DO = Dout;
always @(*) begin
case (A[7:0])
8'h00 : Dout <= seconds_reg;
8'h01 : Dout <= seconds_alarm_reg;
8'h02 : Dout <= minutes_reg;
8'h03 : Dout <= minutes_alarm_reg;
8'h04 : Dout <= hours_reg;
8'h05 : Dout <= hours_alarm_reg;
8'h06 : Dout <= weeks_reg;
8'h07 : Dout <= days_reg;
8'h08 : Dout <= month_reg;
8'h09 : Dout <= year_reg;
8'h0a : Dout <= a_reg;
8'h0b : Dout <= b_reg;
8'h0c : Dout <= c_reg;
8'h0d : Dout <= 8'b10000000;
8'hb1 : Dout <= CMOSCfg[7:6]; // CPU Speed
8'hb2 : Dout <= 0; // Boot device
8'hb3 : Dout <= CMOSCfg[8]; // CPU Cache
8'hb4 : Dout <= CMOSCfg[13:11]; // F11
8'hb5 : Dout <= CMOSCfg[15:14]; // F11 bank
8'hb6 : Dout <= CMOSCfg[18:16]; // Shift+F11
8'hb7 : Dout <= CMOSCfg[20:19]; // Shift+F11 bank
8'hb8 : Dout <= CMOSCfg[10:9]; // #7FFD
8'hb9 : Dout <= CMOSCfg[23:21]; // ZX Palette
8'hba : Dout <= CMOSCfg[24]; // NGS Reset
8'hbb : Dout <= CMOSCfg[27:25]; // INT offset
8'hf0 : Dout <= KEYSCANCODE;
default: Dout <= CMOS_Dout;
endcase
end
always @(posedge CLK) begin
reg flg;
flg <= RTC[64];
if (flg != RTC[64]) begin
seconds_reg <= RTC[7:0];
minutes_reg <= RTC[15:8];
hours_reg <= RTC[23:16];
days_reg <= RTC[31:24];
month_reg <= RTC[39:32];
year_reg <= RTC[47:40];
weeks_reg <= RTC[55:48] + 1'b1;
b_reg <= 8'b00000010;
end
if (RESET) b_reg <= 8'b00000010;
else if (WR & CS) begin
/*
case (A[7:0])
0 : seconds_reg <= DI;
1 : seconds_alarm_reg <= DI;
2 : minutes_reg <= DI;
3 : minutes_alarm_reg <= DI;
4 : hours_reg <= DI;
5 : hours_alarm_reg <= DI;
6 : weeks_reg <= DI;
7 : days_reg <= DI;
8 : month_reg <= DI;
9 : year_reg <= DI;
11 : begin
b_reg <= DI;
if (b_reg[2] == 1'b0) begin // BCD to BIN convertion
if (DI[4] == 1'b0) leap_reg <= DI[1:0];
else leap_reg <= {~DI[1], DI[0]};
end
else begin
leap_reg <= DI[1:0];
end
end
endcase
*/
end
if (RESET) begin
a_reg <= 8'b00100110;
c_reg <= 0;
end
else if (~b_reg[7] & ENA) begin
if (pre_scaler) begin
pre_scaler <= pre_scaler - 1'd1;
a_reg[7] <= 0;
end
else begin
pre_scaler <= 437500; //(0.4375MHz)
a_reg[7] <= 1;
c_reg[4] <= 1;
// alarm
if ((seconds_reg == seconds_alarm_reg) && (minutes_reg == minutes_alarm_reg) && (hours_reg == hours_alarm_reg)) c_reg[5] <= 1'b1;
if (~b_reg[2]) begin
// DM binary-coded-decimal (BCD) data mode
if (seconds_reg[3:0] != 9) seconds_reg[3:0] <= seconds_reg[3:0] + 1'd1;
else begin
seconds_reg[3:0] <= 0;
if (seconds_reg[6:4] != 5) seconds_reg[6:4] <= seconds_reg[6:4] + 1'd1;
else begin
seconds_reg[6:4] <= 0;
if (minutes_reg[3:0] != 9) minutes_reg[3:0] <= minutes_reg[3:0] + 1'd1;
else begin
minutes_reg[3:0] <= 0;
if (minutes_reg[6:4] != 5) minutes_reg[6:4] <= minutes_reg[6:4] + 1'd1;
else begin
minutes_reg[6:4] <= 0;
if (hours_reg[3:0] == 9) begin
hours_reg[3:0] <= 0;
hours_reg[5:4] <= hours_reg[5:4] + 1'd1;
end
else if ({b_reg[1], hours_reg[7], hours_reg[4:0]} == 7'b0010010) begin
hours_reg[4:0] <= 1;
hours_reg[7] <= ~hours_reg[7];
end
else if (({b_reg[1], hours_reg[7], hours_reg[4:0]} != 7'b0110010) &&
({b_reg[1], hours_reg[5:0]} != 7'b1100011)) hours_reg[3:0] <= hours_reg[3:0] + 1'd1;
else begin
if (~b_reg[1]) hours_reg[7:0] <= 1;
else hours_reg[5:0] <= 0;
if (weeks_reg[2:0] != 7) weeks_reg[2:0] <= weeks_reg[2:0] + 1'd1;
else weeks_reg[2:0] <= 1;
if (({month_reg, days_reg, leap_reg} == {16'h0228, 2'b01}) ||
({month_reg, days_reg, leap_reg} == {16'h0228, 2'b10}) ||
({month_reg, days_reg, leap_reg} == {16'h0228, 2'b11}) ||
({month_reg, days_reg, leap_reg} == {16'h0229, 2'b00}) ||
({month_reg, days_reg} == 16'h0430) ||
({month_reg, days_reg} == 16'h0630) ||
({month_reg, days_reg} == 16'h0930) ||
({month_reg, days_reg} == 16'h1130) ||
(days_reg == 8'h31)) begin
days_reg[5:0] <= 1;
if (month_reg[3:0] == 9) month_reg[4:0] <= 'h10;
else if (month_reg[4:0] != 'h12) month_reg[3:0] <= month_reg[3:0] + 1'd1;
else begin
month_reg[4:0] <= 1;
leap_reg[1:0] <= leap_reg[1:0] + 1'd1;
if (year_reg[3:0] != 9) year_reg[3:0] <= year_reg[3:0] + 1'd1;
else begin
year_reg[3:0] <= 0;
if (year_reg[7:4] != 9) year_reg[7:4] <= year_reg[7:4] + 1'd1;
else year_reg[7:4] <= 0;
end
end
end
else if (days_reg[3:0] != 9) days_reg[3:0] <= days_reg[3:0] + 1'd1;
else begin
days_reg[3:0] <= 0;
days_reg[5:4] <= days_reg[5:4] + 1'd1;
end
end
end
end
end
end
end else begin
// DM binary data mode
if (seconds_reg != 8'h3B) seconds_reg <= seconds_reg + 1'd1;
else begin
seconds_reg <= 0;
if (minutes_reg != 8'h3B) minutes_reg <= minutes_reg + 1'd1;
else begin
minutes_reg <= 0;
if ({b_reg[1], hours_reg[7], hours_reg[3:0]} == 6'b001100) hours_reg[7:0] <= 8'b10000001;
else if (({b_reg[1], hours_reg[7], hours_reg[3:0]} != 6'b011100) & ({b_reg[1], hours_reg[4:0]} != 6'b110111)) hours_reg[4:0] <= hours_reg[4:0] + 1'd1;
else begin
if (b_reg[1] == 1'b0) hours_reg[7:0] <= 1;
else hours_reg <= 0;
if (weeks_reg != 7) weeks_reg <= weeks_reg + 1'd1;
else weeks_reg <= 1; // Sunday = 1
if (({month_reg, days_reg, leap_reg} == {16'h021C, 2'b01}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b10}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b11}) | ({month_reg, days_reg, leap_reg} == {16'h021D, 2'b00}) | ({month_reg, days_reg} == 16'h041E) | ({month_reg, days_reg} == 16'h061E) | ({month_reg, days_reg} == 16'h091E) | ({month_reg, days_reg} == 16'h0B1E) | (days_reg == 8'h1F)) begin
days_reg <= 1;
if (month_reg != 8'h0C) month_reg <= month_reg + 1'd1;
else begin
month_reg <= 1;
leap_reg[1:0] <= leap_reg[1:0] + 1'd1;
if (year_reg != 8'h63) year_reg <= year_reg + 1'd1;
else year_reg <= 0;
end
end else days_reg <= days_reg + 1'd1;
end
end
end
end
end
end
end
// 50 Bytes of General Purpose RAM
dpram #(.DATAWIDTH(8), .ADDRWIDTH(8), .MEM_INIT_FILE("src/rtc/CMOS.mif")) CMOS
(
.clock (CLK),
.address_a (A),
.data_a (DI),
.wren_a (WR & CS),
.q_a (CMOS_Dout)
);
endmodule

View File

@ -1,302 +0,0 @@
-------------------------------------------------------------------[18.10.2014]
-- MC146818A REAL-TIME CLOCK PLUS RAM
-------------------------------------------------------------------------------
-- V0.1 05.10.2011 Initial version
-- V0.2 06.09.2014 Added General Purpose RAM
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_unsigned.all;
entity mc146818a is
port (
RESET : in std_logic;
CLK : in std_logic;
ENA : in std_logic;
CS : in std_logic;
RTC : in std_logic_vector(64 downto 0);
CMOSCfg : in std_logic_vector(31 downto 0);
KEYSCANCODE : in std_logic_vector(7 downto 0);
WR : in std_logic;
A : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0));
end;
architecture rtl of mc146818a is
signal pre_scaler : std_logic_vector(18 downto 0);
signal leap_reg : std_logic_vector(1 downto 0);
signal seconds_reg : std_logic_vector(7 downto 0); -- 00
signal seconds_alarm_reg : std_logic_vector(7 downto 0); -- 01
signal minutes_reg : std_logic_vector(7 downto 0); -- 02
signal minutes_alarm_reg : std_logic_vector(7 downto 0); -- 03
signal hours_reg : std_logic_vector(7 downto 0); -- 04
signal hours_alarm_reg : std_logic_vector(7 downto 0); -- 05
signal weeks_reg : std_logic_vector(7 downto 0); -- 06
signal days_reg : std_logic_vector(7 downto 0); -- 07
signal month_reg : std_logic_vector(7 downto 0); -- 08
signal year_reg : std_logic_vector(7 downto 0); -- 09
signal a_reg : std_logic_vector(7 downto 0); -- 0A
signal b_reg : std_logic_vector(7 downto 0); -- 0B
signal c_reg : std_logic_vector(7 downto 0); -- 0C
signal CMOS_Dout : std_logic_vector(7 downto 0);
signal Dout : std_logic_vector(7 downto 0);
begin
DO <= Dout;
process(CLK, A, seconds_reg, seconds_alarm_reg, minutes_reg, minutes_alarm_reg, hours_reg, hours_alarm_reg, weeks_reg, days_reg, month_reg, year_reg, KEYSCANCODE, CMOS_Dout, a_reg, b_reg, c_reg, CMOSCfg)
begin
-- 14 Bytes of Clock and Control Registers Read
case A(7 downto 0) is
when x"00" => Dout <= seconds_reg;
-- when x"01" => Dout <= seconds_alarm_reg;
when x"02" => Dout <= minutes_reg;
-- when x"03" => Dout <= minutes_alarm_reg;
when x"04" => Dout <= hours_reg;
-- when x"05" => Dout <= hours_alarm_reg;
when x"06" => Dout <= weeks_reg;
when x"07" => Dout <= days_reg;
when x"08" => Dout <= month_reg;
when x"09" => Dout <= year_reg;
when x"0a" => Dout <= a_reg;
when x"0b" => Dout <= b_reg;
when x"0c" => Dout <= c_reg;
when x"0d" => Dout <= "10000000";
when x"b1" => Dout <= "000000" & CMOSCfg(7 downto 6); -- CPU Speed
when x"b2" => Dout <= "00000000"; -- Boot device
when x"b3" => Dout <= "0000000" & CMOSCfg(8); -- CPU Cache
when x"b4" => Dout <= "00000" & CMOSCfg(13 downto 11); -- F11
when x"b5" => Dout <= "000000" & CMOSCfg(15 downto 14); -- F11 bank
when x"b6" => Dout <= "00000" & CMOSCfg(18 downto 16); -- Shift+F11
when x"b7" => Dout <= "000000" & CMOSCfg(20 downto 19); -- Shift+F11 bank
when x"b8" => Dout <= "000000" & CMOSCfg(10 downto 9); -- #7FFD
when x"b9" => Dout <= "00000" & CMOSCfg(23 downto 21); -- ZX Palette
when x"ba" => Dout <= "0000000" & CMOSCfg(24); -- NGS Reset
when x"bb" => Dout <= "00000" & CMOSCfg(27 downto 25); -- INT offset
when x"f0" => Dout <= KEYSCANCODE;
when others => Dout <= CMOS_Dout;
end case;
end process;
process(CLK)
variable flg : std_logic := '0';
begin
if rising_edge(CLK) then
if flg /= RTC(64) then
seconds_reg <= RTC(7 downto 0);
minutes_reg <= RTC(15 downto 8);
hours_reg <= RTC(23 downto 16);
days_reg <= RTC(31 downto 24);
month_reg <= RTC(39 downto 32);
year_reg <= RTC(47 downto 40);
weeks_reg <= RTC(55 downto 48) + "1";
b_reg <= "00000010";
end if;
flg := RTC(64);
-- if RESET = '1' then
-- b_reg <= "00000010";
-- elsif WR = '1' and CS = '1' then
-- case A(7 downto 0) is
-- when x"00" => seconds_reg <= DI;
-- when x"01" => seconds_alarm_reg <= DI;
-- when x"02" => minutes_reg <= DI;
-- when x"03" => minutes_alarm_reg <= DI;
-- when x"04" => hours_reg <= DI;
-- when x"05" => hours_alarm_reg <= DI;
-- when x"06" => weeks_reg <= DI;
-- when x"07" => days_reg <= DI;
-- when x"08" => month_reg <= DI;
-- when x"09" => year_reg <= DI;
-- when x"0b" => b_reg <= DI;
--
-- if b_reg(2) = '0' then -- BCD to BIN convertion
-- if DI(4) = '0' then
-- leap_reg <= DI(1 downto 0);
-- else
-- leap_reg <= (not DI(1)) & DI(0);
-- end if;
-- else
-- leap_reg <= DI(1 downto 0);
-- end if;
--
-- when others => null;
-- end case;
-- end if;
if RESET = '1' then
a_reg <= "00100110";
c_reg <= (others => '0');
elsif b_reg(7) = '0' and ENA = '1' then
if pre_scaler /= X"000000" then
pre_scaler <= pre_scaler - 1;
a_reg(7) <= '0';
else
pre_scaler <= "1101010110011111100"; --(0.4375MHz)
a_reg(7) <= '1';
c_reg(4) <= '1';
-- alarm
-- if ((seconds_reg = seconds_alarm_reg) and
-- (minutes_reg = minutes_alarm_reg) and
-- (hours_reg = hours_alarm_reg)) then
-- c_reg(5) <= '1';
-- end if;
-- DM binary-coded-decimal (BCD) data mode
--if b_reg(2) = '0' then
if seconds_reg(3 downto 0) /= "1001" then
seconds_reg(3 downto 0) <= seconds_reg(3 downto 0) + 1;
else
seconds_reg(3 downto 0) <= (others => '0');
if seconds_reg(6 downto 4) /= "101" then
seconds_reg(6 downto 4) <= seconds_reg(6 downto 4) + 1;
else
seconds_reg(6 downto 4) <= (others => '0');
if minutes_reg(3 downto 0) /= "1001" then
minutes_reg(3 downto 0) <= minutes_reg(3 downto 0) + 1;
else
minutes_reg(3 downto 0) <= (others => '0');
if minutes_reg(6 downto 4) /= "101" then
minutes_reg(6 downto 4) <= minutes_reg(6 downto 4) + 1;
else
minutes_reg(6 downto 4) <= (others => '0');
if hours_reg(3 downto 0) = "1001" then
hours_reg(3 downto 0) <= (others => '0');
hours_reg(5 downto 4) <= hours_reg(5 downto 4) + 1;
elsif b_reg(1) & hours_reg(7) & hours_reg(4 downto 0) = "0010010" then
hours_reg(4 downto 0) <= "00001";
hours_reg(7) <= not hours_reg(7);
elsif ((b_reg(1) & hours_reg(7) & hours_reg(4 downto 0) /= "0110010") and
(b_reg(1) & hours_reg(5 downto 0) /= "1100011")) then
hours_reg(3 downto 0) <= hours_reg(3 downto 0) + 1;
else
if b_reg(1) = '0' then
hours_reg(7 downto 0) <= "00000001";
else
hours_reg(5 downto 0) <= (others => '0');
end if;
if weeks_reg(2 downto 0) /= "111" then
weeks_reg(2 downto 0) <= weeks_reg(2 downto 0) + 1;
else
weeks_reg(2 downto 0) <= "001";
end if;
if ((month_reg & days_reg & leap_reg = X"0228" & "01") or
(month_reg & days_reg & leap_reg = X"0228" & "10") or
(month_reg & days_reg & leap_reg = X"0228" & "11") or
(month_reg & days_reg & leap_reg = X"0229" & "00") or
(month_reg & days_reg = X"0430") or
(month_reg & days_reg = X"0630") or
(month_reg & days_reg = X"0930") or
(month_reg & days_reg = X"1130") or
( days_reg = X"31")) then
days_reg(5 downto 0) <= "000001";
if month_reg(3 downto 0) = "1001" then
month_reg(4 downto 0) <= "10000";
elsif month_reg(4 downto 0) /= "10010" then
month_reg(3 downto 0) <= month_reg(3 downto 0) + 1;
else
month_reg(4 downto 0) <= "00001";
leap_reg(1 downto 0) <= leap_reg(1 downto 0) + 1;
if year_reg(3 downto 0) /= "1001" then
year_reg(3 downto 0) <= year_reg(3 downto 0) + 1;
else
year_reg(3 downto 0) <= "0000";
if year_reg(7 downto 4) /= "1001" then
year_reg(7 downto 4) <= year_reg(7 downto 4) + 1;
else
year_reg(7 downto 4) <= "0000";
end if;
end if;
end if;
elsif days_reg(3 downto 0) /= "1001" then
days_reg(3 downto 0) <= days_reg(3 downto 0) + 1;
else
days_reg(3 downto 0) <= (others => '0');
days_reg(5 downto 4) <= days_reg(5 downto 4) + 1;
end if;
end if;
end if;
end if;
end if;
end if;
-- DM binary data mode
-- else
-- if seconds_reg /= x"3B" then
-- seconds_reg <= seconds_reg + 1;
-- else
-- seconds_reg <= (others => '0');
-- if minutes_reg /= x"3B" then
-- minutes_reg <= minutes_reg + 1;
-- else
-- minutes_reg <= (others => '0');
-- if b_reg(1) & hours_reg(7) & hours_reg(3 downto 0) = "001100" then
-- hours_reg(7 downto 0) <= "10000001";
-- elsif ((b_reg(1) & hours_reg(7) & hours_reg(3 downto 0) /= "011100") and
-- (b_reg(1) & hours_reg(4 downto 0) /= "110111")) then
-- hours_reg(4 downto 0) <= hours_reg(4 downto 0) + 1;
-- else
-- if b_reg(1) = '0' then
-- hours_reg(7 downto 0) <= "00000001";
-- else
-- hours_reg <= (others => '0');
-- end if;
-- if weeks_reg /= x"07" then
-- weeks_reg <= weeks_reg + 1;
-- else
-- weeks_reg <= x"01"; -- Sunday = 1
-- end if;
-- if ((month_reg & days_reg & leap_reg = X"021C" & "01") or
-- (month_reg & days_reg & leap_reg = X"021C" & "10") or
-- (month_reg & days_reg & leap_reg = X"021C" & "11") or
-- (month_reg & days_reg & leap_reg = X"021D" & "00") or
-- (month_reg & days_reg = X"041E") or
-- (month_reg & days_reg = X"061E") or
-- (month_reg & days_reg = X"091E") or
-- (month_reg & days_reg = X"0B1E") or
-- ( days_reg = X"1F")) then
-- days_reg <= x"01";
-- if month_reg /= x"0C" then
-- month_reg <= month_reg + 1;
-- else
-- month_reg <= x"01";
-- leap_reg(1 downto 0) <= leap_reg(1 downto 0) + 1;
-- if year_reg /= x"63" then
-- year_reg <= year_reg + 1;
-- else
-- year_reg <= x"00";
-- end if;
-- end if;
-- else
-- days_reg <= days_reg + 1;
-- end if;
-- end if;
-- end if;
-- end if;
-- end if;
end if;
end if;
end if;
end process;
-- 50 Bytes of General Purpose RAM
SE11: entity work.CMOS
port map (
clock => CLK,
data => DI,
rdaddress => A,
wraddress => A,
wren => WR and CS,
q => CMOS_Dout
);
end rtl;

View File

@ -787,17 +787,17 @@ end
mc146818a SE9 mc146818a SE9
( (
.reset(reset), .RESET(reset),
.clk(clk_28mhz), .CLK(clk_28mhz),
.ena(ena_0_4375mhz), .ENA(ena_0_4375mhz),
.cs(1), .CS(1),
.keyscancode(key_scancode), .KEYSCANCODE(key_scancode),
.rtc(RTC), .RTC(RTC),
.cmoscfg(CMOSCfg), .CMOSCfg(CMOSCfg),
.wr(mc146818a_wr), .WR(mc146818a_wr),
.a(gluclock_addr[7:0]), .A(gluclock_addr[7:0]),
.di(cpu_do_bus), .DI(cpu_do_bus),
.do(mc146818a_do_bus) .DO(mc146818a_do_bus)
); );