From c9d6dd85c1e98b0ca7f9382cd236cc8ebb225612 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Tue, 21 Aug 2018 21:29:25 +0800 Subject: [PATCH] RTC: cleanup. --- TSConf-lite.qsf | 3 +- src/rtc/CMOS.vhd | 235 -------------------------------- src/rtc/mc146818a.v | 248 ++++++++++++++++++++++++++++++++++ src/rtc/mc146818a.vhd | 302 ------------------------------------------ src/tsconf.v | 22 +-- 5 files changed, 260 insertions(+), 550 deletions(-) delete mode 100644 src/rtc/CMOS.vhd create mode 100644 src/rtc/mc146818a.v delete mode 100644 src/rtc/mc146818a.vhd diff --git a/TSConf-lite.qsf b/TSConf-lite.qsf index 6ab98ce..0153fbb 100644 --- a/TSConf-lite.qsf +++ b/TSConf-lite.qsf @@ -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/zint.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 VHDL_FILE src/rtc/mc146818a.vhd +set_global_assignment -name VERILOG_FILE src/rtc/mc146818a.v 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 SYSTEMVERILOG_FILE src/sound/ym2149.sv diff --git a/src/rtc/CMOS.vhd b/src/rtc/CMOS.vhd deleted file mode 100644 index ea97169..0000000 --- a/src/rtc/CMOS.vhd +++ /dev/null @@ -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 diff --git a/src/rtc/mc146818a.v b/src/rtc/mc146818a.v new file mode 100644 index 0000000..feb751a --- /dev/null +++ b/src/rtc/mc146818a.v @@ -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 diff --git a/src/rtc/mc146818a.vhd b/src/rtc/mc146818a.vhd deleted file mode 100644 index 2d7b58d..0000000 --- a/src/rtc/mc146818a.vhd +++ /dev/null @@ -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; \ No newline at end of file diff --git a/src/tsconf.v b/src/tsconf.v index 6245721..92c4399 100644 --- a/src/tsconf.v +++ b/src/tsconf.v @@ -787,17 +787,17 @@ end mc146818a SE9 ( - .reset(reset), - .clk(clk_28mhz), - .ena(ena_0_4375mhz), - .cs(1), - .keyscancode(key_scancode), - .rtc(RTC), - .cmoscfg(CMOSCfg), - .wr(mc146818a_wr), - .a(gluclock_addr[7:0]), - .di(cpu_do_bus), - .do(mc146818a_do_bus) + .RESET(reset), + .CLK(clk_28mhz), + .ENA(ena_0_4375mhz), + .CS(1), + .KEYSCANCODE(key_scancode), + .RTC(RTC), + .CMOSCfg(CMOSCfg), + .WR(mc146818a_wr), + .A(gluclock_addr[7:0]), + .DI(cpu_do_bus), + .DO(mc146818a_do_bus) );