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

Subversion Repositories fpz8

[/] [fpz8_cpu_v1.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 fabiop
-- FPz8 mk1
2
-- Zilog Z8 Encore! 100% compatible softcore
3
-- Author:      Fábio Pereira (fabio.jve@gmail.com)
4
-- Version:     0.9             Nov, 11th, 2016
5
 
6
-- FPz8 is a softcore 100% object-code compatible with the Z8 encore microcontroller line. Current implementation includes 
7
-- 2kb of file registers (RAM), 16kb of program memory (using FPGA RAM), 8 vectored interrupts with programmable priority, 
8
-- full-featured onchip debugger 100% compatible with Zilog's OCD and ZDS-II IDE.
9
-- It was designed to work as a SoC and everything (except the USB chip) fits inside a single FPGA (I have used an Altera 
10
-- Cyclone IV EP4CE6 device). The debugger connection makes use of a serial-to-USB chip (it is part of the low-cost FPGA 
11
-- board used on the project).
12
-- In a near future I plan to add some more features to the device (such as a timer and maybe other peripherals).
13
-- The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using those technologies). I also 
14
-- believe the FPz8 can be a very interesting tool for learning/teaching about VHDL, computing and microprocessors/microcontrollers 
15
-- programming.
16
 
17
-- 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).
18
-- If you want to contribute to the project, contact me and share your thoughts.
19
-- Don't forget to credit the author!
20
 
21
-- Note: currently there are only a few SFRs physically implemented, they are:
22
-- 0xFC0 - IRQ0
23
-- 0xFC1 - IRQ0ENH
24
-- 0xFC2 - IRQ0ENL
25
-- 0xFCF - IRQCTL
26
-- 0xFD2 - PAIN
27
-- 0xFD3 - PAOUT
28
-- 0xFF8 - FCTL
29
-- 0xFFC - FLAGS
30
-- 0xFFD - RP
31
-- 0xFFE - SPH
32
-- 0xFFF - SPL
33
-- Also notice INT7 is not physically present as it is planned to be used with the coming timer peripheral
34
 
35
-- What else is missing from the original architecture?
36
-- A: no watchdog (WDT instruction runs as a NOP), no LDE and LDEI instructions (data memory related), no option bytes
37
 
38
-- FPz8 was tested on a EP4CE6 mini board (50MHz clock)
39
-- http://www.ebay.com/itm/EP4CE6-Mini-Board-USB-Blaster-Altera-Cyclone-IV-FPGA-CPLD-Nano-Size-
40
 
41
-- This work is licensed under the Creative Commons Attribution 4.0 International License.
42
-- To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.
43
 
44
library ieee ;
45
use ieee.std_logic_1164.all ;
46
use ieee.numeric_std.all;
47
use ieee.std_logic_unsigned.all ;
48
 
49
entity fpz8_cpu_v1 IS
50
        port
51
        (
52
                IAB                     : buffer std_logic_vector(15 downto 0);  -- instruction address bus (16 bits)
53
                IDB                     : in std_logic_vector(7 downto 0);               -- instruction data bus (8 bits)
54
                PWDB            : out std_logic_vector(7 downto 0);              -- program write data bus (8 bits)
55
                MAB                     : buffer std_logic_vector(11 downto 0);  -- memory address bus (12 bits)
56
                MIDB            : in std_logic_vector(7 downto 0);               -- memory input data bus (8 bits)
57
                MODB            : out std_logic_vector(7 downto 0);              -- memory output data bus (8 bits)
58
                RIDB            : in std_logic_vector(7 downto 0);               -- register input data bus (8 bits)
59
                RODB            : out std_logic_vector(7 downto 0);              -- register output data bus (8 bits)            
60
                PGM_WR          : out std_logic;                                                -- program memory write enable
61
                WR                      : buffer std_logic;                                             -- write enable
62
                REG_SEL         : buffer std_logic;                                             -- SFR select (addresses F00 to FFF, except internal registers)
63
                MEM_SEL         : buffer std_logic;                                             -- memory select
64
                INT0            : in std_logic;                                                 -- interrupt 0 input (vector 0x0016)
65
                INT1            : in std_logic;                                                 -- interrupt 1 input (vector 0x0014)
66
                INT2            : in std_logic;                                                 -- interrupt 2 input (vector 0x0012)
67
                INT3            : in std_logic;                                                 -- interrupt 3 input (vector 0x0010)
68
                INT4            : in std_logic;                                                 -- interrupt 4 input (vector 0x000E)
69
                INT5            : in std_logic;                                                 -- interrupt 5 input (vector 0x000C)
70
                INT6            : in std_logic;                                                 -- interrupt 6 input (vector 0x000A)
71
                DBG_RX          : in std_logic;                                                 -- debugger receive input
72
                DBG_TX          : buffer std_logic;                                             -- debugger transmit output
73
                PAOUT           : out std_logic_vector(7 downto 0);              -- port A output data
74
                PAIN            : in std_logic_vector(7 downto 0);               -- port A input data
75
                CLK                     : in std_logic;                                                 -- main clock
76
                CLK_OUT         : out std_logic;                                                -- main gated-clock output
77
                CLK_OUTN        : out std_logic;                                                -- main inverted-gated-clock output
78
                STOP            : buffer std_logic;                                             -- stop output   
79
                RESET           : in std_logic                                                  -- CPU reset                    
80
        );
81
end fpz8_cpu_v1;
82
 
83
architecture cpu of fpz8_cpu_v1 is
84
 
85
type Tinstqueue is array (0 TO 7) of std_logic_vector(7 downto 0);
86
type Tflags is record
87
        C,Z,S,V,D,H,F2,F1                       : std_logic;
88
end record;
89
shared variable CPU_FLAGS, ALU_FLAGS            : Tflags;
90
shared variable ALU_NOUPDATE                            : std_logic;
91
shared variable INT7                                            : std_logic;
92
shared variable IRQE                                            : std_logic;
93
shared variable HALT                                            : std_logic;
94
shared variable IRQ0                                            : std_logic_vector(7 downto 0);          -- interrupts 0-7 flags
95
shared variable IRQ0ENH,IRQ0ENL                         : std_logic_vector(7 downto 0);          -- interrupts 0-7 enable high and low
96
shared variable SP                                                      : std_logic_vector(11 downto 0); -- stack pointer
97
shared variable RP                                                      : std_logic_vector(7 downto 0);          -- register pointer
98
shared variable FCTL                                            : std_logic_vector(7 downto 0);          -- flash control
99
shared variable PAOUT_BUFFER                            : std_logic_vector(7 downto 0);
100
signal                  RXSYNC1, RXSYNC2                        : std_logic;
101
ATTRIBUTE preserve                                                      : boolean;
102
ATTRIBUTE preserve OF RXSYNC1                           : signal IS true;
103
ATTRIBUTE preserve OF RXSYNC2                           : signal IS true;
104
 
105
constant ALU_ADD        : std_logic_vector(3 downto 0):=x"0";     -- CZSVH D=0
106
constant ALU_ADC        : std_logic_vector(3 downto 0):=x"1";    -- CZSVH D=0
107
constant ALU_SUB        : std_logic_vector(3 downto 0):=x"2";    -- CZSVH D=1
108
constant ALU_SBC        : std_logic_vector(3 downto 0):=x"3";    -- CZSVH D=1
109
constant ALU_OR         : std_logic_vector(3 downto 0):=x"4";    -- ZS V=0
110
constant ALU_AND        : std_logic_vector(3 downto 0):=x"5";    -- ZS V=0
111
constant ALU_TCM        : std_logic_vector(3 downto 0):=x"6";    -- ZS V=0
112
constant ALU_TM         : std_logic_vector(3 downto 0):=x"7";    -- ZS V=0
113
constant ALU_CPC        : std_logic_vector(3 downto 0):=x"9";    -- CZSV
114
constant ALU_CP         : std_logic_vector(3 downto 0):=x"A";    -- CZSV
115
constant ALU_XOR        : std_logic_vector(3 downto 0):=x"B";    -- ZS V=0
116
constant ALU_BSWAP  : std_logic_vector(3 downto 0):=x"D";        -- ZS V=0
117
constant ALU_LD         : std_logic_vector(3 downto 0):=x"E";    -- Load does not change any flag
118
 
119
constant LU2_RLC        : std_logic_vector(3 downto 0):=x"1";    -- CZSV
120
constant LU2_INC        : std_logic_vector(3 downto 0):=x"2";    -- ZSV
121
constant LU2_DEC        : std_logic_vector(3 downto 0):=x"3";    -- ZSV
122
constant LU2_DA         : std_logic_vector(3 downto 0):=x"4";    -- CZS
123
constant LU2_COM        : std_logic_vector(3 downto 0):=x"6";    -- ZS V=0
124
constant LU2_LD         : std_logic_vector(3 downto 0):=x"7";    -- Load does not change any flag
125
constant LU2_RL         : std_logic_vector(3 downto 0):=x"9";    -- CZSV
126
constant LU2_SRL        : std_logic_vector(3 downto 0):=x"A";    -- CZSV
127
constant LU2_CLR        : std_logic_vector(3 downto 0):=x"B";    -- Clear does not change any flag
128
constant LU2_RRC        : std_logic_vector(3 downto 0):=x"C";    -- CZSV
129
constant LU2_SRA        : std_logic_vector(3 downto 0):=x"D";    -- CZSV
130
constant LU2_RR         : std_logic_vector(3 downto 0):=x"E";    -- CZSV
131
constant LU2_SWAP       : std_logic_vector(3 downto 0):=x"F";    -- ZS
132
 
133
-- Debug commands
134
constant DBGCMD_READ_REV                : std_logic_vector(7 downto 0):=x"00";
135
constant DBGCMD_READ_STATUS             : std_logic_vector(7 downto 0):=x"02";
136
constant DBGCMD_READ_RUNCOUNTER : std_logic_vector(7 downto 0):=x"03";
137
constant DBGCMD_WRITE_CTRL              : std_logic_vector(7 downto 0):=x"04";
138
constant DBGCMD_READ_CTRL               : std_logic_vector(7 downto 0):=x"05";
139
constant DBGCMD_WRITE_PC                : std_logic_vector(7 downto 0):=x"06";
140
constant DBGCMD_READ_PC                 : std_logic_vector(7 downto 0):=x"07";
141
constant DBGCMD_WRITE_REG               : std_logic_vector(7 downto 0):=x"08";
142
constant DBGCMD_READ_REG                : std_logic_vector(7 downto 0):=x"09";
143
constant DBGCMD_WRITE_PROGRAM   : std_logic_vector(7 downto 0):=x"0A";
144
constant DBGCMD_READ_PROGRAM    : std_logic_vector(7 downto 0):=x"0B";
145
constant DBGCMD_READ_CRC                : std_logic_vector(7 downto 0):=x"0E";
146
constant DBGCMD_STEP                    : std_logic_vector(7 downto 0):=x"10";
147
constant DBGCMD_STUFF                   : std_logic_vector(7 downto 0):=x"11";
148
constant DBGCMD_EXEC                    : std_logic_vector(7 downto 0):=x"12";
149
 
150
-- DATAWRITE controls where data to be written actually goes (an internal register, an external register (through register data bus) or RAM)
151
procedure DATAWRITE
152
        (       ADDRESS : in std_logic_vector(11 downto 0);
153
                DATA    : in std_logic_vector(7 downto 0)) is
154
begin
155
        if (ADDRESS>=x"F00") then               ----------------------------------------------- it is a SFR address
156
                if (ADDRESS=x"FFC") then        ---------------------------------------------------- FLAGS register
157
                        CPU_FLAGS.C := DATA(7);
158
                        CPU_FLAGS.Z := DATA(6);
159
                        CPU_FLAGS.S := DATA(5);
160
                        CPU_FLAGS.V := DATA(4);
161
                        CPU_FLAGS.D := DATA(3);
162
                        CPU_FLAGS.H := DATA(2);
163
                        CPU_FLAGS.F2 := DATA(1);
164
                        CPU_FLAGS.F1 := DATA(0);
165
                elsif (ADDRESS=x"FFD") then RP := DATA; ------------------------------------------- RP register
166
                elsif (ADDRESS=x"FFE") then SP(11 downto 8) := DATA(3 downto 0); -------------- SPH register
167
                elsif (ADDRESS=x"FFF") then SP(7 downto 0) := DATA;      ------------------------------ SPL register
168
                elsif (ADDRESS=x"FF8") then     ----------------------------------------------------- FCTL register
169
                        if (DATA=x"73") then FCTL:=x"01";
170
                        elsif (DATA=x"8C" and FCTL=x"01") then FCTL:=x"03";
171
                        elsif (DATA=x"95") then FCTL:=x"04";
172
                        else FCTL:=x"00";
173
                        end if;
174
                elsif (ADDRESS=x"FC0") then     IRQ0 := DATA; --------------------------------------- IRQ0 register
175
                elsif (ADDRESS=x"FC1") then IRQ0ENH := DATA;    ------------------------------ IRQ0ENH register
176
                elsif (ADDRESS=x"FC2") then IRQ0ENL := DATA;    ------------------------------ IRQ0ENL register
177
                elsif (ADDRESS=x"FCF") then     IRQE := DATA(7);        ------------------------------- IRQCTL register
178
                elsif (ADDRESS=x"FD3") then ---------------------------------------------------- PAOUT register
179
                        PAOUT <= DATA;
180
                        PAOUT_BUFFER := DATA;
181
                else
182
                        REG_SEL <= '1';
183
                        RODB <= DATA;
184
                end if;
185
        else
186
                MEM_SEL <= '1';
187
                MODB <= DATA;
188
        end if;
189
end datawrite;
190
 
191
-- DATAREAD controls where the data to be read actually comes from (an internal register, an external register (through register data bus) or RAM)
192
impure function DATAREAD
193
        (ADDRESS        : in std_logic_vector(11 downto 0))
194
        return std_logic_vector is
195
begin
196
        if (ADDRESS>=x"F00") then       -------------------------------- it is a SFR address
197
                if (ADDRESS=x"FFC") then        --------------------------------- FLAGS register
198
                        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);
199
                elsif (ADDRESS=x"FFD") then return RP;  ------------------------ RP register
200
                elsif (ADDRESS=x"FFE") then     ----------------------------------- SPH register
201
                        return "0000" & SP(11 downto 8);
202
                elsif (ADDRESS=x"FFF") then return SP(7 downto 0);       ----------- SPL register
203
                elsif (ADDRESS=x"FF8") then return FCTL;        ------------------ FCTL register
204
                elsif (ADDRESS=x"FC0") then     return IRQ0;    ------------------ IRQ0 register
205
                elsif (ADDRESS=x"FC1") then return IRQ0ENH;     --------------- IRQ0ENH register
206
                elsif (ADDRESS=x"FC2") then return IRQ0ENL;     --------------- IRQ0ENL register
207
                elsif (ADDRESS=x"FCF") then return IRQE&"0000000";      -------- IRQCTL register
208
                elsif (ADDRESS=x"FD2") then return PAIN;        ------------------ PAIN register
209
                elsif (ADDRESS=x"FD3") then return PAOUT_BUFFER;        --------- PAOUT register
210
                else
211
                        REG_SEL <= '1';
212
                        return RIDB;
213
                end if;
214
        else
215
                MEM_SEL <= '1';
216
                return MIDB;
217
        end if;
218
end DATAREAD;
219
 
220
-- CONDITIONCODE returns the result of a logical condition (for conditional jumps)
221
function CONDITIONCODE
222
        (       CONDITION       : in std_logic_vector(3 downto 0)) return STD_LOGIC is
223
begin
224
        case CONDITION is
225
                when x"0" =>
226
                        return '0';
227
                when x"1" =>
228
                        return ALU_FLAGS.S xor ALU_FLAGS.V;
229
                when x"2" =>
230
                        return ALU_FLAGS.Z or (ALU_FLAGS.S xor ALU_FLAGS.V);
231
                when x"3" =>
232
                        return ALU_FLAGS.C or ALU_FLAGS.Z;
233
                when x"4" =>
234
                        return ALU_FLAGS.V;
235
                when x"5" =>
236
                        return ALU_FLAGS.S;
237
                when x"6" =>
238
                        return ALU_FLAGS.Z;
239
                when x"7" =>
240
                        return ALU_FLAGS.C;
241
                when x"8" =>
242
                        return '1';
243
                when x"9" =>
244
                        return NOT (ALU_FLAGS.S xor ALU_FLAGS.V);
245
                when x"A" =>
246
                        return NOT (ALU_FLAGS.Z or (ALU_FLAGS.S xor ALU_FLAGS.V));
247
                when x"B" =>
248
                        return (NOT ALU_FLAGS.C) AND (NOT ALU_FLAGS.Z);
249
                when x"C" =>
250
                        return NOT ALU_FLAGS.V;
251
                when x"D" =>
252
                        return NOT ALU_FLAGS.S;
253
                when x"E" =>
254
                        return NOT ALU_FLAGS.Z;
255
                when others =>
256
                        return NOT ALU_FLAGS.C;
257
        end case;
258
end CONDITIONCODE;
259
 
260
-- ADDRESSER12 generates a 12-bit address (it decides when to use escaped addressing mode)
261
function ADDRESSER12
262
        (       ADDR    : in std_logic_vector(11 downto 0)) return std_logic_vector is
263
begin
264
        if (ADDR(11 downto 4)=x"EE") then               -- escaped addressing mode (work register)
265
                return RP(3 downto 0) & RP(7 downto 4) & ADDR(3 downto 0);
266
        elsif (ADDR(11 downto 8)=x"E") then             -- escaped addressing mode (register)
267
                return RP(3 downto 0) & ADDR(7 downto 0);
268
        else return ADDR;                                               -- full address
269
        end if;
270
end ADDRESSER12;
271
 
272
-- ADDRESSER8 generates a 12-bit address from an 8-bit address (it decides when to use escaped addressing mode)
273
function ADDRESSER8
274
        (       ADDR    : in std_logic_vector(7 downto 0)) return std_logic_vector is
275
begin
276
        if (ADDR(7 downto 4)=x"E") then         -- escaped addressing mode (register)
277
                return RP(3 downto 0) & RP(7 downto 4) & ADDR(3 downto 0);
278
        else return RP(3 downto 0) & ADDR(7 downto 0);    -- full address
279
        end if;
280
end ADDRESSER8;
281
 
282
-- ADDRESSER12 generates a 12-bit address from a 4-bit address (using RP register)
283
function ADDRESSER4
284
        (       ADDR    : in std_logic_vector(3 downto 0)) return std_logic_vector is
285
begin
286
        return RP(3 downto 0) & RP(7 downto 4) & ADDR;
287
end ADDRESSER4;
288
 
289
-- 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
290
function ALU
291
        (       ALU_OP  : in std_logic_vector(3 downto 0);
292
                OPER1   : in std_logic_vector(7 downto 0);
293
                OPER2   : in std_logic_vector(7 downto 0);
294
                CIN             : in STD_LOGIC) return std_logic_vector is
295
variable RESULT : std_logic_vector(7 downto 0);
296
variable HALF1,HALF2    : std_logic_vector(4 downto 0);
297
begin
298
        ALU_NOUPDATE := '0';
299
        case ALU_OP is
300
                when ALU_ADD =>         -- ADD operation **************************************************
301
                        HALF1 := ('0'&OPER1(3 downto 0))+('0'&OPER2(3 downto 0));
302
                        ALU_FLAGS.H := HALF1(4);
303
                        HALF2 := ('0'&OPER1(7 downto 4))+('0'&OPER2(7 downto 4))+HALF1(4);
304
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
305
                        ALU_FLAGS.C := HALF2(4);
306
                        if (OPER1(7)=OPER2(7)) then
307
                                if (OPER1(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
308
                                end if;
309
                        else ALU_FLAGS.V:='0';
310
                        end if;
311
                when ALU_ADC =>         -- ADC operation **************************************************
312
                        HALF1 := ('0'&OPER1(3 downto 0))+('0'&OPER2(3 downto 0)+(CIN));
313
                        ALU_FLAGS.H := HALF1(4);
314
                        HALF2 := ('0'&OPER1(7 downto 4))+('0'&OPER2(7 downto 4))+HALF1(4);
315
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
316
                        ALU_FLAGS.C := HALF2(4);
317
                        if (OPER1(7)=OPER2(7)) then
318
                                if (OPER1(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
319
                                end if;
320
                        else ALU_FLAGS.V:='0';
321
                        end if;
322
                when ALU_SUB =>         -- SUB operation **************************************************
323
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)));
324
                        ALU_FLAGS.H := (HALF1(4));
325
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
326
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
327
                        ALU_FLAGS.C := (HALF2(4));
328
                        if (OPER1(7)/=OPER2(7)) then
329
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
330
                                end if;
331
                        else ALU_FLAGS.V:='0';
332
                        end if;
333
                when ALU_SBC =>         -- SBC operation **************************************************
334
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)))-CIN;
335
                        ALU_FLAGS.H := (HALF1(4));
336
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
337
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
338
                        ALU_FLAGS.C := (HALF2(4));
339
                        if (OPER1(7)/=OPER2(7)) then
340
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
341
                                end if;
342
                        else ALU_FLAGS.V:='0';
343
                        end if;
344
                when ALU_OR =>  -- Logical or operation ***********************************************
345
                        RESULT := OPER1 or OPER2;
346
                when ALU_AND => -- Logical AND operation **********************************************
347
                        RESULT := OPER1 AND OPER2;
348
                when ALU_TCM => -- Test Complement Mask operation *************************************
349
                        RESULT := (NOT OPER1) AND OPER2;
350
                        ALU_NOUPDATE := '1';
351
                when ALU_TM =>  -- Test Mask operation ************************************************
352
                        RESULT := OPER1 AND OPER2;
353
                        ALU_NOUPDATE := '1';
354
                when ALU_CPC =>         -- CPC operation **************************************************
355
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)))-CIN;
356
                        ALU_FLAGS.H := (HALF1(4));
357
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
358
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
359
                        ALU_FLAGS.C := (HALF2(4));
360
                        if (OPER1(7)/=OPER2(7)) then
361
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
362
                                end if;
363
                        else ALU_FLAGS.V:='0';
364
                        end if;
365
                        ALU_NOUPDATE := '1';
366
                when ALU_CP =>  -- Compare operation **************************************************
367
                        HALF1 := ('0'&OPER1(3 downto 0))-('0'&(OPER2(3 downto 0)));
368
                        ALU_FLAGS.H := (HALF1(4));
369
                        HALF2 := ('0'&OPER1(7 downto 4))-('0'&(OPER2(7 downto 4)))-HALF1(4);
370
                        RESULT := HALF2(3 downto 0) & HALF1(3 downto 0);
371
                        ALU_FLAGS.C := (HALF2(4));
372
                        if (OPER1(7)/=OPER2(7)) then
373
                                if (OPER1(7)=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
374
                                end if;
375
                        else ALU_FLAGS.V:='0';
376
                        end if;
377
                        ALU_NOUPDATE := '1';
378
                when ALU_XOR => -- Logical xor operation **********************************************
379
                        RESULT := OPER1 xor OPER2;
380
                when ALU_BSWAP =>       -- Bit Swap operation *********************************************
381
                        RESULT := OPER2(0)&OPER2(1)&OPER2(2)&OPER2(3)&OPER2(4)&OPER2(5)&OPER2(6)&OPER2(7);
382
                when others =>  -- Load operation *****************************************************
383
                        RESULT := OPER2;
384
 
385
        end case;
386
        if (RESULT(7 downto 0)=x"00") then ALU_FLAGS.Z := '1'; else ALU_FLAGS.Z := '0';
387
        end if;
388
        ALU_FLAGS.S := RESULT(7);
389
        return RESULT(7 downto 0);
390
end ALU;
391
 
392
-- LU2 is the second logic unit, it performs mostly logical operations not covered by the ALU
393
function LU2
394
        (       LU2_OP  : in std_logic_vector(3 downto 0);
395
                OPER    : in std_logic_vector(7 downto 0);
396
                DIN             : in std_logic;
397
                HIN             : in std_logic;
398
                CIN             : in std_logic) return std_logic_vector is
399
variable RESULT : std_logic_vector(7 downto 0);
400
begin
401
        case LU2_OP is
402
                when LU2_RLC =>         -- RLC operation **************************************************
403
                        ALU_FLAGS.C := OPER(7);
404
                        RESULT := OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1)&OPER(0)&CIN;
405
                when LU2_INC =>         -- INC operation **************************************************
406
                        RESULT := OPER+1;
407
                        if (RESULT=x"00") then ALU_FLAGS.C:='1'; else ALU_FLAGS.C:='0';
408
                        end if;
409
                when LU2_DEC =>         -- DEC operation **************************************************
410
                        RESULT := OPER-1;
411
                        if (RESULT=x"FF") then ALU_FLAGS.C:='1'; else ALU_FLAGS.C:='0';
412
                        end if;
413
                when LU2_DA =>          -- DA operation ***************************************************
414
                        if (DIN='0') then        -- decimal adjust following an add operation
415
                                if (OPER(3 downto 0)>x"9" or HIN='1') then
416
                                        RESULT := ALU(ALU_ADD,OPER,x"06",'0');
417
                                else RESULT := OPER;
418
                                end if;
419
                                if (RESULT(7 downto 4)>x"9" or ALU_FLAGS.C='1') then
420
                                        RESULT := ALU(ALU_ADD,RESULT,x"60",'0');
421
                                end if;
422
                        else    -------------- decimal adjust following a sub operation
423
                        end if;
424
                when LU2_COM =>         -- COM operation **************************************************
425
                        RESULT := NOT OPER;
426
                when LU2_RL =>          -- RL operation ***************************************************
427
                        ALU_FLAGS.C := OPER(7);
428
                        RESULT := OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1)&OPER(0)&ALU_FLAGS.C;
429
                when LU2_SRL =>         -- SRL operation **************************************************
430
                        ALU_FLAGS.C := OPER(0);
431
                        RESULT := '0'&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
432
                when LU2_RRC =>         -- RRC operation **************************************************
433
                        ALU_FLAGS.C := OPER(0);
434
                        RESULT := CIN&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
435
                when LU2_RR =>          -- RR operation ***************************************************
436
                        ALU_FLAGS.C := OPER(0);
437
                        RESULT := ALU_FLAGS.C&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
438
                when LU2_SRA =>         -- SRA operation **************************************************
439
                        ALU_FLAGS.C := OPER(0);
440
                        RESULT := OPER(7)&OPER(7)&OPER(6)&OPER(5)&OPER(4)&OPER(3)&OPER(2)&OPER(1);
441
                when LU2_SWAP =>        -- SWAP operation *************************************************
442
                        RESULT := OPER(3)&OPER(2)&OPER(1)&OPER(0)&OPER(7)&OPER(6)&OPER(5)&OPER(4);
443
                when LU2_LD =>          -- LOAD operation *************************************************
444
                        RESULT := OPER;
445
                when others =>          -- CLR operation **************************************************
446
                        RESULT := x"00";
447
        end case;
448
        if (OPER(7)/=RESULT(7)) then ALU_FLAGS.V :='1'; else ALU_FLAGS.V :='0';
449
        end if;
450
        if (RESULT=x"00") then ALU_FLAGS.Z := '1'; else ALU_FLAGS.Z := '0';
451
        end if;
452
        ALU_FLAGS.S := RESULT(7);
453
        return RESULT;
454
end LU2;
455
 
456
-- ADDER16 adds a signed 8-bit offset to a 16-bit address
457
function ADDER16
458
        (       ADDR16  : in std_logic_vector(15 downto 0);
459
                OFFSET  : in std_logic_vector(7 downto 0)) return std_logic_vector is
460
begin
461
        if (OFFSET(7)='0') then return ADDR16 + (x"00" & OFFSET);
462
        else return ADDR16 + (x"FF" & OFFSET);
463
        end if;
464
end ADDER16;
465
 
466
begin
467
        clock_out: process(CLK)
468
        begin
469
                CLK_OUTN <= not CLK;
470
                CLK_OUT <= CLK;
471
        end process;
472
        -- main process controls debugging and instruction fetching and decoding along
473
        main: process (CLK,RESET,DBG_RX)
474
        -- CPU state machine
475
        type Tcpu_state is (
476
                CPU_DECOD,
477
                CPU_INDRR,
478
                CPU_MUL, CPU_MUL1, CPU_MUL2,
479
                CPU_XADTOM,
480
                CPU_MTOXAD, CPU_MTOXAD2,
481
                CPU_XRTOM,
482
                CPU_XRRTORR, CPU_XRRTORR2,
483
                CPU_XRRTORR3, CPU_XRRTORR4,
484
                CPU_IMTOIRR, CPU_MTOIRR,                -- indirect and direct to indirect register pair addressing mode
485
                CPU_IRRS, CPU_IRRS2,
486
                CPU_XRRD, CPU_XRRD2, CPU_XRRD3, -- indexed rr pair as destination
487
                CPU_XRRS, CPU_XRRS2, CPU_XRRS3, -- indexed rr pair as source
488
                CPU_IND1, CPU_IND2,                             -- indirect memory access
489
                CPU_ISMD1,                                              -- indirect source to memory destination
490
                CPU_TMA,                                                -- Two memory access instructions (register to/with register)
491
                CPU_OMA,                                                -- One memory access instructions (immediate to/with register)
492
                CPU_OMA2,                                               -- One memory access instructions (immediate to/with register) logic unit related
493
                CPU_DMAB,                                               -- Decrement address bus (for word access)
494
                CPU_LDW, CPU_LDW2,
495
                CPU_LDPTOIM, CPU_LDPTOIM2,
496
                CPU_LDPTOM, CPU_LDPTOM2,
497
                CPU_LDPTOM3, CPU_LDPTOM4,
498
                CPU_LDMTOP, CPU_LDMTOP2,
499
                CPU_BIT,
500
                CPU_IBTJ, CPU_BTJ,
501
                CPU_DJNZ,
502
                CPU_INDJUMP, CPU_INDJUMP2,
503
                CPU_TRAP, CPU_TRAP2,
504
                CPU_INDSTACK, CPU_INDSTACK2,
505
                CPU_STACK, CPU_STACK1,
506
                CPU_STACK2, CPU_STACK3,
507
                CPU_UNSTACK, CPU_UNSTACK2,
508
                CPU_UNSTACK3,
509
                CPU_STORE,                                              -- store results, no change to the flags
510
                CPU_VECTOR, CPU_VECTOR2,
511
                CPU_HALTED,
512
                CPU_RESET,
513
                CPU_ILLEGAL
514
        );
515
        type Tfetch_state is (
516
                F_ADDR,         -- instruction queue is initializing, reset pointers and empty queue
517
                F_READ          -- instruction queue is fetching opcodes
518
        );
519
        type Tdbg_uartrxstate is (
520
                DBGST_NOSYNC,                   -- debug UART receiver is not synchronized to the host
521
                DBGST_WAITSTART,                -- debug UART receiver is waiting for a 0x80 char
522
                DBGST_MEASURING,                -- debug UART receiver is measuring a possible sync char
523
                DBGST_IDLE,                             -- debug UART receiver is synchronized and awaiting commands
524
                DBGST_START,                    -- debug UART received a start bit
525
                DBGST_RECEIVING,                -- debug UART is receiving new command/data
526
                DBGST_ERROR                             -- debug UART receiver is in error state
527
        );
528
        type Tdbg_uarttxstate is (
529
                DBGTX_INIT,                             -- debug UART transmitter is initializing
530
                DBGTX_IDLE,                             -- debug UART transmitter is waiting new data to transmit
531
                DBGTX_START,                    -- debug UART transmitter is sending a start bit
532
                DBGTX_TRASMITTING,              -- debug UART transmitter is sending data
533
                DBGTX_BREAK,                    -- debug UART transmitter is preparing to send a break
534
                DBGTX_BREAK2                    -- debug UART is waiting for the break complete
535
        );
536
        type Tdbg_command is (
537
                DBG_WAIT_CMD,                                                   -- debugger is waiting for commands
538
                DBG_SEND_REV, DBG_SEND_REV2,                    -- debugger is processing a read revision command
539
                DBG_SEND_STATUS,                                                -- debugger is processing a read OCDST command
540
                DBG_WRITE_CTRL,                                                 -- debugger is processing a write OCDCTRL command
541
                DBG_SEND_CTRL,                                                  -- debugger is processing a read OCDCTRL command
542
                DBG_WRITE_PC, DBG_WRITE_PC2,                    -- debugger is processing a PC write command
543
                DBG_SEND_PC, DBG_SEND_PC2,                              -- debugger is processing a PC read command
544
                DBG_WRITE_REG, DBG_READ_REG,                    -- debugger is processing a read/write to registers
545
                DBG_REG, DBG_REG2, DBG_REG3,                    -- debugger is processing a read/write to registers
546
                DBG_REG4, DBG_REG5,                                             -- debugger is processing a read/write to registers
547
                DBG_WRITE_PROGMEM, DBG_READ_PROGMEM,    -- debugger is processing a read/write to program memory
548
                DBG_PROGMEM, DBG_PROGMEM2,                              -- debugger is processing a read/write to program memory
549
                DBG_PROGMEM3, DBG_PROGMEM4,                     -- debugger is processing a read/write to program memory
550
                DBG_PROGMEM5, DBG_PROGMEM6,                             -- debugger is processing a read/write to program memory
551
                DBG_STEP,                                                               -- debugger is processing a step command
552
                DBG_STUFF,                                                              -- debugger is processing a stuff command
553
                DBG_EXEC, DBG_EXEC2, DBG_EXEC3                  -- debugger is processing a execute command
554
        );
555
        type Tdbg_uart is record
556
                RX_STATE        : Tdbg_uartrxstate;
557
                TX_STATE        : Tdbg_uarttxstate;
558
                RX_DONE         : std_logic;                                            -- new data is available
559
                TX_EMPTY        : std_logic;                                            -- tx buffer is empty
560
                DBG_SYNC        : std_logic;                                            -- debugger is synchronized to host
561
                WRT                     : std_logic;                                            -- write/read command flag
562
                LAST_SMP        : std_logic;                                            -- last sample read from DBG_RX pin
563
                SIZE            : std_logic_vector(15 downto 0); -- 16-bit size of command
564
                TXSHIFTREG      : std_logic_vector(8 downto 0);          -- transmitter shift register
565
                RXSHIFTREG      : std_logic_vector(8 downto 0);          -- receiver shift register
566
                TX_DATA         : std_logic_vector(7 downto 0);          -- TX buffer
567
                RX_DATA         : std_logic_vector(7 downto 0);          -- RX buffer
568
                RXCNT           : integer range 0 to 15;                 -- received bit counter
569
                TXCNT           : integer range 0 to 15;                 -- transmitted bit counter
570
                BAUDPRE         : integer range 0 to 2;                          -- baud prescaler
571
                BAUDCNTRX       : std_logic_vector(11 downto 0); -- RX baud divider
572
                BAUDCNTTX       : std_logic_vector(11 downto 0); -- TX baud divider
573
                BITTIMERX       : std_logic_vector(11 downto 0); -- RX bit-time register (1/2 bit-time)
574
                BITTIMETX       : std_logic_vector(11 downto 0); -- TX bit-time register
575
        end record;
576
        variable CPU_STATE              : TCPU_STATE;                                           -- current CPU state 
577
        variable DBG_UART               : Tdbg_uart;
578
        variable DBG_CMD                : Tdbg_command;
579
        variable CAN_FETCH              : std_logic;                                            -- controls whether the instruction queue can actually fetch opcodes
580
        variable LU_INSTRUCTION : std_logic;                                            -- indicates a LU2-related instruction
581
        variable WORD_DATA              : std_logic;                                            -- indicates a 16-bit data instruction
582
        variable PC                     : std_logic_vector(15 downto 0); -- program counter
583
        variable FETCH_ADDR             : std_logic_vector(15 downto 0); -- next address to be fetched
584
        variable DEST_ADDR16    : std_logic_vector(15 downto 0); -- temporary 16-bit destination address
585
        variable DEST_ADDR              : std_logic_vector(11 downto 0); -- temporary 12-bit destination address
586
        variable TEMP_DATA              : std_logic_vector(7 downto 0);          -- temporary 8-bit data
587
        variable OLD_IRQ0               : std_logic_vector(7 downto 0);          -- previous state of IRQs
588
        variable INTVECT                : std_logic_vector(7 downto 0);          -- current interrupt vector (lower 8-bits)
589
        variable RESULT                 : std_logic_vector(7 downto 0);          -- temporary 8-bit result
590
        variable TEMP_OP                : std_logic_vector(3 downto 0);          -- ALU/LU2 operation code
591
        variable ATM_COUNTER    : integer range 0 to 3;                          -- temporary interrupt disable counter (ATM instruction)
592
        variable NUM_BYTES              : integer range 0 to 5;                          -- number of bytes decoded
593
        variable CKDIVIDER              : integer range 0 to 2;
594
        type Tinstructionqueue is record
595
                WRPOS                           : integer range 0 to 7;                          -- instruction queue write pointer
596
                RDPOS                           : integer range 0 to 7;                          -- instruction queue read pointer
597
                CNT                                     : integer range 0 to 7;                          -- instruction queue available bytes
598
                FETCH_STATE                     : tfetch_state;
599
                QUEUE                           : Tinstqueue;
600
                FULL                            : std_logic;                                            -- indicates whether the queue is full or not
601
        end record;
602
        variable IQUEUE                 : Tinstructionqueue;
603
        type Tocdcr is record
604
                DBGMODE                         : std_logic;
605
                BRKEN                           : std_logic;
606
                DBGACK                          : std_logic;
607
                BRKLOOP                         : std_logic;
608
                RST                                     : std_logic;
609
        end record;
610
        variable OCDCR                  : Tocdcr;
611
        type Tocdflags is record
612
                SINGLESTEP                      : std_logic;
613
        end record;
614
        variable OCD                    : Tocdflags;
615
 
616
        begin
617
                if (reset='1') then     -- reset operations             
618
                        IAB <= x"0002";
619
                        MAB <= x"000";
620
                        PWDB <= x"00";
621
                        SP := x"000";
622
                        RP := x"00";
623
                        WR <= '0';
624
                        PGM_WR <= '0';
625
                        STOP <= '0';
626
                        CAN_FETCH := '1';
627
                        FETCH_ADDR := x"0000";
628
                        DBG_UART.RX_STATE := DBGST_NOSYNC;
629
                        DBG_UART.TX_STATE := DBGTX_INIT;
630
                        OCDCR.DBGMODE := '0';
631
                        OCDCR.BRKEN := '0';
632
                        OCDCR.DBGACK := '0';
633
                        OCDCR.BRKLOOP := '0';
634
                        OCD.SINGLESTEP := '0';
635
                        OCDCR.RST := '0';
636
                        RXSYNC1 <= '1';
637
                        RXSYNC2 <= '1';
638
                        DBG_UART.LAST_SMP := '1';
639
                        IQUEUE.FETCH_STATE := F_ADDR;
640
                        IRQE := '0';
641
                        IRQ0 := x"00";
642
                        OLD_IRQ0 := x"00";
643
                        IRQ0ENH := x"00";
644
                        IRQ0ENL := x"00";
645
                        ATM_COUNTER := 0;
646
                        CKDIVIDER := 0;
647
                        CPU_STATE := CPU_VECTOR;
648
                elsif (rising_edge(clk)) then
649
                        if (OLD_IRQ0(0)='0' and INT0='1') then IRQ0(0) := '1'; end if;
650
                        if (OLD_IRQ0(1)='0' and INT1='1') then IRQ0(1) := '1'; end if;
651
                        if (OLD_IRQ0(2)='0' and INT2='1') then IRQ0(2) := '1'; end if;
652
                        if (OLD_IRQ0(3)='0' and INT3='1') then IRQ0(3) := '1'; end if;
653
                        if (OLD_IRQ0(4)='0' and INT4='1') then IRQ0(4) := '1'; end if;
654
                        if (OLD_IRQ0(5)='0' and INT5='1') then IRQ0(5) := '1'; end if;
655
                        if (OLD_IRQ0(6)='0' and INT6='1') then IRQ0(6) := '1'; end if;
656
                        OLD_IRQ0 := INT7&INT6&INT5&INT4&INT3&INT2&INT1&INT0;
657
                        CKDIVIDER := CKDIVIDER + 1;
658
                        if (CKDIVIDER=0) then    -- main clock (50MHz) is divided by 3, resulting in a 16.66MHz system clock
659
                                WR <= '0';
660
                                PGM_WR <= '0';
661
 
662
                                -- This is the instruction queue FSM
663
                                if (CAN_FETCH='1') then
664
                                        if (IQUEUE.FETCH_STATE=F_ADDR) then
665
                                                FETCH_ADDR := PC;
666
                                                IAB <= PC;
667
                                                IQUEUE.WRPOS := 0;
668
                                                IQUEUE.RDPOS := 0;
669
                                                IQUEUE.CNT := 0;
670
                                                IQUEUE.FETCH_STATE := F_READ;
671
                                        else
672
                                                if (IQUEUE.FULL='0') then
673
                                                        IQUEUE.QUEUE(IQUEUE.WRPOS) := IDB;
674
                                                        FETCH_ADDR := FETCH_ADDR + 1;
675
                                                        IAB <= FETCH_ADDR;
676
                                                        IQUEUE.WRPOS := IQUEUE.WRPOS + 1;
677
                                                        IQUEUE.CNT := IQUEUE.CNT + 1;
678
                                                end if;
679
                                        end if;
680
                                end if;
681
                                if (IQUEUE.CNT=7) then IQUEUE.FULL:='1'; else IQUEUE.FULL:='0';
682
                                end if;
683
                                -- This is the end of instruction queue FSM     
684
 
685
                                -- These are the Debugger FSMs
686
                                DBG_UART.BAUDPRE := DBG_UART.BAUDPRE+1;
687
                                if (DBG_UART.BAUDPRE=0) then
688
                                        DBG_UART.BAUDCNTRX := DBG_UART.BAUDCNTRX+1;
689
                                        DBG_UART.BAUDCNTTX := DBG_UART.BAUDCNTTX+1;
690
                                end if;
691
                                RXSYNC2 <= DBG_RX;
692
                                RXSYNC1 <= RXSYNC2;
693
                                case DBG_UART.RX_STATE is
694
                                        when DBGST_NOSYNC =>
695
                                                DBG_UART.DBG_SYNC := '0';
696
                                                DBG_UART.RX_DONE := '0';
697
                                                DBG_CMD := DBG_WAIT_CMD;
698
                                                DBG_UART.RX_STATE := DBGST_WAITSTART;
699
                                        when DBGST_WAITSTART =>
700
                                                if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then
701
                                                        DBG_UART.RX_STATE := DBGST_MEASURING;
702
                                                        DBG_UART.BAUDCNTRX := x"000";
703
                                                end if;
704
                                        when DBGST_MEASURING =>
705
                                                if (DBG_UART.BAUDCNTRX/=x"FFF") then
706
                                                        if (RXSYNC1='1') then
707
                                                                DBG_UART.DBG_SYNC := '1';
708
                                                                DBG_UART.RX_STATE := DBGST_IDLE;
709
                                                                DBG_UART.BITTIMERX := "0000"&DBG_UART.BAUDCNTRX(11 downto 4);
710
                                                                DBG_UART.BITTIMETX := "000"&DBG_UART.BAUDCNTRX(11 downto 3);
711
                                                        end if;
712
                                                else
713
                                                        DBG_UART.RX_STATE := DBGST_NOSYNC;
714
                                                end if;
715
                                        when DBGST_IDLE =>
716
                                                DBG_UART.BAUDCNTRX:=x"000";
717
                                                DBG_UART.RXCNT:=0;
718
                                                if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then  -- it's a start bit
719
                                                        DBG_UART.RX_STATE := DBGST_START;
720
                                                end if;
721
                                        when DBGST_START =>
722
                                                if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMERX) then
723
                                                        DBG_UART.BAUDCNTRX:=x"000";
724
                                                        if (RXSYNC1='0') then
725
                                                                DBG_UART.RX_STATE := DBGST_RECEIVING;
726
                                                        else
727
                                                                DBG_UART.RX_STATE := DBGST_ERROR;
728
                                                                DBG_UART.TX_STATE := DBGTX_BREAK;
729
                                                        end if;
730
                                                end if;
731
                                        when DBGST_RECEIVING =>
732
                                                if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMETX) then
733
                                                        DBG_UART.BAUDCNTRX:=x"000";
734
                                                        -- one bit time elapsed, sample RX input
735
                                                        DBG_UART.RXSHIFTREG := RXSYNC1 & DBG_UART.RXSHIFTREG(8 downto 1);
736
                                                        DBG_UART.RXCNT := DBG_UART.RXCNT + 1;
737
                                                        if (DBG_UART.RXCNT=9) then
738
                                                                if (RXSYNC1='1') then
739
                                                                        -- if the stop bit is 1, rx is completed ok
740
                                                                        DBG_UART.RX_DATA := DBG_UART.RXSHIFTREG(7 downto 0);
741
                                                                        DBG_UART.RX_DONE := '1';
742
                                                                        DBG_UART.RX_STATE := DBGST_IDLE;
743
                                                                else
744
                                                                        -- if the stop bit is 0, it is a break char, reset receiver
745
                                                                        DBG_UART.RX_STATE := DBGST_ERROR;
746
                                                                        DBG_UART.TX_STATE := DBGTX_BREAK;
747
                                                                end if;
748
                                                        end if;
749
                                                end if;
750
                                        when others =>
751
                                end case;
752
                                DBG_UART.LAST_SMP := RXSYNC1;
753
                                case DBG_UART.TX_STATE is
754
                                        when DBGTX_INIT =>
755
                                                DBG_UART.TX_EMPTY := '1';
756
                                                DBG_UART.TX_STATE:=DBGTX_IDLE;
757
                                        when DBGTX_IDLE =>      -- UART is idle and not transmitting
758
                                                DBG_TX <= '1';
759
                                                if (DBG_UART.TX_EMPTY='0' and DBG_UART.DBG_SYNC='1') then        -- there is new data in TX_DATA register
760
                                                        DBG_UART.BAUDCNTTX:=x"000";
761
                                                        DBG_UART.TX_STATE := DBGTX_START;
762
                                                end if;
763
                                        when DBGTX_START =>
764
                                                if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then
765
                                                        DBG_UART.BAUDCNTTX:=x"000";
766
                                                        DBG_UART.TXSHIFTREG := '1'&DBG_UART.TX_DATA;
767
                                                        DBG_UART.TXCNT := 10;
768
                                                        DBG_UART.TX_STATE := DBGTX_TRASMITTING;
769
                                                        DBG_TX <= '0';
770
                                                end if;
771
                                        when DBGTX_TRASMITTING =>       -- UART is shifting data
772
                                                if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then
773
                                                        DBG_UART.BAUDCNTTX:=x"000";
774
                                                        DBG_TX <= DBG_UART.TXSHIFTREG(0);
775
                                                        DBG_UART.TXSHIFTREG := '1'&DBG_UART.TXSHIFTREG(8 downto 1);
776
                                                        DBG_UART.TXCNT :=DBG_UART.TXCNT - 1;
777
                                                        if (DBG_UART.TXCNT=0) then
778
                                                                DBG_UART.TX_STATE:=DBGTX_IDLE;
779
                                                                DBG_UART.TX_EMPTY := '1';
780
                                                        end if;
781
                                                end if;
782
                                        when DBGTX_BREAK =>
783
                                                DBG_UART.BAUDCNTTX:=x"000";
784
                                                DBG_UART.TX_STATE:=DBGTX_BREAK2;
785
                                        when DBGTX_BREAK2 =>
786
                                                DBG_TX <= '0';
787
                                                DBG_UART.RX_STATE := DBGST_NOSYNC;
788
                                                if (DBG_UART.BAUDCNTTX=x"FFF") then
789
                                                        DBG_UART.TX_STATE:=DBGTX_INIT;
790
                                                end if;
791
                                end case;
792
                                if (RXSYNC1='0') then DBG_TX <='0';
793
                                end if;
794
                                case DBG_CMD is
795
                                        when DBG_WAIT_CMD =>
796
                                                if (DBG_UART.RX_DONE='1') then
797
                                                        case DBG_UART.RX_DATA is
798
                                                                when DBGCMD_READ_REV =>         DBG_CMD := DBG_SEND_REV;
799
                                                                when DBGCMD_READ_STATUS =>      DBG_CMD := DBG_SEND_STATUS;
800
                                                                when DBGCMD_WRITE_CTRL =>       DBG_CMD := DBG_WRITE_CTRL;
801
                                                                when DBGCMD_READ_CTRL =>        DBG_CMD := DBG_SEND_CTRL;
802
                                                                when DBGCMD_WRITE_PC =>         DBG_CMD := DBG_WRITE_PC;
803
                                                                when DBGCMD_READ_PC =>          DBG_CMD := DBG_SEND_PC;
804
                                                                when DBGCMD_WRITE_REG =>        DBG_CMD := DBG_WRITE_REG;
805
                                                                when DBGCMD_READ_REG =>         DBG_CMD := DBG_READ_REG;
806
                                                                when DBGCMD_WRITE_PROGRAM=>     DBG_CMD := DBG_WRITE_PROGMEM;
807
                                                                when DBGCMD_READ_PROGRAM=>      DBG_CMD := DBG_READ_PROGMEM;
808
                                                                when DBGCMD_STEP =>                     DBG_CMD := DBG_STEP;
809
                                                                when DBGCMD_STUFF =>            DBG_CMD := DBG_STUFF;
810
                                                                when DBGCMD_EXEC =>                     DBG_CMD := DBG_EXEC;
811
                                                                when others =>
812
                                                        end case;
813
                                                        DBG_UART.RX_DONE:='0';
814
                                                end if;
815
                                        when DBG_SEND_REV =>
816
                                                if (DBG_UART.TX_EMPTY='1') then
817
                                                        DBG_UART.TX_DATA:=x"01";
818
                                                        DBG_UART.TX_EMPTY:='0';
819
                                                        DBG_CMD := DBG_SEND_REV2;
820
                                                end if;
821
                                        when DBG_SEND_REV2 =>
822
                                                if (DBG_UART.TX_EMPTY='1') then
823
                                                        DBG_UART.TX_DATA:=x"00";
824
                                                        DBG_UART.TX_EMPTY:='0';
825
                                                        DBG_CMD := DBG_WAIT_CMD;
826
                                                end if;
827
                                        when DBG_SEND_STATUS =>
828
                                                if (DBG_UART.TX_EMPTY='1') then
829
                                                        DBG_UART.TX_DATA:=OCDCR.DBGMODE&HALT&"000000";
830
                                                        DBG_UART.TX_EMPTY:='0';
831
                                                        DBG_CMD := DBG_WAIT_CMD;
832
                                                end if;
833
                                        when DBG_WRITE_CTRL =>
834
                                                if (DBG_UART.RX_DONE='1') then
835
                                                        DBG_UART.RX_DONE:='0';
836
                                                        OCDCR.DBGMODE := DBG_UART.RX_DATA(7);
837
                                                        OCDCR.BRKEN := DBG_UART.RX_DATA(6);
838
                                                        OCDCR.DBGACK := DBG_UART.RX_DATA(5);
839
                                                        OCDCR.BRKLOOP := DBG_UART.RX_DATA(4);
840
                                                        OCDCR.RST := DBG_UART.RX_DATA(0);
841
                                                        if (OCDCR.RST='1') then CPU_STATE:=CPU_RESET;
842
                                                        end if;
843
                                                        DBG_CMD := DBG_WAIT_CMD;
844
                                                end if;
845
                                        when DBG_SEND_CTRL =>
846
                                                if (DBG_UART.TX_EMPTY='1') then
847
                                                        DBG_UART.TX_DATA:=OCDCR.DBGMODE&OCDCR.BRKEN&OCDCR.DBGACK&OCDCR.BRKLOOP&"000"&OCDCR.RST;
848
                                                        DBG_UART.TX_EMPTY:='0';
849
                                                        DBG_CMD := DBG_WAIT_CMD;
850
                                                end if;
851
                                        when DBG_WRITE_PC =>
852
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
853
                                                        DBG_UART.RX_DONE:='0';
854
                                                        CAN_FETCH := '0';
855
                                                        PC(15 downto 8) := DBG_UART.RX_DATA;
856
                                                        DBG_CMD := DBG_WRITE_PC2;
857
                                                end if;
858
                                        when DBG_WRITE_PC2 =>
859
                                                if (DBG_UART.RX_DONE='1') then
860
                                                        DBG_UART.RX_DONE:='0';
861
                                                        PC(7 downto 0) := DBG_UART.RX_DATA;
862
                                                        IQUEUE.FETCH_STATE := F_ADDR;
863
                                                        IQUEUE.CNT := 0;
864
                                                        CAN_FETCH := '1';
865
                                                        DBG_CMD := DBG_WAIT_CMD;
866
                                                end if;
867
                                        when DBG_SEND_PC =>
868
                                                if (DBG_UART.TX_EMPTY='1') then
869
                                                        DBG_UART.TX_DATA:=PC(15 downto 8);
870
                                                        DBG_UART.TX_EMPTY:='0';
871
                                                        DBG_CMD := DBG_SEND_PC2;
872
                                                end if;
873
                                        when DBG_SEND_PC2 =>
874
                                                if (DBG_UART.TX_EMPTY='1') then
875
                                                        DBG_UART.TX_DATA:=PC(7 downto 0);
876
                                                        DBG_UART.TX_EMPTY:='0';
877
                                                        DBG_CMD := DBG_WAIT_CMD;
878
                                                end if;
879
                                        when DBG_WRITE_REG =>
880
                                                DBG_UART.WRT := '1';
881
                                                DBG_CMD := DBG_REG;
882
                                        when DBG_READ_REG =>
883
                                                DBG_UART.WRT := '0';
884
                                                DBG_CMD := DBG_REG;
885
                                        when DBG_REG =>
886
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
887
                                                        CAN_FETCH := '0';
888
                                                        MAB(11 downto 8) <= DBG_UART.RX_DATA(3 downto 0);
889
                                                        DBG_UART.RX_DONE:='0';
890
                                                        DBG_CMD := DBG_REG2;
891
                                                end if;
892
                                        when DBG_REG2 =>
893
                                                if (DBG_UART.RX_DONE='1') then
894
                                                        MAB(7 downto 0) <= DBG_UART.RX_DATA;
895
                                                        DBG_UART.RX_DONE:='0';
896
                                                        DBG_CMD := DBG_REG3;
897
                                                end if;
898
                                        when DBG_REG3 =>
899
                                                if (DBG_UART.RX_DONE='1') then
900
                                                        DBG_UART.SIZE := x"00"&DBG_UART.RX_DATA;
901
                                                        DBG_UART.RX_DONE:='0';
902
                                                        DBG_CMD := DBG_REG4;
903
                                                end if;
904
                                        when DBG_REG4 =>
905
                                                if (OCDCR.DBGMODE='1') then
906
                                                        if (DBG_UART.WRT='1') then
907
                                                                if (DBG_UART.RX_DONE='1') then
908
                                                                        CPU_STATE := CPU_OMA;
909
                                                                        TEMP_DATA := DBG_UART.RX_DATA;
910
                                                                        DBG_UART.RX_DONE:='0';
911
                                                                        DBG_CMD := DBG_REG5;
912
                                                                end if;
913
                                                        else
914
                                                                if (DBG_UART.TX_EMPTY='1') then
915
                                                                        DBG_UART.TX_DATA:=DATAREAD(MAB);
916
                                                                        DBG_UART.TX_EMPTY:='0';
917
                                                                        DBG_CMD := DBG_REG5;
918
                                                                end if;
919
                                                        end if;
920
                                                end if;
921
                                        when DBG_REG5 =>
922
                                                if (CPU_STATE=CPU_DECOD) then
923
                                                        MAB <= MAB + 1;
924
                                                        DBG_UART.SIZE := DBG_UART.SIZE - 1;
925
                                                        if (DBG_UART.SIZE=x"0000") then
926
                                                                DBG_CMD := DBG_WAIT_CMD;
927
                                                                CAN_FETCH := '1';
928
                                                        else DBG_CMD := DBG_REG4;
929
                                                        end if;
930
                                                end if;
931
                                        when DBG_WRITE_PROGMEM =>
932
                                                DBG_UART.WRT := '1';
933
                                                DBG_CMD := DBG_PROGMEM;
934
                                        when DBG_READ_PROGMEM =>
935
                                                DBG_UART.WRT := '0';
936
                                                DBG_CMD := DBG_PROGMEM;
937
                                        when DBG_PROGMEM =>
938
                                                if (DBG_UART.RX_DONE='1') then
939
                                                        CAN_FETCH := '0';
940
                                                        IAB(15 downto 8) <= DBG_UART.RX_DATA;
941
                                                        DBG_UART.RX_DONE:='0';
942
                                                        DBG_CMD := DBG_PROGMEM2;
943
                                                end if;
944
                                        when DBG_PROGMEM2 =>
945
                                                if (DBG_UART.RX_DONE='1') then
946
                                                        IAB(7 downto 0) <= DBG_UART.RX_DATA;
947
                                                        DBG_UART.RX_DONE:='0';
948
                                                        DBG_CMD := DBG_PROGMEM3;
949
                                                end if;
950
                                        when DBG_PROGMEM3 =>
951
                                                if (DBG_UART.RX_DONE='1') then
952
                                                        DBG_UART.SIZE(15 downto 8) := DBG_UART.RX_DATA;
953
                                                        DBG_UART.RX_DONE:='0';
954
                                                        DBG_CMD := DBG_PROGMEM4;
955
                                                end if;
956
                                        when DBG_PROGMEM4 =>
957
                                                if (DBG_UART.RX_DONE='1') then
958
                                                        DBG_UART.SIZE(7 downto 0) := DBG_UART.RX_DATA;
959
                                                        DBG_UART.RX_DONE:='0';
960
                                                        DBG_CMD := DBG_PROGMEM5;
961
                                                end if;
962
                                        when DBG_PROGMEM5 =>
963
                                                if (DBG_UART.WRT='1') then
964
                                                        if (DBG_UART.RX_DONE='1') then
965
                                                                PWDB <= DBG_UART.RX_DATA;
966
                                                                DBG_UART.RX_DONE:='0';
967
                                                                PGM_WR <= '1';
968
                                                                DBG_CMD := DBG_PROGMEM6;
969
                                                        end if;
970
                                                else
971
                                                        if (DBG_UART.TX_EMPTY='1') then
972
                                                                DBG_UART.TX_DATA:=IDB;
973
                                                                DBG_UART.TX_EMPTY:='0';
974
                                                                DBG_CMD := DBG_PROGMEM6;
975
                                                        end if;
976
                                                end if;
977
                                        when DBG_PROGMEM6 =>
978
                                                IAB <= IAB + 1;
979
                                                DBG_UART.SIZE := DBG_UART.SIZE - 1;
980
                                                if (DBG_UART.SIZE=x"0000") then
981
                                                        DBG_CMD := DBG_WAIT_CMD;
982
                                                        CAN_FETCH := '1';
983
                                                        IQUEUE.CNT := 0;
984
                                                        IQUEUE.FETCH_STATE := F_ADDR;
985
                                                else DBG_CMD := DBG_PROGMEM5;
986
                                                end if;
987
                                        when DBG_STEP =>
988
                                                OCD.SINGLESTEP:='1';
989
                                                IQUEUE.FETCH_STATE := F_ADDR;
990
                                                DBG_CMD := DBG_WAIT_CMD;
991
                                        when DBG_STUFF =>
992
                                                if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then
993
                                                        IQUEUE.QUEUE(IQUEUE.RDPOS) := DBG_UART.RX_DATA;
994
                                                        DBG_UART.RX_DONE:='0';
995
                                                        DBG_CMD := DBG_STEP;
996
                                                end if;
997
                                        when DBG_EXEC =>
998
                                                if (OCDCR.DBGMODE='1') then
999
                                                        OCD.SINGLESTEP:='1';
1000
                                                        CAN_FETCH:='0';
1001
                                                        IQUEUE.CNT := 0;
1002
                                                        IQUEUE.FETCH_STATE := F_ADDR;
1003
                                                end if;
1004
                                                DBG_CMD := DBG_EXEC2;
1005
                                        when DBG_EXEC2 =>
1006
                                                if (DBG_UART.RX_DONE='1') then
1007
                                                        if (OCDCR.DBGMODE='0') then DBG_CMD := DBG_WAIT_CMD;
1008
                                                        else
1009
                                                                IQUEUE.QUEUE(IQUEUE.WRPOS) := DBG_UART.RX_DATA;
1010
                                                                DBG_UART.RX_DONE:='0';
1011
                                                                IQUEUE.WRPOS := IQUEUE.WRPOS + 1;
1012
                                                                IQUEUE.CNT := IQUEUE.CNT + 1;
1013
                                                                DBG_CMD := DBG_EXEC3;
1014
                                                        end if;
1015
                                                end if;
1016
                                        when DBG_EXEC3 =>
1017
                                                if (OCD.SINGLESTEP='1') then DBG_CMD := DBG_EXEC2; else
1018
                                                        DBG_CMD := DBG_WAIT_CMD;
1019
                                                        CAN_FETCH:='0';
1020
                                                        IQUEUE.FETCH_STATE := F_ADDR;
1021
                                                end if;
1022
                                        when others =>
1023
                                end case;
1024
                                -- This is the end of the debugger code         
1025
 
1026
                                -- This is the main instruction decoder
1027
                                case CPU_STATE IS
1028
                                when CPU_DECOD =>
1029
                                        TEMP_OP := ALU_LD;                                      -- default ALU operation is load
1030
                                        LU_INSTRUCTION := '0';                           -- default is ALU operation (instead of LU2)
1031
                                        WORD_DATA := '0';                                        -- default is 8-bit operation
1032
                                        INTVECT := x"00";                                       -- default vector is 0x00
1033
                                        NUM_BYTES := 0;                                          -- default instruction length is 0 bytes
1034
                                        if (ATM_COUNTER/=3) then ATM_COUNTER := ATM_COUNTER+1;
1035
                                        else    -- interrupt processing *****************************************************************************
1036
                                                if (IRQE='1') then      -- if interrupts are enabled
1037
                                                        -- first the highest priority interrupts
1038
                                                        if ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='1') then
1039
                                                                INTVECT:=x"08";
1040
                                                                IRQ0(7):='0';
1041
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='1') and IRQ0ENL(6)='1') then
1042
                                                                INTVECT:=x"0A";
1043
                                                                IRQ0(6):='0';
1044
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='1') and IRQ0ENL(5)='1') then
1045
                                                                INTVECT:=x"0C";
1046
                                                                IRQ0(5):='0';
1047
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='1') and IRQ0ENL(4)='1') then
1048
                                                                INTVECT:=x"0E";
1049
                                                                IRQ0(4):='0';
1050
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='1') and IRQ0ENL(3)='1') then
1051
                                                                INTVECT:=x"10";
1052
                                                                IRQ0(3):='0';
1053
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='1') and IRQ0ENL(2)='1') then
1054
                                                                INTVECT:=x"12";
1055
                                                                IRQ0(2):='0';
1056
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='1') and IRQ0ENL(1)='1') then
1057
                                                                INTVECT:=x"14";
1058
                                                                IRQ0(1):='0';
1059
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='1') and IRQ0ENL(0)='1') then
1060
                                                                INTVECT:=x"16";
1061
                                                                IRQ0(0):='0';
1062
                                                        -- now priority level 2 interrupts
1063
                                                        elsif ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='0') then
1064
                                                                INTVECT:=x"08";
1065
                                                                IRQ0(7):='0';
1066
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='1') and IRQ0ENL(6)='0') then
1067
                                                                INTVECT:=x"0A";
1068
                                                                IRQ0(6):='0';
1069
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='1') and IRQ0ENL(5)='0') then
1070
                                                                INTVECT:=x"0C";
1071
                                                                IRQ0(5):='0';
1072
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='1') and IRQ0ENL(4)='0') then
1073
                                                                INTVECT:=x"0E";
1074
                                                                IRQ0(4):='0';
1075
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='1') and IRQ0ENL(3)='0') then
1076
                                                                INTVECT:=x"10";
1077
                                                                IRQ0(3):='0';
1078
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='1') and IRQ0ENL(2)='0') then
1079
                                                                INTVECT:=x"12";
1080
                                                                IRQ0(2):='0';
1081
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='1') and IRQ0ENL(1)='0') then
1082
                                                                INTVECT:=x"14";
1083
                                                                IRQ0(1):='0';
1084
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='1') and IRQ0ENL(0)='0') then
1085
                                                                INTVECT:=x"16";
1086
                                                                IRQ0(0):='0';
1087
                                                        -- now priority level 1 interrupts
1088
                                                        elsif ((IRQ0(7)='1') and (IRQ0ENH(7)='0') and IRQ0ENL(7)='1') then
1089
                                                                INTVECT:=x"08";
1090
                                                                IRQ0(7):='0';
1091
                                                        elsif ((IRQ0(6)='1') and (IRQ0ENH(6)='0') and IRQ0ENL(6)='1') then
1092
                                                                INTVECT:=x"0A";
1093
                                                                IRQ0(6):='0';
1094
                                                        elsif ((IRQ0(5)='1') and (IRQ0ENH(5)='0') and IRQ0ENL(5)='1') then
1095
                                                                INTVECT:=x"0C";
1096
                                                                IRQ0(5):='0';
1097
                                                        elsif ((IRQ0(4)='1') and (IRQ0ENH(4)='0') and IRQ0ENL(4)='1') then
1098
                                                                INTVECT:=x"0E";
1099
                                                                IRQ0(4):='0';
1100
                                                        elsif ((IRQ0(3)='1') and (IRQ0ENH(3)='0') and IRQ0ENL(3)='1') then
1101
                                                                INTVECT:=x"10";
1102
                                                                IRQ0(3):='0';
1103
                                                        elsif ((IRQ0(2)='1') and (IRQ0ENH(2)='0') and IRQ0ENL(2)='1') then
1104
                                                                INTVECT:=x"12";
1105
                                                                IRQ0(2):='0';
1106
                                                        elsif ((IRQ0(1)='1') and (IRQ0ENH(1)='0') and IRQ0ENL(1)='1') then
1107
                                                                INTVECT:=x"14";
1108
                                                                IRQ0(1):='0';
1109
                                                        elsif ((IRQ0(0)='1') and (IRQ0ENH(0)='0') and IRQ0ENL(0)='1') then
1110
                                                                INTVECT:=x"16";
1111
                                                                IRQ0(0):='0';
1112
                                                        end if;
1113
                                                        if (INTVECT/=x"00") then
1114
                                                                DEST_ADDR16 := PC;
1115
                                                                IAB <= x"00"&INTVECT;   -- build the address of the interrupt vector
1116
                                                                SP := SP - 1;                   -- prepare stack pointer by decrementing it
1117
                                                                MAB <= SP;                              -- put SP on MAB
1118
                                                                CAN_FETCH := '0';                -- disable instruction fetching
1119
                                                                IQUEUE.CNT := 0;         -- empty instruction queue
1120
                                                                STOP <= '0';                     -- disable stop bit
1121
                                                                LU_INSTRUCTION := '1';  -- the stacking uses this bit to flag it is an interrupt stacking operation
1122
                                                                CPU_STATE := CPU_STACK;
1123
                                                        end if;
1124
                                                end if;
1125
                                        end if;
1126
 
1127
                                        if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then
1128
                                                ------------------------------------------------------------------------------------------------------------------------------
1129
                                                --**************************************************************************************************************************--
1130
                                                --                                                     5-byte instructions                                                  --
1131
                                                --**************************************************************************************************************************--
1132
                                                ------------------------------------------------------------------------------------------------------------------------------
1133
                                                if (IQUEUE.CNT>=5) then
1134
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
1135
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
1136
                                                                ---------------------------------------------------------------------------------------------- CPC ER2,ER1 instruction
1137
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A8") then
1138
                                                                        MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
1139
                                                                        DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4));
1140
                                                                        TEMP_OP := ALU_CPC;
1141
                                                                        NUM_BYTES := 5;
1142
                                                                        CPU_STATE := CPU_TMA;
1143
                                                                ---------------------------------------------------------------------------------------------- CPC IMM,ER1 instruction
1144
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A9") then
1145
                                                                        MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
1146
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1147
                                                                        TEMP_OP := ALU_CPC;
1148
                                                                        NUM_BYTES := 5;
1149
                                                                        CPU_STATE := CPU_OMA;
1150
                                                                --------------------------------------------------------------------------------------------- LDWX ER1,ER2 instruction
1151
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"E8") then
1152
                                                                        MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4));
1153
                                                                        DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4));
1154
                                                                        NUM_BYTES := 5;
1155
                                                                        CPU_STATE := CPU_LDW;
1156
                                                                end if;
1157
                                                        end if;
1158
                                                end if;
1159
 
1160
                                                ------------------------------------------------------------------------------------------------------------------------------
1161
                                                --**************************************************************************************************************************--
1162
                                                --                                                     4-byte instructions                                                  --
1163
                                                --**************************************************************************************************************************--
1164
                                                ------------------------------------------------------------------------------------------------------------------------------
1165
                                                if (IQUEUE.CNT>=4) then
1166
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then    ------------------------------------------------ column 9 instructions
1167
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1168
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX rr1,r2,X instruction
1169
                                                                        when x"9" =>    ------------------------------------------------------------------------ LEA rr1,rr2,X instruction
1170
                                                                        when x"C" =>
1171
                                                                                CPU_STATE := CPU_ILLEGAL;
1172
                                                                        when x"D" =>
1173
                                                                                CPU_STATE := CPU_ILLEGAL;
1174
                                                                        when x"F" =>
1175
                                                                                CPU_STATE := CPU_ILLEGAL;
1176
                                                                        when others =>  -------------------------------------------------------------- IM,ER1 addressing mode instructions
1177
                                                                                MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3));
1178
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1179
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1180
                                                                                NUM_BYTES := 4;
1181
                                                                                CPU_STATE := CPU_OMA;
1182
                                                                end case;
1183
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions
1184
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1185
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX r1,rr2,X instruction
1186
                                                                        when x"9" =>    -------------------------------------------------------------------------- LEA r1,r2,X instruction
1187
                                                                        when x"C" =>    -------------------------------------------------------------------------------- PUSHX instruction
1188
                                                                        when x"D" =>    --------------------------------------------------------------------------------- POPX instruction
1189
                                                                        when x"F" =>
1190
                                                                                CPU_STATE := CPU_ILLEGAL;
1191
                                                                        when others =>  ------------------------------------------------------------- ER2,ER1 addressing mode instructions
1192
                                                                                MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+1)) & IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
1193
                                                                                DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3));
1194
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1195
                                                                                NUM_BYTES := 4;
1196
                                                                                CPU_STATE := CPU_TMA;
1197
                                                                end case;
1198
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
1199
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
1200
                                                                ------------------------------------------------------------------------------------------------ CPC R2,R1 instruction
1201
                                                                TEMP_OP := ALU_CPC;
1202
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A4") then
1203
                                                                        MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3));
1204
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
1205
                                                                        NUM_BYTES := 4;
1206
                                                                        CPU_STATE := CPU_TMA;
1207
                                                                ----------------------------------------------------------------------------------------------- CPC IR2,R1 instruction
1208
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A5") then
1209
                                                                        DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3));
1210
                                                                        MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1211
                                                                        NUM_BYTES := 4;
1212
                                                                        CPU_STATE := CPU_ISMD1;
1213
                                                                ----------------------------------------------------------------------------------------------- CPC R1,IMM instruction
1214
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A6") then
1215
                                                                        MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
1216
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3);
1217
                                                                        NUM_BYTES := 4;
1218
                                                                        CPU_STATE := CPU_OMA;
1219
                                                                ---------------------------------------------------------------------------------------------- CPC IR1,IMM instruction
1220
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A7") then
1221
                                                                        MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1222
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3);
1223
                                                                        NUM_BYTES := 4;
1224
                                                                        CPU_STATE := CPU_IND1;
1225
                                                                end if;
1226
                                                        end if;
1227
                                                end if;
1228
 
1229
                                                ------------------------------------------------------------------------------------------------------------------------------
1230
                                                --**************************************************************************************************************************--
1231
                                                --                                                     3-byte instructions                                                  --
1232
                                                --**************************************************************************************************************************--
1233
                                                ------------------------------------------------------------------------------------------------------------------------------
1234
                                                if (IQUEUE.CNT>=3) then
1235
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"D") then    -------------------------------------------------- JP cc,DirectAddress
1236
                                                                if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then
1237
                                                                        PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1238
                                                                        IQUEUE.FETCH_STATE := F_ADDR;
1239
                                                                else
1240
                                                                        NUM_BYTES := 3;
1241
                                                                end if;
1242
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then -------------------------------------------- column 9 instructions
1243
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then   ----------------------------------------- LDX rr1,r2,X instruction
1244
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1245
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1246
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
1247
                                                                        NUM_BYTES := 3;
1248
                                                                        CPU_STATE := CPU_XRRD;
1249
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then        ------------------------------------ LEA rr1,rr2,X instruction
1250
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1251
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1252
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1253
                                                                        NUM_BYTES := 3;
1254
                                                                        CPU_STATE := CPU_XRRTORR;
1255
                                                                end if;
1256
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions
1257
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then   ----------------------------------------- LDX r1,rr2,X instruction
1258
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1259
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1260
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
1261
                                                                        NUM_BYTES := 3;
1262
                                                                        CPU_STATE := CPU_XRRS;
1263
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then        -------------------------------------- LEA r1,r2,X instruction
1264
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1265
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1266
                                                                        RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1267
                                                                        NUM_BYTES := 3;
1268
                                                                        CPU_STATE := CPU_XRTOM;
1269
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"C") then        ---------------------------------------- PUSHX ER2 instruction
1270
                                                                        SP := SP - 1;
1271
                                                                        MAB <= ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
1272
                                                                        DEST_ADDR := SP;
1273
                                                                        NUM_BYTES := 3;
1274
                                                                        CPU_STATE := CPU_TMA;
1275
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"D") then        ----------------------------------------- POPX ER2 instruction
1276
                                                                        MAB <= SP;
1277
                                                                        DEST_ADDR := ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));
1278
                                                                        SP := SP + 1;
1279
                                                                        NUM_BYTES := 3;
1280
                                                                        CPU_STATE := CPU_TMA;
1281
                                                                end if;
1282
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"7") then -------------------------------------------- column 7 instructions
1283
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1284
                                                                        when x"8" =>    ------------------------------------------------------------------------- LDX IRR2,IR1 instruction
1285
                                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1286
                                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1287
                                                                                NUM_BYTES := 3;
1288
                                                                                CPU_STATE := CPU_IRRS;
1289
                                                                        when x"9" =>    ------------------------------------------------------------------------- LDX IR2,IRR1 instruction
1290
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1291
                                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1292
                                                                                NUM_BYTES := 3;
1293
                                                                                CPU_STATE := CPU_IMTOIRR;
1294
                                                                        when x"C" =>    --------------------------------------------------------------------------- LD r1,r2,X instruction
1295
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1296
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1297
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                                                                                 -- RESULT = offset (X)
1298
                                                                                NUM_BYTES := 3;
1299
                                                                                CPU_STATE := CPU_XADTOM;
1300
                                                                        when x"D" =>    --------------------------------------------------------------------------- LD r2,r1,X instruction
1301
                                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
1302
                                                                                DEST_ADDR := RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
1303
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1304
                                                                                NUM_BYTES := 3;
1305
                                                                                CPU_STATE := CPU_MTOXAD;
1306
                                                                        when x"F" =>    ------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction
1307
                                                                        when others =>  ----------------------------------------------------------------------------- IR1,imm instructions
1308
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1309
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1310
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1311
                                                                                NUM_BYTES := 3;
1312
                                                                                CPU_STATE := CPU_IND1;
1313
                                                                end case;
1314
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"6") then -------------------------------------------- column 6 instructions
1315
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1316
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDX IRR2,R1 instruction
1317
                                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1318
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
1319
                                                                                NUM_BYTES := 3;
1320
                                                                                LU_INSTRUCTION := '1';  -- in this mode this flag is used to signal the direct register addressing mode
1321
                                                                                CPU_STATE := CPU_IRRS;
1322
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDX R2,IRR1 instruction
1323
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1324
                                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1325
                                                                                NUM_BYTES := 3;
1326
                                                                                CPU_STATE := CPU_MTOIRR;
1327
                                                                        when x"C" =>    -- illegal, decoded at 1-byte decoder
1328
                                                                                --CPU_STATE := CPU_ILLEGAL;     -- uncommenting this adds +400 LEs to the design!!!
1329
                                                                        when x"D" =>    ------------------------------------------------------------------------------ CALL DA instruction
1330
                                                                        when x"F" =>    ------------------------------------------------------------------------- BTJ p,b,r1,X instruction
1331
                                                                        when others =>  ------------------------------------------------------------------------------ R1,imm instructions
1332
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1333
                                                                                TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1334
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1335
                                                                                NUM_BYTES := 3;
1336
                                                                                CPU_STATE := CPU_OMA;
1337
                                                                end case;
1338
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"5") then -------------------------------------------- column 5 instructions
1339
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1340
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDX Ir1,ER2 instruction
1341
                                                                                MAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1342
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                      -- dest address
1343
                                                                                NUM_BYTES := 3;
1344
                                                                                CPU_STATE := CPU_IND2;
1345
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDX Ir2,ER1 instruction
1346
                                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
1347
                                                                                DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1348
                                                                                NUM_BYTES := 3;
1349
                                                                                CPU_STATE := CPU_ISMD1;
1350
                                                                        when x"C" =>    ------------------------------------------------------------------------- LDC Ir1,Irr2 instruction
1351
                                                                        when x"D" =>    ----------------------------------------------------------------------------- BSWAP R1 instruction
1352
                                                                        when x"F" =>    ---------------------------------------------------------------------------- LD R2,IR1 instruction
1353
                                                                        when others =>  ------------------------------------------------------------------------------ IR2,R1 instructions
1354
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
1355
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1356
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1357
                                                                                NUM_BYTES := 3;
1358
                                                                                CPU_STATE := CPU_ISMD1;
1359
                                                                end case;
1360
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"4") then -------------------------------------------- column 4 instructions
1361
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1362
                                                                        when x"8" =>    --------------------------------------------------------------------------- LDX r1,ER2 instruction
1363
                                                                                MAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1364
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                      -- dest address
1365
                                                                                NUM_BYTES := 3;
1366
                                                                                CPU_STATE := CPU_TMA;
1367
                                                                        when x"9" =>    --------------------------------------------------------------------------- LDX r2,ER1 instruction
1368
                                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);
1369
                                                                                DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1370
                                                                                NUM_BYTES := 3;
1371
                                                                                CPU_STATE := CPU_TMA;
1372
                                                                        when x"C" =>    ------------------------------------------------------------------------------ JP Irr1 instruction
1373
                                                                        when x"D" =>    ---------------------------------------------------------------------------- CALL Irr1 instruction
1374
                                                                        when x"F" =>    ----------------------------------------------------------------------------- MULT RR1 instruction
1375
                                                                        when others =>  ------------------------------------------------------------------------------- R2,R1 instructions
1376
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1377
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
1378
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1379
                                                                                NUM_BYTES := 3;
1380
                                                                                CPU_STATE := CPU_TMA;
1381
                                                                end case;
1382
                                                        end if;
1383
                                                        ------------------------------------------------------------------------------------------------- BTJ p,b,r1,X instruction
1384
                                                        ------------------------------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction
1385
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F6" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F7") then
1386
                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1387
                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);    -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0)
1388
                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                 -- RESULT has the offset X
1389
                                                                NUM_BYTES := 3;
1390
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS)(0)='0') then CPU_STATE := CPU_BTJ; else CPU_STATE := CPU_IBTJ;
1391
                                                                end if;
1392
                                                        ---------------------------------------------------------------------------------------------------- LD R2,IR1 instruction
1393
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F5") then
1394
                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1395
                                                                DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1396
                                                                NUM_BYTES := 3;
1397
                                                                CPU_STATE := CPU_IND2;
1398
                                                        ------------------------------------------------------------------------------------------------------ CALL DA instruction
1399
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D6") then
1400
                                                                DEST_ADDR16 := PC + 3;
1401
                                                                PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1402
                                                                SP := SP - 1;
1403
                                                                MAB <= SP;
1404
                                                                LU_INSTRUCTION := '0';   -- this is used to indicate wether the stacking is due to a CALL or INT, 0 for a CALL
1405
                                                                IQUEUE.FETCH_STATE := F_ADDR;
1406
                                                                CPU_STATE := CPU_STACK;
1407
                                                        ---------------------------------------------------------------------------------------------------- 2nd page instructions
1408
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then
1409
                                                                -------------------------------------------------------------------------------------------------- PUSH IM instruction
1410
                                                                if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"70") then
1411
                                                                        SP := SP - 1;
1412
                                                                        MAB <= SP;
1413
                                                                        TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1414
                                                                        NUM_BYTES := 3;
1415
                                                                        CPU_STATE := CPU_OMA;
1416
                                                                ------------------------------------------------------------------------------------------------ CPC r1,r2 instruction
1417
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A2") then
1418
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0));                                                     -- source address                               
1419
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));                                              -- dest address
1420
                                                                        TEMP_OP := ALU_CPC;
1421
                                                                        NUM_BYTES := 3;
1422
                                                                        CPU_STATE := CPU_TMA;
1423
                                                                ----------------------------------------------------------------------------------------------- CPC r1,Ir2 instruction
1424
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A3") then
1425
                                                                        MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0));                                                     -- source address                               
1426
                                                                        DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4));                                              -- dest address
1427
                                                                        TEMP_OP := ALU_CPC;
1428
                                                                        NUM_BYTES := 3;
1429
                                                                        CPU_STATE := CPU_ISMD1;
1430
                                                                --------------------------------------------------------------------------------------------------- SRL R1 instruction
1431
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C0") then
1432
                                                                        MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2));
1433
                                                                        TEMP_OP := LU2_SRL;
1434
                                                                        NUM_BYTES := 3;
1435
                                                                        CPU_STATE := CPU_OMA2;
1436
                                                                -------------------------------------------------------------------------------------------------- SRL IR1 instruction
1437
                                                                elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C1") then
1438
                                                                        MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2);
1439
                                                                        TEMP_OP := LU2_SRL;
1440
                                                                        NUM_BYTES := 3;
1441
                                                                        CPU_STATE := CPU_IND1;
1442
                                                                        LU_INSTRUCTION := '1';
1443
                                                                end if;
1444
                                                        end if;
1445
                                                end if;
1446
 
1447
                                                ------------------------------------------------------------------------------------------------------------------------------
1448
                                                --**************************************************************************************************************************--
1449
                                                --                                                     2-byte instructions                                                  --
1450
                                                --**************************************************************************************************************************--
1451
                                                ------------------------------------------------------------------------------------------------------------------------------
1452
                                                if (IQUEUE.CNT>=2) then
1453
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"C") then    ------------------------------------------------- LD r,IMM instruction
1454
                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1455
                                                                DATAWRITE(RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4),IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1456
                                                                NUM_BYTES := 2;
1457
                                                                CPU_STATE := CPU_STORE;
1458
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"B") then -------------------------------------------- JR cc,RelativeAddress
1459
                                                                PC := PC + 2;
1460
                                                                if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then
1461
                                                                        PC := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1462
                                                                        IQUEUE.FETCH_STATE := F_ADDR;
1463
                                                                else
1464
                                                                        IQUEUE.RDPOS := IQUEUE.RDPOS + 2;
1465
                                                                        IQUEUE.CNT := IQUEUE.CNT - 2;
1466
                                                                end if;
1467
                                                                CPU_STATE := CPU_DECOD;
1468
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"A") then ------------------------------------------- DJNZ r,RelativeAddress
1469
                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1470
                                                                PC := PC + 2;
1471
                                                                DEST_ADDR16 := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1472
                                                                IQUEUE.RDPOS := IQUEUE.RDPOS + 2;
1473
                                                                IQUEUE.CNT := IQUEUE.CNT - 2;
1474
                                                                IQUEUE.FETCH_STATE := F_ADDR;
1475
                                                                CPU_STATE := CPU_DJNZ;
1476
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"3") then -------------------------------------------- column 3 instructions
1477
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1478
                                                                        when x"8" =>    ------------------------------------------------------------------------ LDEI Ir1,Irr2 instruction
1479
                                                                        when x"9" =>    ------------------------------------------------------------------------ LDEI Ir2,Irr1 instruction
1480
                                                                        when x"C" =>    ------------------------------------------------------------------------ LDCI Ir1,Irr2 instruction
1481
                                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
1482
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
1483
                                                                                NUM_BYTES := 2;
1484
                                                                                CAN_FETCH := '0';
1485
                                                                                LU_INSTRUCTION := '0';   -- indicates it is a read from program memory
1486
                                                                                WORD_DATA := '1';               -- indicates it is a LDCI instruction
1487
                                                                                CPU_STATE := CPU_LDPTOIM;
1488
                                                                        when x"D" =>    ------------------------------------------------------------------------ LDCI Ir2,Irr1 instruction
1489
                                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
1490
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
1491
                                                                                NUM_BYTES := 2;
1492
                                                                                CAN_FETCH := '0';
1493
                                                                                LU_INSTRUCTION := '1';  -- indicates it is a write onto program memory
1494
                                                                                WORD_DATA := '1';               -- indicates it is a LDCI instruction
1495
                                                                                CPU_STATE := CPU_LDPTOIM;
1496
                                                                        when x"F" =>    ---------------------------------------------------------------------------- LD Ir1,r2 instruction
1497
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
1498
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
1499
                                                                                NUM_BYTES := 2;
1500
                                                                                CPU_STATE := CPU_IND2;
1501
                                                                        when others =>  --------------------------------------------------------------------------- Ir2 to r1 instructions
1502
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1503
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1504
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1505
                                                                                NUM_BYTES := 2;
1506
                                                                                CPU_STATE := CPU_ISMD1;
1507
                                                                end case;
1508
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"2") then -------------------------------------------- column 2 instructions
1509
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1510
                                                                        when x"8" =>    -------------------------------------------------------------------------- LDE r1,Irr2 instruction
1511
                                                                        when x"9" =>    -------------------------------------------------------------------------- LDE r2,Irr1 instruction
1512
                                                                        when x"C" =>    -------------------------------------------------------------------------- LDC r1,Irr2 instruction
1513
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
1514
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
1515
                                                                                NUM_BYTES := 2;
1516
                                                                                CAN_FETCH := '0';
1517
                                                                                LU_INSTRUCTION := '0';
1518
                                                                                CPU_STATE := CPU_LDPTOM;
1519
                                                                        when x"D" =>    -------------------------------------------------------------------------- LDC r2,Irr1 instruction
1520
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
1521
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
1522
                                                                                NUM_BYTES := 2;
1523
                                                                                CAN_FETCH := '0';
1524
                                                                                LU_INSTRUCTION := '1';
1525
                                                                                CPU_STATE := CPU_LDPTOM;
1526
                                                                        when x"E" =>    --------------------------------------------------------------------------- BIT p,b,r1 instruction
1527
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));
1528
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4);    -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0)
1529
                                                                                RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2);                                 -- RESULT has the offset X
1530
                                                                                NUM_BYTES := 2;
1531
                                                                                CPU_STATE := CPU_BIT;
1532
                                                                        when x"F" =>    ----------------------------------------------------------------------------- TRAP imm instruction
1533
                                                                                MAB <= "000" & IQUEUE.QUEUE(IQUEUE.RDPOS+1) & '0';
1534
                                                                                DEST_ADDR16 := PC + 2;
1535
                                                                                NUM_BYTES := 2;
1536
                                                                                CPU_STATE := CPU_TRAP;
1537
                                                                        when others =>  ---------------------------------------------------------------------------- r2 to r1 instructions
1538
                                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0));                                                     -- source address                               
1539
                                                                                DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));                                              -- dest address
1540
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1541
                                                                                NUM_BYTES := 2;
1542
                                                                                CPU_STATE := CPU_TMA;
1543
                                                                end case;
1544
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"1") then -------------------------------------------- column 1 instructions
1545
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1546
                                                                        when x"0" =>     ------------------------------------------------------------------------------ SRP IMM instruction      
1547
                                                                                RP := IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1548
                                                                                NUM_BYTES := 2;
1549
                                                                                CPU_STATE := CPU_DECOD;
1550
                                                                        when x"5" =>    ------------------------------------------------------------------------------ POP IR1 instruction
1551
                                                                                MAB <= SP;
1552
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1553
                                                                                SP := SP + 1;
1554
                                                                                NUM_BYTES := 2;
1555
                                                                                CPU_STATE := CPU_IND2;
1556
                                                                        when x"7" =>    ----------------------------------------------------------------------------- PUSH IR1 instruction
1557
                                                                                SP := SP - 1;
1558
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1559
                                                                                DEST_ADDR := SP;
1560
                                                                                NUM_BYTES := 2;
1561
                                                                                CPU_STATE := CPU_ISMD1;
1562
                                                                        when x"8" =>    --------------------------------------------------------------------------------- DECW instruction
1563
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1564
                                                                                TEMP_OP := LU2_DEC;
1565
                                                                                WORD_DATA := '1';
1566
                                                                                NUM_BYTES := 2;
1567
                                                                                CPU_STATE := CPU_INDRR;
1568
                                                                        when x"A" =>    --------------------------------------------------------------------------------- INCW instruction
1569
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1570
                                                                                TEMP_OP := LU2_INC;
1571
                                                                                WORD_DATA := '1';
1572
                                                                                NUM_BYTES := 2;
1573
                                                                                CPU_STATE := CPU_INDRR;
1574
                                                                        when others =>  --------------------------------------------------------------------------------- IR1 instructions
1575
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1576
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1577
                                                                                NUM_BYTES := 2;
1578
                                                                                CPU_STATE := CPU_IND1;
1579
                                                                                LU_INSTRUCTION := '1';
1580
                                                                end case;
1581
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"0") then  -------------------------------------------- column 0 instructions
1582
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1583
                                                                        when x"0" =>     ---------------------------------------------------------------------------------- BRK instruction      
1584
                                                                                -- do nothing, BRK decoding is done in 1-byte instruction section
1585
                                                                        when x"5" =>    ---------------------------------------------------------------------------------- POP instruction
1586
                                                                                MAB <= SP;
1587
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1588
                                                                                SP := SP + 1;
1589
                                                                                NUM_BYTES := 2;
1590
                                                                                CPU_STATE := CPU_TMA;
1591
                                                                        when x"7" =>    --------------------------------------------------------------------------------- PUSH instruction
1592
                                                                                SP := SP - 1;
1593
                                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1594
                                                                                DEST_ADDR := SP;
1595
                                                                                NUM_BYTES := 2;
1596
                                                                                CPU_STATE := CPU_TMA;
1597
                                                                        when x"8" =>    --------------------------------------------------------------------------------- DECW instruction
1598
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1599
                                                                                MAB <= DEST_ADDR+1;
1600
                                                                                TEMP_OP := LU2_DEC;
1601
                                                                                WORD_DATA := '1';
1602
                                                                                NUM_BYTES := 2;
1603
                                                                                CPU_STATE := CPU_OMA2;
1604
                                                                        when x"A" =>    --------------------------------------------------------------------------------- INCW instruction
1605
                                                                                DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1606
                                                                                MAB <= DEST_ADDR+1;
1607
                                                                                TEMP_OP := LU2_INC;
1608
                                                                                WORD_DATA := '1';
1609
                                                                                NUM_BYTES := 2;
1610
                                                                                CPU_STATE := CPU_OMA2;
1611
                                                                        when others =>  ---------------------------------------------------------------------------------- R1 instructions
1612
                                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1613
                                                                                TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1614
                                                                                NUM_BYTES := 2;
1615
                                                                                CPU_STATE := CPU_OMA2;
1616
                                                                end case;
1617
                                                        end if;
1618
                                                        ---------------------------------------------------------------------------------------------------------- MUL instruction 
1619
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F4") then
1620
                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1621
                                                                NUM_BYTES := 2;
1622
                                                                CPU_STATE := CPU_MUL;
1623
                                                        ---------------------------------------------------------------------------------------------------- CALL IRR1 instruction
1624
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D4") then
1625
                                                                DEST_ADDR16 := PC + 2;
1626
                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1627
                                                                IQUEUE.FETCH_STATE := F_ADDR;
1628
                                                                CPU_STATE := CPU_INDSTACK;
1629
                                                        ------------------------------------------------------------------------------------------------------ JP IRR1 instruction
1630
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C4") then
1631
                                                                MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1);
1632
                                                                IQUEUE.FETCH_STATE := F_ADDR;
1633
                                                                CPU_STATE := CPU_INDJUMP;
1634
                                                        ----------------------------------------------------------------------------------------------------- BSWAP R1 instruction
1635
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D5") then
1636
                                                                MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1));
1637
                                                                TEMP_OP := ALU_BSWAP;
1638
                                                                NUM_BYTES := 2;
1639
                                                                CPU_STATE := CPU_OMA;
1640
                                                        ------------------------------------------------------------------------------------------------- LDC Ir1,Irr2 instruction
1641
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C5") then
1642
                                                                RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0);
1643
                                                                MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4));
1644
                                                                NUM_BYTES := 2;
1645
                                                                CAN_FETCH := '0';
1646
                                                                LU_INSTRUCTION := '0';
1647
                                                                CPU_STATE := CPU_LDPTOIM;
1648
                                                        end if;
1649
                                                end if;
1650
 
1651
                                                ------------------------------------------------------------------------------------------------------------------------------
1652
                                                --**************************************************************************************************************************--
1653
                                                --                                                     1-byte instructions                                                  --
1654
                                                --**************************************************************************************************************************--
1655
                                                ------------------------------------------------------------------------------------------------------------------------------
1656
                                                if (IQUEUE.CNT>=1) then
1657
                                                        if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"F") then    ------------------------------------------------ column F instructions
1658
                                                                case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is
1659
                                                                        when x"0" =>     ---------------------------------------------------------------------------------- NOP instruction      
1660
                                                                                NUM_BYTES := 1;
1661
                                                                        when x"1" =>    ------------------------------------------------------------------------------ page 2 instructions
1662
                                                                        when x"2" =>
1663
                                                                                ATM_COUNTER := 0;
1664
                                                                                NUM_BYTES := 1;
1665
                                                                        when x"3" =>
1666
                                                                                CPU_STATE := CPU_ILLEGAL;
1667
                                                                        when x"4" =>
1668
                                                                                CPU_STATE := CPU_ILLEGAL;
1669
                                                                        when x"5" =>    ---------------------------------------------------------------------------------- WDT instruction
1670
                                                                                NUM_BYTES := 1;
1671
                                                                        when x"6" =>    --------------------------------------------------------------------------------- STOP instruction
1672
                                                                                NUM_BYTES := 1;
1673
                                                                                CPU_STATE := CPU_HALTED;
1674
                                                                                STOP <= '1';
1675
                                                                        when x"7" =>    --------------------------------------------------------------------------------- HALT instruction
1676
                                                                                NUM_BYTES := 1;
1677
                                                                                CPU_STATE := CPU_HALTED;
1678
                                                                        when x"8" =>    ----------------------------------------------------------------------------------- DI instruction
1679
                                                                                IRQE := '0';
1680
                                                                                NUM_BYTES := 1;
1681
                                                                        when x"9" =>    ----------------------------------------------------------------------------------- EI instruction
1682
                                                                                IRQE := '1';
1683
                                                                                NUM_BYTES := 1;
1684
                                                                        when x"A" =>    ---------------------------------------------------------------------------------- RET instruction
1685
                                                                                NUM_BYTES := 1;
1686
                                                                                MAB <= SP;
1687
                                                                                CPU_STATE := CPU_UNSTACK;
1688
                                                                        when x"B" =>    --------------------------------------------------------------------------------- IRET instruction
1689
                                                                                NUM_BYTES := 1;
1690
                                                                                IRQE := '1';
1691
                                                                                MAB <= SP;
1692
                                                                                CPU_STATE := CPU_UNSTACK3;
1693
                                                                        when x"C" =>    ---------------------------------------------------------------------------------- RCF instruction
1694
                                                                                CPU_FLAGS.C := '0';
1695
                                                                                NUM_BYTES := 1;
1696
                                                                        when x"D" =>    ---------------------------------------------------------------------------------- SCF instruction
1697
                                                                                CPU_FLAGS.C := '1';
1698
                                                                                NUM_BYTES := 1;
1699
                                                                        when x"E" =>    ---------------------------------------------------------------------------------- CCF instruction
1700
                                                                                CPU_FLAGS.C := not CPU_FLAGS.C;
1701
                                                                                NUM_BYTES := 1;
1702
                                                                        when others =>  ---------------------------------------------------------------------------------- R1 instructions
1703
                                                                                CPU_STATE := CPU_ILLEGAL;
1704
                                                                end case;
1705
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"E") then ------------------------------------------------ INC r instruction
1706
                                                                MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4);
1707
                                                                TEMP_OP := LU2_INC;
1708
                                                                NUM_BYTES := 1;
1709
                                                                CPU_STATE := CPU_OMA2;
1710
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"00") then   -------------------------------------------------------------- BRK instruction
1711
                                                                if (OCDCR.BRKEN='1') then               -- the BRK instruction is enabled
1712
                                                                        if (OCDCR.DBGACK='1') then
1713
                                                                                if (DBG_UART.TX_EMPTY='1') then
1714
                                                                                        DBG_UART.TX_DATA:=x"FF";
1715
                                                                                        DBG_UART.TX_EMPTY:='0';
1716
                                                                                end if;
1717
                                                                        end if;
1718
                                                                        if (OCDCR.BRKLOOP='0') then      -- if loop on BRK is disabled
1719
                                                                                OCDCR.DBGMODE := '1';   -- set DBGMODE halting CPU
1720
                                                                        end if;
1721
                                                                else
1722
                                                                        NUM_BYTES := 1;                 -- remove the instruction from queue (execute as a NOP)
1723
                                                                end if;
1724
                                                        elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F9" or
1725
                                                                        IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F8" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C6") then      --------------------------- illegal opcode
1726
                                                                CPU_STATE:= CPU_ILLEGAL;
1727
                                                                NUM_BYTES := 1;
1728
                                                        end if;
1729
                                                end if;
1730
                                        end if;
1731
                                        PC := PC + NUM_BYTES;
1732
                                        IQUEUE.RDPOS := IQUEUE.RDPOS + NUM_BYTES;
1733
                                        IQUEUE.CNT := IQUEUE.CNT - NUM_BYTES;
1734
                                        if (OCD.SINGLESTEP='1') then
1735
                                                if (NUM_BYTES/=0 or IQUEUE.FETCH_STATE=F_ADDR) then OCD.SINGLESTEP:='0';
1736
                                                end if;
1737
                                        end if;
1738
                                when CPU_MUL => -- MUL ***********************************************************************************************************
1739
                                        TEMP_DATA := DATAREAD(MAB);             -- read first operand
1740
                                        MAB <= MAB + 1;                                 -- go to the next operand 
1741
                                        CPU_STATE := CPU_MUL1;
1742
                                when CPU_MUL1 =>
1743
                                        DEST_ADDR16 := TEMP_DATA * DATAREAD(MAB);       -- multiply previous operand by the second operand and store temporarily
1744
                                        DATAWRITE(MAB,DEST_ADDR16(7 downto 0));          -- write the lower byte in current memory address 
1745
                                        WR <= '1';
1746
                                        CPU_STATE := CPU_MUL2;
1747
                                when CPU_MUL2 =>
1748
                                        MAB <= MAB - 1;                                                         -- decrement memory address (point to the first operand)
1749
                                        DATAWRITE(MAB,DEST_ADDR16(15 downto 8));        -- write the higher byte
1750
                                        CPU_STATE := CPU_STORE;                                         -- complete store operation
1751
                                when CPU_XRRTORR =>     -- LEA *******************************************************************************************************
1752
                                        TEMP_DATA := DATAREAD(MAB);                                     -- read the operand and store it
1753
                                        MAB <= MAB + 1;                                                         -- go to the next memory address
1754
                                        CPU_STATE := CPU_XRRTORR2;
1755
                                when CPU_XRRTORR2 =>
1756
                                        -- read the next operand and perform a 16 bit add with the offset previously in result
1757
                                        DEST_ADDR16 := ADDER16(TEMP_DATA & DATAREAD(MAB),RESULT);
1758
                                        MAB <= DEST_ADDR;                                                       -- point to the destination address
1759
                                        DATAWRITE(MAB,DEST_ADDR16(15 downto 8));        -- store the higher byte of the 16-bit result
1760
                                        CPU_STATE := CPU_XRRTORR3;
1761
                                when CPU_XRRTORR3 =>
1762
                                        WR <= '1';
1763
                                        CPU_STATE := CPU_XRRTORR4;
1764
                                when CPU_XRRTORR4 =>
1765
                                        MAB <= MAB + 1;                                                         -- go to the next memory address
1766
                                        DATAWRITE(MAB,DEST_ADDR16(7 downto 0));          -- store the lower byte of the 16-bit result
1767
                                        CPU_STATE := CPU_STORE;                                         -- complete store operation
1768
                                when CPU_MTOXAD =>      -- MEMORY TO INDEXED 8-BIT ADDRESS ***************************************************************************
1769
                                        TEMP_DATA := DATAREAD(MAB);
1770
                                        MAB <= DEST_ADDR;
1771
                                        CPU_STATE := CPU_MTOXAD2;
1772
                                when CPU_MTOXAD2 =>
1773
                                        MAB <= RP(3 downto 0)&(DATAREAD(MAB) + RESULT);
1774
                                        DATAWRITE(MAB,TEMP_DATA);
1775
                                        CPU_STATE := CPU_STORE;
1776
                                when CPU_XADTOM =>      -- INDEXED 8-BIT ADDRESS TO MEMORY ***************************************************************************
1777
                                        MAB <= RP(3 downto 0)&(DATAREAD(MAB) + RESULT);
1778
                                        CPU_STATE := CPU_TMA;
1779
                                when CPU_XRTOM =>       -- LEA *******************************************************************************************************
1780
                                        TEMP_DATA := DATAREAD(MAB)+RESULT;
1781
                                        MAB <= DEST_ADDR;
1782
                                        DATAWRITE(MAB,TEMP_DATA);
1783
                                        CPU_STATE := CPU_STORE;
1784
                                when CPU_IMTOIRR =>     -- INDIRECT MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ***********************************************
1785
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);   -- source address is read from indirect register
1786
                                        CPU_STATE := CPU_MTOIRR;
1787
                                when CPU_MTOIRR =>      -- MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ********************************************************
1788
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
1789
                                        MAB <= DEST_ADDR;                                               -- MAB points to the indirect destination register pair
1790
                                        RESULT := x"00";
1791
                                        CPU_STATE := CPU_XRRD2;                                 -- proceed as X indexed register pair destination
1792
                                when CPU_IRRS =>        -- RR PAIR AS INDIRECT SOURCE ADDRESS ************************************************************************
1793
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
1794
                                        MAB <= MAB + 1;
1795
                                        CPU_STATE := CPU_IRRS2;
1796
                                when CPU_IRRS2 =>
1797
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
1798
                                        MAB <= DEST_ADDR16(11 downto 0);
1799
                                        if (LU_INSTRUCTION='1') then
1800
                                                CPU_STATE:= CPU_TMA;                            -- if it is direct addressing mode, go to TMA
1801
                                        else
1802
                                                CPU_STATE := CPU_IND2;                          -- if it is indirect addressing mode, go to IND2
1803
                                        end if;
1804
                                when CPU_XRRD =>
1805
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
1806
                                        MAB <= DEST_ADDR;
1807
                                        CPU_STATE := CPU_XRRD2;
1808
                                when CPU_XRRD2 =>
1809
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
1810
                                        MAB <= MAB + 1;
1811
                                        CPU_STATE := CPU_XRRD3;
1812
                                when CPU_XRRD3 =>
1813
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
1814
                                        MAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0);
1815
                                        DATAWRITE(MAB,TEMP_DATA);
1816
                                        CPU_STATE := CPU_STORE;
1817
                                when CPU_XRRS =>
1818
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
1819
                                        MAB <= MAB + 1;
1820
                                        CPU_STATE := CPU_XRRS2;
1821
                                when CPU_XRRS2 =>
1822
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
1823
                                        MAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0);
1824
                                        CPU_STATE := CPU_XRRS3;
1825
                                when CPU_XRRS3 =>
1826
                                        TEMP_DATA := DATAREAD(MAB);
1827
                                        MAB <= DEST_ADDR;
1828
                                        DATAWRITE(MAB,TEMP_DATA);
1829
                                        CPU_STATE := CPU_STORE;
1830
                                when CPU_INDRR =>       -- INDIRECT DESTINATION ADDRESS FOR WORD INSTRUCTIONS (DECW AND INCW) ****************************************
1831
                                        MAB <= (RP(3 downto 0) & DATAREAD(MAB))+1;       -- the destination address is given by indirect address
1832
                                        CPU_STATE := CPU_OMA2;
1833
                                when CPU_ISMD1 =>       -- INDIRECT SOURCE ADDRESS ***********************************************************************************
1834
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);   -- source address is read from indirect register
1835
                                        CPU_STATE := CPU_TMA;
1836
                                when CPU_IND2 =>        -- READS REGISTER AND PERFORM OPERATION ON AN INDIRECT DESTINATION *******************************************
1837
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
1838
                                        MAB <= DEST_ADDR;                                               -- place the address of the indirect register on MAB
1839
                                        CPU_STATE := CPU_IND1;                                  -- proceed to the indirect
1840
                                when CPU_IND1 =>        -- INDIRECT DESTINATION ADDRESS ******************************************************************************
1841
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);   -- the destination address is given by indirect address
1842
                                        if (LU_INSTRUCTION='0') then CPU_STATE := CPU_OMA;                                       -- proceed with one memory access
1843
                                        else CPU_STATE := CPU_OMA2;                                                                                     -- proceed with one memory access (logic unit related)
1844
                                        end if;
1845
                                when CPU_TMA =>         -- TWO MEMORY ACCESS, READS SOURCE OPERAND FROM MEMORY *******************************************************
1846
                                        TEMP_DATA := DATAREAD(MAB);                             -- reads data from the source (MAB) address and store it into TEMP_DATA
1847
                                        MAB <= DEST_ADDR;                                               -- place the destination address (DEST_ADDR) on the memory address bus (MAB)
1848
                                        CPU_STATE := CPU_OMA;                                   -- proceed to the last stage
1849
                                when CPU_OMA =>         -- ONE MEMORY ACCESS stage ***********************************************************************************
1850
                                        -- this stage performs the TEMP_OP operation between TEMP_DATA and data read from current (MAB) address (destination)
1851
                                        RESULT := ALU(TEMP_OP,DATAREAD(MAB),TEMP_DATA,CPU_FLAGS.C);
1852
                                        if (TEMP_OP<ALU_OR) then
1853
                                                CPU_FLAGS.C := ALU_FLAGS.C;
1854
                                                CPU_FLAGS.V := ALU_FLAGS.V;
1855
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1856
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1857
                                                CPU_FLAGS.H := ALU_FLAGS.H;
1858
                                                CPU_FLAGS.D := TEMP_OP(1);
1859
                                        elsif (TEMP_OP=ALU_CP or TEMP_OP=ALU_CPC) then
1860
                                                CPU_FLAGS.C := ALU_FLAGS.C;
1861
                                                CPU_FLAGS.V := ALU_FLAGS.V;
1862
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1863
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1864
                                        elsif (TEMP_OP/=ALU_LD) then
1865
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1866
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1867
                                                CPU_FLAGS.V := '0';
1868
                                        end if;
1869
                                        if (ALU_NOUPDATE='0') then
1870
                                                DATAWRITE(MAB,RESULT);
1871
                                                WR <= '1';
1872
                                        end if;
1873
                                        CPU_STATE := CPU_DECOD;
1874
                                        if (WORD_DATA='1') then
1875
                                                CPU_STATE := CPU_LDW;
1876
                                        end if;
1877
                                when CPU_OMA2 =>        -- ONE MEMORY ACCESS stage logic unit related ****************************************************************
1878
                                        -- this stage performs the TEMP_OP LU2 operation on data read from current (MAB) address
1879
                                        RESULT := LU2(TEMP_OP,DATAREAD(MAB),CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.C);
1880
                                        if (TEMP_OP=LU2_DEC or TEMP_OP=LU2_INC) then
1881
                                                CPU_FLAGS.V := ALU_FLAGS.V;
1882
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1883
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1884
                                        elsif (TEMP_OP=LU2_COM) then
1885
                                                CPU_FLAGS.V := '0';
1886
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1887
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1888
                                        elsif (TEMP_OP=LU2_SWAP) then
1889
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1890
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1891
                                        elsif (TEMP_OP=LU2_DA) then
1892
                                                CPU_FLAGS.C := ALU_FLAGS.C;
1893
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1894
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1895
                                        elsif (TEMP_OP=LU2_LD) then
1896
                                                CPU_FLAGS.V := ALU_FLAGS.V;
1897
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1898
                                                CPU_FLAGS.Z := CPU_FLAGS.Z and ALU_FLAGS.Z;
1899
                                        elsif (TEMP_OP/=LU2_CLR) then
1900
                                                CPU_FLAGS.C := ALU_FLAGS.C;
1901
                                                CPU_FLAGS.V := ALU_FLAGS.V;
1902
                                                CPU_FLAGS.Z := ALU_FLAGS.Z;
1903
                                                CPU_FLAGS.S := ALU_FLAGS.S;
1904
                                        end if;
1905
                                        DATAWRITE(MAB,RESULT);
1906
                                        WR <= '1';
1907
                                        if (WORD_DATA='1') then
1908
                                                WORD_DATA := '0';
1909
                                                if (ALU_FLAGS.C='0') then TEMP_OP := LU2_LD;
1910
                                                end if;
1911
                                                CPU_STATE := CPU_DMAB;
1912
                                        else CPU_STATE := CPU_DECOD;
1913
                                        end if;
1914
                                when CPU_DMAB =>        -- DECREMENT MEMORY ADDRESS BUS *****************************************************************************
1915
                                        MAB <= MAB - 1;
1916
                                        CPU_STATE := CPU_OMA2;
1917
                                when CPU_LDW =>
1918
                                        if (WORD_DATA='0') then
1919
                                                TEMP_DATA := DATAREAD(MAB);
1920
                                                MAB <= MAB + 1;
1921
                                        else
1922
                                                DATAWRITE(MAB,TEMP_DATA);
1923
                                                WR <= '1';
1924
                                        end if;
1925
                                        CPU_STATE := CPU_LDW2;
1926
                                when CPU_LDW2 =>
1927
                                        if (WORD_DATA='0') then
1928
                                                RESULT := DATAREAD(MAB);
1929
                                                MAB <= DEST_ADDR;
1930
                                                WORD_DATA := '1';
1931
                                                CPU_STATE := CPU_LDW;
1932
                                        else
1933
                                                MAB <= MAB + 1;
1934
                                                DATAWRITE(MAB,RESULT);
1935
                                                CPU_STATE := CPU_STORE;
1936
                                        end if;
1937
                                when CPU_LDPTOIM =>     -- LOAD PROGRAM TO INDIRECT MEMORY **************************************************************************
1938
                                        TEMP_DATA := DATAREAD(MAB);
1939
                                        DEST_ADDR := RP(3 downto 0) & TEMP_DATA; -- the destination address is read from the indirect address
1940
                                        if (WORD_DATA='1') then
1941
                                                -- it is a LDCI instruction, so we have to increment the indirect address after the operation
1942
                                                DATAWRITE(MAB,TEMP_DATA+1);
1943
                                                WR <= '1';
1944
                                                CPU_STATE := CPU_LDPTOIM2;
1945
                                        else
1946
                                                -- it is a LDC instruction, proceed the load instruction
1947
                                                MAB <= ADDRESSER4(RESULT(3 downto 0));           -- the source address (program memory) is read from source register pair
1948
                                                CPU_STATE := CPU_LDPTOM;
1949
                                        end if;
1950
                                when CPU_LDPTOIM2 =>
1951
                                        MAB <= ADDRESSER4(RESULT(3 downto 0));           -- the source address (program memory) is read from source register pair
1952
                                        CPU_STATE := CPU_LDPTOM;
1953
                                when CPU_LDPTOM =>      -- LOAD PROGRAM TO MEMORY ***********************************************************************************
1954
                                        IAB(15 downto 8) <= DATAREAD(MAB);      -- read the high address from the first register
1955
                                        MAB <= MAB + 1;
1956
                                        CPU_STATE := CPU_LDPTOM2;
1957
                                when CPU_LDPTOM2 =>
1958
                                        IAB(7 downto 0) <= DATAREAD(MAB);        -- read the low address from the second register
1959
                                        MAB <= DEST_ADDR;
1960
                                        if (LU_INSTRUCTION='0') then
1961
                                                CPU_STATE := CPU_LDPTOM3;               -- if it is a read from program memory
1962
                                        else
1963
                                                CPU_STATE := CPU_LDMTOP;                -- if it is a write onto program memory
1964
                                        end if;
1965
                                when CPU_LDPTOM3 =>     -- READ PROGRAM MEMORY AND STORE INTO RAM *******************************************************************
1966
                                        DATAWRITE(MAB,IDB);
1967
                                        WR <= '1';
1968
                                        CAN_FETCH := '1';       -- re-enable fetching
1969
                                        FETCH_ADDR := PC;
1970
                                        IAB <= PC;
1971
                                        CPU_STATE := CPU_DECOD;
1972
                                        if (WORD_DATA='1') then
1973
                                                CPU_STATE := CPU_LDPTOM4;
1974
                                        end if;
1975
                                when CPU_LDPTOM4 =>
1976
                                        DEST_ADDR := ADDRESSER4(RESULT(3 downto 0));
1977
                                        MAB <= DEST_ADDR+1;
1978
                                        TEMP_OP := LU2_INC;
1979
                                        CPU_STATE := CPU_OMA2;
1980
                                when CPU_LDMTOP =>      -- READ RAM AND STORE ONTO PROGRAM MEMORY *******************************************************************
1981
                                        PWDB <= DATAREAD(MAB);  -- PWDB receive the content of RAM
1982
                                        PGM_WR <= '1';                  -- enable program memory write signal
1983
                                        CPU_STATE := CPU_LDMTOP2;
1984
                                when CPU_LDMTOP2 =>
1985
                                        CAN_FETCH := '1';               -- re-enable instruction fetching
1986
                                        FETCH_ADDR := PC;
1987
                                        IAB <= PC;
1988
                                        CPU_STATE := CPU_DECOD;
1989
                                        if (WORD_DATA='1') then
1990
                                                CPU_STATE := CPU_LDPTOM4;
1991
                                        end if;
1992
                                when CPU_BIT =>
1993
                                        TEMP_DATA := DATAREAD(MAB);
1994
                                        TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0)))):=TEMP_OP(3);
1995
                                        DATAWRITE(MAB,TEMP_DATA);
1996
                                        WR <= '1';
1997
                                        CPU_STATE := CPU_DECOD;
1998
                                when CPU_IBTJ =>
1999
                                        MAB <= RP(3 downto 0) & DATAREAD(MAB);
2000
                                        CPU_STATE := CPU_BTJ;
2001
                                when CPU_BTJ =>
2002
                                        TEMP_DATA := DATAREAD(MAB);
2003
                                        if (TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0))))=TEMP_OP(3)) then
2004
                                                PC := ADDER16(PC,RESULT);
2005
                                                IQUEUE.FETCH_STATE := F_ADDR;
2006
                                        end if;
2007
                                        CPU_STATE := CPU_DECOD;
2008
                                when CPU_DJNZ =>
2009
                                        RESULT := LU2(LU2_DEC,DATAREAD(MAB),'0','0','0');
2010
                                        if (ALU_FLAGS.Z='0') then        -- result is not zero, then jump relative
2011
                                                PC := DEST_ADDR16;
2012
                                                IQUEUE.FETCH_STATE := F_ADDR;
2013
                                        end if;
2014
                                        DATAWRITE(MAB,RESULT);
2015
                                        WR <= '1';
2016
                                        CPU_STATE := CPU_DECOD;
2017
                                when CPU_INDJUMP =>
2018
                                        PC(15 downto 8) := DATAREAD(MAB);
2019
                                        MAB <= MAB + 1;
2020
                                        CPU_STATE:= CPU_INDJUMP2;
2021
                                when CPU_INDJUMP2 =>
2022
                                        PC(7 downto 0) := DATAREAD(MAB);
2023
                                        IQUEUE.FETCH_STATE := F_ADDR;
2024
                                        CPU_STATE := CPU_DECOD;
2025
                                when CPU_TRAP =>
2026
                                        PC(15 downto 8) := DATAREAD(MAB);
2027
                                        MAB <= MAB + 1;
2028
                                        CPU_STATE:= CPU_TRAP2;
2029
                                when CPU_TRAP2 =>
2030
                                        PC(7 downto 0) := DATAREAD(MAB);
2031
                                        SP := SP - 1;
2032
                                        MAB <= SP;
2033
                                        IQUEUE.FETCH_STATE := F_ADDR;
2034
                                        LU_INSTRUCTION := '1';
2035
                                        CPU_STATE := CPU_STACK;
2036
                                when CPU_INDSTACK =>
2037
                                        PC(15 downto 8) := DATAREAD(MAB);
2038
                                        MAB <= MAB + 1;
2039
                                        CPU_STATE:= CPU_INDSTACK2;
2040
                                when CPU_INDSTACK2 =>
2041
                                        PC(7 downto 0) := DATAREAD(MAB);
2042
                                        SP := SP - 1;
2043
                                        MAB <= SP;
2044
                                        IQUEUE.FETCH_STATE := F_ADDR;
2045
                                        CPU_STATE := CPU_STACK;
2046
                                when CPU_VECTOR =>
2047
                                        PC(15 downto 8) := IDB;
2048
                                        IAB <= IAB + 1;
2049
                                        CPU_STATE := CPU_VECTOR2;
2050
                                when CPU_VECTOR2 =>
2051
                                        PC(7 downto 0) := IDB;
2052
                                        IQUEUE.FETCH_STATE := F_ADDR;
2053
                                        CAN_FETCH := '1';
2054
                                        if (LU_INSTRUCTION='1') then CPU_STATE := CPU_STACK;
2055
                                        else CPU_STATE := CPU_DECOD;
2056
                                        end if;
2057
                                when CPU_STACK =>       -- PUSH PC 7:0 INTO THE STACK *******************************************************************************
2058
                                        DATAWRITE(MAB,DEST_ADDR16(7 downto 0));
2059
                                        WR <= '1';
2060
                                        CPU_STATE := CPU_STACK1;
2061
                                when CPU_STACK1 =>
2062
                                        SP := SP - 1;
2063
                                        MAB <= SP;
2064
                                        CPU_STATE := CPU_STACK2;
2065
                                when CPU_STACK2 =>
2066
                                        DATAWRITE(MAB,DEST_ADDR16(15 downto 8));
2067
                                        WR <= '1';
2068
                                        if (LU_INSTRUCTION='1') then
2069
                                                CPU_STATE := CPU_STACK3;
2070
                                        else
2071
                                                CPU_STATE := CPU_DECOD;
2072
                                        end if;
2073
                                when CPU_STACK3 =>      -- PUSH FLAGS INTO THE STACK *******************************************************************************
2074
                                        SP := SP - 1;
2075
                                        MAB <= SP;
2076
                                        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);
2077
                                        WR <= '1';
2078
                                        IRQE := '0';
2079
                                        CPU_STATE := CPU_DECOD;
2080
                                when CPU_UNSTACK3 =>
2081
                                        TEMP_DATA := DATAREAD(MAB);
2082
                                        CPU_FLAGS.C := TEMP_DATA(7);
2083
                                        CPU_FLAGS.Z := TEMP_DATA(6);
2084
                                        CPU_FLAGS.S := TEMP_DATA(5);
2085
                                        CPU_FLAGS.V := TEMP_DATA(4);
2086
                                        CPU_FLAGS.D := TEMP_DATA(3);
2087
                                        CPU_FLAGS.H := TEMP_DATA(2);
2088
                                        CPU_FLAGS.F2 := TEMP_DATA(1);
2089
                                        CPU_FLAGS.F1 := TEMP_DATA(0);
2090
                                        SP := SP + 1;
2091
                                        MAB <= SP;
2092
                                        CPU_STATE := CPU_UNSTACK;
2093
                                when CPU_UNSTACK =>
2094
                                        DEST_ADDR16(15 downto 8) := DATAREAD(MAB);
2095
                                        SP := SP + 1;
2096
                                        MAB <= SP;
2097
                                        CPU_STATE := CPU_UNSTACK2;
2098
                                when CPU_UNSTACK2 =>
2099
                                        DEST_ADDR16(7 downto 0) := DATAREAD(MAB);
2100
                                        SP := SP + 1;
2101
                                        PC := DEST_ADDR16;
2102
                                        IQUEUE.FETCH_STATE := F_ADDR;
2103
                                        CPU_STATE := CPU_DECOD;
2104
                                when CPU_STORE =>
2105
                                        WR <= '1';
2106
                                        CPU_STATE := CPU_DECOD;
2107
                                when CPU_HALTED =>      -- HALT mode, wait for an interrupt or reset
2108
                                when CPU_ILLEGAL =>     -- An illegal opcode was fetched 
2109
                                when CPU_RESET =>
2110
                                        IAB <= x"0002";
2111
                                        MAB <= x"000";
2112
                                        PWDB <= x"00";
2113
                                        SP := x"000";
2114
                                        RP := x"00";
2115
                                        WR <= '0';
2116
                                        PGM_WR <= '0';
2117
                                        STOP <= '0';
2118
                                        CAN_FETCH := '1';
2119
                                        FETCH_ADDR := x"0000";
2120
                                        RXSYNC1 <= '1';
2121
                                        RXSYNC2 <= '1';
2122
                                        DBG_UART.LAST_SMP := '1';
2123
                                        IQUEUE.FETCH_STATE := F_ADDR;
2124
                                        IRQE := '0';
2125
                                        IRQ0 := x"00";
2126
                                        OLD_IRQ0 := x"00";
2127
                                        IRQ0ENH := x"00";
2128
                                        IRQ0ENL := x"00";
2129
                                        OCDCR.RST := '0';
2130
                                        ATM_COUNTER := 0;
2131
                                        CPU_STATE := CPU_VECTOR;
2132
                                when others =>
2133
                                        CPU_STATE := CPU_DECOD;
2134
                                end case;
2135
                                -- end of the main decoder
2136
                        end if; -- CKDIVIDER
2137
                end if;
2138
        end process;
2139
end CPU;

powered by: WebSVN 2.1.0

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