OpenCores
URL https://opencores.org/ocsvn/fpz8/fpz8/trunk

Subversion Repositories fpz8

[/] [fpz8_cpu_v1.vhd] - Diff between revs 2 and 3

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 3
-- FPz8 mk1
-- FPz8 mk1 v0.99
-- Zilog Z8 Encore! 100% compatible softcore
-- Zilog Z8 Encore! 100% compatible softcore
-- Author:      Fábio Pereira (fabio.jve@gmail.com)
-- Author:      Fábio Pereira (fabio.jve@gmail.com)
 
-- Version: 0.99        Nov, 24th, 2016 (changed LDWX instruction, interrupts, condition code function, debugger command processor)
 
-- Version: 0.91        Nov, 15th, 2016
-- Version:     0.9             Nov, 11th, 2016
-- Version:     0.9             Nov, 11th, 2016
 
 
-- FPz8 is a softcore 100% object-code compatible with the Z8 encore microcontroller line. Current implementation includes 
-- FPz8 is a softcore almost 100% object-code compatible with the Z8 encore microcontroller line. Current implementation includes 
-- 2kb of file registers (RAM), 16kb of program memory (using FPGA RAM), 8 vectored interrupts with programmable priority, 
-- 2kb of file registers (RAM), 16kb of program memory (using FPGA RAM), 8 vectored interrupts with programmable priority, 
-- full-featured onchip debugger 100% compatible with Zilog's OCD and ZDS-II IDE.
-- full-featured onchip debugger 100% compatible with Zilog's OCD and ZDS-II IDE.
-- It was designed to work as a SoC and everything (except the USB chip) fits inside a single FPGA (I have used an Altera 
-- It was designed to work as a SoC and everything (except the USB chip) fits inside a single FPGA (I have used an Altera 
-- Cyclone IV EP4CE6 device). The debugger connection makes use of a serial-to-USB chip (it is part of the low-cost FPGA 
-- Cyclone IV EP4CE6 device). The debugger connection makes use of a serial-to-USB chip (it is part of the low-cost FPGA 
-- board used on the project).
-- board used on the project).
-- In a near future I plan to add some more features to the device (such as a timer and maybe other peripherals).
-- In a near future I plan to add some more features to the device (such as a timer and maybe other peripherals).
-- The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using those technologies). I also 
-- The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using these technologies). I also 
-- believe the FPz8 can be a very interesting tool for learning/teaching about VHDL, computing and microprocessors/microcontrollers 
-- believe FPz8 can be a very interesting tool for learning/teaching VHDL, computing and microprocessors/microcontrollers 
-- programming.
-- programming.
 
 
-- You are free to use and to modify FPz8 to fit your needs, except for comercial use (I don't expect anyone would do that anyway).
-- You are free to use and to modify FPz8 to fit your needs, except for comercial use (I don't expect anyone would do that anyway).
-- If you want to contribute to the project, contact me and share your thoughts.
-- If you want to contribute to the project, contact me and share your thoughts.
-- Don't forget to credit the author!
-- Don't forget to credit the author!
 
 
-- Note: currently there are only a few SFRs physically implemented, they are:
-- Note: currently there are only a few SFRs physically implemented, they are:
-- 0xFC0 - IRQ0
-- 0xFC0 - IRQ0
-- 0xFC1 - IRQ0ENH
-- 0xFC1 - IRQ0ENH
-- 0xFC2 - IRQ0ENL
-- 0xFC2 - IRQ0ENL
-- 0xFCF - IRQCTL
-- 0xFCF - IRQCTL
-- 0xFD2 - PAIN
-- 0xFD2 - PAIN
-- 0xFD3 - PAOUT
-- 0xFD3 - PAOUT
-- 0xFF8 - FCTL
-- 0xFF8 - FCTL
-- 0xFFC - FLAGS
-- 0xFFC - FLAGS
-- 0xFFD - RP
-- 0xFFD - RP
-- 0xFFE - SPH
-- 0xFFE - SPH
-- 0xFFF - SPL
-- 0xFFF - SPL
-- Also notice INT7 is not physically present as it is planned to be used with the coming timer peripheral
 
 
 
-- What else is missing from the original architecture?
-- What else is missing from the original architecture?
-- A: no watchdog (WDT instruction runs as a NOP), no LDE and LDEI instructions (data memory related), no option bytes
-- A: no watchdog (WDT instruction runs as a NOP), no LDE and LDEI instructions (data memory related), no option bytes,
 
--    no data memory related debug commands, no CRC debug command, no ID bytes
 
 
-- FPz8 was tested on a EP4CE6 mini board (50MHz clock)
-- FPz8 was tested on an EP4CE6 mini board (50MHz clock)
-- http://www.ebay.com/itm/EP4CE6-Mini-Board-USB-Blaster-Altera-Cyclone-IV-FPGA-CPLD-Nano-Size-
-- http://www.ebay.com/itm/EP4CE6-Mini-Board-USB-Blaster-Altera-Cyclone-IV-FPGA-CPLD-Nano-Size-
 
 
-- This work is licensed under the Creative Commons Attribution 4.0 International License.
-- This work is licensed under the Creative Commons Attribution 4.0 International License.
-- To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
-- To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
 
 
library ieee ;
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all ;
use ieee.std_logic_unsigned.all ;
 
 
entity fpz8_cpu_v1 IS
entity fpz8_cpu_v1 IS
        port
        port
        (
        (
                IAB                     : buffer std_logic_vector(15 downto 0);  -- instruction address bus (16 bits)
                IAB                     : buffer std_logic_vector(15 downto 0);  -- instruction address bus (16 bits)
                IDB                     : in std_logic_vector(7 downto 0);               -- instruction data bus (8 bits)
                IDB                     : in std_logic_vector(7 downto 0);               -- instruction data bus (8 bits)
                PWDB            : out std_logic_vector(7 downto 0);              -- program write data bus (8 bits)
                IWDB            : out std_logic_vector(7 downto 0);              -- instruction write data bus (8 bits)
                MAB                     : buffer std_logic_vector(11 downto 0);  -- memory address bus (12 bits)
                FRAB            : buffer std_logic_vector(11 downto 0);  -- file register address bus (12 bits)
                MIDB            : in std_logic_vector(7 downto 0);               -- memory input data bus (8 bits)
                FRIDB           : in std_logic_vector(7 downto 0);               -- memory input data bus (8 bits)
                MODB            : out std_logic_vector(7 downto 0);              -- memory output data bus (8 bits)
                FRODB           : out std_logic_vector(7 downto 0);              -- memory output data bus (8 bits)
                RIDB            : in std_logic_vector(7 downto 0);               -- register input data bus (8 bits)
                RIDB            : in std_logic_vector(7 downto 0);               -- register input data bus (8 bits)
                RODB            : out std_logic_vector(7 downto 0);              -- register output data bus (8 bits)            
                RODB            : out std_logic_vector(7 downto 0);              -- register output data bus (8 bits)            
                PGM_WR          : out std_logic;                                                -- program memory write enable
                PGM_WR          : out std_logic;                                                -- program memory write enable
                WR                      : buffer std_logic;                                             -- write enable
                WR                      : buffer std_logic;                                             -- write enable
                REG_SEL         : buffer std_logic;                                             -- SFR select (addresses F00 to FFF, except internal registers)
                REG_SEL         : buffer std_logic;                                             -- SFR select (addresses F00 to FFF, except internal registers)
                MEM_SEL         : buffer std_logic;                                             -- memory select
                MEM_SEL         : buffer std_logic;                                             -- memory select
                INT0            : in std_logic;                                                 -- interrupt 0 input (vector 0x0016)
                INT0            : in std_logic;                                                 -- interrupt 0 input (vector 0x0016)
                INT1            : in std_logic;                                                 -- interrupt 1 input (vector 0x0014)
                INT1            : in std_logic;                                                 -- interrupt 1 input (vector 0x0014)
                INT2            : in std_logic;                                                 -- interrupt 2 input (vector 0x0012)
                INT2            : in std_logic;                                                 -- interrupt 2 input (vector 0x0012)
                INT3            : in std_logic;                                                 -- interrupt 3 input (vector 0x0010)
                INT3            : in std_logic;                                                 -- interrupt 3 input (vector 0x0010)
                INT4            : in std_logic;                                                 -- interrupt 4 input (vector 0x000E)
                INT4            : in std_logic;                                                 -- interrupt 4 input (vector 0x000E)
                INT5            : in std_logic;                                                 -- interrupt 5 input (vector 0x000C)
                INT5            : in std_logic;                                                 -- interrupt 5 input (vector 0x000C)
                INT6            : in std_logic;                                                 -- interrupt 6 input (vector 0x000A)
                INT6            : in std_logic;                                                 -- interrupt 6 input (vector 0x000A)
 
                INT7            : in std_logic;                                                 -- interrupt 7 input (vector 0x0008)
                DBG_RX          : in std_logic;                                                 -- debugger receive input
                DBG_RX          : in std_logic;                                                 -- debugger receive input
                DBG_TX          : buffer std_logic;                                             -- debugger transmit output
                DBG_TX          : buffer std_logic;                                             -- debugger transmit output
                PAOUT           : out std_logic_vector(7 downto 0);              -- port A output data
                PAOUT           : out std_logic_vector(7 downto 0);              -- port A output data
                PAIN            : in std_logic_vector(7 downto 0);               -- port A input data
                PAIN            : in std_logic_vector(7 downto 0);               -- port A input data
                CLK                     : in std_logic;                                                 -- main clock
                CLK                     : in std_logic;                                                 -- main clock
                CLK_OUT         : out std_logic;                                                -- main gated-clock output
                CLK_OUT         : buffer std_logic;                                             -- main clock output
                CLK_OUTN        : out std_logic;                                                -- main inverted-gated-clock output
                CLK_OUTN        : out std_logic;                                                -- main inverted clock output
                STOP            : buffer std_logic;                                             -- stop output   
                STOP            : buffer std_logic;                                             -- stop output   
 
                RESET_OUT       : out std_logic;                                                -- reset output
                RESET           : in std_logic                                                  -- CPU reset                    
                RESET           : in std_logic                                                  -- CPU reset                    
        );
        );
end fpz8_cpu_v1;
end fpz8_cpu_v1;
 
 
architecture cpu of fpz8_cpu_v1 is
architecture cpu of fpz8_cpu_v1 is
 
 
type Tinstqueue is array (0 TO 7) of std_logic_vector(7 downto 0);
type Tinstqueue is array (0 TO 7) of std_logic_vector(7 downto 0);
type Tflags is record
type Tflags is record
        C,Z,S,V,D,H,F2,F1                       : std_logic;
        C,Z,S,V,D,H,F2,F1                       : std_logic;
end record;
end record;
shared variable CPU_FLAGS, ALU_FLAGS            : Tflags;
shared variable CPU_FLAGS, ALU_FLAGS            : Tflags;
shared variable ALU_NOUPDATE                            : std_logic;
shared variable ALU_NOUPDATE                            : std_logic;
shared variable INT7                                            : std_logic;
 
shared variable IRQE                                            : std_logic;
shared variable IRQE                                            : std_logic;
shared variable HALT                                            : std_logic;
 
shared variable IRQ0                                            : std_logic_vector(7 downto 0);          -- interrupts 0-7 flags
shared variable IRQ0                                            : std_logic_vector(7 downto 0);          -- interrupts 0-7 flags
shared variable IRQ0ENH,IRQ0ENL                         : std_logic_vector(7 downto 0);          -- interrupts 0-7 enable high and low
shared variable IRQ0ENH,IRQ0ENL                         : std_logic_vector(7 downto 0);          -- interrupts 0-7 enable high and low
shared variable SP                                                      : std_logic_vector(11 downto 0); -- stack pointer
shared variable SP                                                      : std_logic_vector(11 downto 0); -- stack pointer
shared variable RP                                                      : std_logic_vector(7 downto 0);          -- register pointer
shared variable RP                                                      : std_logic_vector(7 downto 0);          -- register pointer
shared variable FCTL                                            : std_logic_vector(7 downto 0);          -- flash control
shared variable FCTL                                            : std_logic_vector(7 downto 0);          -- flash control
shared variable PAOUT_BUFFER                            : std_logic_vector(7 downto 0);
shared variable PAOUT_BUFFER                            : std_logic_vector(7 downto 0);
signal                  RXSYNC1, RXSYNC2                        : std_logic;
signal                  RXSYNC1, RXSYNC2                        : std_logic;
ATTRIBUTE preserve                                                      : boolean;
ATTRIBUTE preserve                                                      : boolean;
ATTRIBUTE preserve OF RXSYNC1                           : signal IS true;
ATTRIBUTE preserve OF RXSYNC1                           : signal IS true;
ATTRIBUTE preserve OF RXSYNC2                           : signal IS true;
ATTRIBUTE preserve OF RXSYNC2                           : signal IS true;
 
signal IRQ0_LATCH                                                       : std_logic_vector(7 downto 0);          -- current state of IRQ inputs
 
attribute preserve of IRQ0_LATCH                        : signal is true;
 
 
constant ALU_ADD        : std_logic_vector(3 downto 0):=x"0";     -- CZSVH D=0
constant ALU_ADD        : std_logic_vector(3 downto 0):=x"0";     -- CZSVH D=0
constant ALU_ADC        : std_logic_vector(3 downto 0):=x"1";    -- CZSVH D=0
constant ALU_ADC        : std_logic_vector(3 downto 0):=x"1";    -- CZSVH D=0
constant ALU_SUB        : std_logic_vector(3 downto 0):=x"2";    -- CZSVH D=1
constant ALU_SUB        : std_logic_vector(3 downto 0):=x"2";    -- CZSVH D=1
constant ALU_SBC        : std_logic_vector(3 downto 0):=x"3";    -- CZSVH D=1
constant ALU_SBC        : std_logic_vector(3 downto 0):=x"3";    -- CZSVH D=1
constant ALU_OR         : std_logic_vector(3 downto 0):=x"4";    -- ZS V=0
constant ALU_OR         : std_logic_vector(3 downto 0):=x"4";    -- ZS V=0
constant ALU_AND        : std_logic_vector(3 downto 0):=x"5";    -- ZS V=0
constant ALU_AND        : std_logic_vector(3 downto 0):=x"5";    -- ZS V=0
constant ALU_TCM        : std_logic_vector(3 downto 0):=x"6";    -- ZS V=0
constant ALU_TCM        : std_logic_vector(3 downto 0):=x"6";    -- ZS V=0
constant ALU_TM         : std_logic_vector(3 downto 0):=x"7";    -- ZS V=0
constant ALU_TM         : std_logic_vector(3 downto 0):=x"7";    -- ZS V=0
constant ALU_CPC        : std_logic_vector(3 downto 0):=x"9";    -- CZSV
constant ALU_CPC        : std_logic_vector(3 downto 0):=x"9";    -- CZSV
constant ALU_CP         : std_logic_vector(3 downto 0):=x"A";    -- CZSV
constant ALU_CP         : std_logic_vector(3 downto 0):=x"A";    -- CZSV
constant ALU_XOR        : std_logic_vector(3 downto 0):=x"B";    -- ZS V=0
constant ALU_XOR        : std_logic_vector(3 downto 0):=x"B";    -- ZS V=0
constant ALU_BSWAP  : std_logic_vector(3 downto 0):=x"D";        -- ZS V=0
constant ALU_BSWAP  : std_logic_vector(3 downto 0):=x"D";        -- ZS V=0
constant ALU_LD         : std_logic_vector(3 downto 0):=x"E";    -- Load does not change any flag
constant ALU_LD         : std_logic_vector(3 downto 0):=x"E";    -- Load does not change any flag
 
 
constant LU2_RLC        : std_logic_vector(3 downto 0):=x"1";    -- CZSV
constant LU2_RLC        : std_logic_vector(3 downto 0):=x"1";    -- CZSV
constant LU2_INC        : std_logic_vector(3 downto 0):=x"2";    -- ZSV
constant LU2_INC        : std_logic_vector(3 downto 0):=x"2";    -- ZSV
constant LU2_DEC        : std_logic_vector(3 downto 0):=x"3";    -- ZSV
constant LU2_DEC        : std_logic_vector(3 downto 0):=x"3";    -- ZSV
constant LU2_DA         : std_logic_vector(3 downto 0):=x"4";    -- CZS
constant LU2_DA         : std_logic_vector(3 downto 0):=x"4";    -- CZS
constant LU2_COM        : std_logic_vector(3 downto 0):=x"6";    -- ZS V=0
constant LU2_COM        : std_logic_vector(3 downto 0):=x"6";    -- ZS V=0
constant LU2_LD         : std_logic_vector(3 downto 0):=x"7";    -- Load does not change any flag
constant LU2_LD         : std_logic_vector(3 downto 0):=x"7";    -- Load does not change any flag
constant LU2_RL         : std_logic_vector(3 downto 0):=x"9";    -- CZSV
constant LU2_RL         : std_logic_vector(3 downto 0):=x"9";    -- CZSV
constant LU2_SRL        : std_logic_vector(3 downto 0):=x"A";    -- CZSV
constant LU2_SRL        : std_logic_vector(3 downto 0):=x"A";    -- CZSV
constant LU2_CLR        : std_logic_vector(3 downto 0):=x"B";    -- Clear does not change any flag
constant LU2_CLR        : std_logic_vector(3 downto 0):=x"B";    -- Clear does not change any flag
constant LU2_RRC        : std_logic_vector(3 downto 0):=x"C";    -- CZSV
constant LU2_RRC        : std_logic_vector(3 downto 0):=x"C";    -- CZSV
constant LU2_SRA        : std_logic_vector(3 downto 0):=x"D";    -- CZSV
constant LU2_SRA        : std_logic_vector(3 downto 0):=x"D";    -- CZSV
constant LU2_RR         : std_logic_vector(3 downto 0):=x"E";    -- CZSV
constant LU2_RR         : std_logic_vector(3 downto 0):=x"E";    -- CZSV
constant LU2_SWAP       : std_logic_vector(3 downto 0):=x"F";    -- ZS
constant LU2_SWAP       : std_logic_vector(3 downto 0):=x"F";    -- ZS
 
 
-- Debug commands
-- Debug commands
constant DBGCMD_READ_REV                : std_logic_vector(7 downto 0):=x"00";
constant DBGCMD_READ_REV                : std_logic_vector(7 downto 0):=x"00";
constant DBGCMD_READ_STATUS             : std_logic_vector(7 downto 0):=x"02";
constant DBGCMD_READ_STATUS             : std_logic_vector(7 downto 0):=x"02";
constant DBGCMD_READ_RUNCOUNTER : std_logic_vector(7 downto 0):=x"03";
constant DBGCMD_READ_RUNCOUNTER : std_logic_vector(7 downto 0):=x"03";
constant DBGCMD_WRITE_CTRL              : std_logic_vector(7 downto 0):=x"04";
constant DBGCMD_WRITE_CTRL              : std_logic_vector(7 downto 0):=x"04";
constant DBGCMD_READ_CTRL               : std_logic_vector(7 downto 0):=x"05";
constant DBGCMD_READ_CTRL               : std_logic_vector(7 downto 0):=x"05";
constant DBGCMD_WRITE_PC                : std_logic_vector(7 downto 0):=x"06";
constant DBGCMD_WRITE_PC                : std_logic_vector(7 downto 0):=x"06";
constant DBGCMD_READ_PC                 : std_logic_vector(7 downto 0):=x"07";
constant DBGCMD_READ_PC                 : std_logic_vector(7 downto 0):=x"07";
constant DBGCMD_WRITE_REG               : std_logic_vector(7 downto 0):=x"08";
constant DBGCMD_WRITE_REG               : std_logic_vector(7 downto 0):=x"08";
constant DBGCMD_READ_REG                : std_logic_vector(7 downto 0):=x"09";
constant DBGCMD_READ_REG                : std_logic_vector(7 downto 0):=x"09";
constant DBGCMD_WRITE_PROGRAM   : std_logic_vector(7 downto 0):=x"0A";
constant DBGCMD_WRITE_PROGRAM   : std_logic_vector(7 downto 0):=x"0A";
constant DBGCMD_READ_PROGRAM    : std_logic_vector(7 downto 0):=x"0B";
constant DBGCMD_READ_PROGRAM    : std_logic_vector(7 downto 0):=x"0B";
constant DBGCMD_READ_CRC                : std_logic_vector(7 downto 0):=x"0E";
constant DBGCMD_READ_CRC                : std_logic_vector(7 downto 0):=x"0E";
constant DBGCMD_STEP                    : std_logic_vector(7 downto 0):=x"10";
constant DBGCMD_STEP                    : std_logic_vector(7 downto 0):=x"10";
constant DBGCMD_STUFF                   : std_logic_vector(7 downto 0):=x"11";
constant DBGCMD_STUFF                   : std_logic_vector(7 downto 0):=x"11";
constant DBGCMD_EXEC                    : std_logic_vector(7 downto 0):=x"12";
constant DBGCMD_EXEC                    : std_logic_vector(7 downto 0):=x"12";
 
 
-- DATAWRITE controls where data to be written actually goes (an internal register, an external register (through register data bus) or RAM)
-- DATAWRITE controls where data to be written actually goes (an internal register, an external register (through register data bus) or RAM)
procedure DATAWRITE
procedure DATAWRITE
        (       ADDRESS : in std_logic_vector(11 downto 0);
        (       ADDRESS : in std_logic_vector(11 downto 0);
                DATA    : in std_logic_vector(7 downto 0)) is
                DATA    : in std_logic_vector(7 downto 0)) is
begin
begin
        if (ADDRESS>=x"F00") then               ----------------------------------------------- it is a SFR address
        if (ADDRESS>=x"F00") then               ----------------------------------------------- it is a SFR address
                if (ADDRESS=x"FFC") then        ---------------------------------------------------- FLAGS register
                if (ADDRESS=x"FFC") then        ---------------------------------------------------- FLAGS register
                        CPU_FLAGS.C := DATA(7);
                        CPU_FLAGS.C := DATA(7);
                        CPU_FLAGS.Z := DATA(6);
                        CPU_FLAGS.Z := DATA(6);
                        CPU_FLAGS.S := DATA(5);
                        CPU_FLAGS.S := DATA(5);
                        CPU_FLAGS.V := DATA(4);
                        CPU_FLAGS.V := DATA(4);
                        CPU_FLAGS.D := DATA(3);
                        CPU_FLAGS.D := DATA(3);
                        CPU_FLAGS.H := DATA(2);
                        CPU_FLAGS.H := DATA(2);
                        CPU_FLAGS.F2 := DATA(1);
                        CPU_FLAGS.F2 := DATA(1);
                        CPU_FLAGS.F1 := DATA(0);
                        CPU_FLAGS.F1 := DATA(0);
                elsif (ADDRESS=x"FFD") then RP := DATA; ------------------------------------------- RP register
                elsif (ADDRESS=x"FFD") then RP := DATA; ------------------------------------------- RP register
                elsif (ADDRESS=x"FFE") then SP(11 downto 8) := DATA(3 downto 0); -------------- SPH register
                elsif (ADDRESS=x"FFE") then SP(11 downto 8) := DATA(3 downto 0); -------------- SPH register
                elsif (ADDRESS=x"FFF") then SP(7 downto 0) := DATA;      ------------------------------ SPL register
                elsif (ADDRESS=x"FFF") then SP(7 downto 0) := DATA;      ------------------------------ SPL register
                elsif (ADDRESS=x"FF8") then     ----------------------------------------------------- FCTL register
                elsif (ADDRESS=x"FF8") then     ----------------------------------------------------- FCTL register
                        if (DATA=x"73") then FCTL:=x"01";
                        if (DATA=x"73") then FCTL:=x"01";
                        elsif (DATA=x"8C" and FCTL=x"01") then FCTL:=x"03";
                        elsif (DATA=x"8C" and FCTL=x"01") then FCTL:=x"03";
                        elsif (DATA=x"95") then FCTL:=x"04";
                        elsif (DATA=x"95") then FCTL:=x"04";
                        else FCTL:=x"00";
                        else FCTL:=x"00";
                        end if;
                        end if;
                elsif (ADDRESS=x"FC0") then     IRQ0 := DATA; --------------------------------------- IRQ0 register
                elsif (ADDRESS=x"FC0") then     IRQ0 := DATA; --------------------------------------- IRQ0 register
                elsif (ADDRESS=x"FC1") then IRQ0ENH := DATA;    ------------------------------ IRQ0ENH register
                elsif (ADDRESS=x"FC1") then IRQ0ENH := DATA;    ------------------------------ IRQ0ENH register
                elsif (ADDRESS=x"FC2") then IRQ0ENL := DATA;    ------------------------------ IRQ0ENL register
                elsif (ADDRESS=x"FC2") then IRQ0ENL := DATA;    ------------------------------ IRQ0ENL register
                elsif (ADDRESS=x"FCF") then     IRQE := DATA(7);        ------------------------------- IRQCTL register
                elsif (ADDRESS=x"FCF") then     IRQE := DATA(7);        ------------------------------- IRQCTL register
                elsif (ADDRESS=x"FD3") then ---------------------------------------------------- PAOUT register
                elsif (ADDRESS=x"FD3") then ---------------------------------------------------- PAOUT register
                        PAOUT <= DATA;
                        PAOUT <= DATA;
                        PAOUT_BUFFER := DATA;
                        PAOUT_BUFFER := DATA;
                else
                else -- if it is not an internal SFR but ADDRESS>=0xF00 then it is an external register
                        REG_SEL <= '1';
                        REG_SEL <= '1'; -- enable external register select
                        RODB <= DATA;
                        RODB <= DATA;   -- output data on register output data bus
                end if;
                end if;
        else
        else    -- if ADDRESS < 0xF00 then it is a RAM register
                MEM_SEL <= '1';
                MEM_SEL <= '1';         -- enable external memory select
                MODB <= DATA;
                FRODB <= DATA;          -- output data on file register output data bus
        end if;
        end if;
end datawrite;
end datawrite;
 
 
-- DATAREAD controls where the data to be read actually comes from (an internal register, an external register (through register data bus) or RAM)
-- DATAREAD controls where the data to be read actually comes from (an internal register, an external register (through register data bus) or RAM)
impure function DATAREAD
impure function DATAREAD
        (ADDRESS        : in std_logic_vector(11 downto 0))
        (ADDRESS        : in std_logic_vector(11 downto 0))
        return std_logic_vector is
        return std_logic_vector is
begin
begin
        if (ADDRESS>=x"F00") then       -------------------------------- it is a SFR address
        if (ADDRESS>=x"F00") then       -------------------------------- it is a SFR address
                if (ADDRESS=x"FFC") then        --------------------------------- FLAGS register
                if (ADDRESS=x"FFC") then        --------------------------------- FLAGS register
                        return (CPU_FLAGS.C,CPU_FLAGS.Z,CPU_FLAGS.S,CPU_FLAGS.V,CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.F2,CPU_FLAGS.F1);
                        return (CPU_FLAGS.C,CPU_FLAGS.Z,CPU_FLAGS.S,CPU_FLAGS.V,CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.F2,CPU_FLAGS.F1);
                elsif (ADDRESS=x"FFD") then return RP;  ------------------------ RP register
                elsif (ADDRESS=x"FFD") then return RP;  ------------------------ RP register
                elsif (ADDRESS=x"FFE") then     ----------------------------------- SPH register
                elsif (ADDRESS=x"FFE") then     ----------------------------------- SPH register
                        return "0000" & SP(11 downto 8);
                        return "0000" & SP(11 downto 8);
                elsif (ADDRESS=x"FFF") then return SP(7 downto 0);       ----------- SPL register
                elsif (ADDRESS=x"FFF") then return SP(7 downto 0);       ----------- SPL register
                elsif (ADDRESS=x"FF8") then return FCTL;        ------------------ FCTL register
                elsif (ADDRESS=x"FF8") then return FCTL;        ------------------ FCTL register
                elsif (ADDRESS=x"FC0") then     return IRQ0;    ------------------ IRQ0 register
                elsif (ADDRESS=x"FC0") then     return IRQ0;    ------------------ IRQ0 register
                elsif (ADDRESS=x"FC1") then return IRQ0ENH;     --------------- IRQ0ENH register
                elsif (ADDRESS=x"FC1") then return IRQ0ENH;     --------------- IRQ0ENH register
                elsif (ADDRESS=x"FC2") then return IRQ0ENL;     --------------- IRQ0ENL register
                elsif (ADDRESS=x"FC2") then return IRQ0ENL;     --------------- IRQ0ENL register
                elsif (ADDRESS=x"FCF") then return IRQE&"0000000";      -------- IRQCTL register
                elsif (ADDRESS=x"FCF") then return IRQE&"0000000";      -------- IRQCTL register
                elsif (ADDRESS=x"FD2") then return PAIN;        ------------------ PAIN register
                elsif (ADDRESS=x"FD2") then return PAIN;        ------------------ PAIN register
                elsif (ADDRESS=x"FD3") then return PAOUT_BUFFER;        --------- PAOUT register
                elsif (ADDRESS=x"FD3") then return PAOUT_BUFFER;        --------- PAOUT register
                else
                else
                        REG_SEL <= '1';
                        REG_SEL <= '1';
                        return RIDB;
                        return RIDB;
                end if;
                end if;
        else
        else
                MEM_SEL <= '1';
                MEM_SEL <= '1';
                return MIDB;
                return FRIDB;
        end if;
        end if;
end DATAREAD;
end DATAREAD;
 
 
-- CONDITIONCODE returns the result of a logical condition (for conditional jumps)
-- CONDITIONCODE returns the result of a logical condition (for conditional jumps)
function CONDITIONCODE
function CONDITIONCODE
        (       CONDITION       : in std_logic_vector(3 downto 0)) return STD_LOGIC is
        (       CONDITION       : in std_logic_vector(3 downto 0)) return STD_LOGIC is
begin
begin
        case CONDITION is
        case CONDITION is
                when x"0" =>
                when x"0" =>
                        return '0';
                        return '0';
                when x"1" =>
                when x"1" =>
                        return ALU_FLAGS.S xor ALU_FLAGS.V;
                        return CPU_FLAGS.S xor CPU_FLAGS.V;
                when x"2" =>
                when x"2" =>
                        return ALU_FLAGS.Z or (ALU_FLAGS.S xor ALU_FLAGS.V);
                        return CPU_FLAGS.Z or (CPU_FLAGS.S xor CPU_FLAGS.V);
                when x"3" =>
                when x"3" =>
                        return ALU_FLAGS.C or ALU_FLAGS.Z;
                        return CPU_FLAGS.C or CPU_FLAGS.Z;
                when x"4" =>
                when x"4" =>
                        return ALU_FLAGS.V;
                        return CPU_FLAGS.V;
                when x"5" =>
                when x"5" =>
                        return ALU_FLAGS.S;
                        return CPU_FLAGS.S;
                when x"6" =>
                when x"6" =>
                        return ALU_FLAGS.Z;
                        return CPU_FLAGS.Z;
                when x"7" =>
                when x"7" =>
                        return ALU_FLAGS.C;
                        return CPU_FLAGS.C;
                when x"8" =>
                when x"8" =>
                        return '1';
                        return '1';
                when x"9" =>
                when x"9" =>
                        return NOT (ALU_FLAGS.S xor ALU_FLAGS.V);
                        return NOT (CPU_FLAGS.S xor CPU_FLAGS.V);
                when x"A" =>
                when x"A" =>
                        return NOT (ALU_FLAGS.Z or (ALU_FLAGS.S xor ALU_FLAGS.V));
                        return NOT (CPU_FLAGS.Z or (CPU_FLAGS.S xor CPU_FLAGS.V));
                when x"B" =>
                when x"B" =>
                        return (NOT ALU_FLAGS.C) AND (NOT ALU_FLAGS.Z);
                        return (NOT CPU_FLAGS.C) AND (NOT CPU_FLAGS.Z);
                when x"C" =>
                when x"C" =>
                        return NOT ALU_FLAGS.V;
                        return NOT CPU_FLAGS.V;
                when x"D" =>
                when x"D" =>
                        return NOT ALU_FLAGS.S;
                        return NOT CPU_FLAGS.S;
                when x"E" =>
                when x"E" =>
                        return NOT ALU_FLAGS.Z;
                        return NOT CPU_FLAGS.Z;
                when others =>
                when others =>
                        return NOT ALU_FLAGS.C;
                        return NOT CPU_FLAGS.C;
        end case;
        end case;
end CONDITIONCODE;
end CONDITIONCODE;
 
 
-- ADDRESSER12 generates a 12-bit address (it decides when to use escaped addressing mode)
-- ADDRESSER12 generates a 12-bit address (it decides when to use escaped addressing mode)
function ADDRESSER12
function ADDRESSER12
        (       ADDR    : in std_logic_vector(11 downto 0)) return std_logic_vector is
        (       ADDR    : in std_logic_vector(11 downto 0)) return std_logic_vector is
begin
begin
        if (ADDR(11 downto 4)=x"EE") then               -- escaped addressing mode (work register)
        if (ADDR(11 downto 4)=x"EE") then               -- escaped addressing mode (work register)
                return RP(3 downto 0) & RP(7 downto 4) & ADDR(3 downto 0);
                return RP(3 downto 0) & RP(7 downto 4) & ADDR(3 downto 0);
        elsif (ADDR(11 downto 8)=x"E") then             -- escaped addressing mode (register)
        elsif (ADDR(11 downto 8)=x"E") then             -- escaped addressing mode (register)
                return RP(3 downto 0) & ADDR(7 downto 0);
                return RP(3 downto 0) & ADDR(7 downto 0);
        else return ADDR;                                               -- full address
        else return ADDR;                                               -- full address
        end if;
        end if;
end ADDRESSER12;
end ADDRESSER12;
 
 
-- ADDRESSER8 generates a 12-bit address from an 8-bit address (it decides when to use escaped addressing mode)
-- ADDRESSER8 generates a 12-bit address from an 8-bit address (it decides when to use escaped addressing mode)
function ADDRESSER8
function ADDRESSER8
        (       ADDR    : in std_logic_vector(7 downto 0)) return std_logic_vector is
        (       ADDR    : in std_logic_vector(7 downto 0)) return std_logic_vector is
begin
begin
        if (ADDR(7 downto 4)=x"E") then         -- escaped addressing mode (register)
        if (ADDR(7 downto 4)=x"E") then         -- escaped addressing mode (register)
                return RP(3 downto 0) & RP(7 downto 4) & ADDR(3 downto 0);
                return RP(3 downto 0) & RP(7 downto 4) & ADDR(3 downto 0);
        else return RP(3 downto 0) & ADDR(7 downto 0);    -- full address
        else return RP(3 downto 0) & ADDR(7 downto 0);    -- full address
        end if;
        end if;
end ADDRESSER8;
end ADDRESSER8;
 
 
-- ADDRESSER12 generates a 12-bit address from a 4-bit address (using RP register)
-- ADDRESSER4 generates a 12-bit address from a 4-bit address (using RP register)
function ADDRESSER4
function ADDRESSER4
        (       ADDR    : in std_logic_vector(3 downto 0)) return std_logic_vector is
        (       ADDR    : in std_logic_vector(3 downto 0)) return std_logic_vector is
begin
begin
        return RP(3 downto 0) & RP(7 downto 4) & ADDR;
        return RP(3 downto 0) & RP(7 downto 4) & ADDR;
end ADDRESSER4;
end ADDRESSER4;
 
 
-- ALU is the arithmetic and logic unit, it receives two 8-bit operands along with a 4-bit operation code and a carry input, returning an 8-bit result
-- ALU is the arithmetic and logic unit, it receives two 8-bit operands along with a 4-bit operation code and a carry input, returning an 8-bit result
function ALU
function ALU
        (       ALU_OP  : in std_logic_vector(3 downto 0);
        (       ALU_OP  : in std_logic_vector(3 downto 0);
                OPER1   : in std_logic_vector(7 downto 0);
                OPER1   : in std_logic_vector(7 downto 0);
                OPER2   : in std_logic_vector(7 downto 0);
                OPER2   : in std_logic_vector(7 downto 0);
                CIN             : in STD_LOGIC) return std_logic_vector is
                CIN             : in STD_LOGIC) return std_logic_vector is
variable RESULT : std_logic_vector(7 downto 0);
variable RESULT : std_logic_vector(7 downto 0);
variable HALF1,HALF2    : std_logic_vector(4 downto 0);
variable HALF1,HALF2    : std_logic_vector(4 downto 0);
begin
begin
        ALU_NOUPDATE := '0';
        ALU_NOUPDATE := '0';
        case ALU_OP is
        case ALU_OP is
                when ALU_ADD =>         -- ADD operation **************************************************
                when ALU_ADD =>         -- ADD operation **************************************************
                        HALF1 := ('0'&OPER1(3 downto 0))+('0'&OPER2(3 downto 0));
                        HALF1 := ('0'&OPER1(3 downto 0))+('0'&OPER2(3 downto 0));
                        ALU_FLAGS.H := HALF1(4);
                        ALU_FLAGS.H := HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))+('0'&OPER2(7 downto 4))+HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))+('0'&OPER2(7 downto 4))+HALF1(4);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        ALU_FLAGS.C := HALF2(4);
                        ALU_FLAGS.C := HALF2(4);
                        if (OPER1(7)=OPER2(7)) then
                        if (OPER1(7)=OPER2(7)) then
                                if (OPER1(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                if (OPER1(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                end if;
                                end if;
                        else ALU_FLAGS.V:='0';
                        else ALU_FLAGS.V:='0';
                        end if;
                        end if;
                when ALU_ADC =>         -- ADC operation **************************************************
                when ALU_ADC =>         -- ADC operation **************************************************
                        HALF1 := ('0'&OPER1(3 downto 0))+('0'&OPER2(3 downto 0)+(CIN));
                        HALF1 := ('0'&OPER1(3 downto 0))+('0'&OPER2(3 downto 0)+(CIN));
                        ALU_FLAGS.H := HALF1(4);
                        ALU_FLAGS.H := HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))+('0'&OPER2(7 downto 4))+HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))+('0'&OPER2(7 downto 4))+HALF1(4);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        ALU_FLAGS.C := HALF2(4);
                        ALU_FLAGS.C := HALF2(4);
                        if (OPER1(7)=OPER2(7)) then
                        if (OPER1(7)=OPER2(7)) then
                                if (OPER1(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                if (OPER1(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                end if;
                                end if;
                        else ALU_FLAGS.V:='0';
                        else ALU_FLAGS.V:='0';
                        end if;
                        end if;
                when ALU_SUB =>         -- SUB operation **************************************************
                when ALU_SUB =>         -- SUB operation **************************************************
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)));
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)));
                        ALU_FLAGS.H := (HALF1(4));
                        ALU_FLAGS.H := (HALF1(4));
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        ALU_FLAGS.C := (HALF2(4));
                        ALU_FLAGS.C := (HALF2(4));
                        if (OPER1(7)/=OPER2(7)) then
                        if (OPER1(7)/=OPER2(7)) then
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                end if;
                                end if;
                        else ALU_FLAGS.V:='0';
                        else ALU_FLAGS.V:='0';
                        end if;
                        end if;
                when ALU_SBC =>         -- SBC operation **************************************************
                when ALU_SBC =>         -- SBC operation **************************************************
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)))-CIN;
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)))-CIN;
                        ALU_FLAGS.H := (HALF1(4));
                        ALU_FLAGS.H := (HALF1(4));
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        ALU_FLAGS.C := (HALF2(4));
                        ALU_FLAGS.C := (HALF2(4));
                        if (OPER1(7)/=OPER2(7)) then
                        if (OPER1(7)/=OPER2(7)) then
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                end if;
                                end if;
                        else ALU_FLAGS.V:='0';
                        else ALU_FLAGS.V:='0';
                        end if;
                        end if;
                when ALU_OR =>  -- Logical or operation ***********************************************
                when ALU_OR =>  -- Logical or operation ***********************************************
                        RESULT := OPER1 or OPER2;
                        RESULT := OPER1 or OPER2;
                when ALU_AND => -- Logical AND operation **********************************************
                when ALU_AND => -- Logical AND operation **********************************************
                        RESULT := OPER1 AND OPER2;
                        RESULT := OPER1 AND OPER2;
                when ALU_TCM => -- Test Complement Mask operation *************************************
                when ALU_TCM => -- Test Complement Mask operation *************************************
                        RESULT := (NOT OPER1) AND OPER2;
                        RESULT := (NOT OPER1) AND OPER2;
                        ALU_NOUPDATE := '1';
                        ALU_NOUPDATE := '1';
                when ALU_TM =>  -- Test Mask operation ************************************************
                when ALU_TM =>  -- Test Mask operation ************************************************
                        RESULT := OPER1 AND OPER2;
                        RESULT := OPER1 AND OPER2;
                        ALU_NOUPDATE := '1';
                        ALU_NOUPDATE := '1';
                when ALU_CPC =>         -- CPC operation **************************************************
                when ALU_CPC =>         -- CPC operation **************************************************
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)))-CIN;
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)))-CIN;
                        ALU_FLAGS.H := (HALF1(4));
                        ALU_FLAGS.H := (HALF1(4));
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        ALU_FLAGS.C := (HALF2(4));
                        ALU_FLAGS.C := (HALF2(4));
                        if (OPER1(7)/=OPER2(7)) then
                        if (OPER1(7)/=OPER2(7)) then
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                end if;
                                end if;
                        else ALU_FLAGS.V:='0';
                        else ALU_FLAGS.V:='0';
                        end if;
                        end if;
                        ALU_NOUPDATE := '1';
                        ALU_NOUPDATE := '1';
                when ALU_CP =>  -- Compare operation **************************************************
                when ALU_CP =>  -- Compare operation **************************************************
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)));
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)));
                        ALU_FLAGS.H := (HALF1(4));
                        ALU_FLAGS.H := (HALF1(4));
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
                        ALU_FLAGS.C := (HALF2(4));
                        ALU_FLAGS.C := (HALF2(4));
                        if (OPER1(7)/=OPER2(7)) then
                        if (OPER1(7)/=OPER2(7)) then
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
                                end if;
                                end if;
                        else ALU_FLAGS.V:='0';
                        else ALU_FLAGS.V:='0';
                        end if;
                        end if;
                        ALU_NOUPDATE := '1';
                        ALU_NOUPDATE := '1';
                when ALU_XOR => -- Logical xor operation **********************************************
                when ALU_XOR => -- Logical xor operation **********************************************
                        RESULT := OPER1 xor OPER2;
                        RESULT := OPER1 xor OPER2;
                when ALU_BSWAP =>       -- Bit Swap operation *********************************************
                when ALU_BSWAP =>       -- Bit Swap operation *********************************************
                        RESULT := OPER2(0)&OPER2(1)&OPER2(2)&OPER2(3)&OPER2(4)&OPER2(5)&OPER2(6)&OPER2(7);
                        RESULT := OPER2(0)&OPER2(1)&OPER2(2)&OPER2(3)&OPER2(4)&OPER2(5)&OPER2(6)&OPER2(7);
                when others =>  -- Load operation *****************************************************
                when others =>  -- Load operation *****************************************************
                        RESULT := OPER2;
                        RESULT := OPER2;
 
 
        end case;
        end case;
        if (RESULT(7 downto 0)=x"00") then ALU_FLAGS.Z := '1'; else ALU_FLAGS.Z := '0';
        if (RESULT(7 downto 0)=x"00") then ALU_FLAGS.Z := '1'; else ALU_FLAGS.Z := '0';
        end if;
        end if;
        ALU_FLAGS.S := RESULT(7);
        ALU_FLAGS.S := RESULT(7);
        return RESULT(7 downto 0);
        return RESULT(7 downto 0);
end ALU;
end ALU;
 
 
-- LU2 is the second logic unit, it performs mostly logical operations not covered by the ALU
-- LU2 is the second logic unit, it performs mostly logical operations not covered by the ALU
function LU2
function LU2
        (       LU2_OP  : in std_logic_vector(3 downto 0);
        (       LU2_OP  : in std_logic_vector(3 downto 0);
                OPER    : in std_logic_vector(7 downto 0);
                OPER    : in std_logic_vector(7 downto 0);
                DIN             : in std_logic;
                DIN             : in std_logic;
                HIN             : in std_logic;
                HIN             : in std_logic;
                CIN             : in std_logic) return std_logic_vector is
                CIN             : in std_logic) return std_logic_vector is
variable RESULT : std_logic_vector(7 downto 0);
variable RESULT : std_logic_vector(7 downto 0);
begin
begin
        case LU2_OP is
        case LU2_OP is
                when LU2_RLC =>         -- RLC operation **************************************************
                when LU2_RLC =>         -- RLC operation **************************************************
                        ALU_FLAGS.C := OPER(7);
                        ALU_FLAGS.C := OPER(7);
                        RESULT := OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1)&OPER(0)&CIN;
                        RESULT := OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1)&OPER(0)&CIN;
                when LU2_INC =>         -- INC operation **************************************************
                when LU2_INC =>         -- INC operation **************************************************
                        RESULT := OPER+1;
                        RESULT := OPER+1;
                        if (RESULT=x"00") then ALU_FLAGS.C:='1'; else ALU_FLAGS.C:='0';
                        if (RESULT=x"00") then ALU_FLAGS.C:='1'; else ALU_FLAGS.C:='0';
                        end if;
                        end if;
                when LU2_DEC =>         -- DEC operation **************************************************
                when LU2_DEC =>         -- DEC operation **************************************************
                        RESULT := OPER-1;
                        RESULT := OPER-1;
                        if (RESULT=x"FF") then ALU_FLAGS.C:='1'; else ALU_FLAGS.C:='0';
                        if (RESULT=x"FF") then ALU_FLAGS.C:='1'; else ALU_FLAGS.C:='0';
                        end if;
                        end if;
                when LU2_DA =>          -- DA operation ***************************************************
                when LU2_DA =>          -- DA operation ***************************************************
                        if (DIN='0') then        -- decimal adjust following an add operation
                        if (DIN='0') then        -- decimal adjust following an add operation
                                if (OPER(3 downto 0)>x"9" or HIN='1') then
                                if (OPER(3 downto 0)>x"9" or HIN='1') then
                                        RESULT := ALU(ALU_ADD,OPER,x"06",'0');
                                        RESULT := ALU(ALU_ADD,OPER,x"06",'0');
                                else RESULT := OPER;
                                else RESULT := OPER;
                                end if;
                                end if;
                                if (RESULT(7 downto 4)>x"9" or ALU_FLAGS.C='1') then
                                if (RESULT(7 downto 4)>x"9" or ALU_FLAGS.C='1') then
                                        RESULT := ALU(ALU_ADD,RESULT,x"60",'0');
                                        RESULT := ALU(ALU_ADD,RESULT,x"60",'0');
                                end if;
                                end if;
                        else    -------------- decimal adjust following a sub operation
                        else    -------------- decimal adjust following a sub operation
                        end if;
                        end if;
                when LU2_COM =>         -- COM operation **************************************************
                when LU2_COM =>         -- COM operation **************************************************
                        RESULT := NOT OPER;
                        RESULT := NOT OPER;
                when LU2_RL =>          -- RL operation ***************************************************
                when LU2_RL =>          -- RL operation ***************************************************
                        ALU_FLAGS.C := OPER(7);
                        ALU_FLAGS.C := OPER(7);
                        RESULT := OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1)&OPER(0)&ALU_FLAGS.C;
                        RESULT := OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1)&OPER(0)&ALU_FLAGS.C;
                when LU2_SRL =>         -- SRL operation **************************************************
                when LU2_SRL =>         -- SRL operation **************************************************
                        ALU_FLAGS.C := OPER(0);
                        ALU_FLAGS.C := OPER(0);
                        RESULT := '0'&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                        RESULT := '0'&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                when LU2_RRC =>         -- RRC operation **************************************************
                when LU2_RRC =>         -- RRC operation **************************************************
                        ALU_FLAGS.C := OPER(0);
                        ALU_FLAGS.C := OPER(0);
                        RESULT := CIN&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                        RESULT := CIN&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                when LU2_RR =>          -- RR operation ***************************************************
                when LU2_RR =>          -- RR operation ***************************************************
                        ALU_FLAGS.C := OPER(0);
                        ALU_FLAGS.C := OPER(0);
                        RESULT := ALU_FLAGS.C&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                        RESULT := ALU_FLAGS.C&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                when LU2_SRA =>         -- SRA operation **************************************************
                when LU2_SRA =>         -- SRA operation **************************************************
                        ALU_FLAGS.C := OPER(0);
                        ALU_FLAGS.C := OPER(0);
                        RESULT := OPER(7)&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                        RESULT := OPER(7)&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
                when LU2_SWAP =>        -- SWAP operation *************************************************
                when LU2_SWAP =>        -- SWAP operation *************************************************
                        RESULT := OPER(3)&OPER(2)&OPER(1)&OPER(0)&OPER(7)&OPER(6)&OPER(5)&OPER(4);
                        RESULT := OPER(3)&OPER(2)&OPER(1)&OPER(0)&OPER(7)&OPER(6)&OPER(5)&OPER(4);
                when LU2_LD =>          -- LOAD operation *************************************************
                when LU2_LD =>          -- LOAD operation *************************************************
                        RESULT := OPER;
                        RESULT := OPER;
                when others =>          -- CLR operation **************************************************
                when others =>          -- CLR operation **************************************************
                        RESULT := x"00";
                        RESULT := x"00";
        end case;
        end case;
        if (OPER(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
        if (OPER(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
        end if;
        end if;
        if (RESULT=x"00") then ALU_FLAGS.Z := '1'; else ALU_FLAGS.Z := '0';
        if (RESULT=x"00") then ALU_FLAGS.Z := '1'; else ALU_FLAGS.Z := '0';
        end if;
        end if;
        ALU_FLAGS.S := RESULT(7);
        ALU_FLAGS.S := RESULT(7);
        return RESULT;
        return RESULT;
end LU2;
end LU2;
 
 
-- ADDER16 adds a signed 8-bit offset to a 16-bit address
-- ADDER16 adds a signed 8-bit offset to a 16-bit address
function ADDER16
function ADDER16
        (       ADDR16  : in std_logic_vector(15 downto 0);
        (       ADDR16  : in std_logic_vector(15 downto 0);
                OFFSET  : in std_logic_vector(7 downto 0)) return std_logic_vector is
                OFFSET  : in std_logic_vector(7 downto 0)) return std_logic_vector is
begin
begin
        if (OFFSET(7)='0') then return ADDR16 + (x"00" & OFFSET);
        if (OFFSET(7)='0') then return ADDR16 + (x"00" & OFFSET);
        else return ADDR16 + (x"FF" & OFFSET);
        else return ADDR16 + (x"FF" & OFFSET);
        end if;
        end if;
end ADDER16;
end ADDER16;
 
 
begin
begin
        clock_out: process(CLK)
        clock_out: process(CLK,RESET)
 
        variable CKDIVIDER              : integer range 0 to 2;
        begin
        begin
                CLK_OUTN <= not CLK;
                if (RESET='1') then
                CLK_OUT <= CLK;
                        CKDIVIDER := 0;
        end process;
                        CLK_OUTN <= '1';
 
                        CLK_OUT <= '0';
 
                elsif (rising_edge(CLK)) then
 
                        CLK_OUTN <= '1';
 
                        CLK_OUT <= '0';
 
                        CKDIVIDER := CKDIVIDER + 1;
 
                        if (CKDIVIDER=0) then    -- main clock (50MHz) is divided by 3, resulting in a 16.66MHz system clock
 
                                CLK_OUT <= '1';
 
                                CLK_OUTN <= '0';
 
                        end if;
 
                end if;
 
        end process;    -- clock_out process
        -- main process controls debugging and instruction fetching and decoding along
        -- main process controls debugging and instruction fetching and decoding along
        main: process (CLK,RESET,DBG_RX)
        main: process (CLK_OUT,RESET,DBG_RX)
        -- CPU state machine
        -- CPU state machine
        type Tcpu_state is (
        type Tcpu_state is (
                CPU_DECOD,
                CPU_DECOD,
                CPU_INDRR,
                CPU_INDRR,                                              -- indirect rr mode
                CPU_MUL, CPU_MUL1, CPU_MUL2,
                CPU_MUL, CPU_MUL1, CPU_MUL2,    -- MUL instruction
                CPU_XADTOM,
                CPU_XADTOM,                                             -- address with offset to memory
                CPU_MTOXAD, CPU_MTOXAD2,
                CPU_MTOXAD, CPU_MTOXAD2,                -- memory to address with offset
                CPU_XRTOM,
                CPU_XRTOM,                                              -- register with offset to memory
                CPU_XRRTORR, CPU_XRRTORR2,
                CPU_XRRTORR, CPU_XRRTORR2,              -- register pair with offset to register pair
                CPU_XRRTORR3, CPU_XRRTORR4,
                CPU_XRRTORR3, CPU_XRRTORR4,
                CPU_IMTOIRR, CPU_MTOIRR,                -- indirect and direct to indirect register pair addressing mode
                CPU_IMTOIRR, CPU_MTOIRR,                -- indirect and direct to indirect register pair addressing mode
                CPU_IRRS, CPU_IRRS2,
                CPU_IRRS, CPU_IRRS2,                    -- indirect register pair as source
                CPU_XRRD, CPU_XRRD2, CPU_XRRD3, -- indexed rr pair as destination
                CPU_XRRD, CPU_XRRD2, CPU_XRRD3, -- indexed rr pair as destination
                CPU_XRRS, CPU_XRRS2, CPU_XRRS3, -- indexed rr pair as source
                CPU_XRRS, CPU_XRRS2, CPU_XRRS3, -- indexed rr pair as source
                CPU_IND1, CPU_IND2,                             -- indirect memory access
                CPU_IND1, CPU_IND2,                             -- indirect memory access
                CPU_ISMD1,                                              -- indirect source to memory destination
                CPU_ISMD1,                                              -- indirect source to memory destination
                CPU_TMA,                                                -- Two memory access instructions (register to/with register)
                CPU_TMA,                                                -- Two memory access instructions (register to/with register)
                CPU_OMA,                                                -- One memory access instructions (immediate to/with register)
                CPU_OMA,                                                -- One memory access instructions (immediate to/with register)
                CPU_OMA2,                                               -- One memory access instructions (immediate to/with register) logic unit related
                CPU_OMA2,                                               -- One memory access instructions (immediate to/with register) logic unit related
                CPU_DMAB,                                               -- Decrement address bus (for word access)
                CPU_DMAB,                                               -- Decrement address bus (for word access)
                CPU_LDW, CPU_LDW2,
                CPU_LDW, CPU_LDW2, CPU_LDW3,    -- load word instruction
                CPU_LDPTOIM, CPU_LDPTOIM2,
                CPU_LDW4, CPU_LDW5,
                CPU_LDPTOM, CPU_LDPTOM2,
                CPU_LDPTOIM, CPU_LDPTOIM2,              -- load program to indirect memory
 
                CPU_LDPTOM, CPU_LDPTOM2,                -- load program to memory
                CPU_LDPTOM3, CPU_LDPTOM4,
                CPU_LDPTOM3, CPU_LDPTOM4,
                CPU_LDMTOP, CPU_LDMTOP2,
                CPU_LDMTOP, CPU_LDMTOP2,                -- load memory to program
                CPU_BIT,
                CPU_BIT,                                                -- BIT instruction
                CPU_IBTJ, CPU_BTJ,
                CPU_IBTJ, CPU_BTJ,                              -- BTJ instruction
                CPU_DJNZ,
                CPU_DJNZ,                                               -- DJNZ instruction
                CPU_INDJUMP, CPU_INDJUMP2,
                CPU_INDJUMP, CPU_INDJUMP2,              -- indirect JP
                CPU_TRAP, CPU_TRAP2,
                CPU_TRAP, CPU_TRAP2,                    -- TRAP instruction
                CPU_INDSTACK, CPU_INDSTACK2,
                CPU_INDSTACK, CPU_INDSTACK2,    -- indirect stacking
                CPU_STACK, CPU_STACK1,
                CPU_STACK, CPU_STACK1,                  -- stacking operations
                CPU_STACK2, CPU_STACK3,
                CPU_STACK2, CPU_STACK3,
                CPU_UNSTACK, CPU_UNSTACK2,
                CPU_UNSTACK, CPU_UNSTACK2,              -- unstacking operations
                CPU_UNSTACK3,
                CPU_UNSTACK3,
                CPU_STORE,                                              -- store results, no change to the flags
                CPU_STORE,                                              -- store results, no change to the flags
                CPU_VECTOR, CPU_VECTOR2,
                CPU_VECTOR, CPU_VECTOR2,                -- vectoring stages
                CPU_HALTED,
                CPU_RESET,                                              -- reset state
                CPU_RESET,
                CPU_ILLEGAL                                             -- illegal state
                CPU_ILLEGAL
 
        );
        );
        type Tfetch_state is (
        type Tfetch_state is (
                F_ADDR,         -- instruction queue is initializing, reset pointers and empty queue
                F_ADDR,         -- instruction queue is initializing, reset pointers and empty queue
                F_READ          -- instruction queue is fetching opcodes
                F_READ          -- instruction queue is fetching opcodes
        );
        );
        type Tdbg_uartrxstate is (
        type Tdbg_uartrxstate is (
                DBGST_NOSYNC,                   -- debug UART receiver is not synchronized to the host
                DBGST_NOSYNC,                   -- debug UART receiver is not synchronized to the host
                DBGST_WAITSTART,                -- debug UART receiver is waiting for a 0x80 char
                DBGST_WAITSTART,                -- debug UART receiver is waiting for a 0x80 char
                DBGST_MEASURING,                -- debug UART receiver is measuring a possible sync char
                DBGST_MEASURING,                -- debug UART receiver is measuring a possible sync char
                DBGST_IDLE,                             -- debug UART receiver is synchronized and awaiting commands
                DBGST_IDLE,                             -- debug UART receiver is synchronized and awaiting commands
                DBGST_START,                    -- debug UART received a start bit
                DBGST_START,                    -- debug UART received a start bit
                DBGST_RECEIVING,                -- debug UART is receiving new command/data
                DBGST_RECEIVING,                -- debug UART is receiving new command/data
                DBGST_ERROR                             -- debug UART receiver is in error state
                DBGST_ERROR                             -- debug UART receiver is in error state
        );
        );
        type Tdbg_uarttxstate is (
        type Tdbg_uarttxstate is (
                DBGTX_INIT,                             -- debug UART transmitter is initializing
                DBGTX_INIT,                             -- debug UART transmitter is initializing
                DBGTX_IDLE,                             -- debug UART transmitter is waiting new data to transmit
                DBGTX_IDLE,                             -- debug UART transmitter is waiting new data to transmit
                DBGTX_START,                    -- debug UART transmitter is sending a start bit
                DBGTX_START,                    -- debug UART transmitter is sending a start bit
                DBGTX_TRASMITTING,              -- debug UART transmitter is sending data
                DBGTX_TRASMITTING,              -- debug UART transmitter is sending data
                DBGTX_BREAK,                    -- debug UART transmitter is preparing to send a break
                DBGTX_BREAK,                    -- debug UART transmitter is preparing to send a break
                DBGTX_BREAK2                    -- debug UART is waiting for the break complete
                DBGTX_BREAK2                    -- debug UART is waiting for the break complete
        );
        );
        type Tdbg_command is (
        type Tdbg_command is (
                DBG_WAIT_CMD,                                                   -- debugger is waiting for commands
                DBG_WAIT_CMD,                                                   -- debugger is waiting for commands
                DBG_SEND_REV, DBG_SEND_REV2,                    -- debugger is processing a read revision command
                DBG_SEND_REV, DBG_SEND_REV2,                    -- debugger is processing a read revision command
                DBG_SEND_STATUS,                                                -- debugger is processing a read OCDST command
                DBG_SEND_STATUS,                                                -- debugger is processing a read OCDST command
                DBG_WRITE_CTRL,                                                 -- debugger is processing a write OCDCTRL command
                DBG_WRITE_CTRL,                                                 -- debugger is processing a write OCDCTRL command
                DBG_SEND_CTRL,                                                  -- debugger is processing a read OCDCTRL command
                DBG_SEND_CTRL,                                                  -- debugger is processing a read OCDCTRL command
                DBG_WRITE_PC, DBG_WRITE_PC2,                    -- debugger is processing a PC write command
                DBG_WRITE_PC, DBG_WRITE_PC2,                    -- debugger is processing a PC write command
                DBG_SEND_PC, DBG_SEND_PC2,                              -- debugger is processing a PC read command
                DBG_SEND_PC, DBG_SEND_PC2,                              -- debugger is processing a PC read command
                DBG_WRITE_REG, DBG_READ_REG,                    -- debugger is processing a read/write to registers
                DBG_WRITE_REG, DBG_READ_REG,                    -- debugger is processing a read/write to registers
                DBG_REG, DBG_REG2, DBG_REG3,                    -- debugger is processing a read/write to registers
                DBG_REG, DBG_REG2, DBG_REG3,                    -- debugger is processing a read/write to registers
                DBG_REG4, DBG_REG5,                                             -- debugger is processing a read/write to registers
                DBG_REG4, DBG_REG5,                                             -- debugger is processing a read/write to registers
                DBG_WRITE_PROGMEM, DBG_READ_PROGMEM,    -- debugger is processing a read/write to program memory
                DBG_WRITE_PROGMEM, DBG_READ_PROGMEM,    -- debugger is processing a read/write to program memory
                DBG_PROGMEM, DBG_PROGMEM2,                              -- debugger is processing a read/write to program memory
                DBG_PROGMEM, DBG_PROGMEM2,                              -- debugger is processing a read/write to program memory
                DBG_PROGMEM3, DBG_PROGMEM4,                     -- debugger is processing a read/write to program memory
                DBG_PROGMEM3, DBG_PROGMEM4,                     -- debugger is processing a read/write to program memory
                DBG_PROGMEM5, DBG_PROGMEM6,                             -- debugger is processing a read/write to program memory
                DBG_PROGMEM5, DBG_PROGMEM6,                             -- debugger is processing a read/write to program memory
                DBG_STEP,                                                               -- debugger is processing a step command
                DBG_STEP,                                                               -- debugger is processing a step command
                DBG_STUFF,                                                              -- debugger is processing a stuff command
                DBG_STUFF,                                                              -- debugger is processing a stuff command
                DBG_EXEC, DBG_EXEC2, DBG_EXEC3                  -- debugger is processing a execute command
                DBG_EXEC, DBG_EXEC2, DBG_EXEC3                  -- debugger is processing a execute command
        );
        );
        type Tdbg_uart is record
        type Tdbg_uart is record
                RX_STATE        : Tdbg_uartrxstate;
                RX_STATE        : Tdbg_uartrxstate;
                TX_STATE        : Tdbg_uarttxstate;
                TX_STATE        : Tdbg_uarttxstate;
                RX_DONE         : std_logic;                                            -- new data is available
                RX_DONE         : std_logic;                                            -- new data is available
                TX_EMPTY        : std_logic;                                            -- tx buffer is empty
                TX_EMPTY        : std_logic;                                            -- tx buffer is empty
                DBG_SYNC        : std_logic;                                            -- debugger is synchronized to host
                DBG_SYNC        : std_logic;                                            -- debugger is synchronized to host
                WRT                     : std_logic;                                            -- write/read command flag
                WRT                     : std_logic;                                            -- write/read command flag
                LAST_SMP        : std_logic;                                            -- last sample read from DBG_RX pin
                LAST_SMP        : std_logic;                                            -- last sample read from DBG_RX pin
                SIZE            : std_logic_vector(15 downto 0); -- 16-bit size of command
                SIZE            : std_logic_vector(15 downto 0); -- 16-bit size of command
                TXSHIFTREG      : std_logic_vector(8 downto 0);          -- transmitter shift register
                TXSHIFTREG      : std_logic_vector(8 downto 0);          -- transmitter shift register
                RXSHIFTREG      : std_logic_vector(8 downto 0);          -- receiver shift register
                RXSHIFTREG      : std_logic_vector(8 downto 0);          -- receiver shift register
                TX_DATA         : std_logic_vector(7 downto 0);          -- TX buffer
                TX_DATA         : std_logic_vector(7 downto 0);          -- TX buffer
                RX_DATA         : std_logic_vector(7 downto 0);          -- RX buffer
                RX_DATA         : std_logic_vector(7 downto 0);          -- RX buffer
                RXCNT           : integer range 0 to 15;                 -- received bit counter
                RXCNT           : integer range 0 to 15;                 -- received bit counter
                TXCNT           : integer range 0 to 15;                 -- transmitted bit counter
                TXCNT           : integer range 0 to 15;                 -- transmitted bit counter
                BAUDPRE         : integer range 0 to 2;                          -- baud prescaler
                BAUDPRE         : integer range 0 to 2;                          -- baud prescaler
                BAUDCNTRX       : std_logic_vector(11 downto 0); -- RX baud divider
                BAUDCNTRX       : std_logic_vector(11 downto 0); -- RX baud divider
                BAUDCNTTX       : std_logic_vector(11 downto 0); -- TX baud divider
                BAUDCNTTX       : std_logic_vector(11 downto 0); -- TX baud divider
                BITTIMERX       : std_logic_vector(11 downto 0); -- RX bit-time register (1/2 bit-time)
                BITTIMERX       : std_logic_vector(11 downto 0); -- RX bit-time register (1/2 bit-time)
                BITTIMETX       : std_logic_vector(11 downto 0); -- TX bit-time register
                BITTIMETX       : std_logic_vector(11 downto 0); -- TX bit-time register
        end record;
        end record;
        variable CPU_STATE              : TCPU_STATE;                                           -- current CPU state 
        variable CPU_STATE              : TCPU_STATE;                                           -- current CPU state 
        variable DBG_UART               : Tdbg_uart;
        variable DBG_UART               : Tdbg_uart;
        variable DBG_CMD                : Tdbg_command;
        variable DBG_CMD                : Tdbg_command;
        variable CAN_FETCH              : std_logic;                                            -- controls whether the instruction queue can actually fetch opcodes
        variable CAN_FETCH              : std_logic;                                            -- controls whether the instruction queue can actually fetch opcodes
        variable LU_INSTRUCTION : std_logic;                                            -- indicates a LU2-related instruction
        variable LU_INSTRUCTION : std_logic;                                            -- indicates a LU2-related instruction
 
        variable INT_FLAG               : std_logic;                                            -- indicates an interrupt
        variable WORD_DATA              : std_logic;                                            -- indicates a 16-bit data instruction
        variable WORD_DATA              : std_logic;                                            -- indicates a 16-bit data instruction
 
        variable HALT                   : std_logic;                                            -- indicates the CPU is halted
        variable PC                     : std_logic_vector(15 downto 0); -- program counter
        variable PC                     : std_logic_vector(15 downto 0); -- program counter
        variable FETCH_ADDR             : std_logic_vector(15 downto 0); -- next address to be fetched
        variable FETCH_ADDR             : std_logic_vector(15 downto 0); -- next address to be fetched
        variable DEST_ADDR16    : std_logic_vector(15 downto 0); -- temporary 16-bit destination address
        variable DEST_ADDR16    : std_logic_vector(15 downto 0); -- temporary 16-bit destination address
        variable DEST_ADDR              : std_logic_vector(11 downto 0); -- temporary 12-bit destination address
        variable DEST_ADDR              : std_logic_vector(11 downto 0); -- temporary 12-bit destination address
        variable TEMP_DATA              : std_logic_vector(7 downto 0);          -- temporary 8-bit data
        variable TEMP_DATA              : std_logic_vector(7 downto 0);          -- temporary 8-bit data
        variable OLD_IRQ0               : std_logic_vector(7 downto 0);          -- previous state of IRQs
        variable OLD_IRQ0               : std_logic_vector(7 downto 0);          -- previous state of IRQ inputs
        variable INTVECT                : std_logic_vector(7 downto 0);          -- current interrupt vector (lower 8-bits)
        variable INTVECT                : std_logic_vector(7 downto 0);          -- current interrupt vector (lower 8-bits)
        variable RESULT                 : std_logic_vector(7 downto 0);          -- temporary 8-bit result
        variable RESULT                 : std_logic_vector(7 downto 0);          -- temporary 8-bit result
        variable TEMP_OP                : std_logic_vector(3 downto 0);          -- ALU/LU2 operation code
        variable TEMP_OP                : std_logic_vector(3 downto 0);          -- ALU/LU2 operation code
        variable ATM_COUNTER    : integer range 0 to 3;                          -- temporary interrupt disable counter (ATM instruction)
        variable ATM_COUNTER    : integer range 0 to 3;                          -- temporary interrupt disable counter (ATM instruction)
        variable NUM_BYTES              : integer range 0 to 5;                          -- number of bytes decoded
        variable NUM_BYTES              : integer range 0 to 5;                          -- number of bytes decoded
        variable CKDIVIDER              : integer range 0 to 2;
 
        type Tinstructionqueue is record
        type Tinstructionqueue is record
                WRPOS                           : integer range 0 to 7;                          -- instruction queue write pointer
                WRPOS                           : integer range 0 to 7;                          -- instruction queue write pointer
                RDPOS                           : integer range 0 to 7;                          -- instruction queue read pointer
                RDPOS                           : integer range 0 to 7;                          -- instruction queue read pointer
                CNT                                     : integer range 0 to 7;                          -- instruction queue available bytes
                CNT                                     : integer range 0 to 7;                          -- instruction queue available bytes
                FETCH_STATE                     : tfetch_state;
                FETCH_STATE                     : tfetch_state;
                QUEUE                           : Tinstqueue;
                QUEUE                           : Tinstqueue;
                FULL                            : std_logic;                                            -- indicates whether the queue is full or not
                FULL                            : std_logic;                                            -- indicates whether the queue is full or not
        end record;
        end record;
        variable IQUEUE                 : Tinstructionqueue;
        variable IQUEUE                 : Tinstructionqueue;
        type Tocdcr is record
        type Tocdcr is record
                DBGMODE                         : std_logic;
                DBGMODE                         : std_logic;
                BRKEN                           : std_logic;
                BRKEN                           : std_logic;
                DBGACK                          : std_logic;
                DBGACK                          : std_logic;
                BRKLOOP                         : std_logic;
                BRKLOOP                         : std_logic;
                RST                                     : std_logic;
                RST                                     : std_logic;
        end record;
        end record;
        variable OCDCR                  : Tocdcr;
        variable OCDCR                  : Tocdcr;
        type Tocdflags is record
        type Tocdflags is record
                SINGLESTEP                      : std_logic;
                SINGLESTEP                      : std_logic;
        end record;
        end record;
        variable OCD                    : Tocdflags;
        variable OCD                    : Tocdflags;
 
 
        begin
        begin
                if (reset='1') then     -- reset operations             
                RESET_OUT <= RESET or OCDCR.RST;
 
                if (RESET='1') then     -- reset operations             
                        IAB <= x"0002";
                        IAB <= x"0002";
                        MAB <= x"000";
                        FRAB <= x"000";
                        PWDB <= x"00";
                        IWDB <= x"00";
                        SP := x"000";
                        SP := x"000";
                        RP := x"00";
                        RP := x"00";
                        WR <= '0';
                        WR <= '0';
                        PGM_WR <= '0';
                        PGM_WR <= '0';
                        STOP <= '0';
                        STOP <= '0';
                        CAN_FETCH := '1';
                        CAN_FETCH := '1';
                        FETCH_ADDR := x"0000";
                        FETCH_ADDR := x"0000";
                        DBG_UART.RX_STATE := DBGST_NOSYNC;
                        DBG_UART.RX_STATE := DBGST_NOSYNC;
                        DBG_UART.TX_STATE := DBGTX_INIT;
                        DBG_UART.TX_STATE := DBGTX_INIT;
                        OCDCR.DBGMODE := '0';
                        OCDCR.DBGMODE := '0';
                        OCDCR.BRKEN := '0';
                        OCDCR.BRKEN := '0';
                        OCDCR.DBGACK := '0';
                        OCDCR.DBGACK := '0';
                        OCDCR.BRKLOOP := '0';
                        OCDCR.BRKLOOP := '0';
                        OCD.SINGLESTEP := '0';
                        OCD.SINGLESTEP := '0';
                        OCDCR.RST := '0';
                        OCDCR.RST := '0';
                        RXSYNC1 <= '1';
                        RXSYNC1 <= '1';
                        RXSYNC2 <= '1';
                        RXSYNC2 <= '1';
                        DBG_UART.LAST_SMP := '1';
                        DBG_UART.LAST_SMP := '1';
                        IQUEUE.FETCH_STATE := F_ADDR;
                        IQUEUE.FETCH_STATE := F_ADDR;
                        IRQE := '0';
                        IRQE := '0';
                        IRQ0 := x"00";
                        IRQ0 := x"00";
                        OLD_IRQ0 := x"00";
                        OLD_IRQ0 := x"00";
                        IRQ0ENH := x"00";
                        IRQ0ENH := x"00";
                        IRQ0ENL := x"00";
                        IRQ0ENL := x"00";
                        ATM_COUNTER := 0;
                        ATM_COUNTER := 0;
                        CKDIVIDER := 0;
 
                        CPU_STATE := CPU_VECTOR;
                        CPU_STATE := CPU_VECTOR;
                elsif (rising_edge(clk)) then
                elsif (rising_edge(CLK_OUT)) then
                        if (OLD_IRQ0(0)='0' and INT0='1') then IRQ0(0) := '1'; end if;
                        IRQ0_LATCH <= INT7&INT6&INT5&INT4&INT3&INT2&INT1&INT0;
                        if (OLD_IRQ0(1)='0' and INT1='1') then IRQ0(1) := '1'; end if;
                        if (OLD_IRQ0(0)/=IRQ0_LATCH(0)) then IRQ0(0) := '1'; end if;
                        if (OLD_IRQ0(2)='0' and INT2='1') then IRQ0(2) := '1'; end if;
                        if (OLD_IRQ0(1)/=IRQ0_LATCH(1)) then IRQ0(1) := '1'; end if;
                        if (OLD_IRQ0(3)='0' and INT3='1') then IRQ0(3) := '1'; end if;
                        if (OLD_IRQ0(2)/=IRQ0_LATCH(2)) then IRQ0(2) := '1'; end if;
                        if (OLD_IRQ0(4)='0' and INT4='1') then IRQ0(4) := '1'; end if;
                        if (OLD_IRQ0(3)/=IRQ0_LATCH(3)) then IRQ0(3) := '1'; end if;
                        if (OLD_IRQ0(5)='0' and INT5='1') then IRQ0(5) := '1'; end if;
                        if (OLD_IRQ0(4)/=IRQ0_LATCH(4)) then IRQ0(4) := '1'; end if;
                        if (OLD_IRQ0(6)='0' and INT6='1') then IRQ0(6) := '1'; end if;
                        if (OLD_IRQ0(5)/=IRQ0_LATCH(5)) then IRQ0(5) := '1'; end if;
                        OLD_IRQ0 := INT7&INT6&INT5&INT4&INT3&INT2&INT1&INT0;
                        if (OLD_IRQ0(6)/=IRQ0_LATCH(6)) then IRQ0(6) := '1'; end if;
                        CKDIVIDER := CKDIVIDER + 1;
                        if (OLD_IRQ0(7)/=IRQ0_LATCH(7)) then IRQ0(7) := '1'; end if;
                        if (CKDIVIDER=0) then    -- main clock (50MHz) is divided by 3, resulting in a 16.66MHz system clock
                        OLD_IRQ0 := IRQ0_LATCH;
 
 
                                WR <= '0';
                                WR <= '0';
                                PGM_WR <= '0';
                        PGM_WR <= '0';
 
 
                                -- This is the instruction queue FSM
                        -- start of instruction queue FSM
                                if (CAN_FETCH='1') then
                                if (CAN_FETCH='1') then
                                        if (IQUEUE.FETCH_STATE=F_ADDR) then
                                if (IQUEUE.FETCH_STATE=F_ADDR) then
                                                FETCH_ADDR := PC;
                                        FETCH_ADDR := PC;
                                                IAB <= PC;
                                        IAB <= PC;
                                                IQUEUE.WRPOS := 0;
                                        IQUEUE.WRPOS := 0;
                                                IQUEUE.RDPOS := 0;
                                        IQUEUE.RDPOS := 0;
                                                IQUEUE.CNT := 0;
                                        IQUEUE.CNT := 0;
                                                IQUEUE.FETCH_STATE := F_READ;
                                        IQUEUE.FETCH_STATE := F_READ;
                                        else
                                else
                                                if (IQUEUE.FULL='0') then
                                        if (IQUEUE.FULL='0') then
                                                        IQUEUE.QUEUE(IQUEUE.WRPOS) := IDB;
                                                IQUEUE.QUEUE(IQUEUE.WRPOS) := IDB;
                                                        FETCH_ADDR := FETCH_ADDR + 1;
                                                FETCH_ADDR := FETCH_ADDR + 1;
                                                        IAB <= FETCH_ADDR;
                                                IAB <= FETCH_ADDR;
                                                        IQUEUE.WRPOS := IQUEUE.WRPOS + 1;
                                                IQUEUE.WRPOS := IQUEUE.WRPOS + 1;
                                                        IQUEUE.CNT := IQUEUE.CNT + 1;
                                                IQUEUE.CNT := IQUEUE.CNT + 1;
                                                end if;
                                        end if;
                                        end if;
                                end if;
                                end if;
                        end if;
                                if (IQUEUE.CNT=7) then IQUEUE.FULL:='1'; else IQUEUE.FULL:='0';
                        if (IQUEUE.CNT=7) then IQUEUE.FULL:='1'; else IQUEUE.FULL:='0';
                                end if;
                                end if;
                                -- This is the end of instruction queue FSM     
                        -- end of instruction queue FSM 
 
 
                                -- These are the Debugger FSMs
                        -- start of debugger UART
                                DBG_UART.BAUDPRE := DBG_UART.BAUDPRE+1;
                        DBG_UART.BAUDPRE := DBG_UART.BAUDPRE+1; -- baudrate prescaler
                                if (DBG_UART.BAUDPRE=0) then
                                if (DBG_UART.BAUDPRE=0) then
                                        DBG_UART.BAUDCNTRX := DBG_UART.BAUDCNTRX+1;
                                DBG_UART.BAUDCNTRX := DBG_UART.BAUDCNTRX+1;
                                        DBG_UART.BAUDCNTTX := DBG_UART.BAUDCNTTX+1;
                                DBG_UART.BAUDCNTTX := DBG_UART.BAUDCNTTX+1;
                                end if;
                                end if;
                                RXSYNC2 <= DBG_RX;
                        RXSYNC2 <= DBG_RX;              -- DBG_RX input synchronization
                                RXSYNC1 <= RXSYNC2;
                        RXSYNC1 <= RXSYNC2;             -- RXSYNC1 is a synchronized DBG_RX signal
                                case DBG_UART.RX_STATE is
                                case DBG_UART.RX_STATE is
                                        when DBGST_NOSYNC =>
                                when DBGST_NOSYNC =>
                                                DBG_UART.DBG_SYNC := '0';
                                        DBG_UART.DBG_SYNC := '0';
                                                DBG_UART.RX_DONE := '0';
                                        DBG_UART.RX_DONE := '0';
                                                DBG_CMD := DBG_WAIT_CMD;
                                        DBG_CMD := DBG_WAIT_CMD;
                                                DBG_UART.RX_STATE := DBGST_WAITSTART;
                                        DBG_UART.RX_STATE := DBGST_WAITSTART;
                                        when DBGST_WAITSTART =>
                                when DBGST_WAITSTART =>
                                                if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then
                                        if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then
                                                        DBG_UART.RX_STATE := DBGST_MEASURING;
                                                DBG_UART.RX_STATE := DBGST_MEASURING;
                                                        DBG_UART.BAUDCNTRX := x"000";
                                                DBG_UART.BAUDCNTRX := x"000";
                                                end if;
                                        end if;
                                        when DBGST_MEASURING =>
                                when DBGST_MEASURING =>
                                                if (DBG_UART.BAUDCNTRX/=x"FFF") then
                                        if (DBG_UART.BAUDCNTRX/=x"FFF") then
                                                        if (RXSYNC1='1') then
                                                if (RXSYNC1='1') then
                                                                DBG_UART.DBG_SYNC := '1';
                                                        DBG_UART.DBG_SYNC := '1';
                                                                DBG_UART.RX_STATE := DBGST_IDLE;
                                                        DBG_UART.RX_STATE := DBGST_IDLE;
                                                                DBG_UART.BITTIMERX := "0000"&DBG_UART.BAUDCNTRX(11 downto 4);
                                                        DBG_UART.BITTIMERX := "0000"&DBG_UART.BAUDCNTRX(11 downto 4);
                                                                DBG_UART.BITTIMETX := "000"&DBG_UART.BAUDCNTRX(11 downto 3);
                                                        DBG_UART.BITTIMETX := "000"&DBG_UART.BAUDCNTRX(11 downto 3);
                                                        end if;
                                                end if;
                                                else
                                        else
                                                        DBG_UART.RX_STATE := DBGST_NOSYNC;
                                                DBG_UART.RX_STATE := DBGST_NOSYNC;
                                                end if;
                                        end if;
                                        when DBGST_IDLE =>
                                when DBGST_IDLE =>
                                                DBG_UART.BAUDCNTRX:=x"000";
                                        DBG_UART.BAUDCNTRX:=x"000";
                                                DBG_UART.RXCNT:=0;
                                        DBG_UART.RXCNT:=0;
                                                if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then  -- it's a start bit
                                        if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then  -- it's a start bit
                                                        DBG_UART.RX_STATE := DBGST_START;
                                                DBG_UART.RX_STATE := DBGST_START;
                                                end if;
                                        end if;
                                        when DBGST_START =>
                                when DBGST_START =>
                                                if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMERX) then
                                        if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMERX) then
                                                        DBG_UART.BAUDCNTRX:=x"000";
                                                DBG_UART.BAUDCNTRX:=x"000";
                                                        if (RXSYNC1='0') then
                                                if (RXSYNC1='0') then
                                                                DBG_UART.RX_STATE := DBGST_RECEIVING;
                                                        DBG_UART.RX_STATE := DBGST_RECEIVING;
                                                        else
                                                else
                                                                DBG_UART.RX_STATE := DBGST_ERROR;
                                                        DBG_UART.RX_STATE := DBGST_ERROR;
                                                                DBG_UART.TX_STATE := DBGTX_BREAK;
                                                        DBG_UART.TX_STATE := DBGTX_BREAK;
                                                        end if;
                                                end if;
                                                end if;
                                        end if;
                                        when DBGST_RECEIVING =>
                                when DBGST_RECEIVING =>
                                                if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMETX) then
                                        if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMETX) then
                                                        DBG_UART.BAUDCNTRX:=x"000";
                                                DBG_UART.BAUDCNTRX:=x"000";
                                                        -- one bit time elapsed, sample RX input
                                                -- one bit time elapsed, sample RX input
                                                        DBG_UART.RXSHIFTREG := RXSYNC1 & DBG_UART.RXSHIFTREG(8 downto 1);
                                                DBG_UART.RXSHIFTREG := RXSYNC1 & DBG_UART.RXSHIFTREG(8 downto 1);
                                                        DBG_UART.RXCNT := DBG_UART.RXCNT + 1;
                                                DBG_UART.RXCNT := DBG_UART.RXCNT + 1;
                                                        if (DBG_UART.RXCNT=9) then
                                                if (DBG_UART.RXCNT=9) then
                                                                if (RXSYNC1='1') then
                                                        if (RXSYNC1='1') then
                                                                        -- if the stop bit is 1, rx is completed ok
                                                                -- if the stop bit is 1, rx is completed ok
                                                                        DBG_UART.RX_DATA := DBG_UART.RXSHIFTREG(7 downto 0);
                                                                DBG_UART.RX_DATA := DBG_UART.RXSHIFTREG(7 downto 0);
                                                                        DBG_UART.RX_DONE := '1';
                                                                DBG_UART.RX_DONE := '1';
                                                                        DBG_UART.RX_STATE := DBGST_IDLE;
                                                                DBG_UART.RX_STATE := DBGST_IDLE;
                                                                else
                                                        else
                                                                        -- if the stop bit is 0, it is a break char, reset receiver
                                                                -- if the stop bit is 0, it is a break char, reset receiver
                                                                        DBG_UART.RX_STATE := DBGST_ERROR;
                                                                DBG_UART.RX_STATE := DBGST_ERROR;
                                                                        DBG_UART.TX_STATE := DBGTX_BREAK;
                                                                DBG_UART.TX_STATE := DBGTX_BREAK;
                                                                end if;
                                                        end if;
                                                        end if;
                                                end if;
                                                end if;
                                        end if;
                                        when others =>
                                when others =>
                                end case;
                        end case;
                                DBG_UART.LAST_SMP := RXSYNC1;
                        DBG_UART.LAST_SMP := RXSYNC1;
                                case DBG_UART.TX_STATE is
                        case DBG_UART.TX_STATE is
                                        when DBGTX_INIT =>
                                when DBGTX_INIT =>
                                                DBG_UART.TX_EMPTY := '1';
                                        DBG_UART.TX_EMPTY := '1';
                                                DBG_UART.TX_STATE:=DBGTX_IDLE;
                                        DBG_UART.TX_STATE:=DBGTX_IDLE;
                                        when DBGTX_IDLE =>      -- UART is idle and not transmitting
                                when DBGTX_IDLE =>      -- UART is idle and not transmitting
                                                DBG_TX <= '1';
                                        DBG_TX <= '1';
                                                if (DBG_UART.TX_EMPTY='0' and DBG_UART.DBG_SYNC='1') then        -- there is new data in TX_DATA register
                                        if (DBG_UART.TX_EMPTY='0' and DBG_UART.DBG_SYNC='1') then        -- there is new data in TX_DATA register
                                                        DBG_UART.BAUDCNTTX:=x"000";
                                                DBG_UART.BAUDCNTTX:=x"000";
                                                        DBG_UART.TX_STATE := DBGTX_START;
                                                DBG_UART.TX_STATE := DBGTX_START;
                                                end if;
                                        end if;
                                        when DBGTX_START =>
                                when DBGTX_START =>
                                                if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then
                                        if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then
                                                        DBG_UART.BAUDCNTTX:=x"000";
                                                DBG_UART.BAUDCNTTX:=x"000";
                                                        DBG_UART.TXSHIFTREG := '1'&DBG_UART.TX_DATA;
                                                DBG_UART.TXSHIFTREG := '1'&DBG_UART.TX_DATA;
                                                        DBG_UART.TXCNT := 10;
                                                DBG_UART.TXCNT := 10;
                                                        DBG_UART.TX_STATE := DBGTX_TRASMITTING;
                                                DBG_UART.TX_STATE := DBGTX_TRASMITTING;
                                                        DBG_TX <= '0';
                                                DBG_TX <= '0';
                                                end if;
                                        end if;
                                        when DBGTX_TRASMITTING =>       -- UART is shifting data
                                when DBGTX_TRASMITTING =>       -- UART is shifting data
                                                if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then
                                        if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then
                                                        DBG_UART.BAUDCNTTX:=x"000";
                                                DBG_UART.BAUDCNTTX:=x"000";
                                                        DBG_TX <= DBG_UART.TXSHIFTREG(0);
                                                DBG_TX <= DBG_UART.TXSHIFTREG(0);
                                                        DBG_UART.TXSHIFTREG := '1'&DBG_UART.TXSHIFTREG(8 downto 1);
                                                DBG_UART.TXSHIFTREG := '1'&DBG_UART.TXSHIFTREG(8 downto 1);
                                                        DBG_UART.TXCNT :=DBG_UART.TXCNT - 1;
                                                DBG_UART.TXCNT :=DBG_UART.TXCNT - 1;
                                                        if (DBG_UART.TXCNT=0) then
                                                if (DBG_UART.TXCNT=0) then
                                                                DBG_UART.TX_STATE:=DBGTX_IDLE;
                                                        DBG_UART.TX_STATE:=DBGTX_IDLE;
                                                                DBG_UART.TX_EMPTY := '1';
                                                        DBG_UART.TX_EMPTY := '1';
                                                        end if;
                                                end if;
                                                end if;
                                        end if;
                                        when DBGTX_BREAK =>
                                when DBGTX_BREAK =>
                                                DBG_UART.BAUDCNTTX:=x"000";
                                        DBG_UART.BAUDCNTTX:=x"000";
                                                DBG_UART.TX_STATE:=DBGTX_BREAK2;
                                        DBG_UART.TX_STATE:=DBGTX_BREAK2;
                                        when DBGTX_BREAK2 =>
                                when DBGTX_BREAK2 =>
                                                DBG_TX <= '0';
                                        DBG_TX <= '0';
                                                DBG_UART.RX_STATE := DBGST_NOSYNC;
                                        DBG_UART.RX_STATE := DBGST_NOSYNC;
                                                if (DBG_UART.BAUDCNTTX=x"FFF") then
                                        if (DBG_UART.BAUDCNTTX=x"FFF") then
                                                        DBG_UART.TX_STATE:=DBGTX_INIT;
                                                DBG_UART.TX_STATE:=DBGTX_INIT;
                                                end if;
                                        end if;
                                end case;
                                end case;
                                if (RXSYNC1='0') then DBG_TX <='0';
                        if (RXSYNC1='0') then DBG_TX <='0';       -- this mimics open-collector feature of OCD communication
                                end if;
                                end if;
 
                        -- end of the debugger UART             
 
 
 
                        -- This is the instruction decoder
 
                        case CPU_STATE IS
 
                                when CPU_DECOD =>
 
                                        TEMP_OP := ALU_LD;                                      -- default ALU operation is load
 
                                        LU_INSTRUCTION := '0';                           -- default is ALU operation (instead of LU2)
 
                                        INT_FLAG := '0';                                 -- reset temporary interrupt flag
 
                                        WORD_DATA := '0';                                        -- default is 8-bit operation
 
                                        INTVECT := x"00";                                       -- default vector is 0x00
 
                                        NUM_BYTES := 0;                                          -- default instruction length is 0 bytes
 
 
 
                                        -- start of debugger command processor
                                case DBG_CMD is
                                case DBG_CMD is
                                        when DBG_WAIT_CMD =>
                                                when DBG_WAIT_CMD =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        case DBG_UART.RX_DATA is
                                                                case DBG_UART.RX_DATA is
                                                                when DBGCMD_READ_REV =>         DBG_CMD := DBG_SEND_REV;
                                                                        when DBGCMD_READ_REV =>         DBG_CMD := DBG_SEND_REV;
                                                                when DBGCMD_READ_STATUS =>      DBG_CMD := DBG_SEND_STATUS;
                                                                        when DBGCMD_READ_STATUS =>      DBG_CMD := DBG_SEND_STATUS;
                                                                when DBGCMD_WRITE_CTRL =>       DBG_CMD := DBG_WRITE_CTRL;
                                                                        when DBGCMD_WRITE_CTRL =>       DBG_CMD := DBG_WRITE_CTRL;
                                                                when DBGCMD_READ_CTRL =>        DBG_CMD := DBG_SEND_CTRL;
                                                                        when DBGCMD_READ_CTRL =>        DBG_CMD := DBG_SEND_CTRL;
                                                                when DBGCMD_WRITE_PC =>         DBG_CMD := DBG_WRITE_PC;
                                                                        when DBGCMD_WRITE_PC =>         DBG_CMD := DBG_WRITE_PC;
                                                                when DBGCMD_READ_PC =>          DBG_CMD := DBG_SEND_PC;
                                                                        when DBGCMD_READ_PC =>          DBG_CMD := DBG_SEND_PC;
                                                                when DBGCMD_WRITE_REG =>        DBG_CMD := DBG_WRITE_REG;
                                                                        when DBGCMD_WRITE_REG =>        DBG_CMD := DBG_WRITE_REG;
                                                                when DBGCMD_READ_REG =>         DBG_CMD := DBG_READ_REG;
                                                                        when DBGCMD_READ_REG =>         DBG_CMD := DBG_READ_REG;
                                                                when DBGCMD_WRITE_PROGRAM=>     DBG_CMD := DBG_WRITE_PROGMEM;
                                                                        when DBGCMD_WRITE_PROGRAM=>     DBG_CMD := DBG_WRITE_PROGMEM;
                                                                when DBGCMD_READ_PROGRAM=>      DBG_CMD := DBG_READ_PROGMEM;
                                                                        when DBGCMD_READ_PROGRAM=>      DBG_CMD := DBG_READ_PROGMEM;
                                                                when DBGCMD_STEP =>                     DBG_CMD := DBG_STEP;
                                                                        when DBGCMD_STEP =>                     DBG_CMD := DBG_STEP;
                                                                when DBGCMD_STUFF =>            DBG_CMD := DBG_STUFF;
                                                                        when DBGCMD_STUFF =>            DBG_CMD := DBG_STUFF;
                                                                when DBGCMD_EXEC =>                     DBG_CMD := DBG_EXEC;
                                                                        when DBGCMD_EXEC =>                     DBG_CMD := DBG_EXEC;
                                                                when others =>
                                                                        when others =>
                                                        end case;
                                                                end case;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                end if;
                                                end if;
                                        when DBG_SEND_REV =>
                                                when DBG_SEND_REV =>    -- read revision first byte
                                                if (DBG_UART.TX_EMPTY='1') then
                                                if (DBG_UART.TX_EMPTY='1') then
                                                        DBG_UART.TX_DATA:=x"01";
                                                                DBG_UART.TX_DATA:=x"01";
                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_UART.TX_EMPTY:='0';
                                                        DBG_CMD := DBG_SEND_REV2;
                                                                DBG_CMD := DBG_SEND_REV2;
                                                end if;
                                                end if;
                                        when DBG_SEND_REV2 =>
                                                when DBG_SEND_REV2 =>   -- read revision second byte
                                                if (DBG_UART.TX_EMPTY='1') then
                                                if (DBG_UART.TX_EMPTY='1') then
                                                        DBG_UART.TX_DATA:=x"00";
                                                                DBG_UART.TX_DATA:=x"00";
                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_UART.TX_EMPTY:='0';
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                end if;
                                                end if;
                                        when DBG_SEND_STATUS =>
                                                when DBG_SEND_STATUS => -- read OCD status
                                                if (DBG_UART.TX_EMPTY='1') then
                                                if (DBG_UART.TX_EMPTY='1') then
                                                        DBG_UART.TX_DATA:=OCDCR.DBGMODE&HALT&"000000";
                                                                DBG_UART.TX_DATA:=OCDCR.DBGMODE&HALT&"000000";
                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_UART.TX_EMPTY:='0';
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                end if;
                                                end if;
                                        when DBG_WRITE_CTRL =>
                                                when DBG_WRITE_CTRL =>  -- write OCD control register
                                                if (DBG_UART.RX_DONE='1') then
                                                if (DBG_UART.RX_DONE='1') then
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        OCDCR.DBGMODE := DBG_UART.RX_DATA(7);
                                                                OCDCR.DBGMODE := DBG_UART.RX_DATA(7);
                                                        OCDCR.BRKEN := DBG_UART.RX_DATA(6);
                                                                OCDCR.BRKEN := DBG_UART.RX_DATA(6);
                                                        OCDCR.DBGACK := DBG_UART.RX_DATA(5);
                                                                OCDCR.DBGACK := DBG_UART.RX_DATA(5);
                                                        OCDCR.BRKLOOP := DBG_UART.RX_DATA(4);
                                                                OCDCR.BRKLOOP := DBG_UART.RX_DATA(4);
                                                        OCDCR.RST := DBG_UART.RX_DATA(0);
                                                                OCDCR.RST := DBG_UART.RX_DATA(0);
                                                        if (OCDCR.RST='1') then CPU_STATE:=CPU_RESET;
                                                                if (OCDCR.RST='1') then CPU_STATE:=CPU_RESET;
                                                        end if;
                                                                end if;
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                end if;
                                                end if;
                                        when DBG_SEND_CTRL =>
                                                when DBG_SEND_CTRL =>   -- read OCD control register
                                                if (DBG_UART.TX_EMPTY='1') then
                                                if (DBG_UART.TX_EMPTY='1') then
                                                        DBG_UART.TX_DATA:=OCDCR.DBGMODE&OCDCR.BRKEN&OCDCR.DBGACK&OCDCR.BRKLOOP&"000"&OCDCR.RST;
                                                                DBG_UART.TX_DATA:=OCDCR.DBGMODE&OCDCR.BRKEN&OCDCR.DBGACK&OCDCR.BRKLOOP&"000"&OCDCR.RST;
                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_UART.TX_EMPTY:='0';
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                end if;
                                                end if;
                                        when DBG_WRITE_PC =>
                                                when DBG_WRITE_PC =>    -- write PC high byte
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        CAN_FETCH := '0';
                                                                CAN_FETCH := '0';
                                                        PC(15 downto 8) := DBG_UART.RX_DATA;
                                                                PC(15 downto 8) := DBG_UART.RX_DATA;
                                                        DBG_CMD := DBG_WRITE_PC2;
                                                                DBG_CMD := DBG_WRITE_PC2;
                                                end if;
                                                end if;
                                        when DBG_WRITE_PC2 =>
                                                when DBG_WRITE_PC2 =>   -- write PC low byte
                                                if (DBG_UART.RX_DONE='1') then
                                                if (DBG_UART.RX_DONE='1') then
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        PC(7 downto 0) := DBG_UART.RX_DATA;
                                                                PC(7 downto 0) := DBG_UART.RX_DATA;
                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                        IQUEUE.CNT := 0;
                                                                IQUEUE.CNT := 0;
                                                        CAN_FETCH := '1';
                                                                CAN_FETCH := '1';
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                end if;
                                                end if;
                                        when DBG_SEND_PC =>
                                                when DBG_SEND_PC =>             -- read PC high byte
                                                if (DBG_UART.TX_EMPTY='1') then
                                                if (DBG_UART.TX_EMPTY='1') then
                                                        DBG_UART.TX_DATA:=PC(15 downto 8);
                                                                DBG_UART.TX_DATA:=PC(15 downto 8);
                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_UART.TX_EMPTY:='0';
                                                        DBG_CMD := DBG_SEND_PC2;
                                                                DBG_CMD := DBG_SEND_PC2;
                                                end if;
                                                end if;
                                        when DBG_SEND_PC2 =>
                                                when DBG_SEND_PC2 =>    -- read PC high byte
                                                if (DBG_UART.TX_EMPTY='1') then
                                                if (DBG_UART.TX_EMPTY='1') then
                                                        DBG_UART.TX_DATA:=PC(7 downto 0);
                                                                DBG_UART.TX_DATA:=PC(7 downto 0);
                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_UART.TX_EMPTY:='0';
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                end if;
                                                end if;
                                        when DBG_WRITE_REG =>
                                                when DBG_WRITE_REG =>   -- write to SFR/user registers
                                                DBG_UART.WRT := '1';
                                                DBG_UART.WRT := '1';
                                                DBG_CMD := DBG_REG;
                                                DBG_CMD := DBG_REG;
                                        when DBG_READ_REG =>
                                                when DBG_READ_REG =>    -- read SFR/user registers
                                                DBG_UART.WRT := '0';
                                                DBG_UART.WRT := '0';
                                                DBG_CMD := DBG_REG;
                                                DBG_CMD := DBG_REG;
                                        when DBG_REG =>
                                                when DBG_REG =>                 -- proceed with register read/write
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
                                                        CAN_FETCH := '0';
                                                                FRAB(11 downto 8) <= DBG_UART.RX_DATA(3 downto 0);
                                                        MAB(11 downto 8) <= DBG_UART.RX_DATA(3 downto 0);
 
                                                        DBG_UART.RX_DONE:='0';
                                                        DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_REG2;
                                                                DBG_CMD := DBG_REG2;
                                                end if;
                                                        end if;
                                        when DBG_REG2 =>
                                                when DBG_REG2 =>
                                                if (DBG_UART.RX_DONE='1') then
                                                if (DBG_UART.RX_DONE='1') then
                                                        MAB(7 downto 0) <= DBG_UART.RX_DATA;
                                                                FRAB(7 downto 0) <= DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                        DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_REG3;
                                                                DBG_CMD := DBG_REG3;
                                                end if;
                                                        end if;
                                        when DBG_REG3 =>
                                                when DBG_REG3 =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        DBG_UART.SIZE := x"00"&DBG_UART.RX_DATA;
                                                                DBG_UART.SIZE := x"00"&DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_REG4;
                                                                DBG_CMD := DBG_REG4;
                                                end if;
                                                        end if;
                                        when DBG_REG4 =>
                                        when DBG_REG4 =>
                                                if (OCDCR.DBGMODE='1') then
 
                                                        if (DBG_UART.WRT='1') then
                                                        if (DBG_UART.WRT='1') then
                                                                if (DBG_UART.RX_DONE='1') then
                                                                if (DBG_UART.RX_DONE='1') then
                                                                        CPU_STATE := CPU_OMA;
                                                                        CPU_STATE := CPU_OMA;
                                                                        TEMP_DATA := DBG_UART.RX_DATA;
                                                                        TEMP_DATA := DBG_UART.RX_DATA;
                                                                        DBG_UART.RX_DONE:='0';
                                                                        DBG_UART.RX_DONE:='0';
                                                                        DBG_CMD := DBG_REG5;
                                                                        DBG_CMD := DBG_REG5;
                                                                end if;
                                                                end if;
                                                        else
                                                        else
                                                                if (DBG_UART.TX_EMPTY='1') then
                                                                if (DBG_UART.TX_EMPTY='1') then
                                                                        DBG_UART.TX_DATA:=DATAREAD(MAB);
                                                                        DBG_UART.TX_DATA:=DATAREAD(FRAB);
                                                                        DBG_UART.TX_EMPTY:='0';
                                                                        DBG_UART.TX_EMPTY:='0';
                                                                        DBG_CMD := DBG_REG5;
                                                                        DBG_CMD := DBG_REG5;
                                                                end if;
                                                                end if;
                                                        end if;
                                                        end if;
                                                end if;
 
                                        when DBG_REG5 =>
                                        when DBG_REG5 =>
                                                if (CPU_STATE=CPU_DECOD) then
                                                        FRAB <= FRAB + 1;
                                                        MAB <= MAB + 1;
 
                                                        DBG_UART.SIZE := DBG_UART.SIZE - 1;
                                                        DBG_UART.SIZE := DBG_UART.SIZE - 1;
                                                        if (DBG_UART.SIZE=x"0000") then
                                                        if (DBG_UART.SIZE=x"0000") then
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                                CAN_FETCH := '1';
 
                                                        else DBG_CMD := DBG_REG4;
                                                        else DBG_CMD := DBG_REG4;
                                                        end if;
                                                        end if;
                                                end if;
 
                                        when DBG_WRITE_PROGMEM =>
                                        when DBG_WRITE_PROGMEM =>
                                                DBG_UART.WRT := '1';
                                                        DBG_UART.WRT := '1';
                                                DBG_CMD := DBG_PROGMEM;
                                                        DBG_CMD := DBG_PROGMEM;
                                        when DBG_READ_PROGMEM =>
                                                when DBG_READ_PROGMEM =>
                                                DBG_UART.WRT := '0';
                                                        DBG_UART.WRT := '0';
                                                DBG_CMD := DBG_PROGMEM;
                                                        DBG_CMD := DBG_PROGMEM;
                                        when DBG_PROGMEM =>
                                                when DBG_PROGMEM =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        CAN_FETCH := '0';
                                                                CAN_FETCH := '0';
                                                        IAB(15 downto 8) <= DBG_UART.RX_DATA;
                                                                IAB(15 downto 8) <= DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_PROGMEM2;
                                                                DBG_CMD := DBG_PROGMEM2;
                                                end if;
                                                        end if;
                                        when DBG_PROGMEM2 =>
                                                when DBG_PROGMEM2 =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        IAB(7 downto 0) <= DBG_UART.RX_DATA;
                                                                IAB(7 downto 0) <= DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_PROGMEM3;
                                                                DBG_CMD := DBG_PROGMEM3;
                                                end if;
                                                        end if;
                                        when DBG_PROGMEM3 =>
                                                when DBG_PROGMEM3 =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        DBG_UART.SIZE(15 downto 8) := DBG_UART.RX_DATA;
                                                                DBG_UART.SIZE(15 downto 8) := DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_PROGMEM4;
                                                                DBG_CMD := DBG_PROGMEM4;
                                                end if;
                                                        end if;
                                        when DBG_PROGMEM4 =>
                                                when DBG_PROGMEM4 =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        DBG_UART.SIZE(7 downto 0) := DBG_UART.RX_DATA;
                                                                DBG_UART.SIZE(7 downto 0) := DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_PROGMEM5;
                                                                DBG_CMD := DBG_PROGMEM5;
                                                end if;
                                                        end if;
                                        when DBG_PROGMEM5 =>
                                                when DBG_PROGMEM5 =>
                                                if (DBG_UART.WRT='1') then
                                                        if (DBG_UART.WRT='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                                PWDB <= DBG_UART.RX_DATA;
                                                                        IWDB <= DBG_UART.RX_DATA;
                                                                DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                                PGM_WR <= '1';
                                                                        PGM_WR <= '1';
                                                                DBG_CMD := DBG_PROGMEM6;
                                                                        DBG_CMD := DBG_PROGMEM6;
                                                        end if;
                                                                end if;
                                                else
                                                        else
                                                        if (DBG_UART.TX_EMPTY='1') then
                                                                if (DBG_UART.TX_EMPTY='1') then
                                                                DBG_UART.TX_DATA:=IDB;
                                                                        DBG_UART.TX_DATA:=IDB;
                                                                DBG_UART.TX_EMPTY:='0';
                                                                        DBG_UART.TX_EMPTY:='0';
                                                                DBG_CMD := DBG_PROGMEM6;
                                                                        DBG_CMD := DBG_PROGMEM6;
                                                        end if;
                                                                end if;
                                                end if;
                                                        end if;
                                        when DBG_PROGMEM6 =>
                                                when DBG_PROGMEM6 =>
                                                IAB <= IAB + 1;
                                                        IAB <= IAB + 1;
                                                DBG_UART.SIZE := DBG_UART.SIZE - 1;
                                                        DBG_UART.SIZE := DBG_UART.SIZE - 1;
                                                if (DBG_UART.SIZE=x"0000") then
                                                        if (DBG_UART.SIZE=x"0000") then
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                                DBG_CMD := DBG_WAIT_CMD;
                                                        CAN_FETCH := '1';
                                                                CAN_FETCH := '1';
                                                        IQUEUE.CNT := 0;
                                                                IQUEUE.CNT := 0;
                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                else DBG_CMD := DBG_PROGMEM5;
                                                        else DBG_CMD := DBG_PROGMEM5;
                                                end if;
                                                        end if;
                                        when DBG_STEP =>
                                                when DBG_STEP =>
                                                OCD.SINGLESTEP:='1';
                                                        OCD.SINGLESTEP:='1';
                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                DBG_CMD := DBG_WAIT_CMD;
                                                        DBG_CMD := DBG_WAIT_CMD;
                                        when DBG_STUFF =>
                                                when DBG_STUFF =>
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
                                                        if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
                                                        IQUEUE.QUEUE(IQUEUE.RDPOS) := DBG_UART.RX_DATA;
                                                                IQUEUE.QUEUE(IQUEUE.RDPOS) := DBG_UART.RX_DATA;
                                                        DBG_UART.RX_DONE:='0';
                                                                DBG_UART.RX_DONE:='0';
                                                        DBG_CMD := DBG_STEP;
                                                                DBG_CMD := DBG_STEP;
                                                end if;
                                                        end if;
                                        when DBG_EXEC =>
                                                when DBG_EXEC =>
                                                if (OCDCR.DBGMODE='1') then
                                                        if (OCDCR.DBGMODE='1') then
                                                        OCD.SINGLESTEP:='1';
                                                                OCD.SINGLESTEP:='1';
                                                        CAN_FETCH:='0';
                                                                CAN_FETCH:='0';
                                                        IQUEUE.CNT := 0;
                                                                IQUEUE.CNT := 0;
                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                end if;
                                                        end if;
                                                DBG_CMD := DBG_EXEC2;
                                                        DBG_CMD := DBG_EXEC2;
                                        when DBG_EXEC2 =>
                                                when DBG_EXEC2 =>
                                                if (DBG_UART.RX_DONE='1') then
                                                        if (DBG_UART.RX_DONE='1') then
                                                        if (OCDCR.DBGMODE='0') then DBG_CMD := DBG_WAIT_CMD;
                                                                if (OCDCR.DBGMODE='0') then DBG_CMD := DBG_WAIT_CMD;
                                                        else
                                                                else
                                                                IQUEUE.QUEUE(IQUEUE.WRPOS) := DBG_UART.RX_DATA;
                                                                        IQUEUE.QUEUE(IQUEUE.WRPOS) := DBG_UART.RX_DATA;
                                                                DBG_UART.RX_DONE:='0';
                                                                        DBG_UART.RX_DONE:='0';
                                                                IQUEUE.WRPOS := IQUEUE.WRPOS + 1;
                                                                        IQUEUE.WRPOS := IQUEUE.WRPOS + 1;
                                                                IQUEUE.CNT := IQUEUE.CNT + 1;
                                                                        IQUEUE.CNT := IQUEUE.CNT + 1;
                                                                DBG_CMD := DBG_EXEC3;
                                                                        DBG_CMD := DBG_EXEC3;
                                                        end if;
                                                                end if;
                                                end if;
                                                        end if;
                                        when DBG_EXEC3 =>
                                                when DBG_EXEC3 =>
                                                if (OCD.SINGLESTEP='1') then DBG_CMD := DBG_EXEC2; else
                                                        if (OCD.SINGLESTEP='1') then DBG_CMD := DBG_EXEC2; else
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                        DBG_CMD := DBG_WAIT_CMD;
                                                        CAN_FETCH:='0';
 
                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                end if;
                                                        end if;
                                        when others =>
                                                when others =>
                                end case;
                                end case;
                                -- This is the end of the debugger code         
                                        -- end of debugger command processor
 
 
                                -- This is the main instruction decoder
 
                                case CPU_STATE IS
 
                                when CPU_DECOD =>
 
                                        TEMP_OP := ALU_LD;                                      -- default ALU operation is load
 
                                        LU_INSTRUCTION := '0';                           -- default is ALU operation (instead of LU2)
 
                                        WORD_DATA := '0';                                        -- default is 8-bit operation
 
                                        INTVECT := x"00";                                       -- default vector is 0x00
 
                                        NUM_BYTES := 0;                                          -- default instruction length is 0 bytes
 
                                        if (ATM_COUNTER/=3) then ATM_COUNTER := ATM_COUNTER+1;
                                        if (ATM_COUNTER/=3) then ATM_COUNTER := ATM_COUNTER+1;
                                        else    -- interrupt processing *****************************************************************************
                                        else    -- interrupt processing *****************************************************************************
                                                if (IRQE='1') then      -- if interrupts are enabled
                                                if (IRQE='1') then      -- if interrupts are enabled
                                                        -- first the highest priority interrupts
                                                        -- first the highest priority level interrupts
                                                        if ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='1') then
                                                        if ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='1') then
                                                                INTVECT:=x"08";
                                                                INTVECT:=x"08";
                                                                IRQ0(7):='0';
                                                                IRQ0(7):='0';
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='1') and IRQ0ENL(6)='1') then
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='1') and IRQ0ENL(6)='1') then
                                                                INTVECT:=x"0A";
                                                                INTVECT:=x"0A";
                                                                IRQ0(6):='0';
                                                                IRQ0(6):='0';
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='1') and IRQ0ENL(5)='1') then
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='1') and IRQ0ENL(5)='1') then
                                                                INTVECT:=x"0C";
                                                                INTVECT:=x"0C";
                                                                IRQ0(5):='0';
                                                                IRQ0(5):='0';
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='1') and IRQ0ENL(4)='1') then
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='1') and IRQ0ENL(4)='1') then
                                                                INTVECT:=x"0E";
                                                                INTVECT:=x"0E";
                                                                IRQ0(4):='0';
                                                                IRQ0(4):='0';
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='1') and IRQ0ENL(3)='1') then
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='1') and IRQ0ENL(3)='1') then
                                                                INTVECT:=x"10";
                                                                INTVECT:=x"10";
                                                                IRQ0(3):='0';
                                                                IRQ0(3):='0';
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='1') and IRQ0ENL(2)='1') then
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='1') and IRQ0ENL(2)='1') then
                                                                INTVECT:=x"12";
                                                                INTVECT:=x"12";
                                                                IRQ0(2):='0';
                                                                IRQ0(2):='0';
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='1') and IRQ0ENL(1)='1') then
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='1') and IRQ0ENL(1)='1') then
                                                                INTVECT:=x"14";
                                                                INTVECT:=x"14";
                                                                IRQ0(1):='0';
                                                                IRQ0(1):='0';
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='1') and IRQ0ENL(0)='1') then
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='1') and IRQ0ENL(0)='1') then
                                                                INTVECT:=x"16";
                                                                INTVECT:=x"16";
                                                                IRQ0(0):='0';
                                                                IRQ0(0):='0';
                                                        -- now priority level 2 interrupts
                                                        -- now priority level 2 interrupts
                                                        elsif ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='0') then
                                                        elsif ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='0') then
                                                                INTVECT:=x"08";
                                                                INTVECT:=x"08";
                                                                IRQ0(7):='0';
                                                                IRQ0(7):='0';
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='1') and IRQ0ENL(6)='0') then
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='1') and IRQ0ENL(6)='0') then
                                                                INTVECT:=x"0A";
                                                                INTVECT:=x"0A";
                                                                IRQ0(6):='0';
                                                                IRQ0(6):='0';
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='1') and IRQ0ENL(5)='0') then
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='1') and IRQ0ENL(5)='0') then
                                                                INTVECT:=x"0C";
                                                                INTVECT:=x"0C";
                                                                IRQ0(5):='0';
                                                                IRQ0(5):='0';
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='1') and IRQ0ENL(4)='0') then
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='1') and IRQ0ENL(4)='0') then
                                                                INTVECT:=x"0E";
                                                                INTVECT:=x"0E";
                                                                IRQ0(4):='0';
                                                                IRQ0(4):='0';
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='1') and IRQ0ENL(3)='0') then
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='1') and IRQ0ENL(3)='0') then
                                                                INTVECT:=x"10";
                                                                INTVECT:=x"10";
                                                                IRQ0(3):='0';
                                                                IRQ0(3):='0';
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='1') and IRQ0ENL(2)='0') then
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='1') and IRQ0ENL(2)='0') then
                                                                INTVECT:=x"12";
                                                                INTVECT:=x"12";
                                                                IRQ0(2):='0';
                                                                IRQ0(2):='0';
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='1') and IRQ0ENL(1)='0') then
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='1') and IRQ0ENL(1)='0') then
                                                                INTVECT:=x"14";
                                                                INTVECT:=x"14";
                                                                IRQ0(1):='0';
                                                                IRQ0(1):='0';
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='1') and IRQ0ENL(0)='0') then
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='1') and IRQ0ENL(0)='0') then
                                                                INTVECT:=x"16";
                                                                INTVECT:=x"16";
                                                                IRQ0(0):='0';
                                                                IRQ0(0):='0';
                                                        -- now priority level 1 interrupts
                                                        -- now priority level 1 interrupts
                                                        elsif ((IRQ0(7)='1') and (IRQ0ENH(7)='0') and IRQ0ENL(7)='1') then
                                                        elsif ((IRQ0(7)='1') and (IRQ0ENH(7)='0') and IRQ0ENL(7)='1') then
                                                                INTVECT:=x"08";
                                                                INTVECT:=x"08";
                                                                IRQ0(7):='0';
                                                                IRQ0(7):='0';
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='0') and IRQ0ENL(6)='1') then
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='0') and IRQ0ENL(6)='1') then
                                                                INTVECT:=x"0A";
                                                                INTVECT:=x"0A";
                                                                IRQ0(6):='0';
                                                                IRQ0(6):='0';
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='0') and IRQ0ENL(5)='1') then
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='0') and IRQ0ENL(5)='1') then
                                                                INTVECT:=x"0C";
                                                                INTVECT:=x"0C";
                                                                IRQ0(5):='0';
                                                                IRQ0(5):='0';
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='0') and IRQ0ENL(4)='1') then
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='0') and IRQ0ENL(4)='1') then
                                                                INTVECT:=x"0E";
                                                                INTVECT:=x"0E";
                                                                IRQ0(4):='0';
                                                                IRQ0(4):='0';
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='0') and IRQ0ENL(3)='1') then
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='0') and IRQ0ENL(3)='1') then
                                                                INTVECT:=x"10";
                                                                INTVECT:=x"10";
                                                                IRQ0(3):='0';
                                                                IRQ0(3):='0';
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='0') and IRQ0ENL(2)='1') then
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='0') and IRQ0ENL(2)='1') then
                                                                INTVECT:=x"12";
                                                                INTVECT:=x"12";
                                                                IRQ0(2):='0';
                                                                IRQ0(2):='0';
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='0') and IRQ0ENL(1)='1') then
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='0') and IRQ0ENL(1)='1') then
                                                                INTVECT:=x"14";
                                                                INTVECT:=x"14";
                                                                IRQ0(1):='0';
                                                                IRQ0(1):='0';
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='0') and IRQ0ENL(0)='1') then
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='0') and IRQ0ENL(0)='1') then
                                                                INTVECT:=x"16";
                                                                INTVECT:=x"16";
                                                                IRQ0(0):='0';
                                                                IRQ0(0):='0';
                                                        end if;
                                                        end if;
                                                        if (INTVECT/=x"00") then
                                                        if (INTVECT/=x"00") then
 
                                                                if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then
                                                                DEST_ADDR16 := PC;
                                                                DEST_ADDR16 := PC;
                                                                IAB <= x"00"&INTVECT;   -- build the address of the interrupt vector
                                                                        IAB <= x"00"&INTVECT;   -- build the interrupt vector address
                                                                SP := SP - 1;                   -- prepare stack pointer by decrementing it
                                                                SP := SP - 1;                   -- prepare stack pointer by decrementing it
                                                                MAB <= SP;                              -- put SP on MAB
                                                                        FRAB <= SP;                             -- put SP on FRAB
                                                                CAN_FETCH := '0';                -- disable instruction fetching
                                                                CAN_FETCH := '0';                -- disable instruction fetching
                                                                IQUEUE.CNT := 0;         -- empty instruction queue
                                                                        OCD.SINGLESTEP := '0';   -- disable stepping
 
                                                                        IQUEUE.CNT := 0;         -- set queue empty
                                                                STOP <= '0';                     -- disable stop bit
                                                                STOP <= '0';                     -- disable stop bit
                                                                LU_INSTRUCTION := '1';  -- the stacking uses this bit to flag it is an interrupt stacking operation
                                                                        HALT := '0';                     -- disable halt mode
                                                                CPU_STATE := CPU_STACK;
                                                                        INT_FLAG := '1';                -- signal it is an interrupt stacking operation
                                                        end if;
                                                                        CPU_STATE := CPU_VECTOR;
                                                end if;
                                                end if;
                                        end if;
                                        end if;
 
                                                end if; -- if IRQE=1
 
                                        end if; -- if ATM_COUNTER...
 
                                        if (STOP='0' and HALT='0') then
                                        if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then
                                        if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                        ------------------------------------------------------------------------------------------------------------------------------
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                --                                                     5-byte instructions                                                  --
                                                        --                                                     5-byte instructions                                                  --
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                if (IQUEUE.CNT>=5) then
                                                        if (IQUEUE.CNT>=5) then -- 5-byte instructions
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
                                                                ---------------------------------------------------------------------------------------------- CPC ER2,ER1 instruction
                                                                        ---------------------------------------------------------------------------------------------- CPC ER2,ER1 instruction
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A8") then
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A8") then
                                                                        MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
                                                                                FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
                                                                        DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4));
                                                                        DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4));
                                                                        TEMP_OP := ALU_CPC;
                                                                                TEMP_OP := ALU_CPC;
                                                                        NUM_BYTES := 5;
                                                                                NUM_BYTES := 5;
                                                                        CPU_STATE := CPU_TMA;
                                                                                CPU_STATE := CPU_TMA;
                                                                ---------------------------------------------------------------------------------------------- CPC IMM,ER1 instruction
                                                                        ---------------------------------------------------------------------------------------------- CPC IMM,ER1 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A9") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A9") then
                                                                        MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
                                                                                FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        TEMP_OP := ALU_CPC;
                                                                                TEMP_OP := ALU_CPC;
                                                                        NUM_BYTES := 5;
                                                                                NUM_BYTES := 5;
                                                                        CPU_STATE := CPU_OMA;
                                                                                CPU_STATE := CPU_OMA;
                                                                --------------------------------------------------------------------------------------------- LDWX ER1,ER2 instruction
                                                                        --------------------------------------------------------------------------------------------- LDWX ER1,ER2 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"E8") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"E8") then
                                                                        MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
                                                                                FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4));
                                                                        DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4));
                                                                                DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
                                                                        NUM_BYTES := 5;
                                                                        NUM_BYTES := 5;
                                                                        CPU_STATE := CPU_LDW;
                                                                                CPU_STATE := CPU_LDW;
                                                                end if;
                                                                        end if;
                                                        end if;
                                                                end if;
                                                end if;
                                                        end if;
 
 
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                        ------------------------------------------------------------------------------------------------------------------------------
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                --                                                     4-byte instructions                                                  --
                                                        --                                                     4-byte instructions                                                  --
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                if (IQUEUE.CNT>=4) then
                                                        if (IQUEUE.CNT>=4) then -- 4-byte instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then    ------------------------------------------------ column 9 instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then    ------------------------------------------------ column 9 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX rr1,r2,X instruction
                                                                                when x"8" =>    ------------------------------------------------------------------------- LDX rr1,r2,X instruction
                                                                        when x"9" =>    ------------------------------------------------------------------------ LEA rr1,rr2,X instruction
                                                                                when x"9" =>    ------------------------------------------------------------------------ LEA rr1,rr2,X instruction
                                                                        when x"C" =>
                                                                                when x"C" =>
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                        when x"D" =>
                                                                                when x"D" =>
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                        when x"F" =>
                                                                                when x"F" =>
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                        when others =>  -------------------------------------------------------------- IM,ER1 addressing mode instructions
                                                                        when others =>  -------------------------------------------------------------- IM,ER1 addressing mode instructions
                                                                                MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                                        FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 4;
                                                                                        NUM_BYTES := 4;
                                                                                CPU_STATE := CPU_OMA;
                                                                                        CPU_STATE := CPU_OMA;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX r1,rr2,X instruction
                                                                                when x"8" =>    ------------------------------------------------------------------------- LDX r1,rr2,X instruction
                                                                        when x"9" =>    -------------------------------------------------------------------------- LEA r1,r2,X instruction
                                                                                when x"9" =>    -------------------------------------------------------------------------- LEA r1,r2,X instruction
                                                                        when x"C" =>    -------------------------------------------------------------------------------- PUSHX instruction
                                                                                when x"C" =>    -------------------------------------------------------------------------------- PUSHX instruction
                                                                        when x"D" =>    --------------------------------------------------------------------------------- POPX instruction
                                                                                when x"D" =>    --------------------------------------------------------------------------------- POPX instruction
                                                                        when x"F" =>
                                                                                when x"F" =>
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                        when others =>  ------------------------------------------------------------- ER2,ER1 addressing mode instructions
                                                                        when others =>  ------------------------------------------------------------- ER2,ER1 addressing mode instructions
                                                                                MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+1)) & IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
                                                                                        FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+1)) & IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
                                                                                DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                                DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 4;
                                                                                        NUM_BYTES := 4;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                end case;
                                                                        end case;
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
                                                                ---------------------------------------------------------------------------------------------------- 2nd page instructions
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
                                                                ------------------------------------------------------------------------------------------------ CPC R2,R1 instruction
                                                                        ------------------------------------------------------------------------------------------------ CPC R2,R1 instruction
                                                                TEMP_OP := ALU_CPC;
                                                                        TEMP_OP := ALU_CPC;
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A4") then
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A4") then
                                                                        MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                                FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        NUM_BYTES := 4;
                                                                                NUM_BYTES := 4;
                                                                        CPU_STATE := CPU_TMA;
                                                                                CPU_STATE := CPU_TMA;
                                                                ----------------------------------------------------------------------------------------------- CPC IR2,R1 instruction
                                                                        ----------------------------------------------------------------------------------------------- CPC IR2,R1 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A5") then
                                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A5") then
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3));
                                                                        MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        NUM_BYTES := 4;
                                                                        NUM_BYTES := 4;
                                                                        CPU_STATE := CPU_ISMD1;
                                                                                CPU_STATE := CPU_ISMD1;
                                                                ----------------------------------------------------------------------------------------------- CPC R1,IMM instruction
                                                                        ----------------------------------------------------------------------------------------------- CPC R1,IMM instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A6") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A6") then
                                                                        MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3);
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3);
                                                                        NUM_BYTES := 4;
                                                                                NUM_BYTES := 4;
                                                                        CPU_STATE := CPU_OMA;
                                                                                CPU_STATE := CPU_OMA;
                                                                ---------------------------------------------------------------------------------------------- CPC IR1,IMM instruction
                                                                        ---------------------------------------------------------------------------------------------- CPC IR1,IMM instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A7") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A7") then
                                                                        MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3);
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3);
                                                                        NUM_BYTES := 4;
                                                                                NUM_BYTES := 4;
                                                                        CPU_STATE := CPU_IND1;
                                                                                CPU_STATE := CPU_IND1;
                                                                end if;
                                                                        end if;
                                                        end if;
                                                                end if;
                                                end if;
                                                        end if;
 
 
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                        ------------------------------------------------------------------------------------------------------------------------------
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                --                                                     3-byte instructions                                                  --
                                                        --                                                     3-byte instructions                                                  --
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                if (IQUEUE.CNT>=3) then
                                                        if (IQUEUE.CNT>=3) then -- 3-byte instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"D") then    -------------------------------------------------- JP cc,DirectAddress
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"D") then    -------------------------------------------------- JP cc,DirectAddress
                                                                if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then
                                                                        if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then
                                                                        PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                else
                                                                        else
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                end if;
                                                                        end if;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then -------------------------------------------- column 9 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then -------------------------------------------- column 9 instructions
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then   ----------------------------------------- LDX rr1,r2,X instruction
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then   ----------------------------------------- LDX rr1,r2,X instruction
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_XRRD;
                                                                                CPU_STATE := CPU_XRRD;
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then        ------------------------------------ LEA rr1,rr2,X instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then        ------------------------------------ LEA rr1,rr2,X instruction
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_XRRTORR;
                                                                                CPU_STATE := CPU_XRRTORR;
                                                                end if;
                                                                        end if;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then   ----------------------------------------- LDX r1,rr2,X instruction
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then   ----------------------------------------- LDX r1,rr2,X instruction
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_XRRS;
                                                                                CPU_STATE := CPU_XRRS;
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then        -------------------------------------- LEA r1,r2,X instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then        -------------------------------------- LEA r1,r2,X instruction
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_XRTOM;
                                                                                CPU_STATE := CPU_XRTOM;
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"C") then        ---------------------------------------- PUSHX ER2 instruction
                                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"C") then        ---------------------------------------- PUSHX ER2 instruction
                                                                        SP := SP - 1;
                                                                        SP := SP - 1;
                                                                        MAB <= ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
                                                                                FRAB <= ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
                                                                        DEST_ADDR := SP;
                                                                        DEST_ADDR := SP;
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_TMA;
                                                                                CPU_STATE := CPU_TMA;
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"D") then        ----------------------------------------- POPX ER2 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"D") then        ----------------------------------------- POPX ER2 instruction
                                                                        MAB <= SP;
                                                                                FRAB <= SP;
                                                                        DEST_ADDR := ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
                                                                        DEST_ADDR := ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
                                                                        SP := SP + 1;
                                                                                SP := SP + 1;
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_TMA;
                                                                                CPU_STATE := CPU_TMA;
                                                                end if;
                                                                        end if;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"7") then -------------------------------------------- column 7 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"7") then -------------------------------------------- column 7 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX IRR2,IR1 instruction
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX IRR2,IR1 instruction
                                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_IRRS;
                                                                                        CPU_STATE := CPU_IRRS;
                                                                        when x"9" =>    ------------------------------------------------------------------------- LDX IR2,IRR1 instruction
                                                                        when x"9" =>    ------------------------------------------------------------------------- LDX IR2,IRR1 instruction
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_IMTOIRR;
                                                                                        CPU_STATE := CPU_IMTOIRR;
                                                                        when x"C" =>    --------------------------------------------------------------------------- LD r1,r2,X instruction
                                                                        when x"C" =>    --------------------------------------------------------------------------- LD r1,r2,X instruction
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
                                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_XADTOM;
                                                                                        CPU_STATE := CPU_XADTOM;
                                                                        when x"D" =>    --------------------------------------------------------------------------- LD r2,r1,X instruction
                                                                        when x"D" =>    --------------------------------------------------------------------------- LD r2,r1,X instruction
                                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
                                                                                        FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
                                                                                DEST_ADDR := RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                                DEST_ADDR := RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_MTOXAD;
                                                                                        CPU_STATE := CPU_MTOXAD;
                                                                        when x"F" =>    ------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction
                                                                                when x"F" =>    ------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction
                                                                        when others =>  ----------------------------------------------------------------------------- IR1,imm instructions
                                                                        when others =>  ----------------------------------------------------------------------------- IR1,imm instructions
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_IND1;
                                                                                        CPU_STATE := CPU_IND1;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"6") then -------------------------------------------- column 6 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"6") then -------------------------------------------- column 6 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDX IRR2,R1 instruction
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDX IRR2,R1 instruction
                                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                LU_INSTRUCTION := '1';  -- in this mode this flag is used to signal the direct register addressing mode
                                                                                        LU_INSTRUCTION := '1';  -- in this mode this flag is used to signal the direct register addressing mode
                                                                                CPU_STATE := CPU_IRRS;
                                                                                        CPU_STATE := CPU_IRRS;
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDX R2,IRR1 instruction
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDX R2,IRR1 instruction
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_MTOIRR;
                                                                                        CPU_STATE := CPU_MTOIRR;
                                                                        when x"C" =>    -- illegal, decoded at 1-byte decoder
                                                                                when x"C" =>    -- illegal, decoded at 1-byte decoder
                                                                                --CPU_STATE := CPU_ILLEGAL;     -- uncommenting this adds +400 LEs to the design!!!
                                                                                        --CPU_STATE := CPU_ILLEGAL;     -- uncommenting this adds +400 LEs to the design!!!
                                                                        when x"D" =>    ------------------------------------------------------------------------------ CALL DA instruction
                                                                                when x"D" =>    ------------------------------------------------------------------------------ CALL DA instruction
                                                                        when x"F" =>    ------------------------------------------------------------------------- BTJ p,b,r1,X instruction
                                                                                when x"F" =>    ------------------------------------------------------------------------- BTJ p,b,r1,X instruction
                                                                        when others =>  ------------------------------------------------------------------------------ R1,imm instructions
                                                                        when others =>  ------------------------------------------------------------------------------ R1,imm instructions
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_OMA;
                                                                                        CPU_STATE := CPU_OMA;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"5") then -------------------------------------------- column 5 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"5") then -------------------------------------------- column 5 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDX Ir1,ER2 instruction
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDX Ir1,ER2 instruction
                                                                                MAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                        FRAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                      -- dest address
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                      -- dest address
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_IND2;
                                                                                        CPU_STATE := CPU_IND2;
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDX Ir2,ER1 instruction
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDX Ir2,ER1 instruction
                                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
                                                                                        FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
                                                                                DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_ISMD1;
                                                                                        CPU_STATE := CPU_ISMD1;
                                                                        when x"C" =>    ------------------------------------------------------------------------- LDC Ir1,Irr2 instruction
                                                                                when x"C" =>    ------------------------------------------------------------------------- LDC Ir1,Irr2 instruction
                                                                        when x"D" =>    ----------------------------------------------------------------------------- BSWAP R1 instruction
                                                                                when x"D" =>    ----------------------------------------------------------------------------- BSWAP R1 instruction
                                                                        when x"F" =>    ---------------------------------------------------------------------------- LD R2,IR1 instruction
                                                                                when x"F" =>    ---------------------------------------------------------------------------- LD R2,IR1 instruction
                                                                        when others =>  ------------------------------------------------------------------------------ IR2,R1 instructions
                                                                                when others =>  ------------------------------------------------------------------------------ IR2,R1 instructions
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_ISMD1;
                                                                                        CPU_STATE := CPU_ISMD1;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"4") then -------------------------------------------- column 4 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"4") then -------------------------------------------- column 4 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    --------------------------------------------------------------------------- LDX r1,ER2 instruction
                                                                        when x"8" =>    --------------------------------------------------------------------------- LDX r1,ER2 instruction
                                                                                MAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                        FRAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                      -- dest address
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                      -- dest address
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                        when x"9" =>    --------------------------------------------------------------------------- LDX r2,ER1 instruction
                                                                        when x"9" =>    --------------------------------------------------------------------------- LDX r2,ER1 instruction
                                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
                                                                                        FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
                                                                                DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                        when x"C" =>    ------------------------------------------------------------------------------ JP Irr1 instruction
                                                                                when x"C" =>    ------------------------------------------------------------------------------ JP Irr1 instruction
                                                                        when x"D" =>    ---------------------------------------------------------------------------- CALL Irr1 instruction
                                                                                when x"D" =>    ---------------------------------------------------------------------------- CALL Irr1 instruction
                                                                        when x"F" =>    ----------------------------------------------------------------------------- MULT RR1 instruction
                                                                                when x"F" =>    ----------------------------------------------------------------------------- MULT RR1 instruction
                                                                        when others =>  ------------------------------------------------------------------------------- R2,R1 instructions
                                                                        when others =>  ------------------------------------------------------------------------------- R2,R1 instructions
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 3;
                                                                                        NUM_BYTES := 3;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                end case;
                                                                        end case;
                                                        end if;
                                                                end if;
                                                        ------------------------------------------------------------------------------------------------- BTJ p,b,r1,X instruction
                                                                ------------------------------------------------------------------------------------------------- BTJ p,b,r1,X instruction
                                                        ------------------------------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction
                                                                ------------------------------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F6" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F7") then
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F6" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F7") then
                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);    -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0)
                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);    -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0)
                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                 -- RESULT has the offset X
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                 -- RESULT has the offset X
                                                                NUM_BYTES := 3;
                                                                        NUM_BYTES := 3;
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(0)='0') then CPU_STATE := CPU_BTJ; else CPU_STATE := CPU_IBTJ;
                                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(0)='0') then CPU_STATE := CPU_BTJ; else CPU_STATE := CPU_IBTJ;
                                                                end if;
                                                                        end if;
                                                        ---------------------------------------------------------------------------------------------------- LD R2,IR1 instruction
                                                                ---------------------------------------------------------------------------------------------------- LD R2,IR1 instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F5") then
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F5") then
                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                NUM_BYTES := 3;
                                                                NUM_BYTES := 3;
                                                                CPU_STATE := CPU_IND2;
                                                                        CPU_STATE := CPU_IND2;
                                                        ------------------------------------------------------------------------------------------------------ CALL DA instruction
                                                                ------------------------------------------------------------------------------------------------------ CALL DA instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D6") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D6") then
                                                                DEST_ADDR16 := PC + 3;
                                                                        DEST_ADDR16 := PC + 3;
                                                                PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                SP := SP - 1;
                                                                SP := SP - 1;
                                                                MAB <= SP;
                                                                        FRAB <= SP;
                                                                LU_INSTRUCTION := '0';   -- this is used to indicate wether the stacking is due to a CALL or INT, 0 for a CALL
                                                                LU_INSTRUCTION := '0';   -- this is used to indicate wether the stacking is due to a CALL or INT, 0 for a CALL
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                CPU_STATE := CPU_STACK;
                                                                        CPU_STATE := CPU_STACK;
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
                                                                ---------------------------------------------------------------------------------------------------- 2nd page instructions
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
                                                                -------------------------------------------------------------------------------------------------- PUSH IM instruction
                                                                        -------------------------------------------------------------------------------------------------- PUSH IM instruction
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"70") then
                                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"70") then
                                                                        SP := SP - 1;
                                                                        SP := SP - 1;
                                                                        MAB <= SP;
                                                                                FRAB <= SP;
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_OMA;
                                                                                CPU_STATE := CPU_OMA;
                                                                ------------------------------------------------------------------------------------------------ CPC r1,r2 instruction
                                                                        ------------------------------------------------------------------------------------------------ CPC r1,r2 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A2") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A2") then
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0));                                                     -- source address                               
                                                                                FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0));                                                    -- source address                               
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));                                              -- dest address
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));                                              -- dest address
                                                                        TEMP_OP := ALU_CPC;
                                                                                TEMP_OP := ALU_CPC;
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_TMA;
                                                                                CPU_STATE := CPU_TMA;
                                                                ----------------------------------------------------------------------------------------------- CPC r1,Ir2 instruction
                                                                        ----------------------------------------------------------------------------------------------- CPC r1,Ir2 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A3") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A3") then
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0));                                                     -- source address                               
                                                                                FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0));                                                    -- source address                               
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));                                              -- dest address
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));                                              -- dest address
                                                                        TEMP_OP := ALU_CPC;
                                                                                TEMP_OP := ALU_CPC;
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_ISMD1;
                                                                                CPU_STATE := CPU_ISMD1;
                                                                --------------------------------------------------------------------------------------------------- SRL R1 instruction
                                                                        --------------------------------------------------------------------------------------------------- SRL R1 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C0") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C0") then
                                                                        MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                                FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        TEMP_OP := LU2_SRL;
                                                                        TEMP_OP := LU2_SRL;
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_OMA2;
                                                                                CPU_STATE := CPU_OMA2;
                                                                -------------------------------------------------------------------------------------------------- SRL IR1 instruction
                                                                        -------------------------------------------------------------------------------------------------- SRL IR1 instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C1") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C1") then
                                                                        MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
                                                                                FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
                                                                        TEMP_OP := LU2_SRL;
                                                                        TEMP_OP := LU2_SRL;
                                                                        NUM_BYTES := 3;
                                                                                NUM_BYTES := 3;
                                                                        CPU_STATE := CPU_IND1;
                                                                                CPU_STATE := CPU_IND1;
                                                                        LU_INSTRUCTION := '1';
                                                                                LU_INSTRUCTION := '1';
                                                                end if;
                                                                        end if;
                                                        end if;
                                                                end if;
                                                end if;
                                                        end if;
 
 
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                        ------------------------------------------------------------------------------------------------------------------------------
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                --                                                     2-byte instructions                                                  --
                                                        --                                                     2-byte instructions                                                  --
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                if (IQUEUE.CNT>=2) then
                                                        if (IQUEUE.CNT>=2) then -- 2-byte instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"C") then    ------------------------------------------------- LD r,IMM instruction
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"C") then    ------------------------------------------------- LD r,IMM instruction
                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4));
                                                                DATAWRITE(RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4),IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                        DATAWRITE(ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)),IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                NUM_BYTES := 2;
                                                                NUM_BYTES := 2;
                                                                CPU_STATE := CPU_STORE;
                                                                        CPU_STATE := CPU_STORE;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"B") then -------------------------------------------- JR cc,RelativeAddress
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"B") then -------------------------------------------- JR cc,RelativeAddress
                                                                PC := PC + 2;
                                                                        PC := PC + 2;
                                                                if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then
                                                                        if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then
                                                                        PC := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                PC := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                else
                                                                        else
                                                                        IQUEUE.RDPOS := IQUEUE.RDPOS + 2;
                                                                                IQUEUE.RDPOS := IQUEUE.RDPOS + 2;
                                                                        IQUEUE.CNT := IQUEUE.CNT - 2;
                                                                                IQUEUE.CNT := IQUEUE.CNT - 2;
                                                                end if;
                                                                        end if;
                                                                CPU_STATE := CPU_DECOD;
                                                                        CPU_STATE := CPU_DECOD;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"A") then ------------------------------------------- DJNZ r,RelativeAddress
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"A") then ------------------------------------------- DJNZ r,RelativeAddress
                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4));
                                                                PC := PC + 2;
                                                                PC := PC + 2;
                                                                DEST_ADDR16 := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                        DEST_ADDR16 := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                IQUEUE.RDPOS := IQUEUE.RDPOS + 2;
                                                                        IQUEUE.RDPOS := IQUEUE.RDPOS + 2;
                                                                IQUEUE.CNT := IQUEUE.CNT - 2;
                                                                        IQUEUE.CNT := IQUEUE.CNT - 2;
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                        IQUEUE.FETCH_STATE := F_ADDR;
                                                                CPU_STATE := CPU_DJNZ;
                                                                        CPU_STATE := CPU_DJNZ;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"3") then -------------------------------------------- column 3 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"3") then -------------------------------------------- column 3 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    ------------------------------------------------------------------------ LDEI Ir1,Irr2 instruction
                                                                                when x"8" =>    ------------------------------------------------------------------------ LDEI Ir1,Irr2 instruction
                                                                        when x"9" =>    ------------------------------------------------------------------------ LDEI Ir2,Irr1 instruction
                                                                                when x"9" =>    ------------------------------------------------------------------------ LDEI Ir2,Irr1 instruction
                                                                        when x"C" =>    ------------------------------------------------------------------------ LDCI Ir1,Irr2 instruction
                                                                                when x"C" =>    ------------------------------------------------------------------------ LDCI Ir1,Irr2 instruction
                                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                NUM_BYTES := 2;
                                                                                NUM_BYTES := 2;
                                                                                CAN_FETCH := '0';
                                                                                        CAN_FETCH := '0';
                                                                                LU_INSTRUCTION := '0';   -- indicates it is a read from program memory
                                                                                        LU_INSTRUCTION := '0';   -- indicates it is a read from program memory
                                                                                WORD_DATA := '1';               -- indicates it is a LDCI instruction
                                                                                        WORD_DATA := '1';               -- indicates it is a LDCI instruction
                                                                                CPU_STATE := CPU_LDPTOIM;
                                                                                        CPU_STATE := CPU_LDPTOIM;
                                                                        when x"D" =>    ------------------------------------------------------------------------ LDCI Ir2,Irr1 instruction
                                                                                when x"D" =>    ------------------------------------------------------------------------ LDCI Ir2,Irr1 instruction
                                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                NUM_BYTES := 2;
                                                                                NUM_BYTES := 2;
                                                                                CAN_FETCH := '0';
                                                                                        CAN_FETCH := '0';
                                                                                LU_INSTRUCTION := '1';  -- indicates it is a write onto program memory
                                                                                        LU_INSTRUCTION := '1';  -- indicates it is a write onto program memory
                                                                                WORD_DATA := '1';               -- indicates it is a LDCI instruction
                                                                                        WORD_DATA := '1';               -- indicates it is a LDCI instruction
                                                                                CPU_STATE := CPU_LDPTOIM;
                                                                                        CPU_STATE := CPU_LDPTOIM;
                                                                        when x"F" =>    ---------------------------------------------------------------------------- LD Ir1,r2 instruction
                                                                        when x"F" =>    ---------------------------------------------------------------------------- LD Ir1,r2 instruction
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_IND2;
                                                                                        CPU_STATE := CPU_IND2;
                                                                        when others =>  --------------------------------------------------------------------------- Ir2 to r1 instructions
                                                                        when others =>  --------------------------------------------------------------------------- Ir2 to r1 instructions
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_ISMD1;
                                                                                        CPU_STATE := CPU_ISMD1;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"2") then -------------------------------------------- column 2 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"2") then -------------------------------------------- column 2 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDE r1,Irr2 instruction
                                                                                when x"8" =>    -------------------------------------------------------------------------- LDE r1,Irr2 instruction
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDE r2,Irr1 instruction
                                                                                when x"9" =>    -------------------------------------------------------------------------- LDE r2,Irr1 instruction
                                                                        when x"C" =>    -------------------------------------------------------------------------- LDC r1,Irr2 instruction
                                                                        when x"C" =>    -------------------------------------------------------------------------- LDC r1,Irr2 instruction
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CAN_FETCH := '0';
                                                                                        CAN_FETCH := '0';
                                                                                LU_INSTRUCTION := '0';
                                                                                        LU_INSTRUCTION := '0';
                                                                                CPU_STATE := CPU_LDPTOM;
                                                                                        CPU_STATE := CPU_LDPTOM;
                                                                        when x"D" =>    -------------------------------------------------------------------------- LDC r2,Irr1 instruction
                                                                        when x"D" =>    -------------------------------------------------------------------------- LDC r2,Irr1 instruction
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CAN_FETCH := '0';
                                                                                        CAN_FETCH := '0';
                                                                                LU_INSTRUCTION := '1';
                                                                                        LU_INSTRUCTION := '1';
                                                                                CPU_STATE := CPU_LDPTOM;
                                                                                        CPU_STATE := CPU_LDPTOM;
                                                                        when x"E" =>    --------------------------------------------------------------------------- BIT p,b,r1 instruction
                                                                        when x"E" =>    --------------------------------------------------------------------------- BIT p,b,r1 instruction
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);    -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0)
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);    -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0)
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                 -- RESULT has the offset X
                                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                 -- RESULT has the offset X
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_BIT;
                                                                                        CPU_STATE := CPU_BIT;
                                                                        when x"F" =>    ----------------------------------------------------------------------------- TRAP imm instruction
                                                                        when x"F" =>    ----------------------------------------------------------------------------- TRAP imm instruction
                                                                                MAB <= "000" & IQUEUE.QUEUE(IQUEUE.RDPOS+1) & '0';
                                                                                        FRAB <= "000" & IQUEUE.QUEUE(IQUEUE.RDPOS+1) & '0';
                                                                                DEST_ADDR16 := PC + 2;
                                                                                DEST_ADDR16 := PC + 2;
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_TRAP;
                                                                                        CPU_STATE := CPU_TRAP;
                                                                        when others =>  ---------------------------------------------------------------------------- r2 to r1 instructions
                                                                        when others =>  ---------------------------------------------------------------------------- r2 to r1 instructions
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
                                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                    -- source address                               
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                        TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"1") then -------------------------------------------- column 1 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"1") then -------------------------------------------- column 1 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"0" =>     ------------------------------------------------------------------------------ SRP IMM instruction      
                                                                                when x"0" =>     ------------------------------------------------------------------------------ SRP IMM instruction      
                                                                                RP := IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                        RP := IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_DECOD;
                                                                                        CPU_STATE := CPU_DECOD;
                                                                        when x"5" =>    ------------------------------------------------------------------------------ POP IR1 instruction
                                                                        when x"5" =>    ------------------------------------------------------------------------------ POP IR1 instruction
                                                                                MAB <= SP;
                                                                                        FRAB <= SP;
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                SP := SP + 1;
                                                                                        SP := SP + 1;
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_IND2;
                                                                                        CPU_STATE := CPU_IND2;
                                                                        when x"7" =>    ----------------------------------------------------------------------------- PUSH IR1 instruction
                                                                                when x"7" =>    ----------------------------------------------------------------------------- PUSH IR1 instruction
                                                                                SP := SP - 1;
                                                                                SP := SP - 1;
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := SP;
                                                                                DEST_ADDR := SP;
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_ISMD1;
                                                                                        CPU_STATE := CPU_ISMD1;
                                                                        when x"8" =>    --------------------------------------------------------------------------------- DECW instruction
                                                                        when x"8" =>    --------------------------------------------------------------------------------- DECW instruction
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_OP := LU2_DEC;
                                                                                TEMP_OP := LU2_DEC;
                                                                                WORD_DATA := '1';
                                                                                        WORD_DATA := '1';
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_INDRR;
                                                                                        CPU_STATE := CPU_INDRR;
                                                                        when x"A" =>    --------------------------------------------------------------------------------- INCW instruction
                                                                        when x"A" =>    --------------------------------------------------------------------------------- INCW instruction
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_OP := LU2_INC;
                                                                                TEMP_OP := LU2_INC;
                                                                                WORD_DATA := '1';
                                                                                        WORD_DATA := '1';
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_INDRR;
                                                                                        CPU_STATE := CPU_INDRR;
                                                                        when others =>  --------------------------------------------------------------------------------- IR1 instructions
                                                                        when others =>  --------------------------------------------------------------------------------- IR1 instructions
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_IND1;
                                                                                        CPU_STATE := CPU_IND1;
                                                                                LU_INSTRUCTION := '1';
                                                                                        LU_INSTRUCTION := '1';
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"0") then  -------------------------------------------- column 0 instructions
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"0") then  -------------------------------------------- column 0 instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"0" =>     ---------------------------------------------------------------------------------- BRK instruction      
                                                                                when x"0" =>     ---------------------------------------------------------------------------------- BRK instruction      
                                                                                -- do nothing, BRK decoding is done in 1-byte instruction section
                                                                                        -- do nothing, BRK decoding is done in 1-byte instruction section
                                                                        when x"5" =>    ---------------------------------------------------------------------------------- POP instruction
                                                                        when x"5" =>    ---------------------------------------------------------------------------------- POP instruction
                                                                                MAB <= SP;
                                                                                        FRAB <= SP;
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                SP := SP + 1;
                                                                                        SP := SP + 1;
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                        when x"7" =>    --------------------------------------------------------------------------------- PUSH instruction
                                                                                when x"7" =>    --------------------------------------------------------------------------------- PUSH instruction
                                                                                SP := SP - 1;
                                                                                SP := SP - 1;
                                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := SP;
                                                                                DEST_ADDR := SP;
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_TMA;
                                                                                        CPU_STATE := CPU_TMA;
                                                                        when x"8" =>    --------------------------------------------------------------------------------- DECW instruction
                                                                                when x"8" =>    --------------------------------------------------------------------------------- DECW instruction
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                MAB <= DEST_ADDR+1;
                                                                                        FRAB <= DEST_ADDR+1;
                                                                                TEMP_OP := LU2_DEC;
                                                                                TEMP_OP := LU2_DEC;
                                                                                WORD_DATA := '1';
                                                                                        WORD_DATA := '1';
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_OMA2;
                                                                                        CPU_STATE := CPU_OMA2;
                                                                        when x"A" =>    --------------------------------------------------------------------------------- INCW instruction
                                                                                when x"A" =>    --------------------------------------------------------------------------------- INCW instruction
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                MAB <= DEST_ADDR+1;
                                                                                        FRAB <= DEST_ADDR+1;
                                                                                TEMP_OP := LU2_INC;
                                                                                TEMP_OP := LU2_INC;
                                                                                WORD_DATA := '1';
                                                                                        WORD_DATA := '1';
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_OMA2;
                                                                                        CPU_STATE := CPU_OMA2;
                                                                        when others =>  ---------------------------------------------------------------------------------- R1 instructions
                                                                        when others =>  ---------------------------------------------------------------------------------- R1 instructions
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                                NUM_BYTES := 2;
                                                                                        NUM_BYTES := 2;
                                                                                CPU_STATE := CPU_OMA2;
                                                                                        CPU_STATE := CPU_OMA2;
                                                                end case;
                                                                        end case;
                                                        end if;
                                                                end if;
                                                        ---------------------------------------------------------------------------------------------------------- MUL instruction 
                                                                ---------------------------------------------------------------------------------------------------------- MUL instruction 
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F4") then
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F4") then
                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                NUM_BYTES := 2;
                                                                NUM_BYTES := 2;
                                                                CPU_STATE := CPU_MUL;
                                                                        CPU_STATE := CPU_MUL;
                                                        ---------------------------------------------------------------------------------------------------- CALL IRR1 instruction
                                                                ---------------------------------------------------------------------------------------------------- CALL IRR1 instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D4") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D4") then
                                                                DEST_ADDR16 := PC + 2;
                                                                DEST_ADDR16 := PC + 2;
                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                CPU_STATE := CPU_INDSTACK;
                                                                        CPU_STATE := CPU_INDSTACK;
                                                        ------------------------------------------------------------------------------------------------------ JP IRR1 instruction
                                                                ------------------------------------------------------------------------------------------------------ JP IRR1 instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C4") then
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C4") then
                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                                CPU_STATE := CPU_INDJUMP;
                                                                        CPU_STATE := CPU_INDJUMP;
                                                        ----------------------------------------------------------------------------------------------------- BSWAP R1 instruction
                                                                ----------------------------------------------------------------------------------------------------- BSWAP R1 instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D5") then
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D5") then
                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                        FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
                                                                TEMP_OP := ALU_BSWAP;
                                                                TEMP_OP := ALU_BSWAP;
                                                                NUM_BYTES := 2;
                                                                        NUM_BYTES := 2;
                                                                CPU_STATE := CPU_OMA;
                                                                        CPU_STATE := CPU_OMA;
                                                        ------------------------------------------------------------------------------------------------- LDC Ir1,Irr2 instruction
                                                                ------------------------------------------------------------------------------------------------- LDC Ir1,Irr2 instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C5") then
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C5") then
                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                        FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
                                                                NUM_BYTES := 2;
                                                                NUM_BYTES := 2;
                                                                CAN_FETCH := '0';
                                                                        CAN_FETCH := '0';
                                                                LU_INSTRUCTION := '0';
                                                                        LU_INSTRUCTION := '0';
                                                                CPU_STATE := CPU_LDPTOIM;
                                                                        CPU_STATE := CPU_LDPTOIM;
                                                        end if;
                                                                end if;
                                                end if;
                                                        end if;
 
 
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                        ------------------------------------------------------------------------------------------------------------------------------
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                --                                                     1-byte instructions                                                  --
                                                        --                                                     1-byte instructions                                                  --
                                                --**************************************************************************************************************************--
                                                        --**************************************************************************************************************************--
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                ------------------------------------------------------------------------------------------------------------------------------
                                                if (IQUEUE.CNT>=1) then
                                                        if (IQUEUE.CNT>=1) then -- 1-byte instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"F") then    ------------------------------------------------ column F instructions
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"F") then    ------------------------------------------------ column F instructions
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
                                                                        when x"0" =>     ---------------------------------------------------------------------------------- NOP instruction      
                                                                                when x"0" =>     ---------------------------------------------------------------------------------- NOP instruction      
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"1" =>    ------------------------------------------------------------------------------ page 2 instructions
                                                                                when x"1" =>    ------------------------------------------------------------------------------ page 2 instructions
                                                                        when x"2" =>
                                                                                when x"2" =>
                                                                                ATM_COUNTER := 0;
                                                                                        ATM_COUNTER := 0;
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"3" =>
                                                                                when x"3" =>
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                        when x"4" =>
                                                                                when x"4" =>
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                        when x"5" =>    ---------------------------------------------------------------------------------- WDT instruction
                                                                                when x"5" =>    ---------------------------------------------------------------------------------- WDT instruction
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"6" =>    --------------------------------------------------------------------------------- STOP instruction
                                                                                when x"6" =>    --------------------------------------------------------------------------------- STOP instruction
                                                                                NUM_BYTES := 1;
                                                                                NUM_BYTES := 1;
                                                                                CPU_STATE := CPU_HALTED;
 
                                                                                STOP <= '1';
                                                                                STOP <= '1';
                                                                        when x"7" =>    --------------------------------------------------------------------------------- HALT instruction
                                                                                when x"7" =>    --------------------------------------------------------------------------------- HALT instruction
                                                                                NUM_BYTES := 1;
                                                                                NUM_BYTES := 1;
                                                                                CPU_STATE := CPU_HALTED;
                                                                                        HALT := '1';
                                                                        when x"8" =>    ----------------------------------------------------------------------------------- DI instruction
                                                                        when x"8" =>    ----------------------------------------------------------------------------------- DI instruction
                                                                                IRQE := '0';
                                                                                        IRQE := '0';
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"9" =>    ----------------------------------------------------------------------------------- EI instruction
                                                                                when x"9" =>    ----------------------------------------------------------------------------------- EI instruction
                                                                                IRQE := '1';
                                                                                        IRQE := '1';
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"A" =>    ---------------------------------------------------------------------------------- RET instruction
                                                                                when x"A" =>    ---------------------------------------------------------------------------------- RET instruction
                                                                                NUM_BYTES := 1;
                                                                                NUM_BYTES := 1;
                                                                                MAB <= SP;
                                                                                        FRAB <= SP;
                                                                                CPU_STATE := CPU_UNSTACK;
                                                                                        CPU_STATE := CPU_UNSTACK2;
                                                                        when x"B" =>    --------------------------------------------------------------------------------- IRET instruction
                                                                        when x"B" =>    --------------------------------------------------------------------------------- IRET instruction
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                                IRQE := '1';
                                                                                IRQE := '1';
                                                                                MAB <= SP;
                                                                                        FRAB <= SP;
                                                                                CPU_STATE := CPU_UNSTACK3;
                                                                                CPU_STATE := CPU_UNSTACK3;
                                                                        when x"C" =>    ---------------------------------------------------------------------------------- RCF instruction
                                                                                when x"C" =>    ---------------------------------------------------------------------------------- RCF instruction
                                                                                CPU_FLAGS.C := '0';
                                                                                        CPU_FLAGS.C := '0';
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"D" =>    ---------------------------------------------------------------------------------- SCF instruction
                                                                                when x"D" =>    ---------------------------------------------------------------------------------- SCF instruction
                                                                                CPU_FLAGS.C := '1';
                                                                                        CPU_FLAGS.C := '1';
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when x"E" =>    ---------------------------------------------------------------------------------- CCF instruction
                                                                                when x"E" =>    ---------------------------------------------------------------------------------- CCF instruction
                                                                                CPU_FLAGS.C := not CPU_FLAGS.C;
                                                                                        CPU_FLAGS.C := not CPU_FLAGS.C;
                                                                                NUM_BYTES := 1;
                                                                                        NUM_BYTES := 1;
                                                                        when others =>  ---------------------------------------------------------------------------------- R1 instructions
                                                                                when others =>  ---------------------------------------------------------------------------------- R1 instructions
                                                                                CPU_STATE := CPU_ILLEGAL;
                                                                                        CPU_STATE := CPU_ILLEGAL;
                                                                end case;
                                                                        end case;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"E") then ------------------------------------------------ INC r instruction
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"E") then ------------------------------------------------ INC r instruction
                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                        FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
                                                                TEMP_OP := LU2_INC;
                                                                TEMP_OP := LU2_INC;
                                                                NUM_BYTES := 1;
                                                                        NUM_BYTES := 1;
                                                                CPU_STATE := CPU_OMA2;
                                                                        CPU_STATE := CPU_OMA2;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"00") then   -------------------------------------------------------------- BRK instruction
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"00") then   -------------------------------------------------------------- BRK instruction
                                                                if (OCDCR.BRKEN='1') then               -- the BRK instruction is enabled
                                                                        if (OCDCR.BRKEN='1') then               -- the BRK instruction is enabled
                                                                        if (OCDCR.DBGACK='1') then
                                                                                if (OCDCR.DBGACK='1') then
                                                                                if (DBG_UART.TX_EMPTY='1') then
                                                                                        if (DBG_UART.TX_EMPTY='1') then
                                                                                        DBG_UART.TX_DATA:=x"FF";
                                                                                                DBG_UART.TX_DATA:=x"FF";
                                                                                        DBG_UART.TX_EMPTY:='0';
                                                                                                DBG_UART.TX_EMPTY:='0';
                                                                                end if;
                                                                                        end if;
                                                                        end if;
                                                                                end if;
                                                                        if (OCDCR.BRKLOOP='0') then      -- if loop on BRK is disabled
                                                                                if (OCDCR.BRKLOOP='0') then      -- if loop on BRK is disabled
                                                                                OCDCR.DBGMODE := '1';   -- set DBGMODE halting CPU
                                                                                        OCDCR.DBGMODE := '1';   -- set DBGMODE halting CPU
                                                                        end if;
                                                                                end if;
                                                                else
                                                                        else
                                                                        NUM_BYTES := 1;                 -- remove the instruction from queue (execute as a NOP)
                                                                                NUM_BYTES := 1;                 -- remove the instruction from queue (execute as a NOP)
                                                                end if;
                                                                        end if;
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F9" or
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F9" or
                                                                        IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F8" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C6") then      --------------------------- illegal opcode
                                                                                IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F8" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C6") then      --------------------------- illegal opcode
                                                                CPU_STATE:= CPU_ILLEGAL;
                                                                        CPU_STATE:= CPU_ILLEGAL;
                                                                NUM_BYTES := 1;
                                                                        NUM_BYTES := 1;
                                                        end if;
                                                                end if;
                                                end if;
                                                end if;
                                        end if;
                                                end if; -- if DBGMODE=0...
                                        PC := PC + NUM_BYTES;
                                        end if; -- if not stopped or halted
                                        IQUEUE.RDPOS := IQUEUE.RDPOS + NUM_BYTES;
                                        PC := PC + NUM_BYTES;                                           -- update PC after instruction
                                        IQUEUE.CNT := IQUEUE.CNT - NUM_BYTES;
                                        IQUEUE.RDPOS := IQUEUE.RDPOS + NUM_BYTES;       -- update QUEUE read pointer
                                        if (OCD.SINGLESTEP='1') then
                                        IQUEUE.CNT := IQUEUE.CNT - NUM_BYTES;           -- update QUEUE available bytes
                                                if (NUM_BYTES/=0 or IQUEUE.FETCH_STATE=F_ADDR) then OCD.SINGLESTEP:='0';
                                        if (OCD.SINGLESTEP='1') then                                                                                                    -- if we are stepping instructions
 
                                                if (NUM_BYTES/=0 or IQUEUE.FETCH_STATE=F_ADDR) then OCD.SINGLESTEP:='0';  -- if a instruction was decoded, reset step flag
                                                end if;
                                                end if;
                                        end if;
                                        end if;
                                when CPU_MUL => -- MUL ***********************************************************************************************************
                                when CPU_MUL => -- MUL ***********************************************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);             -- read first operand
                                        TEMP_DATA := DATAREAD(FRAB);            -- read first operand
                                        MAB <= MAB + 1;                                 -- go to the next operand 
                                        FRAB <= FRAB + 1;                                       -- go to the next operand 
                                        CPU_STATE := CPU_MUL1;
                                        CPU_STATE := CPU_MUL1;
                                when CPU_MUL1 =>
                                when CPU_MUL1 =>
                                        DEST_ADDR16 := TEMP_DATA * DATAREAD(MAB);       -- multiply previous operand by the second operand and store temporarily
                                        DEST_ADDR16 := TEMP_DATA * DATAREAD(FRAB);      -- multiply previous operand by the second operand and store temporarily
                                        DATAWRITE(MAB,DEST_ADDR16(7 downto 0));          -- write the lower byte in current memory address 
                                        DATAWRITE(FRAB,DEST_ADDR16(7 downto 0)); -- prepare to write the lower byte in current memory address 
                                        WR <= '1';
                                        WR <= '1';
                                        CPU_STATE := CPU_MUL2;
                                        CPU_STATE := CPU_MUL2;
                                when CPU_MUL2 =>
                                when CPU_MUL2 =>
                                        MAB <= MAB - 1;                                                         -- decrement memory address (point to the first operand)
                                        FRAB <= FRAB - 1;                                                       -- decrement memory address (point to the first operand)
                                        DATAWRITE(MAB,DEST_ADDR16(15 downto 8));        -- write the higher byte
                                        DATAWRITE(FRAB,DEST_ADDR16(15 downto 8));       -- write the higher byte
                                        CPU_STATE := CPU_STORE;                                         -- complete store operation
                                        CPU_STATE := CPU_STORE;                                         -- complete store operation
                                when CPU_XRRTORR =>     -- LEA *******************************************************************************************************
                                when CPU_XRRTORR =>     -- LEA *******************************************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);                                     -- read the operand and store it
                                        TEMP_DATA := DATAREAD(FRAB);                            -- read the operand and store it
                                        MAB <= MAB + 1;                                                         -- go to the next memory address
                                        FRAB <= FRAB + 1;                                                       -- go to the next memory address
                                        CPU_STATE := CPU_XRRTORR2;
                                        CPU_STATE := CPU_XRRTORR2;
                                when CPU_XRRTORR2 =>
                                when CPU_XRRTORR2 =>
                                        -- read the next operand and perform a 16 bit add with the offset previously in result
                                        -- read next operand and perform a 16 bit add with the offset previously in result
                                        DEST_ADDR16 := ADDER16(TEMP_DATA & DATAREAD(MAB),RESULT);
                                        DEST_ADDR16 := ADDER16(TEMP_DATA & DATAREAD(FRAB),RESULT);
                                        MAB <= DEST_ADDR;                                                       -- point to the destination address
                                        FRAB <= DEST_ADDR;                                                      -- point to the destination address
                                        DATAWRITE(MAB,DEST_ADDR16(15 downto 8));        -- store the higher byte of the 16-bit result
                                        DATAWRITE(FRAB,DEST_ADDR16(15 downto 8));       -- store the higher byte of the 16-bit result
                                        CPU_STATE := CPU_XRRTORR3;
                                        CPU_STATE := CPU_XRRTORR3;
                                when CPU_XRRTORR3 =>
                                when CPU_XRRTORR3 =>
                                        WR <= '1';
                                        WR <= '1';
                                        CPU_STATE := CPU_XRRTORR4;
                                        CPU_STATE := CPU_XRRTORR4;
                                when CPU_XRRTORR4 =>
                                when CPU_XRRTORR4 =>
                                        MAB <= MAB + 1;                                                         -- go to the next memory address
                                        FRAB <= FRAB + 1;                                                       -- go to the next memory address
                                        DATAWRITE(MAB,DEST_ADDR16(7 downto 0));          -- store the lower byte of the 16-bit result
                                        DATAWRITE(FRAB,DEST_ADDR16(7 downto 0)); -- store the lower byte of the 16-bit result
                                        CPU_STATE := CPU_STORE;                                         -- complete store operation
                                        CPU_STATE := CPU_STORE;                                         -- complete store operation
                                when CPU_MTOXAD =>      -- MEMORY TO INDEXED 8-BIT ADDRESS ***************************************************************************
                                when CPU_MTOXAD =>      -- MEMORY TO INDEXED 8-BIT ADDRESS ***************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);                            -- read operand from memory
                                        MAB <= DEST_ADDR;
                                        FRAB <= DEST_ADDR;                                                      -- update address bus with destination address
                                        CPU_STATE := CPU_MTOXAD2;
                                        CPU_STATE := CPU_MTOXAD2;
                                when CPU_MTOXAD2 =>
                                when CPU_MTOXAD2 =>
                                        MAB <= RP(3 downto 0)&(DATAREAD(MAB) + RESULT);
                                        FRAB <= RP(3 downto 0)&(DATAREAD(FRAB) + RESULT);        -- update address bus indexed result
                                        DATAWRITE(MAB,TEMP_DATA);
                                        DATAWRITE(FRAB,TEMP_DATA);                                      -- prepare to write data on destination (indexed) address
                                        CPU_STATE := CPU_STORE;
                                        CPU_STATE := CPU_STORE;                                         -- perform store (WR=1)
                                when CPU_XADTOM =>      -- INDEXED 8-BIT ADDRESS TO MEMORY ***************************************************************************
                                when CPU_XADTOM =>      -- INDEXED 8-BIT ADDRESS TO MEMORY ***************************************************************************
                                        MAB <= RP(3 downto 0)&(DATAREAD(MAB) + RESULT);
                                        FRAB <= RP(3 downto 0)&(DATAREAD(FRAB) + RESULT);
                                        CPU_STATE := CPU_TMA;
                                        CPU_STATE := CPU_TMA;
                                when CPU_XRTOM =>       -- LEA *******************************************************************************************************
                                when CPU_XRTOM =>       -- LEA *******************************************************************************************************
                                        TEMP_DATA := DATAREAD(MAB)+RESULT;
                                        TEMP_DATA := DATAREAD(FRAB)+RESULT;
                                        MAB <= DEST_ADDR;
                                        FRAB <= DEST_ADDR;
                                        DATAWRITE(MAB,TEMP_DATA);
                                        DATAWRITE(FRAB,TEMP_DATA);
                                        CPU_STATE := CPU_STORE;
                                        CPU_STATE := CPU_STORE;
                                when CPU_IMTOIRR =>     -- INDIRECT MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ***********************************************
                                when CPU_IMTOIRR =>     -- INDIRECT MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ***********************************************
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);   -- source address is read from indirect register
                                        FRAB <= RP(3 downto 0) & DATAREAD(FRAB); -- source address is read from indirect register
                                        CPU_STATE := CPU_MTOIRR;
                                        CPU_STATE := CPU_MTOIRR;
                                when CPU_MTOIRR =>      -- MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ********************************************************
                                when CPU_MTOIRR =>      -- MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ********************************************************
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
                                        TEMP_DATA := DATAREAD(FRAB);                            -- reads data from the source (FRAB) address and store it into TEMP_DATA
                                        MAB <= DEST_ADDR;                                               -- MAB points to the indirect destination register pair
                                        FRAB <= DEST_ADDR;                                                      -- FRAB points to the indirect destination register pair
                                        RESULT := x"00";
                                        RESULT := x"00";
                                        CPU_STATE := CPU_XRRD2;                                 -- proceed as X indexed register pair destination
                                        CPU_STATE := CPU_XRRD2;                                         -- proceed as X indexed register pair destination
                                when CPU_IRRS =>        -- RR PAIR AS INDIRECT SOURCE ADDRESS ************************************************************************
                                when CPU_IRRS =>        -- RR PAIR AS INDIRECT SOURCE ADDRESS ************************************************************************
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
                                        DEST_ADDR16(15 downto 8) := DATAREAD(FRAB);
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE := CPU_IRRS2;
                                        CPU_STATE := CPU_IRRS2;
                                when CPU_IRRS2 =>
                                when CPU_IRRS2 =>
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
                                        DEST_ADDR16(7 downto 0) := DATAREAD(FRAB);
                                        MAB <= DEST_ADDR16(11 downto 0);
                                        FRAB <= DEST_ADDR16(11 downto 0);
                                        if (LU_INSTRUCTION='1') then
                                        if (LU_INSTRUCTION='1') then
                                                CPU_STATE:= CPU_TMA;                            -- if it is direct addressing mode, go to TMA
                                                CPU_STATE:= CPU_TMA;                            -- if it is direct addressing mode, go to TMA
                                        else
                                        else
                                                CPU_STATE := CPU_IND2;                          -- if it is indirect addressing mode, go to IND2
                                                CPU_STATE := CPU_IND2;                          -- if it is indirect addressing mode, go to IND2
                                        end if;
                                        end if;
                                when CPU_XRRD =>
                                when CPU_XRRD =>        -- RR PAIR PLUS OFFSET AS DESTINATION ADDRESS ****************************************************************
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
                                        TEMP_DATA := DATAREAD(FRAB);                            -- reads data from the source (FRAB) address and store it into TEMP_DATA
                                        MAB <= DEST_ADDR;
                                        FRAB <= DEST_ADDR;
                                        CPU_STATE := CPU_XRRD2;
                                        CPU_STATE := CPU_XRRD2;
                                when CPU_XRRD2 =>
                                when CPU_XRRD2 =>
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
                                        DEST_ADDR16(15 downto 8) := DATAREAD(FRAB);
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE := CPU_XRRD3;
                                        CPU_STATE := CPU_XRRD3;
                                when CPU_XRRD3 =>
                                when CPU_XRRD3 =>
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
                                        DEST_ADDR16(7 downto 0) := DATAREAD(FRAB);
                                        MAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0);
                                        FRAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0);
                                        DATAWRITE(MAB,TEMP_DATA);
                                        DATAWRITE(FRAB,TEMP_DATA);
                                        CPU_STATE := CPU_STORE;
                                        CPU_STATE := CPU_STORE;
                                when CPU_XRRS =>
                                when CPU_XRRS =>        -- RR PAIR PLUS OFFSET AS SOURCE ADDRESS *********************************************************************
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
                                        DEST_ADDR16(15 downto 8) := DATAREAD(FRAB);
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE := CPU_XRRS2;
                                        CPU_STATE := CPU_XRRS2;
                                when CPU_XRRS2 =>
                                when CPU_XRRS2 =>
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
                                        DEST_ADDR16(7 downto 0) := DATAREAD(FRAB);
                                        MAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0);
                                        FRAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0);
                                        CPU_STATE := CPU_XRRS3;
                                        CPU_STATE := CPU_XRRS3;
                                when CPU_XRRS3 =>
                                when CPU_XRRS3 =>
                                        TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);
                                        MAB <= DEST_ADDR;
                                        FRAB <= DEST_ADDR;
                                        DATAWRITE(MAB,TEMP_DATA);
                                        DATAWRITE(FRAB,TEMP_DATA);
                                        CPU_STATE := CPU_STORE;
                                        CPU_STATE := CPU_STORE;
                                when CPU_INDRR =>       -- INDIRECT DESTINATION ADDRESS FOR WORD INSTRUCTIONS (DECW AND INCW) ****************************************
                                when CPU_INDRR =>       -- INDIRECT DESTINATION ADDRESS FOR WORD INSTRUCTIONS (DECW AND INCW) ****************************************
                                        MAB <= (RP(3 downto 0) & DATAREAD(MAB))+1;       -- the destination address is given by indirect address
                                        FRAB <= (RP(3 downto 0) & DATAREAD(FRAB))+1;     -- the destination address is given by indirect address
                                        CPU_STATE := CPU_OMA2;
                                        CPU_STATE := CPU_OMA2;
                                when CPU_ISMD1 =>       -- INDIRECT SOURCE ADDRESS ***********************************************************************************
                                when CPU_ISMD1 =>       -- INDIRECT SOURCE ADDRESS ***********************************************************************************
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);   -- source address is read from indirect register
                                        FRAB <= RP(3 downto 0) & DATAREAD(FRAB); -- source address is read from indirect register
                                        CPU_STATE := CPU_TMA;
                                        CPU_STATE := CPU_TMA;
                                when CPU_IND2 =>        -- READS REGISTER AND PERFORM OPERATION ON AN INDIRECT DESTINATION *******************************************
                                when CPU_IND2 =>        -- READS REGISTER AND PERFORM OPERATION ON AN INDIRECT DESTINATION *******************************************
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
                                        TEMP_DATA := DATAREAD(FRAB);                            -- reads data from the source (FRAB) address and store it into TEMP_DATA
                                        MAB <= DEST_ADDR;                                               -- place the address of the indirect register on MAB
                                        FRAB <= DEST_ADDR;                                              -- place the address of the indirect register on FRAB
                                        CPU_STATE := CPU_IND1;                                  -- proceed to the indirect
                                        CPU_STATE := CPU_IND1;                                  -- proceed to the indirect
                                when CPU_IND1 =>        -- INDIRECT DESTINATION ADDRESS ******************************************************************************
                                when CPU_IND1 =>        -- INDIRECT DESTINATION ADDRESS ******************************************************************************
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);   -- the destination address is given by indirect address
                                        FRAB <= RP(3 downto 0) & DATAREAD(FRAB); -- the destination address is given by indirect address
                                        if (LU_INSTRUCTION='0') then CPU_STATE := CPU_OMA;                                       -- proceed with one memory access
                                        if (LU_INSTRUCTION='0') then CPU_STATE := CPU_OMA;                                       -- proceed with one memory access
                                        else CPU_STATE := CPU_OMA2;                                                                                     -- proceed with one memory access (logic unit related)
                                        else CPU_STATE := CPU_OMA2;                                                                                     -- proceed with one memory access (logic unit related)
                                        end if;
                                        end if;
                                when CPU_TMA =>         -- TWO MEMORY ACCESS, READS SOURCE OPERAND FROM MEMORY *******************************************************
                                when CPU_TMA =>         -- TWO MEMORY ACCESS, READS SOURCE OPERAND FROM MEMORY *******************************************************
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
                                        TEMP_DATA := DATAREAD(FRAB);                    -- reads data from the source (FRAB) address and store it into TEMP_DATA
                                        MAB <= DEST_ADDR;                                               -- place the destination address (DEST_ADDR) on the memory address bus (MAB)
                                        FRAB <= DEST_ADDR;                                              -- place destination address (DEST_ADDR) on memory address bus (FRAB)
                                        CPU_STATE := CPU_OMA;                                   -- proceed to the last stage
                                        CPU_STATE := CPU_OMA;                                   -- proceed to the last stage
                                when CPU_OMA =>         -- ONE MEMORY ACCESS stage ***********************************************************************************
                                when CPU_OMA =>         -- ONE MEMORY ACCESS stage ***********************************************************************************
                                        -- this stage performs the TEMP_OP operation between TEMP_DATA and data read from current (MAB) address (destination)
                                        -- this stage performs TEMP_OP operation between TEMP_DATA and data read from current (FRAB) address (destination)
                                        RESULT := ALU(TEMP_OP,DATAREAD(MAB),TEMP_DATA,CPU_FLAGS.C);
                                        RESULT := ALU(TEMP_OP,DATAREAD(FRAB),TEMP_DATA,CPU_FLAGS.C);
                                        if (TEMP_OP<ALU_OR) then
                                        if (TEMP_OP<ALU_OR) then
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.H := ALU_FLAGS.H;
                                                CPU_FLAGS.H := ALU_FLAGS.H;
                                                CPU_FLAGS.D := TEMP_OP(1);
                                                CPU_FLAGS.D := TEMP_OP(1);
                                        elsif (TEMP_OP=ALU_CP or TEMP_OP=ALU_CPC) then
                                        elsif (TEMP_OP=ALU_CP or TEMP_OP=ALU_CPC) then
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                        elsif (TEMP_OP/=ALU_LD) then
                                        elsif (TEMP_OP/=ALU_LD) then
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.V := '0';
                                                CPU_FLAGS.V := '0';
                                        end if;
                                        end if;
                                        if (ALU_NOUPDATE='0') then
                                        if (ALU_NOUPDATE='0') then
                                                DATAWRITE(MAB,RESULT);
                                                DATAWRITE(FRAB,RESULT);
                                                WR <= '1';
                                                WR <= '1';
                                        end if;
                                        end if;
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                        if (WORD_DATA='1') then
                                        if (WORD_DATA='1') then
                                                CPU_STATE := CPU_LDW;
                                                CPU_STATE := CPU_LDW;
                                        end if;
                                        end if;
                                when CPU_OMA2 =>        -- ONE MEMORY ACCESS stage logic unit related ****************************************************************
                                when CPU_OMA2 =>        -- ONE MEMORY ACCESS stage logic unit related ****************************************************************
                                        -- this stage performs the TEMP_OP LU2 operation on data read from current (MAB) address
                                        -- this stage performs TEMP_OP LU2 operation on data read from current (FRAB) address
                                        RESULT := LU2(TEMP_OP,DATAREAD(MAB),CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.C);
                                        RESULT := LU2(TEMP_OP,DATAREAD(FRAB),CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.C);
                                        if (TEMP_OP=LU2_DEC or TEMP_OP=LU2_INC) then
                                        if (TEMP_OP=LU2_DEC or TEMP_OP=LU2_INC) then
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                        elsif (TEMP_OP=LU2_COM) then
                                        elsif (TEMP_OP=LU2_COM) then
                                                CPU_FLAGS.V := '0';
                                                CPU_FLAGS.V := '0';
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                        elsif (TEMP_OP=LU2_SWAP) then
                                        elsif (TEMP_OP=LU2_SWAP) then
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                        elsif (TEMP_OP=LU2_DA) then
                                        elsif (TEMP_OP=LU2_DA) then
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                        elsif (TEMP_OP=LU2_LD) then
                                        elsif (TEMP_OP=LU2_LD) then
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.Z := CPU_FLAGS.Z and ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := CPU_FLAGS.Z and ALU_FLAGS.Z;
                                        elsif (TEMP_OP/=LU2_CLR) then
                                        elsif (TEMP_OP/=LU2_CLR) then
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.C := ALU_FLAGS.C;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.V := ALU_FLAGS.V;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                                CPU_FLAGS.S := ALU_FLAGS.S;
                                        end if;
                                        end if;
                                        DATAWRITE(MAB,RESULT);
                                        DATAWRITE(FRAB,RESULT);
                                        WR <= '1';
                                        WR <= '1';
                                        if (WORD_DATA='1') then
                                        if (WORD_DATA='1') then
                                                WORD_DATA := '0';
                                                WORD_DATA := '0';
                                                if (ALU_FLAGS.C='0') then TEMP_OP := LU2_LD;
                                                if (ALU_FLAGS.C='0') then TEMP_OP := LU2_LD;
                                                end if;
                                                end if;
                                                CPU_STATE := CPU_DMAB;
                                                CPU_STATE := CPU_DMAB;
                                        else CPU_STATE := CPU_DECOD;
                                        else CPU_STATE := CPU_DECOD;
                                        end if;
                                        end if;
                                when CPU_DMAB =>        -- DECREMENT MEMORY ADDRESS BUS *****************************************************************************
                                when CPU_DMAB =>        -- DECREMENT MEMORY ADDRESS BUS ******************************************************************************
                                        MAB <= MAB - 1;
                                        FRAB <= FRAB - 1;
                                        CPU_STATE := CPU_OMA2;
                                        CPU_STATE := CPU_OMA2;
                                when CPU_LDW =>
                                when CPU_LDW =>         -- LOAD WORD INSTRUCTION *************************************************************************************
                                        if (WORD_DATA='0') then
                                        -- read higher byte from source operand
                                                TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);
                                                MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        else
 
                                                DATAWRITE(MAB,TEMP_DATA);
 
                                                WR <= '1';
 
                                        end if;
 
                                        CPU_STATE := CPU_LDW2;
                                        CPU_STATE := CPU_LDW2;
                                when CPU_LDW2 =>
                                when CPU_LDW2 =>
                                        if (WORD_DATA='0') then
                                        -- read lower byte from source operand
                                                RESULT := DATAREAD(MAB);
                                        RESULT := DATAREAD(FRAB);
                                                MAB <= DEST_ADDR;
                                        FRAB <= DEST_ADDR;
                                                WORD_DATA := '1';
                                        CPU_STATE := CPU_LDW3;
                                                CPU_STATE := CPU_LDW;
                                when CPU_LDW3 =>
                                        else
                                        -- write higher byte to destination operand
                                                MAB <= MAB + 1;
                                        DATAWRITE(FRAB,TEMP_DATA);
                                                DATAWRITE(MAB,RESULT);
                                        WR <= '1';
 
                                        CPU_STATE := CPU_LDW4;
 
                                when CPU_LDW4 =>
 
                                        -- points FRAB to lower byte of destination address
 
                                        FRAB <= FRAB + 1;
 
                                        CPU_STATE := CPU_LDW5;
 
                                when CPU_LDW5 =>
 
                                        DATAWRITE(FRAB,RESULT);
                                                CPU_STATE := CPU_STORE;
                                                CPU_STATE := CPU_STORE;
                                        end if;
 
                                when CPU_LDPTOIM =>     -- LOAD PROGRAM TO INDIRECT MEMORY **************************************************************************
                                when CPU_LDPTOIM =>     -- LOAD PROGRAM TO INDIRECT MEMORY **************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);
                                        DEST_ADDR := RP(3 downto 0) & TEMP_DATA; -- the destination address is read from the indirect address
                                        DEST_ADDR := RP(3 downto 0) & TEMP_DATA; -- the destination address is read from the indirect address
                                        if (WORD_DATA='1') then
                                        if (WORD_DATA='1') then
                                                -- it is a LDCI instruction, so we have to increment the indirect address after the operation
                                                -- it is a LDCI instruction, so we have to increment the indirect address after the operation
                                                DATAWRITE(MAB,TEMP_DATA+1);
                                                DATAWRITE(FRAB,TEMP_DATA+1);
                                                WR <= '1';
                                                WR <= '1';
                                                CPU_STATE := CPU_LDPTOIM2;
                                                CPU_STATE := CPU_LDPTOIM2;
                                        else
                                        else
                                                -- it is a LDC instruction, proceed the load instruction
                                                -- it is a LDC instruction, proceed the load instruction
                                                MAB <= ADDRESSER4(RESULT(3 downto 0));           -- the source address (program memory) is read from source register pair
                                                FRAB <= ADDRESSER4(RESULT(3 downto 0));          -- the source address (program memory) is read from source register pair
                                                CPU_STATE := CPU_LDPTOM;
                                                CPU_STATE := CPU_LDPTOM;
                                        end if;
                                        end if;
                                when CPU_LDPTOIM2 =>
                                when CPU_LDPTOIM2 =>
                                        MAB <= ADDRESSER4(RESULT(3 downto 0));           -- the source address (program memory) is read from source register pair
                                        FRAB <= ADDRESSER4(RESULT(3 downto 0));          -- the source address (program memory) is read from source register pair
                                        CPU_STATE := CPU_LDPTOM;
                                        CPU_STATE := CPU_LDPTOM;
                                when CPU_LDPTOM =>      -- LOAD PROGRAM TO MEMORY ***********************************************************************************
                                when CPU_LDPTOM =>      -- LOAD PROGRAM TO MEMORY ***********************************************************************************
                                        IAB(15 downto 8) <= DATAREAD(MAB);      -- read the high address from the first register
                                        IAB(15 downto 8) <= DATAREAD(FRAB);     -- read the high address from the first register
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE := CPU_LDPTOM2;
                                        CPU_STATE := CPU_LDPTOM2;
                                when CPU_LDPTOM2 =>
                                when CPU_LDPTOM2 =>
                                        IAB(7 downto 0) <= DATAREAD(MAB);        -- read the low address from the second register
                                        IAB(7 downto 0) <= DATAREAD(FRAB);       -- read the low address from the second register
                                        MAB <= DEST_ADDR;
                                        FRAB <= DEST_ADDR;
                                        if (LU_INSTRUCTION='0') then
                                        if (LU_INSTRUCTION='0') then
                                                CPU_STATE := CPU_LDPTOM3;               -- if it is a read from program memory
                                                CPU_STATE := CPU_LDPTOM3;               -- if it is a read from program memory
                                        else
                                        else
                                                CPU_STATE := CPU_LDMTOP;                -- if it is a write onto program memory
                                                CPU_STATE := CPU_LDMTOP;                -- if it is a write onto program memory
                                        end if;
                                        end if;
                                when CPU_LDPTOM3 =>     -- READ PROGRAM MEMORY AND STORE INTO RAM *******************************************************************
                                when CPU_LDPTOM3 =>     -- READ PROGRAM MEMORY AND STORE INTO RAM *******************************************************************
                                        DATAWRITE(MAB,IDB);
                                        DATAWRITE(FRAB,IDB);
                                        WR <= '1';
                                        WR <= '1';
                                        CAN_FETCH := '1';       -- re-enable fetching
                                        CAN_FETCH := '1';       -- re-enable fetching
                                        FETCH_ADDR := PC;
                                        FETCH_ADDR := PC;
                                        IAB <= PC;
                                        IAB <= PC;
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                        if (WORD_DATA='1') then
                                        if (WORD_DATA='1') then
                                                CPU_STATE := CPU_LDPTOM4;
                                                CPU_STATE := CPU_LDPTOM4;
                                        end if;
                                        end if;
                                when CPU_LDPTOM4 =>
                                when CPU_LDPTOM4 =>
                                        DEST_ADDR := ADDRESSER4(RESULT(3 downto 0));
                                        DEST_ADDR := ADDRESSER4(RESULT(3 downto 0));
                                        MAB <= DEST_ADDR+1;
                                        FRAB <= DEST_ADDR+1;
                                        TEMP_OP := LU2_INC;
                                        TEMP_OP := LU2_INC;
                                        CPU_STATE := CPU_OMA2;
                                        CPU_STATE := CPU_OMA2;
                                when CPU_LDMTOP =>      -- READ RAM AND STORE ONTO PROGRAM MEMORY *******************************************************************
                                when CPU_LDMTOP =>      -- READ RAM AND STORE ONTO PROGRAM MEMORY *******************************************************************
                                        PWDB <= DATAREAD(MAB);  -- PWDB receive the content of RAM
                                        IWDB <= DATAREAD(FRAB); -- IWDB receive the content of RAM
                                        PGM_WR <= '1';                  -- enable program memory write signal
                                        PGM_WR <= '1';                  -- enable program memory write signal
                                        CPU_STATE := CPU_LDMTOP2;
                                        CPU_STATE := CPU_LDMTOP2;
                                when CPU_LDMTOP2 =>
                                when CPU_LDMTOP2 =>
                                        CAN_FETCH := '1';               -- re-enable instruction fetching
                                        CAN_FETCH := '1';               -- re-enable instruction fetching
                                        FETCH_ADDR := PC;
                                        FETCH_ADDR := PC;
                                        IAB <= PC;
                                        IAB <= PC;
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                        if (WORD_DATA='1') then
                                        if (WORD_DATA='1') then
                                                CPU_STATE := CPU_LDPTOM4;
                                                CPU_STATE := CPU_LDPTOM4;
                                        end if;
                                        end if;
                                when CPU_BIT =>
                                when CPU_BIT =>         -- BIT INSTRUCTION *******************************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);
                                        TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0)))):=TEMP_OP(3);
                                        TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0)))):=TEMP_OP(3);
                                        DATAWRITE(MAB,TEMP_DATA);
                                        DATAWRITE(FRAB,TEMP_DATA);
                                        WR <= '1';
                                        WR <= '1';
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                when CPU_IBTJ =>
                                when CPU_IBTJ =>        -- INDIRECT BIT TEST JUMP INSTRUCTION ************************************************************************
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);
                                        FRAB <= RP(3 downto 0) & DATAREAD(FRAB);
                                        CPU_STATE := CPU_BTJ;
                                        CPU_STATE := CPU_BTJ;
                                when CPU_BTJ =>
                                when CPU_BTJ =>         -- BIT TEST JUMP INSTRUCTION *********************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);
                                        if (TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0))))=TEMP_OP(3)) then
                                        if (TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0))))=TEMP_OP(3)) then
                                                PC := ADDER16(PC,RESULT);
                                                PC := ADDER16(PC,RESULT);
                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                IQUEUE.FETCH_STATE := F_ADDR;
                                        end if;
                                        end if;
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                when CPU_DJNZ =>
                                when CPU_DJNZ =>        -- DECREMENT AND JUMP IF NOT ZERO INSTRUCTION ****************************************************************
                                        RESULT := LU2(LU2_DEC,DATAREAD(MAB),'0','0','0');
                                        RESULT := LU2(LU2_DEC,DATAREAD(FRAB),'0','0','0');
                                        if (ALU_FLAGS.Z='0') then        -- result is not zero, then jump relative
                                        if (ALU_FLAGS.Z='0') then        -- result is not zero, then jump relative
                                                PC := DEST_ADDR16;
                                                PC := DEST_ADDR16;
                                                IQUEUE.FETCH_STATE := F_ADDR;
                                                IQUEUE.FETCH_STATE := F_ADDR;
                                        end if;
                                        end if;
                                        DATAWRITE(MAB,RESULT);
                                        DATAWRITE(FRAB,RESULT);
                                        WR <= '1';
                                        WR <= '1';
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                when CPU_INDJUMP =>
                                when CPU_INDJUMP =>     -- INDIRECT JUMP INSTRUCTION *********************************************************************************
                                        PC(15 downto 8) := DATAREAD(MAB);
                                        PC(15 downto 8) := DATAREAD(FRAB);
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE:= CPU_INDJUMP2;
                                        CPU_STATE:= CPU_INDJUMP2;
                                when CPU_INDJUMP2 =>
                                when CPU_INDJUMP2 =>
                                        PC(7 downto 0) := DATAREAD(MAB);
                                        PC(7 downto 0) := DATAREAD(FRAB);
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                when CPU_TRAP =>
                                when CPU_TRAP =>        -- TRAP INSTRUCTION ******************************************************************************************
                                        PC(15 downto 8) := DATAREAD(MAB);
                                        PC(15 downto 8) := DATAREAD(FRAB);
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE:= CPU_TRAP2;
                                        CPU_STATE:= CPU_TRAP2;
                                when CPU_TRAP2 =>
                                when CPU_TRAP2 =>
                                        PC(7 downto 0) := DATAREAD(MAB);
                                        PC(7 downto 0) := DATAREAD(FRAB);
                                        SP := SP - 1;
                                        SP := SP - 1;
                                        MAB <= SP;
                                        FRAB <= SP;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        LU_INSTRUCTION := '1';
                                        LU_INSTRUCTION := '1';
                                        CPU_STATE := CPU_STACK;
                                        CPU_STATE := CPU_STACK;
                                when CPU_INDSTACK =>
                                when CPU_INDSTACK =>    -- INDIRECT CALL INSTRUCTION *****************************************************************************
                                        PC(15 downto 8) := DATAREAD(MAB);
                                        PC(15 downto 8) := DATAREAD(FRAB);
                                        MAB <= MAB + 1;
                                        FRAB <= FRAB + 1;
                                        CPU_STATE:= CPU_INDSTACK2;
                                        CPU_STATE:= CPU_INDSTACK2;
                                when CPU_INDSTACK2 =>
                                when CPU_INDSTACK2 =>
                                        PC(7 downto 0) := DATAREAD(MAB);
                                        PC(7 downto 0) := DATAREAD(FRAB);
                                        SP := SP - 1;
                                        SP := SP - 1;
                                        MAB <= SP;
                                        FRAB <= SP;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        CPU_STATE := CPU_STACK;
                                        CPU_STATE := CPU_STACK;
                                when CPU_VECTOR =>
                                when CPU_VECTOR =>              -- LOAD PC WITH ADDRESS STORED IN PROGRAM MEMORY *********************************************************
                                        PC(15 downto 8) := IDB;
                                        PC(15 downto 8) := IDB;         -- read high byte of destination address
                                        IAB <= IAB + 1;
                                        IAB <= IAB + 1;
                                        CPU_STATE := CPU_VECTOR2;
                                        CPU_STATE := CPU_VECTOR2;
                                when CPU_VECTOR2 =>
                                when CPU_VECTOR2 =>
                                        PC(7 downto 0) := IDB;
                                        PC(7 downto 0) := IDB;           -- read low byte of destination address
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IQUEUE.FETCH_STATE := F_ADDR;   -- reset queue FSM
                                        CAN_FETCH := '1';
                                        CAN_FETCH := '1';                               -- restart fetching
                                        if (LU_INSTRUCTION='1') then CPU_STATE := CPU_STACK;
                                        if (INT_FLAG='1') then CPU_STATE := CPU_STACK;
                                        else CPU_STATE := CPU_DECOD;
                                        else CPU_STATE := CPU_DECOD;
                                        end if;
                                        end if;
                                when CPU_STACK =>       -- PUSH PC 7:0 INTO THE STACK *******************************************************************************
                                when CPU_STACK =>       -- PUSH PC 7:0 INTO THE STACK ********************************************************************************
                                        DATAWRITE(MAB,DEST_ADDR16(7 downto 0));
                                        DATAWRITE(FRAB,DEST_ADDR16(7 downto 0));
                                        WR <= '1';
                                        WR <= '1';
                                        CPU_STATE := CPU_STACK1;
                                        CPU_STATE := CPU_STACK1;
                                when CPU_STACK1 =>
                                when CPU_STACK1 =>
                                        SP := SP - 1;
                                        SP := SP - 1;
                                        MAB <= SP;
                                        FRAB <= SP;
                                        CPU_STATE := CPU_STACK2;
                                        CPU_STATE := CPU_STACK2;
                                when CPU_STACK2 =>
                                when CPU_STACK2 =>      -- PUSH PC 15:8 INTO THE STACK *******************************************************************************
                                        DATAWRITE(MAB,DEST_ADDR16(15 downto 8));
                                        DATAWRITE(FRAB,DEST_ADDR16(15 downto 8));
                                        WR <= '1';
                                        WR <= '1';
                                        if (LU_INSTRUCTION='1') then
                                        if (INT_FLAG='1') then
                                                CPU_STATE := CPU_STACK3;
                                                CPU_STATE := CPU_STACK3;
                                        else
                                        else
                                                CPU_STATE := CPU_DECOD;
                                                CPU_STATE := CPU_DECOD;
                                        end if;
                                        end if;
                                when CPU_STACK3 =>      -- PUSH FLAGS INTO THE STACK *******************************************************************************
                                when CPU_STACK3 =>      -- PUSH FLAGS INTO THE STACK *********************************************************************************
                                        SP := SP - 1;
                                        SP := SP - 1;
                                        MAB <= SP;
                                        FRAB <= SP;
                                        DATAWRITE(MAB,CPU_FLAGS.C&CPU_FLAGS.Z&CPU_FLAGS.S&CPU_FLAGS.V&CPU_FLAGS.D&CPU_FLAGS.H&CPU_FLAGS.F2&CPU_FLAGS.F1);
                                        DATAWRITE(FRAB,CPU_FLAGS.C&CPU_FLAGS.Z&CPU_FLAGS.S&CPU_FLAGS.V&CPU_FLAGS.D&CPU_FLAGS.H&CPU_FLAGS.F2&CPU_FLAGS.F1);
                                        WR <= '1';
 
                                        IRQE := '0';
                                        IRQE := '0';
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_STORE;
                                when CPU_UNSTACK3 =>
                                when CPU_UNSTACK3 =>    -- POP FLAGS FROM STACK **********************************************************************************
                                        TEMP_DATA := DATAREAD(MAB);
                                        TEMP_DATA := DATAREAD(FRAB);
                                        CPU_FLAGS.C := TEMP_DATA(7);
                                        CPU_FLAGS.C := TEMP_DATA(7);
                                        CPU_FLAGS.Z := TEMP_DATA(6);
                                        CPU_FLAGS.Z := TEMP_DATA(6);
                                        CPU_FLAGS.S := TEMP_DATA(5);
                                        CPU_FLAGS.S := TEMP_DATA(5);
                                        CPU_FLAGS.V := TEMP_DATA(4);
                                        CPU_FLAGS.V := TEMP_DATA(4);
                                        CPU_FLAGS.D := TEMP_DATA(3);
                                        CPU_FLAGS.D := TEMP_DATA(3);
                                        CPU_FLAGS.H := TEMP_DATA(2);
                                        CPU_FLAGS.H := TEMP_DATA(2);
                                        CPU_FLAGS.F2 := TEMP_DATA(1);
                                        CPU_FLAGS.F2 := TEMP_DATA(1);
                                        CPU_FLAGS.F1 := TEMP_DATA(0);
                                        CPU_FLAGS.F1 := TEMP_DATA(0);
                                        SP := SP + 1;
                                        SP := SP + 1;
                                        MAB <= SP;
                                        FRAB <= SP;
                                        CPU_STATE := CPU_UNSTACK;
 
                                when CPU_UNSTACK =>
 
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
 
                                        SP := SP + 1;
 
                                        MAB <= SP;
 
                                        CPU_STATE := CPU_UNSTACK2;
                                        CPU_STATE := CPU_UNSTACK2;
                                when CPU_UNSTACK2 =>
                                when CPU_UNSTACK2 =>    -- POP PC(15:8) FROM STACK *******************************************************************************
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
                                        DEST_ADDR16(15 downto 8) := DATAREAD(FRAB);
 
                                        SP := SP + 1;
 
                                        FRAB <= SP;
 
                                        CPU_STATE := CPU_UNSTACK;
 
                                when CPU_UNSTACK =>             -- POP PC(7:0) FROM STACK ********************************************************************************
 
                                        DEST_ADDR16(7 downto 0) := DATAREAD(FRAB);
                                        SP := SP + 1;
                                        SP := SP + 1;
                                        PC := DEST_ADDR16;
                                        PC := DEST_ADDR16;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                when CPU_STORE =>
                                when CPU_STORE =>       -- stores data into memory
                                        WR <= '1';
                                        WR <= '1';              -- enable write signal (it is automatically disabled on CPU_DECOD state)
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD; -- proceed to main decoding state
                                when CPU_HALTED =>      -- HALT mode, wait for an interrupt or reset
 
                                when CPU_ILLEGAL =>     -- An illegal opcode was fetched 
                                when CPU_ILLEGAL =>     -- An illegal opcode was fetched 
                                when CPU_RESET =>
                                when CPU_RESET =>               -- SOFTWARE RESET (TRIGGERED BY OCD RESET BIT) ***********************************************************
                                        IAB <= x"0002";
                                        IAB <= x"0002";
                                        MAB <= x"000";
                                        FRAB <= x"000";
                                        PWDB <= x"00";
                                        IWDB <= x"00";
                                        SP := x"000";
                                        SP := x"000";
                                        RP := x"00";
                                        RP := x"00";
                                        WR <= '0';
                                        WR <= '0';
                                        PGM_WR <= '0';
                                        PGM_WR <= '0';
                                        STOP <= '0';
                                        STOP <= '0';
                                        CAN_FETCH := '1';
                                        CAN_FETCH := '1';
                                        FETCH_ADDR := x"0000";
                                        FETCH_ADDR := x"0000";
                                        RXSYNC1 <= '1';
                                        RXSYNC1 <= '1';
                                        RXSYNC2 <= '1';
                                        RXSYNC2 <= '1';
                                        DBG_UART.LAST_SMP := '1';
                                        DBG_UART.LAST_SMP := '1';
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IQUEUE.FETCH_STATE := F_ADDR;
                                        IRQE := '0';
                                        IRQE := '0';
                                        IRQ0 := x"00";
                                        IRQ0 := x"00";
                                        OLD_IRQ0 := x"00";
                                        OLD_IRQ0 := x"00";
                                        IRQ0ENH := x"00";
                                        IRQ0ENH := x"00";
                                        IRQ0ENL := x"00";
                                        IRQ0ENL := x"00";
                                        OCDCR.RST := '0';
                                        OCDCR.RST := '0';
                                        ATM_COUNTER := 0;
                                        ATM_COUNTER := 0;
                                        CPU_STATE := CPU_VECTOR;
                                        CPU_STATE := CPU_VECTOR;
                                when others =>
                                when others =>
                                        CPU_STATE := CPU_DECOD;
                                        CPU_STATE := CPU_DECOD;
                                end case;
                        end case;
                                -- end of the main decoder
                                -- end of the main decoder
                        end if; -- CKDIVIDER
 
                end if;
                end if;
        end process;
        end process;
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.