diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf
index 7a1839be..ec7e9dbf 100644
--- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf
+++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/SpyHunter.qsf
@@ -41,7 +41,7 @@
# ========================
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
-set_global_assignment -name LAST_QUARTUS_VERSION 13.1
+set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26"
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
# Pin & Location Assignments
@@ -214,7 +214,7 @@ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name ENABLE_SIGNALTAP OFF
-set_global_assignment -name USE_SIGNALTAP_FILE output_files/reset.stp
+set_global_assignment -name USE_SIGNALTAP_FILE output_files/csd.stp
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS"
@@ -222,7 +222,7 @@ set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
set_global_assignment -name SMART_RECOMPILE ON
-set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE ON
+set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF
set_global_assignment -name SYSTEMVERILOG_FILE rtl/SpyHunter_MiST.sv
set_global_assignment -name VHDL_FILE rtl/spy_hunter.vhd
set_global_assignment -name VHDL_FILE rtl/ctc_counter.vhd
@@ -235,10 +235,13 @@ set_global_assignment -name VHDL_FILE rtl/cmos_ram.vhd
set_global_assignment -name VHDL_FILE rtl/rom/spy_hunter_bg_bits_2.vhd
set_global_assignment -name VHDL_FILE rtl/rom/spy_hunter_bg_bits_1.vhd
set_global_assignment -name VHDL_FILE rtl/rom/spy_hunter_ch_bits.vhd
-set_global_assignment -name VHDL_FILE rtl/rom/spy_hunter_sound_cpu.vhd
set_global_assignment -name VHDL_FILE rtl/rom/midssio_82s123.vhd
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd
+set_global_assignment -name VHDL_FILE rtl/cheap_squeak_deluxe.vhd
+set_global_assignment -name VHDL_FILE ../../../common/IO/pia6821.vhd
+set_global_assignment -name QIP_FILE ../../../common/CPU/68000/FX68k/fx68k.qip
set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
+set_global_assignment -name SIGNALTAP_FILE output_files/csd.stp
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv
index 8caa38db..7383d4d3 100644
--- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv
+++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/SpyHunter_MiST.sv
@@ -82,6 +82,7 @@ wire [7:0] joy_1;
wire scandoublerD;
wire ypbpr;
wire [15:0] audio_l, audio_r;
+wire [9:0] csd_audio;
wire hs, vs, cs;
wire blankn;
wire [2:0] g, r, b;
@@ -89,6 +90,8 @@ wire [15:0] rom_addr;
wire [15:0] rom_do;
wire [12:0] snd_addr;
wire [15:0] snd_do;
+wire [14:1] csd_addr;
+wire [15:0] csd_do;
wire [14:0] sp_addr;
wire [31:0] sp_do;
wire ioctl_downl;
@@ -111,7 +114,21 @@ data_io data_io(
.ioctl_dout ( ioctl_dout )
);
-wire [24:0] sp_ioctl_addr = ioctl_addr - 17'h10000;//Wrong for CSD roms !!!
+// ROM structure:
+
+// 0000 - DFFF - Main ROM (8 bit)
+// E000 - FFFF - Super Sound board ROM (8 bit)
+// 10000 - 17FFF - CSD ROM (16 bit)
+// 18000 - Sprite ROMs (32 bit)
+
+// spy-hunter_cpu_pg0_2-9-84.6d spy-hunter_cpu_pg1_2-9-84.7d spy-hunter_cpu_pg2_2-9-84.8d spy-hunter_cpu_pg3_2-9-84.9d spy-hunter_cpu_pg4_2-9-84.10d spy-hunter_cpu_pg5_2-9-84.11d
+// spy-hunter_snd_0_sd_11-18-83.a7 spy-hunter_snd_1_sd_11-18-83.a8
+// spy-hunter_cs_deluxe_u17_b_11-18-83.u17 spy-hunter_cs_deluxe_u18_d_11-18-83.u18 spy-hunter_cs_deluxe_u7_a_11-18-83.u7 spy-hunter_cs_deluxe_u8_c_11-18-83.u8
+// spy-hunter_video_1fg_11-18-83.a7 spy-hunter_video_0fg_11-18-83.a8 spy-hunter_video_3fg_11-18-83.a5 spy-hunter_video_2fg_11-18-83.a6 spy-hunter_video_5fg_11-18-83.a3 spy-hunter_video_4fg_11-18-83.a4 spy-hunter_video_7fg_11-18-83.a1 spy-hunter_video_6fg_11-18-83.a2
+
+wire [24:0] rom_ioctl_addr = ~ioctl_addr[16] ? ioctl_addr : // 8 bit ROMs
+ {ioctl_addr[24:16], ioctl_addr[15], ioctl_addr[13:0], ioctl_addr[14]}; // 16 bit ROM
+wire [24:0] sp_ioctl_addr = ioctl_addr - 17'h18000;
reg port1_req, port2_req;
sdram sdram(
@@ -119,19 +136,22 @@ sdram sdram(
.init_n ( pll_locked ),
.clk ( clk_mem ),
- // port1 used for main + sound CPU
+ // port1 used for main + sound CPUs
.port1_req ( port1_req ),
.port1_ack ( ),
- .port1_a ( ioctl_addr[23:1] ),
- .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ),
+ .port1_a ( rom_ioctl_addr[23:1] ),
+ .port1_ds ( {rom_ioctl_addr[0], ~rom_ioctl_addr[0]} ),
.port1_we ( ioctl_downl ),
.port1_d ( {ioctl_dout, ioctl_dout} ),
.port1_q ( ),
.cpu1_addr ( ioctl_downl ? 16'hffff : {1'b0, rom_addr[15:1]} ),
.cpu1_q ( rom_do ),
- .cpu2_addr ( 16'hffff ),// CSD Roms - Change Rom File for this
- .cpu2_q ( ),//snd_do ),
+ // need higher priority for CSD
+ .cpu2_addr ( ioctl_downl ? 16'hffff : (16'h8000 + csd_addr[14:1]) ),
+ .cpu2_q ( csd_do ),
+ .cpu3_addr ( ioctl_downl ? 16'hffff : (16'h7000 + snd_addr[12:1]) ),
+ .cpu3_q ( snd_do ),
// port2 for sprite graphics
.port2_req ( port2_req ),
@@ -202,6 +222,7 @@ spy_hunter spy_hunter(
.separate_audio(1'b0),
.audio_out_l(audio_l),
.audio_out_r(audio_r),
+ .csd_audio_out(csd_audio),
.coin1(btn_coin),
.coin2(1'b0),
.shift(m_shift),
@@ -220,6 +241,8 @@ spy_hunter spy_hunter(
.cpu_rom_do ( rom_addr[0] ? rom_do[15:8] : rom_do[7:0] ),
.snd_rom_addr ( snd_addr ),
.snd_rom_do ( snd_addr[0] ? snd_do[15:8] : snd_do[7:0] ),
+ .csd_rom_addr ( csd_addr ),
+ .csd_rom_do ( csd_do ),
.sp_addr ( sp_addr ),
.sp_graphx32_do ( sp_do )
);
@@ -279,16 +302,16 @@ dac #(
dac_l(
.clk_i(clk_sys),
.res_n_i(1),
- .dac_i(audio_l),
+ .dac_i(audio_l + { csd_audio, 5'd0 }),
.dac_o(AUDIO_L)
);
-
+
dac #(
.C_bits(16))
dac_r(
.clk_i(clk_sys),
.res_n_i(1),
- .dac_i(audio_r),
+ .dac_i(audio_r + { csd_audio, 5'd0 }),
.dac_o(AUDIO_R)
);
diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/cheap_squeak_deluxe.vhd b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/cheap_squeak_deluxe.vhd
new file mode 100644
index 00000000..6e9dc8f1
--- /dev/null
+++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/cheap_squeak_deluxe.vhd
@@ -0,0 +1,219 @@
+-- Midway Cheap Squeak Deluxe sound board
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.fx68k.all;
+
+entity cheap_squeak_deluxe is
+port(
+ clock_40 : in std_logic;
+ reset : in std_logic;
+ input : in std_logic_vector(7 downto 0);
+ rom_addr : out std_logic_vector(14 downto 1);
+ rom_do : in std_logic_vector(15 downto 0);
+ audio_out : out std_logic_vector(9 downto 0)
+);
+end cheap_squeak_deluxe;
+
+architecture rtl of cheap_squeak_deluxe is
+
+signal cpu_ce1 : std_logic;
+signal cpu_ce2 : std_logic;
+signal cpu_ce_count : std_logic_vector( 4 downto 0);
+signal cpu_addr : std_logic_vector(23 downto 1);
+signal cpu_rw : std_logic;
+signal cpu_irq : std_logic;
+signal cpu_data_in : std_logic_vector(15 downto 0);
+signal cpu_data_out : std_logic_vector(15 downto 0);
+signal cpu_as_n : std_logic;
+signal cpu_lds_n : std_logic;
+signal cpu_uds_n : std_logic;
+signal cpu_dtack_n : std_logic;
+signal cpu_vpa_n : std_logic;
+signal cpu_fc : std_logic_vector( 2 downto 0);
+signal cpu_ipl2_N : std_logic;
+signal cpu_sel : std_logic;
+
+signal pia_data_out : std_logic_vector( 7 downto 0);
+signal pia_pa_in : std_logic_vector( 7 downto 0);
+signal pia_pa_out : std_logic_vector( 7 downto 0);
+signal pia_pa_oe : std_logic_vector( 7 downto 0);
+signal pia_pb_in : std_logic_vector( 7 downto 0);
+signal pia_pb_out : std_logic_vector( 7 downto 0);
+signal pia_pb_oe : std_logic_vector( 7 downto 0);
+signal pia_ca1_in : std_logic;
+signal pia_ca2_out : std_logic;
+signal pia_cb1_in : std_logic;
+signal pia_cb2_out : std_logic;
+signal pia_irqa : std_logic;
+signal pia_irqb : std_logic;
+
+signal cs_rom : std_logic;
+signal cs_ram : std_logic;
+signal cs_pia : std_logic;
+
+signal ram_we : std_logic;
+signal ram_data_out : std_logic_vector(15 downto 0);
+
+signal romd1 : std_logic;
+signal romd : std_logic;
+signal rom_addr_out : std_logic_vector(14 downto 1);
+signal rom_addr_old : std_logic_vector(14 downto 1);
+
+begin
+
+fx68k_inst: fx68k
+port map (
+ clk => clock_40,
+ extReset => reset,
+ pwrUp => reset,
+ enPhi1 => cpu_ce1,
+ enPhi2 => cpu_ce2,
+
+ eRWn => cpu_rw,
+ ASn => cpu_as_n,
+ LDSn => cpu_lds_n,
+ UDSn => cpu_uds_n,
+ E => open,
+ VMAn => open,
+ FC0 => cpu_fc(0),
+ FC1 => cpu_fc(1),
+ FC2 => cpu_fc(2),
+ BGn => open,
+ oRESETn => open,
+ oHALTEDn => open,
+ DTACKn => cpu_dtack_n,
+ VPAn => cpu_vpa_n,
+ BERRn => '1',
+ BRn => '1',
+ BGACKn => '1',
+ IPL0n => '1',
+ IPL1n => '1',
+ IPL2n => cpu_ipl2_n,
+ iEdb => cpu_data_in,
+ oEdb => cpu_data_out,
+ eab => cpu_addr
+);
+
+-- U6
+u_wram : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 11)
+port map(
+ clk => clock_40,
+ we => ram_we and not cpu_uds_n,
+ addr => cpu_addr(11 downto 1),
+ d => cpu_data_out(15 downto 8),
+ q => ram_data_out(15 downto 8)
+);
+
+-- U16
+l_wram : entity work.gen_ram
+generic map( dWidth => 8, aWidth => 11)
+port map(
+ clk => clock_40,
+ we => ram_we and not cpu_lds_n,
+ addr => cpu_addr(11 downto 1),
+ d => cpu_data_out(7 downto 0),
+ q => ram_data_out(7 downto 0)
+);
+
+-- U9
+pia6821 : entity work.pia6821
+port map (
+ clk => clock_40,
+ rst => reset,
+ cs => cs_pia,
+ rw => cpu_rw,
+ addr => cpu_addr(1)&cpu_addr(2), -- wired in reverse order
+ data_in => cpu_data_out(15 downto 8),
+ data_out => pia_data_out,
+ irqa => pia_irqa,
+ irqb => pia_irqb,
+ pa_i => pia_pa_in,
+ pa_o => pia_pa_out,
+ pa_oe => open,
+ ca1 => pia_ca1_in,
+ ca2_i => '0',
+ ca2_o => open,
+ ca2_oe => open,
+ pb_i => pia_pb_in,
+ pb_o => pia_pb_out,
+ pb_oe => open,
+ cb1 => pia_cb1_in,
+ cb2_i => '0',
+ cb2_o => open,
+ cb2_oe => open
+);
+
+-- clock enable generation: 40/5 = 8 MHz effective clock (original: 7.5 MHz)
+process (clock_40, reset)
+begin
+ if reset = '1' then
+ cpu_ce1 <= '0';
+ cpu_ce2 <= '0';
+ cpu_ce_count <= (others => '0');
+ elsif rising_edge(clock_40) then
+ cpu_ce1 <= '0';
+ cpu_ce2 <= '0';
+ cpu_ce_count <= cpu_ce_count + 1;
+ if cpu_ce_count = 2 then
+ cpu_ce1 <= '1';
+ end if;
+ if cpu_ce_count = 4 then
+ cpu_ce2 <= '1';
+ cpu_ce_count <= (others => '0');
+ end if;
+ end if;
+end process;
+
+process (clock_40, reset)
+begin
+ if reset = '1' then
+ rom_addr_old <= (others => '1');
+ elsif rising_edge(clock_40) then
+
+ rom_addr_old <= rom_addr_out;
+
+ -- ROMD signal - DTACK_N delay for ROM access
+ if cpu_as_n = '1' then
+ romd1 <= '0';
+ romd <= '0';
+ elsif cpu_ce1 = '1' then
+ romd1 <= '1';
+ romd <= romd1;
+ end if;
+ end if;
+end process;
+
+cpu_sel <= '1' when cpu_as_n = '0' and (cpu_uds_n = '0' or cpu_lds_n = '0') else '0';
+cpu_dtack_n <= not ((cs_rom and romd) or cs_ram or cs_pia);
+
+-- auto-vectored interrupt handling
+cpu_vpa_n <= '0' when cpu_fc = "111" else '1';
+cpu_ipl2_n <= not (pia_irqa or pia_irqb);
+
+cs_rom <= '1' when cpu_sel = '1' and cpu_addr(16 downto 15) = "00" else '0';
+cs_ram <= '1' when cpu_sel = '1' and cpu_addr(16 downto 14) = "111" else '0';
+-- PIA uses 6800 bus cycle originally with VMA, VPA and E clock
+cs_pia <= '1' when cpu_sel = '1' and cpu_addr(16 downto 14) = "110" else '0';
+
+ram_we <= '1' when cs_ram = '1' and cpu_rw = '0' else '0';
+
+cpu_data_in <= rom_do when cs_rom = '1' else
+ ram_data_out when cs_ram = '1' else
+ pia_data_out&x"FF" when cs_pia = '1' else
+ (others => '1');
+
+rom_addr_out <= cpu_addr(14 downto 1) when cs_rom = '1' else rom_addr_old;
+rom_addr <= rom_addr_out;
+
+audio_out <= pia_pa_out(7 downto 0)&pia_pb_out(7 downto 6);
+pia_pb_in(5 downto 0) <= "00"&input(3 downto 0); -- stat1-stat0, sr3-sr0
+pia_ca1_in <= not input(4); -- sirq
+pia_pa_in <= (others => '0');
+pia_cb1_in <= '0'; -- spare
+
+
+end rtl;
diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/rom/spy_hunter_sound_cpu.vhd b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/rom/spy_hunter_sound_cpu.vhd
deleted file mode 100644
index 6e402ca2..00000000
--- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/rom/spy_hunter_sound_cpu.vhd
+++ /dev/null
@@ -1,534 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all,ieee.numeric_std.all;
-
-entity spy_hunter_sound_cpu is
-port (
- clk : in std_logic;
- addr : in std_logic_vector(12 downto 0);
- data : out std_logic_vector(7 downto 0)
-);
-end entity;
-
-architecture prom of spy_hunter_sound_cpu is
- type rom is array(0 to 8191) of std_logic_vector(7 downto 0);
- signal rom_data: rom := (
- X"F3",X"00",X"00",X"00",X"31",X"FF",X"83",X"ED",X"56",X"18",X"55",X"06",X"06",X"11",X"09",X"00",
- X"DD",X"21",X"BC",X"82",X"DD",X"7E",X"01",X"FE",X"FF",X"28",X"13",X"DD",X"4E",X"02",X"21",X"27",
- X"00",X"E5",X"DD",X"6E",X"00",X"67",X"E9",X"11",X"09",X"00",X"DD",X"36",X"02",X"00",X"DD",X"19",
- X"10",X"E2",X"C9",X"85",X"6F",X"D0",X"24",X"C9",X"F5",X"3A",X"00",X"E0",X"3A",X"75",X"83",X"3D",
- X"28",X"06",X"32",X"75",X"83",X"F1",X"FB",X"C9",X"3C",X"32",X"74",X"83",X"3E",X"06",X"32",X"75",
- X"83",X"F1",X"FB",X"C9",X"C5",X"42",X"21",X"00",X"00",X"54",X"78",X"B7",X"C3",X"E7",X"00",X"FF",
- X"21",X"00",X"B0",X"36",X"0F",X"21",X"02",X"B0",X"36",X"F0",X"3A",X"00",X"F0",X"CB",X"47",X"20",
- X"4F",X"CB",X"4F",X"20",X"2E",X"AF",X"32",X"77",X"83",X"CD",X"29",X"05",X"CD",X"E1",X"05",X"3A",
- X"77",X"83",X"FE",X"00",X"28",X"1D",X"CB",X"67",X"20",X"05",X"01",X"00",X"10",X"18",X"03",X"01",
- X"00",X"80",X"11",X"01",X"00",X"60",X"69",X"32",X"00",X"D0",X"37",X"3F",X"ED",X"52",X"20",X"FC",
- X"2F",X"18",X"F2",X"3E",X"FF",X"32",X"00",X"D0",X"3A",X"00",X"F0",X"CB",X"57",X"20",X"08",X"CD",
- X"55",X"06",X"18",X"EF",X"3A",X"00",X"F0",X"CB",X"5F",X"20",X"F9",X"CD",X"7C",X"06",X"18",X"F4",
- X"06",X"00",X"CD",X"38",X"06",X"06",X"FF",X"CD",X"38",X"06",X"06",X"55",X"CD",X"38",X"06",X"06",
- X"AA",X"CD",X"38",X"06",X"AF",X"32",X"77",X"83",X"CD",X"29",X"05",X"CD",X"E1",X"05",X"3A",X"77",
- X"83",X"32",X"00",X"C0",X"CD",X"EE",X"00",X"28",X"03",X"19",X"10",X"FD",X"C1",X"C9",X"31",X"FF",
- X"83",X"F3",X"ED",X"56",X"CD",X"13",X"01",X"CD",X"AD",X"07",X"FB",X"AF",X"32",X"74",X"83",X"CD",
- X"82",X"01",X"CD",X"0B",X"00",X"CD",X"AD",X"07",X"00",X"00",X"00",X"3A",X"74",X"83",X"B7",X"28",
- X"FA",X"18",X"E8",X"21",X"3C",X"1E",X"06",X"20",X"11",X"20",X"80",X"DD",X"21",X"00",X"80",X"7E",
- X"DD",X"77",X"00",X"2F",X"12",X"13",X"23",X"DD",X"23",X"10",X"F4",X"06",X"06",X"11",X"09",X"00",
- X"DD",X"21",X"BC",X"82",X"DD",X"36",X"00",X"FF",X"DD",X"36",X"01",X"FF",X"DD",X"36",X"02",X"00",
- X"DD",X"36",X"03",X"00",X"DD",X"36",X"04",X"00",X"DD",X"36",X"05",X"00",X"DD",X"36",X"06",X"00",
- X"DD",X"19",X"10",X"E0",X"06",X"03",X"21",X"6B",X"83",X"36",X"00",X"23",X"10",X"FB",X"3E",X"01",
- X"32",X"0C",X"83",X"32",X"20",X"83",X"3D",X"32",X"1F",X"83",X"3A",X"00",X"90",X"E6",X"80",X"32",
- X"6E",X"83",X"3E",X"55",X"32",X"71",X"83",X"3E",X"06",X"32",X"75",X"83",X"3E",X"52",X"32",X"76",
- X"83",X"C9",X"3A",X"6E",X"83",X"47",X"3A",X"00",X"90",X"A8",X"CB",X"7F",X"20",X"31",X"CB",X"40",
- X"28",X"1E",X"CB",X"80",X"78",X"32",X"6E",X"83",X"CD",X"E0",X"01",X"3A",X"70",X"83",X"CB",X"47",
- X"28",X"0E",X"CD",X"95",X"02",X"CD",X"A3",X"03",X"CD",X"06",X"04",X"CD",X"02",X"19",X"18",X"23",
- X"CD",X"A3",X"03",X"3A",X"6F",X"83",X"CB",X"47",X"28",X"19",X"CD",X"02",X"19",X"18",X"14",X"78",
- X"2F",X"CB",X"C7",X"32",X"6E",X"83",X"CD",X"A3",X"03",X"3A",X"6F",X"83",X"CB",X"47",X"28",X"03",
- X"CD",X"02",X"19",X"3E",X"01",X"32",X"20",X"83",X"32",X"0C",X"83",X"3D",X"32",X"1F",X"83",X"C9",
- X"3E",X"01",X"32",X"70",X"83",X"DD",X"21",X"00",X"90",X"DD",X"46",X"00",X"CB",X"70",X"28",X"23",
- X"FD",X"21",X"00",X"80",X"FD",X"7E",X"0F",X"E6",X"8F",X"4F",X"78",X"17",X"E6",X"70",X"B1",X"FD",
- X"77",X"0F",X"FD",X"7E",X"1F",X"E6",X"8F",X"4F",X"78",X"17",X"17",X"17",X"17",X"E6",X"70",X"B1",
- X"FD",X"77",X"1F",X"DD",X"7E",X"01",X"4F",X"FE",X"00",X"28",X"23",X"CB",X"7F",X"28",X"6E",X"DD",
- X"7E",X"02",X"CB",X"7F",X"20",X"67",X"79",X"E6",X"7F",X"4F",X"06",X"06",X"FD",X"21",X"BC",X"82",
- X"11",X"09",X"00",X"FD",X"7E",X"06",X"B9",X"CC",X"61",X"02",X"FD",X"19",X"10",X"F5",X"FD",X"21",
- X"6B",X"83",X"DD",X"46",X"02",X"78",X"E6",X"7F",X"28",X"24",X"CB",X"77",X"20",X"20",X"FD",X"77",
- X"01",X"DD",X"7E",X"01",X"CB",X"7F",X"C0",X"DD",X"7E",X"03",X"FE",X"00",X"C8",X"FD",X"77",X"02",
- X"C9",X"DD",X"7E",X"03",X"E5",X"FD",X"6E",X"07",X"FD",X"66",X"08",X"77",X"E1",X"C9",X"DD",X"4E",
- X"01",X"79",X"FE",X"00",X"20",X"09",X"DD",X"7E",X"03",X"FE",X"00",X"20",X"D4",X"18",X"09",X"CB",
- X"79",X"28",X"CE",X"CB",X"78",X"20",X"CA",X"AF",X"32",X"70",X"83",X"18",X"C4",X"79",X"E6",X"7F",
- X"32",X"6B",X"83",X"18",X"A9",X"06",X"03",X"21",X"6B",X"83",X"C5",X"7E",X"4F",X"FE",X"00",X"CA",
- X"66",X"03",X"3A",X"76",X"83",X"91",X"DA",X"66",X"03",X"79",X"FE",X"06",X"20",X"04",X"F3",X"C3",
- X"00",X"00",X"79",X"FE",X"01",X"20",X"0C",X"DD",X"21",X"00",X"80",X"DD",X"7E",X"1F",X"F6",X"80",
- X"DD",X"77",X"1F",X"79",X"FE",X"02",X"20",X"0F",X"DD",X"21",X"00",X"80",X"DD",X"7E",X"1F",X"E6",
- X"7F",X"DD",X"77",X"1F",X"CD",X"6D",X"03",X"79",X"FE",X"03",X"20",X"03",X"CD",X"6D",X"03",X"79",
- X"FE",X"04",X"20",X"07",X"3E",X"52",X"32",X"76",X"83",X"18",X"0A",X"79",X"FE",X"05",X"20",X"05",
- X"3E",X"52",X"32",X"76",X"83",X"79",X"D9",X"6F",X"26",X"00",X"54",X"5D",X"29",X"29",X"19",X"19",
- X"19",X"11",X"01",X"08",X"19",X"EB",X"1A",X"FE",X"00",X"20",X"1F",X"01",X"0C",X"83",X"60",X"69",
- X"3E",X"06",X"08",X"13",X"1A",X"FE",X"00",X"28",X"4A",X"7E",X"CD",X"33",X"00",X"1A",X"77",X"60",
- X"69",X"34",X"08",X"3D",X"FE",X"00",X"20",X"EA",X"18",X"39",X"3E",X"06",X"21",X"20",X"83",X"08",
- X"13",X"1A",X"FE",X"00",X"28",X"2D",X"7E",X"CD",X"33",X"00",X"1A",X"77",X"26",X"00",X"6F",X"29",
- X"01",X"46",X"0A",X"09",X"01",X"20",X"83",X"0A",X"CB",X"27",X"E5",X"21",X"33",X"83",X"CD",X"33",
- X"00",X"EB",X"E3",X"7E",X"12",X"23",X"13",X"7E",X"12",X"0A",X"3C",X"02",X"D1",X"60",X"69",X"08",
- X"3D",X"20",X"CC",X"D9",X"AF",X"77",X"23",X"C1",X"05",X"C2",X"9A",X"02",X"C9",X"D9",X"DD",X"21",
- X"BC",X"82",X"01",X"09",X"00",X"11",X"0C",X"83",X"3E",X"01",X"12",X"62",X"6B",X"3E",X"06",X"08",
- X"DD",X"7E",X"03",X"FE",X"00",X"28",X"0B",X"1A",X"CD",X"33",X"00",X"DD",X"7E",X"03",X"77",X"62",
- X"6B",X"34",X"DD",X"09",X"08",X"3D",X"20",X"E7",X"3E",X"00",X"32",X"1F",X"83",X"3C",X"32",X"20",
- X"83",X"D9",X"C9",X"AF",X"32",X"6F",X"83",X"21",X"0C",X"83",X"7E",X"D6",X"01",X"28",X"2A",X"11",
- X"09",X"00",X"4F",X"DD",X"21",X"BC",X"82",X"06",X"06",X"23",X"7E",X"DD",X"BE",X"04",X"20",X"13",
- X"AF",X"DD",X"77",X"06",X"DD",X"77",X"04",X"DD",X"77",X"05",X"3C",X"32",X"6F",X"83",X"0D",X"20",
- X"E2",X"18",X"06",X"DD",X"19",X"10",X"E4",X"18",X"F5",X"21",X"1F",X"83",X"7E",X"4F",X"FE",X"00",
- X"C8",X"3E",X"01",X"32",X"6F",X"83",X"06",X"06",X"21",X"5C",X"1E",X"DD",X"21",X"BC",X"82",X"11",
- X"09",X"00",X"79",X"A6",X"28",X"0A",X"AF",X"DD",X"77",X"06",X"DD",X"77",X"04",X"DD",X"77",X"05",
- X"DD",X"19",X"23",X"10",X"ED",X"C9",X"3A",X"20",X"83",X"D6",X"01",X"C8",X"08",X"CD",X"38",X"04",
- X"CD",X"54",X"04",X"79",X"CB",X"27",X"21",X"33",X"83",X"CD",X"33",X"00",X"7A",X"FE",X"00",X"20",
- X"11",X"CB",X"7E",X"20",X"0A",X"E5",X"CD",X"95",X"04",X"E1",X"7A",X"FE",X"00",X"20",X"03",X"CD",
- X"CE",X"04",X"23",X"36",X"00",X"08",X"18",X"D1",X"06",X"00",X"0E",X"01",X"16",X"01",X"3A",X"20",
- X"83",X"5F",X"21",X"33",X"83",X"23",X"7A",X"BB",X"C8",X"23",X"23",X"78",X"BE",X"30",X"02",X"46",
- X"4A",X"14",X"18",X"F2",X"79",X"CB",X"27",X"21",X"33",X"83",X"CD",X"33",X"00",X"C5",X"06",X"06",
- X"4E",X"11",X"09",X"00",X"21",X"5C",X"1E",X"DD",X"21",X"BC",X"82",X"7E",X"A1",X"28",X"1D",X"DD",
- X"7E",X"04",X"FE",X"00",X"20",X"16",X"21",X"20",X"83",X"C1",X"79",X"CD",X"33",X"00",X"7E",X"DD",
- X"77",X"04",X"DD",X"70",X"05",X"AF",X"DD",X"77",X"03",X"16",X"01",X"C9",X"DD",X"19",X"23",X"10",
- X"DA",X"16",X"00",X"C1",X"C9",X"26",X"06",X"11",X"09",X"00",X"DD",X"21",X"BC",X"82",X"DD",X"7E",
- X"04",X"FE",X"00",X"20",X"15",X"79",X"21",X"20",X"83",X"CD",X"33",X"00",X"7E",X"DD",X"77",X"04",
- X"DD",X"70",X"05",X"AF",X"DD",X"77",X"03",X"16",X"01",X"C9",X"DD",X"19",X"25",X"20",X"DF",X"16",
- X"00",X"21",X"33",X"83",X"79",X"CB",X"27",X"CD",X"33",X"00",X"F6",X"3F",X"77",X"C9",X"16",X"FF",
- X"1E",X"00",X"E5",X"C5",X"4E",X"06",X"00",X"DD",X"21",X"BC",X"82",X"21",X"5C",X"1E",X"7E",X"A1",
- X"28",X"08",X"DD",X"7E",X"05",X"BA",X"30",X"02",X"57",X"58",X"D5",X"11",X"09",X"00",X"DD",X"19",
- X"D1",X"23",X"04",X"78",X"FE",X"06",X"20",X"E6",X"C1",X"7A",X"B8",X"30",X"24",X"21",X"20",X"83",
- X"79",X"CD",X"33",X"00",X"4E",X"6B",X"26",X"00",X"54",X"5D",X"29",X"29",X"29",X"19",X"EB",X"DD",
- X"21",X"BC",X"82",X"DD",X"19",X"DD",X"71",X"04",X"DD",X"70",X"05",X"AF",X"DD",X"77",X"03",X"E1",
- X"C9",X"E1",X"C0",X"CB",X"76",X"C8",X"E5",X"18",X"D4",X"DD",X"21",X"D1",X"05",X"AF",X"F5",X"DD",
- X"6E",X"00",X"DD",X"66",X"01",X"7C",X"B5",X"20",X"0A",X"F1",X"47",X"3A",X"77",X"83",X"B0",X"32",
- X"77",X"83",X"C9",X"DD",X"5E",X"04",X"DD",X"56",X"05",X"DD",X"4E",X"02",X"DD",X"46",X"03",X"ED",
- X"B0",X"DD",X"6E",X"00",X"DD",X"66",X"01",X"DD",X"5E",X"02",X"DD",X"56",X"03",X"7A",X"B3",X"28",
- X"11",X"06",X"02",X"3E",X"00",X"77",X"BE",X"C2",X"CC",X"05",X"F6",X"FF",X"10",X"F7",X"23",X"1B",
- X"18",X"EB",X"DD",X"66",X"01",X"DD",X"6E",X"00",X"DD",X"5E",X"02",X"DD",X"56",X"03",X"7A",X"B3",
- X"28",X"06",X"36",X"00",X"23",X"1B",X"18",X"F6",X"DD",X"6E",X"00",X"DD",X"66",X"01",X"DD",X"5E",
- X"02",X"DD",X"56",X"03",X"7A",X"B3",X"28",X"14",X"7E",X"FE",X"00",X"20",X"2F",X"3E",X"01",X"77",
- X"BE",X"C2",X"CC",X"05",X"CB",X"27",X"30",X"F7",X"23",X"1B",X"18",X"E8",X"AF",X"DD",X"66",X"05",
- X"DD",X"6E",X"04",X"DD",X"56",X"01",X"DD",X"5E",X"00",X"DD",X"4E",X"02",X"DD",X"46",X"03",X"ED",
- X"B0",X"47",X"F1",X"B0",X"11",X"07",X"00",X"DD",X"19",X"C3",X"2E",X"05",X"DD",X"7E",X"06",X"18",
- X"DC",X"00",X"80",X"00",X"02",X"00",X"80",X"10",X"00",X"82",X"00",X"02",X"00",X"80",X"10",X"00",
- X"00",X"DD",X"21",X"1D",X"06",X"16",X"00",X"DD",X"6E",X"02",X"DD",X"66",X"03",X"DD",X"4E",X"00",
- X"DD",X"46",X"01",X"78",X"B1",X"28",X"1A",X"AF",X"86",X"23",X"0D",X"20",X"FB",X"05",X"20",X"F8",
- X"DD",X"BE",X"04",X"28",X"05",X"7A",X"DD",X"B6",X"05",X"57",X"01",X"06",X"00",X"DD",X"09",X"18",
- X"D6",X"7A",X"B7",X"C8",X"47",X"3A",X"77",X"83",X"B0",X"32",X"77",X"83",X"C9",X"00",X"10",X"00",
- X"00",X"D7",X"01",X"00",X"10",X"00",X"10",X"BD",X"02",X"00",X"00",X"00",X"20",X"00",X"04",X"00",
- X"00",X"00",X"30",X"00",X"08",X"00",X"00",X"29",X"3A",X"00",X"90",X"B8",X"20",X"FA",X"3A",X"01",
- X"90",X"B8",X"20",X"F4",X"3A",X"02",X"90",X"B8",X"20",X"EE",X"3A",X"03",X"90",X"B8",X"20",X"E8",
- X"78",X"32",X"00",X"C0",X"C9",X"06",X"00",X"CD",X"B5",X"06",X"0E",X"00",X"3E",X"AD",X"CD",X"F5",
- X"06",X"0E",X"01",X"3E",X"07",X"CD",X"F5",X"06",X"06",X"01",X"CD",X"B5",X"06",X"0E",X"00",X"3E",
- X"AD",X"CD",X"F5",X"06",X"0E",X"01",X"3E",X"77",X"CD",X"F5",X"06",X"C9",X"CD",X"55",X"06",X"16",
- X"10",X"3E",X"00",X"1E",X"FF",X"06",X"00",X"0E",X"00",X"CD",X"F5",X"06",X"2F",X"0E",X"01",X"CD",
- X"F5",X"06",X"06",X"01",X"32",X"78",X"83",X"E6",X"7F",X"CD",X"F5",X"06",X"3A",X"78",X"83",X"2F",
- X"0E",X"00",X"CD",X"F5",X"06",X"3C",X"E6",X"0F",X"47",X"07",X"07",X"07",X"07",X"B0",X"1D",X"20",
- X"FD",X"15",X"20",X"CF",X"C9",X"CD",X"0C",X"07",X"36",X"00",X"DD",X"36",X"00",X"F4",X"36",X"01",
- X"DD",X"36",X"00",X"01",X"36",X"02",X"DD",X"36",X"00",X"FA",X"36",X"03",X"DD",X"36",X"00",X"00",
- X"36",X"04",X"DD",X"36",X"00",X"7D",X"36",X"05",X"DD",X"36",X"00",X"00",X"36",X"08",X"DD",X"36",
- X"00",X"0B",X"36",X"09",X"DD",X"36",X"00",X"0B",X"36",X"0A",X"DD",X"36",X"00",X"0B",X"36",X"07",
- X"DD",X"36",X"00",X"F8",X"C9",X"CD",X"0C",X"07",X"32",X"72",X"83",X"AF",X"A9",X"28",X"09",X"36",
- X"0F",X"3A",X"72",X"83",X"DD",X"77",X"00",X"C9",X"36",X"0E",X"18",X"F5",X"32",X"72",X"83",X"AF",
- X"A8",X"3A",X"72",X"83",X"20",X"08",X"21",X"00",X"A0",X"DD",X"21",X"02",X"A0",X"C9",X"21",X"00",
- X"B0",X"DD",X"21",X"02",X"B0",X"C9",X"21",X"F4",X"07",X"16",X"00",X"19",X"56",X"21",X"E8",X"07",
- X"79",X"CB",X"27",X"5F",X"7A",X"16",X"00",X"19",X"5E",X"23",X"56",X"6F",X"26",X"00",X"19",X"11",
- X"40",X"80",X"19",X"C9",X"21",X"62",X"1E",X"CB",X"27",X"D2",X"53",X"07",X"24",X"CD",X"33",X"00",
- X"C3",X"56",X"07",X"CD",X"33",X"00",X"E5",X"1E",X"38",X"51",X"CD",X"54",X"00",X"11",X"EC",X"1C",
- X"19",X"C5",X"4E",X"23",X"46",X"60",X"69",X"C1",X"D1",X"1A",X"77",X"23",X"13",X"1A",X"77",X"C9",
- X"C5",X"3E",X"06",X"90",X"47",X"57",X"1E",X"38",X"CD",X"54",X"00",X"EB",X"FD",X"21",X"EC",X"1C",
- X"FD",X"19",X"16",X"00",X"58",X"21",X"3E",X"82",X"19",X"FD",X"7E",X"14",X"4F",X"FE",X"0F",X"7E",
- X"20",X"17",X"CB",X"27",X"CB",X"27",X"CB",X"27",X"CB",X"27",X"E6",X"F0",X"47",X"FD",X"6E",X"12",
- X"FD",X"66",X"13",X"7E",X"A1",X"B0",X"77",X"C1",X"C9",X"E6",X"0F",X"18",X"EF",X"01",X"1F",X"00",
- X"21",X"00",X"80",X"11",X"20",X"80",X"09",X"EB",X"09",X"06",X"0F",X"DD",X"21",X"00",X"B0",X"1A",
- X"BE",X"28",X"07",X"77",X"DD",X"70",X"00",X"32",X"02",X"B0",X"1B",X"2B",X"05",X"F2",X"BF",X"07",
- X"06",X"0F",X"DD",X"21",X"00",X"A0",X"1A",X"BE",X"28",X"07",X"77",X"DD",X"70",X"00",X"32",X"02",
- X"A0",X"1B",X"2B",X"05",X"F2",X"D6",X"07",X"C9",X"00",X"00",X"55",X"00",X"AA",X"00",X"FF",X"00",
- X"54",X"01",X"A9",X"01",X"00",X"11",X"22",X"33",X"44",X"4D",X"49",X"44",X"57",X"41",X"59",X"00",
- X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
- X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
- X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
- X"00",X"00",X"01",X"01",X"02",X"03",X"04",X"05",X"06",X"00",X"01",X"02",X"03",X"04",X"05",X"06",
- X"01",X"07",X"07",X"07",X"07",X"07",X"07",X"00",X"07",X"07",X"07",X"07",X"07",X"07",X"01",X"08",
- X"00",X"00",X"00",X"00",X"00",X"01",X"09",X"0A",X"0B",X"0C",X"00",X"00",X"01",X"47",X"00",X"00",
- X"00",X"00",X"00",X"00",X"47",X"00",X"00",X"00",X"00",X"00",X"01",X"40",X"00",X"00",X"00",X"00",
- X"00",X"00",X"26",X"00",X"00",X"00",X"00",X"00",X"01",X"10",X"00",X"00",X"00",X"00",X"00",X"01",
- X"11",X"00",X"00",X"00",X"00",X"00",X"01",X"12",X"13",X"14",X"15",X"16",X"17",X"00",X"12",X"13",
- X"14",X"15",X"16",X"17",X"01",X"18",X"19",X"1A",X"1B",X"1C",X"00",X"00",X"18",X"19",X"1A",X"1B",
- X"1C",X"00",X"01",X"1D",X"1E",X"1F",X"20",X"00",X"00",X"00",X"1D",X"1E",X"1F",X"20",X"00",X"00",
- X"01",X"21",X"22",X"23",X"00",X"00",X"00",X"00",X"21",X"22",X"23",X"00",X"00",X"00",X"01",X"24",
- X"25",X"00",X"00",X"00",X"00",X"00",X"24",X"25",X"00",X"00",X"00",X"00",X"01",X"26",X"00",X"00",
- X"00",X"00",X"00",X"00",X"2B",X"00",X"00",X"00",X"00",X"00",X"01",X"27",X"00",X"00",X"00",X"00",
- X"00",X"00",X"27",X"00",X"00",X"00",X"00",X"00",X"00",X"2A",X"00",X"00",X"00",X"00",X"00",X"01",
- X"29",X"00",X"00",X"00",X"00",X"00",X"00",X"29",X"00",X"00",X"00",X"00",X"00",X"01",X"2A",X"00",
- X"00",X"00",X"00",X"00",X"01",X"2B",X"00",X"00",X"00",X"00",X"00",X"01",X"2C",X"00",X"00",X"00",
- X"00",X"00",X"01",X"2D",X"00",X"00",X"00",X"00",X"00",X"00",X"2D",X"00",X"00",X"00",X"00",X"00",
- X"01",X"2E",X"2F",X"00",X"00",X"00",X"00",X"00",X"2E",X"2F",X"35",X"36",X"41",X"42",X"01",X"35",
- X"36",X"00",X"00",X"00",X"00",X"01",X"41",X"42",X"00",X"00",X"00",X"00",X"01",X"30",X"00",X"00",
- X"00",X"00",X"00",X"00",X"30",X"00",X"00",X"00",X"00",X"00",X"01",X"31",X"00",X"00",X"00",X"00",
- X"00",X"01",X"32",X"00",X"00",X"00",X"00",X"00",X"01",X"33",X"00",X"00",X"00",X"00",X"00",X"00",
- X"33",X"00",X"00",X"00",X"00",X"00",X"01",X"34",X"00",X"00",X"00",X"00",X"00",X"00",X"34",X"00",
- X"00",X"00",X"00",X"00",X"01",X"37",X"28",X"3F",X"00",X"00",X"00",X"00",X"37",X"28",X"3F",X"00",
- X"00",X"00",X"01",X"38",X"00",X"00",X"00",X"00",X"00",X"01",X"39",X"00",X"00",X"00",X"00",X"00",
- X"00",X"39",X"00",X"00",X"00",X"00",X"00",X"01",X"3A",X"00",X"00",X"00",X"00",X"00",X"00",X"3A",
- X"00",X"00",X"00",X"00",X"00",X"01",X"3B",X"00",X"00",X"00",X"00",X"00",X"00",X"3B",X"00",X"00",
- X"00",X"00",X"00",X"01",X"3C",X"00",X"00",X"00",X"00",X"00",X"00",X"3C",X"00",X"00",X"00",X"00",
- X"00",X"01",X"3D",X"00",X"00",X"00",X"00",X"00",X"00",X"3D",X"00",X"00",X"00",X"00",X"00",X"01",
- X"3E",X"00",X"00",X"00",X"00",X"00",X"00",X"3E",X"3D",X"3C",X"3B",X"00",X"00",X"01",X"0F",X"00",
- X"00",X"00",X"00",X"00",X"01",X"0D",X"00",X"00",X"00",X"00",X"00",X"01",X"43",X"00",X"00",X"00",
- X"00",X"00",X"01",X"44",X"00",X"00",X"00",X"00",X"00",X"01",X"45",X"00",X"00",X"00",X"00",X"00",
- X"01",X"46",X"00",X"00",X"00",X"00",X"00",X"00",X"43",X"44",X"45",X"46",X"00",X"00",X"01",X"48",
- X"49",X"4A",X"48",X"49",X"4A",X"00",X"31",X"00",X"00",X"00",X"00",X"00",X"01",X"4B",X"00",X"00",
- X"00",X"00",X"00",X"00",X"4B",X"00",X"00",X"00",X"00",X"00",X"01",X"4C",X"4D",X"00",X"00",X"00",
- X"00",X"00",X"4C",X"4D",X"00",X"00",X"00",X"00",X"01",X"4E",X"00",X"00",X"00",X"00",X"00",X"00",
- X"4E",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"01",X"01",X"02",X"02",X"04",X"03",X"08",X"04",
- X"10",X"05",X"20",X"06",X"FF",X"90",X"82",X"81",X"C2",X"77",X"C4",X"77",X"C8",X"77",X"D0",X"77",
- X"82",X"0D",X"C2",X"1E",X"82",X"0F",X"82",X"29",X"82",X"32",X"81",X"80",X"82",X"80",X"84",X"64",
- X"88",X"80",X"90",X"7F",X"A0",X"80",X"81",X"7C",X"82",X"62",X"84",X"80",X"88",X"71",X"90",X"82",
- X"81",X"7C",X"82",X"51",X"88",X"50",X"90",X"71",X"81",X"80",X"88",X"80",X"90",X"81",X"82",X"2C",
- X"88",X"4D",X"C8",X"2C",X"E0",X"50",X"81",X"7E",X"C1",X"7D",X"88",X"70",X"88",X"70",X"C2",X"31",
- X"84",X"66",X"90",X"80",X"84",X"65",X"81",X"7F",X"88",X"57",X"81",X"7E",X"84",X"67",X"C8",X"2C",
- X"90",X"81",X"84",X"66",X"A0",X"60",X"C2",X"3F",X"E0",X"50",X"E0",X"50",X"E0",X"50",X"E0",X"50",
- X"E0",X"50",X"E0",X"50",X"82",X"70",X"C8",X"2C",X"90",X"82",X"84",X"67",X"E0",X"50",X"E0",X"50",
- X"E0",X"50",X"E0",X"50",X"82",X"50",X"89",X"51",X"92",X"51",X"A4",X"51",X"88",X"56",X"E0",X"50",
- X"C1",X"50",X"81",X"7C",X"BE",X"0C",X"FF",X"FF",X"FF",X"FF",X"CC",X"0C",X"DA",X"0C",X"6D",X"18",
- X"EC",X"0C",X"FA",X"0C",X"6D",X"18",X"0F",X"0D",X"1D",X"0D",X"6D",X"18",X"32",X"0D",X"40",X"0D",
- X"6D",X"18",X"55",X"0D",X"63",X"0D",X"6D",X"18",X"78",X"0D",X"86",X"0D",X"6D",X"18",X"9E",X"0D",
- X"AC",X"0D",X"7B",X"18",X"BE",X"0D",X"CC",X"0D",X"6D",X"18",X"E1",X"0D",X"ED",X"0D",X"04",X"16",
- X"1E",X"0E",X"2A",X"0E",X"04",X"16",X"3C",X"0E",X"48",X"0E",X"04",X"16",X"5D",X"0E",X"69",X"0E",
- X"04",X"16",X"BA",X"0E",X"C8",X"0E",X"74",X"18",X"DD",X"0E",X"EB",X"0E",X"88",X"18",X"15",X"0F",
- X"21",X"0F",X"6D",X"18",X"2D",X"0F",X"39",X"0F",X"6D",X"18",X"4B",X"0F",X"59",X"0F",X"95",X"18",
- X"7D",X"0F",X"D1",X"0F",X"88",X"18",X"8B",X"0F",X"D1",X"0F",X"88",X"18",X"99",X"0F",X"D1",X"0F",
- X"88",X"18",X"A7",X"0F",X"D1",X"0F",X"88",X"18",X"B5",X"0F",X"D1",X"0F",X"88",X"18",X"C3",X"0F",
- X"D1",X"0F",X"88",X"18",X"FA",X"0F",X"40",X"10",X"88",X"18",X"08",X"10",X"40",X"10",X"88",X"18",
- X"16",X"10",X"40",X"10",X"88",X"18",X"24",X"10",X"40",X"10",X"88",X"18",X"32",X"10",X"40",X"10",
- X"88",X"18",X"5D",X"10",X"8D",X"10",X"88",X"18",X"69",X"10",X"8D",X"10",X"88",X"18",X"75",X"10",
- X"8D",X"10",X"88",X"18",X"81",X"10",X"8D",X"10",X"88",X"18",X"AA",X"10",X"CE",X"10",X"88",X"18",
- X"B6",X"10",X"CE",X"10",X"88",X"18",X"C2",X"10",X"CE",X"10",X"88",X"18",X"EB",X"10",X"03",X"11",
- X"88",X"18",X"F7",X"10",X"03",X"11",X"88",X"18",X"20",X"11",X"2C",X"11",X"A2",X"18",X"F6",X"15",
- X"1C",X"17",X"17",X"16",X"41",X"14",X"88",X"14",X"AF",X"18",X"BA",X"11",X"C8",X"11",X"6D",X"18",
- X"D7",X"11",X"E5",X"11",X"74",X"18",X"F4",X"11",X"02",X"12",X"74",X"18",X"11",X"12",X"1D",X"12",
- X"88",X"18",X"37",X"12",X"45",X"12",X"88",X"18",X"61",X"12",X"9B",X"12",X"DC",X"18",X"AA",X"12",
- X"BA",X"12",X"DC",X"18",X"E7",X"12",X"F5",X"12",X"88",X"18",X"12",X"13",X"20",X"13",X"C9",X"18",
- X"4D",X"13",X"70",X"13",X"95",X"18",X"7F",X"13",X"8B",X"13",X"88",X"18",X"96",X"13",X"B1",X"13",
- X"A4",X"13",X"61",X"12",X"D5",X"13",X"DC",X"18",X"AA",X"12",X"F3",X"13",X"DC",X"18",X"23",X"14",
- X"4F",X"14",X"AF",X"18",X"18",X"15",X"24",X"15",X"88",X"18",X"4D",X"15",X"A8",X"15",X"EF",X"18",
- X"5B",X"15",X"A8",X"15",X"EF",X"18",X"C6",X"15",X"46",X"16",X"17",X"16",X"D2",X"15",X"24",X"16",
- X"17",X"16",X"DE",X"15",X"46",X"16",X"17",X"16",X"EA",X"15",X"35",X"16",X"17",X"16",X"31",X"14",
- X"4F",X"14",X"AF",X"18",X"69",X"15",X"77",X"15",X"BC",X"18",X"61",X"12",X"6D",X"17",X"DC",X"18",
- X"AA",X"12",X"7C",X"17",X"DC",X"18",X"57",X"16",X"75",X"16",X"EF",X"18",X"61",X"16",X"86",X"16",
- X"EF",X"18",X"61",X"16",X"97",X"16",X"EF",X"18",X"6B",X"16",X"A8",X"16",X"EF",X"18",X"7E",X"0E",
- X"8E",X"0E",X"DC",X"18",X"41",X"14",X"D0",X"14",X"AF",X"18",X"23",X"14",X"D0",X"14",X"AF",X"18",
- X"31",X"14",X"D0",X"14",X"AF",X"18",X"8B",X"17",X"A5",X"17",X"95",X"18",X"B4",X"17",X"D8",X"17",
- X"DC",X"18",X"C6",X"17",X"D8",X"17",X"DC",X"18",X"25",X"18",X"33",X"18",X"C9",X"18",X"CD",X"65",
- X"19",X"00",X"00",X"FF",X"0A",X"00",X"FF",X"C9",X"CD",X"70",X"07",X"C9",X"CD",X"65",X"19",X"01",
- X"02",X"FF",X"0A",X"01",X"00",X"DE",X"02",X"01",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",
- X"01",X"00",X"04",X"01",X"03",X"01",X"34",X"00",X"04",X"01",X"FD",X"00",X"CD",X"65",X"19",X"01",
- X"02",X"FF",X"0A",X"01",X"00",X"AA",X"02",X"01",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",
- X"01",X"00",X"01",X"3C",X"00",X"04",X"01",X"03",X"01",X"34",X"00",X"04",X"01",X"FD",X"00",X"CD",
- X"65",X"19",X"01",X"02",X"FF",X"0A",X"01",X"00",X"7B",X"02",X"01",X"FF",X"C9",X"CD",X"6A",X"1A",
- X"C7",X"0C",X"00",X"01",X"00",X"01",X"78",X"00",X"04",X"01",X"03",X"01",X"34",X"00",X"04",X"01",
- X"FD",X"00",X"CD",X"65",X"19",X"01",X"02",X"FF",X"0A",X"01",X"00",X"52",X"02",X"01",X"FF",X"C9",
- X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"B4",X"00",X"04",X"01",X"03",X"01",X"34",
- X"00",X"04",X"01",X"FD",X"00",X"CD",X"65",X"19",X"01",X"02",X"FF",X"0A",X"01",X"00",X"2D",X"02",
- X"01",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"F0",X"00",X"04",X"01",
- X"03",X"01",X"34",X"00",X"04",X"01",X"FD",X"00",X"CD",X"65",X"19",X"01",X"02",X"FF",X"0A",X"01",
- X"00",X"0C",X"02",X"01",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"C8",
- X"00",X"01",X"64",X"00",X"04",X"01",X"03",X"01",X"34",X"00",X"04",X"01",X"FD",X"00",X"CD",X"65",
- X"19",X"01",X"05",X"FF",X"0A",X"0E",X"00",X"50",X"02",X"00",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",
- X"0C",X"00",X"01",X"FF",X"02",X"01",X"07",X"01",X"07",X"00",X"07",X"01",X"FE",X"00",X"CD",X"65",
- X"19",X"01",X"01",X"FF",X"0A",X"03",X"00",X"A9",X"02",X"00",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",
- X"0C",X"00",X"01",X"04",X"04",X"01",X"03",X"02",X"02",X"FF",X"01",X"05",X"00",X"05",X"01",X"FE",
- X"00",X"CD",X"65",X"19",X"01",X"08",X"FF",X"0A",X"07",X"18",X"1E",X"FF",X"C9",X"CD",X"6A",X"1A",
- X"FF",X"0D",X"00",X"01",X"00",X"07",X"02",X"01",X"01",X"14",X"00",X"0E",X"03",X"FF",X"00",X"CD",
- X"7B",X"1B",X"0D",X"0E",X"01",X"FF",X"01",X"02",X"01",X"01",X"03",X"FF",X"00",X"CD",X"6A",X"1A",
- X"C7",X"0C",X"02",X"02",X"FF",X"05",X"01",X"F0",X"FF",X"05",X"02",X"10",X"00",X"00",X"CD",X"65",
- X"19",X"01",X"08",X"FF",X"0A",X"07",X"18",X"19",X"FF",X"C9",X"CD",X"6A",X"1A",X"FF",X"0D",X"00",
- X"01",X"00",X"07",X"02",X"01",X"01",X"12",X"00",X"0E",X"03",X"FF",X"00",X"CD",X"65",X"19",X"01",
- X"07",X"FF",X"0A",X"00",X"18",X"16",X"FF",X"C9",X"CD",X"6A",X"1A",X"FF",X"0D",X"00",X"01",X"00",
- X"01",X"0F",X"00",X"05",X"02",X"03",X"01",X"0A",X"00",X"0F",X"05",X"FF",X"00",X"CD",X"65",X"19",
- X"01",X"07",X"FF",X"0A",X"00",X"18",X"11",X"FF",X"C9",X"CD",X"6A",X"1A",X"FF",X"0D",X"00",X"01",
- X"00",X"01",X"0F",X"00",X"05",X"02",X"03",X"01",X"08",X"00",X"0F",X"05",X"FF",X"00",X"CD",X"65",
- X"19",X"01",X"01",X"FF",X"0A",X"00",X"00",X"81",X"02",X"00",X"2A",X"01",X"FF",X"C9",X"CD",X"6A",
- X"1A",X"9A",X"0E",X"01",X"01",X"00",X"07",X"C0",X"01",X"00",X"CD",X"6A",X"1A",X"A9",X"0E",X"00",
- X"01",X"00",X"05",X"01",X"02",X"08",X"50",X"FF",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"02",X"02",
- X"00",X"90",X"04",X"02",X"00",X"FF",X"03",X"02",X"00",X"00",X"CD",X"65",X"19",X"10",X"07",X"FF",
- X"0A",X"0E",X"04",X"10",X"2A",X"0B",X"FF",X"C9",X"CD",X"6A",X"1A",X"C8",X"0C",X"00",X"01",X"00",
- X"04",X"06",X"FF",X"02",X"02",X"FF",X"03",X"14",X"01",X"07",X"0B",X"01",X"00",X"CD",X"65",X"19",
- X"01",X"04",X"FF",X"0A",X"0C",X"18",X"A8",X"04",X"1F",X"FF",X"C9",X"CD",X"7B",X"1B",X"06",X"0F",
- X"01",X"1C",X"01",X"01",X"EA",X"01",X"01",X"13",X"00",X"01",X"01",X"F7",X"01",X"01",X"08",X"01",
- X"01",X"F7",X"01",X"01",X"09",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"03",X"02",
- X"01",X"01",X"01",X"FD",X"00",X"CD",X"65",X"19",X"10",X"00",X"FF",X"0A",X"0F",X"04",X"0B",X"FF",
- X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"0F",X"01",X"FF",X"00",X"CD",X"65",X"19",
- X"10",X"04",X"FF",X"0A",X"0D",X"04",X"04",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",
- X"00",X"01",X"07",X"F3",X"01",X"0D",X"0D",X"01",X"08",X"F3",X"00",X"CD",X"65",X"19",X"10",X"0B",
- X"FF",X"2A",X"0B",X"0A",X"0F",X"04",X"1F",X"FF",X"C9",X"CD",X"6A",X"1A",X"6B",X"0F",X"00",X"01",
- X"00",X"04",X"04",X"FF",X"01",X"01",X"04",X"0F",X"06",X"FF",X"00",X"CD",X"6A",X"1A",X"C8",X"0C",
- X"01",X"01",X"00",X"03",X"05",X"00",X"01",X"02",X"FB",X"1E",X"03",X"00",X"00",X"CD",X"65",X"19",
- X"01",X"04",X"FF",X"0A",X"0F",X"18",X"00",X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",
- X"FF",X"0A",X"0F",X"18",X"04",X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",
- X"0F",X"18",X"08",X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",X"18",
- X"0C",X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",X"18",X"10",X"2A",
- X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",X"18",X"14",X"2A",X"04",X"FF",
- X"C9",X"CD",X"7B",X"1B",X"DF",X"0F",X"01",X"FF",X"05",X"01",X"02",X"05",X"01",X"FE",X"00",X"CD",
- X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"08",X"00",X"03",X"01",X"FB",X"01",X"03",X"00",
- X"03",X"01",X"05",X"01",X"20",X"00",X"0F",X"0A",X"FF",X"00",X"CD",X"65",X"19",X"01",X"04",X"FF",
- X"0A",X"0F",X"18",X"00",X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",
- X"18",X"04",X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",X"18",X"08",
- X"2A",X"04",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",X"18",X"0C",X"2A",X"04",
- X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"0A",X"0F",X"18",X"10",X"2A",X"04",X"FF",X"C9",
- X"CD",X"7B",X"1B",X"4E",X"10",X"01",X"FF",X"06",X"01",X"02",X"06",X"01",X"FE",X"00",X"CD",X"6A",
- X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"10",X"00",X"0F",X"09",X"FF",X"00",X"CD",X"65",X"19",
- X"01",X"04",X"FF",X"18",X"00",X"0A",X"0F",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"18",
- X"02",X"0A",X"0F",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"18",X"04",X"0A",X"0F",X"FF",
- X"C9",X"CD",X"65",X"19",X"01",X"04",X"FF",X"18",X"06",X"0A",X"0F",X"FF",X"C9",X"CD",X"7B",X"1B",
- X"9B",X"10",X"01",X"FF",X"04",X"01",X"04",X"04",X"01",X"FC",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",
- X"00",X"01",X"00",X"01",X"0C",X"00",X"0F",X"08",X"FF",X"00",X"CD",X"65",X"19",X"01",X"02",X"FF",
- X"0A",X"0F",X"18",X"10",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"02",X"FF",X"0A",X"0F",X"18",X"15",
- X"FF",X"C9",X"CD",X"65",X"19",X"01",X"02",X"FF",X"0A",X"0F",X"18",X"18",X"FF",X"C9",X"CD",X"7B",
- X"1B",X"DC",X"10",X"01",X"FF",X"04",X"01",X"02",X"04",X"01",X"FE",X"00",X"CD",X"6A",X"1A",X"C7",
- X"0C",X"00",X"01",X"00",X"01",X"18",X"00",X"0F",X"0E",X"FF",X"00",X"CD",X"65",X"19",X"01",X"07",
- X"FF",X"0A",X"0F",X"18",X"00",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"07",X"FF",X"0A",X"0F",X"18",
- X"02",X"FF",X"C9",X"CD",X"7B",X"1B",X"11",X"11",X"01",X"FF",X"07",X"01",X"02",X"07",X"01",X"FE",
- X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"0A",X"00",X"0F",X"07",X"FF",X"00",
- X"CD",X"65",X"19",X"10",X"06",X"FF",X"0A",X"0C",X"04",X"1E",X"FF",X"C9",X"CD",X"6A",X"1A",X"3E",
- X"11",X"00",X"01",X"01",X"03",X"03",X"01",X"01",X"04",X"F1",X"01",X"09",X"0C",X"00",X"CD",X"6A",
- X"1A",X"C7",X"0C",X"01",X"01",X"FF",X"01",X"09",X"F1",X"01",X"07",X"F1",X"01",X"05",X"0F",X"01",
- X"03",X"0F",X"00",X"CD",X"65",X"19",X"10",X"08",X"FF",X"0A",X"0E",X"04",X"18",X"2C",X"23",X"2A",
- X"08",X"FF",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"2C",X"2C",X"CD",
- X"C9",X"1C",X"20",X"CD",X"33",X"1A",X"02",X"2A",X"2A",X"C9",X"CD",X"6A",X"1A",X"89",X"11",X"00",
- X"01",X"FF",X"07",X"01",X"FE",X"01",X"30",X"0E",X"00",X"CD",X"70",X"07",X"CD",X"6A",X"1A",X"9B",
- X"11",X"02",X"01",X"FF",X"04",X"21",X"FF",X"04",X"17",X"01",X"00",X"CD",X"6A",X"1A",X"B6",X"11",
- X"01",X"01",X"FF",X"06",X"20",X"01",X"07",X"18",X"FF",X"04",X"20",X"02",X"03",X"20",X"FE",X"07",
- X"18",X"01",X"08",X"20",X"FF",X"00",X"CD",X"A9",X"1C",X"C9",X"CD",X"65",X"19",X"10",X"03",X"FF",
- X"0A",X"0F",X"04",X"1E",X"2A",X"03",X"FF",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",
- X"01",X"04",X"F1",X"01",X"08",X"0F",X"00",X"CD",X"65",X"19",X"10",X"0F",X"FF",X"0A",X"0F",X"04",
- X"00",X"2A",X"0F",X"FF",X"C9",X"CD",X"6A",X"1A",X"C8",X"0C",X"00",X"01",X"07",X"08",X"03",X"FF",
- X"07",X"02",X"01",X"00",X"CD",X"65",X"19",X"10",X"0F",X"FF",X"0A",X"0F",X"2A",X"0F",X"04",X"1F",
- X"FF",X"C9",X"CD",X"6A",X"1A",X"C8",X"0C",X"00",X"01",X"00",X"0F",X"0F",X"FF",X"0F",X"0F",X"01",
- X"00",X"CD",X"65",X"19",X"01",X"03",X"FF",X"0A",X"05",X"18",X"85",X"FF",X"C9",X"CD",X"7B",X"1B",
- X"2B",X"12",X"01",X"05",X"03",X"01",X"FD",X"02",X"01",X"02",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",
- X"00",X"01",X"00",X"0A",X"03",X"01",X"00",X"CD",X"65",X"19",X"01",X"08",X"FF",X"0A",X"0C",X"18",
- X"00",X"04",X"08",X"FF",X"C9",X"CD",X"7B",X"1B",X"52",X"12",X"01",X"00",X"50",X"01",X"02",X"FF",
- X"FE",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"01",X"04",X"F4",X"03",X"01",X"04",
- X"00",X"CD",X"65",X"19",X"01",X"0F",X"FF",X"0A",X"0F",X"02",X"0F",X"2A",X"0F",X"00",X"FF",X"FF",
- X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"01",X"03",X"F1",X"01",X"06",X"0F",X"00",
- X"CD",X"70",X"07",X"CD",X"6A",X"1A",X"71",X"12",X"01",X"01",X"00",X"03",X"60",X"FF",X"02",X"50",
- X"FF",X"02",X"40",X"FF",X"01",X"40",X"FF",X"FF",X"FF",X"00",X"00",X"CD",X"6A",X"1A",X"80",X"12",
- X"02",X"01",X"FF",X"04",X"08",X"F0",X"04",X"08",X"10",X"00",X"CD",X"65",X"19",X"01",X"0F",X"FF",
- X"0A",X"0F",X"02",X"00",X"00",X"10",X"2A",X"0F",X"FF",X"C9",X"CD",X"6A",X"1A",X"80",X"12",X"02",
- X"01",X"FF",X"03",X"01",X"FF",X"01",X"06",X"03",X"00",X"CD",X"6A",X"1A",X"D8",X"12",X"00",X"01",
- X"FF",X"05",X"01",X"01",X"05",X"02",X"FF",X"00",X"CD",X"6A",X"1A",X"C8",X"0C",X"01",X"01",X"FF",
- X"05",X"01",X"FF",X"05",X"02",X"01",X"00",X"CD",X"65",X"19",X"11",X"06",X"FF",X"18",X"A0",X"0A",
- X"0F",X"04",X"0C",X"FF",X"C9",X"CD",X"7B",X"1B",X"03",X"13",X"01",X"00",X"50",X"01",X"FE",X"FF",
- X"FF",X"00",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"01",X"03",X"F1",X"01",X"06",
- X"0F",X"00",X"CD",X"65",X"19",X"10",X"04",X"FF",X"0A",X"09",X"2A",X"04",X"04",X"04",X"FF",X"C9",
- X"CD",X"6A",X"1A",X"2F",X"13",X"02",X"01",X"FF",X"03",X"0A",X"FF",X"03",X"0F",X"01",X"00",X"CD",
- X"6A",X"1A",X"3E",X"13",X"00",X"01",X"FF",X"03",X"0A",X"01",X"03",X"0F",X"FF",X"00",X"CD",X"6A",
- X"1A",X"C8",X"0C",X"01",X"01",X"FF",X"03",X"0A",X"FF",X"03",X"0F",X"01",X"00",X"CD",X"65",X"19",
- X"10",X"0B",X"FF",X"0A",X"0F",X"04",X"1F",X"2A",X"0B",X"FF",X"C9",X"CD",X"6A",X"1A",X"C8",X"0C",
- X"01",X"01",X"00",X"01",X"2C",X"00",X"01",X"01",X"04",X"0F",X"02",X"FF",X"0F",X"06",X"01",X"00",
- X"CD",X"6A",X"1A",X"5B",X"13",X"00",X"01",X"00",X"01",X"4B",X"00",X"0F",X"06",X"FF",X"00",X"CD",
- X"65",X"19",X"01",X"08",X"FF",X"18",X"A0",X"0A",X"0C",X"FF",X"C9",X"CD",X"7B",X"1B",X"52",X"12",
- X"01",X"00",X"FF",X"FF",X"00",X"00",X"CD",X"65",X"19",X"10",X"0F",X"FF",X"04",X"06",X"2A",X"0F",
- X"0A",X"04",X"FF",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"2A",X"2A",
- X"C9",X"CD",X"6A",X"1A",X"C3",X"13",X"00",X"01",X"00",X"0A",X"01",X"01",X"01",X"1C",X"00",X"09",
- X"0A",X"FF",X"00",X"CD",X"6A",X"1A",X"C8",X"0C",X"01",X"01",X"00",X"07",X"03",X"FF",X"03",X"09",
- X"FF",X"02",X"28",X"01",X"00",X"CD",X"70",X"07",X"CD",X"6A",X"1A",X"05",X"14",X"01",X"01",X"FF",
- X"01",X"01",X"F8",X"04",X"B0",X"01",X"03",X"B0",X"FF",X"02",X"B0",X"01",X"03",X"B0",X"FF",X"01",
- X"01",X"08",X"00",X"CD",X"70",X"07",X"CD",X"6A",X"1A",X"14",X"14",X"01",X"01",X"00",X"01",X"01",
- X"F8",X"FF",X"FF",X"00",X"00",X"CD",X"6A",X"1A",X"71",X"12",X"02",X"01",X"FF",X"04",X"08",X"F0",
- X"04",X"08",X"10",X"00",X"CD",X"6A",X"1A",X"71",X"12",X"02",X"01",X"FF",X"03",X"01",X"FF",X"01",
- X"06",X"03",X"00",X"CD",X"65",X"19",X"01",X"01",X"FF",X"0A",X"0A",X"02",X"00",X"00",X"59",X"FF",
- X"C9",X"CD",X"65",X"19",X"11",X"04",X"FF",X"0A",X"0A",X"02",X"00",X"00",X"6B",X"04",X"1A",X"FF",
- X"C9",X"CD",X"65",X"19",X"01",X"01",X"FF",X"0A",X"0A",X"02",X"00",X"00",X"62",X"FF",X"C9",X"CD",
- X"6A",X"1A",X"C1",X"14",X"01",X"02",X"02",X"05",X"01",X"03",X"00",X"02",X"02",X"FA",X"FF",X"05",
- X"01",X"04",X"00",X"02",X"02",X"F9",X"FF",X"05",X"01",X"05",X"00",X"02",X"02",X"F8",X"FF",X"05",
- X"01",X"06",X"00",X"02",X"02",X"F7",X"FF",X"05",X"01",X"07",X"00",X"02",X"02",X"F6",X"FF",X"05",
- X"01",X"08",X"00",X"02",X"02",X"F5",X"FF",X"00",X"CD",X"6A",X"1A",X"C1",X"14",X"01",X"02",X"02",
- X"02",X"02",X"FA",X"FF",X"05",X"01",X"03",X"00",X"02",X"02",X"F9",X"FF",X"05",X"01",X"04",X"00",
- X"02",X"02",X"F8",X"FF",X"05",X"01",X"05",X"00",X"02",X"02",X"F7",X"FF",X"05",X"01",X"07",X"00",
- X"02",X"02",X"F6",X"FF",X"05",X"01",X"06",X"00",X"02",X"02",X"F5",X"FF",X"05",X"01",X"08",X"00",
- X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"04",X"05",X"01",X"02",X"02",X"FE",X"00",
- X"CD",X"6A",X"1A",X"09",X"15",X"01",X"02",X"00",X"06",X"01",X"03",X"00",X"02",X"01",X"FA",X"FF",
- X"06",X"01",X"04",X"00",X"02",X"01",X"F9",X"FF",X"06",X"01",X"05",X"00",X"02",X"01",X"F8",X"FF",
- X"06",X"01",X"06",X"00",X"02",X"01",X"F7",X"FF",X"06",X"01",X"07",X"00",X"02",X"01",X"F6",X"FF",
- X"06",X"01",X"08",X"00",X"02",X"01",X"F5",X"FF",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",
- X"00",X"05",X"0C",X"01",X"0C",X"01",X"FF",X"00",X"CD",X"65",X"19",X"01",X"02",X"FF",X"0A",X"0C",
- X"18",X"8C",X"FF",X"C9",X"CD",X"7B",X"1B",X"35",X"15",X"01",X"09",X"03",X"01",X"FE",X"02",X"01",
- X"0A",X"01",X"01",X"EA",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"00",X"01",X"04",X"F4",
- X"01",X"06",X"0F",X"05",X"06",X"FF",X"05",X"03",X"FF",X"05",X"01",X"FF",X"00",X"CD",X"65",X"19",
- X"01",X"09",X"FF",X"0A",X"07",X"02",X"0C",X"00",X"00",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"08",
- X"FF",X"0A",X"09",X"02",X"0A",X"00",X"00",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"09",X"FF",X"0A",
- X"00",X"00",X"FF",X"02",X"0F",X"FF",X"C9",X"CD",X"6A",X"1A",X"86",X"15",X"00",X"01",X"01",X"01",
- X"01",X"0F",X"05",X"05",X"FD",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"01",X"01",X"01",X"01",X"01",
- X"F6",X"05",X"05",X"02",X"00",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"00",
- X"00",X"CD",X"33",X"1A",X"02",X"00",X"00",X"C9",X"CD",X"6A",X"1A",X"B7",X"15",X"02",X"01",X"FF",
- X"02",X"01",X"01",X"01",X"01",X"FE",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"04",
- X"10",X"01",X"FF",X"FF",X"00",X"00",X"CD",X"65",X"19",X"01",X"0B",X"00",X"0A",X"0D",X"2A",X"0B",
- X"FF",X"C9",X"CD",X"65",X"19",X"01",X"0B",X"00",X"0A",X"0D",X"2A",X"0B",X"FF",X"C9",X"CD",X"65",
- X"19",X"01",X"09",X"00",X"0A",X"0D",X"2A",X"09",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"09",X"00",
- X"0A",X"0D",X"2A",X"09",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"09",X"FF",X"0A",X"0D",X"02",X"0F",
- X"00",X"FF",X"FF",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"18",X"18",
- X"CD",X"33",X"1A",X"02",X"00",X"00",X"C9",X"CD",X"33",X"1A",X"00",X"02",X"02",X"CD",X"33",X"1A",
- X"01",X"0A",X"0A",X"C9",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"02",X"FF",X"02",X"01",X"00",X"FF",
- X"01",X"01",X"00",X"02",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"02",X"FF",X"03",X"01",X"00",
- X"FF",X"01",X"01",X"00",X"03",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"02",X"FF",X"01",X"01",
- X"00",X"03",X"03",X"01",X"00",X"FF",X"00",X"CD",X"65",X"19",X"01",X"0B",X"00",X"0A",X"0F",X"FF",
- X"C9",X"CD",X"65",X"19",X"01",X"0A",X"00",X"0A",X"0F",X"FF",X"C9",X"CD",X"65",X"19",X"01",X"09",
- X"00",X"0A",X"0F",X"FF",X"C9",X"CD",X"6A",X"1A",X"B9",X"16",X"01",X"02",X"FF",X"03",X"04",X"9D",
- X"FF",X"03",X"02",X"63",X"00",X"00",X"CD",X"6A",X"1A",X"C8",X"16",X"01",X"02",X"FF",X"03",X"04",
- X"B1",X"FF",X"03",X"02",X"4F",X"00",X"00",X"CD",X"6A",X"1A",X"C8",X"16",X"01",X"02",X"FF",X"03",
- X"02",X"C5",X"FF",X"03",X"01",X"3B",X"00",X"00",X"CD",X"6A",X"1A",X"D7",X"16",X"01",X"02",X"FF",
- X"03",X"02",X"CF",X"FF",X"03",X"01",X"31",X"00",X"00",X"CD",X"6A",X"1A",X"E6",X"16",X"02",X"01",
- X"FF",X"01",X"0C",X"FF",X"01",X"04",X"01",X"00",X"CD",X"6A",X"1A",X"F8",X"16",X"02",X"01",X"FF",
- X"01",X"06",X"FF",X"01",X"02",X"01",X"00",X"CD",X"6A",X"1A",X"0A",X"17",X"02",X"01",X"FF",X"01",
- X"03",X"FF",X"01",X"01",X"01",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",X"01",X"0C",
- X"00",X"03",X"04",X"FF",X"03",X"02",X"01",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",X"01",X"FF",
- X"01",X"06",X"00",X"03",X"02",X"FF",X"03",X"01",X"01",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",X"00",
- X"01",X"FF",X"01",X"03",X"00",X"01",X"03",X"FD",X"01",X"01",X"03",X"00",X"CD",X"6A",X"1A",X"2B",
- X"17",X"00",X"01",X"FF",X"05",X"01",X"FF",X"01",X"01",X"05",X"00",X"CD",X"6A",X"1A",X"C7",X"0C",
- X"01",X"01",X"FF",X"01",X"28",X"FC",X"01",X"07",X"04",X"01",X"1E",X"FA",X"01",X"05",X"06",X"01",
- X"32",X"FD",X"01",X"08",X"03",X"01",X"28",X"FB",X"01",X"0A",X"05",X"01",X"1E",X"FD",X"01",X"0C",
- X"03",X"00",X"CD",X"70",X"07",X"CD",X"6A",X"1A",X"71",X"12",X"01",X"01",X"00",X"01",X"01",X"F8",
- X"01",X"30",X"01",X"02",X"40",X"01",X"02",X"50",X"01",X"03",X"50",X"01",X"00",X"CD",X"6A",X"1A",
- X"52",X"17",X"02",X"01",X"FF",X"04",X"08",X"F0",X"04",X"08",X"10",X"00",X"CD",X"6A",X"1A",X"52",
- X"17",X"02",X"01",X"FF",X"03",X"01",X"FF",X"01",X"06",X"03",X"00",X"CD",X"65",X"19",X"10",X"06",
- X"FF",X"0A",X"0F",X"04",X"0F",X"2A",X"06",X"FF",X"C9",X"CD",X"6A",X"1A",X"C8",X"0C",X"01",X"01",
- X"00",X"06",X"0F",X"FF",X"00",X"CD",X"6A",X"1A",X"99",X"17",X"00",X"01",X"00",X"02",X"09",X"00",
- X"08",X"09",X"FF",X"00",X"CD",X"65",X"19",X"11",X"0B",X"FF",X"0A",X"0A",X"2A",X"0B",X"04",X"01",
- X"00",X"B8",X"02",X"00",X"FF",X"C9",X"CD",X"65",X"19",X"11",X"0B",X"FF",X"0A",X"0A",X"2A",X"0B",
- X"04",X"01",X"00",X"30",X"02",X"02",X"FF",X"C9",X"CD",X"6A",X"1A",X"0F",X"18",X"00",X"01",X"00",
- X"05",X"01",X"01",X"01",X"0A",X"00",X"05",X"01",X"FD",X"01",X"0F",X"00",X"05",X"01",X"03",X"01",
- X"0F",X"00",X"08",X"0A",X"FF",X"07",X"05",X"FF",X"00",X"CD",X"6A",X"1A",X"0F",X"18",X"02",X"01",
- X"00",X"0F",X"02",X"FF",X"FF",X"FF",X"00",X"00",X"01",X"63",X"00",X"08",X"13",X"01",X"00",X"CD",
- X"6A",X"1A",X"C8",X"0C",X"01",X"01",X"00",X"05",X"01",X"FF",X"FF",X"FF",X"00",X"00",X"01",X"63",
- X"00",X"08",X"13",X"01",X"00",X"CD",X"65",X"19",X"10",X"00",X"FF",X"0A",X"0C",X"04",X"12",X"2A",
- X"00",X"FF",X"C9",X"CD",X"6A",X"1A",X"42",X"18",X"00",X"01",X"FF",X"05",X"07",X"FF",X"05",X"0A",
- X"01",X"00",X"CD",X"6A",X"1A",X"5A",X"18",X"02",X"01",X"FF",X"01",X"10",X"F8",X"01",X"14",X"04",
- X"01",X"20",X"05",X"01",X"15",X"F7",X"01",X"1F",X"08",X"00",X"CD",X"6A",X"1A",X"C8",X"0C",X"01",
- X"01",X"FF",X"05",X"01",X"01",X"05",X"03",X"FF",X"00",X"00",X"00",X"00",X"00",X"CD",X"33",X"1A",
- X"00",X"0A",X"0A",X"C9",X"CD",X"33",X"1A",X"00",X"2A",X"2A",X"C9",X"CD",X"33",X"1A",X"00",X"0A",
- X"0A",X"CD",X"33",X"1A",X"01",X"0A",X"0A",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",
- X"1A",X"01",X"18",X"18",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"2A",
- X"2A",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"04",X"04",X"C9",X"CD",
- X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"00",X"00",X"C9",X"CD",X"33",X"1A",X"00",
- X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"02",X"02",X"C9",X"CD",X"33",X"1A",X"00",X"0A",X"0A",X"CD",
- X"33",X"1A",X"01",X"2A",X"2A",X"CD",X"33",X"1A",X"02",X"04",X"04",X"C9",X"CD",X"33",X"1A",X"00",
- X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"2A",X"2A",X"CD",X"33",X"1A",X"02",X"00",X"00",X"C9",X"CD",
- X"33",X"1A",X"00",X"0A",X"0A",X"CD",X"33",X"1A",X"01",X"00",X"00",X"CD",X"33",X"1A",X"02",X"02",
- X"02",X"C9",X"DD",X"21",X"BC",X"82",X"06",X"00",X"DD",X"7E",X"04",X"DD",X"BE",X"03",X"28",X"49",
- X"DD",X"77",X"03",X"DD",X"36",X"02",X"01",X"26",X"00",X"DD",X"6E",X"04",X"29",X"54",X"5D",X"19",
- X"19",X"11",X"E4",X"0A",X"19",X"5E",X"23",X"56",X"DD",X"E5",X"E5",X"EB",X"11",X"31",X"19",X"D5",
- X"E9",X"E1",X"DD",X"E1",X"23",X"7E",X"DD",X"77",X"00",X"23",X"7E",X"DD",X"77",X"01",X"DD",X"7E",
- X"04",X"FE",X"00",X"28",X"14",X"23",X"23",X"7E",X"FE",X"FF",X"28",X"0D",X"DD",X"E5",X"57",X"2B",
- X"5E",X"EB",X"11",X"57",X"19",X"D5",X"E9",X"DD",X"E1",X"11",X"09",X"00",X"DD",X"19",X"04",X"78",
- X"FE",X"06",X"20",X"A4",X"C9",X"50",X"1E",X"38",X"CD",X"54",X"00",X"11",X"EC",X"1C",X"19",X"E5",
- X"FD",X"E1",X"DD",X"E3",X"DD",X"CB",X"00",X"46",X"20",X"10",X"FD",X"7E",X"09",X"2F",X"4F",X"FD",
- X"5E",X"06",X"FD",X"56",X"07",X"1A",X"B1",X"12",X"18",X"0B",X"FD",X"5E",X"06",X"FD",X"56",X"07",
- X"1A",X"FD",X"A6",X"09",X"12",X"DD",X"CB",X"00",X"66",X"20",X"0A",X"FD",X"7E",X"08",X"2F",X"4F",
- X"1A",X"B1",X"12",X"18",X"05",X"1A",X"FD",X"A6",X"08",X"12",X"DD",X"4E",X"01",X"FD",X"7E",X"14",
- X"FE",X"0F",X"20",X"0A",X"79",X"CB",X"27",X"CB",X"27",X"CB",X"27",X"CB",X"27",X"4F",X"FD",X"5E",
- X"12",X"FD",X"56",X"13",X"1A",X"FD",X"A6",X"14",X"B1",X"12",X"DD",X"7E",X"02",X"4F",X"FE",X"FF",
- X"28",X"39",X"26",X"00",X"68",X"5D",X"54",X"29",X"29",X"29",X"19",X"11",X"BC",X"82",X"19",X"11",
- X"01",X"90",X"3E",X"06",X"CD",X"33",X"00",X"1A",X"E6",X"7F",X"77",X"23",X"FD",X"E5",X"D1",X"EB",
- X"79",X"CD",X"33",X"00",X"7E",X"12",X"23",X"13",X"66",X"6F",X"EB",X"72",X"21",X"03",X"90",X"7E",
- X"12",X"2B",X"7E",X"CB",X"77",X"28",X"04",X"E6",X"0F",X"13",X"12",X"DD",X"E5",X"E1",X"1E",X"03",
- X"16",X"00",X"19",X"D9",X"FD",X"E5",X"D1",X"D9",X"7E",X"FE",X"FF",X"28",X"12",X"D9",X"62",X"6B",
- X"CD",X"33",X"00",X"4E",X"23",X"46",X"D9",X"23",X"7E",X"D9",X"02",X"D9",X"23",X"18",X"E9",X"23",
- X"D1",X"E5",X"C9",X"DD",X"E1",X"48",X"DD",X"5E",X"00",X"CD",X"26",X"07",X"DD",X"5E",X"01",X"FD",
- X"E5",X"16",X"00",X"FD",X"19",X"FD",X"7E",X"00",X"77",X"23",X"FD",X"7E",X"01",X"77",X"FD",X"E1",
- X"DD",X"5E",X"02",X"FD",X"E5",X"FD",X"19",X"FD",X"7E",X"00",X"23",X"77",X"23",X"FD",X"7E",X"01",
- X"77",X"1E",X"03",X"DD",X"19",X"FD",X"E1",X"DD",X"E5",X"C9",X"FD",X"E1",X"C5",X"3E",X"06",X"90",
- X"4F",X"FD",X"5E",X"02",X"CD",X"26",X"07",X"C1",X"C5",X"E5",X"DD",X"E3",X"79",X"FE",X"00",X"28",
- X"33",X"DD",X"6E",X"00",X"DD",X"66",X"01",X"DD",X"5E",X"02",X"DD",X"56",X"03",X"7E",X"12",X"FD",
- X"CB",X"03",X"4E",X"28",X"04",X"23",X"13",X"7E",X"12",X"FD",X"7E",X"06",X"DD",X"77",X"04",X"FD",
- X"7E",X"05",X"DD",X"77",X"05",X"AF",X"DD",X"77",X"06",X"FD",X"7E",X"04",X"DD",X"77",X"07",X"DD",
- X"E1",X"C3",X"72",X"1B",X"DD",X"35",X"04",X"28",X"05",X"DD",X"E1",X"C3",X"72",X"1B",X"FD",X"46",
- X"03",X"CB",X"48",X"26",X"00",X"DD",X"6E",X"06",X"54",X"5D",X"20",X"04",X"0E",X"03",X"18",X"03",
- X"0E",X"04",X"29",X"19",X"19",X"16",X"00",X"1E",X"05",X"19",X"EB",X"FD",X"E5",X"FD",X"19",X"DD",
- X"6E",X"00",X"DD",X"66",X"01",X"DD",X"5E",X"02",X"DD",X"56",X"03",X"CB",X"48",X"20",X"07",X"FD",
- X"7E",X"02",X"86",X"12",X"18",X"10",X"C5",X"4E",X"23",X"46",X"FD",X"6E",X"02",X"FD",X"66",X"03",
- X"09",X"C1",X"EB",X"73",X"23",X"72",X"DD",X"35",X"05",X"20",X"5D",X"DD",X"34",X"06",X"16",X"00",
- X"59",X"FD",X"19",X"FD",X"7E",X"00",X"FE",X"00",X"20",X"3C",X"DD",X"7E",X"07",X"FE",X"00",X"28",
- X"1D",X"FE",X"FF",X"28",X"03",X"DD",X"35",X"07",X"AF",X"DD",X"77",X"06",X"FD",X"E1",X"FD",X"7E",
- X"05",X"DD",X"77",X"05",X"FD",X"7E",X"06",X"DD",X"77",X"04",X"DD",X"E1",X"18",X"34",X"FD",X"E1",
- X"DD",X"E1",X"C1",X"3E",X"06",X"90",X"21",X"5C",X"1E",X"16",X"00",X"5F",X"19",X"3A",X"1F",X"83",
- X"B6",X"32",X"1F",X"83",X"18",X"1D",X"FD",X"7E",X"01",X"DD",X"77",X"04",X"FD",X"7E",X"00",X"DD",
- X"77",X"05",X"FD",X"E1",X"DD",X"E1",X"18",X"0A",X"FD",X"7E",X"01",X"DD",X"77",X"04",X"FD",X"E1",
- X"DD",X"E1",X"C1",X"FD",X"6E",X"00",X"FD",X"66",X"01",X"E5",X"C9",X"FD",X"E1",X"C5",X"3E",X"06",
- X"90",X"4F",X"FD",X"5E",X"02",X"CD",X"26",X"07",X"59",X"C1",X"C5",X"E5",X"DD",X"E3",X"79",X"FE",
- X"00",X"28",X"48",X"C5",X"4B",X"16",X"00",X"1E",X"09",X"19",X"71",X"C1",X"2B",X"DD",X"75",X"00",
- X"DD",X"74",X"01",X"DD",X"75",X"02",X"DD",X"74",X"03",X"DD",X"6E",X"00",X"DD",X"66",X"01",X"DD",
- X"5E",X"02",X"DD",X"56",X"03",X"7E",X"12",X"FD",X"7E",X"05",X"DD",X"77",X"04",X"FD",X"7E",X"04",
- X"DD",X"77",X"05",X"AF",X"DD",X"77",X"06",X"FD",X"7E",X"03",X"DD",X"77",X"07",X"DD",X"7E",X"08",
- X"DD",X"4E",X"09",X"CD",X"44",X"07",X"DD",X"E1",X"C3",X"A0",X"1C",X"DD",X"35",X"04",X"28",X"05",
- X"DD",X"E1",X"C3",X"A0",X"1C",X"26",X"00",X"DD",X"6E",X"06",X"54",X"5D",X"0E",X"03",X"19",X"19",
- X"16",X"00",X"1E",X"04",X"19",X"EB",X"FD",X"E5",X"FD",X"19",X"DD",X"6E",X"00",X"DD",X"66",X"01",
- X"DD",X"5E",X"02",X"DD",X"56",X"03",X"FD",X"7E",X"02",X"CB",X"7F",X"CA",X"1E",X"1C",X"86",X"CB",
- X"7F",X"CA",X"2B",X"1C",X"CB",X"77",X"CA",X"2B",X"1C",X"C6",X"C0",X"C3",X"2B",X"1C",X"86",X"CB",
- X"7F",X"CA",X"2B",X"1C",X"CB",X"77",X"CA",X"2B",X"1C",X"C6",X"40",X"12",X"C5",X"DD",X"4E",X"09",
- X"CD",X"44",X"07",X"C1",X"DD",X"35",X"05",X"20",X"5D",X"DD",X"34",X"06",X"16",X"00",X"59",X"FD",
- X"19",X"FD",X"7E",X"00",X"FE",X"00",X"20",X"3C",X"DD",X"7E",X"07",X"FE",X"00",X"28",X"1D",X"FE",
- X"FF",X"28",X"03",X"DD",X"35",X"07",X"AF",X"DD",X"77",X"06",X"FD",X"E1",X"FD",X"7E",X"04",X"DD",
- X"77",X"05",X"FD",X"7E",X"05",X"DD",X"77",X"04",X"DD",X"E1",X"18",X"34",X"FD",X"E1",X"DD",X"E1",
- X"C1",X"3E",X"06",X"90",X"21",X"5C",X"1E",X"16",X"00",X"5F",X"19",X"3A",X"1F",X"83",X"B6",X"32",
- X"1F",X"83",X"18",X"1D",X"FD",X"7E",X"01",X"DD",X"77",X"04",X"FD",X"7E",X"00",X"DD",X"77",X"05",
- X"FD",X"E1",X"DD",X"E1",X"18",X"0A",X"FD",X"7E",X"01",X"DD",X"77",X"04",X"FD",X"E1",X"DD",X"E1",
- X"C1",X"FD",X"6E",X"00",X"FD",X"66",X"01",X"E5",X"C9",X"3E",X"06",X"90",X"6F",X"26",X"00",X"54",
- X"5D",X"29",X"19",X"FD",X"21",X"F2",X"82",X"EB",X"FD",X"19",X"FD",X"6E",X"00",X"FD",X"66",X"01",
- X"FD",X"7E",X"02",X"96",X"D8",X"3E",X"01",X"77",X"C9",X"DD",X"E1",X"FD",X"E5",X"E1",X"DD",X"5E",
- X"00",X"16",X"00",X"19",X"E5",X"68",X"26",X"00",X"54",X"5D",X"29",X"19",X"11",X"F2",X"82",X"19",
- X"D1",X"1A",X"77",X"13",X"23",X"1A",X"77",X"DD",X"23",X"DD",X"E5",X"C9",X"00",X"80",X"01",X"80",
- X"06",X"80",X"07",X"80",X"F7",X"FE",X"08",X"80",X"0B",X"80",X"0C",X"80",X"0D",X"80",X"0E",X"80",
- X"F0",X"00",X"48",X"80",X"59",X"80",X"6A",X"80",X"7B",X"80",X"8C",X"80",X"44",X"80",X"55",X"80",
- X"66",X"80",X"77",X"80",X"88",X"80",X"3E",X"82",X"F4",X"82",X"49",X"80",X"5A",X"80",X"6B",X"80",
- X"7C",X"80",X"8D",X"80",X"02",X"80",X"03",X"80",X"06",X"80",X"07",X"80",X"EF",X"FD",X"09",X"80",
- X"0B",X"80",X"0C",X"80",X"0D",X"80",X"0E",X"80",X"0F",X"00",X"9D",X"80",X"AE",X"80",X"BF",X"80",
- X"D0",X"80",X"E1",X"80",X"99",X"80",X"AA",X"80",X"BB",X"80",X"CC",X"80",X"DD",X"80",X"3F",X"82",
- X"F7",X"82",X"9E",X"80",X"AF",X"80",X"C0",X"80",X"D1",X"80",X"E2",X"80",X"04",X"80",X"05",X"80",
- X"06",X"80",X"07",X"80",X"DF",X"FB",X"0A",X"80",X"0B",X"80",X"0C",X"80",X"0D",X"80",X"0F",X"80",
- X"F0",X"00",X"F2",X"80",X"03",X"81",X"14",X"81",X"25",X"81",X"36",X"81",X"EE",X"80",X"FF",X"80",
- X"10",X"81",X"21",X"81",X"32",X"81",X"40",X"82",X"FA",X"82",X"F3",X"80",X"04",X"81",X"15",X"81",
- X"26",X"81",X"37",X"81",X"10",X"80",X"11",X"80",X"16",X"80",X"17",X"80",X"F7",X"FE",X"18",X"80",
- X"1B",X"80",X"1C",X"80",X"1D",X"80",X"1E",X"80",X"F0",X"00",X"47",X"81",X"58",X"81",X"69",X"81",
- X"7A",X"81",X"8B",X"81",X"43",X"81",X"54",X"81",X"65",X"81",X"76",X"81",X"87",X"81",X"41",X"82",
- X"FD",X"82",X"48",X"81",X"59",X"81",X"6A",X"81",X"7B",X"81",X"8C",X"81",X"12",X"80",X"13",X"80",
- X"16",X"80",X"17",X"80",X"EF",X"FD",X"19",X"80",X"1B",X"80",X"1C",X"80",X"1D",X"80",X"1E",X"80",
- X"0F",X"00",X"9C",X"81",X"AD",X"81",X"BE",X"81",X"CF",X"81",X"E0",X"81",X"98",X"81",X"A9",X"81",
- X"BA",X"81",X"CB",X"81",X"DC",X"81",X"42",X"82",X"00",X"83",X"9D",X"81",X"AE",X"81",X"BF",X"81",
- X"D0",X"81",X"E1",X"81",X"14",X"80",X"15",X"80",X"16",X"80",X"17",X"80",X"DF",X"FB",X"1A",X"80",
- X"1B",X"80",X"1C",X"80",X"1D",X"80",X"1F",X"80",X"F0",X"00",X"F1",X"81",X"02",X"82",X"13",X"82",
- X"24",X"82",X"35",X"82",X"ED",X"81",X"FE",X"81",X"0F",X"82",X"20",X"82",X"31",X"82",X"43",X"82",
- X"03",X"83",X"F2",X"81",X"03",X"82",X"14",X"82",X"25",X"82",X"36",X"82",X"00",X"00",X"00",X"00",
- X"00",X"00",X"00",X"FF",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"00",
- X"00",X"00",X"00",X"FF",X"00",X"00",X"00",X"00",X"00",X"00",X"00",X"70",X"01",X"02",X"04",X"08",
- X"10",X"20",X"D1",X"0F",X"60",X"0F",X"EE",X"0E",X"83",X"0E",X"18",X"0E",X"B2",X"0D",X"4D",X"0D",
- X"EE",X"0C",X"8E",X"0C",X"34",X"0C",X"DA",X"0B",X"84",X"0B",X"2F",X"0B",X"DF",X"0A",X"8F",X"0A",
- X"43",X"0A",X"F7",X"09",X"B0",X"09",X"68",X"09",X"24",X"09",X"E1",X"08",X"A1",X"08",X"61",X"08",
- X"25",X"08",X"E9",X"07",X"B0",X"07",X"77",X"07",X"42",X"07",X"0C",X"07",X"D9",X"06",X"A7",X"06",
- X"77",X"06",X"47",X"06",X"15",X"06",X"ED",X"05",X"C3",X"05",X"98",X"05",X"6F",X"05",X"47",X"05",
- X"21",X"05",X"FB",X"04",X"D8",X"04",X"B4",X"04",X"92",X"04",X"70",X"04",X"50",X"04",X"31",X"04",
- X"13",X"04",X"F4",X"03",X"D8",X"03",X"BC",X"03",X"9F",X"03",X"86",X"03",X"6D",X"03",X"53",X"03",
- X"3B",X"03",X"24",X"03",X"0D",X"03",X"F6",X"02",X"E1",X"02",X"CC",X"02",X"B8",X"02",X"A4",X"02",
- X"91",X"02",X"7E",X"02",X"6C",X"02",X"5A",X"02",X"49",X"02",X"38",X"02",X"28",X"02",X"18",X"02",
- X"09",X"02",X"FA",X"01",X"EC",X"01",X"DE",X"01",X"D1",X"01",X"C3",X"01",X"B7",X"01",X"AA",X"01",
- X"9E",X"01",X"92",X"01",X"86",X"01",X"7B",X"01",X"71",X"01",X"66",X"01",X"5C",X"01",X"52",X"01",
- X"48",X"01",X"3F",X"01",X"36",X"01",X"2D",X"01",X"25",X"01",X"1C",X"01",X"14",X"01",X"0C",X"01",
- X"04",X"01",X"FD",X"00",X"F6",X"00",X"EF",X"00",X"E8",X"00",X"E1",X"00",X"DB",X"00",X"D5",X"00",
- X"CF",X"00",X"C9",X"00",X"C4",X"00",X"BE",X"00",X"B8",X"00",X"B3",X"00",X"AE",X"00",X"A9",X"00",
- X"A4",X"00",X"9F",X"00",X"9B",X"00",X"96",X"00",X"92",X"00",X"8E",X"00",X"8A",X"00",X"86",X"00",
- X"82",X"00",X"7F",X"00",X"7B",X"00",X"77",X"00",X"74",X"00",X"71",X"00",X"6D",X"00",X"6A",X"00",
- X"67",X"00",X"64",X"00",X"62",X"00",X"5F",X"00",X"5C",X"00",X"59",X"00",X"56",X"00",X"54",X"00",
- X"52",X"00",X"50",X"00",X"4E",X"00",X"4B",X"00",X"49",X"00",X"47",X"00",X"45",X"00",X"43",X"00",
- X"41",X"00",X"3F",X"00",X"3D",X"00",X"3B",X"00",X"39",X"00",X"38",X"00",X"37",X"00",X"35",X"00",
- X"33",X"00",X"32",X"00",X"31",X"00",X"2F",X"00",X"2D",X"00",X"2C",X"00",X"2B",X"00",X"2A",X"00",
- X"29",X"00",X"27",X"00",X"26",X"00",X"26",X"00",X"25",X"00",X"24",X"00",X"23",X"00",X"22",X"00",
- X"21",X"00",X"20",X"00",X"1F",X"00",X"1E",X"00",X"1D",X"00",X"1C",X"00",X"1B",X"00",X"1B",X"00",
- X"1A",X"00",X"19",X"00",X"18",X"00",X"18",X"00",X"17",X"00",X"16",X"00",X"15",X"00",X"15",X"00",
- X"14",X"00",X"14",X"00",X"13",X"00",X"13",X"00",X"12",X"00",X"12",X"00",X"11",X"00",X"11",X"00",
- X"10",X"00",X"52",X"6F",X"62",X"65",X"72",X"74",X"20",X"4D",X"20",X"4C",X"69",X"62",X"62",X"65",
- X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF",X"FF");
-begin
-process(clk)
-begin
- if rising_edge(clk) then
- data <= rom_data(to_integer(unsigned(addr)));
- end if;
-end process;
-end architecture;
diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/sdram.sv b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/sdram.sv
index 41f5b7a8..9f78c393 100644
--- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/sdram.sv
+++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/sdram.sv
@@ -50,6 +50,8 @@ module sdram (
output reg [15:0] cpu1_q,
input [16:1] cpu2_addr,
output reg [15:0] cpu2_q,
+ input [16:1] cpu3_addr,
+ output reg [15:0] cpu3_q,
input port2_req,
output reg port2_ack,
@@ -150,9 +152,9 @@ assign SDRAM_nRAS = sd_cmd[2];
assign SDRAM_nCAS = sd_cmd[1];
assign SDRAM_nWE = sd_cmd[0];
-reg [24:1] addr_latch[2];
+reg [24:1] addr_latch[3];
reg [24:1] addr_latch_next[2];
-reg [16:1] addr_last[2];
+reg [16:1] addr_last[4];
reg [16:2] addr_last2[2];
reg [15:0] din_latch[2];
reg [1:0] oe_latch;
@@ -162,14 +164,15 @@ reg [1:0] ds[2];
reg port1_state;
reg port2_state;
-localparam PORT_NONE = 2'd0;
-localparam PORT_CPU1 = 2'd1;
-localparam PORT_CPU2 = 2'd2;
-localparam PORT_SP = 2'd1;
-localparam PORT_REQ = 2'd3;
+localparam PORT_NONE = 3'd0;
+localparam PORT_CPU1 = 3'd1;
+localparam PORT_CPU2 = 3'd2;
+localparam PORT_CPU3 = 3'd3;
+localparam PORT_SP = 3'd1;
+localparam PORT_REQ = 3'd4;
-reg [1:0] next_port[2];
-reg [1:0] port[2];
+reg [2:0] next_port[2];
+reg [2:0] port[2];
reg refresh;
reg [10:0] refresh_cnt;
@@ -189,6 +192,9 @@ always @(*) begin
end else if (cpu2_addr != addr_last[PORT_CPU2]) begin
next_port[0] = PORT_CPU2;
addr_latch_next[0] = { 8'd0, cpu2_addr };
+ end else if (cpu3_addr != addr_last[PORT_CPU3]) begin
+ next_port[0] = PORT_CPU3;
+ addr_latch_next[0] = { 8'd0, cpu3_addr };
end else begin
next_port[0] = PORT_NONE;
addr_latch_next[0] = addr_latch[0];
@@ -321,6 +327,7 @@ always @(posedge clk) begin
PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end
PORT_CPU1: begin cpu1_q <= sd_din; end
PORT_CPU2: begin cpu2_q <= sd_din; end
+ PORT_CPU3: begin cpu3_q <= sd_din; end
default: ;
endcase;
end
diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd
index 99bba730..1a4e834a 100644
--- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd
+++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter.vhd
@@ -151,7 +151,8 @@ port(
separate_audio : in std_logic;
audio_out_l : out std_logic_vector(15 downto 0);
audio_out_r : out std_logic_vector(15 downto 0);
-
+ csd_audio_out : out std_logic_vector( 9 downto 0);
+
coin1 : in std_logic;
coin2 : in std_logic;
shift : in std_logic;
@@ -176,6 +177,8 @@ port(
cpu_rom_do : in std_logic_vector(7 downto 0);
snd_rom_addr : out std_logic_vector(12 downto 0);
snd_rom_do : in std_logic_vector(7 downto 0);
+ csd_rom_addr : out std_logic_vector(14 downto 1);
+ csd_rom_do : in std_logic_vector(15 downto 0);
sp_addr : out std_logic_vector(14 downto 0);
sp_graphx32_do : in std_logic_vector(31 downto 0);
dbg_cpu_addr : out std_logic_vector(15 downto 0)
@@ -1154,6 +1157,17 @@ port map(
-- data => sp_graphx_do
--);
+-- background & sprite palette
+palette : entity work.gen_ram
+generic map( dWidth => 9, aWidth => 6)
+port map(
+ clk => clock_vidn,
+ we => palette_we,
+ addr => palette_addr,
+ d => cpu_addr(0) & cpu_do,
+ q => palette_do
+);
+
-- Spy hunter sound board
sound_board : entity work.spy_hunter_sound_board
port map(
@@ -1177,19 +1191,22 @@ port map(
separate_audio => separate_audio,
audio_out_l => audio_out_l,
audio_out_r => audio_out_r,
-
+
+ cpu_rom_addr => snd_rom_addr,
+ cpu_rom_do => snd_rom_do,
+
dbg_cpu_addr => open --dbg_cpu_addr
);
-
--- background & sprite palette
-palette : entity work.gen_ram
-generic map( dWidth => 9, aWidth => 6)
-port map(
- clk => clock_vidn,
- we => palette_we,
- addr => palette_addr,
- d => cpu_addr(0) & cpu_do,
- q => palette_do
+
+-- Cheap Squeak Deluxe
+csd: entity work.cheap_squeak_deluxe
+port map (
+ clock_40 => clock_40,
+ reset => reset,
+ input => output_4,
+ rom_addr => csd_rom_addr,
+ rom_do => csd_rom_do,
+ audio_out => csd_audio_out
);
end struct;
\ No newline at end of file
diff --git a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter_sound_board.vhd b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter_sound_board.vhd
index 1a6c1d15..ccc88bd5 100644
--- a/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter_sound_board.vhd
+++ b/Arcade_MiST/Midway MCR Scroll/SpyHunter_MiST/rtl/spy_hunter_sound_board.vhd
@@ -74,7 +74,10 @@ port(
audio_out_l : out std_logic_vector(15 downto 0);
audio_out_r : out std_logic_vector(15 downto 0);
-
+
+ cpu_rom_addr : out std_logic_vector(12 downto 0);
+ cpu_rom_do : in std_logic_vector(7 downto 0);
+
dbg_cpu_addr : out std_logic_vector(15 downto 0)
);
end spy_hunter_sound_board;
@@ -101,7 +104,7 @@ architecture struct of spy_hunter_sound_board is
signal cpu_irq_n : std_logic;
signal cpu_m1_n : std_logic;
- signal cpu_rom_do : std_logic_vector( 7 downto 0);
+-- signal cpu_rom_do : std_logic_vector( 7 downto 0);
signal wram_we : std_logic;
signal wram_do : std_logic_vector( 7 downto 0);
@@ -436,12 +439,14 @@ port map(
);
-- cpu program ROM 0x0000-0x3FFF
-rom_cpu : entity work.spy_hunter_sound_cpu
-port map(
- clk => clock_sndn,
- addr => cpu_addr(12 downto 0),
- data => cpu_rom_do
-);
+--rom_cpu : entity work.spy_hunter_sound_cpu
+--port map(
+-- clk => clock_sndn,
+-- addr => cpu_addr(12 downto 0),
+-- data => cpu_rom_do
+--);
+
+cpu_rom_addr <= cpu_addr(12 downto 0);
-- working RAM 0x8000-0x83FF
wram : entity work.gen_ram
diff --git a/common/CPU/68000/FX68k/LICENSE b/common/CPU/68000/FX68k/LICENSE
new file mode 100644
index 00000000..f288702d
--- /dev/null
+++ b/common/CPU/68000/FX68k/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/common/CPU/68000/FX68k/README.md b/common/CPU/68000/FX68k/README.md
new file mode 100644
index 00000000..b1c80178
--- /dev/null
+++ b/common/CPU/68000/FX68k/README.md
@@ -0,0 +1,17 @@
+# fx68k
+FX68K 68000 cycle accurate SystemVerilog core
+
+Copyright (c) 2018 by Jorge Cwik
+fx68k@fxatari.com
+
+FX68K is a 68000 cycle exact compatible core. At least in theory, it should be impossible to distinguish functionally from a real 68K processor.
+
+On Cyclone families it uses just over 5,100 LEs and about 5KB internal ram, reaching a max effective clock frequency close to 40MHz. Some optimizations are still possible to implement and increase the performance.
+
+The core is fully synchronous. Considerable effort was made to avoid any asynchronous logic.
+
+Written in SystemVerilog.
+
+The timing of the external bus signals is exactly as the original processor. The only feature that is not implemented yet is bus retry using the external HALT input signal.
+
+It was designed to replace an actual chip on a real board. This wasn't yet tested however and not all necessary output enable control signals are fully implemented.
diff --git a/common/CPU/68000/FX68k/Rom.sv b/common/CPU/68000/FX68k/Rom.sv
deleted file mode 100644
index 1b35c374..00000000
--- a/common/CPU/68000/FX68k/Rom.sv
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// microrom and nanorom instantiation
-//
-// There is bit of wasting of resources here. An extra registering pipeline happens that is not needed.
-// This is just for the purpose of helping inferring block RAM using pure generic code. Inferring RAM is important for performance.
-// Might be more efficient to use vendor specific features such as clock enable.
-//
-
-module uRom( input clk, input [UADDR_WIDTH-1:0] microAddr, output logic [UROM_WIDTH-1:0] microOutput);
- reg [UROM_WIDTH-1:0] uRam[ UROM_DEPTH];
- initial begin
- $readmemb("microrom.mem", uRam);
- end
-
- always_ff @( posedge clk)
- microOutput <= uRam[ microAddr];
-endmodule
-
-
-module nanoRom( input clk, input [NADDR_WIDTH-1:0] nanoAddr, output logic [NANO_WIDTH-1:0] nanoOutput);
- reg [NANO_WIDTH-1:0] nRam[ NANO_DEPTH];
- initial begin
- $readmemb("nanorom.mem", nRam);
- end
-
- always_ff @( posedge clk)
- nanoOutput <= nRam[ nanoAddr];
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/aluCorf.sv b/common/CPU/68000/FX68k/aluCorf.sv
deleted file mode 100644
index d73bd08e..00000000
--- a/common/CPU/68000/FX68k/aluCorf.sv
+++ /dev/null
@@ -1,35 +0,0 @@
-// add bcd correction factor
-// It would be more efficient to merge add/sub with main ALU !!!
-module aluCorf( input [7:0] binResult, input bAdd, input cin, input hCarry,
- output [7:0] bcdResult, output dC, output logic ov);
-
- reg [8:0] htemp;
- reg [4:0] hNib;
-
- wire lowC = hCarry | (bAdd ? gt9( binResult[ 3:0]) : 1'b0);
- wire highC = cin | (bAdd ? (gt9( htemp[7:4]) | htemp[8]) : 1'b0);
-
- always_comb begin
- if( bAdd) begin
- htemp = { 1'b0, binResult} + (lowC ? 4'h6 : 4'h0);
- hNib = htemp[8:4] + (highC ? 4'h6 : 4'h0);
- ov = hNib[3] & ~binResult[7];
- end
- else begin
- htemp = { 1'b0, binResult} - (lowC ? 4'h6 : 4'h0);
- hNib = htemp[8:4] - (highC ? 4'h6 : 4'h0);
- ov = ~hNib[3] & binResult[7];
- end
- end
-
- assign bcdResult = { hNib[ 3:0], htemp[3:0]};
- assign dC = hNib[4] | cin;
-
- // Nibble > 9
- function gt9 (input [3:0] nib);
- begin
- gt9 = nib[3] & (nib[2] | nib[1]);
- end
- endfunction
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/aluGetOp.sv b/common/CPU/68000/FX68k/aluGetOp.sv
deleted file mode 100644
index 8c779973..00000000
--- a/common/CPU/68000/FX68k/aluGetOp.sv
+++ /dev/null
@@ -1,90 +0,0 @@
-// Get current OP from row & col
-module aluGetOp( input [15:0] row, input [2:0] col, input isCorf,
- output logic [4:0] aluOp);
-
- always_comb begin
- aluOp = 'X;
- unique case( col)
- 1: aluOp = OP_AND;
- 5: aluOp = OP_EXT;
-
- default:
- unique case( 1'b1)
- row[1]:
- unique case( col)
- 2: aluOp = OP_SUB;
- 3: aluOp = OP_SUBC;
- 4,6: aluOp = OP_SLAA;
- endcase
-
- row[2]:
- unique case( col)
- 2: aluOp = OP_ADD;
- 3: aluOp = OP_ADDC;
- 4: aluOp = OP_ASR;
- endcase
-
- row[3]:
- unique case( col)
- 2: aluOp = OP_ADDX;
- 3: aluOp = isCorf ? OP_ABCD : OP_ADD;
- 4: aluOp = OP_ASL;
- endcase
-
- row[4]:
- aluOp = ( col == 4) ? OP_LSL : OP_AND;
-
- row[5],
- row[6]:
- unique case( col)
- 2: aluOp = OP_SUB;
- 3: aluOp = OP_SUBC;
- 4: aluOp = OP_LSR;
- endcase
-
- row[7]: // MUL
- unique case( col)
- 2: aluOp = OP_SUB;
- 3: aluOp = OP_ADD;
- 4: aluOp = OP_ROXR;
- endcase
-
- row[8]:
- // OP_AND For EXT.L
- // But would be more efficient to change ucode and use column 1 instead of col3 at ublock extr1!
- unique case( col)
- 2: aluOp = OP_EXT;
- 3: aluOp = OP_AND;
- 4: aluOp = OP_ROXR;
- endcase
-
- row[9]:
- unique case( col)
- 2: aluOp = OP_SUBX;
- 3: aluOp = OP_SBCD;
- 4: aluOp = OP_ROL;
- endcase
-
- row[10]:
- unique case( col)
- 2: aluOp = OP_SUBX;
- 3: aluOp = OP_SUBC;
- 4: aluOp = OP_ROR;
- endcase
-
- row[11]:
- unique case( col)
- 2: aluOp = OP_SUB0;
- 3: aluOp = OP_SUB0;
- 4: aluOp = OP_ROXL;
- endcase
-
- row[12]: aluOp = OP_ADDX;
- row[13]: aluOp = OP_EOR;
- row[14]: aluOp = (col == 4) ? OP_EOR : OP_OR;
- row[15]: aluOp = (col == 3) ? OP_ADD : OP_OR; // OP_ADD used by DBcc
-
- endcase
- endcase
- end
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/aluShifter.sv b/common/CPU/68000/FX68k/aluShifter.sv
deleted file mode 100644
index c36d26eb..00000000
--- a/common/CPU/68000/FX68k/aluShifter.sv
+++ /dev/null
@@ -1,32 +0,0 @@
-module aluShifter( input [31:0] data,
- input isByte, input isLong, swapWords,
- input dir, input cin,
- output logic [31:0] result);
- // output reg cout
-
- logic [31:0] tdata;
-
- // size mux, put cin in position if dir == right
- always_comb begin
- tdata = data;
- if( isByte & dir)
- tdata[8] = cin;
- else if( !isLong & dir)
- tdata[16] = cin;
- end
-
- always_comb begin
- // Reverse alu/alue position for MUL & DIV
- // Result reversed again
- if( swapWords & dir)
- result = { tdata[0], tdata[31:17], cin, tdata[15:1]};
- else if( swapWords)
- result = { tdata[30:16], cin, tdata[14:0], tdata[31]};
-
- else if( dir)
- result = { cin, tdata[31:1]};
- else
- result = { tdata[30:0], cin};
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/busArbiter.sv b/common/CPU/68000/FX68k/busArbiter.sv
deleted file mode 100644
index 89bd2fb3..00000000
--- a/common/CPU/68000/FX68k/busArbiter.sv
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// DMA/BUS Arbitration
-//
-
-module busArbiter( input s_clks Clks,
- input BRi, BgackI, Halti, bgBlock,
- output busAvail,
- output logic BGn);
-
- enum int unsigned { DRESET = 0, DIDLE, D1, D_BR, D_BA, D_BRA, D3, D2} dmaPhase, next;
-
- always_comb begin
- case(dmaPhase)
- DRESET: next = DIDLE;
- DIDLE: begin
- if( bgBlock)
- next = DIDLE;
- else if( ~BgackI)
- next = D_BA;
- else if( ~BRi)
- next = D1;
- else
- next = DIDLE;
- end
-
- D_BA: begin // Loop while only BGACK asserted, BG negated here
- if( ~BRi & !bgBlock)
- next = D3;
- else if( ~BgackI & !bgBlock)
- next = D_BA;
- else
- next = DIDLE;
- end
-
- D1: next = D_BR; // Loop while only BR asserted
- D_BR: next = ~BRi & BgackI ? D_BR : D_BA; // No direct path to IDLE !
-
- D3: next = D_BRA;
- D_BRA: begin // Loop while both BR and BGACK asserted
- case( {BgackI, BRi} )
- 2'b11: next = DIDLE; // Both deasserted
- 2'b10: next = D_BR; // BR asserted only
- 2'b01: next = D2; // BGACK asserted only
- 2'b00: next = D_BRA; // Stay here while both asserted
- endcase
- end
-
- // Might loop here if both deasserted, should normally don't arrive here anyway?
- // D2: next = (BgackI & BRi) | bgBlock ? D2: D_BA;
-
- D2: next = D_BA;
-
- default: next = DIDLE; // Should not reach here normally
- endcase
- end
-
- logic granting;
- always_comb begin
- unique case( next)
- D1, D3, D_BR, D_BRA: granting = 1'b1;
- default: granting = 1'b0;
- endcase
- end
-
- reg rGranted;
- assign busAvail = Halti & BRi & BgackI & ~rGranted;
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.extReset) begin
- dmaPhase <= DRESET;
- rGranted <= 1'b0;
- end
- else if( Clks.enPhi2) begin
- dmaPhase <= next;
- // Internal signal changed on PHI2
- rGranted <= granting;
- end
-
- // External Output changed on PHI1
- if( Clks.extReset)
- BGn <= 1'b1;
- else if( Clks.enPhi1)
- BGn <= ~rGranted;
-
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/busControl.sv b/common/CPU/68000/FX68k/busControl.sv
deleted file mode 100644
index 8236fbd7..00000000
--- a/common/CPU/68000/FX68k/busControl.sv
+++ /dev/null
@@ -1,197 +0,0 @@
-module busControl( input s_clks Clks, input enT1, input enT4,
- input permStart, permStop, iStop,
- input aob0,
- input isWrite, isByte, isRmc,
- input busAvail,
- output bgBlock,
- output busAddrErr,
- output waitBusCycle,
- output busStarting, // Asserted during S0
- output logic addrOe, // Asserted from S1 to the end, whole bus cycle except S0
- output bciWrite, // Used for SSW on bus/addr error
-
- input rDtack, BeDebounced, Vpai,
- output ASn, output LDSn, output UDSn, eRWn);
-
- reg rAS, rLDS, rUDS, rRWn;
- assign ASn = rAS;
- assign LDSn = rLDS;
- assign UDSn = rUDS;
- assign eRWn = rRWn;
-
- reg dataOe;
-
- reg bcPend;
- reg isWriteReg, bciByte, isRmcReg, wendReg;
- assign bciWrite = isWriteReg;
- reg addrOeDelay;
- reg isByteT4;
-
- wire canStart, busEnd;
- wire bcComplete, bcReset;
-
- wire isRcmReset = bcComplete & bcReset & isRmcReg;
-
- assign busAddrErr = aob0 & ~bciByte;
-
- // Bus retry not really supported.
- // It's BERR and HALT and not address error, and not read-modify cycle.
- wire busRetry = ~busAddrErr & 1'b0;
-
- enum int unsigned { SRESET = 0, SIDLE, S0, S2, S4, S6, SRMC_RES} busPhase, next;
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.extReset)
- busPhase <= SRESET;
- else if( Clks.enPhi1)
- busPhase <= next;
- end
-
- always_comb begin
- case( busPhase)
- SRESET: next = SIDLE;
- SRMC_RES: next = SIDLE; // Single cycle special state when read phase of RMC reset
- S0: next = S2;
- S2: next = S4;
- S4: next = busEnd ? S6 : S4;
- S6: next = isRcmReset ? SRMC_RES : (canStart ? S0 : SIDLE);
- SIDLE: next = canStart ? S0 : SIDLE;
- default: next = SIDLE;
- endcase
- end
-
- // Idle phase of RMC bus cycle. Might be better to just add a new state
- wire rmcIdle = (busPhase == SIDLE) & ~ASn & isRmcReg;
-
- assign canStart = (busAvail | rmcIdle) & (bcPend | permStart) & !busRetry & !bcReset;
-
- wire busEnding = (next == SIDLE) | (next == S0);
-
- assign busStarting = (busPhase == S0);
-
- // term signal (DTACK, BERR, VPA, adress error)
- assign busEnd = ~rDtack | iStop;
-
- // bcComplete asserted on raising edge of S6 (together with SNC).
- assign bcComplete = (busPhase == S6);
-
- // Clear bus info latch on completion (regular or aborted) and no bus retry (and not PHI1).
- // bciClear asserted half clock later on PHI2, and bci latches cleared async concurrently
- wire bciClear = bcComplete & ~busRetry;
-
- // Reset on reset or (berr & berrDelay & (not halt or rmc) & not 6800 & in bus cycle) (and not PHI1)
- assign bcReset = Clks.extReset | (addrOeDelay & BeDebounced & Vpai);
-
- // Enable uclock only on S6 (S8 on Bus Error) or not bciPermStop
- assign waitBusCycle = wendReg & !bcComplete;
-
- // Block Bus Grant when starting new bus cycle. But No need if AS already asserted (read phase of RMC)
- // Except that when that RMC phase aborted on bus error, it's asserted one cycle later!
- assign bgBlock = ((busPhase == S0) & ASn) | (busPhase == SRMC_RES);
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.extReset) begin
- addrOe <= 1'b0;
- end
- else if( Clks.enPhi2 & ( busPhase == S0)) // From S1, whole bus cycle except S0
- addrOe <= 1'b1;
- else if( Clks.enPhi1 & (busPhase == SRMC_RES))
- addrOe <= 1'b0;
- else if( Clks.enPhi1 & ~isRmcReg & busEnding)
- addrOe <= 1'b0;
-
- if( Clks.enPhi1)
- addrOeDelay <= addrOe;
-
- if( Clks.extReset) begin
- rAS <= 1'b1;
- rUDS <= 1'b1;
- rLDS <= 1'b1;
- rRWn <= 1'b1;
- dataOe <= '0;
- end
- else begin
-
- if( Clks.enPhi2 & isWriteReg & (busPhase == S2))
- dataOe <= 1'b1;
- else if( Clks.enPhi1 & (busEnding | (busPhase == SIDLE)) )
- dataOe <= 1'b0;
-
- if( Clks.enPhi1 & busEnding)
- rRWn <= 1'b1;
- else if( Clks.enPhi1 & isWriteReg) begin
- // Unlike LDS/UDS Asserted even in address error
- if( (busPhase == S0) & isWriteReg)
- rRWn <= 1'b0;
- end
-
- // AS. Actually follows addrOe half cycle later!
- if( Clks.enPhi1 & (busPhase == S0))
- rAS <= 1'b0;
- else if( Clks.enPhi2 & (busPhase == SRMC_RES)) // Bus error on read phase of RMC. Deasserted one cycle later
- rAS <= 1'b1;
- else if( Clks.enPhi2 & bcComplete & ~SRMC_RES)
- if( ~isRmcReg) // Keep AS asserted on the IDLE phase of RMC
- rAS <= 1'b1;
-
- if( Clks.enPhi1 & (busPhase == S0)) begin
- if( ~isWriteReg & !busAddrErr) begin
- rUDS <= ~(~bciByte | ~aob0);
- rLDS <= ~(~bciByte | aob0);
- end
- end
- else if( Clks.enPhi1 & isWriteReg & (busPhase == S2) & !busAddrErr) begin
- rUDS <= ~(~bciByte | ~aob0);
- rLDS <= ~(~bciByte | aob0);
- end
- else if( Clks.enPhi2 & bcComplete) begin
- rUDS <= 1'b1;
- rLDS <= 1'b1;
- end
-
- end
-
- end
-
- // Bus cycle info latch. Needed because uinstr might change if the bus is busy and we must wait.
- // Note that urom advances even on wait states. It waits *after* updating urom and nanorom latches.
- // Even without wait states, ublocks of type ir (init reading) will not wait for bus completion.
- // Originally latched on (permStart AND T1).
-
- // Bus cycle info latch: isRead, isByte, read-modify-cycle, and permStart (bus cycle pending). Some previously latched on T4?
- // permStop also latched, but unconditionally on T1
-
- // Might make more sense to register this outside this module
- always_ff @( posedge Clks.clk) begin
- if( enT4) begin
- isByteT4 <= isByte;
- end
- end
-
- // Bus Cycle Info Latch
- always_ff @( posedge Clks.clk) begin
- if( Clks.pwrUp) begin
- bcPend <= 1'b0;
- wendReg <= 1'b0;
- isWriteReg <= 1'b0;
- bciByte <= 1'b0;
- isRmcReg <= 1'b0;
- end
-
- else if( Clks.enPhi2 & (bciClear | bcReset)) begin
- bcPend <= 1'b0;
- wendReg <= 1'b0;
- end
- else begin
- if( enT1 & permStart) begin
- isWriteReg <= isWrite;
- bciByte <= isByteT4;
- isRmcReg <= isRmc & ~isWrite; // We need special case the end of the read phase only.
- bcPend <= 1'b1;
- end
- if( enT1)
- wendReg <= permStop;
- end
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/ccrTable.sv b/common/CPU/68000/FX68k/ccrTable.sv
deleted file mode 100644
index b50f822f..00000000
--- a/common/CPU/68000/FX68k/ccrTable.sv
+++ /dev/null
@@ -1,76 +0,0 @@
-// Row/col CCR update table
-module ccrTable(
- input [2:0] col, input [15:0] row, input finish,
- output logic [MASK_NBITS-1:0] ccrMask);
-
- localparam
- KNZ00 = 5'b01111, // ok coz operators clear them
- KKZKK = 5'b00100,
- KNZKK = 5'b01100,
- KNZ10 = 5'b01111, // Used by OP_EXT on divison overflow
- KNZ0C = 5'b01111, // Used by DIV. V should be 0, but it is ok:
- // DIVU: ends with quotient - 0, so V & C always clear.
- // DIVS: ends with 1i (AND), again, V & C always clear.
-
- KNZVC = 5'b01111,
- CUPDALL = 5'b11111,
- CUNUSED = 5'bxxxxx;
-
-
- logic [MASK_NBITS-1:0] ccrMask1;
-
- always_comb begin
- unique case( col)
- 1: ccrMask = ccrMask1;
-
- 2,3:
- unique case( 1'b1)
- row[1]: ccrMask = KNZ0C; // DIV, used as 3n in col3
- row[2],
- row[3], // ABCD
- row[5],
- row[9], // SBCD/NBCD
- row[10], // SUBX/NEGX
- row[12]: ccrMask = CUPDALL; // ADDX
- row[6], // CMP
- row[7], // MUL
- row[11]: ccrMask = KNZVC; // NOT
- row[4],
- row[8], // Not used in col 3
- row[13],
- row[14]: ccrMask = KNZ00;
- row[15]: ccrMask = 5'b0; // TAS/Scc, not used in col 3
- // default: ccrMask = CUNUSED;
- endcase
-
- 4:
- unique case( row)
- // 1: DIV, only n (4n & 6n)
- // 14: BCLR 4n
- // 6,12,13,15 // not used
- `ALU_ROW_02,
- `ALU_ROW_03, // ASL (originally ANZVA)
- `ALU_ROW_04,
- `ALU_ROW_05: ccrMask = CUPDALL; // Shifts (originally ANZ0A)
-
- `ALU_ROW_07: ccrMask = KNZ00; // MUL (originally KNZ0A)
- `ALU_ROW_09,
- `ALU_ROW_10: ccrMask = KNZ00; // RO[lr] (originally KNZ0A)
- `ALU_ROW_11: ccrMask = CUPDALL; // ROXL (originally ANZ0A)
- default: ccrMask = CUNUSED;
- endcase
-
- 5: ccrMask = row[1] ? KNZ10 : 5'b0;
- default: ccrMask = CUNUSED;
- endcase
- end
-
- // Column 1 (AND)
- always_comb begin
- if( finish)
- ccrMask1 = row[7] ? KNZ00 : KNZKK;
- else
- ccrMask1 = row[13] | row[14] ? KKZKK : KNZ00;
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/dataIo.sv b/common/CPU/68000/FX68k/dataIo.sv
deleted file mode 100644
index c20f36d3..00000000
--- a/common/CPU/68000/FX68k/dataIo.sv
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Data bus I/O
-// At a separate module because it is a bit complicated and the timing is special.
-// Here we do the low/high byte mux and the special case of MOVEP.
-//
-// Original implementation is rather complex because both the internal and external buses are bidirectional.
-// Input is latched async at the EDB register.
-// We capture directly from the external data bus to the internal registers (IRC & DBIN) on PHI2, starting the external S7 phase, at a T4 internal period.
-
-module dataIo( input s_clks Clks,
- input enT1, enT2, enT3, enT4,
- input s_nanod Nanod, input s_irdecod Irdecod,
- input [15:0] iEdb,
- input aob0,
-
- input dobIdle,
- input [15:0] dobInput,
-
- output logic [15:0] Irc,
- output logic [15:0] dbin,
- output logic [15:0] oEdb
- );
-
- reg [15:0] dob;
-
- // DBIN/IRC
-
- // Timing is different than any other register. We can latch only on the next T4 (bus phase S7).
- // We need to register all control signals correctly because the next ublock will already be started.
- // Can't latch control on T4 because if there are wait states there might be multiple T4 before we latch.
-
- reg xToDbin, xToIrc;
- reg dbinNoLow, dbinNoHigh;
- reg byteMux, isByte_T4;
-
- always_ff @( posedge Clks.clk) begin
-
- // Byte mux control. Can't latch at T1. AOB might be not ready yet.
- // Must latch IRD decode at T1 (or T4). Then combine and latch only at T3.
-
- // Can't latch at T3, a new IRD might be loaded already at T1.
- // Ok to latch at T4 if combination latched then at T3
- if( enT4)
- isByte_T4 <= Irdecod.isByte; // Includes MOVEP from mem, we could OR it here
-
- if( enT3) begin
- dbinNoHigh <= Nanod.noHighByte;
- dbinNoLow <= Nanod.noLowByte;
- byteMux <= Nanod.busByte & isByte_T4 & ~aob0;
- end
-
- if( enT1) begin
- // If on wait states, we continue latching until next T1
- xToDbin <= 1'b0;
- xToIrc <= 1'b0;
- end
- else if( enT3) begin
- xToDbin <= Nanod.todbin;
- xToIrc <= Nanod.toIrc;
- end
-
- // Capture on T4 of the next ucycle
- // If there are wait states, we keep capturing every PHI2 until the next T1
-
- if( xToIrc & Clks.enPhi2)
- Irc <= iEdb;
- if( xToDbin & Clks.enPhi2) begin
- // Original connects both halves of EDB.
- if( ~dbinNoLow)
- dbin[ 7:0] <= byteMux ? iEdb[ 15:8] : iEdb[7:0];
- if( ~dbinNoHigh)
- dbin[ 15:8] <= ~byteMux & dbinNoLow ? iEdb[ 7:0] : iEdb[ 15:8];
- end
- end
-
- // DOB
- logic byteCycle;
-
- always_ff @( posedge Clks.clk) begin
- // Originaly on T1. Transfer to internal EDB also on T1 (stays enabled upto the next T1). But only on T4 (S3) output enables.
- // It is safe to do on T3, then, but control signals if derived from IRD must be registered.
- // Originally control signals are not registered.
-
- // Wait states don't affect DOB operation that is done at the start of the bus cycle.
-
- if( enT4)
- byteCycle <= Nanod.busByte & Irdecod.isByte; // busIsByte but not MOVEP
-
- // Originally byte low/high interconnect is done at EDB, not at DOB.
- if( enT3 & ~dobIdle) begin
- dob[7:0] <= Nanod.noLowByte ? dobInput[15:8] : dobInput[ 7:0];
- dob[15:8] <= (byteCycle | Nanod.noHighByte) ? dobInput[ 7:0] : dobInput[15:8];
- end
- end
- assign oEdb = dob;
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/excUnit.sv b/common/CPU/68000/FX68k/excUnit.sv
deleted file mode 100644
index b42b4616..00000000
--- a/common/CPU/68000/FX68k/excUnit.sv
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- Execution unit
-
- Executes register transfers set by the microcode. Originally through a set of bidirectional buses.
- Most sources are available at T3, but DBIN only at T4! CCR also might be updated at T4, but it is not connected to these buses.
- We mux at T1 and T2, then transfer to the destination at T3. The exception is AOB that need to be updated earlier.
-
-*/
-
-module excUnit( input s_clks Clks,
- input enT1, enT2, enT3, enT4,
- input s_nanod Nanod, input s_irdecod Irdecod,
- input [15:0] Ird, // ALU row (and others) decoder needs it
- input pswS,
- input [15:0] ftu,
- input [15:0] iEdb,
-
- output logic [7:0] ccr,
- output [15:0] alue,
-
- output prenEmpty, au05z,
- output logic dcr4, ze,
- output logic aob0,
- output [15:0] AblOut,
- output logic [15:0] Irc,
- output logic [15:0] oEdb,
- output logic [23:1] eab);
-
-localparam REG_USP = 15;
-localparam REG_SSP = 16;
-localparam REG_DT = 17;
-
- // Register file
- reg [15:0] regs68L[ 18];
- reg [15:0] regs68H[ 18];
-
-// synthesis translate off
- /*
- It is bad practice to initialize simulation registers that the hardware doesn't.
- There is risk that simulation would be different than the real hardware. But in this case is the other way around.
- Some ROM uses something like sub.l An,An at powerup which clears the register
- Simulator power ups the registers with 'X, as they are really undetermined at the real hardware.
- But the simulator doesn't realize (it can't) that the same value is substracting from itself,
- and that the result should be zero even when it's 'X - 'X.
- */
-
- initial begin
- for( int i = 0; i < 18; i++) begin
- regs68L[i] <= '0;
- regs68H[i] <= '0;
- end
- end
-
- // For simulation display only
- wire [31:0] SSP = { regs68H[REG_SSP], regs68L[REG_SSP]};
-
-// synthesis translate on
-
-
- wire [15:0] aluOut;
- wire [15:0] dbin;
- logic [15:0] dcrOutput;
-
- reg [15:0] PcL, PcH;
-
- reg [31:0] auReg, aob;
-
- reg [15:0] Ath, Atl;
-
- // Bus execution
- reg [15:0] Dbl, Dbh;
- reg [15:0] Abh, Abl;
- reg [15:0] Abd, Dbd;
-
- assign AblOut = Abl;
- assign au05z = (~| auReg[5:0]);
-
- logic [15:0] dblMux, dbhMux;
- logic [15:0] abhMux, ablMux;
- logic [15:0] abdMux, dbdMux;
-
- logic abdIsByte;
-
- logic Pcl2Dbl, Pch2Dbh;
- logic Pcl2Abl, Pch2Abh;
-
-
- // RX RY muxes
- // RX and RY actual registers
- logic [4:0] actualRx, actualRy;
- logic [3:0] movemRx;
- logic byteNotSpAlign; // Byte instruction and no sp word align
-
- // IRD decoded signals must be latched. See comments on decoder
- // But nanostore decoding can't be latched before T4.
- //
- // If we need this earlier we can register IRD decode on T3 and use nano async
-
- logic [4:0] rxMux, ryMux;
- logic [3:0] rxReg, ryReg;
- logic rxIsSp, ryIsSp;
- logic rxIsAreg, ryIsAreg;
-
- always_comb begin
-
- // Unique IF !!
- if( Nanod.ssp) begin
- rxMux = REG_SSP;
- rxIsSp = 1'b1;
- rxReg = 1'bX;
- end
- else if( Irdecod.rxIsUsp) begin
- rxMux = REG_USP;
- rxIsSp = 1'b1;
- rxReg = 1'bX;
- end
- else if( Irdecod.rxIsDt & !Irdecod.implicitSp) begin
- rxMux = REG_DT;
- rxIsSp = 1'b0;
- rxReg = 1'bX;
- end
- else begin
- if( Irdecod.implicitSp)
- rxReg = 15;
- else if( Irdecod.rxIsMovem)
- rxReg = movemRx;
- else
- rxReg = { Irdecod.rxIsAreg, Irdecod.rx};
-
- if( (& rxReg)) begin
- rxMux = pswS ? REG_SSP : 15;
- rxIsSp = 1'b1;
- end
- else begin
- rxMux = { 1'b0, rxReg};
- rxIsSp = 1'b0;
- end
- end
-
- // RZ has higher priority!
- if( Irdecod.ryIsDt & !Nanod.rz) begin
- ryMux = REG_DT;
- ryIsSp = 1'b0;
- ryReg = 'X;
- end
- else begin
- ryReg = Nanod.rz ? Irc[15:12] : {Irdecod.ryIsAreg, Irdecod.ry};
- ryIsSp = (& ryReg);
- if( ryIsSp & pswS) // No implicit SP on RY
- ryMux = REG_SSP;
- else
- ryMux = { 1'b0, ryReg};
- end
-
- end
-
- always_ff @( posedge Clks.clk) begin
- if( enT4) begin
- byteNotSpAlign <= Irdecod.isByte & ~(Nanod.rxlDbl ? rxIsSp : ryIsSp);
-
- actualRx <= rxMux;
- actualRy <= ryMux;
-
- rxIsAreg <= rxIsSp | rxMux[3];
- ryIsAreg <= ryIsSp | ryMux[3];
- end
-
- if( enT4)
- abdIsByte <= Nanod.abdIsByte & Irdecod.isByte;
- end
-
- // Set RX/RY low word to which bus segment is connected.
-
- wire ryl2Abl = Nanod.ryl2ab & (ryIsAreg | Nanod.ablAbd);
- wire ryl2Abd = Nanod.ryl2ab & (~ryIsAreg | Nanod.ablAbd);
- wire ryl2Dbl = Nanod.ryl2db & (ryIsAreg | Nanod.dblDbd);
- wire ryl2Dbd = Nanod.ryl2db & (~ryIsAreg | Nanod.dblDbd);
-
- wire rxl2Abl = Nanod.rxl2ab & (rxIsAreg | Nanod.ablAbd);
- wire rxl2Abd = Nanod.rxl2ab & (~rxIsAreg | Nanod.ablAbd);
- wire rxl2Dbl = Nanod.rxl2db & (rxIsAreg | Nanod.dblDbd);
- wire rxl2Dbd = Nanod.rxl2db & (~rxIsAreg | Nanod.dblDbd);
-
- // Buses. Main mux
-
- logic abhIdle, ablIdle, abdIdle;
- logic dbhIdle, dblIdle, dbdIdle;
-
- always_comb begin
- {abhIdle, ablIdle, abdIdle} = '0;
- {dbhIdle, dblIdle, dbdIdle} = '0;
-
- unique case( 1'b1)
- ryl2Dbd: dbdMux = regs68L[ actualRy];
- rxl2Dbd: dbdMux = regs68L[ actualRx];
- Nanod.alue2Dbd: dbdMux = alue;
- Nanod.dbin2Dbd: dbdMux = dbin;
- Nanod.alu2Dbd: dbdMux = aluOut;
- Nanod.dcr2Dbd: dbdMux = dcrOutput;
- default: begin dbdMux = 'X; dbdIdle = 1'b1; end
- endcase
-
- unique case( 1'b1)
- rxl2Dbl: dblMux = regs68L[ actualRx];
- ryl2Dbl: dblMux = regs68L[ actualRy];
- Nanod.ftu2Dbl: dblMux = ftu;
- Nanod.au2Db: dblMux = auReg[15:0];
- Nanod.atl2Dbl: dblMux = Atl;
- Pcl2Dbl: dblMux = PcL;
- default: begin dblMux = 'X; dblIdle = 1'b1; end
- endcase
-
- unique case( 1'b1)
- Nanod.rxh2dbh: dbhMux = regs68H[ actualRx];
- Nanod.ryh2dbh: dbhMux = regs68H[ actualRy];
- Nanod.au2Db: dbhMux = auReg[31:16];
- Nanod.ath2Dbh: dbhMux = Ath;
- Pch2Dbh: dbhMux = PcH;
- default: begin dbhMux = 'X; dbhIdle = 1'b1; end
- endcase
-
- unique case( 1'b1)
- ryl2Abd: abdMux = regs68L[ actualRy];
- rxl2Abd: abdMux = regs68L[ actualRx];
- Nanod.dbin2Abd: abdMux = dbin;
- Nanod.alu2Abd: abdMux = aluOut;
- default: begin abdMux = 'X; abdIdle = 1'b1; end
- endcase
-
- unique case( 1'b1)
- Pcl2Abl: ablMux = PcL;
- rxl2Abl: ablMux = regs68L[ actualRx];
- ryl2Abl: ablMux = regs68L[ actualRy];
- Nanod.ftu2Abl: ablMux = ftu;
- Nanod.au2Ab: ablMux = auReg[15:0];
- Nanod.aob2Ab: ablMux = aob[15:0];
- Nanod.atl2Abl: ablMux = Atl;
- default: begin ablMux = 'X; ablIdle = 1'b1; end
- endcase
-
- unique case( 1'b1)
- Pch2Abh: abhMux = PcH;
- Nanod.rxh2abh: abhMux = regs68H[ actualRx];
- Nanod.ryh2abh: abhMux = regs68H[ actualRy];
- Nanod.au2Ab: abhMux = auReg[31:16];
- Nanod.aob2Ab: abhMux = aob[31:16];
- Nanod.ath2Abh: abhMux = Ath;
- default: begin abhMux = 'X; abhIdle = 1'b1; end
- endcase
-
- end
-
- // Source starts driving the bus on T1. Bus holds data until end of T3. Destination latches at T3.
-
- // These registers store the first level mux, without bus interconnections.
- // Even when this uses almost to 100 registers, it saves a lot of comb muxing and it is much faster.
- reg [15:0] preAbh, preAbl, preAbd;
- reg [15:0] preDbh, preDbl, preDbd;
-
- always_ff @( posedge Clks.clk) begin
-
- // Register first level mux at T1
- if( enT1) begin
- {preAbh, preAbl, preAbd} <= { abhMux, ablMux, abdMux};
- {preDbh, preDbl, preDbd} <= { dbhMux, dblMux, dbdMux};
- end
-
- // Process bus interconnection at T2. Many combinations only used on DIV
- // We use a simple method. If a specific bus segment is not driven we know that it should get data from a neighbour segment.
- // In some cases this is not true and the segment is really idle without any destination. But then it doesn't matter.
-
- if( enT2) begin
- if( Nanod.extAbh)
- Abh <= { 16{ ablIdle ? preAbd[ 15] : preAbl[ 15] }};
- else if( abhIdle)
- Abh <= ablIdle ? preAbd : preAbl;
- else
- Abh <= preAbh;
-
- if( ~ablIdle)
- Abl <= preAbl;
- else
- Abl <= Nanod.ablAbh ? preAbh : preAbd;
-
- Abd <= ~abdIdle ? preAbd : ablIdle ? preAbh : preAbl;
-
- if( Nanod.extDbh)
- Dbh <= { 16{ dblIdle ? preDbd[ 15] : preDbl[ 15] }};
- else if( dbhIdle)
- Dbh <= dblIdle ? preDbd : preDbl;
- else
- Dbh <= preDbh;
-
- if( ~dblIdle)
- Dbl <= preDbl;
- else
- Dbl <= Nanod.dblDbh ? preDbh : preDbd;
-
- Dbd <= ~dbdIdle ? preDbd: dblIdle ? preDbh : preDbl;
-
- /*
- Dbl <= dblMux; Dbh <= dbhMux;
- Abd <= abdMux; Dbd <= dbdMux;
- Abh <= abhMux; Abl <= ablMux; */
- end
- end
-
- // AOB
- //
- // Originally change on T1. We do on T2, only then the output is enabled anyway.
- //
- // AOB[0] is used for address error. But even when raises on T1, seems not actually used until T2 or possibly T3.
- // It is used on T1 when deasserted at the BSER exception ucode. Probably deassertion timing is not critical.
- // But in that case (at BSER), AOB is loaded from AU, so we can safely transfer on T1.
-
- // We need to take directly from first level muxes that are updated and T1
-
- wire au2Aob = Nanod.au2Aob | (Nanod.au2Db & Nanod.db2Aob);
-
- always_ff @( posedge Clks.clk) begin
- // UNIQUE IF !
-
- if( enT1 & au2Aob) // From AU we do can on T1
- aob <= auReg;
- else if( enT2) begin
- if( Nanod.db2Aob)
- aob <= { preDbh, ~dblIdle ? preDbl : preDbd};
- else if( Nanod.ab2Aob)
- aob <= { preAbh, ~ablIdle ? preAbl : preAbd};
- end
- end
-
- assign eab = aob[23:1];
- assign aob0 = aob[0];
-
- // AU
- logic [31:0] auInpMux;
-
- // `ifdef ALW_COMB_BUG
- // Old Modelsim bug. Doesn't update ouput always. Need excplicit sensitivity list !?
- // always @( Nanod.auCntrl) begin
-
- always_comb begin
- unique case( Nanod.auCntrl)
- 3'b000: auInpMux = 0;
- 3'b001: auInpMux = byteNotSpAlign | Nanod.noSpAlign ? 1 : 2; // +1/+2
- 3'b010: auInpMux = -4;
- 3'b011: auInpMux = { Abh, Abl};
- 3'b100: auInpMux = 2;
- 3'b101: auInpMux = 4;
- 3'b110: auInpMux = -2;
- 3'b111: auInpMux = byteNotSpAlign | Nanod.noSpAlign ? -1 : -2; // -1/-2
- default: auInpMux = 'X;
- endcase
- end
-
- // Simulation problem
- // Sometimes (like in MULM1) DBH is not set. AU is used in these cases just as a 6 bits counter testing if bits 5-0 are zero.
- // But when adding something like 32'hXXXX0000, the simulator (incorrectly) will set *all the 32 bits* of the result as X.
-
-// synthesis translate_off
- `define SIMULBUGX32 1
- wire [16:0] aulow = Dbl + auInpMux[15:0];
- wire [31:0] auResult = {Dbh + auInpMux[31:16] + aulow[16], aulow[15:0]};
-// synthesis translate_on
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.pwrUp)
- auReg <= '0;
- else if( enT3 & Nanod.auClkEn)
- `ifdef SIMULBUGX32
- auReg <= auResult;
- `else
- auReg <= { Dbh, Dbl } + auInpMux;
- `endif
- end
-
-
- // Main A/D registers
-
- always_ff @( posedge Clks.clk) begin
- if( enT3) begin
- if( Nanod.dbl2rxl | Nanod.abl2rxl) begin
- if( ~rxIsAreg) begin
- if( Nanod.dbl2rxl) regs68L[ actualRx] <= Dbd;
- else if( abdIsByte) regs68L[ actualRx][7:0] <= Abd[7:0];
- else regs68L[ actualRx] <= Abd;
- end
- else
- regs68L[ actualRx] <= Nanod.dbl2rxl ? Dbl : Abl;
- end
-
- if( Nanod.dbl2ryl | Nanod.abl2ryl) begin
- if( ~ryIsAreg) begin
- if( Nanod.dbl2ryl) regs68L[ actualRy] <= Dbd;
- else if( abdIsByte) regs68L[ actualRy][7:0] <= Abd[7:0];
- else regs68L[ actualRy] <= Abd;
- end
- else
- regs68L[ actualRy] <= Nanod.dbl2ryl ? Dbl : Abl;
- end
-
- // High registers are easier. Both A & D on the same buses, and not byte ops.
- if( Nanod.dbh2rxh | Nanod.abh2rxh)
- regs68H[ actualRx] <= Nanod.dbh2rxh ? Dbh : Abh;
- if( Nanod.dbh2ryh | Nanod.abh2ryh)
- regs68H[ actualRy] <= Nanod.dbh2ryh ? Dbh : Abh;
-
- end
- end
-
- // PC & AT
- reg dbl2Pcl, dbh2Pch, abh2Pch, abl2Pcl;
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.extReset) begin
- { dbl2Pcl, dbh2Pch, abh2Pch, abl2Pcl } <= '0;
-
- Pcl2Dbl <= 1'b0;
- Pch2Dbh <= 1'b0;
- Pcl2Abl <= 1'b0;
- Pch2Abh <= 1'b0;
- end
- else if( enT4) begin // Must latch on T4 !
- dbl2Pcl <= Nanod.dbl2reg & Nanod.pcldbl;
- dbh2Pch <= Nanod.dbh2reg & Nanod.pchdbh;
- abh2Pch <= Nanod.abh2reg & Nanod.pchabh;
- abl2Pcl <= Nanod.abl2reg & Nanod.pclabl;
-
- Pcl2Dbl <= Nanod.reg2dbl & Nanod.pcldbl;
- Pch2Dbh <= Nanod.reg2dbh & Nanod.pchdbh;
- Pcl2Abl <= Nanod.reg2abl & Nanod.pclabl;
- Pch2Abh <= Nanod.reg2abh & Nanod.pchabh;
- end
-
- // Unique IF !!!
- if( enT1 & Nanod.au2Pc)
- PcL <= auReg[15:0];
- else if( enT3) begin
- if( dbl2Pcl)
- PcL <= Dbl;
- else if( abl2Pcl)
- PcL <= Abl;
- end
-
- // Unique IF !!!
- if( enT1 & Nanod.au2Pc)
- PcH <= auReg[31:16];
- else if( enT3) begin
- if( dbh2Pch)
- PcH <= Dbh;
- else if( abh2Pch)
- PcH <= Abh;
- end
-
- // Unique IF !!!
- if( enT3) begin
- if( Nanod.dbl2Atl)
- Atl <= Dbl;
- else if( Nanod.abl2Atl)
- Atl <= Abl;
- end
-
- // Unique IF !!!
- if( enT3) begin
- if( Nanod.abh2Ath)
- Ath <= Abh;
- else if( Nanod.dbh2Ath)
- Ath <= Dbh;
- end
-
- end
-
- // Movem reg mask priority encoder
-
- wire rmIdle;
- logic [3:0] prHbit;
- logic [15:0] prenLatch;
-
- // Invert reg order for predecrement mode
- assign prenEmpty = (~| prenLatch);
- pren rmPren( .mask( prenLatch), .hbit (prHbit));
-
- always_ff @( posedge Clks.clk) begin
- // Cheating: PREN always loaded from DBIN
- // Must be on T1 to branch earlier if reg mask is empty!
- if( enT1 & Nanod.abl2Pren)
- prenLatch <= dbin;
- else if( enT3 & Nanod.updPren) begin
- prenLatch [prHbit] <= 1'b0;
- movemRx <= Irdecod.movemPreDecr ? ~prHbit : prHbit;
- end
- end
-
- // DCR
- wire [15:0] dcrCode;
-
- wire [3:0] dcrInput = abdIsByte ? { 1'b0, Abd[ 2:0]} : Abd[ 3:0];
- onehotEncoder4 dcrDecoder( .bin( dcrInput), .bitMap( dcrCode));
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.pwrUp)
- dcr4 <= '0;
- else if( enT3 & Nanod.abd2Dcr) begin
- dcrOutput <= dcrCode;
- dcr4 <= Abd[4];
- end
- end
-
- // ALUB
- reg [15:0] alub;
-
- always_ff @( posedge Clks.clk) begin
- if( enT3) begin
- // UNIQUE IF !!
- if( Nanod.dbd2Alub)
- alub <= Dbd;
- else if( Nanod.abd2Alub)
- alub <= Abd; // abdIsByte affects this !!??
- end
- end
-
- wire alueClkEn = enT3 & Nanod.dbd2Alue;
-
- // DOB/DBIN/IRC
-
- logic [15:0] dobInput;
- wire dobIdle = (~| Nanod.dobCtrl);
-
- always_comb begin
- unique case (Nanod.dobCtrl)
- NANO_DOB_ADB: dobInput = Abd;
- NANO_DOB_DBD: dobInput = Dbd;
- NANO_DOB_ALU: dobInput = aluOut;
- default: dobInput = 'X;
- endcase
- end
-
- dataIo dataIo( .Clks, .enT1, .enT2, .enT3, .enT4, .Nanod, .Irdecod,
- .iEdb, .dobIdle, .dobInput, .aob0,
- .Irc, .dbin, .oEdb);
-
- fx68kAlu alu(
- .clk( Clks.clk), .pwrUp( Clks.pwrUp), .enT1, .enT3, .enT4,
- .ird( Ird),
- .aluColumn( Nanod.aluColumn), .aluAddrCtrl( Nanod.aluActrl),
- .init( Nanod.aluInit), .finish( Nanod.aluFinish), .aluIsByte( Irdecod.isByte),
- .ftu2Ccr( Nanod.ftu2Ccr),
- .alub, .ftu, .alueClkEn, .alue,
- .aluDataCtrl( Nanod.aluDctrl), .iDataBus( Dbd), .iAddrBus(Abd),
- .ze, .aluOut, .ccr);
-
-endmodule
diff --git a/common/CPU/68000/FX68k/fx68k.sv b/common/CPU/68000/FX68k/fx68k.sv
index 996d9ac3..d7717454 100644
--- a/common/CPU/68000/FX68k/fx68k.sv
+++ b/common/CPU/68000/FX68k/fx68k.sv
@@ -231,23 +231,12 @@ module fx68k(
wire rstUrom;
// For the time being, address translation is done for nanorom only.
- microToNanoAddr microToNanoAddr(
- .uAddr ( nma),
- .orgAddr ( orgAddr)
- );
+ microToNanoAddr microToNanoAddr( .uAddr( nma), .orgAddr);
// Output of these modules will be updated at T2 at the latest (depending on clock division)
- nanoRom nanoRom(
- .clk ( Clks.clk),
- .nanoAddr (nanoAddr),
- .nanoOutput (nanoOutput)
- );
-
- uRom uRom(
- .clk ( Clks.clk),
- .microAddr ( microAddr),
- .microOutput( microOutput));
+ nanoRom nanoRom( .clk( Clks.clk), .nanoAddr, .nanoOutput);
+ uRom uRom( .clk( Clks.clk), .microAddr, .microOutput);
always_ff @( posedge Clks.clk) begin
// uaddr originally latched on T1, except bits 6 & 7, the conditional bits, on T2
@@ -394,10 +383,10 @@ module fx68k(
rFC <= '0;
else if( enT1 & Nanod.permStart) begin // S0 phase of bus cycle
rFC[2] <= pswS;
- // PC relativ access is marked as FC type 'n' (0) at ucode.
+ // If FC is type 'n' (0) at ucode, access type depends on PC relative mode
// We don't care about RZ in this case. Those uinstructions with RZ don't start a bus cycle.
- rFC[1] <= microLatch[ 16] | ( ~microLatch[ 15] & ~Irdecod.isPcRel);
- rFC[0] <= microLatch[ 15] | ( ~microLatch[ 16] & Irdecod.isPcRel);
+ rFC[1] <= microLatch[ 16] | ( ~microLatch[ 15] & Irdecod.isPcRel);
+ rFC[0] <= microLatch[ 15] | ( ~microLatch[ 16] & ~Irdecod.isPcRel);
end
end
@@ -639,4 +628,2054 @@ module fx68k(
tvnMux = { 8'h0, Irdecod.macroTvn, 2'b00};
end
-endmodule
\ No newline at end of file
+endmodule
+
+// Nanorom (plus) decoder for die nanocode
+module nDecoder3( input s_clks Clks, input s_irdecod Irdecod, output s_nanod Nanod,
+ input enT2, enT4,
+ input [UROM_WIDTH-1:0] microLatch,
+ input [NANO_WIDTH-1:0] nanoLatch);
+
+localparam NANO_IR2IRD = 67;
+localparam NANO_TOIRC = 66;
+localparam NANO_ALU_COL = 63; // ALU operator column order is 63-64-65 !
+localparam NANO_ALU_FI = 61; // ALU finish-init 62-61
+localparam NANO_TODBIN = 60;
+localparam NANO_ALUE = 57; // 57-59 shared with DCR control
+localparam NANO_DCR = 57; // 57-59 shared with ALUE control
+localparam NANO_DOBCTRL_1 = 56; // Input to control and permwrite
+localparam NANO_LOWBYTE = 55; // Used by MOVEP
+localparam NANO_HIGHBYTE = 54;
+localparam NANO_DOBCTRL_0 = 53; // Input to control and permwrite
+localparam NANO_ALU_DCTRL = 51; // 52-51 databus input mux control
+localparam NANO_ALU_ACTRL = 50; // addrbus input mux control
+localparam NANO_DBD2ALUB = 49;
+localparam NANO_ABD2ALUB = 48;
+localparam NANO_DBIN2DBD = 47;
+localparam NANO_DBIN2ABD = 46;
+localparam NANO_ALU2ABD = 45;
+localparam NANO_ALU2DBD = 44;
+localparam NANO_RZ = 43;
+localparam NANO_BUSBYTE = 42; // If *both* this set and instruction is byte sized, then bus cycle is byte sized.
+localparam NANO_PCLABL = 41;
+localparam NANO_RXL_DBL = 40; // Switches RXL/RYL on DBL/ABL buses
+localparam NANO_PCLDBL = 39;
+localparam NANO_ABDHRECHARGE = 38;
+localparam NANO_REG2ABL = 37; // register to ABL
+localparam NANO_ABL2REG = 36; // ABL to register
+localparam NANO_ABLABD = 35;
+localparam NANO_DBLDBD = 34;
+localparam NANO_DBL2REG = 33; // DBL to register
+localparam NANO_REG2DBL = 32; // register to DBL
+localparam NANO_ATLCTRL = 29; // 31-29
+localparam NANO_FTUCONTROL = 25;
+localparam NANO_SSP = 24;
+localparam NANO_RXH_DBH = 22; // Switches RXH/RYH on DBH/ABH buses
+localparam NANO_AUOUT = 20; // 21-20
+localparam NANO_AUCLKEN = 19;
+localparam NANO_AUCTRL = 16; // 18-16
+localparam NANO_DBLDBH = 15;
+localparam NANO_ABLABH = 14;
+localparam NANO_EXT_ABH = 13;
+localparam NANO_EXT_DBH = 12;
+localparam NANO_ATHCTRL = 9; // 11-9
+localparam NANO_REG2ABH = 8; // register to ABH
+localparam NANO_ABH2REG = 7; // ABH to register
+localparam NANO_REG2DBH = 6; // register to DBH
+localparam NANO_DBH2REG = 5; // DBH to register
+localparam NANO_AOBCTRL = 3; // 4-3
+localparam NANO_PCH = 0; // 1-0 PchDbh PchAbh
+localparam NANO_NO_SP_ALGN = 0; // Same bits as above when both set
+
+localparam NANO_FTU_UPDTPEND = 1; // Also loads FTU constant according to IRD !
+localparam NANO_FTU_INIT_ST = 15; // Set S, clear T (but not TPEND)
+localparam NANO_FTU_CLRTPEND = 14;
+localparam NANO_FTU_TVN = 13;
+localparam NANO_FTU_ABL2PREN = 12; // ABL => FTU & ABL => PREN. Both transfers enabled, but only one will be used depending on uroutine.
+localparam NANO_FTU_SSW = 11;
+localparam NANO_FTU_RSTPREN = 10;
+localparam NANO_FTU_IRD = 9;
+localparam NANO_FTU_2ABL = 8;
+localparam NANO_FTU_RDSR = 7;
+localparam NANO_FTU_INL = 6;
+localparam NANO_FTU_PSWI = 5; // Read Int Mask into FTU
+localparam NANO_FTU_DBL = 4;
+localparam NANO_FTU_2SR = 2;
+localparam NANO_FTU_CONST = 1;
+
+ reg [3:0] ftuCtrl;
+
+ logic [2:0] athCtrl, atlCtrl;
+ assign athCtrl = nanoLatch[ NANO_ATHCTRL+2: NANO_ATHCTRL];
+ assign atlCtrl = nanoLatch[ NANO_ATLCTRL+2: NANO_ATLCTRL];
+ wire [1:0] aobCtrl = nanoLatch[ NANO_AOBCTRL+1:NANO_AOBCTRL];
+ wire [1:0] dobCtrl = {nanoLatch[ NANO_DOBCTRL_1], nanoLatch[NANO_DOBCTRL_0]};
+
+ always_ff @( posedge Clks.clk) begin
+ if( enT4) begin
+ // Reverse order!
+ ftuCtrl <= { nanoLatch[ NANO_FTUCONTROL+0], nanoLatch[ NANO_FTUCONTROL+1], nanoLatch[ NANO_FTUCONTROL+2], nanoLatch[ NANO_FTUCONTROL+3]} ;
+
+ Nanod.auClkEn <= !nanoLatch[ NANO_AUCLKEN];
+ Nanod.auCntrl <= nanoLatch[ NANO_AUCTRL+2 : NANO_AUCTRL+0];
+ Nanod.noSpAlign <= (nanoLatch[ NANO_NO_SP_ALGN + 1:NANO_NO_SP_ALGN] == 2'b11);
+ Nanod.extDbh <= nanoLatch[ NANO_EXT_DBH];
+ Nanod.extAbh <= nanoLatch[ NANO_EXT_ABH];
+ Nanod.todbin <= nanoLatch[ NANO_TODBIN];
+ Nanod.toIrc <= nanoLatch[ NANO_TOIRC];
+
+ // ablAbd is disabled on byte transfers (adbhCharge plus irdIsByte). Not sure the combination makes much sense.
+ // It happens in a few cases but I don't see anything enabled on abL (or abH) section anyway.
+
+ Nanod.ablAbd <= nanoLatch[ NANO_ABLABD];
+ Nanod.ablAbh <= nanoLatch[ NANO_ABLABH];
+ Nanod.dblDbd <= nanoLatch[ NANO_DBLDBD];
+ Nanod.dblDbh <= nanoLatch[ NANO_DBLDBH];
+
+ Nanod.dbl2Atl <= (atlCtrl == 3'b010);
+ Nanod.atl2Dbl <= (atlCtrl == 3'b011);
+ Nanod.abl2Atl <= (atlCtrl == 3'b100);
+ Nanod.atl2Abl <= (atlCtrl == 3'b101);
+
+ Nanod.aob2Ab <= (athCtrl == 3'b101); // Used on BSER1 only
+
+ Nanod.abh2Ath <= (athCtrl == 3'b001) | (athCtrl == 3'b101);
+ Nanod.dbh2Ath <= (athCtrl == 3'b100);
+ Nanod.ath2Dbh <= (athCtrl == 3'b110);
+ Nanod.ath2Abh <= (athCtrl == 3'b011);
+
+ Nanod.alu2Dbd <= nanoLatch[ NANO_ALU2DBD];
+ Nanod.alu2Abd <= nanoLatch[ NANO_ALU2ABD];
+
+ Nanod.abd2Dcr <= (nanoLatch[ NANO_DCR+1:NANO_DCR] == 2'b11);
+ Nanod.dcr2Dbd <= (nanoLatch[ NANO_DCR+2:NANO_DCR+1] == 2'b11);
+ Nanod.dbd2Alue <= (nanoLatch[ NANO_ALUE+2:NANO_ALUE+1] == 2'b10);
+ Nanod.alue2Dbd <= (nanoLatch[ NANO_ALUE+1:NANO_ALUE] == 2'b01);
+
+ Nanod.dbd2Alub <= nanoLatch[ NANO_DBD2ALUB];
+ Nanod.abd2Alub <= nanoLatch[ NANO_ABD2ALUB];
+
+ // Originally not latched. We better should because we transfer one cycle later, T3 instead of T1.
+ Nanod.dobCtrl <= dobCtrl;
+ // Nanod.adb2Dob <= (dobCtrl == 2'b10); Nanod.dbd2Dob <= (dobCtrl == 2'b01); Nanod.alu2Dob <= (dobCtrl == 2'b11);
+
+ end
+ end
+
+ // Update SSW at the start of Bus/Addr error ucode
+ assign Nanod.updSsw = Nanod.aob2Ab;
+
+ assign Nanod.updTpend = (ftuCtrl == NANO_FTU_UPDTPEND);
+ assign Nanod.clrTpend = (ftuCtrl == NANO_FTU_CLRTPEND);
+ assign Nanod.tvn2Ftu = (ftuCtrl == NANO_FTU_TVN);
+ assign Nanod.const2Ftu = (ftuCtrl == NANO_FTU_CONST);
+ assign Nanod.ftu2Dbl = (ftuCtrl == NANO_FTU_DBL) | ( ftuCtrl == NANO_FTU_INL);
+ assign Nanod.ftu2Abl = (ftuCtrl == NANO_FTU_2ABL);
+ assign Nanod.inl2psw = (ftuCtrl == NANO_FTU_INL);
+ assign Nanod.pswIToFtu = (ftuCtrl == NANO_FTU_PSWI);
+ assign Nanod.ftu2Sr = (ftuCtrl == NANO_FTU_2SR);
+ assign Nanod.sr2Ftu = (ftuCtrl == NANO_FTU_RDSR);
+ assign Nanod.ird2Ftu = (ftuCtrl == NANO_FTU_IRD); // Used on bus/addr error
+ assign Nanod.ssw2Ftu = (ftuCtrl == NANO_FTU_SSW);
+ assign Nanod.initST = (ftuCtrl == NANO_FTU_INL) | (ftuCtrl == NANO_FTU_CLRTPEND) | (ftuCtrl == NANO_FTU_INIT_ST);
+ assign Nanod.abl2Pren = (ftuCtrl == NANO_FTU_ABL2PREN);
+ assign Nanod.updPren = (ftuCtrl == NANO_FTU_RSTPREN);
+
+ assign Nanod.Ir2Ird = nanoLatch[ NANO_IR2IRD];
+
+ // ALU control better latched later after combining with IRD decoding
+
+ assign Nanod.aluDctrl = nanoLatch[ NANO_ALU_DCTRL+1 : NANO_ALU_DCTRL];
+ assign Nanod.aluActrl = nanoLatch[ NANO_ALU_ACTRL];
+ assign Nanod.aluColumn = { nanoLatch[ NANO_ALU_COL], nanoLatch[ NANO_ALU_COL+1], nanoLatch[ NANO_ALU_COL+2]};
+ wire [1:0] aluFinInit = nanoLatch[ NANO_ALU_FI+1:NANO_ALU_FI];
+ assign Nanod.aluFinish = (aluFinInit == 2'b10);
+ assign Nanod.aluInit = (aluFinInit == 2'b01);
+
+ // FTU 2 CCR encoded as both ALU Init and ALU Finish set.
+ // In theory this encoding allows writes to CCR without writing to SR
+ // But FTU 2 CCR and to SR are both set together at nanorom.
+ assign Nanod.ftu2Ccr = ( aluFinInit == 2'b11);
+
+ assign Nanod.abdIsByte = nanoLatch[ NANO_ABDHRECHARGE];
+
+ // Not being latched on T4 creates non unique case warning!
+ assign Nanod.au2Db = (nanoLatch[ NANO_AUOUT + 1: NANO_AUOUT] == 2'b01);
+ assign Nanod.au2Ab = (nanoLatch[ NANO_AUOUT + 1: NANO_AUOUT] == 2'b10);
+ assign Nanod.au2Pc = (nanoLatch[ NANO_AUOUT + 1: NANO_AUOUT] == 2'b11);
+
+ assign Nanod.db2Aob = (aobCtrl == 2'b10);
+ assign Nanod.ab2Aob = (aobCtrl == 2'b01);
+ assign Nanod.au2Aob = (aobCtrl == 2'b11);
+
+ assign Nanod.dbin2Abd = nanoLatch[ NANO_DBIN2ABD];
+ assign Nanod.dbin2Dbd = nanoLatch[ NANO_DBIN2DBD];
+
+ assign Nanod.permStart = (| aobCtrl);
+ assign Nanod.isWrite = ( | dobCtrl);
+ assign Nanod.waitBusFinish = nanoLatch[ NANO_TOIRC] | nanoLatch[ NANO_TODBIN] | Nanod.isWrite;
+ assign Nanod.busByte = nanoLatch[ NANO_BUSBYTE];
+
+ assign Nanod.noLowByte = nanoLatch[ NANO_LOWBYTE];
+ assign Nanod.noHighByte = nanoLatch[ NANO_HIGHBYTE];
+
+ // Not registered. Register at T4 after combining
+ // Might be better to remove all those and combine here instead of at execution unit !!
+ assign Nanod.abl2reg = nanoLatch[ NANO_ABL2REG];
+ assign Nanod.abh2reg = nanoLatch[ NANO_ABH2REG];
+ assign Nanod.dbl2reg = nanoLatch[ NANO_DBL2REG];
+ assign Nanod.dbh2reg = nanoLatch[ NANO_DBH2REG];
+ assign Nanod.reg2dbl = nanoLatch[ NANO_REG2DBL];
+ assign Nanod.reg2dbh = nanoLatch[ NANO_REG2DBH];
+ assign Nanod.reg2abl = nanoLatch[ NANO_REG2ABL];
+ assign Nanod.reg2abh = nanoLatch[ NANO_REG2ABH];
+
+ assign Nanod.ssp = nanoLatch[ NANO_SSP];
+
+ assign Nanod.rz = nanoLatch[ NANO_RZ];
+
+ // Actually DTL can't happen on PC relative mode. See IR decoder.
+
+ wire dtldbd = 1'b0;
+ wire dthdbh = 1'b0;
+ wire dtlabd = 1'b0;
+ wire dthabh = 1'b0;
+
+ wire dblSpecial = Nanod.pcldbl | dtldbd;
+ wire dbhSpecial = Nanod.pchdbh | dthdbh;
+ wire ablSpecial = Nanod.pclabl | dtlabd;
+ wire abhSpecial = Nanod.pchabh | dthabh;
+
+ //
+ // Combine with IRD decoding
+ // Careful that IRD is updated only on T1! All output depending on IRD must be latched on T4!
+ //
+
+ // PC used instead of RY on PC relative instuctions
+
+ assign Nanod.rxlDbl = nanoLatch[ NANO_RXL_DBL];
+ wire isPcRel = Irdecod.isPcRel & !Nanod.rz;
+ wire pcRelDbl = isPcRel & !nanoLatch[ NANO_RXL_DBL];
+ wire pcRelDbh = isPcRel & !nanoLatch[ NANO_RXH_DBH];
+ wire pcRelAbl = isPcRel & nanoLatch[ NANO_RXL_DBL];
+ wire pcRelAbh = isPcRel & nanoLatch[ NANO_RXH_DBH];
+
+ assign Nanod.pcldbl = nanoLatch[ NANO_PCLDBL] | pcRelDbl;
+ assign Nanod.pchdbh = (nanoLatch[ NANO_PCH+1:NANO_PCH] == 2'b01) | pcRelDbh;
+
+ assign Nanod.pclabl = nanoLatch[ NANO_PCLABL] | pcRelAbl;
+ assign Nanod.pchabh = (nanoLatch[ NANO_PCH+1:NANO_PCH] == 2'b10) | pcRelAbh;
+
+ // Might be better not to register these signals to allow latching RX/RY mux earlier!
+ // But then must latch Irdecod.isPcRel on T3!
+
+ always_ff @( posedge Clks.clk) begin
+ if( enT4) begin
+ Nanod.rxl2db <= Nanod.reg2dbl & !dblSpecial & nanoLatch[ NANO_RXL_DBL];
+ Nanod.rxl2ab <= Nanod.reg2abl & !ablSpecial & !nanoLatch[ NANO_RXL_DBL];
+
+ Nanod.dbl2rxl <= Nanod.dbl2reg & !dblSpecial & nanoLatch[ NANO_RXL_DBL];
+ Nanod.abl2rxl <= Nanod.abl2reg & !ablSpecial & !nanoLatch[ NANO_RXL_DBL];
+
+ Nanod.rxh2dbh <= Nanod.reg2dbh & !dbhSpecial & nanoLatch[ NANO_RXH_DBH];
+ Nanod.rxh2abh <= Nanod.reg2abh & !abhSpecial & !nanoLatch[ NANO_RXH_DBH];
+
+ Nanod.dbh2rxh <= Nanod.dbh2reg & !dbhSpecial & nanoLatch[ NANO_RXH_DBH];
+ Nanod.abh2rxh <= Nanod.abh2reg & !abhSpecial & !nanoLatch[ NANO_RXH_DBH];
+
+ Nanod.dbh2ryh <= Nanod.dbh2reg & !dbhSpecial & !nanoLatch[ NANO_RXH_DBH];
+ Nanod.abh2ryh <= Nanod.abh2reg & !abhSpecial & nanoLatch[ NANO_RXH_DBH];
+
+ Nanod.dbl2ryl <= Nanod.dbl2reg & !dblSpecial & !nanoLatch[ NANO_RXL_DBL];
+ Nanod.abl2ryl <= Nanod.abl2reg & !ablSpecial & nanoLatch[ NANO_RXL_DBL];
+
+ Nanod.ryl2db <= Nanod.reg2dbl & !dblSpecial & !nanoLatch[ NANO_RXL_DBL];
+ Nanod.ryl2ab <= Nanod.reg2abl & !ablSpecial & nanoLatch[ NANO_RXL_DBL];
+
+ Nanod.ryh2dbh <= Nanod.reg2dbh & !dbhSpecial & !nanoLatch[ NANO_RXH_DBH];
+ Nanod.ryh2abh <= Nanod.reg2abh & !abhSpecial & nanoLatch[ NANO_RXH_DBH];
+ end
+
+ // Originally isTas only delayed on T2 (and seems only a late mask rev fix)
+ // Better latch the combination on T4
+ if( enT4)
+ Nanod.isRmc <= Irdecod.isTas & nanoLatch[ NANO_BUSBYTE];
+ end
+
+
+endmodule
+
+//
+// IRD execution decoder. Complements nano code decoder
+//
+// IRD updated on T1, while ncode still executing. To avoid using the next IRD,
+// decoded signals must be registered on T3, or T4 before using them.
+//
+module irdDecode( input [15:0] ird,
+ output s_irdecod Irdecod);
+
+ wire [3:0] line = ird[15:12];
+ logic [15:0] lineOnehot;
+
+ // This can be registered and pipelined from the IR decoder !
+ onehotEncoder4 irdLines( line, lineOnehot);
+
+ wire isRegShift = (lineOnehot['he]) & (ird[7:6] != 2'b11);
+ wire isDynShift = isRegShift & ird[5];
+
+ assign Irdecod.isPcRel = (& ird[ 5:3]) & ~isDynShift & !ird[2] & ird[1];
+ assign Irdecod.isTas = lineOnehot[4] & (ird[11:6] == 6'b101011);
+
+ assign Irdecod.rx = ird[11:9];
+ assign Irdecod.ry = ird[ 2:0];
+
+ wire isPreDecr = (ird[ 5:3] == 3'b100);
+ wire eaAreg = (ird[5:3] == 3'b001);
+
+ // rx is A or D
+ // movem
+ always_comb begin
+ unique case( 1'b1)
+ lineOnehot[1],
+ lineOnehot[2],
+ lineOnehot[3]:
+ // MOVE: RX always Areg except if dest mode is Dn 000
+ Irdecod.rxIsAreg = (| ird[8:6]);
+
+ lineOnehot[4]: Irdecod.rxIsAreg = (& ird[8:6]); // not CHK (LEA)
+
+ lineOnehot['h8]: Irdecod.rxIsAreg = eaAreg & ird[8] & ~ird[7]; // SBCD
+ lineOnehot['hc]: Irdecod.rxIsAreg = eaAreg & ird[8] & ~ird[7]; // ABCD/EXG An,An
+
+ lineOnehot['h9],
+ lineOnehot['hb],
+ lineOnehot['hd]: Irdecod.rxIsAreg =
+ (ird[7] & ird[6]) | // SUBA/CMPA/ADDA
+ (eaAreg & ird[8] & (ird[7:6] != 2'b11)); // SUBX/CMPM/ADDX
+ default:
+ Irdecod.rxIsAreg = Irdecod.implicitSp;
+ endcase
+ end
+
+ // RX is movem
+ always_comb begin
+ Irdecod.rxIsMovem = lineOnehot[4] & ~ird[8] & ~Irdecod.implicitSp;
+ end
+ assign Irdecod.movemPreDecr = Irdecod.rxIsMovem & isPreDecr;
+
+ // RX is DT.
+ // but SSP explicit or pc explicit has higher priority!
+ // addq/subq (scc & dbcc also, but don't use rx)
+ // Immediate including static bit
+ assign Irdecod.rxIsDt = lineOnehot[5] | (lineOnehot[0] & ~ird[8]);
+
+ // RX is USP
+ assign Irdecod.rxIsUsp = lineOnehot[4] & (ird[ 11:4] == 8'he6);
+
+ // RY is DT
+ // rz or PC explicit has higher priority
+
+ wire eaImmOrAbs = (ird[5:3] == 3'b111) & ~ird[1];
+ assign Irdecod.ryIsDt = eaImmOrAbs & ~isRegShift;
+
+ // RY is Address register
+ always_comb begin
+ logic eaIsAreg;
+
+ // On most cases RY is Areg expect if mode is 000 (DATA REG) or 111 (IMM, ABS,PC REL)
+ eaIsAreg = (ird[5:3] != 3'b000) & (ird[5:3] != 3'b111);
+
+ unique case( 1'b1)
+ // MOVE: RY always Areg expect if mode is 000 (DATA REG) or 111 (IMM, ABS,PC REL)
+ // Most lines, including misc line 4, also.
+ default: Irdecod.ryIsAreg = eaIsAreg;
+
+ lineOnehot[5]: // DBcc is an exception
+ Irdecod.ryIsAreg = eaIsAreg & (ird[7:3] != 5'b11001);
+
+ lineOnehot[6],
+ lineOnehot[7]: Irdecod.ryIsAreg = 1'b0;
+
+ lineOnehot['he]:
+ Irdecod.ryIsAreg = ~isRegShift;
+ endcase
+ end
+
+ // Byte sized instruction
+
+ // Original implementation sets this for some instructions that aren't really byte size
+ // but doesn't matter because they don't have a byte transfer enabled at nanocode, such as MOVEQ
+
+ wire xIsScc = (ird[7:6] == 2'b11) & (ird[5:3] != 3'b001);
+ wire xStaticMem = (ird[11:8] == 4'b1000) & (ird[5:4] == 2'b00); // Static bit to mem
+ always_comb begin
+ unique case( 1'b1)
+ lineOnehot[0]:
+ Irdecod.isByte =
+ ( ird[8] & (ird[5:4] != 2'b00) ) | // Dynamic bit to mem
+ ( (ird[11:8] == 4'b1000) & (ird[5:4] != 2'b00) ) | // Static bit to mem
+ ( (ird[8:7] == 2'b10) & (ird[5:3] == 3'b001) ) | // Movep from mem only! For byte mux
+ ( (ird[8:6] == 3'b000) & !xStaticMem ); // Immediate byte
+
+ lineOnehot[1]: Irdecod.isByte = 1'b1; // MOVE.B
+
+
+ lineOnehot[4]: Irdecod.isByte = (ird[7:6] == 2'b00) | Irdecod.isTas;
+ lineOnehot[5]: Irdecod.isByte = (ird[7:6] == 2'b00) | xIsScc;
+
+ lineOnehot[8],
+ lineOnehot[9],
+ lineOnehot['hb],
+ lineOnehot['hc],
+ lineOnehot['hd],
+ lineOnehot['he]: Irdecod.isByte = (ird[7:6] == 2'b00);
+
+ default: Irdecod.isByte = 1'b0;
+ endcase
+ end
+
+ // Need it for special byte size. Bus is byte, but whole register word is modified.
+ assign Irdecod.isMovep = lineOnehot[0] & ird[8] & eaAreg;
+
+
+ // rxIsSP implicit use of RX for actual SP transfer
+ //
+ // This logic is simple and will include some instructions that don't actually reference SP.
+ // But doesn't matter as long as they don't perform any RX transfer.
+
+ always_comb begin
+ unique case( 1'b1)
+ lineOnehot[6]: Irdecod.implicitSp = (ird[11:8] == 4'b0001); // BSR
+ lineOnehot[4]:
+ // Misc like RTS, JSR, etc
+ Irdecod.implicitSp = (ird[11:8] == 4'b1110) | (ird[11:6] == 6'b1000_01);
+ default: Irdecod.implicitSp = 1'b0;
+ endcase
+ end
+
+ // Modify CCR (and not SR)
+ // Probably overkill !! Only needs to distinguish SR vs CCR
+ // RTR, MOVE to CCR, xxxI to CCR
+ assign Irdecod.toCcr = ( lineOnehot[4] & ((ird[11:0] == 12'he77) | (ird[11:6] == 6'b010011)) ) |
+ ( lineOnehot[0] & (ird[8:6] == 3'b000));
+
+ // FTU constants
+ // This should not be latched on T3/T4. Latch on T2 or not at all. FTU needs it on next T3.
+ // Note: Reset instruction gets constant from ALU not from FTU!
+ logic [15:0] ftuConst;
+ wire [3:0] zero28 = (ird[11:9] == 0) ? 4'h8 : { 1'b0, ird[11:9]}; // xltate 0,1-7 into 8,1-7
+
+ always_comb begin
+ unique case( 1'b1)
+ lineOnehot[6], // Bcc short
+ lineOnehot[7]: ftuConst = { { 8{ ird[ 7]}}, ird[ 7:0] }; // MOVEQ
+
+ lineOnehot['h5], // addq/subq/static shift double check this
+ lineOnehot['he]: ftuConst = { 12'b0, zero28};
+
+ // MULU/MULS DIVU/DIVS
+ lineOnehot['h8],
+ lineOnehot['hc]: ftuConst = 16'h0f;
+
+ lineOnehot[4]: ftuConst = 16'h80; // TAS
+
+ default: ftuConst = '0;
+ endcase
+ end
+ assign Irdecod.ftuConst = ftuConst;
+
+ //
+ // TRAP Vector # for group 2 exceptions
+ //
+
+ always_comb begin
+ if( lineOnehot[4]) begin
+ case ( ird[6:5])
+ 2'b00,2'b01: Irdecod.macroTvn = 6; // CHK
+ 2'b11: Irdecod.macroTvn = 7; // TRAPV
+ 2'b10: Irdecod.macroTvn = {2'b10, ird[3:0]}; // TRAP
+ endcase
+ end
+ else
+ Irdecod.macroTvn = 5; // Division by zero
+ end
+
+
+ wire eaAdir = (ird[ 5:3] == 3'b001);
+ wire size11 = ird[7] & ird[6];
+
+ // Opcodes variants that don't affect flags
+ // ADDA/SUBA ADDQ/SUBQ MOVEA
+
+ assign Irdecod.inhibitCcr =
+ ( (lineOnehot[9] | lineOnehot['hd]) & size11) | // ADDA/SUBA
+ ( lineOnehot[5] & eaAdir) | // ADDQ/SUBQ to An (originally checks for line[4] as well !?)
+ ( (lineOnehot[2] | lineOnehot[3]) & ird[8:6] == 3'b001); // MOVEA
+
+endmodule
+
+/*
+ Execution unit
+
+ Executes register transfers set by the microcode. Originally through a set of bidirectional buses.
+ Most sources are available at T3, but DBIN only at T4! CCR also might be updated at T4, but it is not connected to these buses.
+ We mux at T1 and T2, then transfer to the destination at T3. The exception is AOB that need to be updated earlier.
+
+*/
+
+module excUnit( input s_clks Clks,
+ input enT1, enT2, enT3, enT4,
+ input s_nanod Nanod, input s_irdecod Irdecod,
+ input [15:0] Ird, // ALU row (and others) decoder needs it
+ input pswS,
+ input [15:0] ftu,
+ input [15:0] iEdb,
+
+ output logic [7:0] ccr,
+ output [15:0] alue,
+
+ output prenEmpty, au05z,
+ output logic dcr4, ze,
+ output logic aob0,
+ output [15:0] AblOut,
+ output logic [15:0] Irc,
+ output logic [15:0] oEdb,
+ output logic [23:1] eab);
+
+localparam REG_USP = 15;
+localparam REG_SSP = 16;
+localparam REG_DT = 17;
+
+ // Register file
+ reg [15:0] regs68L[ 18];
+ reg [15:0] regs68H[ 18];
+
+// synthesis translate off
+ /*
+ It is bad practice to initialize simulation registers that the hardware doesn't.
+ There is risk that simulation would be different than the real hardware. But in this case is the other way around.
+ Some ROM uses something like sub.l An,An at powerup which clears the register
+ Simulator power ups the registers with 'X, as they are really undetermined at the real hardware.
+ But the simulator doesn't realize (it can't) that the same value is substracting from itself,
+ and that the result should be zero even when it's 'X - 'X.
+ */
+
+ initial begin
+ for( int i = 0; i < 18; i++) begin
+ regs68L[i] <= '0;
+ regs68H[i] <= '0;
+ end
+ end
+
+ // For simulation display only
+ wire [31:0] SSP = { regs68H[REG_SSP], regs68L[REG_SSP]};
+
+// synthesis translate on
+
+
+ wire [15:0] aluOut;
+ wire [15:0] dbin;
+ logic [15:0] dcrOutput;
+
+ reg [15:0] PcL, PcH;
+
+ reg [31:0] auReg, aob;
+
+ reg [15:0] Ath, Atl;
+
+ // Bus execution
+ reg [15:0] Dbl, Dbh;
+ reg [15:0] Abh, Abl;
+ reg [15:0] Abd, Dbd;
+
+ assign AblOut = Abl;
+ assign au05z = (~| auReg[5:0]);
+
+ logic [15:0] dblMux, dbhMux;
+ logic [15:0] abhMux, ablMux;
+ logic [15:0] abdMux, dbdMux;
+
+ logic abdIsByte;
+
+ logic Pcl2Dbl, Pch2Dbh;
+ logic Pcl2Abl, Pch2Abh;
+
+
+ // RX RY muxes
+ // RX and RY actual registers
+ logic [4:0] actualRx, actualRy;
+ logic [3:0] movemRx;
+ logic byteNotSpAlign; // Byte instruction and no sp word align
+
+ // IRD decoded signals must be latched. See comments on decoder
+ // But nanostore decoding can't be latched before T4.
+ //
+ // If we need this earlier we can register IRD decode on T3 and use nano async
+
+ logic [4:0] rxMux, ryMux;
+ logic [3:0] rxReg, ryReg;
+ logic rxIsSp, ryIsSp;
+ logic rxIsAreg, ryIsAreg;
+
+ always_comb begin
+
+ // Unique IF !!
+ if( Nanod.ssp) begin
+ rxMux = REG_SSP;
+ rxIsSp = 1'b1;
+ rxReg = 1'bX;
+ end
+ else if( Irdecod.rxIsUsp) begin
+ rxMux = REG_USP;
+ rxIsSp = 1'b1;
+ rxReg = 1'bX;
+ end
+ else if( Irdecod.rxIsDt & !Irdecod.implicitSp) begin
+ rxMux = REG_DT;
+ rxIsSp = 1'b0;
+ rxReg = 1'bX;
+ end
+ else begin
+ if( Irdecod.implicitSp)
+ rxReg = 15;
+ else if( Irdecod.rxIsMovem)
+ rxReg = movemRx;
+ else
+ rxReg = { Irdecod.rxIsAreg, Irdecod.rx};
+
+ if( (& rxReg)) begin
+ rxMux = pswS ? REG_SSP : 15;
+ rxIsSp = 1'b1;
+ end
+ else begin
+ rxMux = { 1'b0, rxReg};
+ rxIsSp = 1'b0;
+ end
+ end
+
+ // RZ has higher priority!
+ if( Irdecod.ryIsDt & !Nanod.rz) begin
+ ryMux = REG_DT;
+ ryIsSp = 1'b0;
+ ryReg = 'X;
+ end
+ else begin
+ ryReg = Nanod.rz ? Irc[15:12] : {Irdecod.ryIsAreg, Irdecod.ry};
+ ryIsSp = (& ryReg);
+ if( ryIsSp & pswS) // No implicit SP on RY
+ ryMux = REG_SSP;
+ else
+ ryMux = { 1'b0, ryReg};
+ end
+
+ end
+
+ always_ff @( posedge Clks.clk) begin
+ if( enT4) begin
+ byteNotSpAlign <= Irdecod.isByte & ~(Nanod.rxlDbl ? rxIsSp : ryIsSp);
+
+ actualRx <= rxMux;
+ actualRy <= ryMux;
+
+ rxIsAreg <= rxIsSp | rxMux[3];
+ ryIsAreg <= ryIsSp | ryMux[3];
+ end
+
+ if( enT4)
+ abdIsByte <= Nanod.abdIsByte & Irdecod.isByte;
+ end
+
+ // Set RX/RY low word to which bus segment is connected.
+
+ wire ryl2Abl = Nanod.ryl2ab & (ryIsAreg | Nanod.ablAbd);
+ wire ryl2Abd = Nanod.ryl2ab & (~ryIsAreg | Nanod.ablAbd);
+ wire ryl2Dbl = Nanod.ryl2db & (ryIsAreg | Nanod.dblDbd);
+ wire ryl2Dbd = Nanod.ryl2db & (~ryIsAreg | Nanod.dblDbd);
+
+ wire rxl2Abl = Nanod.rxl2ab & (rxIsAreg | Nanod.ablAbd);
+ wire rxl2Abd = Nanod.rxl2ab & (~rxIsAreg | Nanod.ablAbd);
+ wire rxl2Dbl = Nanod.rxl2db & (rxIsAreg | Nanod.dblDbd);
+ wire rxl2Dbd = Nanod.rxl2db & (~rxIsAreg | Nanod.dblDbd);
+
+ // Buses. Main mux
+
+ logic abhIdle, ablIdle, abdIdle;
+ logic dbhIdle, dblIdle, dbdIdle;
+
+ always_comb begin
+ {abhIdle, ablIdle, abdIdle} = '0;
+ {dbhIdle, dblIdle, dbdIdle} = '0;
+
+ unique case( 1'b1)
+ ryl2Dbd: dbdMux = regs68L[ actualRy];
+ rxl2Dbd: dbdMux = regs68L[ actualRx];
+ Nanod.alue2Dbd: dbdMux = alue;
+ Nanod.dbin2Dbd: dbdMux = dbin;
+ Nanod.alu2Dbd: dbdMux = aluOut;
+ Nanod.dcr2Dbd: dbdMux = dcrOutput;
+ default: begin dbdMux = 'X; dbdIdle = 1'b1; end
+ endcase
+
+ unique case( 1'b1)
+ rxl2Dbl: dblMux = regs68L[ actualRx];
+ ryl2Dbl: dblMux = regs68L[ actualRy];
+ Nanod.ftu2Dbl: dblMux = ftu;
+ Nanod.au2Db: dblMux = auReg[15:0];
+ Nanod.atl2Dbl: dblMux = Atl;
+ Pcl2Dbl: dblMux = PcL;
+ default: begin dblMux = 'X; dblIdle = 1'b1; end
+ endcase
+
+ unique case( 1'b1)
+ Nanod.rxh2dbh: dbhMux = regs68H[ actualRx];
+ Nanod.ryh2dbh: dbhMux = regs68H[ actualRy];
+ Nanod.au2Db: dbhMux = auReg[31:16];
+ Nanod.ath2Dbh: dbhMux = Ath;
+ Pch2Dbh: dbhMux = PcH;
+ default: begin dbhMux = 'X; dbhIdle = 1'b1; end
+ endcase
+
+ unique case( 1'b1)
+ ryl2Abd: abdMux = regs68L[ actualRy];
+ rxl2Abd: abdMux = regs68L[ actualRx];
+ Nanod.dbin2Abd: abdMux = dbin;
+ Nanod.alu2Abd: abdMux = aluOut;
+ default: begin abdMux = 'X; abdIdle = 1'b1; end
+ endcase
+
+ unique case( 1'b1)
+ Pcl2Abl: ablMux = PcL;
+ rxl2Abl: ablMux = regs68L[ actualRx];
+ ryl2Abl: ablMux = regs68L[ actualRy];
+ Nanod.ftu2Abl: ablMux = ftu;
+ Nanod.au2Ab: ablMux = auReg[15:0];
+ Nanod.aob2Ab: ablMux = aob[15:0];
+ Nanod.atl2Abl: ablMux = Atl;
+ default: begin ablMux = 'X; ablIdle = 1'b1; end
+ endcase
+
+ unique case( 1'b1)
+ Pch2Abh: abhMux = PcH;
+ Nanod.rxh2abh: abhMux = regs68H[ actualRx];
+ Nanod.ryh2abh: abhMux = regs68H[ actualRy];
+ Nanod.au2Ab: abhMux = auReg[31:16];
+ Nanod.aob2Ab: abhMux = aob[31:16];
+ Nanod.ath2Abh: abhMux = Ath;
+ default: begin abhMux = 'X; abhIdle = 1'b1; end
+ endcase
+
+ end
+
+ // Source starts driving the bus on T1. Bus holds data until end of T3. Destination latches at T3.
+
+ // These registers store the first level mux, without bus interconnections.
+ // Even when this uses almost to 100 registers, it saves a lot of comb muxing and it is much faster.
+ reg [15:0] preAbh, preAbl, preAbd;
+ reg [15:0] preDbh, preDbl, preDbd;
+
+ always_ff @( posedge Clks.clk) begin
+
+ // Register first level mux at T1
+ if( enT1) begin
+ {preAbh, preAbl, preAbd} <= { abhMux, ablMux, abdMux};
+ {preDbh, preDbl, preDbd} <= { dbhMux, dblMux, dbdMux};
+ end
+
+ // Process bus interconnection at T2. Many combinations only used on DIV
+ // We use a simple method. If a specific bus segment is not driven we know that it should get data from a neighbour segment.
+ // In some cases this is not true and the segment is really idle without any destination. But then it doesn't matter.
+
+ if( enT2) begin
+ if( Nanod.extAbh)
+ Abh <= { 16{ ablIdle ? preAbd[ 15] : preAbl[ 15] }};
+ else if( abhIdle)
+ Abh <= ablIdle ? preAbd : preAbl;
+ else
+ Abh <= preAbh;
+
+ if( ~ablIdle)
+ Abl <= preAbl;
+ else
+ Abl <= Nanod.ablAbh ? preAbh : preAbd;
+
+ Abd <= ~abdIdle ? preAbd : ablIdle ? preAbh : preAbl;
+
+ if( Nanod.extDbh)
+ Dbh <= { 16{ dblIdle ? preDbd[ 15] : preDbl[ 15] }};
+ else if( dbhIdle)
+ Dbh <= dblIdle ? preDbd : preDbl;
+ else
+ Dbh <= preDbh;
+
+ if( ~dblIdle)
+ Dbl <= preDbl;
+ else
+ Dbl <= Nanod.dblDbh ? preDbh : preDbd;
+
+ Dbd <= ~dbdIdle ? preDbd: dblIdle ? preDbh : preDbl;
+
+ /*
+ Dbl <= dblMux; Dbh <= dbhMux;
+ Abd <= abdMux; Dbd <= dbdMux;
+ Abh <= abhMux; Abl <= ablMux; */
+ end
+ end
+
+ // AOB
+ //
+ // Originally change on T1. We do on T2, only then the output is enabled anyway.
+ //
+ // AOB[0] is used for address error. But even when raises on T1, seems not actually used until T2 or possibly T3.
+ // It is used on T1 when deasserted at the BSER exception ucode. Probably deassertion timing is not critical.
+ // But in that case (at BSER), AOB is loaded from AU, so we can safely transfer on T1.
+
+ // We need to take directly from first level muxes that are updated and T1
+
+ wire au2Aob = Nanod.au2Aob | (Nanod.au2Db & Nanod.db2Aob);
+
+ always_ff @( posedge Clks.clk) begin
+ // UNIQUE IF !
+
+ if( enT1 & au2Aob) // From AU we do can on T1
+ aob <= auReg;
+ else if( enT2) begin
+ if( Nanod.db2Aob)
+ aob <= { preDbh, ~dblIdle ? preDbl : preDbd};
+ else if( Nanod.ab2Aob)
+ aob <= { preAbh, ~ablIdle ? preAbl : preAbd};
+ end
+ end
+
+ assign eab = aob[23:1];
+ assign aob0 = aob[0];
+
+ // AU
+ logic [31:0] auInpMux;
+
+ // `ifdef ALW_COMB_BUG
+ // Old Modelsim bug. Doesn't update ouput always. Need excplicit sensitivity list !?
+ // always @( Nanod.auCntrl) begin
+
+ always_comb begin
+ unique case( Nanod.auCntrl)
+ 3'b000: auInpMux = 0;
+ 3'b001: auInpMux = byteNotSpAlign | Nanod.noSpAlign ? 1 : 2; // +1/+2
+ 3'b010: auInpMux = -4;
+ 3'b011: auInpMux = { Abh, Abl};
+ 3'b100: auInpMux = 2;
+ 3'b101: auInpMux = 4;
+ 3'b110: auInpMux = -2;
+ 3'b111: auInpMux = byteNotSpAlign | Nanod.noSpAlign ? -1 : -2; // -1/-2
+ default: auInpMux = 'X;
+ endcase
+ end
+
+ // Simulation problem
+ // Sometimes (like in MULM1) DBH is not set. AU is used in these cases just as a 6 bits counter testing if bits 5-0 are zero.
+ // But when adding something like 32'hXXXX0000, the simulator (incorrectly) will set *all the 32 bits* of the result as X.
+
+// synthesis translate_off
+ `define SIMULBUGX32 1
+ wire [16:0] aulow = Dbl + auInpMux[15:0];
+ wire [31:0] auResult = {Dbh + auInpMux[31:16] + aulow[16], aulow[15:0]};
+// synthesis translate_on
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.pwrUp)
+ auReg <= '0;
+ else if( enT3 & Nanod.auClkEn)
+ `ifdef SIMULBUGX32
+ auReg <= auResult;
+ `else
+ auReg <= { Dbh, Dbl } + auInpMux;
+ `endif
+ end
+
+
+ // Main A/D registers
+
+ always_ff @( posedge Clks.clk) begin
+ if( enT3) begin
+ if( Nanod.dbl2rxl | Nanod.abl2rxl) begin
+ if( ~rxIsAreg) begin
+ if( Nanod.dbl2rxl) regs68L[ actualRx] <= Dbd;
+ else if( abdIsByte) regs68L[ actualRx][7:0] <= Abd[7:0];
+ else regs68L[ actualRx] <= Abd;
+ end
+ else
+ regs68L[ actualRx] <= Nanod.dbl2rxl ? Dbl : Abl;
+ end
+
+ if( Nanod.dbl2ryl | Nanod.abl2ryl) begin
+ if( ~ryIsAreg) begin
+ if( Nanod.dbl2ryl) regs68L[ actualRy] <= Dbd;
+ else if( abdIsByte) regs68L[ actualRy][7:0] <= Abd[7:0];
+ else regs68L[ actualRy] <= Abd;
+ end
+ else
+ regs68L[ actualRy] <= Nanod.dbl2ryl ? Dbl : Abl;
+ end
+
+ // High registers are easier. Both A & D on the same buses, and not byte ops.
+ if( Nanod.dbh2rxh | Nanod.abh2rxh)
+ regs68H[ actualRx] <= Nanod.dbh2rxh ? Dbh : Abh;
+ if( Nanod.dbh2ryh | Nanod.abh2ryh)
+ regs68H[ actualRy] <= Nanod.dbh2ryh ? Dbh : Abh;
+
+ end
+ end
+
+ // PC & AT
+ reg dbl2Pcl, dbh2Pch, abh2Pch, abl2Pcl;
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.extReset) begin
+ { dbl2Pcl, dbh2Pch, abh2Pch, abl2Pcl } <= '0;
+
+ Pcl2Dbl <= 1'b0;
+ Pch2Dbh <= 1'b0;
+ Pcl2Abl <= 1'b0;
+ Pch2Abh <= 1'b0;
+ end
+ else if( enT4) begin // Must latch on T4 !
+ dbl2Pcl <= Nanod.dbl2reg & Nanod.pcldbl;
+ dbh2Pch <= Nanod.dbh2reg & Nanod.pchdbh;
+ abh2Pch <= Nanod.abh2reg & Nanod.pchabh;
+ abl2Pcl <= Nanod.abl2reg & Nanod.pclabl;
+
+ Pcl2Dbl <= Nanod.reg2dbl & Nanod.pcldbl;
+ Pch2Dbh <= Nanod.reg2dbh & Nanod.pchdbh;
+ Pcl2Abl <= Nanod.reg2abl & Nanod.pclabl;
+ Pch2Abh <= Nanod.reg2abh & Nanod.pchabh;
+ end
+
+ // Unique IF !!!
+ if( enT1 & Nanod.au2Pc)
+ PcL <= auReg[15:0];
+ else if( enT3) begin
+ if( dbl2Pcl)
+ PcL <= Dbl;
+ else if( abl2Pcl)
+ PcL <= Abl;
+ end
+
+ // Unique IF !!!
+ if( enT1 & Nanod.au2Pc)
+ PcH <= auReg[31:16];
+ else if( enT3) begin
+ if( dbh2Pch)
+ PcH <= Dbh;
+ else if( abh2Pch)
+ PcH <= Abh;
+ end
+
+ // Unique IF !!!
+ if( enT3) begin
+ if( Nanod.dbl2Atl)
+ Atl <= Dbl;
+ else if( Nanod.abl2Atl)
+ Atl <= Abl;
+ end
+
+ // Unique IF !!!
+ if( enT3) begin
+ if( Nanod.abh2Ath)
+ Ath <= Abh;
+ else if( Nanod.dbh2Ath)
+ Ath <= Dbh;
+ end
+
+ end
+
+ // Movem reg mask priority encoder
+
+ wire rmIdle;
+ logic [3:0] prHbit;
+ logic [15:0] prenLatch;
+
+ // Invert reg order for predecrement mode
+ assign prenEmpty = (~| prenLatch);
+ pren rmPren( .mask( prenLatch), .hbit (prHbit));
+
+ always_ff @( posedge Clks.clk) begin
+ // Cheating: PREN always loaded from DBIN
+ // Must be on T1 to branch earlier if reg mask is empty!
+ if( enT1 & Nanod.abl2Pren)
+ prenLatch <= dbin;
+ else if( enT3 & Nanod.updPren) begin
+ prenLatch [prHbit] <= 1'b0;
+ movemRx <= Irdecod.movemPreDecr ? ~prHbit : prHbit;
+ end
+ end
+
+ // DCR
+ wire [15:0] dcrCode;
+
+ wire [3:0] dcrInput = abdIsByte ? { 1'b0, Abd[ 2:0]} : Abd[ 3:0];
+ onehotEncoder4 dcrDecoder( .bin( dcrInput), .bitMap( dcrCode));
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.pwrUp)
+ dcr4 <= '0;
+ else if( enT3 & Nanod.abd2Dcr) begin
+ dcrOutput <= dcrCode;
+ dcr4 <= Abd[4];
+ end
+ end
+
+ // ALUB
+ reg [15:0] alub;
+
+ always_ff @( posedge Clks.clk) begin
+ if( enT3) begin
+ // UNIQUE IF !!
+ if( Nanod.dbd2Alub)
+ alub <= Dbd;
+ else if( Nanod.abd2Alub)
+ alub <= Abd; // abdIsByte affects this !!??
+ end
+ end
+
+ wire alueClkEn = enT3 & Nanod.dbd2Alue;
+
+ // DOB/DBIN/IRC
+
+ logic [15:0] dobInput;
+ wire dobIdle = (~| Nanod.dobCtrl);
+
+ always_comb begin
+ unique case (Nanod.dobCtrl)
+ NANO_DOB_ADB: dobInput = Abd;
+ NANO_DOB_DBD: dobInput = Dbd;
+ NANO_DOB_ALU: dobInput = aluOut;
+ default: dobInput = 'X;
+ endcase
+ end
+
+ dataIo dataIo( .Clks, .enT1, .enT2, .enT3, .enT4, .Nanod, .Irdecod,
+ .iEdb, .dobIdle, .dobInput, .aob0,
+ .Irc, .dbin, .oEdb);
+
+ fx68kAlu alu(
+ .clk( Clks.clk), .pwrUp( Clks.pwrUp), .enT1, .enT3, .enT4,
+ .ird( Ird),
+ .aluColumn( Nanod.aluColumn), .aluAddrCtrl( Nanod.aluActrl),
+ .init( Nanod.aluInit), .finish( Nanod.aluFinish), .aluIsByte( Irdecod.isByte),
+ .ftu2Ccr( Nanod.ftu2Ccr),
+ .alub, .ftu, .alueClkEn, .alue,
+ .aluDataCtrl( Nanod.aluDctrl), .iDataBus( Dbd), .iAddrBus(Abd),
+ .ze, .aluOut, .ccr);
+
+endmodule
+
+//
+// Data bus I/O
+// At a separate module because it is a bit complicated and the timing is special.
+// Here we do the low/high byte mux and the special case of MOVEP.
+//
+// Original implementation is rather complex because both the internal and external buses are bidirectional.
+// Input is latched async at the EDB register.
+// We capture directly from the external data bus to the internal registers (IRC & DBIN) on PHI2, starting the external S7 phase, at a T4 internal period.
+
+module dataIo( input s_clks Clks,
+ input enT1, enT2, enT3, enT4,
+ input s_nanod Nanod, input s_irdecod Irdecod,
+ input [15:0] iEdb,
+ input aob0,
+
+ input dobIdle,
+ input [15:0] dobInput,
+
+ output logic [15:0] Irc,
+ output logic [15:0] dbin,
+ output logic [15:0] oEdb
+ );
+
+ reg [15:0] dob;
+
+ // DBIN/IRC
+
+ // Timing is different than any other register. We can latch only on the next T4 (bus phase S7).
+ // We need to register all control signals correctly because the next ublock will already be started.
+ // Can't latch control on T4 because if there are wait states there might be multiple T4 before we latch.
+
+ reg xToDbin, xToIrc;
+ reg dbinNoLow, dbinNoHigh;
+ reg byteMux, isByte_T4;
+
+ always_ff @( posedge Clks.clk) begin
+
+ // Byte mux control. Can't latch at T1. AOB might be not ready yet.
+ // Must latch IRD decode at T1 (or T4). Then combine and latch only at T3.
+
+ // Can't latch at T3, a new IRD might be loaded already at T1.
+ // Ok to latch at T4 if combination latched then at T3
+ if( enT4)
+ isByte_T4 <= Irdecod.isByte; // Includes MOVEP from mem, we could OR it here
+
+ if( enT3) begin
+ dbinNoHigh <= Nanod.noHighByte;
+ dbinNoLow <= Nanod.noLowByte;
+ byteMux <= Nanod.busByte & isByte_T4 & ~aob0;
+ end
+
+ if( enT1) begin
+ // If on wait states, we continue latching until next T1
+ xToDbin <= 1'b0;
+ xToIrc <= 1'b0;
+ end
+ else if( enT3) begin
+ xToDbin <= Nanod.todbin;
+ xToIrc <= Nanod.toIrc;
+ end
+
+ // Capture on T4 of the next ucycle
+ // If there are wait states, we keep capturing every PHI2 until the next T1
+
+ if( xToIrc & Clks.enPhi2)
+ Irc <= iEdb;
+ if( xToDbin & Clks.enPhi2) begin
+ // Original connects both halves of EDB.
+ if( ~dbinNoLow)
+ dbin[ 7:0] <= byteMux ? iEdb[ 15:8] : iEdb[7:0];
+ if( ~dbinNoHigh)
+ dbin[ 15:8] <= ~byteMux & dbinNoLow ? iEdb[ 7:0] : iEdb[ 15:8];
+ end
+ end
+
+ // DOB
+ logic byteCycle;
+
+ always_ff @( posedge Clks.clk) begin
+ // Originaly on T1. Transfer to internal EDB also on T1 (stays enabled upto the next T1). But only on T4 (S3) output enables.
+ // It is safe to do on T3, then, but control signals if derived from IRD must be registered.
+ // Originally control signals are not registered.
+
+ // Wait states don't affect DOB operation that is done at the start of the bus cycle.
+
+ if( enT4)
+ byteCycle <= Nanod.busByte & Irdecod.isByte; // busIsByte but not MOVEP
+
+ // Originally byte low/high interconnect is done at EDB, not at DOB.
+ if( enT3 & ~dobIdle) begin
+ dob[7:0] <= Nanod.noLowByte ? dobInput[15:8] : dobInput[ 7:0];
+ dob[15:8] <= (byteCycle | Nanod.noHighByte) ? dobInput[ 7:0] : dobInput[15:8];
+ end
+ end
+ assign oEdb = dob;
+
+endmodule
+
+
+// Provides ucode routine entries (A1/A3) for each opcode
+// Also checks for illegal opcode and priv violation
+
+// This is one of the slowest part of the processor.
+// But no need to optimize or pipeline because the result is not needed until at least 4 cycles.
+// IR updated at the least one microinstruction earlier.
+// Just need to configure the timing analizer correctly.
+
+module uaddrDecode(
+ input [15:0] opcode,
+ output [UADDR_WIDTH-1:0] a1, a2, a3,
+ output logic isPriv, isIllegal, isLineA, isLineF,
+ output [15:0] lineBmap);
+
+ wire [3:0] line = opcode[15:12];
+ logic [3:0] eaCol, movEa;
+
+ onehotEncoder4 irLineDecod( line, lineBmap);
+
+ assign isLineA = lineBmap[ 'hA];
+ assign isLineF = lineBmap[ 'hF];
+
+ pla_lined pla_lined( .movEa( movEa), .col( eaCol),
+ .opcode( opcode), .lineBmap( lineBmap),
+ .palIll( isIllegal), .plaA1( a1), .plaA2( a2), .plaA3( a3) );
+
+ // ea decoding
+ assign eaCol = eaDecode( opcode[ 5:0]);
+ assign movEa = eaDecode( {opcode[ 8:6], opcode[ 11:9]} );
+
+ // EA decode
+ function [3:0] eaDecode;
+ input [5:0] eaBits;
+ begin
+ unique case( eaBits[ 5:3])
+ 3'b111:
+ case( eaBits[ 2:0])
+ 3'b000: eaDecode = 7; // Absolute short
+ 3'b001: eaDecode = 8; // Absolute long
+ 3'b010: eaDecode = 9; // PC displacement
+ 3'b011: eaDecode = 10; // PC offset
+ 3'b100: eaDecode = 11; // Immediate
+ default: eaDecode = 12; // Invalid
+ endcase
+
+ default: eaDecode = eaBits[5:3]; // Register based EAs
+ endcase
+ end
+ endfunction
+
+
+ /*
+ Privileged instructions:
+
+ ANDI/EORI/ORI SR
+ MOVE to SR
+ MOVE to/from USP
+ RESET
+ RTE
+ STOP
+ */
+
+ always_comb begin
+ unique case( lineBmap)
+
+ // ori/andi/eori SR
+ 'h01: isPriv = ((opcode & 16'hf5ff) == 16'h007c);
+
+ 'h10:
+ begin
+ // No priority !!!
+ if( (opcode & 16'hffc0) == 16'h46c0) // move to sr
+ isPriv = 1'b1;
+
+ else if( (opcode & 16'hfff0) == 16'h4e60) // move usp
+ isPriv = 1'b1;
+
+ else if( opcode == 16'h4e70 || // reset
+ opcode == 16'h4e73 || // rte
+ opcode == 16'h4e72) // stop
+ isPriv = 1'b1;
+ else
+ isPriv = 1'b0;
+ end
+
+ default: isPriv = 1'b0;
+ endcase
+ end
+
+
+endmodule
+
+// bin to one-hot, 4 bits to 16-bit bitmap
+module onehotEncoder4( input [3:0] bin, output reg [15:0] bitMap);
+ always_comb begin
+ case( bin)
+ 'b0000: bitMap = 16'h0001;
+ 'b0001: bitMap = 16'h0002;
+ 'b0010: bitMap = 16'h0004;
+ 'b0011: bitMap = 16'h0008;
+ 'b0100: bitMap = 16'h0010;
+ 'b0101: bitMap = 16'h0020;
+ 'b0110: bitMap = 16'h0040;
+ 'b0111: bitMap = 16'h0080;
+ 'b1000: bitMap = 16'h0100;
+ 'b1001: bitMap = 16'h0200;
+ 'b1010: bitMap = 16'h0400;
+ 'b1011: bitMap = 16'h0800;
+ 'b1100: bitMap = 16'h1000;
+ 'b1101: bitMap = 16'h2000;
+ 'b1110: bitMap = 16'h4000;
+ 'b1111: bitMap = 16'h8000;
+ endcase
+ end
+endmodule
+
+// priority encoder
+// used by MOVEM regmask
+// this might benefit from device specific features
+// MOVEM doesn't need speed, will read the result 2 CPU cycles after each update.
+module pren( mask, hbit);
+ parameter size = 16;
+ parameter outbits = 4;
+
+ input [size-1:0] mask;
+ output reg [outbits-1:0] hbit;
+ // output reg idle;
+
+ always @( mask) begin
+ integer i;
+ hbit = 0;
+ // idle = 1;
+ for( i = size-1; i >= 0; i = i - 1) begin
+ if( mask[ i]) begin
+ hbit = i;
+ // idle = 0;
+ end
+ end
+ end
+
+endmodule
+
+// Microcode sequencer
+
+module sequencer( input s_clks Clks, input enT3,
+ input [UROM_WIDTH-1:0] microLatch,
+ input A0Err, BerrA, busAddrErr, Spuria, Avia,
+ input Tpend, intPend, isIllegal, isPriv, excRst, isLineA, isLineF,
+ input [15:0] psw,
+ input prenEmpty, au05z, dcr4, ze, i11,
+ input [1:0] alue01,
+ input [15:0] Ird,
+ input [UADDR_WIDTH-1:0] a1, a2, a3,
+ output logic [3:0] tvn,
+ output logic [UADDR_WIDTH-1:0] nma);
+
+ logic [UADDR_WIDTH-1:0] uNma;
+ logic [UADDR_WIDTH-1:0] grp1Nma;
+ logic [1:0] c0c1;
+ reg a0Rst;
+ wire A0Sel;
+ wire inGrp0Exc;
+
+ // assign nma = Clks.extReset ? RSTP0_NMA : (A0Err ? BSER1_NMA : uNma);
+ // assign nma = A0Err ? (a0Rst ? RSTP0_NMA : BSER1_NMA) : uNma;
+
+ // word type I: 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+ // NMA : .. .. 09 08 01 00 05 04 03 02 07 06 .. .. .. .. ..
+
+ wire [UADDR_WIDTH-1:0] dbNma = { microLatch[ 14:13], microLatch[ 6:5], microLatch[ 10:7], microLatch[ 12:11]};
+
+ // Group 0 exception.
+ // Separated block from regular NMA. Otherwise simulation might depend on order of assigments.
+ always_comb begin
+ if( A0Err) begin
+ if( a0Rst) // Reset
+ nma = RSTP0_NMA;
+ else if( inGrp0Exc) // Double fault
+ nma = HALT1_NMA;
+ else // Bus or address error
+ nma = BSER1_NMA;
+ end
+ else
+ nma = uNma;
+ end
+
+ always_comb begin
+ // Format II (conditional) or I (direct branch)
+ if( microLatch[1])
+ uNma = { microLatch[ 14:13], c0c1, microLatch[ 10:7], microLatch[ 12:11]};
+ else
+ case( microLatch[ 3:2])
+ 0: uNma = dbNma; // DB
+ 1: uNma = A0Sel ? grp1Nma : a1;
+ 2: uNma = a2;
+ 3: uNma = a3;
+ endcase
+ end
+
+ // Format II, conditional, NMA decoding
+ wire [1:0] enl = { Ird[6], prenEmpty}; // Updated on T3
+
+ wire [1:0] ms0 = { Ird[8], alue01[0]};
+ wire [3:0] m01 = { au05z, Ird[8], alue01};
+ wire [1:0] nz1 = { psw[ NF], psw[ ZF]};
+ wire [1:0] nv = { psw[ NF], psw[ VF]};
+
+ logic ccTest;
+ wire [4:0] cbc = microLatch[ 6:2]; // CBC bits
+
+ always_comb begin
+ unique case( cbc)
+ 'h0: c0c1 = {i11, i11}; // W/L offset EA, from IRC
+
+ 'h1: c0c1 = (au05z) ? 2'b01 : 2'b11; // Updated on T3
+ 'h11: c0c1 = (au05z) ? 2'b00 : 2'b11;
+
+ 'h02: c0c1 = { 1'b0, ~psw[ CF]}; // C used in DIV
+ 'h12: c0c1 = { 1'b1, ~psw[ CF]};
+
+ 'h03: c0c1 = {psw[ ZF], psw[ ZF]}; // Z used in DIVU
+
+ 'h04: // nz1, used in DIVS
+ case( nz1)
+ 'b00: c0c1 = 2'b10;
+ 'b10: c0c1 = 2'b01;
+ 'b01,'b11: c0c1 = 2'b11;
+ endcase
+
+ 'h05: c0c1 = {psw[ NF], 1'b1}; // N used in CHK and DIV
+ 'h15: c0c1 = {1'b1, psw[ NF]};
+
+ // nz2, used in DIVS (same combination as nz1)
+ 'h06: c0c1 = { ~nz1[1] & ~nz1[0], 1'b1};
+
+ 'h07: // ms0 used in MUL
+ case( ms0)
+ 'b10, 'b00: c0c1 = 2'b11;
+ 'b01: c0c1 = 2'b01;
+ 'b11: c0c1 = 2'b10;
+ endcase
+
+ 'h08: // m01 used in MUL
+ case( m01)
+ 'b0000,'b0001,'b0100,'b0111: c0c1 = 2'b11;
+ 'b0010,'b0011,'b0101: c0c1 = 2'b01;
+ 'b0110: c0c1 = 2'b10;
+ default: c0c1 = 2'b00;
+ endcase
+
+ // Conditional
+ 'h09: c0c1 = (ccTest) ? 2'b11 : 2'b01;
+ 'h19: c0c1 = (ccTest) ? 2'b11 : 2'b10;
+
+ // DCR bit 4 (high or low word)
+ 'h0c: c0c1 = dcr4 ? 2'b01: 2'b11;
+ 'h1c: c0c1 = dcr4 ? 2'b10: 2'b11;
+
+ // DBcc done
+ 'h0a: c0c1 = ze ? 2'b11 : 2'b00;
+
+ // nv, used in CHK
+ 'h0b: c0c1 = (nv == 2'b00) ? 2'b00 : 2'b11;
+
+ // V, used in trapv
+ 'h0d: c0c1 = { ~psw[ VF], ~psw[VF]};
+
+ // enl, combination of pren idle and word/long on IRD
+ 'h0e,'h1e:
+ case( enl)
+ 2'b00: c0c1 = 'b10;
+ 2'b10: c0c1 = 'b11;
+ // 'hx1 result 00/01 depending on condition 0e/1e
+ 2'b01,2'b11:
+ c0c1 = { 1'b0, microLatch[ 6]};
+ endcase
+
+ default: c0c1 = 'X;
+ endcase
+ end
+
+ // CCR conditional
+ always_comb begin
+ unique case( Ird[ 11:8])
+ 'h0: ccTest = 1'b1; // T
+ 'h1: ccTest = 1'b0; // F
+ 'h2: ccTest = ~psw[ CF] & ~psw[ ZF]; // HI
+ 'h3: ccTest = psw[ CF] | psw[ZF]; // LS
+ 'h4: ccTest = ~psw[ CF]; // CC (HS)
+ 'h5: ccTest = psw[ CF]; // CS (LO)
+ 'h6: ccTest = ~psw[ ZF]; // NE
+ 'h7: ccTest = psw[ ZF]; // EQ
+ 'h8: ccTest = ~psw[ VF]; // VC
+ 'h9: ccTest = psw[ VF]; // VS
+ 'ha: ccTest = ~psw[ NF]; // PL
+ 'hb: ccTest = psw[ NF]; // MI
+ 'hc: ccTest = (psw[ NF] & psw[ VF]) | (~psw[ NF] & ~psw[ VF]); // GE
+ 'hd: ccTest = (psw[ NF] & ~psw[ VF]) | (~psw[ NF] & psw[ VF]); // LT
+ 'he: ccTest = (psw[ NF] & psw[ VF] & ~psw[ ZF]) |
+ (~psw[ NF] & ~psw[ VF] & ~psw[ ZF]); // GT
+ 'hf: ccTest = psw[ ZF] | (psw[ NF] & ~psw[VF]) | (~psw[ NF] & psw[VF]); // LE
+ endcase
+ end
+
+ // Exception logic
+ logic rTrace, rInterrupt;
+ logic rIllegal, rPriv, rLineA, rLineF;
+ logic rExcRst, rExcAdrErr, rExcBusErr;
+ logic rSpurious, rAutovec;
+ wire grp1LatchEn, grp0LatchEn;
+
+ // Originally control signals latched on T4. Then exception latches updated on T3
+ assign grp1LatchEn = microLatch[0] & (microLatch[1] | !microLatch[4]);
+ assign grp0LatchEn = microLatch[4] & !microLatch[1];
+
+ assign inGrp0Exc = rExcRst | rExcBusErr | rExcAdrErr;
+
+ always_ff @( posedge Clks.clk) begin
+ if( grp0LatchEn & enT3) begin
+ rExcRst <= excRst;
+ rExcBusErr <= BerrA;
+ rExcAdrErr <= busAddrErr;
+ rSpurious <= Spuria;
+ rAutovec <= Avia;
+ end
+
+ // Update group 1 exception latches
+ // Inputs from IR decoder updated on T1 as soon as IR loaded
+ // Trace pending updated on T3 at the start of the instruction
+ // Interrupt pending on T2
+ if( grp1LatchEn & enT3) begin
+ rTrace <= Tpend;
+ rInterrupt <= intPend;
+ rIllegal <= isIllegal & ~isLineA & ~isLineF;
+ rLineA <= isLineA;
+ rLineF <= isLineF;
+ rPriv <= isPriv & !psw[ SF];
+ end
+ end
+
+ // exception priority
+ always_comb begin
+ grp1Nma = TRAC1_NMA;
+ if( rExcRst)
+ tvn = '0; // Might need to change that to signal in exception
+ else if( rExcBusErr | rExcAdrErr)
+ tvn = { 1'b1, rExcAdrErr};
+
+ // Seudo group 0 exceptions. Just for updating TVN
+ else if( rSpurious | rAutovec)
+ tvn = rSpurious ? TVN_SPURIOUS : TVN_AUTOVEC;
+
+ else if( rTrace)
+ tvn = 9;
+ else if( rInterrupt) begin
+ tvn = TVN_INTERRUPT;
+ grp1Nma = ITLX1_NMA;
+ end
+ else begin
+ unique case( 1'b1) // Can't happen more than one of these
+ rIllegal: tvn = 4;
+ rPriv: tvn = 8;
+ rLineA: tvn = 10;
+ rLineF: tvn = 11;
+ default: tvn = 1; // Signal no group 0/1 exception
+ endcase
+ end
+ end
+
+ assign A0Sel = rIllegal | rLineF | rLineA | rPriv | rTrace | rInterrupt;
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.extReset)
+ a0Rst <= 1'b1;
+ else if( enT3)
+ a0Rst <= 1'b0;
+ end
+
+endmodule
+
+
+//
+// DMA/BUS Arbitration
+//
+
+module busArbiter( input s_clks Clks,
+ input BRi, BgackI, Halti, bgBlock,
+ output busAvail,
+ output logic BGn);
+
+ enum int unsigned { DRESET = 0, DIDLE, D1, D_BR, D_BA, D_BRA, D3, D2} dmaPhase, next;
+
+ always_comb begin
+ case(dmaPhase)
+ DRESET: next = DIDLE;
+ DIDLE: begin
+ if( bgBlock)
+ next = DIDLE;
+ else if( ~BgackI)
+ next = D_BA;
+ else if( ~BRi)
+ next = D1;
+ else
+ next = DIDLE;
+ end
+
+ D_BA: begin // Loop while only BGACK asserted, BG negated here
+ if( ~BRi & !bgBlock)
+ next = D3;
+ else if( ~BgackI & !bgBlock)
+ next = D_BA;
+ else
+ next = DIDLE;
+ end
+
+ D1: next = D_BR; // Loop while only BR asserted
+ D_BR: next = ~BRi & BgackI ? D_BR : D_BA; // No direct path to IDLE !
+
+ D3: next = D_BRA;
+ D_BRA: begin // Loop while both BR and BGACK asserted
+ case( {BgackI, BRi} )
+ 2'b11: next = DIDLE; // Both deasserted
+ 2'b10: next = D_BR; // BR asserted only
+ 2'b01: next = D2; // BGACK asserted only
+ 2'b00: next = D_BRA; // Stay here while both asserted
+ endcase
+ end
+
+ // Might loop here if both deasserted, should normally don't arrive here anyway?
+ // D2: next = (BgackI & BRi) | bgBlock ? D2: D_BA;
+
+ D2: next = D_BA;
+
+ default: next = DIDLE; // Should not reach here normally
+ endcase
+ end
+
+ logic granting;
+ always_comb begin
+ unique case( next)
+ D1, D3, D_BR, D_BRA: granting = 1'b1;
+ default: granting = 1'b0;
+ endcase
+ end
+
+ reg rGranted;
+ assign busAvail = Halti & BRi & BgackI & ~rGranted;
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.extReset) begin
+ dmaPhase <= DRESET;
+ rGranted <= 1'b0;
+ end
+ else if( Clks.enPhi2) begin
+ dmaPhase <= next;
+ // Internal signal changed on PHI2
+ rGranted <= granting;
+ end
+
+ // External Output changed on PHI1
+ if( Clks.extReset)
+ BGn <= 1'b1;
+ else if( Clks.enPhi1)
+ BGn <= ~rGranted;
+
+ end
+
+endmodule
+
+module busControl( input s_clks Clks, input enT1, input enT4,
+ input permStart, permStop, iStop,
+ input aob0,
+ input isWrite, isByte, isRmc,
+ input busAvail,
+ output bgBlock,
+ output busAddrErr,
+ output waitBusCycle,
+ output busStarting, // Asserted during S0
+ output logic addrOe, // Asserted from S1 to the end, whole bus cycle except S0
+ output bciWrite, // Used for SSW on bus/addr error
+
+ input rDtack, BeDebounced, Vpai,
+ output ASn, output LDSn, output UDSn, eRWn);
+
+ reg rAS, rLDS, rUDS, rRWn;
+ assign ASn = rAS;
+ assign LDSn = rLDS;
+ assign UDSn = rUDS;
+ assign eRWn = rRWn;
+
+ reg dataOe;
+
+ reg bcPend;
+ reg isWriteReg, bciByte, isRmcReg, wendReg;
+ assign bciWrite = isWriteReg;
+ reg addrOeDelay;
+ reg isByteT4;
+
+ wire canStart, busEnd;
+ wire bcComplete, bcReset;
+
+ wire isRcmReset = bcComplete & bcReset & isRmcReg;
+
+ assign busAddrErr = aob0 & ~bciByte;
+
+ // Bus retry not really supported.
+ // It's BERR and HALT and not address error, and not read-modify cycle.
+ wire busRetry = ~busAddrErr & 1'b0;
+
+ enum int unsigned { SRESET = 0, SIDLE, S0, S2, S4, S6, SRMC_RES} busPhase, next;
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.extReset)
+ busPhase <= SRESET;
+ else if( Clks.enPhi1)
+ busPhase <= next;
+ end
+
+ always_comb begin
+ case( busPhase)
+ SRESET: next = SIDLE;
+ SRMC_RES: next = SIDLE; // Single cycle special state when read phase of RMC reset
+ S0: next = S2;
+ S2: next = S4;
+ S4: next = busEnd ? S6 : S4;
+ S6: next = isRcmReset ? SRMC_RES : (canStart ? S0 : SIDLE);
+ SIDLE: next = canStart ? S0 : SIDLE;
+ default: next = SIDLE;
+ endcase
+ end
+
+ // Idle phase of RMC bus cycle. Might be better to just add a new state
+ wire rmcIdle = (busPhase == SIDLE) & ~ASn & isRmcReg;
+
+ assign canStart = (busAvail | rmcIdle) & (bcPend | permStart) & !busRetry & !bcReset;
+
+ wire busEnding = (next == SIDLE) | (next == S0);
+
+ assign busStarting = (busPhase == S0);
+
+ // term signal (DTACK, BERR, VPA, adress error)
+ assign busEnd = ~rDtack | iStop;
+
+ // bcComplete asserted on raising edge of S6 (together with SNC).
+ assign bcComplete = (busPhase == S6);
+
+ // Clear bus info latch on completion (regular or aborted) and no bus retry (and not PHI1).
+ // bciClear asserted half clock later on PHI2, and bci latches cleared async concurrently
+ wire bciClear = bcComplete & ~busRetry;
+
+ // Reset on reset or (berr & berrDelay & (not halt or rmc) & not 6800 & in bus cycle) (and not PHI1)
+ assign bcReset = Clks.extReset | (addrOeDelay & BeDebounced & Vpai);
+
+ // Enable uclock only on S6 (S8 on Bus Error) or not bciPermStop
+ assign waitBusCycle = wendReg & !bcComplete;
+
+ // Block Bus Grant when starting new bus cycle. But No need if AS already asserted (read phase of RMC)
+ // Except that when that RMC phase aborted on bus error, it's asserted one cycle later!
+ assign bgBlock = ((busPhase == S0) & ASn) | (busPhase == SRMC_RES);
+
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.extReset) begin
+ addrOe <= 1'b0;
+ end
+ else if( Clks.enPhi2 & ( busPhase == S0)) // From S1, whole bus cycle except S0
+ addrOe <= 1'b1;
+ else if( Clks.enPhi1 & (busPhase == SRMC_RES))
+ addrOe <= 1'b0;
+ else if( Clks.enPhi1 & ~isRmcReg & busEnding)
+ addrOe <= 1'b0;
+
+ if( Clks.enPhi1)
+ addrOeDelay <= addrOe;
+
+ if( Clks.extReset) begin
+ rAS <= 1'b1;
+ rUDS <= 1'b1;
+ rLDS <= 1'b1;
+ rRWn <= 1'b1;
+ dataOe <= '0;
+ end
+ else begin
+
+ if( Clks.enPhi2 & isWriteReg & (busPhase == S2))
+ dataOe <= 1'b1;
+ else if( Clks.enPhi1 & (busEnding | (busPhase == SIDLE)) )
+ dataOe <= 1'b0;
+
+ if( Clks.enPhi1 & busEnding)
+ rRWn <= 1'b1;
+ else if( Clks.enPhi1 & isWriteReg) begin
+ // Unlike LDS/UDS Asserted even in address error
+ if( (busPhase == S0) & isWriteReg)
+ rRWn <= 1'b0;
+ end
+
+ // AS. Actually follows addrOe half cycle later!
+ if( Clks.enPhi1 & (busPhase == S0))
+ rAS <= 1'b0;
+ else if( Clks.enPhi2 & (busPhase == SRMC_RES)) // Bus error on read phase of RMC. Deasserted one cycle later
+ rAS <= 1'b1;
+ else if( Clks.enPhi2 & bcComplete & ~SRMC_RES)
+ if( ~isRmcReg) // Keep AS asserted on the IDLE phase of RMC
+ rAS <= 1'b1;
+
+ if( Clks.enPhi1 & (busPhase == S0)) begin
+ if( ~isWriteReg & !busAddrErr) begin
+ rUDS <= ~(~bciByte | ~aob0);
+ rLDS <= ~(~bciByte | aob0);
+ end
+ end
+ else if( Clks.enPhi1 & isWriteReg & (busPhase == S2) & !busAddrErr) begin
+ rUDS <= ~(~bciByte | ~aob0);
+ rLDS <= ~(~bciByte | aob0);
+ end
+ else if( Clks.enPhi2 & bcComplete) begin
+ rUDS <= 1'b1;
+ rLDS <= 1'b1;
+ end
+
+ end
+
+ end
+
+ // Bus cycle info latch. Needed because uinstr might change if the bus is busy and we must wait.
+ // Note that urom advances even on wait states. It waits *after* updating urom and nanorom latches.
+ // Even without wait states, ublocks of type ir (init reading) will not wait for bus completion.
+ // Originally latched on (permStart AND T1).
+
+ // Bus cycle info latch: isRead, isByte, read-modify-cycle, and permStart (bus cycle pending). Some previously latched on T4?
+ // permStop also latched, but unconditionally on T1
+
+ // Might make more sense to register this outside this module
+ always_ff @( posedge Clks.clk) begin
+ if( enT4) begin
+ isByteT4 <= isByte;
+ end
+ end
+
+ // Bus Cycle Info Latch
+ always_ff @( posedge Clks.clk) begin
+ if( Clks.pwrUp) begin
+ bcPend <= 1'b0;
+ wendReg <= 1'b0;
+ isWriteReg <= 1'b0;
+ bciByte <= 1'b0;
+ isRmcReg <= 1'b0;
+ end
+
+ else if( Clks.enPhi2 & (bciClear | bcReset)) begin
+ bcPend <= 1'b0;
+ wendReg <= 1'b0;
+ end
+ else begin
+ if( enT1 & permStart) begin
+ isWriteReg <= isWrite;
+ bciByte <= isByteT4;
+ isRmcReg <= isRmc & ~isWrite; // We need special case the end of the read phase only.
+ bcPend <= 1'b1;
+ end
+ if( enT1)
+ wendReg <= permStop;
+ end
+ end
+
+endmodule
+
+//
+// microrom and nanorom instantiation
+//
+// There is bit of wasting of resources here. An extra registering pipeline happens that is not needed.
+// This is just for the purpose of helping inferring block RAM using pure generic code. Inferring RAM is important for performance.
+// Might be more efficient to use vendor specific features such as clock enable.
+//
+
+module uRom( input clk, input [UADDR_WIDTH-1:0] microAddr, output logic [UROM_WIDTH-1:0] microOutput);
+ reg [UROM_WIDTH-1:0] uRam[ UROM_DEPTH];
+ initial begin
+ $readmemb("microrom.mem", uRam);
+ end
+
+ always_ff @( posedge clk)
+ microOutput <= uRam[ microAddr];
+endmodule
+
+
+module nanoRom( input clk, input [NADDR_WIDTH-1:0] nanoAddr, output logic [NANO_WIDTH-1:0] nanoOutput);
+ reg [NANO_WIDTH-1:0] nRam[ NANO_DEPTH];
+ initial begin
+ $readmemb("nanorom.mem", nRam);
+ end
+
+ always_ff @( posedge clk)
+ nanoOutput <= nRam[ nanoAddr];
+endmodule
+
+// Translate uaddr to nanoaddr
+module microToNanoAddr(
+ input [UADDR_WIDTH-1:0] uAddr,
+ output [NADDR_WIDTH-1:0] orgAddr);
+
+ wire [UADDR_WIDTH-1:2] baseAddr = uAddr[UADDR_WIDTH-1:2];
+ logic [NADDR_WIDTH-1:2] orgBase;
+ assign orgAddr = { orgBase, uAddr[1:0]};
+
+ always @( baseAddr)
+ begin
+ // nano ROM (136 addresses)
+ case( baseAddr)
+
+'h00: orgBase = 7'h0 ;
+'h01: orgBase = 7'h1 ;
+'h02: orgBase = 7'h2 ;
+'h03: orgBase = 7'h2 ;
+'h08: orgBase = 7'h3 ;
+'h09: orgBase = 7'h4 ;
+'h0A: orgBase = 7'h5 ;
+'h0B: orgBase = 7'h5 ;
+'h10: orgBase = 7'h6 ;
+'h11: orgBase = 7'h7 ;
+'h12: orgBase = 7'h8 ;
+'h13: orgBase = 7'h8 ;
+'h18: orgBase = 7'h9 ;
+'h19: orgBase = 7'hA ;
+'h1A: orgBase = 7'hB ;
+'h1B: orgBase = 7'hB ;
+'h20: orgBase = 7'hC ;
+'h21: orgBase = 7'hD ;
+'h22: orgBase = 7'hE ;
+'h23: orgBase = 7'hD ;
+'h28: orgBase = 7'hF ;
+'h29: orgBase = 7'h10 ;
+'h2A: orgBase = 7'h11 ;
+'h2B: orgBase = 7'h10 ;
+'h30: orgBase = 7'h12 ;
+'h31: orgBase = 7'h13 ;
+'h32: orgBase = 7'h14 ;
+'h33: orgBase = 7'h14 ;
+'h38: orgBase = 7'h15 ;
+'h39: orgBase = 7'h16 ;
+'h3A: orgBase = 7'h17 ;
+'h3B: orgBase = 7'h17 ;
+'h40: orgBase = 7'h18 ;
+'h41: orgBase = 7'h18 ;
+'h42: orgBase = 7'h18 ;
+'h43: orgBase = 7'h18 ;
+'h44: orgBase = 7'h19 ;
+'h45: orgBase = 7'h19 ;
+'h46: orgBase = 7'h19 ;
+'h47: orgBase = 7'h19 ;
+'h48: orgBase = 7'h1A ;
+'h49: orgBase = 7'h1A ;
+'h4A: orgBase = 7'h1A ;
+'h4B: orgBase = 7'h1A ;
+'h4C: orgBase = 7'h1B ;
+'h4D: orgBase = 7'h1B ;
+'h4E: orgBase = 7'h1B ;
+'h4F: orgBase = 7'h1B ;
+'h54: orgBase = 7'h1C ;
+'h55: orgBase = 7'h1D ;
+'h56: orgBase = 7'h1E ;
+'h57: orgBase = 7'h1F ;
+'h5C: orgBase = 7'h20 ;
+'h5D: orgBase = 7'h21 ;
+'h5E: orgBase = 7'h22 ;
+'h5F: orgBase = 7'h23 ;
+'h70: orgBase = 7'h24 ;
+'h71: orgBase = 7'h24 ;
+'h72: orgBase = 7'h24 ;
+'h73: orgBase = 7'h24 ;
+'h74: orgBase = 7'h24 ;
+'h75: orgBase = 7'h24 ;
+'h76: orgBase = 7'h24 ;
+'h77: orgBase = 7'h24 ;
+'h78: orgBase = 7'h25 ;
+'h79: orgBase = 7'h25 ;
+'h7A: orgBase = 7'h25 ;
+'h7B: orgBase = 7'h25 ;
+'h7C: orgBase = 7'h25 ;
+'h7D: orgBase = 7'h25 ;
+'h7E: orgBase = 7'h25 ;
+'h7F: orgBase = 7'h25 ;
+'h84: orgBase = 7'h26 ;
+'h85: orgBase = 7'h27 ;
+'h86: orgBase = 7'h28 ;
+'h87: orgBase = 7'h29 ;
+'h8C: orgBase = 7'h2A ;
+'h8D: orgBase = 7'h2B ;
+'h8E: orgBase = 7'h2C ;
+'h8F: orgBase = 7'h2D ;
+'h94: orgBase = 7'h2E ;
+'h95: orgBase = 7'h2F ;
+'h96: orgBase = 7'h30 ;
+'h97: orgBase = 7'h31 ;
+'h9C: orgBase = 7'h32 ;
+'h9D: orgBase = 7'h33 ;
+'h9E: orgBase = 7'h34 ;
+'h9F: orgBase = 7'h35 ;
+'hA4: orgBase = 7'h36 ;
+'hA5: orgBase = 7'h36 ;
+'hA6: orgBase = 7'h37 ;
+'hA7: orgBase = 7'h37 ;
+'hAC: orgBase = 7'h38 ;
+'hAD: orgBase = 7'h38 ;
+'hAE: orgBase = 7'h39 ;
+'hAF: orgBase = 7'h39 ;
+'hB4: orgBase = 7'h3A ;
+'hB5: orgBase = 7'h3A ;
+'hB6: orgBase = 7'h3B ;
+'hB7: orgBase = 7'h3B ;
+'hBC: orgBase = 7'h3C ;
+'hBD: orgBase = 7'h3C ;
+'hBE: orgBase = 7'h3D ;
+'hBF: orgBase = 7'h3D ;
+'hC0: orgBase = 7'h3E ;
+'hC1: orgBase = 7'h3F ;
+'hC2: orgBase = 7'h40 ;
+'hC3: orgBase = 7'h41 ;
+'hC8: orgBase = 7'h42 ;
+'hC9: orgBase = 7'h43 ;
+'hCA: orgBase = 7'h44 ;
+'hCB: orgBase = 7'h45 ;
+'hD0: orgBase = 7'h46 ;
+'hD1: orgBase = 7'h47 ;
+'hD2: orgBase = 7'h48 ;
+'hD3: orgBase = 7'h49 ;
+'hD8: orgBase = 7'h4A ;
+'hD9: orgBase = 7'h4B ;
+'hDA: orgBase = 7'h4C ;
+'hDB: orgBase = 7'h4D ;
+'hE0: orgBase = 7'h4E ;
+'hE1: orgBase = 7'h4E ;
+'hE2: orgBase = 7'h4F ;
+'hE3: orgBase = 7'h4F ;
+'hE8: orgBase = 7'h50 ;
+'hE9: orgBase = 7'h50 ;
+'hEA: orgBase = 7'h51 ;
+'hEB: orgBase = 7'h51 ;
+'hF0: orgBase = 7'h52 ;
+'hF1: orgBase = 7'h52 ;
+'hF2: orgBase = 7'h52 ;
+'hF3: orgBase = 7'h52 ;
+'hF8: orgBase = 7'h53 ;
+'hF9: orgBase = 7'h53 ;
+'hFA: orgBase = 7'h53 ;
+'hFB: orgBase = 7'h53 ;
+
+ default:
+ orgBase = 'X;
+ endcase
+ end
+
+endmodule
+
+//
+// For compilation test only
+//
+
+`ifdef FX68K_TEST
+module fx68kTop( input clk32,
+ input extReset,
+ // input pwrUp,
+
+ input DTACKn, input VPAn,
+ input BERRn,
+ input BRn, BGACKn,
+ input IPL0n, input IPL1n, input IPL2n,
+ input [15:0] iEdb,
+
+ output [15:0] oEdb,
+ output eRWn, output ASn, output LDSn, output UDSn,
+ output logic E, output VMAn,
+ output FC0, output FC1, output FC2,
+ output BGn,
+ output oRESETn, output oHALTEDn,
+ output [23:1] eab
+ );
+
+ // Clock must be at least twice the desired frequency. A 32 MHz clock means a maximum 16 MHz effective frequency.
+ // In this example we divide the clock by 4. Resulting on an effective processor running at 8 MHz.
+
+ reg [1:0] clkDivisor = '0;
+ always @( posedge clk32) begin
+ clkDivisor <= clkDivisor + 1'b1;
+ end
+
+ /*
+ These two signals must be a single cycle pulse. They don't need to be registered.
+ Same signal can't be asserted twice in a row. Other than that there are no restrictions.
+ There can be any number of cycles, or none, even variable non constant cycles, between each pulse.
+ */
+
+ wire enPhi1 = (clkDivisor == 2'b11);
+ wire enPhi2 = (clkDivisor == 2'b01);
+
+
+ fx68k fx68k( .clk( clk32),
+ .extReset, .pwrUp( extReset), .enPhi1, .enPhi2,
+
+ .DTACKn, .VPAn, .BERRn, .BRn, .BGACKn,
+ .IPL0n, .IPL1n, .IPL2n,
+ .iEdb,
+
+ .oEdb,
+ .eRWn, .ASn, .LDSn, .UDSn,
+ .E, .VMAn,
+ .FC0, .FC1, .FC2,
+ .BGn,
+ .oRESETn, .oHALTEDn, .eab);
+
+endmodule
+`endif
diff --git a/common/CPU/68000/FX68k/fx68k.txt b/common/CPU/68000/FX68k/fx68k.txt
index 7ad0b47f..3397c02f 100644
--- a/common/CPU/68000/FX68k/fx68k.txt
+++ b/common/CPU/68000/FX68k/fx68k.txt
@@ -72,3 +72,16 @@ set_multicycle_path -setup -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/micr
set_multicycle_path -hold -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/nanoAddr_reg*/D] 1
set_multicycle_path -hold -from [get_pins fx68k/Ir*/C] -to [get_pins fx68k/microAddr_reg*/D] 1
+
+The update of the CCR flags is also time critical. Some compilers might benefit with the following constraints, but this wasn't fully verified yet:
+
+
+# Altera/Intel
+# set_multicycle_path -start -setup -from [fx68k:fx68k|nanoLatch[*]]
+# -to [get_keepers fx68k:fx68k|excUnit:excUnit|fx68kAlu:alu|pswCcr[*]] 2
+# set_multicycle_path -start -setup -from [fx68k:fx68k|excUnit:excUnit|fx68kAlu:alu|oper[*]]
+# -to [get_keepers fx68k:fx68k|excUnit:excUnit|fx68kAlu:alu|pswCcr[*]] 2
+# set_multicycle_path -start -hold -from [fx68k:fx68k|nanoLatch[*]]
+# -to [get_keepers fx68k:fx68k|excUnit:excUnit|fx68kAlu:alu|pswCcr[*]] 1
+# set_multicycle_path -start -hold -from [fx68k:fx68k|excUnit:excUnit|fx68kAlu:alu|oper[*]]
+# -to [get_keepers fx68k:fx68k|excUnit:excUnit|fx68kAlu:alu|pswCcr[*]] 1
diff --git a/common/CPU/68000/FX68k/fx68k.vhd b/common/CPU/68000/FX68k/fx68k.vhd
new file mode 100644
index 00000000..1f169a8b
--- /dev/null
+++ b/common/CPU/68000/FX68k/fx68k.vhd
@@ -0,0 +1,39 @@
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package fx68k is
+COMPONENT fx68k
+PORT
+(
+ clk : in std_logic;
+ extReset : in std_logic; -- External sync reset on emulated system
+ pwrUp : in std_logic; -- Asserted together with reset on emulated system coldstart
+ enPhi1 : in std_logic;
+ enPhi2 : in std_logic; -- Clock enables. Next cycle is PHI1 or PHI2
+
+ eRWn : out std_logic;
+ ASn : out std_logic;
+ LDSn : out std_logic;
+ UDSn : out std_logic;
+ E : out std_logic;
+ VMAn : out std_logic;
+ FC0 : out std_logic;
+ FC1 : out std_logic;
+ FC2 : out std_logic;
+ BGn : out std_logic;
+ oRESETn : out std_logic;
+ oHALTEDn : out std_logic;
+ DTACKn : in std_logic;
+ VPAn : in std_logic;
+ BERRn : in std_logic;
+ BRn : in std_logic;
+ BGACKn : in std_logic;
+ IPL0n : in std_logic;
+ IPL1n : in std_logic;
+ IPL2n : in std_logic;
+ iEdb : in std_logic_vector(15 downto 0);
+ oEdb : out std_logic_vector(15 downto 0);
+ eab : out std_logic_vector(23 downto 1)
+);
+END COMPONENT;
+end package;
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/fx68kAlu.sv b/common/CPU/68000/FX68k/fx68kAlu.sv
index 347b033d..95059c43 100644
--- a/common/CPU/68000/FX68k/fx68kAlu.sv
+++ b/common/CPU/68000/FX68k/fx68kAlu.sv
@@ -96,31 +96,15 @@ module fx68kAlu ( input clk, pwrUp, enT1, enT3, enT4,
wire [15:0] cRow;
wire cIsArX;
wire cNoCcrEn;
- rowDecoder rowDecoder(
- .ird ( ird),
- .row ( cRow),
- .noCcrEn ( cNoCcrEn),
- .isArX ( cIsArX)
- );
+ rowDecoder rowDecoder( .ird( ird), .row( cRow), .noCcrEn( cNoCcrEn), .isArX( cIsArX));
// Get Operation & CCR Mask from row/col
// Registering them on T4 increase performance. But slowest part seems to be corf !
wire [4:0] cMask;
wire [4:0] aluOp;
- aluGetOp aluGetOp(
- .row ( row),
- .col ( aluColumn),
- .isCorf ( isCorf),
- .aluOp ( aluOp)
- );
-
- ccrTable ccrTable(
- .col ( aluColumn),
- .row ( row),
- .finish ( finish),
- .ccrMask ( cMask)
- );
+ aluGetOp aluGetOp( .row, .col( aluColumn), .isCorf, .aluOp);
+ ccrTable ccrTable( .col( aluColumn), .row( row), .finish, .ccrMask( cMask));
// Inefficient, uCode could help !
wire shftIsMul = row[7];
@@ -177,26 +161,16 @@ module fx68kAlu ( input clk, pwrUp, enT1, enT3, enT4,
// Can't be registered because uses bus operands that aren't available early !
wire shftMsb = isLong ? alue[15] : (isByte ? aOperand[7] : aOperand[15]);
- aluShifter shifter(
- .data ( { alue, aOperand}),
- .swapWords ( shftIsMul | shftIsDiv),
- .cin ( shftCin),
- .dir ( shftRight),
- .isByte ( isByte),
- .isLong ( isLong),
- .result ( shftResult)
- );
+ aluShifter shifter( .data( { alue, aOperand}),
+ .swapWords( shftIsMul | shftIsDiv),
+ .cin( shftCin), .dir( shftRight), .isByte( isByte), .isLong( isLong),
+ .result( shftResult));
wire [7:0] bcdResult;
wire bcdC, bcdV;
- aluCorf aluCorf(
- .binResult ( aluLatch[7:0]),
- .hCarry ( coreH),
- .bAdd ( (oper != OP_SBCD) ),
- .cin ( pswCcr[ XF]),
- .bcdResult ( bcdResult),
- .dC ( bcdC),
- .ov ( bcdV));
+ aluCorf aluCorf( .binResult( aluLatch[7:0]), .hCarry( coreH),
+ .bAdd( (oper != OP_SBCD) ), .cin( pswCcr[ XF]),
+ .bcdResult( bcdResult), .dC( bcdC), .ov( bcdV));
// BCD adjust is among the slowest processing on ALU !
// Precompute and register BCD result on T1
@@ -332,7 +306,7 @@ module fx68kAlu ( input clk, pwrUp, enT1, enT3, enT4,
ccrTemp[XF] = pswCcr[XF]; ccrTemp[CF] = 0; ccrTemp[VF] = 0;
- // Not on all operators !!!
+ // Not on all operators
ccrTemp[ ZF] = isByte ? ~(| result[7:0]) : ~(| result);
ccrTemp[ NF] = isByte ? result[7] : result[15];
@@ -341,7 +315,8 @@ module fx68kAlu ( input clk, pwrUp, enT1, enT3, enT4,
OP_EXT:
// Division overflow.
if( aluColumn == 5) begin
- ccrTemp[VF] = 1'b1; ccrTemp[NF] = 1'b1;
+ ccrTemp[VF] = 1'b1;
+ ccrTemp[NF] = 1'b1; ccrTemp[ ZF] = 1'b0;
end
OP_SUB0, // used by NOT
@@ -438,7 +413,8 @@ module fx68kAlu ( input clk, pwrUp, enT1, enT3, enT4,
logic [4:0] ccrMasked;
always_comb begin
ccrMasked = (ccrTemp & ccrMask) | (pswCcr & ~ccrMask);
- if( finish | isCorf | isArX)
+ // if( finish | isCorf | isArX) // No need to check specicially for isCorf as they always have the "finish" flag anyway
+ if( finish | isArX)
ccrMasked[ ZF] = ccrTemp[ ZF] & pswCcr[ ZF];
end
@@ -476,4 +452,388 @@ module fx68kAlu ( input clk, pwrUp, enT1, enT3, enT4,
endmodule
+// add bcd correction factor
+// It would be more efficient to merge add/sub with main ALU !!!
+module aluCorf( input [7:0] binResult, input bAdd, input cin, input hCarry,
+ output [7:0] bcdResult, output dC, output logic ov);
+ reg [8:0] htemp;
+ reg [4:0] hNib;
+
+ wire lowC = hCarry | (bAdd ? gt9( binResult[ 3:0]) : 1'b0);
+ wire highC = cin | (bAdd ? (gt9( htemp[7:4]) | htemp[8]) : 1'b0);
+
+ always_comb begin
+ if( bAdd) begin
+ htemp = { 1'b0, binResult} + (lowC ? 4'h6 : 4'h0);
+ hNib = htemp[8:4] + (highC ? 4'h6 : 4'h0);
+ ov = hNib[3] & ~binResult[7];
+ end
+ else begin
+ htemp = { 1'b0, binResult} - (lowC ? 4'h6 : 4'h0);
+ hNib = htemp[8:4] - (highC ? 4'h6 : 4'h0);
+ ov = ~hNib[3] & binResult[7];
+ end
+ end
+
+ assign bcdResult = { hNib[ 3:0], htemp[3:0]};
+ assign dC = hNib[4] | cin;
+
+ // Nibble > 9
+ function gt9 (input [3:0] nib);
+ begin
+ gt9 = nib[3] & (nib[2] | nib[1]);
+ end
+ endfunction
+
+endmodule
+
+
+module aluShifter( input [31:0] data,
+ input isByte, input isLong, swapWords,
+ input dir, input cin,
+ output logic [31:0] result);
+ // output reg cout
+
+ logic [31:0] tdata;
+
+ // size mux, put cin in position if dir == right
+ always_comb begin
+ tdata = data;
+ if( isByte & dir)
+ tdata[8] = cin;
+ else if( !isLong & dir)
+ tdata[16] = cin;
+ end
+
+ always_comb begin
+ // Reverse alu/alue position for MUL & DIV
+ // Result reversed again
+ if( swapWords & dir)
+ result = { tdata[0], tdata[31:17], cin, tdata[15:1]};
+ else if( swapWords)
+ result = { tdata[30:16], cin, tdata[14:0], tdata[31]};
+
+ else if( dir)
+ result = { cin, tdata[31:1]};
+ else
+ result = { tdata[30:0], cin};
+ end
+
+endmodule
+
+
+// Get current OP from row & col
+module aluGetOp( input [15:0] row, input [2:0] col, input isCorf,
+ output logic [4:0] aluOp);
+
+ always_comb begin
+ aluOp = 'X;
+ unique case( col)
+ 1: aluOp = OP_AND;
+ 5: aluOp = OP_EXT;
+
+ default:
+ unique case( 1'b1)
+ row[1]:
+ unique case( col)
+ 2: aluOp = OP_SUB;
+ 3: aluOp = OP_SUBC;
+ 4,6: aluOp = OP_SLAA;
+ endcase
+
+ row[2]:
+ unique case( col)
+ 2: aluOp = OP_ADD;
+ 3: aluOp = OP_ADDC;
+ 4: aluOp = OP_ASR;
+ endcase
+
+ row[3]:
+ unique case( col)
+ 2: aluOp = OP_ADDX;
+ 3: aluOp = isCorf ? OP_ABCD : OP_ADD;
+ 4: aluOp = OP_ASL;
+ endcase
+
+ row[4]:
+ aluOp = ( col == 4) ? OP_LSL : OP_AND;
+
+ row[5],
+ row[6]:
+ unique case( col)
+ 2: aluOp = OP_SUB;
+ 3: aluOp = OP_SUBC;
+ 4: aluOp = OP_LSR;
+ endcase
+
+ row[7]: // MUL
+ unique case( col)
+ 2: aluOp = OP_SUB;
+ 3: aluOp = OP_ADD;
+ 4: aluOp = OP_ROXR;
+ endcase
+
+ row[8]:
+ // OP_AND For EXT.L
+ // But would be more efficient to change ucode and use column 1 instead of col3 at ublock extr1!
+ unique case( col)
+ 2: aluOp = OP_EXT;
+ 3: aluOp = OP_AND;
+ 4: aluOp = OP_ROXR;
+ endcase
+
+ row[9]:
+ unique case( col)
+ 2: aluOp = OP_SUBX;
+ 3: aluOp = OP_SBCD;
+ 4: aluOp = OP_ROL;
+ endcase
+
+ row[10]:
+ unique case( col)
+ 2: aluOp = OP_SUBX;
+ 3: aluOp = OP_SUBC;
+ 4: aluOp = OP_ROR;
+ endcase
+
+ row[11]:
+ unique case( col)
+ 2: aluOp = OP_SUB0;
+ 3: aluOp = OP_SUB0;
+ 4: aluOp = OP_ROXL;
+ endcase
+
+ row[12]: aluOp = OP_ADDX;
+ row[13]: aluOp = OP_EOR;
+ row[14]: aluOp = (col == 4) ? OP_EOR : OP_OR;
+ row[15]: aluOp = (col == 3) ? OP_ADD : OP_OR; // OP_ADD used by DBcc
+
+ endcase
+ endcase
+ end
+endmodule
+
+// Decodes IRD into ALU row (1-15)
+// Slow, but no need to optimize for speed since IRD is latched at least two CPU cycles before it is used
+// We also register the result after combining with column from nanocode
+//
+// Many opcodes are not decoded because they either don't do any ALU op,
+// or use only columns 1 and 5 that are the same for all rows.
+
+module rowDecoder( input [15:0] ird,
+ output logic [15:0] row, output noCcrEn, output logic isArX);
+
+
+ // Addr or data register direct
+ wire eaRdir = (ird[ 5:4] == 2'b00);
+ // Addr register direct
+ wire eaAdir = (ird[ 5:3] == 3'b001);
+ wire size11 = ird[7] & ird[6];
+
+ always_comb begin
+ case( ird[15:12])
+ 'h4,
+ 'h9,
+ 'hd:
+ isArX = row[10] | row[12];
+ default:
+ isArX = 1'b0;
+ endcase
+ end
+
+ always_comb begin
+ unique case( ird[15:12])
+
+ 'h4: begin
+ if( ird[8])
+ row = `ALU_ROW_06; // chk (or lea)
+ else case( ird[11:9])
+ 'b000: row = `ALU_ROW_10; // negx
+ 'b001: row = `ALU_ROW_04; // clr
+ 'b010: row = `ALU_ROW_05; // neg
+ 'b011: row = `ALU_ROW_11; // not
+ 'b100: row = (ird[7]) ? `ALU_ROW_08 : `ALU_ROW_09; // nbcd/swap/ext(or pea)
+ 'b101: row = `ALU_ROW_15; // tst & tas
+ default: row = 0;
+ endcase
+ end
+
+ 'h0: begin
+ if( ird[8]) // dynamic bit
+ row = ird[7] ? `ALU_ROW_14 : `ALU_ROW_13;
+ else case( ird[ 11:9])
+ 'b000: row = `ALU_ROW_14; // ori
+ 'b001: row = `ALU_ROW_04; // andi
+ 'b010: row = `ALU_ROW_05; // subi
+ 'b011: row = `ALU_ROW_02; // addi
+ 'b100: row = ird[7] ? `ALU_ROW_14 : `ALU_ROW_13; // static bit
+ 'b101: row = `ALU_ROW_13; // eori
+ 'b110: row = `ALU_ROW_06; // cmpi
+ default: row = 0;
+ endcase
+ end
+
+ // MOVE
+ // move.b originally also rows 5 & 15. Only because IRD bit 14 is not decoded.
+ // It's the same for move the operations performed by MOVE.B
+
+ 'h1,'h2,'h3: row = `ALU_ROW_02;
+
+ 'h5:
+ if( size11)
+ row = `ALU_ROW_15; // As originally and easier to decode
+ else
+ row = ird[8] ? `ALU_ROW_05 : `ALU_ROW_02; // addq/subq
+ 'h6: row = 0; //bcc/bra/bsr
+ 'h7: row = `ALU_ROW_02; // moveq
+ 'h8:
+ if( size11) // div
+ row = `ALU_ROW_01;
+ else if( ird[8] & eaRdir) // sbcd
+ row = `ALU_ROW_09;
+ else
+ row = `ALU_ROW_14; // or
+ 'h9:
+ if( ird[8] & ~size11 & eaRdir)
+ row = `ALU_ROW_10; // subx
+ else
+ row = `ALU_ROW_05; // sub/suba
+ 'hb:
+ if( ird[8] & ~size11 & ~eaAdir)
+ row = `ALU_ROW_13; // eor
+ else
+ row = `ALU_ROW_06; // cmp/cmpa/cmpm
+ 'hc:
+ if( size11)
+ row = `ALU_ROW_07; // mul
+ else if( ird[8] & eaRdir) // abcd
+ row = `ALU_ROW_03;
+ else
+ row = `ALU_ROW_04; // and
+ 'hd:
+ if( ird[8] & ~size11 & eaRdir)
+ row = `ALU_ROW_12; // addx
+ else
+ row = `ALU_ROW_02; // add/adda
+ 'he:
+ begin
+ reg [1:0] stype;
+
+ if( size11) // memory shift/rotate
+ stype = ird[ 10:9];
+ else // register shift/rotate
+ stype = ird[ 4:3];
+
+ case( {stype, ird[8]})
+ 0: row = `ALU_ROW_02; // ASR
+ 1: row = `ALU_ROW_03; // ASL
+ 2: row = `ALU_ROW_05; // LSR
+ 3: row = `ALU_ROW_04; // LSL
+ 4: row = `ALU_ROW_08; // ROXR
+ 5: row = `ALU_ROW_11; // ROXL
+ 6: row = `ALU_ROW_10; // ROR
+ 7: row = `ALU_ROW_09; // ROL
+ endcase
+ end
+
+ default: row = 0;
+ endcase
+ end
+
+ // Decode opcodes that don't affect flags
+ // ADDA/SUBA ADDQ/SUBQ MOVEA
+
+ assign noCcrEn =
+ // ADDA/SUBA
+ ( ird[15] & ~ird[13] & ird[12] & size11) |
+ // ADDQ/SUBQ to An
+ ( (ird[15:12] == 4'h5) & eaAdir) |
+ // MOVEA
+ ( (~ird[15] & ~ird[14] & ird[13]) & ird[8:6] == 3'b001);
+
+endmodule
+
+// Row/col CCR update table
+module ccrTable(
+ input [2:0] col, input [15:0] row, input finish,
+ output logic [MASK_NBITS-1:0] ccrMask);
+
+ localparam
+ KNZ00 = 5'b01111, // ok coz operators clear them
+ KKZKK = 5'b00100,
+ KNZKK = 5'b01100,
+ KNZ10 = 5'b01111, // Used by OP_EXT on divison overflow
+ KNZ0C = 5'b01111, // Used by DIV. V should be 0, but it is ok:
+ // DIVU: ends with quotient - 0, so V & C always clear.
+ // DIVS: ends with 1i (AND), again, V & C always clear.
+
+ KNZVC = 5'b01111,
+ XNKVC = 5'b11011, // Used by BCD instructions. Don't modify Z at all at the binary operation. Only at the BCD correction cycle
+
+ CUPDALL = 5'b11111,
+ CUNUSED = 5'bxxxxx;
+
+
+ logic [MASK_NBITS-1:0] ccrMask1;
+
+ always_comb begin
+ unique case( col)
+ 1: ccrMask = ccrMask1;
+
+ 2,3:
+ unique case( 1'b1)
+ row[1]: ccrMask = KNZ0C; // DIV, used as 3n in col3
+
+ row[3], // ABCD
+ row[9]: // SBCD/NBCD
+ ccrMask = (col == 2) ? XNKVC : CUPDALL;
+
+ row[2],
+ row[5],
+ row[10], // SUBX/NEGX
+ row[12]: ccrMask = CUPDALL; // ADDX
+
+ row[6], // CMP
+ row[7], // MUL
+ row[11]: ccrMask = KNZVC; // NOT
+ row[4],
+ row[8], // Not used in col 3
+ row[13],
+ row[14]: ccrMask = KNZ00;
+ row[15]: ccrMask = 5'b0; // TAS/Scc, not used in col 3
+ // default: ccrMask = CUNUSED;
+ endcase
+
+ 4:
+ unique case( row)
+ // 1: DIV, only n (4n & 6n)
+ // 14: BCLR 4n
+ // 6,12,13,15 // not used
+ `ALU_ROW_02,
+ `ALU_ROW_03, // ASL (originally ANZVA)
+ `ALU_ROW_04,
+ `ALU_ROW_05: ccrMask = CUPDALL; // Shifts (originally ANZ0A)
+
+ `ALU_ROW_07: ccrMask = KNZ00; // MUL (originally KNZ0A)
+ `ALU_ROW_09,
+ `ALU_ROW_10: ccrMask = KNZ00; // RO[lr] (originally KNZ0A)
+ `ALU_ROW_08, // ROXR (originally ANZ0A)
+ `ALU_ROW_11: ccrMask = CUPDALL; // ROXL (originally ANZ0A)
+ default: ccrMask = CUNUSED;
+ endcase
+
+ 5: ccrMask = row[1] ? KNZ10 : 5'b0;
+ default: ccrMask = CUNUSED;
+ endcase
+ end
+
+ // Column 1 (AND)
+ always_comb begin
+ if( finish)
+ ccrMask1 = row[7] ? KNZ00 : KNZKK;
+ else
+ ccrMask1 = row[13] | row[14] ? KKZKK : KNZ00;
+ end
+
+endmodule
diff --git a/common/CPU/68000/FX68k/fx68k_tb.sv b/common/CPU/68000/FX68k/fx68k_tb.sv
deleted file mode 100644
index de558a77..00000000
--- a/common/CPU/68000/FX68k/fx68k_tb.sv
+++ /dev/null
@@ -1,57 +0,0 @@
-
-//
-// For compilation test only
-//
-
-module fx68k_tb( input clk32,
- input extReset,
- // input pwrUp,
-
- input DTACKn, input VPAn,
- input BERRn,
- input BRn, BGACKn,
- input IPL0n, input IPL1n, input IPL2n,
- input [15:0] iEdb,
-
- output [15:0] oEdb,
- output eRWn, output ASn, output LDSn, output UDSn,
- output logic E, output VMAn,
- output FC0, output FC1, output FC2,
- output BGn,
- output oRESETn, output oHALTEDn,
- output [23:1] eab
- );
-
- // Clock must be at least twice the desired frequency. A 32 MHz clock means a maximum 16 MHz effective frequency.
- // In this example we divide the clock by 4. Resulting on an effective processor running at 8 MHz.
-
- reg [1:0] clkDivisor = '0;
- always @( posedge clk32) begin
- clkDivisor <= clkDivisor + 1'b1;
- end
-
- /*
- These two signals must be a single cycle pulse. They don't need to be registered.
- Same signal can't be asserted twice in a row. Other than that there are no restrictions.
- There can be any number of cycles, or none, even variable non constant cycles, between each pulse.
- */
-
- wire enPhi1 = (clkDivisor == 2'b11);
- wire enPhi2 = (clkDivisor == 2'b01);
-
-
- fx68k fx68k( .clk( clk32),
- .extReset, .pwrUp( extReset), .enPhi1, .enPhi2,
-
- .DTACKn, .VPAn, .BERRn, .BRn, .BGACKn,
- .IPL0n, .IPL1n, .IPL2n,
- .iEdb,
-
- .oEdb,
- .eRWn, .ASn, .LDSn, .UDSn,
- .E, .VMAn,
- .FC0, .FC1, .FC2,
- .BGn,
- .oRESETn, .oHALTEDn, .eab);
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/irdDecode.sv b/common/CPU/68000/FX68k/irdDecode.sv
deleted file mode 100644
index 0a3d193a..00000000
--- a/common/CPU/68000/FX68k/irdDecode.sv
+++ /dev/null
@@ -1,208 +0,0 @@
-//
-// IRD execution decoder. Complements nano code decoder
-//
-// IRD updated on T1, while ncode still executing. To avoid using the next IRD,
-// decoded signals must be registered on T3, or T4 before using them.
-//
-module irdDecode( input [15:0] ird,
- output s_irdecod Irdecod);
-
- wire [3:0] line = ird[15:12];
- logic [15:0] lineOnehot;
-
- // This can be registered and pipelined from the IR decoder !
- onehotEncoder4 irdLines( line, lineOnehot);
-
- wire isRegShift = (lineOnehot['he]) & (ird[7:6] != 2'b11);
- wire isDynShift = isRegShift & ird[5];
-
- assign Irdecod.isPcRel = (& ird[ 5:3]) & ~isDynShift & !ird[2] & ird[1];
- assign Irdecod.isTas = lineOnehot[4] & (ird[11:6] == 6'b101011);
-
- assign Irdecod.rx = ird[11:9];
- assign Irdecod.ry = ird[ 2:0];
-
- wire isPreDecr = (ird[ 5:3] == 3'b100);
- wire eaAreg = (ird[5:3] == 3'b001);
-
- // rx is A or D
- // movem
- always_comb begin
- unique case( 1'b1)
- lineOnehot[1],
- lineOnehot[2],
- lineOnehot[3]:
- // MOVE: RX always Areg except if dest mode is Dn 000
- Irdecod.rxIsAreg = (| ird[8:6]);
-
- lineOnehot[4]: Irdecod.rxIsAreg = (& ird[8:6]); // not CHK (LEA)
-
- lineOnehot['h8]: Irdecod.rxIsAreg = eaAreg & ird[8] & ~ird[7]; // SBCD
- lineOnehot['hc]: Irdecod.rxIsAreg = eaAreg & ird[8] & ~ird[7]; // ABCD/EXG An,An
-
- lineOnehot['h9],
- lineOnehot['hb],
- lineOnehot['hd]: Irdecod.rxIsAreg =
- (ird[7] & ird[6]) | // SUBA/CMPA/ADDA
- (eaAreg & ird[8] & (ird[7:6] != 2'b11)); // SUBX/CMPM/ADDX
- default:
- Irdecod.rxIsAreg = Irdecod.implicitSp;
- endcase
- end
-
- // RX is movem
- always_comb begin
- Irdecod.rxIsMovem = lineOnehot[4] & ~ird[8] & ~Irdecod.implicitSp;
- end
- assign Irdecod.movemPreDecr = Irdecod.rxIsMovem & isPreDecr;
-
- // RX is DT.
- // but SSP explicit or pc explicit has higher priority!
- // addq/subq (scc & dbcc also, but don't use rx)
- // Immediate including static bit
- assign Irdecod.rxIsDt = lineOnehot[5] | (lineOnehot[0] & ~ird[8]);
-
- // RX is USP
- assign Irdecod.rxIsUsp = lineOnehot[4] & (ird[ 11:4] == 8'he6);
-
- // RY is DT
- // rz or PC explicit has higher priority
-
- wire eaImmOrAbs = (ird[5:3] == 3'b111) & ~ird[1];
- assign Irdecod.ryIsDt = eaImmOrAbs & ~isRegShift;
-
- // RY is Address register
- always_comb begin
- logic eaIsAreg;
-
- // On most cases RY is Areg expect if mode is 000 (DATA REG) or 111 (IMM, ABS,PC REL)
- eaIsAreg = (ird[5:3] != 3'b000) & (ird[5:3] != 3'b111);
-
- unique case( 1'b1)
- // MOVE: RY always Areg expect if mode is 000 (DATA REG) or 111 (IMM, ABS,PC REL)
- // Most lines, including misc line 4, also.
- default: Irdecod.ryIsAreg = eaIsAreg;
-
- lineOnehot[5]: // DBcc is an exception
- Irdecod.ryIsAreg = eaIsAreg & (ird[7:3] != 5'b11001);
-
- lineOnehot[6],
- lineOnehot[7]: Irdecod.ryIsAreg = 1'b0;
-
- lineOnehot['he]:
- Irdecod.ryIsAreg = ~isRegShift;
- endcase
- end
-
- // Byte sized instruction
-
- // Original implementation sets this for some instructions that aren't really byte size
- // but doesn't matter because they don't have a byte transfer enabled at nanocode, such as MOVEQ
-
- wire xIsScc = (ird[7:6] == 2'b11) & (ird[5:3] != 3'b001);
- wire xStaticMem = (ird[11:8] == 4'b1000) & (ird[5:4] == 2'b00); // Static bit to mem
- always_comb begin
- unique case( 1'b1)
- lineOnehot[0]:
- Irdecod.isByte =
- ( ird[8] & (ird[5:4] != 2'b00) ) | // Dynamic bit to mem
- ( (ird[11:8] == 4'b1000) & (ird[5:4] != 2'b00) ) | // Static bit to mem
- ( (ird[8:7] == 2'b10) & (ird[5:3] == 3'b001) ) | // Movep from mem only! For byte mux
- ( (ird[8:6] == 3'b000) & !xStaticMem ); // Immediate byte
-
- lineOnehot[1]: Irdecod.isByte = 1'b1; // MOVE.B
-
-
- lineOnehot[4]: Irdecod.isByte = (ird[7:6] == 2'b00) | Irdecod.isTas;
- lineOnehot[5]: Irdecod.isByte = (ird[7:6] == 2'b00) | xIsScc;
-
- lineOnehot[8],
- lineOnehot[9],
- lineOnehot['hb],
- lineOnehot['hc],
- lineOnehot['hd],
- lineOnehot['he]: Irdecod.isByte = (ird[7:6] == 2'b00);
-
- default: Irdecod.isByte = 1'b0;
- endcase
- end
-
- // Need it for special byte size. Bus is byte, but whole register word is modified.
- assign Irdecod.isMovep = lineOnehot[0] & ird[8] & eaAreg;
-
-
- // rxIsSP implicit use of RX for actual SP transfer
- //
- // This logic is simple and will include some instructions that don't actually reference SP.
- // But doesn't matter as long as they don't perform any RX transfer.
-
- always_comb begin
- unique case( 1'b1)
- lineOnehot[6]: Irdecod.implicitSp = (ird[11:8] == 4'b0001); // BSR
- lineOnehot[4]:
- // Misc like RTS, JSR, etc
- Irdecod.implicitSp = (ird[11:8] == 4'b1110) | (ird[11:6] == 6'b1000_01);
- default: Irdecod.implicitSp = 1'b0;
- endcase
- end
-
- // Modify CCR (and not SR)
- // Probably overkill !! Only needs to distinguish SR vs CCR
- // RTR, MOVE to CCR, xxxI to CCR
- assign Irdecod.toCcr = ( lineOnehot[4] & ((ird[11:0] == 12'he77) | (ird[11:6] == 6'b010011)) ) |
- ( lineOnehot[0] & (ird[8:6] == 3'b000));
-
- // FTU constants
- // This should not be latched on T3/T4. Latch on T2 or not at all. FTU needs it on next T3.
- // Note: Reset instruction gets constant from ALU not from FTU!
- logic [15:0] ftuConst;
- wire [3:0] zero28 = (ird[11:9] == 0) ? 4'h8 : { 1'b0, ird[11:9]}; // xltate 0,1-7 into 8,1-7
-
- always_comb begin
- unique case( 1'b1)
- lineOnehot[6], // Bcc short
- lineOnehot[7]: ftuConst = { { 8{ ird[ 7]}}, ird[ 7:0] }; // MOVEQ
-
- lineOnehot['h5], // addq/subq/static shift double check this
- lineOnehot['he]: ftuConst = { 12'b0, zero28};
-
- // MULU/MULS DIVU/DIVS
- lineOnehot['h8],
- lineOnehot['hc]: ftuConst = 16'h0f;
-
- lineOnehot[4]: ftuConst = 16'h80; // TAS
-
- default: ftuConst = '0;
- endcase
- end
- assign Irdecod.ftuConst = ftuConst;
-
- //
- // TRAP Vector # for group 2 exceptions
- //
-
- always_comb begin
- if( lineOnehot[4]) begin
- case ( ird[6:5])
- 2'b00,2'b01: Irdecod.macroTvn = 6; // CHK
- 2'b11: Irdecod.macroTvn = 7; // TRAPV
- 2'b10: Irdecod.macroTvn = {2'b10, ird[3:0]}; // TRAP
- endcase
- end
- else
- Irdecod.macroTvn = 5; // Division by zero
- end
-
-
- wire eaAdir = (ird[ 5:3] == 3'b001);
- wire size11 = ird[7] & ird[6];
-
- // Opcodes variants that don't affect flags
- // ADDA/SUBA ADDQ/SUBQ MOVEA
-
- assign Irdecod.inhibitCcr =
- ( (lineOnehot[9] | lineOnehot['hd]) & size11) | // ADDA/SUBA
- ( lineOnehot[5] & eaAdir) | // ADDQ/SUBQ to An (originally checks for line[4] as well !?)
- ( (lineOnehot[2] | lineOnehot[3]) & ird[8:6] == 3'b001); // MOVEA
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/microToNanoAddr.sv b/common/CPU/68000/FX68k/microToNanoAddr.sv
deleted file mode 100644
index 0113eb96..00000000
--- a/common/CPU/68000/FX68k/microToNanoAddr.sv
+++ /dev/null
@@ -1,157 +0,0 @@
-// Translate uaddr to nanoaddr
-module microToNanoAddr(
- input [UADDR_WIDTH-1:0] uAddr,
- output [NADDR_WIDTH-1:0] orgAddr);
-
- wire [UADDR_WIDTH-1:2] baseAddr = uAddr[UADDR_WIDTH-1:2];
- logic [NADDR_WIDTH-1:2] orgBase;
- assign orgAddr = { orgBase, uAddr[1:0]};
-
- always @( baseAddr)
- begin
- // nano ROM (136 addresses)
- case( baseAddr)
-
-'h00: orgBase = 7'h0 ;
-'h01: orgBase = 7'h1 ;
-'h02: orgBase = 7'h2 ;
-'h03: orgBase = 7'h2 ;
-'h08: orgBase = 7'h3 ;
-'h09: orgBase = 7'h4 ;
-'h0A: orgBase = 7'h5 ;
-'h0B: orgBase = 7'h5 ;
-'h10: orgBase = 7'h6 ;
-'h11: orgBase = 7'h7 ;
-'h12: orgBase = 7'h8 ;
-'h13: orgBase = 7'h8 ;
-'h18: orgBase = 7'h9 ;
-'h19: orgBase = 7'hA ;
-'h1A: orgBase = 7'hB ;
-'h1B: orgBase = 7'hB ;
-'h20: orgBase = 7'hC ;
-'h21: orgBase = 7'hD ;
-'h22: orgBase = 7'hE ;
-'h23: orgBase = 7'hD ;
-'h28: orgBase = 7'hF ;
-'h29: orgBase = 7'h10 ;
-'h2A: orgBase = 7'h11 ;
-'h2B: orgBase = 7'h10 ;
-'h30: orgBase = 7'h12 ;
-'h31: orgBase = 7'h13 ;
-'h32: orgBase = 7'h14 ;
-'h33: orgBase = 7'h14 ;
-'h38: orgBase = 7'h15 ;
-'h39: orgBase = 7'h16 ;
-'h3A: orgBase = 7'h17 ;
-'h3B: orgBase = 7'h17 ;
-'h40: orgBase = 7'h18 ;
-'h41: orgBase = 7'h18 ;
-'h42: orgBase = 7'h18 ;
-'h43: orgBase = 7'h18 ;
-'h44: orgBase = 7'h19 ;
-'h45: orgBase = 7'h19 ;
-'h46: orgBase = 7'h19 ;
-'h47: orgBase = 7'h19 ;
-'h48: orgBase = 7'h1A ;
-'h49: orgBase = 7'h1A ;
-'h4A: orgBase = 7'h1A ;
-'h4B: orgBase = 7'h1A ;
-'h4C: orgBase = 7'h1B ;
-'h4D: orgBase = 7'h1B ;
-'h4E: orgBase = 7'h1B ;
-'h4F: orgBase = 7'h1B ;
-'h54: orgBase = 7'h1C ;
-'h55: orgBase = 7'h1D ;
-'h56: orgBase = 7'h1E ;
-'h57: orgBase = 7'h1F ;
-'h5C: orgBase = 7'h20 ;
-'h5D: orgBase = 7'h21 ;
-'h5E: orgBase = 7'h22 ;
-'h5F: orgBase = 7'h23 ;
-'h70: orgBase = 7'h24 ;
-'h71: orgBase = 7'h24 ;
-'h72: orgBase = 7'h24 ;
-'h73: orgBase = 7'h24 ;
-'h74: orgBase = 7'h24 ;
-'h75: orgBase = 7'h24 ;
-'h76: orgBase = 7'h24 ;
-'h77: orgBase = 7'h24 ;
-'h78: orgBase = 7'h25 ;
-'h79: orgBase = 7'h25 ;
-'h7A: orgBase = 7'h25 ;
-'h7B: orgBase = 7'h25 ;
-'h7C: orgBase = 7'h25 ;
-'h7D: orgBase = 7'h25 ;
-'h7E: orgBase = 7'h25 ;
-'h7F: orgBase = 7'h25 ;
-'h84: orgBase = 7'h26 ;
-'h85: orgBase = 7'h27 ;
-'h86: orgBase = 7'h28 ;
-'h87: orgBase = 7'h29 ;
-'h8C: orgBase = 7'h2A ;
-'h8D: orgBase = 7'h2B ;
-'h8E: orgBase = 7'h2C ;
-'h8F: orgBase = 7'h2D ;
-'h94: orgBase = 7'h2E ;
-'h95: orgBase = 7'h2F ;
-'h96: orgBase = 7'h30 ;
-'h97: orgBase = 7'h31 ;
-'h9C: orgBase = 7'h32 ;
-'h9D: orgBase = 7'h33 ;
-'h9E: orgBase = 7'h34 ;
-'h9F: orgBase = 7'h35 ;
-'hA4: orgBase = 7'h36 ;
-'hA5: orgBase = 7'h36 ;
-'hA6: orgBase = 7'h37 ;
-'hA7: orgBase = 7'h37 ;
-'hAC: orgBase = 7'h38 ;
-'hAD: orgBase = 7'h38 ;
-'hAE: orgBase = 7'h39 ;
-'hAF: orgBase = 7'h39 ;
-'hB4: orgBase = 7'h3A ;
-'hB5: orgBase = 7'h3A ;
-'hB6: orgBase = 7'h3B ;
-'hB7: orgBase = 7'h3B ;
-'hBC: orgBase = 7'h3C ;
-'hBD: orgBase = 7'h3C ;
-'hBE: orgBase = 7'h3D ;
-'hBF: orgBase = 7'h3D ;
-'hC0: orgBase = 7'h3E ;
-'hC1: orgBase = 7'h3F ;
-'hC2: orgBase = 7'h40 ;
-'hC3: orgBase = 7'h41 ;
-'hC8: orgBase = 7'h42 ;
-'hC9: orgBase = 7'h43 ;
-'hCA: orgBase = 7'h44 ;
-'hCB: orgBase = 7'h45 ;
-'hD0: orgBase = 7'h46 ;
-'hD1: orgBase = 7'h47 ;
-'hD2: orgBase = 7'h48 ;
-'hD3: orgBase = 7'h49 ;
-'hD8: orgBase = 7'h4A ;
-'hD9: orgBase = 7'h4B ;
-'hDA: orgBase = 7'h4C ;
-'hDB: orgBase = 7'h4D ;
-'hE0: orgBase = 7'h4E ;
-'hE1: orgBase = 7'h4E ;
-'hE2: orgBase = 7'h4F ;
-'hE3: orgBase = 7'h4F ;
-'hE8: orgBase = 7'h50 ;
-'hE9: orgBase = 7'h50 ;
-'hEA: orgBase = 7'h51 ;
-'hEB: orgBase = 7'h51 ;
-'hF0: orgBase = 7'h52 ;
-'hF1: orgBase = 7'h52 ;
-'hF2: orgBase = 7'h52 ;
-'hF3: orgBase = 7'h52 ;
-'hF8: orgBase = 7'h53 ;
-'hF9: orgBase = 7'h53 ;
-'hFA: orgBase = 7'h53 ;
-'hFB: orgBase = 7'h53 ;
-
- default:
- orgBase = 'X;
- endcase
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/nDecoder3.sv b/common/CPU/68000/FX68k/nDecoder3.sv
deleted file mode 100644
index 8b6f9759..00000000
--- a/common/CPU/68000/FX68k/nDecoder3.sv
+++ /dev/null
@@ -1,274 +0,0 @@
-// Nanorom (plus) decoder for die nanocode
-module nDecoder3( input s_clks Clks, input s_irdecod Irdecod, output s_nanod Nanod,
- input enT2, enT4,
- input [UROM_WIDTH-1:0] microLatch,
- input [NANO_WIDTH-1:0] nanoLatch);
-
-localparam NANO_IR2IRD = 67;
-localparam NANO_TOIRC = 66;
-localparam NANO_ALU_COL = 63; // ALU operator column order is 63-64-65 !
-localparam NANO_ALU_FI = 61; // ALU finish-init 62-61
-localparam NANO_TODBIN = 60;
-localparam NANO_ALUE = 57; // 57-59 shared with DCR control
-localparam NANO_DCR = 57; // 57-59 shared with ALUE control
-localparam NANO_DOBCTRL_1 = 56; // Input to control and permwrite
-localparam NANO_LOWBYTE = 55; // Used by MOVEP
-localparam NANO_HIGHBYTE = 54;
-localparam NANO_DOBCTRL_0 = 53; // Input to control and permwrite
-localparam NANO_ALU_DCTRL = 51; // 52-51 databus input mux control
-localparam NANO_ALU_ACTRL = 50; // addrbus input mux control
-localparam NANO_DBD2ALUB = 49;
-localparam NANO_ABD2ALUB = 48;
-localparam NANO_DBIN2DBD = 47;
-localparam NANO_DBIN2ABD = 46;
-localparam NANO_ALU2ABD = 45;
-localparam NANO_ALU2DBD = 44;
-localparam NANO_RZ = 43;
-localparam NANO_BUSBYTE = 42; // If *both* this set and instruction is byte sized, then bus cycle is byte sized.
-localparam NANO_PCLABL = 41;
-localparam NANO_RXL_DBL = 40; // Switches RXL/RYL on DBL/ABL buses
-localparam NANO_PCLDBL = 39;
-localparam NANO_ABDHRECHARGE = 38;
-localparam NANO_REG2ABL = 37; // register to ABL
-localparam NANO_ABL2REG = 36; // ABL to register
-localparam NANO_ABLABD = 35;
-localparam NANO_DBLDBD = 34;
-localparam NANO_DBL2REG = 33; // DBL to register
-localparam NANO_REG2DBL = 32; // register to DBL
-localparam NANO_ATLCTRL = 29; // 31-29
-localparam NANO_FTUCONTROL = 25;
-localparam NANO_SSP = 24;
-localparam NANO_RXH_DBH = 22; // Switches RXH/RYH on DBH/ABH buses
-localparam NANO_AUOUT = 20; // 21-20
-localparam NANO_AUCLKEN = 19;
-localparam NANO_AUCTRL = 16; // 18-16
-localparam NANO_DBLDBH = 15;
-localparam NANO_ABLABH = 14;
-localparam NANO_EXT_ABH = 13;
-localparam NANO_EXT_DBH = 12;
-localparam NANO_ATHCTRL = 9; // 11-9
-localparam NANO_REG2ABH = 8; // register to ABH
-localparam NANO_ABH2REG = 7; // ABH to register
-localparam NANO_REG2DBH = 6; // register to DBH
-localparam NANO_DBH2REG = 5; // DBH to register
-localparam NANO_AOBCTRL = 3; // 4-3
-localparam NANO_PCH = 0; // 1-0 PchDbh PchAbh
-localparam NANO_NO_SP_ALGN = 0; // Same bits as above when both set
-
-localparam NANO_FTU_UPDTPEND = 1; // Also loads FTU constant according to IRD !
-localparam NANO_FTU_INIT_ST = 15; // Set S, clear T (but not TPEND)
-localparam NANO_FTU_CLRTPEND = 14;
-localparam NANO_FTU_TVN = 13;
-localparam NANO_FTU_ABL2PREN = 12; // ABL => FTU & ABL => PREN. Both transfers enabled, but only one will be used depending on uroutine.
-localparam NANO_FTU_SSW = 11;
-localparam NANO_FTU_RSTPREN = 10;
-localparam NANO_FTU_IRD = 9;
-localparam NANO_FTU_2ABL = 8;
-localparam NANO_FTU_RDSR = 7;
-localparam NANO_FTU_INL = 6;
-localparam NANO_FTU_PSWI = 5; // Read Int Mask into FTU
-localparam NANO_FTU_DBL = 4;
-localparam NANO_FTU_2SR = 2;
-localparam NANO_FTU_CONST = 1;
-
- reg [3:0] ftuCtrl;
-
- logic [2:0] athCtrl, atlCtrl;
- assign athCtrl = nanoLatch[ NANO_ATHCTRL+2: NANO_ATHCTRL];
- assign atlCtrl = nanoLatch[ NANO_ATLCTRL+2: NANO_ATLCTRL];
- wire [1:0] aobCtrl = nanoLatch[ NANO_AOBCTRL+1:NANO_AOBCTRL];
- wire [1:0] dobCtrl = {nanoLatch[ NANO_DOBCTRL_1], nanoLatch[NANO_DOBCTRL_0]};
-
- always_ff @( posedge Clks.clk) begin
- if( enT4) begin
- // Reverse order!
- ftuCtrl <= { nanoLatch[ NANO_FTUCONTROL+0], nanoLatch[ NANO_FTUCONTROL+1], nanoLatch[ NANO_FTUCONTROL+2], nanoLatch[ NANO_FTUCONTROL+3]} ;
-
- Nanod.auClkEn <= !nanoLatch[ NANO_AUCLKEN];
- Nanod.auCntrl <= nanoLatch[ NANO_AUCTRL+2 : NANO_AUCTRL+0];
- Nanod.noSpAlign <= (nanoLatch[ NANO_NO_SP_ALGN + 1:NANO_NO_SP_ALGN] == 2'b11);
- Nanod.extDbh <= nanoLatch[ NANO_EXT_DBH];
- Nanod.extAbh <= nanoLatch[ NANO_EXT_ABH];
- Nanod.todbin <= nanoLatch[ NANO_TODBIN];
- Nanod.toIrc <= nanoLatch[ NANO_TOIRC];
-
- // ablAbd is disabled on byte transfers (adbhCharge plus irdIsByte). Not sure the combination makes much sense.
- // It happens in a few cases but I don't see anything enabled on abL (or abH) section anyway.
-
- Nanod.ablAbd <= nanoLatch[ NANO_ABLABD];
- Nanod.ablAbh <= nanoLatch[ NANO_ABLABH];
- Nanod.dblDbd <= nanoLatch[ NANO_DBLDBD];
- Nanod.dblDbh <= nanoLatch[ NANO_DBLDBH];
-
- Nanod.dbl2Atl <= (atlCtrl == 3'b010);
- Nanod.atl2Dbl <= (atlCtrl == 3'b011);
- Nanod.abl2Atl <= (atlCtrl == 3'b100);
- Nanod.atl2Abl <= (atlCtrl == 3'b101);
-
- Nanod.aob2Ab <= (athCtrl == 3'b101); // Used on BSER1 only
-
- Nanod.abh2Ath <= (athCtrl == 3'b001) | (athCtrl == 3'b101);
- Nanod.dbh2Ath <= (athCtrl == 3'b100);
- Nanod.ath2Dbh <= (athCtrl == 3'b110);
- Nanod.ath2Abh <= (athCtrl == 3'b011);
-
- Nanod.alu2Dbd <= nanoLatch[ NANO_ALU2DBD];
- Nanod.alu2Abd <= nanoLatch[ NANO_ALU2ABD];
-
- Nanod.abd2Dcr <= (nanoLatch[ NANO_DCR+1:NANO_DCR] == 2'b11);
- Nanod.dcr2Dbd <= (nanoLatch[ NANO_DCR+2:NANO_DCR+1] == 2'b11);
- Nanod.dbd2Alue <= (nanoLatch[ NANO_ALUE+2:NANO_ALUE+1] == 2'b10);
- Nanod.alue2Dbd <= (nanoLatch[ NANO_ALUE+1:NANO_ALUE] == 2'b01);
-
- Nanod.dbd2Alub <= nanoLatch[ NANO_DBD2ALUB];
- Nanod.abd2Alub <= nanoLatch[ NANO_ABD2ALUB];
-
- // Originally not latched. We better should because we transfer one cycle later, T3 instead of T1.
- Nanod.dobCtrl <= dobCtrl;
- // Nanod.adb2Dob <= (dobCtrl == 2'b10); Nanod.dbd2Dob <= (dobCtrl == 2'b01); Nanod.alu2Dob <= (dobCtrl == 2'b11);
-
- end
- end
-
- // Update SSW at the start of Bus/Addr error ucode
- assign Nanod.updSsw = Nanod.aob2Ab;
-
- assign Nanod.updTpend = (ftuCtrl == NANO_FTU_UPDTPEND);
- assign Nanod.clrTpend = (ftuCtrl == NANO_FTU_CLRTPEND);
- assign Nanod.tvn2Ftu = (ftuCtrl == NANO_FTU_TVN);
- assign Nanod.const2Ftu = (ftuCtrl == NANO_FTU_CONST);
- assign Nanod.ftu2Dbl = (ftuCtrl == NANO_FTU_DBL) | ( ftuCtrl == NANO_FTU_INL);
- assign Nanod.ftu2Abl = (ftuCtrl == NANO_FTU_2ABL);
- assign Nanod.inl2psw = (ftuCtrl == NANO_FTU_INL);
- assign Nanod.pswIToFtu = (ftuCtrl == NANO_FTU_PSWI);
- assign Nanod.ftu2Sr = (ftuCtrl == NANO_FTU_2SR);
- assign Nanod.sr2Ftu = (ftuCtrl == NANO_FTU_RDSR);
- assign Nanod.ird2Ftu = (ftuCtrl == NANO_FTU_IRD); // Used on bus/addr error
- assign Nanod.ssw2Ftu = (ftuCtrl == NANO_FTU_SSW);
- assign Nanod.initST = (ftuCtrl == NANO_FTU_INL) | (ftuCtrl == NANO_FTU_CLRTPEND) | (ftuCtrl == NANO_FTU_INIT_ST);
- assign Nanod.abl2Pren = (ftuCtrl == NANO_FTU_ABL2PREN);
- assign Nanod.updPren = (ftuCtrl == NANO_FTU_RSTPREN);
-
- assign Nanod.Ir2Ird = nanoLatch[ NANO_IR2IRD];
-
- // ALU control better latched later after combining with IRD decoding
-
- assign Nanod.aluDctrl = nanoLatch[ NANO_ALU_DCTRL+1 : NANO_ALU_DCTRL];
- assign Nanod.aluActrl = nanoLatch[ NANO_ALU_ACTRL];
- assign Nanod.aluColumn = { nanoLatch[ NANO_ALU_COL], nanoLatch[ NANO_ALU_COL+1], nanoLatch[ NANO_ALU_COL+2]};
- wire [1:0] aluFinInit = nanoLatch[ NANO_ALU_FI+1:NANO_ALU_FI];
- assign Nanod.aluFinish = (aluFinInit == 2'b10);
- assign Nanod.aluInit = (aluFinInit == 2'b01);
-
- // FTU 2 CCR encoded as both ALU Init and ALU Finish set.
- // In theory this encoding allows writes to CCR without writing to SR
- // But FTU 2 CCR and to SR are both set together at nanorom.
- assign Nanod.ftu2Ccr = ( aluFinInit == 2'b11);
-
- assign Nanod.abdIsByte = nanoLatch[ NANO_ABDHRECHARGE];
-
- // Not being latched on T4 creates non unique case warning!
- assign Nanod.au2Db = (nanoLatch[ NANO_AUOUT + 1: NANO_AUOUT] == 2'b01);
- assign Nanod.au2Ab = (nanoLatch[ NANO_AUOUT + 1: NANO_AUOUT] == 2'b10);
- assign Nanod.au2Pc = (nanoLatch[ NANO_AUOUT + 1: NANO_AUOUT] == 2'b11);
-
- assign Nanod.db2Aob = (aobCtrl == 2'b10);
- assign Nanod.ab2Aob = (aobCtrl == 2'b01);
- assign Nanod.au2Aob = (aobCtrl == 2'b11);
-
- assign Nanod.dbin2Abd = nanoLatch[ NANO_DBIN2ABD];
- assign Nanod.dbin2Dbd = nanoLatch[ NANO_DBIN2DBD];
-
- assign Nanod.permStart = (| aobCtrl);
- assign Nanod.isWrite = ( | dobCtrl);
- assign Nanod.waitBusFinish = nanoLatch[ NANO_TOIRC] | nanoLatch[ NANO_TODBIN] | Nanod.isWrite;
- assign Nanod.busByte = nanoLatch[ NANO_BUSBYTE];
-
- assign Nanod.noLowByte = nanoLatch[ NANO_LOWBYTE];
- assign Nanod.noHighByte = nanoLatch[ NANO_HIGHBYTE];
-
- // Not registered. Register at T4 after combining
- // Might be better to remove all those and combine here instead of at execution unit !!
- assign Nanod.abl2reg = nanoLatch[ NANO_ABL2REG];
- assign Nanod.abh2reg = nanoLatch[ NANO_ABH2REG];
- assign Nanod.dbl2reg = nanoLatch[ NANO_DBL2REG];
- assign Nanod.dbh2reg = nanoLatch[ NANO_DBH2REG];
- assign Nanod.reg2dbl = nanoLatch[ NANO_REG2DBL];
- assign Nanod.reg2dbh = nanoLatch[ NANO_REG2DBH];
- assign Nanod.reg2abl = nanoLatch[ NANO_REG2ABL];
- assign Nanod.reg2abh = nanoLatch[ NANO_REG2ABH];
-
- assign Nanod.ssp = nanoLatch[ NANO_SSP];
-
- assign Nanod.rz = nanoLatch[ NANO_RZ];
-
- // Actually DTL can't happen on PC relative mode. See IR decoder.
-
- wire dtldbd = 1'b0;
- wire dthdbh = 1'b0;
- wire dtlabd = 1'b0;
- wire dthabh = 1'b0;
-
- wire dblSpecial = Nanod.pcldbl | dtldbd;
- wire dbhSpecial = Nanod.pchdbh | dthdbh;
- wire ablSpecial = Nanod.pclabl | dtlabd;
- wire abhSpecial = Nanod.pchabh | dthabh;
-
- //
- // Combine with IRD decoding
- // Careful that IRD is updated only on T1! All output depending on IRD must be latched on T4!
- //
-
- // PC used instead of RY on PC relative instuctions
-
- assign Nanod.rxlDbl = nanoLatch[ NANO_RXL_DBL];
- wire isPcRel = Irdecod.isPcRel & !Nanod.rz;
- wire pcRelDbl = isPcRel & !nanoLatch[ NANO_RXL_DBL];
- wire pcRelDbh = isPcRel & !nanoLatch[ NANO_RXH_DBH];
- wire pcRelAbl = isPcRel & nanoLatch[ NANO_RXL_DBL];
- wire pcRelAbh = isPcRel & nanoLatch[ NANO_RXH_DBH];
-
- assign Nanod.pcldbl = nanoLatch[ NANO_PCLDBL] | pcRelDbl;
- assign Nanod.pchdbh = (nanoLatch[ NANO_PCH+1:NANO_PCH] == 2'b01) | pcRelDbh;
-
- assign Nanod.pclabl = nanoLatch[ NANO_PCLABL] | pcRelAbl;
- assign Nanod.pchabh = (nanoLatch[ NANO_PCH+1:NANO_PCH] == 2'b10) | pcRelAbh;
-
- // Might be better not to register these signals to allow latching RX/RY mux earlier!
- // But then must latch Irdecod.isPcRel on T3!
-
- always_ff @( posedge Clks.clk) begin
- if( enT4) begin
- Nanod.rxl2db <= Nanod.reg2dbl & !dblSpecial & nanoLatch[ NANO_RXL_DBL];
- Nanod.rxl2ab <= Nanod.reg2abl & !ablSpecial & !nanoLatch[ NANO_RXL_DBL];
-
- Nanod.dbl2rxl <= Nanod.dbl2reg & !dblSpecial & nanoLatch[ NANO_RXL_DBL];
- Nanod.abl2rxl <= Nanod.abl2reg & !ablSpecial & !nanoLatch[ NANO_RXL_DBL];
-
- Nanod.rxh2dbh <= Nanod.reg2dbh & !dbhSpecial & nanoLatch[ NANO_RXH_DBH];
- Nanod.rxh2abh <= Nanod.reg2abh & !abhSpecial & !nanoLatch[ NANO_RXH_DBH];
-
- Nanod.dbh2rxh <= Nanod.dbh2reg & !dbhSpecial & nanoLatch[ NANO_RXH_DBH];
- Nanod.abh2rxh <= Nanod.abh2reg & !abhSpecial & !nanoLatch[ NANO_RXH_DBH];
-
- Nanod.dbh2ryh <= Nanod.dbh2reg & !dbhSpecial & !nanoLatch[ NANO_RXH_DBH];
- Nanod.abh2ryh <= Nanod.abh2reg & !abhSpecial & nanoLatch[ NANO_RXH_DBH];
-
- Nanod.dbl2ryl <= Nanod.dbl2reg & !dblSpecial & !nanoLatch[ NANO_RXL_DBL];
- Nanod.abl2ryl <= Nanod.abl2reg & !ablSpecial & nanoLatch[ NANO_RXL_DBL];
-
- Nanod.ryl2db <= Nanod.reg2dbl & !dblSpecial & !nanoLatch[ NANO_RXL_DBL];
- Nanod.ryl2ab <= Nanod.reg2abl & !ablSpecial & nanoLatch[ NANO_RXL_DBL];
-
- Nanod.ryh2dbh <= Nanod.reg2dbh & !dbhSpecial & !nanoLatch[ NANO_RXH_DBH];
- Nanod.ryh2abh <= Nanod.reg2abh & !abhSpecial & nanoLatch[ NANO_RXH_DBH];
- end
-
- // Originally isTas only delayed on T2 (and seems only a late mask rev fix)
- // Better latch the combination on T4
- if( enT4)
- Nanod.isRmc <= Irdecod.isTas & nanoLatch[ NANO_BUSBYTE];
- end
-
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/onehotEncoder4.sv b/common/CPU/68000/FX68k/onehotEncoder4.sv
deleted file mode 100644
index c7771b41..00000000
--- a/common/CPU/68000/FX68k/onehotEncoder4.sv
+++ /dev/null
@@ -1,23 +0,0 @@
-// bin to one-hot, 4 bits to 16-bit bitmap
-module onehotEncoder4( input [3:0] bin, output reg [15:0] bitMap);
- always_comb begin
- case( bin)
- 'b0000: bitMap = 16'h0001;
- 'b0001: bitMap = 16'h0002;
- 'b0010: bitMap = 16'h0004;
- 'b0011: bitMap = 16'h0008;
- 'b0100: bitMap = 16'h0010;
- 'b0101: bitMap = 16'h0020;
- 'b0110: bitMap = 16'h0040;
- 'b0111: bitMap = 16'h0080;
- 'b1000: bitMap = 16'h0100;
- 'b1001: bitMap = 16'h0200;
- 'b1010: bitMap = 16'h0400;
- 'b1011: bitMap = 16'h0800;
- 'b1100: bitMap = 16'h1000;
- 'b1101: bitMap = 16'h2000;
- 'b1110: bitMap = 16'h4000;
- 'b1111: bitMap = 16'h8000;
- endcase
- end
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/pren.sv b/common/CPU/68000/FX68k/pren.sv
deleted file mode 100644
index ff46c068..00000000
--- a/common/CPU/68000/FX68k/pren.sv
+++ /dev/null
@@ -1,25 +0,0 @@
-// priority encoder
-// used by MOVEM regmask
-// this might benefit from device specific features
-// MOVEM doesn't need speed, will read the result 2 CPU cycles after each update.
-module pren( mask, hbit);
- parameter size = 16;
- parameter outbits = 4;
-
- input [size-1:0] mask;
- output reg [outbits-1:0] hbit;
- // output reg idle;
-
- always @( mask) begin
- integer i;
- hbit = 0;
- // idle = 1;
- for( i = size-1; i >= 0; i = i - 1) begin
- if( mask[ i]) begin
- hbit = i;
- // idle = 0;
- end
- end
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/rowDecoder.sv b/common/CPU/68000/FX68k/rowDecoder.sv
deleted file mode 100644
index 8fa9c038..00000000
--- a/common/CPU/68000/FX68k/rowDecoder.sv
+++ /dev/null
@@ -1,139 +0,0 @@
-// Decodes IRD into ALU row (1-15)
-// Slow, but no need to optimize for speed since IRD is latched at least two CPU cycles before it is used
-// We also register the result after combining with column from nanocode
-//
-// Many opcodes are not decoded because they either don't do any ALU op,
-// or use only columns 1 and 5 that are the same for all rows.
-
-module rowDecoder( input [15:0] ird,
- output logic [15:0] row, output noCcrEn, output logic isArX);
-
-
- // Addr or data register direct
- wire eaRdir = (ird[ 5:4] == 2'b00);
- // Addr register direct
- wire eaAdir = (ird[ 5:3] == 3'b001);
- wire size11 = ird[7] & ird[6];
-
- always_comb begin
- case( ird[15:12])
- 'h4,
- 'h9,
- 'hd:
- isArX = row[10] | row[12];
- default:
- isArX = 1'b0;
- endcase
- end
-
- always_comb begin
- unique case( ird[15:12])
-
- 'h4: begin
- if( ird[8])
- row = `ALU_ROW_06; // chk (or lea)
- else case( ird[11:9])
- 'b000: row = `ALU_ROW_10; // negx
- 'b001: row = `ALU_ROW_04; // clr
- 'b010: row = `ALU_ROW_05; // neg
- 'b011: row = `ALU_ROW_11; // not
- 'b100: row = (ird[7]) ? `ALU_ROW_08 : `ALU_ROW_09; // nbcd/swap/ext(or pea)
- 'b101: row = `ALU_ROW_15; // tst & tas
- default: row = 0;
- endcase
- end
-
- 'h0: begin
- if( ird[8]) // dynamic bit
- row = ird[7] ? `ALU_ROW_14 : `ALU_ROW_13;
- else case( ird[ 11:9])
- 'b000: row = `ALU_ROW_14; // ori
- 'b001: row = `ALU_ROW_04; // andi
- 'b010: row = `ALU_ROW_05; // subi
- 'b011: row = `ALU_ROW_02; // addi
- 'b100: row = ird[7] ? `ALU_ROW_14 : `ALU_ROW_13; // static bit
- 'b101: row = `ALU_ROW_13; // eori
- 'b110: row = `ALU_ROW_06; // cmpi
- default: row = 0;
- endcase
- end
-
- // MOVE
- // move.b originally also rows 5 & 15. Only because IRD bit 14 is not decoded.
- // It's the same for move the operations performed by MOVE.B
-
- 'h1,'h2,'h3: row = `ALU_ROW_02;
-
- 'h5:
- if( size11)
- row = `ALU_ROW_15; // As originally and easier to decode
- else
- row = ird[8] ? `ALU_ROW_05 : `ALU_ROW_02; // addq/subq
- 'h6: row = 0; //bcc/bra/bsr
- 'h7: row = `ALU_ROW_02; // moveq
- 'h8:
- if( size11) // div
- row = `ALU_ROW_01;
- else if( ird[8] & eaRdir) // sbcd
- row = `ALU_ROW_09;
- else
- row = `ALU_ROW_14; // or
- 'h9:
- if( ird[8] & ~size11 & eaRdir)
- row = `ALU_ROW_10; // subx
- else
- row = `ALU_ROW_05; // sub/suba
- 'hb:
- if( ird[8] & ~size11 & ~eaAdir)
- row = `ALU_ROW_13; // eor
- else
- row = `ALU_ROW_06; // cmp/cmpa/cmpm
- 'hc:
- if( size11)
- row = `ALU_ROW_07; // mul
- else if( ird[8] & eaRdir) // abcd
- row = `ALU_ROW_03;
- else
- row = `ALU_ROW_04; // and
- 'hd:
- if( ird[8] & ~size11 & eaRdir)
- row = `ALU_ROW_12; // addx
- else
- row = `ALU_ROW_02; // add/adda
- 'he:
- begin
- reg [1:0] stype;
-
- if( size11) // memory shift/rotate
- stype = ird[ 10:9];
- else // register shift/rotate
- stype = ird[ 4:3];
-
- case( {stype, ird[8]})
- 0: row = `ALU_ROW_02; // ASR
- 1: row = `ALU_ROW_03; // ASL
- 2: row = `ALU_ROW_05; // LSR
- 3: row = `ALU_ROW_04; // LSL
- 4: row = `ALU_ROW_08; // ROXR
- 5: row = `ALU_ROW_11; // ROXL
- 6: row = `ALU_ROW_10; // ROR
- 7: row = `ALU_ROW_09; // ROL
- endcase
- end
-
- default: row = 0;
- endcase
- end
-
- // Decode opcodes that don't affect flags
- // ADDA/SUBA ADDQ/SUBQ MOVEA
-
- assign noCcrEn =
- // ADDA/SUBA
- ( ird[15] & ~ird[13] & ird[12] & size11) |
- // ADDQ/SUBQ to An
- ( (ird[15:12] == 4'h5) & eaAdir) |
- // MOVEA
- ( (~ird[15] & ~ird[14] & ird[13]) & ird[8:6] == 3'b001);
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/sequencer.sv b/common/CPU/68000/FX68k/sequencer.sv
deleted file mode 100644
index dade6edc..00000000
--- a/common/CPU/68000/FX68k/sequencer.sv
+++ /dev/null
@@ -1,237 +0,0 @@
-// Microcode sequencer
-
-module sequencer( input s_clks Clks, input enT3,
- input [UROM_WIDTH-1:0] microLatch,
- input A0Err, BerrA, busAddrErr, Spuria, Avia,
- input Tpend, intPend, isIllegal, isPriv, excRst, isLineA, isLineF,
- input [15:0] psw,
- input prenEmpty, au05z, dcr4, ze, i11,
- input [1:0] alue01,
- input [15:0] Ird,
- input [UADDR_WIDTH-1:0] a1, a2, a3,
- output logic [3:0] tvn,
- output logic [UADDR_WIDTH-1:0] nma);
-
- logic [UADDR_WIDTH-1:0] uNma;
- logic [UADDR_WIDTH-1:0] grp1Nma;
- logic [1:0] c0c1;
- reg a0Rst;
- wire A0Sel;
- wire inGrp0Exc;
-
- // assign nma = Clks.extReset ? RSTP0_NMA : (A0Err ? BSER1_NMA : uNma);
- // assign nma = A0Err ? (a0Rst ? RSTP0_NMA : BSER1_NMA) : uNma;
-
- // word type I: 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
- // NMA : .. .. 09 08 01 00 05 04 03 02 07 06 .. .. .. .. ..
-
- wire [UADDR_WIDTH-1:0] dbNma = { microLatch[ 14:13], microLatch[ 6:5], microLatch[ 10:7], microLatch[ 12:11]};
-
- // Group 0 exception.
- // Separated block from regular NMA. Otherwise simulation might depend on order of assigments.
- always_comb begin
- if( A0Err) begin
- if( a0Rst) // Reset
- nma = RSTP0_NMA;
- else if( inGrp0Exc) // Double fault
- nma = HALT1_NMA;
- else // Bus or address error
- nma = BSER1_NMA;
- end
- else
- nma = uNma;
- end
-
- always_comb begin
- // Format II (conditional) or I (direct branch)
- if( microLatch[1])
- uNma = { microLatch[ 14:13], c0c1, microLatch[ 10:7], microLatch[ 12:11]};
- else
- case( microLatch[ 3:2])
- 0: uNma = dbNma; // DB
- 1: uNma = A0Sel ? grp1Nma : a1;
- 2: uNma = a2;
- 3: uNma = a3;
- endcase
- end
-
- // Format II, conditional, NMA decoding
- wire [1:0] enl = { Ird[6], prenEmpty}; // Updated on T3
-
- wire [1:0] ms0 = { Ird[8], alue01[0]};
- wire [3:0] m01 = { au05z, Ird[8], alue01};
- wire [1:0] nz1 = { psw[ NF], psw[ ZF]};
- wire [1:0] nv = { psw[ NF], psw[ VF]};
-
- logic ccTest;
- wire [4:0] cbc = microLatch[ 6:2]; // CBC bits
-
- always_comb begin
- unique case( cbc)
- 'h0: c0c1 = {i11, i11}; // W/L offset EA, from IRC
-
- 'h1: c0c1 = (au05z) ? 2'b01 : 2'b11; // Updated on T3
- 'h11: c0c1 = (au05z) ? 2'b00 : 2'b11;
-
- 'h02: c0c1 = { 1'b0, ~psw[ CF]}; // C used in DIV
- 'h12: c0c1 = { 1'b1, ~psw[ CF]};
-
- 'h03: c0c1 = {psw[ ZF], psw[ ZF]}; // Z used in DIVU
-
- 'h04: // nz1, used in DIVS
- case( nz1)
- 'b00: c0c1 = 2'b10;
- 'b10: c0c1 = 2'b01;
- 'b01,'b11: c0c1 = 2'b11;
- endcase
-
- 'h05: c0c1 = {psw[ NF], 1'b1}; // N used in CHK and DIV
- 'h15: c0c1 = {1'b1, psw[ NF]};
-
- // nz2, used in DIVS (same combination as nz1)
- 'h06: c0c1 = { ~nz1[1] & ~nz1[0], 1'b1};
-
- 'h07: // ms0 used in MUL
- case( ms0)
- 'b10, 'b00: c0c1 = 2'b11;
- 'b01: c0c1 = 2'b01;
- 'b11: c0c1 = 2'b10;
- endcase
-
- 'h08: // m01 used in MUL
- case( m01)
- 'b0000,'b0001,'b0100,'b0111: c0c1 = 2'b11;
- 'b0010,'b0011,'b0101: c0c1 = 2'b01;
- 'b0110: c0c1 = 2'b10;
- default: c0c1 = 2'b00;
- endcase
-
- // Conditional
- 'h09: c0c1 = (ccTest) ? 2'b11 : 2'b01;
- 'h19: c0c1 = (ccTest) ? 2'b11 : 2'b10;
-
- // DCR bit 4 (high or low word)
- 'h0c: c0c1 = dcr4 ? 2'b01: 2'b11;
- 'h1c: c0c1 = dcr4 ? 2'b10: 2'b11;
-
- // DBcc done
- 'h0a: c0c1 = ze ? 2'b11 : 2'b00;
-
- // nv, used in CHK
- 'h0b: c0c1 = (nv == 2'b00) ? 2'b00 : 2'b11;
-
- // V, used in trapv
- 'h0d: c0c1 = { ~psw[ VF], ~psw[VF]};
-
- // enl, combination of pren idle and word/long on IRD
- 'h0e,'h1e:
- case( enl)
- 2'b00: c0c1 = 'b10;
- 2'b10: c0c1 = 'b11;
- // 'hx1 result 00/01 depending on condition 0e/1e
- 2'b01,2'b11:
- c0c1 = { 1'b0, microLatch[ 6]};
- endcase
-
- default: c0c1 = 'X;
- endcase
- end
-
- // CCR conditional
- always_comb begin
- unique case( Ird[ 11:8])
- 'h0: ccTest = 1'b1; // T
- 'h1: ccTest = 1'b0; // F
- 'h2: ccTest = ~psw[ CF] & ~psw[ ZF]; // HI
- 'h3: ccTest = psw[ CF] | psw[ZF]; // LS
- 'h4: ccTest = ~psw[ CF]; // CC (HS)
- 'h5: ccTest = psw[ CF]; // CS (LO)
- 'h6: ccTest = ~psw[ ZF]; // NE
- 'h7: ccTest = psw[ ZF]; // EQ
- 'h8: ccTest = ~psw[ VF]; // VC
- 'h9: ccTest = psw[ VF]; // VS
- 'ha: ccTest = ~psw[ NF]; // PL
- 'hb: ccTest = psw[ NF]; // MI
- 'hc: ccTest = (psw[ NF] & psw[ VF]) | (~psw[ NF] & ~psw[ VF]); // GE
- 'hd: ccTest = (psw[ NF] & ~psw[ VF]) | (~psw[ NF] & psw[ VF]); // LT
- 'he: ccTest = (psw[ NF] & psw[ VF] & ~psw[ ZF]) |
- (~psw[ NF] & ~psw[ VF] & ~psw[ ZF]); // GT
- 'hf: ccTest = psw[ ZF] | (psw[ NF] & ~psw[VF]) | (~psw[ NF] & psw[VF]); // LE
- endcase
- end
-
- // Exception logic
- logic rTrace, rInterrupt;
- logic rIllegal, rPriv, rLineA, rLineF;
- logic rExcRst, rExcAdrErr, rExcBusErr;
- logic rSpurious, rAutovec;
- wire grp1LatchEn, grp0LatchEn;
-
- // Originally control signals latched on T4. Then exception latches updated on T3
- assign grp1LatchEn = microLatch[0] & (microLatch[1] | !microLatch[4]);
- assign grp0LatchEn = microLatch[4] & !microLatch[1];
-
- assign inGrp0Exc = rExcRst | rExcBusErr | rExcAdrErr;
-
- always_ff @( posedge Clks.clk) begin
- if( grp0LatchEn & enT3) begin
- rExcRst <= excRst;
- rExcBusErr <= BerrA;
- rExcAdrErr <= busAddrErr;
- rSpurious <= Spuria;
- rAutovec <= Avia;
- end
-
- // Update group 1 exception latches
- // Inputs from IR decoder updated on T1 as soon as IR loaded
- // Trace pending updated on T3 at the start of the instruction
- // Interrupt pending on T2
- if( grp1LatchEn & enT3) begin
- rTrace <= Tpend;
- rInterrupt <= intPend;
- rIllegal <= isIllegal & ~isLineA & ~isLineF;
- rLineA <= isLineA;
- rLineF <= isLineF;
- rPriv <= isPriv & !psw[ SF];
- end
- end
-
- // exception priority
- always_comb begin
- grp1Nma = TRAC1_NMA;
- if( rExcRst)
- tvn = '0; // Might need to change that to signal in exception
- else if( rExcBusErr | rExcAdrErr)
- tvn = { 1'b1, rExcAdrErr};
-
- // Seudo group 0 exceptions. Just for updating TVN
- else if( rSpurious | rAutovec)
- tvn = rSpurious ? TVN_SPURIOUS : TVN_AUTOVEC;
-
- else if( rTrace)
- tvn = 9;
- else if( rInterrupt) begin
- tvn = TVN_INTERRUPT;
- grp1Nma = ITLX1_NMA;
- end
- else begin
- unique case( 1'b1) // Can't happen more than one of these
- rIllegal: tvn = 4;
- rPriv: tvn = 8;
- rLineA: tvn = 10;
- rLineF: tvn = 11;
- default: tvn = 1; // Signal no group 0/1 exception
- endcase
- end
- end
-
- assign A0Sel = rIllegal | rLineF | rLineA | rPriv | rTrace | rInterrupt;
-
- always_ff @( posedge Clks.clk) begin
- if( Clks.extReset)
- a0Rst <= 1'b1;
- else if( enT3)
- a0Rst <= 1'b0;
- end
-
-endmodule
\ No newline at end of file
diff --git a/common/CPU/68000/FX68k/uaddrDecode.sv b/common/CPU/68000/FX68k/uaddrDecode.sv
deleted file mode 100644
index 3efdc011..00000000
--- a/common/CPU/68000/FX68k/uaddrDecode.sv
+++ /dev/null
@@ -1,91 +0,0 @@
-// Provides ucode routine entries (A1/A3) for each opcode
-// Also checks for illegal opcode and priv violation
-
-// This is one of the slowest part of the processor.
-// But no need to optimize or pipeline because the result is not needed until at least 4 cycles.
-// IR updated at the least one microinstruction earlier.
-// Just need to configure the timing analizer correctly.
-
-module uaddrDecode(
- input [15:0] opcode,
- output [UADDR_WIDTH-1:0] a1, a2, a3,
- output logic isPriv, isIllegal, isLineA, isLineF,
- output [15:0] lineBmap);
-
- wire [3:0] line = opcode[15:12];
- logic [3:0] eaCol, movEa;
-
- onehotEncoder4 irLineDecod( line, lineBmap);
-
- assign isLineA = lineBmap[ 'hA];
- assign isLineF = lineBmap[ 'hF];
-
- pla_lined pla_lined( .movEa( movEa), .col( eaCol),
- .opcode( opcode), .lineBmap( lineBmap),
- .palIll( isIllegal), .plaA1( a1), .plaA2( a2), .plaA3( a3) );
-
- // ea decoding
- assign eaCol = eaDecode( opcode[ 5:0]);
- assign movEa = eaDecode( {opcode[ 8:6], opcode[ 11:9]} );
-
- // EA decode
- function [3:0] eaDecode;
- input [5:0] eaBits;
- begin
- unique case( eaBits[ 5:3])
- 3'b111:
- case( eaBits[ 2:0])
- 3'b000: eaDecode = 7; // Absolute short
- 3'b001: eaDecode = 8; // Absolute long
- 3'b010: eaDecode = 9; // PC displacement
- 3'b011: eaDecode = 10; // PC offset
- 3'b100: eaDecode = 11; // Immediate
- default: eaDecode = 12; // Invalid
- endcase
-
- default: eaDecode = eaBits[5:3]; // Register based EAs
- endcase
- end
- endfunction
-
-
- /*
- Privileged instructions:
-
- ANDI/EORI/ORI SR
- MOVE to SR
- MOVE to/from USP
- RESET
- RTE
- STOP
- */
-
- always_comb begin
- unique case( lineBmap)
-
- // ori/andi/eori SR
- 'h01: isPriv = ((opcode & 16'hf5ff) == 16'h007c);
-
- 'h10:
- begin
- // No priority !!!
- if( (opcode & 16'hffc0) == 16'h46c0) // move to sr
- isPriv = 1'b1;
-
- else if( (opcode & 16'hfff0) == 16'h4e60) // move usp
- isPriv = 1'b1;
-
- else if( opcode == 16'h4e70 || // reset
- opcode == 16'h4e73 || // rte
- opcode == 16'h4e72) // stop
- isPriv = 1'b1;
- else
- isPriv = 1'b0;
- end
-
- default: isPriv = 1'b0;
- endcase
- end
-
-
-endmodule
\ No newline at end of file