From e8154a7dcb53d37d093c6d7d18b690e1f03724a4 Mon Sep 17 00:00:00 2001 From: antoniovillena Date: Thu, 28 Apr 2016 14:14:15 +0200 Subject: [PATCH] =?UTF-8?q?JupiterAce=20a=20=C3=BAltima=20versi=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cores/JupiterAce/T80.vhd | 1129 +++ cores/JupiterAce/T80_ALU.vhd | 351 + cores/JupiterAce/T80_MCode.vhd | 1971 +++++ cores/JupiterAce/T80_Pack.vhd | 215 + cores/JupiterAce/T80_Reg.vhd | 105 + cores/JupiterAce/T80a.vhd | 286 + cores/JupiterAce/ace.hex | 8192 ++++++++++++++++++++ cores/JupiterAce/ace.rom | Bin 0 -> 8192 bytes cores/JupiterAce/bin2hex.c | 33 + cores/JupiterAce/bin2hex.exe | Bin 0 -> 14795 bytes cores/JupiterAce/fpga_ace.v | 209 +- cores/JupiterAce/jace_logic.v | 193 + cores/JupiterAce/jupiter_ace.gise | 188 + cores/JupiterAce/jupiter_ace.xise | 45 +- cores/JupiterAce/keyboard_for_ace.v | 26 +- cores/JupiterAce/memorias.v | 93 +- cores/JupiterAce/par_usage_statistics.html | 44 +- cores/JupiterAce/pines_zxuno.ucf | 96 +- cores/JupiterAce/pines_zxuno_Ap.ucf | 82 + cores/JupiterAce/pines_zxuno_v4.ucf | 85 + cores/JupiterAce/rom.v | 36 + cores/JupiterAce/tld_jace_spartan6.v | 19 +- cores/JupiterAce/tv80_to_t80_wrapper.v | 79 + 23 files changed, 13205 insertions(+), 272 deletions(-) create mode 100644 cores/JupiterAce/T80.vhd create mode 100644 cores/JupiterAce/T80_ALU.vhd create mode 100644 cores/JupiterAce/T80_MCode.vhd create mode 100644 cores/JupiterAce/T80_Pack.vhd create mode 100644 cores/JupiterAce/T80_Reg.vhd create mode 100644 cores/JupiterAce/T80a.vhd create mode 100644 cores/JupiterAce/ace.hex create mode 100644 cores/JupiterAce/ace.rom create mode 100644 cores/JupiterAce/bin2hex.c create mode 100644 cores/JupiterAce/bin2hex.exe create mode 100644 cores/JupiterAce/jace_logic.v create mode 100644 cores/JupiterAce/jupiter_ace.gise create mode 100644 cores/JupiterAce/pines_zxuno_Ap.ucf create mode 100644 cores/JupiterAce/pines_zxuno_v4.ucf create mode 100644 cores/JupiterAce/rom.v create mode 100644 cores/JupiterAce/tv80_to_t80_wrapper.v diff --git a/cores/JupiterAce/T80.vhd b/cores/JupiterAce/T80.vhd new file mode 100644 index 0000000..54f7ed2 --- /dev/null +++ b/cores/JupiterAce/T80.vhd @@ -0,0 +1,1129 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed wait and halt +-- +-- 0211 : Fixed Refresh addition and IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson +-- +-- 0235 : Added clock enable and IM 2 fix by Mike Johnson +-- +-- 0237 : Changed 8080 I/O address output, added IntE output +-- +-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag +-- +-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode +-- +-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80 is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic; + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + ); +end T80; + +architecture rtl of T80 is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; + + -- Registers + signal ACC, F : std_logic_vector(7 downto 0); + signal Ap, Fp : std_logic_vector(7 downto 0); + signal I : std_logic_vector(7 downto 0); + signal R : unsigned(7 downto 0); + signal SP, PC : unsigned(15 downto 0); + signal RegDIH : std_logic_vector(7 downto 0); + signal RegDIL : std_logic_vector(7 downto 0); + signal RegBusA : std_logic_vector(15 downto 0); + signal RegBusB : std_logic_vector(15 downto 0); + signal RegBusC : std_logic_vector(15 downto 0); + signal RegAddrA_r : std_logic_vector(2 downto 0); + signal RegAddrA : std_logic_vector(2 downto 0); + signal RegAddrB_r : std_logic_vector(2 downto 0); + signal RegAddrB : std_logic_vector(2 downto 0); + signal RegAddrC : std_logic_vector(2 downto 0); + signal RegWEH : std_logic; + signal RegWEL : std_logic; + signal Alternate : std_logic; + + -- Help Registers + signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register + signal IR : std_logic_vector(7 downto 0); -- Instruction register + signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector + signal RegBusA_r : std_logic_vector(15 downto 0); + + signal ID16 : signed(15 downto 0); + signal Save_Mux : std_logic_vector(7 downto 0); + + signal TState : unsigned(2 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal IntE_FF1 : std_logic; + signal IntE_FF2 : std_logic; + signal Halt_FF : std_logic; + signal BusReq_s : std_logic; + signal BusAck : std_logic; + signal ClkEn : std_logic; + signal NMI_s : std_logic; + signal INT_s : std_logic; + signal IStatus : std_logic_vector(1 downto 0); + + signal DI_Reg : std_logic_vector(7 downto 0); + signal T_Res : std_logic; + signal XY_State : std_logic_vector(1 downto 0); + signal Pre_XY_F_M : std_logic_vector(2 downto 0); + signal NextIs_XY_Fetch : std_logic; + signal XY_Ind : std_logic; + signal No_BTR : std_logic; + signal BTR_r : std_logic; + signal Auto_Wait : std_logic; + signal Auto_Wait_t1 : std_logic; + signal Auto_Wait_t2 : std_logic; + signal IncDecZ : std_logic; + + -- ALU signals + signal BusB : std_logic_vector(7 downto 0); + signal BusA : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal F_Out : std_logic_vector(7 downto 0); + + -- Registered micro code outputs + signal Read_To_Reg_r : std_logic_vector(4 downto 0); + signal Arith16_r : std_logic; + signal Z16_r : std_logic; + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Save_ALU_r : std_logic; + signal PreserveC_r : std_logic; + signal MCycles : std_logic_vector(2 downto 0); + + -- Micro code outputs + signal MCycles_d : std_logic_vector(2 downto 0); + signal TStates : std_logic_vector(2 downto 0); + signal IntCycle : std_logic; + signal NMICycle : std_logic; + signal Inc_PC : std_logic; + signal Inc_WZ : std_logic; + signal IncDec_16 : std_logic_vector(3 downto 0); + signal Prefix : std_logic_vector(1 downto 0); + signal Read_To_Acc : std_logic; + signal Read_To_Reg : std_logic; + signal Set_BusB_To : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(3 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Save_ALU : std_logic; + signal PreserveC : std_logic; + signal Arith16 : std_logic; + signal Set_Addr_To : std_logic_vector(2 downto 0); + signal Jump : std_logic; + signal JumpE : std_logic; + signal JumpXY : std_logic; + signal Call : std_logic; + signal RstP : std_logic; + signal LDZ : std_logic; + signal LDW : std_logic; + signal LDSPHL : std_logic; + signal IORQ_i : std_logic; + signal Special_LD : std_logic_vector(2 downto 0); + signal ExchangeDH : std_logic; + signal ExchangeRp : std_logic; + signal ExchangeAF : std_logic; + signal ExchangeRS : std_logic; + signal I_DJNZ : std_logic; + signal I_CPL : std_logic; + signal I_CCF : std_logic; + signal I_SCF : std_logic; + signal I_RETN : std_logic; + signal I_BT : std_logic; + signal I_BC : std_logic; + signal I_BTR : std_logic; + signal I_RLD : std_logic; + signal I_RRD : std_logic; + signal I_INRC : std_logic; + signal SetDI : std_logic; + signal SetEI : std_logic; + signal IMode : std_logic_vector(1 downto 0); + signal Halt : std_logic; + +begin + + mcode : T80_MCode + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + IR => IR, + ISet => ISet, + MCycle => MCycle, + F => F, + NMICycle => NMICycle, + IntCycle => IntCycle, + MCycles => MCycles_d, + TStates => TStates, + Prefix => Prefix, + Inc_PC => Inc_PC, + Inc_WZ => Inc_WZ, + IncDec_16 => IncDec_16, + Read_To_Acc => Read_To_Acc, + Read_To_Reg => Read_To_Reg, + Set_BusB_To => Set_BusB_To, + Set_BusA_To => Set_BusA_To, + ALU_Op => ALU_Op, + Save_ALU => Save_ALU, + PreserveC => PreserveC, + Arith16 => Arith16, + Set_Addr_To => Set_Addr_To, + IORQ => IORQ_i, + Jump => Jump, + JumpE => JumpE, + JumpXY => JumpXY, + Call => Call, + RstP => RstP, + LDZ => LDZ, + LDW => LDW, + LDSPHL => LDSPHL, + Special_LD => Special_LD, + ExchangeDH => ExchangeDH, + ExchangeRp => ExchangeRp, + ExchangeAF => ExchangeAF, + ExchangeRS => ExchangeRS, + I_DJNZ => I_DJNZ, + I_CPL => I_CPL, + I_CCF => I_CCF, + I_SCF => I_SCF, + I_RETN => I_RETN, + I_BT => I_BT, + I_BC => I_BC, + I_BTR => I_BTR, + I_RLD => I_RLD, + I_RRD => I_RRD, + I_INRC => I_INRC, + SetDI => SetDI, + SetEI => SetEI, + IMode => IMode, + Halt => Halt, + NoRead => NoRead, + Write => Write); + + alu : T80_ALU + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + Arith16 => Arith16_r, + Z16 => Z16_r, + ALU_Op => ALU_Op_r, + IR => IR(5 downto 0), + ISet => ISet, + BusA => BusA, + BusB => BusB, + F_In => F, + Q => ALU_Q, + F_Out => F_Out); + + ClkEn <= CEN and not BusAck; + + T_Res <= '1' when TState = unsigned(TStates) else '0'; + + NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and + ((Set_Addr_To = aXY) or + (MCycle = "001" and IR = "11001011") or + (MCycle = "001" and IR = "00110110")) else '0'; + + Save_Mux <= BusB when ExchangeRp = '1' else + DI_Reg when Save_ALU_r = '0' else + ALU_Q; + + process (RESET_n, RestorePC_n, CLK_n) + begin + + if CLK_n'event and CLK_n = '1' then + + if RESET_n = '0' then + PC <= (others => '0'); -- Program Counter + A <= (others => '0'); + TmpAddr <= (others => '0'); + IR <= "00000000"; + ISet <= "00"; + XY_State <= "00"; + IStatus <= "00"; + MCycles <= "000"; + DO <= "00000000"; + + ACC <= (others => '1'); + F <= (others => '1'); + Ap <= (others => '1'); + Fp <= (others => '1'); + I <= (others => '0'); + R <= (others => '0'); + SP <= (others => '1'); + Alternate <= '0'; + + Read_To_Reg_r <= "00000"; + F <= (others => '1'); + Arith16_r <= '0'; + BTR_r <= '0'; + Z16_r <= '0'; + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + PreserveC_r <= '0'; + XY_Ind <= '0'; + + elsif RestorePC_n = '0' then + PC <= unsigned( RestorePC ); + A <= RestorePC; + IStatus <= RestoreInt(1 downto 0); + + elsif ClkEn = '1' then + + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + Read_To_Reg_r <= "00000"; + + MCycles <= MCycles_d; + + if IMode /= "11" then + IStatus <= IMode; + end if; + + Arith16_r <= Arith16; + PreserveC_r <= PreserveC; + if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then + Z16_r <= '1'; + else + Z16_r <= '0'; + end if; + + if MCycle = "001" and TState(2) = '0' then + -- MCycle = 1 and TState = 1, 2, or 3 + + if TState = 2 and Wait_n = '1' then + if Mode < 2 then + A(7 downto 0) <= std_logic_vector(R); + A(15 downto 8) <= I; + R(6 downto 0) <= R(6 downto 0) + 1; + end if; + + if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then + PC <= PC + 1; + end if; + + if IntCycle = '1' and IStatus = "01" then + IR <= "11111111"; + elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DInst; + end if; + + ISet <= "00"; + if Prefix /= "00" then + if Prefix = "11" then + if IR(5) = '1' then + XY_State <= "10"; + else + XY_State <= "01"; + end if; + else + if Prefix = "10" then + XY_State <= "00"; + XY_Ind <= '0'; + end if; + ISet <= Prefix; + end if; + else + XY_State <= "00"; + XY_Ind <= '0'; + end if; + end if; + + else + -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) + + if MCycle = "110" then + XY_Ind <= '1'; + if Prefix = "01" then + ISet <= "01"; + end if; + end if; + + if T_Res = '1' then + BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; + if Jump = '1' then + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(DI_Reg); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + elsif JumpXY = '1' then + A <= RegBusC; + PC <= unsigned(RegBusC); + elsif Call = '1' or RstP = '1' then + A <= TmpAddr; + PC <= unsigned(TmpAddr); + elsif MCycle = MCycles and NMICycle = '1' then + A <= "0000000001100110"; + PC <= "0000000001100110"; + elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then + A(15 downto 8) <= I; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(I); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + else + case Set_Addr_To is + when aXY => + if XY_State = "00" then + A <= RegBusC; + else + if NextIs_XY_Fetch = '1' then + A <= std_logic_vector(PC); + else + A <= TmpAddr; + end if; + end if; + when aIOA => + if Mode = 3 then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + elsif Mode = 2 then + -- Duplicate I/O address on 8080 + A(15 downto 8) <= DI_Reg; + else + A(15 downto 8) <= ACC; + end if; + A(7 downto 0) <= DI_Reg; + when aSP => + A <= std_logic_vector(SP); + when aBC => + if Mode = 3 and IORQ_i = '1' then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + A(7 downto 0) <= RegBusC(7 downto 0); + else + A <= RegBusC; + end if; + when aDE => + A <= RegBusC; + when aZI => + if Inc_WZ = '1' then + A <= std_logic_vector(unsigned(TmpAddr) + 1); + else + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + end if; + when others => + A <= std_logic_vector(PC); + end case; + end if; + + Save_ALU_r <= Save_ALU; + ALU_Op_r <= ALU_Op; + + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + end if; + + if TState = 2 and Wait_n = '1' then + if ISet = "01" and MCycle = "111" then + IR <= DInst; + end if; + if JumpE = '1' then + PC <= unsigned(signed(PC) + signed(DI_Reg)); + elsif Inc_PC = '1' then + PC <= PC + 1; + end if; + if BTR_r = '1' then + PC <= PC - 2; + end if; + if RstP = '1' then + TmpAddr <= (others =>'0'); + TmpAddr(5 downto 3) <= IR(5 downto 3); + end if; + end if; + if TState = 3 and MCycle = "110" then + TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); + end if; + + if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then + if IncDec_16(2 downto 0) = "111" then + if IncDec_16(3) = '1' then + SP <= SP - 1; + else + SP <= SP + 1; + end if; + end if; + end if; + + if LDSPHL = '1' then + SP <= unsigned(RegBusC); + end if; + if ExchangeAF = '1' then + Ap <= ACC; + ACC <= Ap; + Fp <= F; + F <= Fp; + end if; + if ExchangeRS = '1' then + Alternate <= not Alternate; + end if; + end if; + + if TState = 3 then + if LDZ = '1' then + TmpAddr(7 downto 0) <= DI_Reg; + end if; + if LDW = '1' then + TmpAddr(15 downto 8) <= DI_Reg; + end if; + + if Special_LD(2) = '1' then + case Special_LD(1 downto 0) is + when "00" => + ACC <= I; + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= I(7); + + if I = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + when "01" => + ACC <= std_logic_vector(R); + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= R(7); + + if R = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + when "10" => + I <= ACC; + when others => + R <= unsigned(ACC); + end case; + end if; + end if; + + if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then + if Mode = 3 then + F(6) <= F_Out(6); + F(5) <= F_Out(5); + F(7) <= F_Out(7); + if PreserveC_r = '0' then + F(4) <= F_Out(4); + end if; + else + F(7 downto 1) <= F_Out(7 downto 1); + if PreserveC_r = '0' then + F(Flag_C) <= F_Out(0); + end if; + end if; + end if; + if T_Res = '1' and I_INRC = '1' then + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + if DI_Reg(7 downto 0) = "00000000" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + F(Flag_S) <= DI_Reg(7); + F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor + DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); + end if; + + if TState = 1 and Auto_Wait_t1 = '0' then + DO <= BusB; + if I_RLD = '1' then + DO(3 downto 0) <= BusA(3 downto 0); + DO(7 downto 4) <= BusB(3 downto 0); + end if; + if I_RRD = '1' then + DO(3 downto 0) <= BusB(7 downto 4); + DO(7 downto 4) <= BusA(3 downto 0); + end if; + end if; + + if T_Res = '1' then + Read_To_Reg_r(3 downto 0) <= Set_BusA_To; + Read_To_Reg_r(4) <= Read_To_Reg; + if Read_To_Acc = '1' then + Read_To_Reg_r(3 downto 0) <= "0111"; + Read_To_Reg_r(4) <= '1'; + end if; + end if; + + if TState = 1 and I_BT = '1' then + F(Flag_X) <= ALU_Q(3); + F(Flag_Y) <= ALU_Q(1); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_BC = '1' or I_BT = '1' then + F(Flag_P) <= IncDecZ; + end if; + + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10111" => + ACC <= Save_Mux; + when "10110" => + DO <= Save_Mux; + when "11000" => + SP(7 downto 0) <= unsigned(Save_Mux); + when "11001" => + SP(15 downto 8) <= unsigned(Save_Mux); + when "11011" => + F <= Save_Mux; + when others => + end case; + end if; + + end if; + + end if; + + end process; + +--------------------------------------------------------------------------- +-- +-- BC('), DE('), HL('), IX and IY +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + -- Bus A / Write + RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then + RegAddrA_r <= XY_State(1) & "11"; + end if; + + -- Bus B + RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then + RegAddrB_r <= XY_State(1) & "11"; + end if; + + -- Address from register + RegAddrC <= Alternate & Set_Addr_To(1 downto 0); + -- Jump (HL), LD SP,HL + if (JumpXY = '1' or LDSPHL = '1') then + RegAddrC <= Alternate & "10"; + end if; + if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then + RegAddrC <= XY_State(1) & "11"; + end if; + + if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then + IncDecZ <= F_Out(Flag_Z); + end if; + if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then + if ID16 = 0 then + IncDecZ <= '0'; + else + IncDecZ <= '1'; + end if; + end if; + + RegBusA_r <= RegBusA; + end if; + end if; + end process; + + RegAddrA <= + -- 16 bit increment/decrement + XY_State(1) & "11" when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" and XY_State /= "00" else + Alternate & IncDec_16(1 downto 0) when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) else + -- EX HL,DL + Alternate & "10" when ExchangeDH = '1' and TState = 3 else + Alternate & "01" when ExchangeDH = '1' and TState = 4 else + -- Bus A / Write + RegAddrA_r; + + RegAddrB <= + -- EX HL,DL + Alternate & "01" when ExchangeDH = '1' and TState = 3 else + -- Bus B + RegAddrB_r; + + ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else + signed(RegBusA) + 1; + + process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegWEH <= '0'; + RegWEL <= '0'; + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => + RegWEH <= not Read_To_Reg_r(0); + RegWEL <= Read_To_Reg_r(0); + when others => + end case; + end if; + + if ExchangeDH = '1' and (TState = 3 or TState = 4) then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + case IncDec_16(1 downto 0) is + when "00" | "01" | "10" => + RegWEH <= '1'; + RegWEL <= '1'; + when others => + end case; + end if; + end process; + + process (Save_Mux, RegBusB, RegBusA_r, ID16, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegDIH <= Save_Mux; + RegDIL <= Save_Mux; + + if ExchangeDH = '1' and TState = 3 then + RegDIH <= RegBusB(15 downto 8); + RegDIL <= RegBusB(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 4 then + RegDIH <= RegBusA_r(15 downto 8); + RegDIL <= RegBusA_r(7 downto 0); + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + RegDIH <= std_logic_vector(ID16(15 downto 8)); + RegDIL <= std_logic_vector(ID16(7 downto 0)); + end if; + end process; + + Regs : T80_Reg + port map( + Clk => CLK_n, + CEN => ClkEn, + WEH => RegWEH, + WEL => RegWEL, + AddrA => RegAddrA, + AddrB => RegAddrB, + AddrC => RegAddrC, + DIH => RegDIH, + DIL => RegDIL, + DOAH => RegBusA(15 downto 8), + DOAL => RegBusA(7 downto 0), + DOBH => RegBusB(15 downto 8), + DOBL => RegBusB(7 downto 0), + DOCH => RegBusC(15 downto 8), + DOCL => RegBusC(7 downto 0)); + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + case Set_BusB_To is + when "0111" => + BusB <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusB_To(0) = '1' then + BusB <= RegBusB(7 downto 0); + else + BusB <= RegBusB(15 downto 8); + end if; + when "0110" => + BusB <= DI_Reg; + when "1000" => + BusB <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusB <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusB <= "00000001"; + when "1011" => + BusB <= F; + when "1100" => + BusB <= std_logic_vector(PC(7 downto 0)); + when "1101" => + BusB <= std_logic_vector(PC(15 downto 8)); + when "1110" => + BusB <= "00000000"; + when others => + BusB <= "--------"; + end case; + + case Set_BusA_To is + when "0111" => + BusA <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusA_To(0) = '1' then + BusA <= RegBusA(7 downto 0); + else + BusA <= RegBusA(15 downto 8); + end if; + when "0110" => + BusA <= DI_Reg; + when "1000" => + BusA <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusA <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusA <= "00000000"; + when others => + BusB <= "--------"; + end case; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Generate external control signals +-- +--------------------------------------------------------------------------- + process (RESET_n,CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if RESET_n = '0' then + RFSH_n <= '1'; + + elsif CEN = '1' then + if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then + RFSH_n <= '0'; + else + RFSH_n <= '1'; + end if; + end if; + end if; + end process; + + MC <= std_logic_vector(MCycle); + TS <= std_logic_vector(TState); + DI_Reg <= DI; + HALT_n <= not Halt_FF; + BUSAK_n <= not BusAck; + IntCycle_n <= not IntCycle; + IntE <= IntE_FF1; + IORQ <= IORQ_i; + Stop <= I_DJNZ; + + SavePC <= std_logic_vector( PC ); + SaveINT <= "0000" & IntE_FF2 & IntE_FF1 & IStatus when MCycle = "001" and TState = "001" and Prefix = "00" and IntCycle = '0' and NMICycle = '0' else + "1111" & IntE_FF2 & IntE_FF1 & IStatus; + +------------------------------------------------------------------------- +-- +-- Syncronise inputs +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + variable OldNMI_n : std_logic; + begin + if CLK_n'event and CLK_n = '1' then + + if RESET_n = '0' then + BusReq_s <= '0'; + INT_s <= '0'; + NMI_s <= '0'; + OldNMI_n := '0'; + + elsif CEN = '1' then + BusReq_s <= not BUSRQ_n; + INT_s <= not INT_n; + if NMICycle = '1' then + NMI_s <= '0'; + elsif NMI_n = '0' and OldNMI_n = '1' then + NMI_s <= '1'; + end if; + OldNMI_n := NMI_n; + end if; + + end if; + end process; + +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + process (RESET_n, RestorePC_n, CLK_n) + begin + + if CLK_n'event and CLK_n = '1' then + if RESET_n = '0' then + MCycle <= "001"; + TState <= "000"; + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + BusAck <= '0'; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + M1_n <= '1'; + + elsif RestorePC_n = '0' then + MCycle <= "001"; + TState <= "001"; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= RestoreINT(2); + IntE_FF2 <= RestoreINT(3); + + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + BusAck <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + + elsif CEN = '1' then + if T_Res = '1' then + Auto_Wait_t1 <= '0'; + else + Auto_Wait_t1 <= Auto_Wait or IORQ_i; + end if; + Auto_Wait_t2 <= Auto_Wait_t1; + No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or + (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or + (I_BTR and (not IR(4) or F(Flag_Z))); + if TState = 2 then + if SetEI = '1' then + IntE_FF1 <= '1'; + IntE_FF2 <= '1'; + end if; + if I_RETN = '1' then + IntE_FF1 <= IntE_FF2; + end if; + end if; + if TState = 3 then + if SetDI = '1' then + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + end if; + if IntCycle = '1' or NMICycle = '1' then + Halt_FF <= '0'; + end if; + if MCycle = "001" and TState = 2 and Wait_n = '1' then + M1_n <= '1'; + end if; + if BusReq_s = '1' and BusAck = '1' then + else + BusAck <= '0'; + if TState = 2 and Wait_n = '0' then + elsif T_Res = '1' then + if Halt = '1' then + Halt_FF <= '1'; + end if; + if BusReq_s = '1' then + BusAck <= '1'; + else + TState <= "001"; + + if NextIs_XY_Fetch = '1' then + MCycle <= "110"; + Pre_XY_F_M <= MCycle; + if IR = "00110110" and Mode = 0 then + Pre_XY_F_M <= "010"; + end if; + elsif (MCycle = MCycles) or + No_BTR = '1' or + (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') or + ( MCycle = "111" and MCycles= "001" and Pre_XY_F_M = "001" ) then + M1_n <= '0'; + MCycle <= "001"; + IntCycle <= '0'; + NMICycle <= '0'; + if NMI_s = '1' and Prefix = "00" then + NMICycle <= '1'; + IntE_FF1 <= '0'; + elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then + IntCycle <= '1'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + elsif (MCycle = "111") or + (MCycle = "110" and Mode = 1 and ISet /= "01") then + MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + end if; + else + if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor + (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then + TState <= TState + 1; + end if; + end if; + end if; + if TState = 0 then + M1_n <= '0'; + end if; + end if; + end if; + end process; + + process (IntCycle, NMICycle, MCycle) + begin + Auto_Wait <= '0'; + if IntCycle = '1' or NMICycle = '1' then + if MCycle = "001" then + Auto_Wait <= '1'; + end if; + end if; + end process; + +end; diff --git a/cores/JupiterAce/T80_ALU.vhd b/cores/JupiterAce/T80_ALU.vhd new file mode 100644 index 0000000..86fddce --- /dev/null +++ b/cores/JupiterAce/T80_ALU.vhd @@ -0,0 +1,351 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0238 : Fixed zero flag for 16 bit SBC and ADC +-- +-- 0240 : Added GB operations +-- +-- 0242 : Cleanup +-- +-- 0247 : Cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_ALU is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); +end T80_ALU; + +architecture rtl of T80_ALU is + + procedure AddSub(A : std_logic_vector; + B : std_logic_vector; + Sub : std_logic; + Carry_In : std_logic; + signal Res : out std_logic_vector; + signal Carry : out std_logic) is + variable B_i : unsigned(A'length - 1 downto 0); + variable Res_i : unsigned(A'length + 1 downto 0); + begin + if Sub = '1' then + B_i := not unsigned(B); + else + B_i := unsigned(B); + end if; + Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); + Carry <= Res_i(A'length + 1); + Res <= std_logic_vector(Res_i(A'length downto 1)); + end; + + -- AddSub variables (temporary signals) + signal UseCarry : std_logic; + signal Carry7_v : std_logic; + signal Overflow_v : std_logic; + signal HalfCarry_v : std_logic; + signal Carry_v : std_logic; + signal Q_v : std_logic_vector(7 downto 0); + + signal BitMask : std_logic_vector(7 downto 0); + +begin + + with IR(5 downto 3) select BitMask <= "00000001" when "000", + "00000010" when "001", + "00000100" when "010", + "00001000" when "011", + "00010000" when "100", + "00100000" when "101", + "01000000" when "110", + "10000000" when others; + + UseCarry <= not ALU_Op(2) and ALU_Op(0); + AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); + AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); + AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); + OverFlow_v <= Carry_v xor Carry7_v; + + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) + variable Q_t : std_logic_vector(7 downto 0); + variable DAA_Q : unsigned(8 downto 0); + begin + Q_t := "--------"; + F_Out <= F_In; + DAA_Q := "---------"; + case ALU_Op is + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => + F_Out(Flag_N) <= '0'; + F_Out(Flag_C) <= '0'; + case ALU_OP(2 downto 0) is + when "000" | "001" => -- ADD, ADC + Q_t := Q_v; + F_Out(Flag_C) <= Carry_v; + F_Out(Flag_H) <= HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "010" | "011" | "111" => -- SUB, SBC, CP + Q_t := Q_v; + F_Out(Flag_N) <= '1'; + F_Out(Flag_C) <= not Carry_v; + F_Out(Flag_H) <= not HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "100" => -- AND + Q_t(7 downto 0) := BusA and BusB; + F_Out(Flag_H) <= '1'; + when "101" => -- XOR + Q_t(7 downto 0) := BusA xor BusB; + F_Out(Flag_H) <= '0'; + when others => -- OR "110" + Q_t(7 downto 0) := BusA or BusB; + F_Out(Flag_H) <= '0'; + end case; + if ALU_Op(2 downto 0) = "111" then -- CP + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + else + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + end if; + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + if Z16 = '1' then + F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC + end if; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + case ALU_Op(2 downto 0) is + when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP + when others => + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + end case; + if Arith16 = '1' then + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + F_Out(Flag_P) <= F_In(Flag_P); + end if; + when "1100" => + -- DAA + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 + end if; + end if; + F_Out(Flag_X) <= DAA_Q(3); + F_Out(Flag_Y) <= DAA_Q(5); + F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); + Q_t := std_logic_vector(DAA_Q(7 downto 0)); + if DAA_Q(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= DAA_Q(7); + F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor + DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); + when "1101" | "1110" => + -- RLD, RRD + Q_t(7 downto 4) := BusA(7 downto 4); + if ALU_Op(0) = '1' then + Q_t(3 downto 0) := BusB(7 downto 4); + else + Q_t(3 downto 0) := BusB(3 downto 0); + end if; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + when "1001" => + -- BIT + Q_t(7 downto 0) := BusB and BitMask; + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + F_Out(Flag_P) <= '1'; + else + F_Out(Flag_Z) <= '0'; + F_Out(Flag_P) <= '0'; + end if; + F_Out(Flag_H) <= '1'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= '0'; + F_Out(Flag_Y) <= '0'; + if IR(2 downto 0) /= "110" then + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + end if; + when "1010" => + -- SET + Q_t(7 downto 0) := BusB or BitMask; + when "1011" => + -- RES + Q_t(7 downto 0) := BusB and not BitMask; + when "1000" => + -- ROT + case IR(5 downto 3) is + when "000" => -- RLC + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := BusA(7); + F_Out(Flag_C) <= BusA(7); + when "010" => -- RL + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(7); + when "001" => -- RRC + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(0); + F_Out(Flag_C) <= BusA(0); + when "011" => -- RR + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(0); + when "100" => -- SLA + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '0'; + F_Out(Flag_C) <= BusA(7); + when "110" => -- SLL (Undocumented) / SWAP + if Mode = 3 then + Q_t(7 downto 4) := BusA(3 downto 0); + Q_t(3 downto 0) := BusA(7 downto 4); + F_Out(Flag_C) <= '0'; + else + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '1'; + F_Out(Flag_C) <= BusA(7); + end if; + when "101" => -- SRA + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(7); + F_Out(Flag_C) <= BusA(0); + when others => -- SRL + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := '0'; + F_Out(Flag_C) <= BusA(0); + end case; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + if ISet = "00" then + F_Out(Flag_P) <= F_In(Flag_P); + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + end if; + when others => + null; + end case; + Q <= Q_t; + end process; + +end; diff --git a/cores/JupiterAce/T80_MCode.vhd b/cores/JupiterAce/T80_MCode.vhd new file mode 100644 index 0000000..15e2816 --- /dev/null +++ b/cores/JupiterAce/T80_MCode.vhd @@ -0,0 +1,1971 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0235 : Added IM 2 fix by Mike Johnson +-- +-- 0238 : Added NoRead signal +-- +-- 0238b: Fixed instruction timing for POP and DJNZ +-- +-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes +-- +-- 0242 : Fixed I/O instruction timing, cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_MCode is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic + ); +end T80_MCode; + +architecture rtl of T80_MCode is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; +-- constant aNone : std_logic_vector(2 downto 0) := "000"; +-- constant aXY : std_logic_vector(2 downto 0) := "001"; +-- constant aIOA : std_logic_vector(2 downto 0) := "010"; +-- constant aSP : std_logic_vector(2 downto 0) := "011"; +-- constant aBC : std_logic_vector(2 downto 0) := "100"; +-- constant aDE : std_logic_vector(2 downto 0) := "101"; +-- constant aZI : std_logic_vector(2 downto 0) := "110"; + + function is_cc_true( + F : std_logic_vector(7 downto 0); + cc : bit_vector(2 downto 0) + ) return boolean is + begin + if Mode = 3 then + case cc is + when "000" => return F(7) = '0'; -- NZ + when "001" => return F(7) = '1'; -- Z + when "010" => return F(4) = '0'; -- NC + when "011" => return F(4) = '1'; -- C + when "100" => return false; + when "101" => return false; + when "110" => return false; + when "111" => return false; + end case; + else + case cc is + when "000" => return F(6) = '0'; -- NZ + when "001" => return F(6) = '1'; -- Z + when "010" => return F(0) = '0'; -- NC + when "011" => return F(0) = '1'; -- C + when "100" => return F(2) = '0'; -- PO + when "101" => return F(2) = '1'; -- PE + when "110" => return F(7) = '0'; -- P + when "111" => return F(7) = '1'; -- M + end case; + end if; + end; + +begin + + process (IR, ISet, MCycle, F, NMICycle, IntCycle) + variable DDD : std_logic_vector(2 downto 0); + variable SSS : std_logic_vector(2 downto 0); + variable DPair : std_logic_vector(1 downto 0); + variable IRB : bit_vector(7 downto 0); + begin + DDD := IR(5 downto 3); + SSS := IR(2 downto 0); + DPair := IR(5 downto 4); + IRB := to_bitvector(IR); + + MCycles <= "001"; + if MCycle = "001" then + TStates <= "100"; + else + TStates <= "011"; + end if; + Prefix <= "00"; + Inc_PC <= '0'; + Inc_WZ <= '0'; + IncDec_16 <= "0000"; + Read_To_Acc <= '0'; + Read_To_Reg <= '0'; + Set_BusB_To <= "0000"; + Set_BusA_To <= "0000"; + ALU_Op <= "0" & IR(5 downto 3); + Save_ALU <= '0'; + PreserveC <= '0'; + Arith16 <= '0'; + IORQ <= '0'; + Set_Addr_To <= aNone; + Jump <= '0'; + JumpE <= '0'; + JumpXY <= '0'; + Call <= '0'; + RstP <= '0'; + LDZ <= '0'; + LDW <= '0'; + LDSPHL <= '0'; + Special_LD <= "000"; + ExchangeDH <= '0'; + ExchangeRp <= '0'; + ExchangeAF <= '0'; + ExchangeRS <= '0'; + I_DJNZ <= '0'; + I_CPL <= '0'; + I_CCF <= '0'; + I_SCF <= '0'; + I_RETN <= '0'; + I_BT <= '0'; + I_BC <= '0'; + I_BTR <= '0'; + I_RLD <= '0'; + I_RRD <= '0'; + I_INRC <= '0'; + SetDI <= '0'; + SetEI <= '0'; + IMode <= "11"; + Halt <= '0'; + NoRead <= '0'; + Write <= '0'; + + case ISet is + when "00" => + +------------------------------------------------------------------------------ +-- +-- Unprefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is +-- 8 BIT LOAD GROUP + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- LD r,r' + Set_BusB_To(2 downto 0) <= SSS; + ExchangeRp <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => + -- LD r,n + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => + -- LD r,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => + -- LD (HL),r + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110110" => + -- LD (HL),n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00001010" => + -- LD A,(BC) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00011010" => + -- LD A,(DE) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00111010" => + if Mode = 3 then + -- LDD A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end if; + when "00000010" => + -- LD (BC),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00010010" => + -- LD (DE),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110010" => + if Mode = 3 then + -- LDD (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + +-- 16 BIT LOAD GROUP + when "00000001"|"00010001"|"00100001"|"00110001" => + -- LD dd,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1000"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1001"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "00101010" => + if Mode = 3 then + -- LDI A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD HL,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end if; + when "00100010" => + if Mode = 3 then + -- LDI (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD (nn),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "0101"; -- L + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "0100"; -- H + when 5 => + Write <= '1'; + when others => null; + end case; + end if; + when "11111001" => + -- LD SP,HL + TStates <= "110"; + LDSPHL <= '1'; + when "11000101"|"11010101"|"11100101"|"11110101" => + -- PUSH qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "11000001"|"11010001"|"11100001"|"11110001" => + -- POP qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1011"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + IncDec_16 <= "0111"; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "0111"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + +-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP + when "11101011" => + if Mode /= 3 then + -- EX DE,HL + ExchangeDH <= '1'; + end if; + when "00001000" => + if Mode = 3 then + -- LD (nn),SP + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "1000"; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "1001"; + when 5 => + Write <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EX AF,AF' + ExchangeAF <= '1'; + end if; + when "11011001" => + if Mode = 3 then + -- RETI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + SetEI <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EXX + ExchangeRS <= '1'; + end if; + when "11100011" => + if Mode /= 3 then + -- EX (SP),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0101"; + Set_BusB_To <= "0101"; + Set_Addr_To <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + TStates <= "100"; + Write <= '1'; + when 4 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0100"; + Set_BusB_To <= "0100"; + Set_Addr_To <= aSP; + when 5 => + IncDec_16 <= "1111"; + TStates <= "101"; + Write <= '1'; + when others => null; + end case; + end if; + +-- 8 BIT ARITHMETIC AND LOGICAL GROUP + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- ADD A,r + -- ADC A,r + -- SUB A,r + -- SBC A,r + -- AND A,r + -- OR A,r + -- XOR A,r + -- CP A,r + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- ADD A,(HL) + -- ADC A,(HL) + -- SUB A,(HL) + -- SBC A,(HL) + -- AND A,(HL) + -- OR A,(HL) + -- XOR A,(HL) + -- CP A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + when others => null; + end case; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- ADD A,n + -- ADC A,n + -- SUB A,n + -- SBC A,n + -- AND A,n + -- OR A,n + -- XOR A,n + -- CP A,n + MCycles <= "010"; + if MCycle = "010" then + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + end if; + when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => + -- INC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + when "00110100" => + -- INC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => + -- DEC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0010"; + when "00110101" => + -- DEC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + ALU_Op <= "0010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + +-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS + when "00100111" => + -- DAA + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + ALU_Op <= "1100"; + Save_ALU <= '1'; + when "00101111" => + -- CPL + I_CPL <= '1'; + when "00111111" => + -- CCF + I_CCF <= '1'; + when "00110111" => + -- SCF + I_SCF <= '1'; + when "00000000" => + if NMICycle = '1' then + -- NMI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + TStates <= "100"; + Write <= '1'; + when others => null; + end case; + elsif IntCycle = '1' then + -- INT (IM 2) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + LDZ <= '1'; + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + --TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + --TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + else + -- NOP + end if; + when "01110110" => + -- HALT + Halt <= '1'; + when "11110011" => + -- DI + SetDI <= '1'; + when "11111011" => + -- EI + SetEI <= '1'; + +-- 16 BIT ARITHMETIC GROUP + when "00001001"|"00011001"|"00101001"|"00111001" => + -- ADD HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; + when others => + end case; + when "00000011"|"00010011"|"00100011"|"00110011" => + -- INC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when "00001011"|"00011011"|"00101011"|"00111011" => + -- DEC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + +-- ROTATE AND SHIFT GROUP + when "00000111" + -- RLCA + |"00010111" + -- RLA + |"00001111" + -- RRCA + |"00011111" => + -- RRA + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + +-- JUMP GROUP + when "11000011" => + -- JP nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + Jump <= '1'; + when others => null; + end case; + when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+C),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "01" => + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + when "10" => + -- LD A,($FF00+C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => + end case; + when "11" => + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end case; + else + -- JP cc,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Jump <= '1'; + end if; + when others => null; + end case; + end if; + when "00011000" => + if Mode /= 2 then + -- JR e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00111000" => + if Mode /= 2 then + -- JR C,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00110000" => + if Mode /= 2 then + -- JR NC,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00101000" => + if Mode /= 2 then + -- JR Z,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00100000" => + if Mode /= 2 then + -- JR NZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "11101001" => + -- JP (HL) + JumpXY <= '1'; + when "00010000" => + if Mode = 3 then + I_DJNZ <= '1'; + elsif Mode < 2 then + -- DJNZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + I_DJNZ <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= "000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + I_DJNZ <= '1'; + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + +-- CALL AND RETURN GROUP + when "11001101" => + -- CALL nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + IncDec_16 <= "1111"; + Inc_PC <= '1'; + TStates <= "100"; + Set_Addr_To <= aSP; + LDW <= '1'; + Set_BusB_To <= "1101"; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => + if IR(5) = '0' or Mode /= 3 then + -- CALL cc,nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + LDW <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + TStates <= "100"; + Set_BusB_To <= "1101"; + else + MCycles <= "011"; + end if; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + end if; + when "11001001" => + -- RET + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + --TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+nn),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "01" => + -- ADD SP,n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + ALU_Op <= "0000"; + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To <= "1000"; + Set_BusB_To <= "0110"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To <= "1001"; + Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + when others => + end case; + when "10" => + -- LD A,($FF00+nn) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "11" => + -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end case; + else + -- RET cc + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; + when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => + -- RST p + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + +-- INPUT AND OUTPUT GROUP + when "11011011" => + if Mode /= 3 then + -- IN A,(n) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + when "11010011" => + if Mode /= 3 then + -- OUT (n),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- MULTIBYTE INSTRUCTIONS +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + + when "11001011" => + if Mode /= 2 then + Prefix <= "01"; + end if; + + when "11101101" => + if Mode < 2 then + Prefix <= "10"; + end if; + + when "11011101"|"11111101" => + if Mode < 2 then + Prefix <= "11"; + end if; + + end case; + + when "01" => + +------------------------------------------------------------------------------ +-- +-- CB prefixed instructions +-- +------------------------------------------------------------------------------ + + Set_BusA_To(2 downto 0) <= IR(2 downto 0); + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => + -- RLC r + -- RL r + -- RRC r + -- RR r + -- SLA r + -- SRA r + -- SRL r + -- SLL r (Undocumented) / SWAP r + if MCycle = "001" or MCycle = "111" then + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => + -- RLC (HL) + -- RL (HL) + -- RRC (HL) + -- RR (HL) + -- SRA (HL) + -- SRL (HL) + -- SLA (HL) + -- SLL (HL) (Undocumented) / SWAP (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- BIT b,r + if MCycle = "001" or MCycle = "111" then + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + ALU_Op <= "1001"; + end if; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => + -- BIT b,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => + end case; + when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => + -- SET b,r + if MCycle = "001" then + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + else + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 7 => + Set_Addr_To <= aXY; + when 2 => + Set_BusB_To(2 downto 0) <= "110"; + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Set_Addr_To <= aXY; + when 4 => + Write <= '1'; + when others => + end case; + end if; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- SET b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- RES b,r + if MCycle = "001" then + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + else + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 7 => + Set_Addr_To <= aXY; + when 2 => + Set_BusB_To(2 downto 0) <= "110"; + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Set_Addr_To <= aXY; + when 4 => + Write <= '1'; + when others => + end case; + end if; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- RES b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + end case; + + when others => + +------------------------------------------------------------------------------ +-- +-- ED prefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" + + + |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" + | "10100100"|"10100101"|"10100110"|"10100111" + | "10101100"|"10101101"|"10101110"|"10101111" + | "10110100"|"10110101"|"10110110"|"10110111" + | "10111100"|"10111101"|"10111110"|"10111111" + |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => + null; -- NOP, undocumented + when "01111110"|"01111111" => + -- NOP, undocumented + null; +-- 8 BIT LOAD GROUP + when "01010111" => + -- LD A,I + Special_LD <= "100"; + TStates <= "101"; + when "01011111" => + -- LD A,R + Special_LD <= "101"; + TStates <= "101"; + when "01000111" => + -- LD I,A + Special_LD <= "110"; + TStates <= "101"; + when "01001111" => + -- LD R,A + Special_LD <= "111"; + TStates <= "101"; +-- 16 BIT LOAD GROUP + when "01001011"|"01011011"|"01101011"|"01111011" => + -- LD dd,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1000"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '1'; + end if; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1001"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "01000011"|"01010011"|"01100011"|"01110011" => + -- LD (nn),dd + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1000"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1001"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 5 => + Write <= '1'; + when others => null; + end case; + when "10100000" | "10101000" | "10110000" | "10111000" => + -- LDI, LDD, LDIR, LDDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0000"; + Set_Addr_To <= aDE; + if IR(3) = '0' then + IncDec_16 <= "0110"; -- IX + else + IncDec_16 <= "1110"; + end if; + when 3 => + I_BT <= '1'; + TStates <= "101"; + Write <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0101"; -- DE + else + IncDec_16 <= "1101"; + end if; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100001" | "10101001" | "10110001" | "10111001" => + -- CPI, CPD, CPIR, CPDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0111"; + Save_ALU <= '1'; + PreserveC <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + when 3 => + NoRead <= '1'; + I_BC <= '1'; + TStates <= "101"; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => + -- NEG + Alu_OP <= "0010"; + Set_BusB_To <= "0111"; + Set_BusA_To <= "1010"; + Read_To_Acc <= '1'; + Save_ALU <= '1'; + when "01000110"|"01001110"|"01100110"|"01101110" => + -- IM 0 + IMode <= "00"; + when "01010110"|"01110110" => + -- IM 1 + IMode <= "01"; + when "01011110"|"01110111" => + -- IM 2 + IMode <= "10"; +-- 16 bit arithmetic + when "01001010"|"01011010"|"01101010"|"01111010" => + -- ADC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0001"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01000010"|"01010010"|"01100010"|"01110010" => + -- SBC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01101111" => + -- RLD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1101"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RLD <= '1'; + Write <= '1'; + when others => + end case; + when "01100111" => + -- RRD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1110"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RRD <= '1'; + Write <= '1'; + when others => + end case; + when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => + -- RETI, RETN + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + when others => null; + end case; + when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => + -- IN r,(C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + IORQ <= '1'; + if IR(5 downto 3) /= "110" then + Read_To_Reg <= '1'; + Set_BusA_To(2 downto 0) <= IR(5 downto 3); + end if; + I_INRC <= '1'; + when others => + end case; + when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => + -- OUT (C),r + -- OUT (C),0 + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + if IR(5 downto 3) = "110" then + Set_BusB_To(3) <= '1'; + end if; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "10100010" | "10101010" | "10110010" | "10111010" => + -- INI, IND, INIR, INDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aBC; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + IORQ <= '1'; + Set_BusB_To <= "0110"; + Set_Addr_To <= aXY; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + TStates <= "011"; -- "100" + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100011" | "10101011" | "10110011" | "10111011" => + -- OUTI, OUTD, OTIR, OTDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aXY; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + Set_BusB_To <= "0110"; + Set_Addr_To <= aBC; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + IORQ <= '1'; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + end case; + + end case; + + if Mode = 1 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "011"; + end if; + end if; + + if Mode = 3 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "100"; + end if; + end if; + + if Mode < 2 then + if MCycle = "110" then + Inc_PC <= '1'; + if Mode = 1 then + Set_Addr_To <= aXY; + TStates <= "100"; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + end if; + if IRB = "00110110" or IRB = "11001011" then + Set_Addr_To <= aNone; + end if; + end if; + if MCycle = "111" then + if Mode = 0 then + TStates <= "101"; + end if; + if ISet /= "01" then + Set_Addr_To <= aXY; + end if; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + if IRB = "00110110" or ISet = "01" then + -- LD (HL),n + Inc_PC <= '1'; + else + NoRead <= '1'; + end if; + end if; + end if; + + end process; + +end; diff --git a/cores/JupiterAce/T80_Pack.vhd b/cores/JupiterAce/T80_Pack.vhd new file mode 100644 index 0000000..d1b11e1 --- /dev/null +++ b/cores/JupiterAce/T80_Pack.vhd @@ -0,0 +1,215 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T80_Pack is + + component T80 + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic; + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + ); + end component; + + component T80_Reg + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); + end component; + + component T80_MCode + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic + ); + end component; + + component T80_ALU + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); + end component; + +end; diff --git a/cores/JupiterAce/T80_Reg.vhd b/cores/JupiterAce/T80_Reg.vhd new file mode 100644 index 0000000..828485f --- /dev/null +++ b/cores/JupiterAce/T80_Reg.vhd @@ -0,0 +1,105 @@ +-- +-- T80 Registers, technology independent +-- +-- Version : 0244 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0242 : Initial release +-- +-- 0244 : Changed to single register file +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_Reg is + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); +end T80_Reg; + +architecture rtl of T80_Reg is + + type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); + signal RegsH : Register_Image(0 to 7); + signal RegsL : Register_Image(0 to 7); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then + if CEN = '1' then + if WEH = '1' then + RegsH(to_integer(unsigned(AddrA))) <= DIH; + end if; + if WEL = '1' then + RegsL(to_integer(unsigned(AddrA))) <= DIL; + end if; + end if; + end if; + end process; + + DOAH <= RegsH(to_integer(unsigned(AddrA))); + DOAL <= RegsL(to_integer(unsigned(AddrA))); + DOBH <= RegsH(to_integer(unsigned(AddrB))); + DOBL <= RegsL(to_integer(unsigned(AddrB))); + DOCH <= RegsH(to_integer(unsigned(AddrC))); + DOCL <= RegsL(to_integer(unsigned(AddrC))); + +end; diff --git a/cores/JupiterAce/T80a.vhd b/cores/JupiterAce/T80a.vhd new file mode 100644 index 0000000..5e1224e --- /dev/null +++ b/cores/JupiterAce/T80a.vhd @@ -0,0 +1,286 @@ +-- +-- Z80 compatible microprocessor core, asynchronous top level +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80a is + generic( + Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + D : inout std_logic_vector(7 downto 0); + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + + ); +end T80a; + +architecture rtl of T80a is + + signal CEN : std_logic; + signal Reset_s : std_logic; + signal IntCycle_n : std_logic; + signal IORQ : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal MREQ : std_logic; + signal MReq_Inhibit : std_logic; + signal Req_Inhibit : std_logic; + signal RD : std_logic; + signal MREQ_n_i : std_logic; + signal IORQ_n_i : std_logic; + signal RD_n_i : std_logic; + signal WR_n_i : std_logic; + signal RFSH_n_i : std_logic; + signal BUSAK_n_i : std_logic; + signal A_i : std_logic_vector(15 downto 0); + signal DO : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser + signal Wait_s : std_logic; + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + CEN <= '1'; + + BUSAK_n <= BUSAK_n_i; + MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); + RD_n_i <= not RD or Req_Inhibit; + + MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; + IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; + RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; + WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; + RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; + A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); + D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + Reset_s <= '0'; + elsif CLK_n'event and CLK_n = '1' then + Reset_s <= '1'; + end if; + end process; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 1) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n_i, + HALT_n => HALT_n, + WAIT_n => Wait_s, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => Reset_s, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n_i, + CLK_n => CLK_n, + A => A_i, + DInst => D, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + + SavePC => SavePC, + SaveINT => SaveINT, + RestorePC => RestorePC, + RestoreINT => RestoreINT, + + RestorePC_n => RestorePC_n ); + + process (CLK_n) + begin + if CLK_n'event and CLK_n = '0' then + Wait_s <= WAIT_n; + if TState = "011" and BUSAK_n_i = '1' then + DI_Reg <= to_x01(D); + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + WR_n_i <= '1'; + elsif CLK_n'event and CLK_n = '1' then + WR_n_i <= '1'; + if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! + WR_n_i <= not Write; + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + Req_Inhibit <= '0'; + elsif CLK_n'event and CLK_n = '1' then + if MCycle = "001" and TState = "010" then + Req_Inhibit <= '1'; + else + Req_Inhibit <= '0'; + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + MReq_Inhibit <= '0'; + elsif CLK_n'event and CLK_n = '0' then + if MCycle = "001" and TState = "010" then + MReq_Inhibit <= '1'; + else + MReq_Inhibit <= '0'; + end if; + end if; + end process; + + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + RD <= '0'; + MREQ <= '0'; + elsif CLK_n'event and CLK_n = '0' then + + if MCycle = "001" then + if TState = "001" then + RD <= IntCycle_n; + MREQ <= IntCycle_n; + end if; + if TState = "011" then + RD <= '0'; + MREQ <= '1'; + end if; + if TState = "100" then + MREQ <= '0'; + end if; + else + if TState = "001" and NoRead = '0' then + RD <= not Write; + MREQ <= not IORQ; + end if; + if TState = "011" then + RD <= '0'; + MREQ <= '0'; + end if; + end if; + end if; + end process; + + -- IORQ_n_i uses a different timming than MREQ. + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + IORQ_n_i <= '1'; + elsif CLK_n'event and CLK_n = '1' then + if MCycle = "001" then + if TState = "001" then + IORQ_n_i <= IntCycle_n; + end if; + if TState = "011" then + IORQ_n_i <= '1'; + end if; + else + if TState = "001" then + IORQ_n_i <= not IORQ; + end if; + if TState = "011" then + IORQ_n_i <= '1'; + end if; + end if; + end if; + end process; +end; diff --git a/cores/JupiterAce/ace.hex b/cores/JupiterAce/ace.hex new file mode 100644 index 0000000..fcc8b10 --- /dev/null +++ b/cores/JupiterAce/ace.hex @@ -0,0 +1,8192 @@ +F3 +21 +00 +3C +3E +FC +18 +20 +D9 +DD +CB +3E +5E +C3 +EE +03 +2A +3B +3C +73 +23 +C3 +5F +08 +2A +3B +3C +2B +56 +C3 +59 +08 +E1 +7E +32 +3D +3C +C3 +AD +00 +24 +77 +BE +28 +FB +A4 +67 +22 +18 +3C +F9 +21 +0D +01 +18 +03 +C3 +3A +01 +11 +24 +3C +01 +2D +00 +ED +B0 +DD +21 +00 +3C +FD +21 +C8 +04 +CD +24 +0A +AF +32 +00 +27 +21 +00 +2C +7D +E6 +BF +0F +0F +0F +30 +02 +0F +0F +0F +47 +9F +CB +18 +47 +9F +A8 +E6 +F0 +A8 +77 +2C +20 +E7 +11 +FF +2F +21 +FB +1F +01 +08 +00 +ED +B8 +EB +3E +5F +0E +07 +CB +6F +28 +03 +70 +2B +0D +EB +ED +B8 +EB +70 +2B +3D +20 +EE +ED +56 +18 +09 +51 +55 +49 +D4 +00 +00 +04 +9B +00 +ED +7B +18 +3C +FB +C3 +F2 +04 +41 +42 +4F +52 +D4 +98 +00 +05 +AD +00 +FD +E5 +FD +21 +B9 +04 +2A +37 +3C +22 +3B +3C +21 +3E +3C +7E +E6 +B3 +CB +56 +77 +28 +1A +CD +B9 +04 +90 +04 +B3 +08 +4B +10 +05 +D2 +0D +6B +08 +10 +16 +B5 +15 +11 +10 +37 +3C +C1 +08 +0E +1A +DD +CB +3D +7E +20 +1B +CD +08 +18 +45 +52 +52 +4F +D2 +CD +B9 +04 +11 +10 +3D +3C +96 +08 +B3 +09 +95 +0A +0E +1A +DD +36 +3D +FF +2A +37 +3C +01 +0C +00 +09 +22 +3B +3C +FD +E1 +18 +8E +E0 +26 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +4C +3C +4C +3C +4F +3C +51 +3C +45 +3C +5D +3C +FF +00 +0A +46 +4F +52 +54 +C8 +00 +00 +FF +1F +05 +B5 +11 +49 +3C +00 +00 +00 +F5 +08 +F5 +C5 +D5 +E5 +06 +3E +10 +FE +21 +2B +3C +34 +23 +28 +FC +CD +10 +03 +21 +28 +3C +CB +46 +28 +21 +A7 +28 +1E +FE +20 +38 +14 +CB +4E +C4 +07 +08 +CB +56 +28 +02 +E6 +9F +CB +5E +28 +02 +F6 +80 +CD +96 +01 +CD +E6 +01 +CD +82 +02 +E1 +D1 +C1 +F1 +08 +F1 +FB +C9 +FE +0D +20 +14 +21 +00 +27 +22 +22 +3C +22 +20 +3C +AF +CD +98 +01 +21 +E0 +26 +22 +1E +3C +C9 +A7 +C8 +08 +2A +22 +3C +7E +A7 +28 +06 +11 +00 +D9 +19 +30 +28 +ED +5B +24 +3C +21 +A0 +DB +19 +30 +34 +2A +1C +3C +01 +20 +00 +09 +ED +52 +D5 +D4 +21 +04 +CD +B0 +02 +D1 +CD +2F +04 +21 +1E +3C +06 +04 +CD +43 +04 +10 +FB +CD +02 +03 +54 +5D +23 +22 +22 +3C +2B +2B +28 +02 +ED +B8 +08 +12 +13 +ED +53 +20 +3C +AF +C9 +21 +F0 +01 +16 +00 +5F +19 +5E +19 +E9 +20 +13 +0C +1E +0A +37 +1A +50 +06 +9C +C9 +15 +14 +D3 +21 +28 +3C +AE +77 +C9 +2A +20 +3C +2B +7E +A7 +C8 +22 +20 +3C +23 +77 +C9 +2A +20 +3C +23 +ED +5B +22 +3C +A7 +ED +52 +C8 +19 +22 +20 +3C +7E +2B +77 +C9 +2A +20 +3C +23 +22 +20 +3C +CD +02 +03 +62 +6B +1B +1A +A7 +C8 +ED +53 +20 +3C +78 +B1 +28 +02 +ED +B0 +2B +36 +20 +22 +22 +3C +0C +C9 +CD +04 +02 +28 +08 +06 +1F +CD +04 +02 +10 +FB +C9 +2A +1E +3C +ED +5B +24 +3C +A7 +ED +52 +C8 +CD +25 +02 +2A +1E +3C +11 +E0 +FF +AF +19 +BE +20 +FC +22 +1E +3C +CD +F4 +02 +22 +20 +3C +3E +A0 +CD +7E +01 +2A +20 +3C +2B +22 +20 +3C +2A +20 +3C +3A +28 +3C +1F +36 +97 +1F +30 +02 +36 +C3 +1F +D0 +36 +C7 +C9 +CD +11 +02 +28 +08 +06 +1F +CD +11 +02 +10 +FB +C9 +CD +B0 +02 +E0 +E5 +CD +25 +02 +E1 +CD +ED +02 +18 +C6 +21 +00 +27 +ED +5B +1E +3C +A7 +ED +52 +44 +4D +EB +23 +AF +ED +B1 +2B +C9 +2A +22 +3C +2B +22 +20 +3C +CD +2C +02 +20 +FB +C9 +21 +28 +3C +CB +EE +CB +86 +C9 +21 +00 +27 +ED +5B +24 +3C +CD +FA +07 +21 +E0 +26 +22 +24 +3C +36 +00 +2A +24 +3C +22 +1E +3C +23 +22 +20 +3C +CD +B0 +02 +3E +20 +2B +BE +28 +FC +23 +22 +22 +3C +C9 +2A +22 +3C +ED +5B +20 +3C +A7 +ED +52 +44 +4D +19 +C9 +CD +36 +03 +47 +2A +26 +3C +AD +28 +0B +AD +28 +03 +AF +BD +C0 +68 +26 +20 +18 +0D +25 +7C +FE +1E +28 +06 +AF +BC +20 +03 +26 +04 +7D +22 +26 +3C +C9 +01 +FE +FE +ED +50 +5A +CB +3A +9F +E6 +D8 +CB +3A +38 +02 +3E +28 +C6 +57 +6F +7B +F6 +03 +1E +FF +2F +E6 +1F +57 +28 +0D +7D +1C +20 +12 +D6 +08 +CB +3A +30 +FA +5F +20 +09 +2D +CB +00 +30 +06 +ED +78 +18 +E4 +1E +FF +7B +3C +C8 +21 +76 +03 +19 +7E +C9 +76 +68 +79 +36 +35 +74 +67 +63 +62 +6A +75 +37 +34 +72 +66 +78 +6E +6B +69 +38 +33 +65 +64 +7A +6D +6C +6F +39 +32 +77 +73 +00 +20 +0D +70 +30 +31 +71 +61 +00 +56 +48 +59 +07 +01 +54 +47 +43 +42 +4A +55 +09 +08 +52 +46 +58 +4E +4B +49 +03 +33 +45 +44 +5A +4D +4C +4F +04 +02 +57 +53 +00 +20 +0D +50 +05 +0A +51 +41 +00 +2F +5E +5B +26 +25 +3E +7D +3F +2A +2D +5D +27 +24 +3C +7B +60 +2C +2B +7F +28 +23 +45 +5C +3A +2E +3D +3B +29 +40 +57 +7C +00 +20 +0D +22 +5F +21 +51 +7E +00 +28 +05 +CD +7E +01 +D9 +C9 +47 +2A +29 +3C +7C +B5 +78 +28 +01 +E9 +2A +1C +3C +ED +5B +24 +3C +EB +37 +ED +52 +EB +DC +21 +04 +FE +0D +28 +04 +77 +23 +18 +06 +23 +7D +E6 +1F +20 +FA +22 +1C +3C +D9 +C9 +F5 +21 +1C +3C +CD +43 +04 +F1 +2A +24 +3C +11 +20 +24 +A7 +ED +52 +44 +4D +21 +E0 +FF +19 +EB +ED +B0 +06 +20 +2B +36 +20 +10 +FB +C9 +7E +D6 +20 +77 +23 +30 +01 +35 +23 +C9 +EB +5E +16 +00 +21 +00 +3C +19 +EB +D7 +FD +E9 +48 +45 +52 +C5 +AA +00 +04 +62 +04 +ED +5B +37 +3C +D7 +FD +E9 +43 +4F +4E +54 +45 +58 +D4 +5F +04 +07 +4D +04 +33 +43 +55 +52 +52 +45 +4E +D4 +72 +04 +07 +4D +04 +31 +42 +41 +53 +C5 +7F +04 +04 +4D +04 +3F +4D +04 +3E +4D +04 +39 +50 +41 +C4 +89 +04 +03 +F5 +0F +01 +27 +BB +98 +04 +41 +08 +11 +B6 +04 +D8 +12 +0A +0E +1A +21 +3E +3C +7E +E6 +BB +77 +FD +E9 +00 +E8 +FF +B8 +04 +E1 +E1 +5E +23 +56 +23 +E5 +EB +5E +23 +56 +23 +EB +E9 +C8 +04 +01 +0B +00 +ED +5B +3B +3C +2A +37 +3C +09 +ED +52 +38 +02 +E7 +02 +01 +00 +00 +CD +8C +0F +CD +E4 +04 +18 +D5 +3E +FE +DB +FE +1F +D8 +3E +7F +DB +FE +1F +D8 +E7 +03 +CD +B9 +04 +8C +05 +06 +05 +36 +05 +76 +12 +F7 +FF +4C +49 +4E +C5 +A0 +04 +04 +C3 +0E +C6 +04 +3D +06 +EE +08 +83 +12 +07 +00 +4F +05 +76 +12 +F1 +FF +A9 +06 +EE +08 +83 +12 +07 +00 +64 +05 +76 +12 +E3 +FF +1B +06 +1A +0C +83 +12 +03 +00 +B6 +04 +78 +05 +76 +12 +D3 +FF +38 +05 +3A +3E +3C +CB +77 +20 +0E +CB +67 +20 +0A +CD +08 +18 +20 +4F +4B +A0 +3E +0D +CF +FD +E9 +51 +05 +DF +1B +1A +2F +DD +A6 +3E +E6 +40 +13 +28 +04 +D7 +11 +4E +0F +C3 +BF +04 +66 +05 +DF +DD +CB +3E +76 +20 +F4 +FD +E9 +52 +45 +54 +59 +50 +C5 +8B +05 +06 +7A +05 +CD +EA +02 +CD +76 +02 +36 +BF +18 +10 +51 +55 +45 +52 +D9 +05 +05 +05 +8E +05 +CD +D8 +02 +CD +76 +02 +21 +28 +3C +CB +C6 +CB +AE +CB +6E +28 +FC +CD +25 +02 +FD +E9 +57 +4F +52 +C4 +77 +05 +04 +AD +05 +DF +21 +FE +27 +06 +FD +36 +20 +2B +10 +FB +D5 +EB +D7 +D1 +CD +E1 +05 +04 +05 +28 +03 +01 +FF +00 +21 +01 +27 +71 +23 +3E +FC +B9 +30 +01 +4F +0C +D5 +C5 +EB +ED +B0 +C1 +D1 +0D +CD +DA +07 +FD +E9 +1E +20 +2A +24 +3C +22 +1E +3C +01 +00 +00 +23 +7E +BB +28 +FB +A7 +28 +0E +E5 +03 +23 +7E +A7 +28 +03 +BB +20 +F7 +D1 +AF +B8 +C9 +D5 +CD +B0 +02 +E2 +14 +06 +ED +5B +24 +3C +CD +FA +07 +22 +24 +3C +D1 +18 +CD +EB +C1 +01 +00 +00 +37 +C9 +1D +06 +CD +DF +05 +50 +59 +D7 +FD +E9 +56 +4C +49 +53 +D4 +AA +05 +05 +2F +06 +3E +0D +CF +0E +00 +18 +0E +46 +49 +4E +C4 +2C +06 +04 +3F +06 +CD +DF +05 +38 +46 +2A +33 +3C +7E +23 +66 +6F +7E +E6 +3F +28 +2F +A9 +28 +04 +79 +A7 +20 +28 +D5 +E5 +CD +E8 +15 +B1 +28 +17 +41 +1A +CD +07 +08 +13 +AE +E6 +7F +23 +20 +12 +10 +F3 +D1 +13 +D7 +D1 +CD +DA +07 +FD +E9 +CD +FB +17 +76 +CD +E4 +04 +E1 +D1 +2B +7E +2B +6E +67 +B5 +20 +C4 +C3 +8A +06 +11 +00 +00 +D7 +FD +E9 +45 +58 +45 +43 +55 +54 +C5 +3C +06 +07 +9C +06 +DF +C3 +BF +04 +4E +55 +4D +42 +45 +D2 +99 +06 +06 +AB +06 +CD +DF +05 +38 +DA +C5 +D5 +CD +4C +07 +20 +05 +11 +06 +10 +18 +58 +DF +11 +00 +00 +D7 +11 +00 +45 +C1 +C5 +0A +FE +2D +20 +03 +16 +C5 +03 +D7 +50 +59 +2B +2B +CD +23 +07 +23 +34 +2B +30 +F8 +FE +FE +20 +3D +CD +23 +07 +30 +FB +C6 +30 +CD +7B +07 +20 +04 +1E +00 +18 +0E +E6 +DF +FE +45 +20 +27 +E5 +CD +4C +07 +DF +E1 +20 +1F +CD +40 +07 +28 +0F +23 +7E +E6 +7F +83 +FA +1C +07 +28 +10 +AE +E6 +7F +AE +77 +11 +55 +10 +D7 +D1 +C1 +CD +DA +07 +FD +E9 +E1 +E1 +DF +DF +C3 +8A +06 +1A +13 +D6 +30 +D8 +FE +0A +3F +D8 +4F +7E +E6 +F0 +C0 +79 +2B +2B +0E +03 +ED +6F +23 +0D +20 +FA +35 +2B +BF +C9 +06 +06 +AF +CD +2C +07 +C0 +10 +F9 +23 +70 +C9 +D7 +CD +B9 +04 +6B +08 +96 +08 +4B +10 +2D +4A +0C +6B +08 +A9 +0D +D2 +08 +D2 +0D +1F +0E +88 +06 +88 +06 +FF +08 +8A +07 +FF +08 +DF +08 +94 +0D +FF +08 +79 +08 +85 +08 +0E +1A +DF +1A +FE +20 +C8 +A7 +C9 +43 +4F +4E +56 +45 +52 +D4 +A8 +06 +07 +C3 +0E +09 +0E +6B +08 +D2 +08 +96 +08 +B8 +07 +83 +12 +1B +00 +85 +08 +8A +04 +96 +08 +A8 +0C +79 +08 +FF +08 +8A +04 +96 +08 +A8 +0C +EE +0D +DF +08 +76 +12 +D9 +FF +DF +08 +B6 +04 +BA +07 +DF +7B +CD +07 +08 +C6 +D0 +30 +14 +FE +0A +38 +06 +C6 +EF +30 +0C +C6 +0A +DD +BE +3F +30 +05 +16 +00 +5F +D7 +37 +C3 +21 +0C +62 +6B +03 +09 +E5 +DD +CB +3E +66 +CC +7F +09 +CD +B0 +02 +D1 +A7 +ED +52 +44 +4D +2A +1E +3C +23 +EB +38 +05 +28 +02 +ED +B0 +A7 +ED +52 +EB +7A +B3 +C8 +36 +20 +23 +1B +18 +F7 +E6 +7F +FE +61 +D8 +FE +7B +D0 +E6 +5F +C9 +56 +49 +D3 +89 +07 +03 +1A +08 +DD +CB +3E +A6 +FD +E9 +49 +4E +56 +49 +D3 +17 +08 +05 +2A +08 +DD +CB +3E +E6 +FD +E9 +46 +41 +53 +D4 +27 +08 +04 +39 +08 +FD +21 +B9 +04 +FD +E9 +53 +4C +4F +D7 +36 +08 +04 +48 +08 +FD +21 +C8 +04 +FD +E9 +2A +3B +3C +2B +46 +2B +4E +22 +3B +3C +C9 +2B +5E +22 +3B +3C +C9 +72 +23 +22 +3B +3C +C9 +44 +55 +D0 +45 +08 +03 +6D +08 +DF +D7 +D7 +FD +E9 +44 +52 +4F +D0 +6A +08 +04 +7B +08 +DF +FD +E9 +53 +57 +41 +D0 +78 +08 +04 +87 +08 +DF +CD +4E +08 +D7 +50 +59 +D7 +FD +E9 +43 +C0 +84 +08 +02 +98 +08 +DF +1A +5F +16 +00 +D7 +FD +E9 +43 +A1 +95 +08 +02 +A7 +08 +DF +CD +4E +08 +79 +12 +FD +E9 +C0 +A4 +08 +01 +B5 +08 +DF +EB +5E +23 +56 +D7 +FD +E9 +A1 +B2 +08 +01 +C3 +08 +DF +CD +4E +08 +EB +71 +23 +70 +FD +E9 +3E +D2 +C0 +08 +02 +D4 +08 +DF +C1 +D5 +C5 +FD +E9 +52 +BE +D1 +08 +02 +E1 +08 +C1 +D1 +C5 +D7 +FD +E9 +3F +44 +55 +D0 +DE +08 +04 +F0 +08 +DF +D7 +7A +B3 +C4 +10 +00 +FD +E9 +52 +4F +D4 +ED +08 +03 +C3 +0E +D2 +08 +85 +08 +DF +08 +85 +08 +B6 +04 +4F +56 +45 +D2 +FE +08 +04 +C3 +0E +D2 +08 +6B +08 +DF +08 +85 +08 +B6 +04 +50 +49 +43 +CB +11 +09 +04 +27 +09 +CD +4D +09 +FD +E9 +52 +4F +4C +CC +24 +09 +04 +35 +09 +CD +4D +09 +EB +2A +37 +3C +ED +52 +D2 +D7 +04 +62 +6B +23 +23 +ED +B0 +ED +53 +3B +3C +FD +E9 +CD +4E +08 +0B +CB +21 +CB +10 +03 +03 +30 +02 +E7 +07 +2A +3B +3C +ED +42 +E5 +5E +23 +56 +D7 +E1 +C9 +54 +59 +50 +C5 +32 +09 +04 +70 +09 +CD +4E +08 +DF +CD +7F +09 +FD +E9 +1A +4F +13 +1A +47 +13 +78 +B1 +C8 +1A +13 +0B +CF +18 +F7 +3C +A3 +6D +09 +02 +8F +09 +21 +FF +27 +22 +1A +3C +FD +E9 +23 +BE +8C +09 +02 +9E +09 +DF +DF +ED +5B +1A +3C +D7 +21 +FF +27 +A7 +ED +52 +EB +D7 +FD +E9 +AE +49 +0A +01 +C3 +0E +8D +09 +6B +08 +0D +0C +88 +06 +E1 +09 +FF +08 +4A +0A +9C +09 +6E +09 +73 +0A +B6 +04 +55 +AE +B2 +09 +02 +C3 +0E +88 +06 +8D +09 +E1 +09 +76 +12 +E8 +FF +23 +D3 +CF +09 +02 +C3 +0E +F7 +09 +12 +09 +12 +09 +36 +0E +1A +0C +8D +12 +F3 +FF +B6 +04 +A3 +E0 +09 +01 +C3 +0E +8A +04 +96 +08 +C4 +0C +FF +08 +07 +0A +5C +0A +B6 +04 +09 +0A +DF +7B +C6 +30 +FE +3A +38 +02 +C6 +07 +5F +D7 +FD +E9 +43 +4C +D3 +F6 +09 +03 +1F +0A +CD +24 +0A +FD +E9 +11 +FF +26 +2A +24 +3C +01 +20 +00 +09 +2B +ED +B8 +ED +43 +2F +3C +21 +00 +24 +22 +1C +3C +13 +EB +22 +24 +3C +C3 +FA +07 +53 +49 +47 +CE +9B +09 +04 +4C +0A +DF +CB +12 +1E +2D +38 +0C +FD +E9 +48 +4F +4C +C4 +1C +0A +04 +5E +0A +DF +2A +1A +3C +2D +28 +04 +22 +1A +3C +73 +FD +E9 +53 +50 +41 +43 +C5 +5B +0A +05 +75 +0A +3E +20 +CF +FD +E9 +53 +50 +41 +43 +45 +D3 +72 +0A +06 +85 +0A +DF +1B +CB +7A +20 +ED +3E +20 +CF +18 +F6 +43 +D2 +82 +0A +02 +97 +0A +3E +0D +CF +FD +E9 +45 +4D +49 +D4 +94 +0A +04 +A5 +0A +DF +7B +CF +FD +E9 +46 +AE +A2 +0A +02 +B1 +0A +2A +3B +3C +2B +CB +7E +CB +BE +28 +03 +3E +2D +CF +1E +00 +7E +3D +FE +49 +30 +04 +FE +3C +30 +04 +36 +41 +3C +5F +3E +40 +96 +38 +09 +47 +04 +3E +2E +CF +3E +30 +10 +FB +3E +40 +BE +9F +2B +B6 +2B +B6 +2B +B6 +23 +23 +28 +12 +AF +CD +32 +07 +C6 +30 +CF +23 +7E +FE +40 +20 +E5 +3E +2E +CF +18 +E0 +7B +A7 +20 +05 +3E +20 +CF +18 +0B +D6 +41 +6F +9F +67 +3E +45 +CF +CD +0E +18 +DF +DF +FD +E9 +41 +D4 +AE +0A +02 +1B +0B +DF +CD +4E +08 +79 +CD +28 +0B +22 +1C +3C +FD +E9 +C6 +20 +6F +26 +01 +29 +29 +29 +29 +29 +16 +00 +7B +E6 +1F +5F +19 +ED +5B +24 +3C +ED +52 +19 +D8 +E7 +09 +50 +4C +4F +D4 +18 +0B +04 +4C +0B +CD +4E +08 +DF +DD +73 +30 +CB +3B +CB +11 +3E +16 +93 +DF +DD +73 +2F +CB +3B +CB +11 +CD +28 +0B +7E +E6 +78 +FE +10 +7E +28 +02 +3E +10 +5F +16 +87 +79 +E6 +03 +47 +28 +07 +2F +C6 +02 +CE +03 +57 +43 +79 +0F +0F +0F +9F +CB +59 +20 +04 +AB +07 +9F +A8 +A2 +AB +77 +FD +E9 +42 +45 +45 +D0 +49 +0B +04 +C3 +0E +12 +09 +4B +10 +7D +85 +08 +7A +0D +0E +1A +DF +CD +4E +08 +21 +F9 +00 +09 +2C +F3 +3E +7F +DB +FE +0F +30 +11 +CD +C9 +0B +1B +7A +D3 +FE +CD +C9 +0B +B3 +C2 +AF +0B +FB +FD +E9 +E7 +03 +45 +4C +10 +FE +05 +0D +C2 +CB +0B +C9 +49 +4E +4B +45 +D9 +97 +0B +05 +DD +0B +CD +36 +03 +5F +16 +00 +D7 +FD +E9 +49 +CE +DA +0B +02 +ED +0B +CD +4E +08 +16 +00 +ED +58 +D7 +FD +E9 +4F +55 +D4 +EA +0B +03 +FF +0B +CD +4E +08 +DF +ED +59 +FD +E9 +41 +42 +D3 +FC +0B +03 +C3 +0E +6B +08 +94 +0D +B6 +04 +30 +BD +0C +0C +02 +1C +0C +DF +7A +B3 +FE +01 +3E +00 +57 +17 +5F +D7 +FD +E9 +30 +BC +19 +0C +02 +30 +0C +DF +CB +12 +18 +EC +30 +BE +2D +0C +02 +3C +0C +DF +7A +B3 +28 +E0 +CB +12 +3F +18 +DB +BD +39 +0C +01 +C3 +0E +E1 +0D +1A +0C +B6 +04 +BE +49 +0C +01 +58 +0C +DF +D5 +DF +E1 +CD +99 +0C +18 +C0 +BC +55 +0C +01 +C3 +0E +85 +08 +56 +0C +B6 +04 +55 +BC +64 +0C +02 +74 +0C +CD +4E +08 +DF +EB +A7 +ED +42 +18 +A3 +44 +BC +71 +0C +02 +85 +0C +DF +D5 +CD +4E +08 +DF +E1 +A7 +ED +52 +28 +E6 +19 +EB +CD +99 +0C +DF +18 +88 +7C +AA +FA +A0 +0C +ED +52 +CB +14 +C9 +55 +AA +82 +0C +02 +AA +0C +DF +CD +4E +08 +21 +00 +00 +3E +10 +29 +EB +ED +6A +EB +30 +04 +09 +30 +01 +13 +3D +20 +F2 +EB +18 +2F +C6 +0C +DF +D9 +DF +D5 +DF +E1 +7C +B5 +3E +21 +20 +03 +EB +3E +11 +D9 +47 +AF +67 +6F +4F +ED +6A +9F +A7 +ED +52 +99 +30 +01 +19 +3F +D9 +EB +ED +6A +EB +ED +6A +D9 +10 +EB +EB +D7 +D9 +E5 +D7 +D1 +D7 +FD +E9 +2F +4D +4F +C4 +A7 +0C +04 +C3 +0E +85 +08 +D2 +08 +E9 +12 +0D +0C +4B +10 +00 +FF +08 +6B +08 +E9 +12 +60 +0E +D2 +08 +0D +0C +8C +0D +DF +08 +94 +0D +85 +08 +DF +08 +94 +0D +85 +08 +B6 +04 +2A +2F +4D +4F +C4 +FF +0C +05 +C3 +0E +FF +08 +D2 +08 +E9 +12 +0D +0C +FF +08 +6B +08 +DF +08 +60 +0E +D2 +08 +0D +0C +A8 +0C +76 +12 +C1 +FF +AF +30 +0D +01 +C3 +0E +00 +0D +85 +08 +79 +08 +B6 +04 +4D +4F +C4 +50 +0D +03 +C3 +0E +00 +0D +79 +08 +B6 +04 +AA +60 +0D +01 +C3 +0E +A8 +0C +79 +08 +B6 +04 +2A +AF +6C +0D +02 +C3 +0E +31 +0D +85 +08 +79 +08 +B6 +04 +55 +2F +4D +4F +C4 +79 +0D +05 +C3 +0E +C4 +0C +79 +08 +B6 +04 +C3 +0E +2E +0C +83 +12 +03 +00 +A9 +0D +B6 +04 +4E +45 +47 +41 +54 +C5 +8B +0D +06 +AB +0D +01 +02 +00 +18 +0F +44 +4E +45 +47 +41 +54 +C5 +A8 +0D +07 +BC +0D +01 +04 +00 +2A +3B +3C +A7 +ED +42 +78 +9E +77 +23 +0D +20 +F9 +FD +E9 +AB +B9 +0D +01 +D4 +0D +DF +D5 +DF +E1 +19 +EB +D7 +FD +E9 +AD +D1 +0D +01 +C3 +0E +A9 +0D +D2 +0D +B6 +04 +44 +AB +E0 +0D +02 +F0 +0D +DF +D5 +CD +4E +08 +DF +D5 +DF +EB +09 +EB +D7 +C1 +E1 +ED +4A +EB +D7 +FD +E9 +31 +AB +ED +0D +02 +0B +0E +DF +18 +09 +32 +AB +08 +0E +02 +15 +0E +DF +13 +13 +18 +14 +31 +AD +12 +0E +02 +21 +0E +DF +18 +09 +32 +AD +1E +0E +02 +2B +0E +DF +1B +1B +D7 +FD +E9 +4F +D2 +28 +0E +02 +38 +0E +DF +CD +4E +08 +7B +B1 +5F +7A +B0 +57 +D7 +FD +E9 +41 +4E +C4 +35 +0E +03 +4D +0E +DF +CD +4E +08 +7B +A1 +5F +7A +A0 +57 +D7 +FD +E9 +58 +4F +D2 +4A +0E +03 +62 +0E +DF +CD +4E +08 +7B +A9 +5F +7A +A8 +57 +D7 +FD +E9 +4D +41 +D8 +5F +0E +03 +C3 +0E +12 +09 +12 +09 +65 +0C +71 +12 +0F +00 +4D +49 +CE +74 +0E +03 +C3 +0E +12 +09 +12 +09 +56 +0C +83 +12 +03 +00 +85 +08 +79 +08 +B6 +04 +44 +45 +43 +49 +4D +41 +CC +86 +0E +07 +A5 +0E +DD +36 +3F +0A +FD +E9 +BA +A2 +0E +01 +85 +10 +C3 +0E +4B +10 +0A +0E +1A +21 +3E +3C +7E +F6 +44 +77 +FD +E9 +E9 +FF +EB +C3 +BA +04 +43 +52 +45 +41 +54 +C5 +AE +0E +06 +C3 +0E +4B +10 +20 +AB +05 +FB +0E +88 +06 +4E +0F +80 +04 +B3 +08 +6B +08 +B3 +08 +4E +0F +60 +04 +85 +08 +C1 +08 +99 +04 +96 +08 +5F +0F +11 +10 +EC +0F +4E +0F +B6 +04 +FD +0E +CD +2E +0F +DF +1A +3D +FE +3F +38 +02 +E7 +06 +C6 +08 +4F +06 +00 +CD +8C +0F +1A +4F +2A +37 +3C +D5 +CD +9E +0F +D1 +1A +47 +13 +1A +CD +07 +08 +77 +23 +10 +F7 +22 +39 +3C +2B +CB +FE +FD +E9 +DD +CB +3E +56 +28 +02 +E7 +0C +2A +37 +3C +ED +5B +39 +3C +AF +ED +52 +EB +73 +23 +72 +67 +6F +22 +39 +3C +C9 +AC +CF +0E +01 +C3 +0E +83 +0F +60 +04 +29 +0E +C1 +08 +B6 +04 +43 +AC +4D +0F +02 +C3 +0E +4B +10 +01 +76 +0F +60 +04 +1F +0E +A5 +08 +B6 +04 +41 +4C +4C +4F +D4 +5E +0F +05 +78 +0F +CD +4E +08 +2A +37 +3C +CD +9E +0F +FD +E9 +C3 +0E +4B +10 +02 +76 +0F +B6 +04 +21 +1E +00 +C5 +09 +ED +4B +3B +3C +09 +C1 +38 +03 +ED +72 +D8 +E7 +01 +EB +21 +28 +00 +CD +8F +0F +2A +37 +3C +09 +22 +37 +3C +2A +3B +3C +E5 +09 +22 +3B +3C +E3 +E5 +A7 +ED +52 +44 +4D +E1 +D1 +C8 +2B +1B +ED +B8 +23 +C9 +56 +41 +52 +49 +41 +42 +4C +C5 +75 +0F +08 +85 +10 +F0 +0F +4E +0F +B6 +04 +43 +4F +4E +53 +54 +41 +4E +D4 +CE +0F +08 +85 +10 +F5 +0F +4E +0F +B6 +04 +DC +FE +18 +02 +D5 +FF +D7 +FD +E9 +E3 +FF +EB +5E +23 +56 +D7 +FD +E9 +4C +49 +54 +45 +52 +41 +CC +E1 +0F +47 +08 +11 +11 +10 +4E +0F +B6 +04 +02 +FF +FF +13 +10 +06 +01 +E1 +5E +23 +56 +23 +E5 +D7 +10 +F7 +FD +E9 +41 +53 +43 +49 +C9 +05 +10 +45 +C3 +0E +4B +10 +20 +AB +05 +09 +0E +96 +08 +0E +1A +DD +CB +3E +76 +28 +E3 +CD +B9 +04 +11 +10 +4B +10 +4E +0F +5F +0F +B6 +04 +01 +D6 +FF +4D +10 +E1 +5E +16 +00 +06 +01 +18 +C4 +08 +11 +64 +10 +85 +08 +4E +0F +4E +0F +B6 +04 +04 +FF +FF +66 +10 +06 +02 +18 +AB +44 +45 +46 +49 +4E +45 +D2 +27 +10 +07 +85 +10 +85 +10 +60 +04 +4B +10 +0C +83 +0F +76 +12 +34 +FE +E6 +FF +CD +F0 +0F +D0 +0E +6B +08 +B3 +08 +60 +04 +29 +0E +C1 +08 +13 +0E +9A +10 +B6 +04 +9C +10 +DF +C3 +C3 +0E +43 +41 +4C +CC +73 +10 +04 +A9 +10 +DF +EB +E9 +44 +4F +45 +53 +BE +F4 +10 +45 +08 +11 +E8 +10 +D8 +12 +0C +CD +10 +4B +10 +CD +5F +0F +11 +10 +F0 +0F +4E +0F +4B +10 +0A +B6 +04 +C3 +0E +6B +08 +29 +0E +B5 +15 +60 +04 +E1 +0D +1F +0E +4E +0F +60 +04 +85 +08 +C1 +08 +B6 +04 +05 +C5 +FF +B8 +04 +43 +4F +4D +50 +49 +4C +45 +D2 +A6 +10 +08 +85 +10 +08 +11 +60 +11 +60 +04 +4B +10 +0B +83 +0F +76 +12 +B1 +FD +E3 +FF +DD +CB +3E +76 +20 +02 +E7 +04 +CD +F0 +0F +6B +08 +B3 +08 +4E +0F +76 +12 +78 +FF +52 +55 +4E +53 +BE +B3 +10 +45 +08 +11 +40 +11 +D8 +12 +0B +85 +08 +5F +0F +CD +10 +11 +10 +42 +11 +4E +0F +4B +10 +0A +B6 +04 +05 +DE +FF +B8 +04 +E1 +D5 +EB +D7 +42 +4B +D1 +D5 +1B +1B +CD +9E +15 +D1 +C5 +C3 +C3 +0E +49 +4D +4D +45 +44 +49 +41 +54 +C5 +24 +11 +09 +C3 +0E +80 +04 +B3 +08 +B3 +08 +0E +1A +DF +EB +CB +F6 +FD +E9 +56 +4F +43 +41 +42 +55 +4C +41 +52 +D9 +5F +11 +0A +85 +10 +B5 +11 +80 +04 +B3 +08 +13 +0E +4E +0F +88 +06 +5F +0F +60 +04 +11 +10 +35 +3C +6B +08 +B3 +08 +4E +0F +C1 +08 +B6 +04 +44 +45 +46 +49 +4E +49 +54 +49 +4F +4E +D3 +7C +11 +0B +AD +11 +2A +33 +3C +22 +31 +3C +FD +E9 +ED +53 +33 +3C +FD +E9 +49 +C6 +E0 +13 +42 +08 +11 +83 +12 +60 +04 +4B +10 +02 +83 +0F +B6 +04 +57 +48 +49 +4C +C5 +BF +11 +45 +08 +11 +88 +12 +D8 +12 +01 +60 +04 +4B +10 +04 +83 +0F +B6 +04 +45 +4C +53 +C5 +D4 +11 +44 +08 +11 +71 +12 +D8 +12 +02 +83 +0F +25 +12 +60 +04 +29 +0E +4B +10 +02 +B6 +04 +54 +48 +45 +CE +EB +11 +44 +08 +11 +A4 +12 +D8 +12 +02 +25 +12 +B6 +04 +42 +45 +47 +49 +CE +06 +12 +45 +08 +11 +9F +12 +60 +04 +4B +10 +01 +B6 +04 +C3 +0E +6B +08 +60 +04 +85 +08 +E1 +0D +1F +0E +85 +08 +C1 +08 +B6 +04 +C3 +0E +60 +04 +E1 +0D +1F +0E +4E +0F +B6 +04 +52 +45 +50 +45 +41 +D4 +19 +12 +46 +08 +11 +76 +12 +D8 +12 +04 +85 +08 +37 +12 +25 +12 +B6 +04 +55 +4E +54 +49 +CC +4B +12 +45 +08 +11 +8D +12 +D8 +12 +01 +37 +12 +B6 +04 +02 +75 +FF +78 +12 +02 +CE +FF +78 +12 +E1 +5E +23 +56 +19 +C3 +BA +04 +02 +39 +FF +8F +12 +02 +46 +FF +8F +12 +02 +CF +FF +8F +12 +CD +4E +08 +78 +B1 +28 +E2 +E1 +23 +23 +C3 +BA +04 +00 +74 +FF +B9 +04 +00 +5D +FF +B9 +04 +44 +CF +62 +12 +42 +08 +11 +23 +13 +60 +04 +4B +10 +03 +B6 +04 +4C +4F +4F +D0 +AA +12 +44 +08 +11 +32 +13 +D8 +12 +03 +37 +12 +B6 +04 +2B +4C +4F +4F +D0 +BC +12 +45 +08 +11 +3C +13 +76 +12 +EA +FF +DA +12 +DF +E1 +7E +23 +E5 +93 +B2 +28 +4A +E7 +05 +C9 +AA +11 +01 +EB +12 +C1 +D1 +D5 +C5 +D7 +FD +E9 +49 +A7 +E8 +12 +02 +F9 +12 +21 +04 +00 +18 +09 +CA +F6 +12 +01 +04 +13 +21 +06 +00 +39 +5E +23 +56 +D7 +FD +E9 +4C +45 +41 +56 +C5 +01 +13 +05 +18 +13 +C1 +E1 +E1 +E5 +E5 +C5 +FD +E9 +00 +84 +FF +25 +13 +CD +4E +08 +DF +E1 +D5 +C5 +E5 +FD +E9 +02 +85 +FF +34 +13 +11 +01 +00 +18 +06 +02 +8D +FF +3E +13 +DF +C1 +E1 +A7 +ED +5A +7A +D1 +37 +EA +58 +13 +D5 +E5 +07 +30 +01 +EB +CD +99 +0C +3F +30 +02 +E1 +E1 +C5 +9F +C3 +94 +12 +A8 +D4 +13 +41 +08 +11 +79 +13 +4B +10 +29 +60 +04 +85 +08 +83 +0F +9F +13 +85 +08 +C1 +08 +B6 +04 +FF +E5 +FF +7B +13 +E1 +5E +23 +56 +13 +C3 +7C +12 +2E +A2 +60 +13 +42 +08 +11 +96 +13 +4B +10 +22 +76 +12 +D6 +FF +FF +EE +FF +98 +13 +D1 +CD +79 +09 +D5 +FD +E9 +A1 +13 +DF +D5 +CD +E1 +05 +62 +6B +09 +7E +E1 +BD +28 +0A +EB +D7 +11 +78 +05 +CD +15 +18 +18 +E9 +D5 +C5 +2A +37 +3C +CD +9E +0F +C1 +D1 +D5 +C5 +EB +ED +B0 +C1 +50 +59 +D7 +D1 +CD +DA +07 +FD +E9 +DB +CF +12 +41 +D7 +13 +DD +CB +3E +B6 +FD +E9 +DD +15 +13 +01 +E3 +13 +DD +CB +3E +F6 +FD +E9 +45 +58 +49 +D4 +87 +13 +04 +B8 +04 +52 +45 +44 +45 +46 +49 +4E +C5 +EF +13 +08 +FF +13 +CD +2E +0F +2A +31 +3C +5E +23 +56 +EB +23 +22 +05 +27 +E5 +CD +C0 +15 +22 +0D +27 +ED +43 +07 +27 +ED +53 +0B +27 +2A +37 +3C +ED +52 +C2 +DA +14 +D1 +D7 +CD +B9 +04 +10 +16 +3D +06 +0E +1A +DF +21 +AF +C3 +19 +D2 +CF +14 +EB +22 +03 +27 +CD +C0 +15 +22 +01 +27 +E5 +ED +53 +09 +27 +78 +B1 +ED +5B +07 +27 +28 +04 +7A +B3 +28 +7D +E1 +ED +4B +0D +27 +ED +42 +EB +19 +22 +07 +27 +2A +0B +27 +19 +ED +4B +09 +27 +A7 +ED +42 +22 +0B +27 +01 +2E +00 +09 +CB +7C +20 +0B +ED +4B +3B +3C +09 +38 +54 +ED +72 +30 +50 +2A +03 +27 +E5 +2B +2B +46 +2B +4E +2A +05 +27 +E5 +2B +2B +70 +2B +71 +E1 +19 +C1 +A7 +ED +42 +22 +05 +27 +ED +5B +01 +27 +2A +09 +27 +A7 +ED +52 +44 +4D +D5 +C5 +CD +DC +14 +2A +0B +27 +C1 +09 +44 +4D +E1 +C5 +CD +9E +0F +EB +2A +0D +27 +ED +4B +0B +27 +09 +C1 +C5 +E5 +ED +B0 +D1 +C1 +CD +DC +14 +CD +F8 +14 +FD +E9 +2A +31 +3C +ED +5B +05 +27 +1B +73 +23 +72 +E7 +0B +2A +37 +3C +A7 +ED +42 +22 +37 +3C +2A +3B +3C +ED +42 +22 +3B +3C +ED +52 +C8 +C5 +44 +4D +E1 +19 +ED +B0 +C9 +01 +31 +3C +CD +57 +15 +CD +57 +15 +01 +40 +3C +2A +37 +3C +37 +ED +42 +D8 +0A +17 +03 +30 +FB +03 +03 +CD +57 +15 +03 +CD +57 +15 +CD +FB +15 +C3 +0E +1C +85 +10 +16 +08 +11 +13 +B5 +11 +18 +00 +00 +21 +F9 +FF +09 +4E +23 +46 +2B +09 +44 +4D +18 +CD +CD +57 +15 +CD +48 +15 +18 +C5 +CD +57 +15 +03 +CD +57 +15 +18 +BC +CD +57 +15 +21 +B6 +04 +A7 +ED +52 +C8 +CD +9E +15 +18 +F1 +0A +5F +03 +0A +57 +0B +CD +68 +15 +EB +7B +02 +03 +7A +02 +03 +C9 +2A +01 +27 +A7 +ED +52 +62 +6B +D0 +2A +09 +27 +ED +52 +30 +0C +2A +0D +27 +ED +52 +38 +13 +2A +0B +27 +19 +C9 +2A +03 +27 +ED +52 +2A +07 +27 +D8 +2A +05 +27 +19 +C9 +2A +01 +27 +19 +ED +5B +0D +27 +A7 +ED +52 +C9 +1B +1A +17 +D0 +1B +1B +1A +6F +26 +00 +3C +20 +06 +0A +6F +03 +0A +67 +03 +09 +44 +4D +C9 +B7 +15 +DF +EB +CD +E7 +15 +EB +D7 +FD +E9 +E5 +5E +23 +56 +CD +FB +15 +08 +11 +0B +85 +10 +08 +00 +00 +01 +00 +00 +18 +07 +E1 +E5 +23 +23 +4E +23 +46 +E1 +E5 +2B +2B +2B +2B +56 +2B +5E +19 +EB +E1 +2B +7C +FE +3C +7E +CB +B7 +38 +02 +C6 +02 +2B +2B +2B +3D +20 +FC +C9 +23 +E5 +E1 +7E +23 +E5 +66 +6F +B4 +C8 +ED +52 +E1 +23 +20 +F0 +D5 +16 +00 +5E +19 +D1 +E9 +C3 +0E +1F +0E +29 +0E +B3 +08 +80 +04 +B3 +08 +C1 +08 +B6 +04 +CD +B9 +04 +3D +06 +0E +1A +DF +21 +AF +C3 +19 +D8 +E7 +0D +46 +4F +52 +47 +45 +D4 +FC +13 +06 +3A +16 +2A +31 +3C +ED +5B +33 +3C +A7 +ED +52 +C2 +DA +14 +CD +20 +16 +21 +FB +FF +19 +22 +39 +3C +DD +CB +3E +D6 +E7 +FF +45 +44 +49 +D4 +37 +16 +04 +60 +16 +CD +20 +16 +DD +CB +3E +DE +18 +0C +4C +49 +53 +D4 +5D +16 +04 +72 +16 +CD +20 +16 +3E +0D +CF +DD +CB +3E +5E +D5 +C4 +D8 +02 +C1 +0A +5F +03 +0A +57 +0B +CD +FB +15 +C3 +0E +0B +08 +11 +0D +85 +10 +1F +00 +00 +E7 +0E +21 +02 +00 +18 +18 +D5 +21 +02 +00 +09 +7E +23 +66 +6F +2B +2B +2B +6E +7D +07 +9F +67 +CD +0E +18 +D1 +21 +04 +00 +09 +E5 +C5 +CD +E4 +17 +D1 +C1 +CD +E4 +17 +DD +36 +14 +01 +DD +36 +16 +10 +CD +08 +17 +38 +06 +DD +35 +16 +F2 +C7 +16 +DD +CB +3E +5E +20 +10 +38 +28 +21 +26 +3C +36 +00 +7E +A7 +28 +FC +CD +E4 +04 +18 +DB +F5 +DD +CB +3E +9E +C5 +CD +B9 +04 +78 +05 +06 +05 +0E +1A +DD +CB +3E +DE +CD +D8 +02 +C1 +F1 +30 +C1 +DD +CB +3E +9E +FD +E9 +3A +14 +3C +32 +15 +3C +DD +36 +13 +05 +0A +5F +03 +0A +57 +03 +CD +FB +15 +83 +12 +40 +71 +12 +44 +A4 +12 +48 +9F +12 +37 +8D +12 +42 +88 +12 +38 +76 +12 +3C +23 +13 +2B +32 +13 +36 +3C +13 +33 +E8 +10 +29 +40 +11 +26 +11 +10 +3B +64 +10 +47 +4B +10 +51 +79 +13 +62 +96 +13 +63 +B6 +04 +54 +00 +00 +CD +E1 +17 +DD +35 +13 +20 +B7 +A7 +C9 +2A +14 +3C +65 +2C +18 +0C +2A +14 +3C +65 +25 +18 +05 +2A +14 +3C +2D +65 +22 +14 +3C +DD +36 +13 +01 +DD +35 +16 +18 +D7 +CD +DA +17 +D7 +11 +B3 +09 +CD +C1 +17 +CD +15 +18 +18 +CB +CD +DA +17 +D7 +CD +DA +17 +D7 +11 +AF +0A +18 +EB +0A +F5 +CD +E1 +17 +F1 +CF +3E +20 +CF +18 +B2 +CD +08 +18 +0D +3B +8D +37 +C9 +3E +29 +18 +02 +3E +22 +F5 +C5 +CD +E1 +17 +D1 +CD +79 +09 +42 +4B +F1 +CF +A7 +C9 +3A +15 +3C +A7 +F8 +C5 +47 +3E +0D +CF +04 +05 +28 +05 +3E +20 +CF +10 +FB +DD +36 +15 +FF +C1 +C9 +0A +5F +03 +0A +57 +03 +C9 +CD +C1 +17 +EB +2B +7E +CB +7F +20 +05 +CD +E8 +15 +18 +0B +EB +CD +A2 +15 +13 +1A +6F +13 +1A +67 +19 +7E +E6 +7F +CF +CB +7E +23 +28 +F7 +3E +20 +CF +C9 +E3 +CD +FB +17 +E3 +C9 +11 +B3 +09 +D5 +EB +D7 +D1 +C5 +CD +BF +04 +1B +18 +1D +18 +C1 +C1 +C9 +FD +E5 +E5 +FD +E1 +21 +92 +18 +E5 +21 +00 +E0 +CB +79 +28 +02 +26 +FC +13 +FD +2B +F3 +AF +06 +97 +10 +FE +D3 +FE +EE +08 +2C +20 +01 +24 +20 +F2 +06 +2B +10 +FE +D3 +FE +69 +01 +08 +3B +10 +FE +79 +D3 +FE +06 +38 +C3 +8A +18 +79 +CB +78 +10 +FE +30 +04 +06 +3D +10 +FE +D3 +FE +06 +3A +C2 +59 +18 +05 +AF +CB +15 +C2 +5C +18 +1B +FD +23 +06 +2E +3E +7F +DB +FE +1F +D0 +7A +FE +FF +D0 +B3 +28 +0B +FD +6E +00 +7C +AD +67 +AF +37 +C3 +6D +18 +6C +18 +F5 +FD +E1 +08 +06 +3B +10 +FE +AF +D3 +FE +3E +7F +DB +FE +1F +FB +D2 +F0 +04 +08 +C9 +F3 +FD +E5 +E5 +FD +E1 +21 +92 +18 +E5 +61 +08 +AF +4F +C0 +2E +00 +06 +B8 +CD +11 +19 +30 +F6 +3E +DF +B8 +30 +F2 +2C +20 +F1 +06 +CF +CD +15 +19 +30 +E7 +78 +FE +D8 +30 +F4 +CD +15 +19 +D0 +CD +FC +18 +D0 +3F +C0 +18 +11 +08 +30 +05 +FD +75 +00 +18 +05 +FD +7E +00 +AD +C0 +FD +23 +1B +08 +CD +FC +18 +D0 +7A +B3 +20 +E7 +7C +FE +01 +C9 +2E +01 +06 +C7 +CD +11 +19 +D0 +3E +E2 +B8 +CB +15 +D2 +FE +18 +7C +AD +67 +37 +C9 +CD +15 +19 +D0 +3E +14 +3D +20 +FD +A7 +04 +C8 +3E +7F +DB +FE +1F +D0 +A9 +E6 +10 +28 +F3 +79 +2F +4F +37 +C9 +53 +41 +56 +C5 +6F +16 +04 +C3 +0E +10 +1A +4F +1A +B6 +04 +42 +53 +41 +56 +C5 +33 +19 +05 +C3 +0E +3D +1A +4F +1A +B6 +04 +42 +4C +4F +41 +C4 +43 +19 +05 +C3 +0E +3D +1A +74 +1A +B8 +1A +B6 +04 +56 +45 +52 +49 +46 +D9 +53 +19 +06 +C3 +0E +10 +1A +71 +12 +0F +00 +42 +56 +45 +52 +49 +46 +D9 +66 +19 +07 +C3 +0E +3D +1A +74 +1A +BE +1A +B6 +04 +4C +4F +41 +C4 +78 +19 +04 +C3 +0E +10 +1A +0E +1A +2A +37 +3C +22 +0E +23 +EB +21 +CC +FF +39 +A7 +ED +52 +22 +0C +23 +CD +B9 +04 +74 +1A +B8 +1A +0E +1A +ED +4B +37 +3C +21 +50 +3C +22 +01 +27 +23 +22 +09 +27 +2A +25 +23 +09 +22 +37 +3C +21 +AF +C3 +09 +22 +0B +27 +ED +5B +29 +23 +19 +ED +5B +4C +3C +22 +4C +3C +C5 +D5 +ED +73 +0D +27 +CD +04 +15 +C1 +E1 +CB +7E +23 +28 +FB +23 +23 +71 +23 +70 +2A +37 +3C +01 +0C +00 +09 +22 +3B +3C +FD +E9 +C3 +0E +4B +10 +20 +AB +05 +0E +1A +CD +2E +0F +DF +3E +20 +12 +11 +0C +27 +21 +FF +27 +CD +FA +07 +FD +E9 +FB +18 +C3 +0E +F3 +19 +0E +1A +AF +32 +01 +23 +21 +51 +3C +22 +0E +23 +EB +2A +37 +3C +A7 +ED +52 +22 +0C +23 +2A +4C +3C +22 +10 +23 +21 +31 +3C +11 +12 +23 +01 +08 +00 +ED +B0 +FD +E9 +C3 +0E +F3 +19 +11 +10 +0C +23 +C1 +08 +11 +10 +0E +23 +C1 +08 +B6 +04 +51 +1A +3A +02 +23 +A7 +28 +5F +2A +0C +23 +7C +B5 +28 +58 +E5 +11 +19 +00 +21 +01 +23 +4A +CD +20 +18 +D1 +2A +0E +23 +0E +FF +CD +20 +18 +FD +E9 +76 +1A +11 +19 +00 +21 +1A +23 +4A +37 +CD +A7 +18 +30 +F3 +11 +1A +23 +1A +A7 +20 +0B +CD +08 +18 +0D +44 +69 +63 +74 +BA +18 +0A +CD +08 +18 +0D +42 +79 +74 +65 +73 +BA +21 +01 +23 +01 +0B +0B +18 +02 +1A +CF +1A +BE +20 +01 +0D +23 +13 +10 +F5 +20 +C2 +FD +E9 +E7 +0A +BA +1A +06 +FF +18 +12 +C0 +1A +21 +12 +23 +11 +2B +23 +06 +08 +1A +13 +BE +23 +20 +E8 +10 +F8 +2A +0C +23 +ED +5B +25 +23 +7C +B5 +28 +04 +ED +52 +38 +D7 +2A +0E +23 +7C +B5 +20 +03 +2A +27 +23 +0E +FF +CB +18 +CD +A7 +18 +30 +C4 +FD +E9 +01 +0F +3C +AF +02 +0D +20 +FC +2A +3B +3C +11 +FC +FF +2B +4E +77 +19 +23 +22 +3B +3C +2B +46 +77 +79 +0F +A8 +E6 +7F +A8 +32 +02 +3C +CB +B8 +CB +B9 +ED +43 +00 +3C +23 +EB +19 +C9 +3E +09 +B8 +30 +01 +47 +0E +04 +23 +23 +23 +AF +ED +67 +2B +0D +20 +FA +23 +10 +F1 +C6 +FB +E5 +7E +88 +27 +77 +23 +38 +F9 +E1 +C9 +C5 +E5 +06 +04 +A7 +3E +00 +9E +27 +77 +23 +10 +F8 +E1 +C1 +C9 +0E +01 +E5 +D5 +C5 +79 +E6 +0F +47 +A9 +4F +0F +0F +81 +0F +80 +4F +06 +04 +AF +C5 +D5 +E5 +86 +27 +6F +1A +26 +00 +54 +CB +14 +A7 +28 +1B +5F +CB +39 +30 +08 +7D +83 +27 +6F +7C +8A +27 +67 +0C +0D +28 +0A +7B +87 +27 +5F +7A +8F +27 +57 +18 +E6 +EB +E1 +73 +7A +D1 +C1 +13 +23 +10 +CC +C1 +D1 +E1 +C9 +46 +AD +89 +19 +02 +C3 +0E +0F +1D +0E +1A +18 +07 +46 +AB +A3 +1B +02 +B3 +1B +CD +F4 +1A +79 +90 +F5 +30 +06 +EB +ED +44 +DD +70 +00 +47 +C4 +22 +1B +F1 +30 +01 +EB +06 +02 +DD +4E +02 +CB +11 +DC +43 +1B +EB +10 +F8 +CD +53 +1B +1B +1A +C6 +68 +CB +18 +DD +70 +02 +C4 +43 +1B +1A +A7 +20 +19 +DD +35 +00 +DD +35 +00 +D5 +62 +6B +2B +01 +FF +03 +B6 +ED +A8 +10 +FB +EB +70 +D1 +20 +E5 +FD +E9 +54 +5D +D5 +01 +04 +00 +ED +B0 +E1 +1B +1A +A7 +28 +11 +FE +10 +9F +3C +3C +47 +DD +86 +00 +32 +00 +3C +CD +22 +1B +18 +EB +3A +00 +3C +3D +FE +BF +3C +30 +13 +FE +80 +30 +0D +47 +3A +02 +3C +4F +17 +A9 +E6 +80 +A8 +12 +FD +E9 +E7 +08 +01 +00 +04 +71 +23 +10 +FC +FD +E9 +46 +AA +B0 +1B +02 +4D +1C +CD +F4 +1A +AF +B8 +9F +A1 +28 +E7 +E5 +01 +02 +3C +C5 +06 +03 +4E +23 +E3 +23 +CD +55 +1B +E3 +10 +F6 +ED +4B +00 +3C +78 +81 +D6 +42 +32 +00 +3C +E1 +D1 +18 +8E +46 +AF +4A +1C +02 +7D +1C +CD +F4 +1A +AF +B8 +28 +B9 +B9 +28 +B4 +13 +13 +1A +1B +1B +C6 +01 +27 +08 +EB +CD +43 +1B +EB +E5 +11 +10 +3C +01 +04 +00 +ED +B0 +EB +2B +06 +05 +D5 +7E +2B +5E +08 +4F +08 +0C +0D +20 +03 +5F +18 +1B +C5 +06 +02 +16 +10 +CB +23 +17 +CB +12 +30 +F9 +14 +91 +27 +1C +30 +FB +15 +20 +F8 +81 +27 +1D +10 +E9 +C1 +4B +D1 +0C +0D +28 +17 +E5 +2B +2B +CD +55 +1B +D5 +11 +FB +FF +19 +11 +03 +3C +79 +12 +CD +53 +1B +D1 +E1 +23 +04 +10 +B8 +2A +00 +3C +7C +95 +C6 +40 +21 +08 +3C +47 +3A +0B +3C +A7 +20 +03 +05 +05 +2B +DD +70 +00 +D1 +C3 +04 +1C +46 +4E +45 +47 +41 +54 +C5 +7A +1C +07 +11 +1D +DF +7A +A7 +28 +02 +EE +80 +57 +D7 +FD +E9 +49 +4E +D4 +0E +1D +03 +24 +1D +2A +3B +3C +2B +11 +00 +00 +7E +07 +FE +82 +38 +14 +AF +2B +CD +32 +07 +23 +EB +44 +4D +29 +29 +09 +29 +4F +06 +00 +09 +EB +18 +E6 +2B +2B +72 +2B +73 +11 +94 +0D +C3 +BF +04 +55 +46 +4C +4F +41 +D4 +21 +1D +06 +5B +1D +DF +EB +01 +00 +10 +51 +59 +29 +7B +8F +27 +5F +7A +8F +27 +57 +CB +11 +10 +F3 +D7 +16 +46 +59 +D7 +2B +2B +CD +40 +07 +FD +E9 +00 +00 +00 +00 +00 +00 +00 +10 +10 +10 +10 +00 +10 +00 +24 +24 +00 +00 +00 +00 +00 +24 +7E +24 +24 +7E +24 +00 +08 +3E +28 +3E +0A +3E +08 +62 +64 +08 +10 +26 +46 +00 +10 +28 +10 +2A +44 +3A +00 +08 +10 +00 +00 +00 +00 +00 +04 +08 +08 +08 +08 +04 +00 +20 +10 +10 +10 +10 +20 +00 +00 +14 +08 +3E +08 +14 +00 +00 +08 +08 +3E +08 +08 +00 +00 +00 +00 +00 +08 +08 +10 +00 +00 +00 +3E +00 +00 +00 +00 +00 +00 +00 +18 +18 +00 +00 +02 +04 +08 +10 +20 +00 +3C +46 +4A +52 +62 +3C +00 +18 +28 +08 +08 +08 +3E +00 +3C +42 +02 +3C +40 +7E +00 +3C +42 +0C +02 +42 +3C +00 +08 +18 +28 +48 +7E +08 +00 +7E +40 +7C +02 +42 +3C +00 +3C +40 +7C +42 +42 +3C +00 +7E +02 +04 +08 +10 +10 +00 +3C +42 +3C +42 +42 +3C +00 +3C +42 +42 +3E +02 +3C +00 +00 +00 +10 +00 +00 +10 +00 +00 +10 +00 +00 +10 +10 +20 +00 +04 +08 +10 +08 +04 +00 +00 +00 +3E +00 +3E +00 +00 +00 +10 +08 +04 +08 +10 +00 +3C +42 +04 +08 +00 +08 +3C +4A +56 +5E +40 +3C +3C +42 +42 +7E +42 +42 +7C +42 +7C +42 +42 +7C +3C +42 +40 +40 +42 +3C +78 +44 +42 +42 +44 +78 +7E +40 +7C +40 +40 +7E +7E +40 +7C +40 +40 +40 +3C +42 +40 +4E +42 +3C +42 +42 +7E +42 +42 +42 +3E +08 +08 +08 +08 +3E +02 +02 +02 +42 +42 +3C +44 +48 +70 +48 +44 +42 +40 +40 +40 +40 +40 +7E +42 +66 +5A +42 +42 +42 +42 +62 +52 +4A +46 +42 +3C +42 +42 +42 +42 +3C +7C +42 +42 +7C +40 +40 +3C +42 +42 +52 +4A +3C +7C +42 +42 +7C +44 +42 +3C +40 +3C +02 +42 +3C +FE +10 +10 +10 +10 +10 +42 +42 +42 +42 +42 +3E +42 +42 +42 +42 +24 +18 +42 +42 +42 +42 +5A +24 +42 +24 +18 +18 +24 +42 +82 +44 +28 +10 +10 +10 +7E +04 +08 +10 +20 +7E +0E +08 +08 +08 +08 +0E +00 +40 +20 +10 +08 +04 +70 +10 +10 +10 +10 +70 +10 +38 +54 +10 +10 +10 +00 +00 +00 +00 +00 +00 +FF +1C +22 +78 +20 +20 +7E +00 +00 +38 +04 +3C +44 +3E +00 +20 +20 +3C +22 +22 +3C +00 +00 +1C +20 +20 +20 +1C +00 +04 +04 +3C +44 +44 +3E +00 +00 +38 +44 +78 +40 +3C +00 +0C +10 +18 +10 +10 +10 +00 +00 +3C +44 +44 +3C +04 +38 +40 +40 +78 +44 +44 +44 +00 +10 +00 +30 +10 +10 +38 +00 +04 +00 +04 +04 +04 +24 +18 +20 +28 +30 +30 +28 +24 +00 +10 +10 +10 +10 +10 +0C +00 +00 +68 +54 +54 +54 +54 +00 +00 +78 +44 +44 +44 +44 +00 +00 +38 +44 +44 +44 +38 +00 +00 +78 +44 +44 +78 +40 +40 +00 +3C +44 +44 +3C +04 +06 +00 +1C +20 +20 +20 +20 +00 +00 +38 +40 +38 +04 +78 +00 +10 +38 +10 +10 +10 +0C +00 +00 +44 +44 +44 +44 +3C +00 +00 +44 +44 +28 +28 +10 +00 +00 +44 +54 +54 +54 +28 +00 +00 +44 +28 +10 +28 +44 +00 +00 +44 +44 +44 +3C +04 +38 +00 +7C +08 +10 +20 +7C +00 +0E +08 +30 +30 +08 +0E +00 +08 +08 +08 +08 +08 +08 +00 +70 +10 +0C +0C +10 +70 +00 +32 +4C +00 +00 +00 +00 +00 +3C +42 +99 +A1 +A1 +99 +42 +3C +FF +58 +1D +00 diff --git a/cores/JupiterAce/ace.rom b/cores/JupiterAce/ace.rom new file mode 100644 index 0000000000000000000000000000000000000000..71cac211108c49619c2c19a9f2e0e8a696b4b059 GIT binary patch literal 8192 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

+#include + +int main (int argc, char *argv[]) +{ + FILE *f; + unsigned char *scr; + char nombre[256]; + int i,leido; + + if (argc<2) + return 1; + + scr = malloc(65536); + f = fopen (argv[1],"rb"); + if (!f) + return 1; + + leido = fread (scr, 1, 65536, f); + fclose (f); + + strcpy (nombre, argv[1]); + nombre[strlen(nombre)-3]=0; + strcat (nombre, "hex"); + + f = fopen (nombre, "wt"); + for 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 9'd248 && cntscn <= 9'd255) + vsync = 1'b0; + else + vsync = 1'b1; + end + assign int_n = vsync; + + reg hsync; // LINE signal in schematic + always @* begin + if (cntpix >= 9'd320 && cntpix <= 9'd351) + hsync = 1'b0; + else + hsync = 1'b1; + end + + assign csync = hsync & vsync; + + reg viden; // VIDEN signal in schematic + always @* begin + if (cntpix >= 9'd0 && cntpix <= 9'd255 && + cntscn >= 9'd0 && cntscn <= 9'd191) + viden = 1'b1; + else + viden = 1'b0; + end + + // SHIFT/LOAD signal to 74LS166 + reg shiftload; + always @* begin + if (cnt[2:0] == 3'b000 && viden == 1'b1) + shiftload = 1'b1; + else + shiftload = 1'b0; + end + + assign screen_addr = {cnt[16:12], cnt[7:3]}; + assign char_addr = {screen_data[6:0], cnt[11:9]}; + + // 74LS166 + reg [7:0] shiftreg = 8'h00; + always @(posedge clk) begin + if (shiftload == 1'b1) + shiftreg <= char_data; + else + shiftreg <= {shiftreg[6:0], 1'b0}; + end + + // Pixel inverter reg and video output stage + reg pixinverter = 1'b0; + always @(posedge clk) begin + if (cnt[2:0] == 3'b000) + pixinverter <= viden & screen_data[7]; + end + + assign video = shiftreg[7] ^ pixinverter; + + // Address decoder + reg fast_access; + always @* begin + rom_enable = 1'b0; + sram_enable = 1'b0; + cram_enable = 1'b0; + uram_enable = 1'b0; + xram_enable = 1'b0; + eram_enable = 1'b0; + fast_access = 1'b1; + if (mreq_n == 1'b0) begin + if (cpu_addr >= 16'h0000 && cpu_addr <= 16'h1FFF) + rom_enable = 1'b1; + else if (cpu_addr >= 16'h2000 && cpu_addr <= 16'h27FF) begin + sram_enable = 1'b1; + if (cpu_addr >= 16'h2400 && cpu_addr <= 16'h27FF) + fast_access = 1'b0; + end + else if (cpu_addr >= 16'h2800 && cpu_addr <= 16'h2FFF) begin + cram_enable = 1'b1; + if (cpu_addr >= 16'h2C00 && cpu_addr <= 16'h2FFF) + fast_access = 1'b0; + end + else if (cpu_addr >= 16'h3000 && cpu_addr <= 16'h3FFF) + uram_enable = 1'b1; + else if (cpu_addr >= 16'h4000 && cpu_addr <= 16'h7FFF) + xram_enable = 1'b1; + else + eram_enable = 1'b1; + end + end + + // CPU arbitration to share memory with video generator + always @(posedge clk) begin + if ((sram_enable == 1'b1 || cram_enable == 1'b1) && viden == 1'b1 && fast_access == 1'b0) + wait_n <= 1'b0; + else if (viden == 1'b0) + wait_n <= 1'b1; + end + + // IO devices + always @* begin + data_to_cpu_oe = 1'b0; + data_to_cpu = {2'b11, ear, kbdcols}; + if (iorq_n == 1'b0 && cpu_addr[0] == 1'b0 && rd_n == 1'b0) begin + data_to_cpu_oe = 1'b1; + end + end + always @(posedge clk) begin + if (iorq_n == 1'b0 && cpu_addr[0] == 1'b0) begin + if (rd_n == 1'b0 && wr_n == 1'b1) + spk <= 1'b0; + else if (rd_n == 1'b1 && wr_n == 1'b0) + spk <= 1'b1; + if (wr_n == 1'b0) + mic <= data_from_cpu[3]; + end + end +endmodule diff --git a/cores/JupiterAce/jupiter_ace.gise b/cores/JupiterAce/jupiter_ace.gise new file mode 100644 index 0000000..d297a4b --- /dev/null +++ b/cores/JupiterAce/jupiter_ace.gise @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + 11.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cores/JupiterAce/jupiter_ace.xise b/cores/JupiterAce/jupiter_ace.xise index 74f0752..d10d56d 100644 --- a/cores/JupiterAce/jupiter_ace.xise +++ b/cores/JupiterAce/jupiter_ace.xise @@ -15,16 +15,6 @@ - - - - - - - - - - @@ -53,22 +43,7 @@ - - - - - - - - - - - - - - - @@ -82,6 +57,18 @@ + + + + + + + + + + + + @@ -96,7 +83,7 @@ - + @@ -140,7 +127,7 @@ - + @@ -421,7 +408,9 @@ - + + + diff --git a/cores/JupiterAce/keyboard_for_ace.v b/cores/JupiterAce/keyboard_for_ace.v index 51e102d..12deba5 100644 --- a/cores/JupiterAce/keyboard_for_ace.v +++ b/cores/JupiterAce/keyboard_for_ace.v @@ -407,34 +407,36 @@ module keyboard_for_ace( `KEY_CORCHA: begin matrix[0][1] <= is_released; - if (!shift_pressed) - matrix[6][4] <= is_released; // ^ - else + if (alt_pressed || shift_pressed) matrix[5][4] <= is_released; // [ + else + matrix[6][4] <= is_released; // ^ end `KEY_CORCHC: begin matrix[0][1] <= is_released; - if (!shift_pressed) - matrix[6][2] <= is_released; // + - else + if (shift_pressed) + matrix[7][3] <= is_released; // * + else if (alt_pressed) matrix[5][3] <= is_released; // ] + else + matrix[6][2] <= is_released; // + end `KEY_LLAVA: begin matrix[0][1] <= is_released; - if (!shift_pressed) - matrix[0][3] <= is_released; // pound - else + if (alt_pressed || shift_pressed) matrix[1][3] <= is_released; // { + else + matrix[0][3] <= is_released; // pound end `KEY_LLAVC: begin matrix[0][1] <= is_released; - if (!shift_pressed) - matrix[5][2] <= is_released; // copyright - else + if (alt_pressed || shift_pressed) matrix[1][4] <= is_released; // } + else + matrix[5][2] <= is_released; // copyright end `KEY_COMA: begin diff --git a/cores/JupiterAce/memorias.v b/cores/JupiterAce/memorias.v index 881264d..d59c279 100644 --- a/cores/JupiterAce/memorias.v +++ b/cores/JupiterAce/memorias.v @@ -20,56 +20,73 @@ // ////////////////////////////////////////////////////////////////////////////////// -module ram1k( +module ram1k ( input wire clk, + input wire ce, input wire [9:0] a, input wire [7:0] din, - output wire [7:0] dout, - input wire ce_n, - input wire oe_n, - input wire we_n + output reg [7:0] dout, + input wire we ); - reg [7:0] dato; - reg [7:0] mem[0:1023]; - wire ce = ~ce_n; - wire we = ~we_n; - - assign dout = (oe_n | ce_n)? 8'bzzzzzzzz : dato; - - always @(posedge clk) begin - if (ce == 1'b1) begin - if (we == 1'b0) - dato <= mem[a]; - else - mem[a] <= din; - end + reg [7:0] mem[0:1023]; + always @(posedge clk) begin + dout <= mem[a]; + if (we == 1'b1 && ce == 1'b1) + mem[a] <= din; end endmodule -module ram16k( +module ram1k_dualport( input wire clk, + input wire ce, + input wire [9:0] a1, + input wire [9:0] a2, + input wire [7:0] din, + output reg [7:0] dout1, + output reg [7:0] dout2, + input wire we + ); + + reg [7:0] mem[0:1023]; + always @(posedge clk) begin + dout2 <= mem[a2]; + dout1 <= mem[a1]; + if (we == 1'b1 && ce == 1'b1) + mem[a1] <= din; + end +endmodule + +module ram16k ( + input wire clk, + input wire ce, input wire [13:0] a, input wire [7:0] din, - output wire [7:0] dout, - input wire ce_n, - input wire oe_n, - input wire we_n + output reg [7:0] dout, + input wire we ); - reg [7:0] dato; - reg [7:0] mem[0:16383]; - wire ce = ~ce_n; - wire we = ~we_n; - - assign dout = (oe_n | ce_n)? 8'bzzzzzzzz : dato; - - always @(posedge clk) begin - if (ce == 1'b1) begin - if (we == 1'b0) - dato <= mem[a]; - else - mem[a] <= din; - end + reg [7:0] mem[0:16383]; + always @(posedge clk) begin + dout <= mem[a]; + if (we == 1'b1 && ce == 1'b1) + mem[a] <= din; + end +endmodule + +module ram32k ( + input wire clk, + input wire ce, + input wire [14:0] a, + input wire [7:0] din, + output reg [7:0] dout, + input wire we + ); + + reg [7:0] mem[0:32767]; + always @(posedge clk) begin + dout <= mem[a]; + if (we == 1'b1 && ce == 1'b1) + mem[a] <= din; end endmodule diff --git a/cores/JupiterAce/par_usage_statistics.html b/cores/JupiterAce/par_usage_statistics.html index f61cabb..e9e92b5 100644 --- a/cores/JupiterAce/par_usage_statistics.html +++ b/cores/JupiterAce/par_usage_statistics.html @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - + + + + - +
Par Statistics
Total Non-vccgnd Signals=1987
Total Non-vccgnd Design Pins=9927
Total Non-vccgnd Conns=9927
Total Non-vccgnd Timing Constrained Conns=2153
Phase 1 CPU=8.4 sec
Phase 2 CPU=9.4 sec
Phase 3 CPU=12.1 sec
Phase 4 CPU=12.9 sec
Phase 5 CPU=18.2 sec
Phase 6 CPU=18.2 sec
Phase 7 CPU=18.2 sec
Phase 8 CPU=18.2 sec
Phase 9 CPU=18.2 sec
Phase 10 CPU=18.5 sec
AvgWirelenPerPin Fanout 1=2.0
AvgWirelenPerPin Fanout 2=2.5
AvgWirelenPerPin Fanout 3=3.3
Total Non-vccgnd Signals=2039
Total Non-vccgnd Design Pins=10450
Total Non-vccgnd Conns=10450
Total Non-vccgnd Timing Constrained Conns=10425
Phase 1 CPU=11.4 sec
Phase 2 CPU=12.3 sec
Phase 3 CPU=16.9 sec
Phase 4 CPU=17.8 sec
Phase 5 CPU=24.9 sec
Phase 6 CPU=24.9 sec
Phase 7 CPU=24.9 sec
Phase 8 CPU=24.9 sec
Phase 9 CPU=25.6 sec
Phase 10 CPU=26.4 sec
AvgWirelenPerPin Fanout 1=3.0
AvgWirelenPerPin Fanout 2=3.0
AvgWirelenPerPin Fanout 3=4.0
AvgWirelenPerPin Fanout 4=4.0
AvgWirelenPerPin Fanout 10=3.9
AvgWirelenPerPin Fanout 50=3.2
AvgWirelenPerPin Fanout 100=7.6
AvgWirelenPerPin Fanout 500=3.7
AvgWirelenPerPin Fanout 10=4.7
AvgWirelenPerPin Fanout 50=4.1
AvgWirelenPerPin Fanout 100=8.6
AvgWirelenPerPin Fanout 500=3.4
AvgWirelenPerPin Fanout 5000=0.0
AvgWirelenPerPin Fanout 20000=0.0
AvgWirelenPerPin Fanout 50000=0.0
AvgWirelenPerPin Fanout 100000=0.0
IRR Gamma=4.6416
IRR Gamma=6.0303
diff --git a/cores/JupiterAce/pines_zxuno.ucf b/cores/JupiterAce/pines_zxuno.ucf index db5b540..7fea9f7 100644 --- a/cores/JupiterAce/pines_zxuno.ucf +++ b/cores/JupiterAce/pines_zxuno.ucf @@ -1,34 +1,34 @@ # Clocks & debug NET "clk50mhz" LOC="P55" | IOSTANDARD = LVCMOS33; -#NET "testled" LOC="P10" | IOSTANDARD = LVCMOS33; +#NET "testled" LOC="2" | IOSTANDARD = LVCMOS33; NET "clk50mhz" PERIOD=20 ns; -#NET "sysclk" PERIOD=35 ns; +#NET "clk12" PERIOD=83 ns; # Video output -NET "r<2>" LOC="P93" | IOSTANDARD = LVCMOS33; -NET "r<1>" LOC="P92" | IOSTANDARD = LVCMOS33; -NET "r<0>" LOC="P88" | IOSTANDARD = LVCMOS33; -NET "g<2>" LOC="P84" | IOSTANDARD = LVCMOS33; -NET "g<1>" LOC="P83" | IOSTANDARD = LVCMOS33; -NET "g<0>" LOC="P82" | IOSTANDARD = LVCMOS33; -NET "b<2>" LOC="P81" | IOSTANDARD = LVCMOS33; -NET "b<1>" LOC="P80" | IOSTANDARD = LVCMOS33; -NET "b<0>" LOC="P79" | IOSTANDARD = LVCMOS33; -NET "csync" LOC="P87" | IOSTANDARD = LVCMOS33; -#NET "vsync" LOC="P85" | IOSTANDARD = LVCMOS33; -NET "stdn" LOC="P67" | IOSTANDARD = LVCMOS33; -NET "stdnb" LOC="P66" | IOSTANDARD = LVCMOS33; +NET "r<2>" LOC="P97" | IOSTANDARD = LVCMOS33; +NET "r<1>" LOC="P95" | IOSTANDARD = LVCMOS33; +NET "r<0>" LOC="P94" | IOSTANDARD = LVCMOS33; +NET "g<2>" LOC="P88" | IOSTANDARD = LVCMOS33; +NET "g<1>" LOC="P87" | IOSTANDARD = LVCMOS33; +NET "g<0>" LOC="P85" | IOSTANDARD = LVCMOS33; +NET "b<2>" LOC="P84" | IOSTANDARD = LVCMOS33; +NET "b<1>" LOC="P83" | IOSTANDARD = LVCMOS33; +NET "b<0>" LOC="P82" | IOSTANDARD = LVCMOS33; +NET "csync" LOC="P93" | IOSTANDARD = LVCMOS33; +#NET "vsync" LOC="P92" | IOSTANDARD = LVCMOS33; +NET "stdn" LOC="P51" | IOSTANDARD = LVCMOS33; +NET "stdnb" LOC="P50" | IOSTANDARD = LVCMOS33; # Sound input/output -NET "audio_out_left" LOC="P8" | IOSTANDARD = LVCMOS33; -NET "audio_out_right" LOC="P9" | IOSTANDARD = LVCMOS33; -NET "ear" LOC="P105" | IOSTANDARD = LVCMOS33; +NET "audio_out_left" LOC="P98" | IOSTANDARD = LVCMOS33; +NET "audio_out_right" LOC="P99" | IOSTANDARD = LVCMOS33; +NET "ear" LOC="P1" | IOSTANDARD = LVCMOS33; # Keyboard and mouse -NET "clkps2" LOC="P98" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 1 DIN -NET "dataps2" LOC="P97" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 5 DIN -#NET "mouseclk" LOC="P94" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 6 DIN -#NET "mousedata" LOC="P95" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 2 DIN +NET "clkps2" LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 1 DIN +NET "dataps2" LOC="P142" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 5 DIN +#NET "mouseclk" LOC="P57" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 6 DIN +#NET "mousedata" LOC="P56" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 2 DIN # SRAM #NET "sram_addr<0>" LOC="P115" | IOSTANDARD = LVCMOS33; @@ -51,34 +51,32 @@ NET "dataps2" LOC="P97" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 5 DIN #NET "sram_addr<17>" LOC="P141" | IOSTANDARD = LVCMOS33; #NET "sram_addr<18>" LOC="P138" | IOSTANDARD = LVCMOS33; # -#NET "sram_data<0>" LOC="P114" | IOSTANDARD = LVCMOS33; -#NET "sram_data<1>" LOC="P112" | IOSTANDARD = LVCMOS33; -#NET "sram_data<2>" LOC="P111" | IOSTANDARD = LVCMOS33; -#NET "sram_data<3>" LOC="P99" | IOSTANDARD = LVCMOS33; -#NET "sram_data<4>" LOC="P100" | IOSTANDARD = LVCMOS33; -#NET "sram_data<5>" LOC="P101" | IOSTANDARD = LVCMOS33; -#NET "sram_data<6>" LOC="P102" | IOSTANDARD = LVCMOS33; -#NET "sram_data<7>" LOC="P104" | IOSTANDARD = LVCMOS33; -# -#NET "sram_we_n" LOC="P134" | IOSTANDARD = LVCMOS33; -# -## SPI Flash +#NET "sram_data<0>" LOC="P114" | IOSTANDARD = LVCMOS33; +#NET "sram_data<1>" LOC="P112" | IOSTANDARD = LVCMOS33; +#NET "sram_data<2>" LOC="P111" | IOSTANDARD = LVCMOS33; +#NET "sram_data<3>" LOC="P105" | IOSTANDARD = LVCMOS33; +#NET "sram_data<4>" LOC="P104" | IOSTANDARD = LVCMOS33; +#NET "sram_data<5>" LOC="P102" | IOSTANDARD = LVCMOS33; +#NET "sram_data<6>" LOC="P101" | IOSTANDARD = LVCMOS33; +#NET "sram_data<7>" LOC="P100" | IOSTANDARD = LVCMOS33; + +#NET "sram_we_n" LOC="P134" | IOSTANDARD = LVCMOS33; + +# SPI Flash #NET "flash_cs_n" LOC="P38" | IOSTANDARD = LVCMOS33; #NET "flash_clk" LOC="P70" | IOSTANDARD = LVCMOS33; #NET "flash_mosi" LOC="P64" | IOSTANDARD = LVCMOS33; #NET "flash_miso" LOC="P65" | IOSTANDARD = LVCMOS33; -##NET "flash_ext1" LOC="P62" | IOSTANDARD = LVCMOS33; -##NET "flash_ext2" LOC="P61" | IOSTANDARD = LVCMOS33; -# -## SD/MMC -#NET "sd_cs_n" LOC="P59" | IOSTANDARD = LVCMOS33; -#NET "sd_clk" LOC="P75" | IOSTANDARD = LVCMOS33; -#NET "sd_mosi" LOC="P74" | IOSTANDARD = LVCMOS33; -#NET "sd_miso" LOC="P78" | IOSTANDARD = LVCMOS33; -# -## JOYSTICK -#NET "joyup" LOC="P142" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY6 -#NET "joydown" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY4 -#NET "joyleft" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY3 -#NET "joyright" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY2 -#NET "joyfire" LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY7 + +# SD/MMC +#NET "sd_cs_n" LOC="P78" | IOSTANDARD = LVCMOS33; +#NET "sd_clk" LOC="P80" | IOSTANDARD = LVCMOS33; +#NET "sd_mosi" LOC="P79" | IOSTANDARD = LVCMOS33; +#NET "sd_miso" LOC="P81" | IOSTANDARD = LVCMOS33; + +# JOYSTICK +#NET "joyup" LOC="P74" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY6 +#NET "joydown" LOC="P67" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY4 +#NET "joyleft" LOC="P59" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY3 +#NET "joyright" LOC="P58" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY2 +#NET "joyfire" LOC="P75" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY7 diff --git a/cores/JupiterAce/pines_zxuno_Ap.ucf b/cores/JupiterAce/pines_zxuno_Ap.ucf new file mode 100644 index 0000000..7fea9f7 --- /dev/null +++ b/cores/JupiterAce/pines_zxuno_Ap.ucf @@ -0,0 +1,82 @@ +# Clocks & debug +NET "clk50mhz" LOC="P55" | IOSTANDARD = LVCMOS33; +#NET "testled" LOC="2" | IOSTANDARD = LVCMOS33; +NET "clk50mhz" PERIOD=20 ns; +#NET "clk12" PERIOD=83 ns; + +# Video output +NET "r<2>" LOC="P97" | IOSTANDARD = LVCMOS33; +NET "r<1>" LOC="P95" | IOSTANDARD = LVCMOS33; +NET "r<0>" LOC="P94" | IOSTANDARD = LVCMOS33; +NET "g<2>" LOC="P88" | IOSTANDARD = LVCMOS33; +NET "g<1>" LOC="P87" | IOSTANDARD = LVCMOS33; +NET "g<0>" LOC="P85" | IOSTANDARD = LVCMOS33; +NET "b<2>" LOC="P84" | IOSTANDARD = LVCMOS33; +NET "b<1>" LOC="P83" | IOSTANDARD = LVCMOS33; +NET "b<0>" LOC="P82" | IOSTANDARD = LVCMOS33; +NET "csync" LOC="P93" | IOSTANDARD = LVCMOS33; +#NET "vsync" LOC="P92" | IOSTANDARD = LVCMOS33; +NET "stdn" LOC="P51" | IOSTANDARD = LVCMOS33; +NET "stdnb" LOC="P50" | IOSTANDARD = LVCMOS33; + +# Sound input/output +NET "audio_out_left" LOC="P98" | IOSTANDARD = LVCMOS33; +NET "audio_out_right" LOC="P99" | IOSTANDARD = LVCMOS33; +NET "ear" LOC="P1" | IOSTANDARD = LVCMOS33; + +# Keyboard and mouse +NET "clkps2" LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 1 DIN +NET "dataps2" LOC="P142" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 5 DIN +#NET "mouseclk" LOC="P57" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 6 DIN +#NET "mousedata" LOC="P56" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 2 DIN + +# SRAM +#NET "sram_addr<0>" LOC="P115" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<1>" LOC="P116" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<2>" LOC="P117" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<3>" LOC="P119" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<4>" LOC="P120" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<5>" LOC="P123" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<6>" LOC="P126" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<7>" LOC="P131" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<8>" LOC="P127" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<9>" LOC="P124" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<10>" LOC="P118" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<11>" LOC="P121" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<12>" LOC="P133" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<13>" LOC="P132" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<14>" LOC="P137" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<15>" LOC="P140" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<16>" LOC="P139" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<17>" LOC="P141" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<18>" LOC="P138" | IOSTANDARD = LVCMOS33; +# +#NET "sram_data<0>" LOC="P114" | IOSTANDARD = LVCMOS33; +#NET "sram_data<1>" LOC="P112" | IOSTANDARD = LVCMOS33; +#NET "sram_data<2>" LOC="P111" | IOSTANDARD = LVCMOS33; +#NET "sram_data<3>" LOC="P105" | IOSTANDARD = LVCMOS33; +#NET "sram_data<4>" LOC="P104" | IOSTANDARD = LVCMOS33; +#NET "sram_data<5>" LOC="P102" | IOSTANDARD = LVCMOS33; +#NET "sram_data<6>" LOC="P101" | IOSTANDARD = LVCMOS33; +#NET "sram_data<7>" LOC="P100" | IOSTANDARD = LVCMOS33; + +#NET "sram_we_n" LOC="P134" | IOSTANDARD = LVCMOS33; + +# SPI Flash +#NET "flash_cs_n" LOC="P38" | IOSTANDARD = LVCMOS33; +#NET "flash_clk" LOC="P70" | IOSTANDARD = LVCMOS33; +#NET "flash_mosi" LOC="P64" | IOSTANDARD = LVCMOS33; +#NET "flash_miso" LOC="P65" | IOSTANDARD = LVCMOS33; + +# SD/MMC +#NET "sd_cs_n" LOC="P78" | IOSTANDARD = LVCMOS33; +#NET "sd_clk" LOC="P80" | IOSTANDARD = LVCMOS33; +#NET "sd_mosi" LOC="P79" | IOSTANDARD = LVCMOS33; +#NET "sd_miso" LOC="P81" | IOSTANDARD = LVCMOS33; + +# JOYSTICK +#NET "joyup" LOC="P74" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY6 +#NET "joydown" LOC="P67" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY4 +#NET "joyleft" LOC="P59" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY3 +#NET "joyright" LOC="P58" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY2 +#NET "joyfire" LOC="P75" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY7 diff --git a/cores/JupiterAce/pines_zxuno_v4.ucf b/cores/JupiterAce/pines_zxuno_v4.ucf new file mode 100644 index 0000000..7862a72 --- /dev/null +++ b/cores/JupiterAce/pines_zxuno_v4.ucf @@ -0,0 +1,85 @@ +# Clocks & debug +NET "clk50mhz" LOC="P55" | IOSTANDARD = LVCMOS33; +#NET "testled" LOC="P10" | IOSTANDARD = LVCMOS33; +NET "clk50mhz" PERIOD=20 ns; +#NET "clk12" PERIOD=83 ns; + +# Video output +NET "b<2>" LOC="P93" | IOSTANDARD = LVCMOS33; +NET "b<1>" LOC="P92" | IOSTANDARD = LVCMOS33; +NET "b<0>" LOC="P88" | IOSTANDARD = LVCMOS33; +NET "g<2>" LOC="P84" | IOSTANDARD = LVCMOS33; +NET "g<1>" LOC="P83" | IOSTANDARD = LVCMOS33; +NET "g<0>" LOC="P82" | IOSTANDARD = LVCMOS33; +NET "r<2>" LOC="P81" | IOSTANDARD = LVCMOS33; +NET "r<1>" LOC="P80" | IOSTANDARD = LVCMOS33; +NET "r<0>" LOC="P79" | IOSTANDARD = LVCMOS33; +NET "csync" LOC="P87" | IOSTANDARD = LVCMOS33; +#NET "vsync" LOC="P85" | IOSTANDARD = LVCMOS33; +NET "stdn" LOC="P66" | IOSTANDARD = LVCMOS33; +NET "stdnb" LOC="P67" | IOSTANDARD = LVCMOS33; + +# Sound input/output +NET "audio_out_left" LOC="P10" | IOSTANDARD = LVCMOS33; +NET "audio_out_right" LOC="P9" | IOSTANDARD = LVCMOS33; +NET "ear" LOC="P94" | IOSTANDARD = LVCMOS33; + +# Keyboard and mouse +NET "clkps2" LOC="P99" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 1 DIN +NET "dataps2" LOC="P98" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 5 DIN +#NET "mouseclk" LOC="P95" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 6 DIN +#NET "mousedata" LOC="P97" | IOSTANDARD = LVCMOS33 | PULLUP; # pin 2 DIN + +# SRAM +#NET "sram_addr<0>" LOC="P141" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<1>" LOC="P139" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<2>" LOC="P137" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<3>" LOC="P134" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<4>" LOC="P133" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<5>" LOC="P120" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<6>" LOC="P118" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<7>" LOC="P116" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<8>" LOC="P114" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<9>" LOC="P112" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<10>" LOC="P104" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<11>" LOC="P102" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<12>" LOC="P101" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<13>" LOC="P100" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<14>" LOC="P111" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<15>" LOC="P131" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<16>" LOC="P138" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<17>" LOC="P140" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<18>" LOC="P142" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<19>" LOC="P105" | IOSTANDARD = LVCMOS33; +#NET "sram_addr<20>" LOC="P143" | IOSTANDARD = LVCMOS33; + +#NET "sram_data<0>" LOC="P132" | IOSTANDARD = LVCMOS33; +#NET "sram_data<1>" LOC="P127" | IOSTANDARD = LVCMOS33; +#NET "sram_data<2>" LOC="P124" | IOSTANDARD = LVCMOS33; +#NET "sram_data<3>" LOC="P123" | IOSTANDARD = LVCMOS33; +#NET "sram_data<4>" LOC="P115" | IOSTANDARD = LVCMOS33; +#NET "sram_data<5>" LOC="P117" | IOSTANDARD = LVCMOS33; +#NET "sram_data<6>" LOC="P119" | IOSTANDARD = LVCMOS33; +#NET "sram_data<7>" LOC="P126" | IOSTANDARD = LVCMOS33; + +#NET "sram_we_n" LOC="P121" | IOSTANDARD = LVCMOS33; + +# SPI Flash +#NET "flash_cs_n" LOC="P38" | IOSTANDARD = LVCMOS33; +#NET "flash_clk" LOC="P70" | IOSTANDARD = LVCMOS33; +#NET "flash_mosi" LOC="P64" | IOSTANDARD = LVCMOS33; +#NET "flash_miso" LOC="P65" | IOSTANDARD = LVCMOS33; + +# SD/MMC +#NET "sd_cs_n" LOC="P59" | IOSTANDARD = LVCMOS33; +#NET "sd_clk" LOC="P75" | IOSTANDARD = LVCMOS33; +#NET "sd_mosi" LOC="P74" | IOSTANDARD = LVCMOS33; +#NET "sd_miso" LOC="P78" | IOSTANDARD = LVCMOS33; + +# JOYSTICK +#NET "joyup" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY6 +#NET "joydown" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY4 +#NET "joyleft" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY3 +#NET "joyright" LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY2 +#NET "joyfire" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY7 +#NET "btn2" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; #JOY5 diff --git a/cores/JupiterAce/rom.v b/cores/JupiterAce/rom.v new file mode 100644 index 0000000..8145ce2 --- /dev/null +++ b/cores/JupiterAce/rom.v @@ -0,0 +1,36 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 04:12:52 02/09/2014 +// Design Name: +// Module Name: rom +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module rom ( + input wire clk, + input wire [12:0] a, + output reg [7:0] dout + ); + + reg [7:0] mem[0:8191]; + integer i; + initial begin // usa $readmemb/$readmemh dependiendo del formato del fichero que contenga la ROM + $readmemh ("ace.hex", mem, 0); + end + + always @(posedge clk) begin + dout <= mem[a[12:0]]; + end +endmodule diff --git a/cores/JupiterAce/tld_jace_spartan6.v b/cores/JupiterAce/tld_jace_spartan6.v index 7796750..9028dc1 100644 --- a/cores/JupiterAce/tld_jace_spartan6.v +++ b/cores/JupiterAce/tld_jace_spartan6.v @@ -36,6 +36,7 @@ module tld_jace_spartan6 ( wire clkram; // 50MHz (maybe less if needed) to clock internal RAM/ROM wire clk65; // 6.5MHz main frequency Jupiter ACE + wire clkcpu; // CPU CLK wire kbd_reset; wire [7:0] kbd_rows; @@ -61,19 +62,20 @@ module tld_jace_spartan6 ( always @(posedge clk65) poweron_reset <= {poweron_reset[6:0],1'b1}; - dcmclock reloj_maestro( - .CLKIN_IN(clk50mhz), - .CLKDV_OUT(clk65), - .CLKIN_IBUFG_OUT(clkram), - .CLK0_OUT(), - .LOCKED_OUT() - ); + cuatro_relojes system_clocks_pll ( + .CLK_IN1(clk50mhz), + .CLK_OUT1(clkram), // for driving synch RAM and ROM = 26.6666 MHz + .CLK_OUT2(clk65), // video clock = 6.66666 MHz + .CLK_OUT3(clkcpu), // CPU clock = 0.5 video clock + .CLK_OUT4() // Super CPU clock (just a test) + ); jupiter_ace the_core ( .clkram(clkram), .clk65(clk65), + .clkcpu(clkcpu), .reset(kbd_reset & poweron_reset[7]), - .ear(!ear), + .ear(ear), .filas(kbd_rows), .columnas(kbd_columns), .video(video), @@ -92,5 +94,4 @@ module tld_jace_spartan6 ( .kbd_nmi() ); - endmodule diff --git a/cores/JupiterAce/tv80_to_t80_wrapper.v b/cores/JupiterAce/tv80_to_t80_wrapper.v new file mode 100644 index 0000000..3a6a8f2 --- /dev/null +++ b/cores/JupiterAce/tv80_to_t80_wrapper.v @@ -0,0 +1,79 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 03:39:55 05/13/2012 +// Design Name: +// Module Name: tv80_to_t80_wrapper +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// + +module tv80n_wrapper ( + // Outputs + m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, dout, + // Inputs + reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di + ); + + input reset_n; + input clk; + input wait_n; + input int_n; + input nmi_n; + input busrq_n; + output m1_n; + output mreq_n; + output iorq_n; + output rd_n; + output wr_n; + output rfsh_n; + output halt_n; + output busak_n; + output [15:0] A; + input [7:0] di; + output [7:0] dout; + + wire [7:0] d; + + T80a TheCPU ( + .RESET_n(reset_n), + .CLK_n(clk), + .WAIT_n(wait_n), + .INT_n(int_n), + .NMI_n(nmi_n), + .BUSRQ_n(busrq_n), + .M1_n(m1_n), + .MREQ_n(mreq_n), + .IORQ_n(iorq_n), + .RD_n(rd_n), + .WR_n(wr_n), + .RFSH_n(rfsh_n), + .HALT_n(halt_n), + .BUSAK_n(busak_n), + .A(A), + .D(d), + + .SavePC(), + .SaveINT(), + .RestorePC(16'h0000), + .RestoreINT(8'h00), + .RestorePC_n(1'b1) + ); + + assign dout = d; + assign d = ( (!mreq_n || !iorq_n) && !rd_n)? di : + ( (!mreq_n || !iorq_n) && !wr_n)? 8'hZZ : + 8'hFF; + +endmodule