OpenCores
URL https://opencores.org/ocsvn/68hc08/68hc08/trunk

Subversion Repositories 68hc08

[/] [68hc08/] [trunk/] [X68UR08.vhd] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 riedelx
-----------------------------------------------------------------------------------
2
--  68HC08 microcontroller implementation
3
--  Ulrich Riedel
4
--  v1.0  2005.11.24  first version
5
-----------------------------------------------------------------------------------
6
-- divider.vhd  parallel division
7
-- based on non-restoring division, uncorrected remainder
8
-- Controlled add/subtract "cas" cell (NOT CSA)
9
-- "T" is sub_add signal in div_ser.vhdl
10
 
11
library IEEE;
12
use IEEE.std_logic_1164.all;
13
 
14
entity cas is  -- Controlled Add/Subtract cell
15
  port (
16
    divisor       : in  std_logic;
17
    T             : in  std_logic;
18
    remainder_in  : in  std_logic;
19
    cin           : in  std_logic;
20
    remainder_out : out std_logic;
21
    cout          : out std_logic);
22
end entity cas;
23
 
24
architecture behavior of cas is
25
  signal tt : std_logic;
26
begin
27
  tt            <= (T   xor divisor) after 1 ns;
28
  remainder_out <= (tt  xor remainder_in xor cin) after 1 ns;
29
  cout          <= ((tt and remainder_in) or (tt and cin) or (remainder_in and cin)) after 1 ns;
30
end architecture behavior;  -- cas
31
 
32
-----------------------------------------------------------------------------------
33
 
34
library IEEE;
35
use IEEE.std_logic_1164.all;
36
 
37
entity divcas9 is   -- 17 bit dividend, 9 bit divisor
38
  port (
39
    dividend  : in  std_logic_vector(16 downto 0);
40
    divisor   : in  std_logic_vector(8 downto 0);
41
    quotient  : out std_logic_vector(8 downto 0);
42
    remainder : out std_logic_vector(8 downto 0)
43
  );
44
end entity divcas9;
45
 
46
architecture behavior of divcas9 is
47
 
48
  component cas port(
49
    divisor       : in  std_logic;
50
    T             : in  std_logic;
51
    remainder_in  : in  std_logic;
52
    cin           : in  std_logic;
53
    remainder_out : out std_logic;
54
    cout          : out std_logic
55
  );
56
  end component;
57
 
58
  signal T : std_logic_vector(8 downto 0);
59
  signal c8G, c8F, c8E, c8D, c8C, c8B, c8A, c89, c88 : std_logic;
60
  signal c7F, c7E, c7D, c7C, c7B, c7A, c79, c78, c77 : std_logic;
61
  signal c6E, c6D, c6C, c6B, c6A, c69, c68, c67, c66 : std_logic;
62
  signal c5D, c5C, c5B, c5A, c59, c58, c57, c56, c55 : std_logic;
63
  signal c4C, c4B, c4A, c49, c48, c47, c46, c45, c44 : std_logic;
64
  signal c3B, c3A, c39, c38, c37, c36, c35, c34, c33 : std_logic;
65
  signal c2A, c29, c28, c27, c26, c25, c24, c23, c22 : std_logic;
66
  signal c19, c18, c17, c16, c15, c14, c13, c12, c11 : std_logic;
67
  signal c08, c07, c06, c05, c04, c03, c02, c01, c00 : std_logic;
68
  signal r8G, r8F, r8E, r8D, r8C, r8B, r8A, r89, r88 : std_logic;
69
  signal r7F, r7E, r7D, r7C, r7B, r7A, r79, r78, r77 : std_logic;
70
  signal r6E, r6D, r6C, r6B, r6A, r69, r68, r67, r66 : std_logic;
71
  signal r5D, r5C, r5B, r5A, r59, r58, r57, r56, r55 : std_logic;
72
  signal r4C, r4B, r4A, r49, r48, r47, r46, r45, r44 : std_logic;
73
  signal r3B, r3A, r39, r38, r37, r36, r35, r34, r33 : std_logic;
74
  signal r2A, r29, r28, r27, r26, r25, r24, r23, r22 : std_logic;
75
  signal r19, r18, r17, r16, r15, r14, r13, r12, r11 : std_logic;
76
  signal r08, r07, r06, r05, r04, r03, r02, r01, r00 : std_logic;
77
begin
78
  -- dividend(16) assumed zero and unused
79
  T(8) <= '1';
80
  cas8G: cas port map(divisor(8), T(8), dividend(16), c8F,  r8G, c8G);
81
  cas8F: cas port map(divisor(7), T(8), dividend(15), c8E,  r8F, c8F);
82
  cas8E: cas port map(divisor(6), T(8), dividend(14), c8D,  r8E, c8E);
83
  cas8D: cas port map(divisor(5), T(8), dividend(13), c8C,  r8D, c8D);
84
  cas8C: cas port map(divisor(4), T(8), dividend(12), c8B,  r8C, c8C);
85
  cas8B: cas port map(divisor(3), T(8), dividend(11), c8A,  r8B, c8B);
86
  cas8A: cas port map(divisor(2), T(8), dividend(10), c89,  r8A, c8A);
87
  cas89: cas port map(divisor(1), T(8), dividend(9) , c88,  r89, c89);
88
  cas88: cas port map(divisor(0), T(8), dividend(8) , T(8), r88, c88);
89
  T(7) <= not r8G;
90
 
91
  cas7F: cas port map(divisor(8), T(7), r8F        , c7E,  r7F, c7F);
92
  cas7E: cas port map(divisor(7), T(7), r8E        , c7D,  r7E, c7E);
93
  cas7D: cas port map(divisor(6), T(7), r8D        , c7C,  r7D, c7D);
94
  cas7C: cas port map(divisor(5), T(7), r8C        , c7B,  r7C, c7C);
95
  cas7B: cas port map(divisor(4), T(7), r8B        , c7A,  r7B, c7B);
96
  cas7A: cas port map(divisor(3), T(7), r8A        , c79,  r7A, c7A);
97
  cas79: cas port map(divisor(2), T(7), r89        , c78,  r79, c79);
98
  cas78: cas port map(divisor(1), T(7), r88        , c77,  r78, c78);
99
  cas77: cas port map(divisor(0), T(7), dividend(7), T(7), r77, c77);
100
  T(6) <= not r7F;
101
 
102
  cas6E: cas port map(divisor(8), T(6), r7E        , c6D,  r6E, c6E);
103
  cas6D: cas port map(divisor(7), T(6), r7D        , c6C,  r6D, c6D);
104
  cas6C: cas port map(divisor(6), T(6), r7C        , c6B,  r6C, c6C);
105
  cas6B: cas port map(divisor(5), T(6), r7B        , c6A,  r6B, c6B);
106
  cas6A: cas port map(divisor(4), T(6), r7A        , c69,  r6A, c6A);
107
  cas69: cas port map(divisor(3), T(6), r79        , c68,  r69, c69);
108
  cas68: cas port map(divisor(2), T(6), r78        , c67,  r68, c68);
109
  cas67: cas port map(divisor(1), T(6), r77        , c66,  r67, c67);
110
  cas66: cas port map(divisor(0), T(6), dividend(6), T(6), r66, c66);
111
  T(5) <= not r6E;
112
 
113
  cas5D: cas port map(divisor(8), T(5), r6D        , c5C,  r5D, c5D);
114
  cas5C: cas port map(divisor(7), T(5), r6C        , c5B,  r5C, c5C);
115
  cas5B: cas port map(divisor(6), T(5), r6B        , c5A,  r5B, c5B);
116
  cas5A: cas port map(divisor(5), T(5), r6A        , c59,  r5A, c5A);
117
  cas59: cas port map(divisor(4), T(5), r69        , c58,  r59, c59);
118
  cas58: cas port map(divisor(3), T(5), r68        , c57,  r58, c58);
119
  cas57: cas port map(divisor(2), T(5), r67        , c56,  r57, c57);
120
  cas56: cas port map(divisor(1), T(5), r66        , c55,  r56, c56);
121
  cas55: cas port map(divisor(0), T(5), dividend(5), T(5), r55, c55);
122
  T(4) <= not r5D;
123
 
124
  cas4C: cas port map(divisor(8), T(4), r5C        , c4B,  r4C, c4C);
125
  cas4B: cas port map(divisor(7), T(4), r5B        , c4A,  r4B, c4B);
126
  cas4A: cas port map(divisor(6), T(4), r5A        , c49,  r4A, c4A);
127
  cas49: cas port map(divisor(5), T(4), r59        , c48,  r49, c49);
128
  cas48: cas port map(divisor(4), T(4), r58        , c47,  r48, c48);
129
  cas47: cas port map(divisor(3), T(4), r57        , c46,  r47, c47);
130
  cas46: cas port map(divisor(2), T(4), r56        , c45,  r46, c46);
131
  cas45: cas port map(divisor(1), T(4), r55        , c44,  r45, c45);
132
  cas44: cas port map(divisor(0), T(4), dividend(4), T(4), r44, c44);
133
  T(3) <= not r4C;
134
 
135
  cas3B: cas port map(divisor(8), T(3), r4B        , c3A,  r3B, c3B);
136
  cas3A: cas port map(divisor(7), T(3), r4A        , c39,  r3A, c3A);
137
  cas39: cas port map(divisor(6), T(3), r49        , c38,  r39, c39);
138
  cas38: cas port map(divisor(5), T(3), r48        , c37,  r38, c38);
139
  cas37: cas port map(divisor(4), T(3), r47        , c36,  r37, c37);
140
  cas36: cas port map(divisor(3), T(3), r46        , c35,  r36, c36);
141
  cas35: cas port map(divisor(2), T(3), r45        , c34,  r35, c35);
142
  cas34: cas port map(divisor(1), T(3), r44        , c33,  r34, c34);
143
  cas33: cas port map(divisor(0), T(3), dividend(3), T(3), r33, c33);
144
  T(2) <= not r3B;
145
 
146
  cas2A: cas port map(divisor(8), T(2), r3A        , c29,  r2A, c2A);
147
  cas29: cas port map(divisor(7), T(2), r39        , c28,  r29, c29);
148
  cas28: cas port map(divisor(6), T(2), r38        , c27,  r28, c28);
149
  cas27: cas port map(divisor(5), T(2), r37        , c26,  r27, c27);
150
  cas26: cas port map(divisor(4), T(2), r36        , c25,  r26, c26);
151
  cas25: cas port map(divisor(3), T(2), r35        , c24,  r25, c25);
152
  cas24: cas port map(divisor(2), T(2), r34        , c23,  r24, c24);
153
  cas23: cas port map(divisor(1), T(2), r33        , c22,  r23, c23);
154
  cas22: cas port map(divisor(0), T(2), dividend(2), T(2), r22, c22);
155
  T(1) <= not r2A;
156
 
157
  cas19: cas port map(divisor(8), T(1), r29        , c18,  r19, c19);
158
  cas18: cas port map(divisor(7), T(1), r28        , c17,  r18, c18);
159
  cas17: cas port map(divisor(6), T(1), r27        , c16,  r17, c17);
160
  cas16: cas port map(divisor(5), T(1), r26        , c15,  r16, c16);
161
  cas15: cas port map(divisor(4), T(1), r25        , c14,  r15, c15);
162
  cas14: cas port map(divisor(3), T(1), r24        , c13,  r14, c14);
163
  cas13: cas port map(divisor(2), T(1), r23        , c12,  r13, c13);
164
  cas12: cas port map(divisor(1), T(1), r22        , c11,  r12, c12);
165
  cas11: cas port map(divisor(0), T(1), dividend(1), T(1), r11, c11);
166
  T(0) <= not r19;
167
 
168
  cas08: cas port map(divisor(8), T(0), r18        , c07,  r08, c08);
169
  cas07: cas port map(divisor(7), T(0), r17        , c06,  r07, c07);
170
  cas06: cas port map(divisor(6), T(0), r16        , c05,  r06, c06);
171
  cas05: cas port map(divisor(5), T(0), r15        , c04,  r05, c05);
172
  cas04: cas port map(divisor(4), T(0), r14        , c03,  r04, c04);
173
  cas03: cas port map(divisor(3), T(0), r13        , c02,  r03, c03);
174
  cas02: cas port map(divisor(2), T(0), r12        , c01,  r02, c02);
175
  cas01: cas port map(divisor(1), T(0), r11        , c00,  r01, c01);
176
  cas00: cas port map(divisor(0), T(0), dividend(0), T(0), r00, c00);
177
 
178
  quotient(8)  <= T(7);
179
  quotient(7)  <= T(6);
180
  quotient(6)  <= T(5);
181
  quotient(5)  <= T(4);
182
  quotient(4)  <= T(3);
183
  quotient(3)  <= T(2);
184
  quotient(2)  <= T(1);
185
  quotient(1)  <= T(0);
186
  quotient(0)  <= not r08;
187
  remainder(8) <= r08;
188
  remainder(7) <= r07;
189
  remainder(6) <= r06;
190
  remainder(5) <= r05;
191
  remainder(4) <= r04;
192
  remainder(3) <= r03;
193
  remainder(2) <= r02;
194
  remainder(1) <= r01;
195
  remainder(0) <= r00;
196
 
197
end architecture behavior; -- divcas9
198
-------------------------------------------------------------------------
199
library IEEE;
200
use IEEE.std_logic_1164.all;
201
 
202
entity fadd is               -- full adder stage, interface
203
  port(a    : in  std_logic;
204
       b    : in  std_logic;
205
       cin  : in  std_logic;
206
       s    : out std_logic;
207
       cout : out std_logic);
208
end entity fadd;
209
 
210
architecture behavior of fadd is  -- full adder stage, body
211
begin  -- circuits of fadd
212
  s <= a xor b xor cin after 1 ns;
213
  cout <= (a and b) or (a and cin) or (b and cin) after 1 ns;
214
end architecture behavior; -- fadd
215
-------------------------------------------------------------------------
216
library IEEE;
217
use IEEE.std_logic_1164.all;
218
entity add8 is             -- simple 8 bit ripple carry adder
219
  port(a    : in  std_logic_vector(7 downto 0);
220
       b    : in  std_logic_vector(7 downto 0);
221
       cin  : in  std_logic;
222
       sum  : out std_logic_vector(7 downto 0);
223
       cout : out std_logic);
224
end entity add8;
225
 
226
architecture behavior of add8 is
227
  signal c : std_logic_vector(0 to 6); -- internal carry signals
228
  component fadd   -- duplicates entity port
229
  port(a    : in  std_logic;
230
       b    : in  std_logic;
231
       cin  : in  std_logic;
232
       s    : out std_logic;
233
       cout : out std_logic);
234
  end component fadd ;
235
begin
236
  a0:            fadd port map(a(0), b(0), cin, sum(0), c(0));
237
  stage: for I in 1 to 6 generate
238
             as: fadd port map(a(I), b(I), c(I-1) , sum(I), c(I));
239
         end generate stage;
240
  a31:           fadd port map(a(7), b(7), c(6) , sum(7), cout);
241
end architecture behavior;  -- add8
242
 
243
-------------------------------------------------------------------------
244
library IEEE;
245
use IEEE.std_logic_1164.all;
246
 
247
entity add8c is          -- one stage of carry save adder for multiplier
248
  port(
249
    b       : in  std_logic;                     -- a multiplier bit
250
    a       : in  std_logic_vector(7 downto 0);  -- multiplicand
251
    sum_in  : in  std_logic_vector(7 downto 0);  -- sums from previous stage
252
    cin     : in  std_logic_vector(7 downto 0);  -- carrys from previous stage
253
    sum_out : out std_logic_vector(7 downto 0);  -- sums to next stage
254
    cout    : out std_logic_vector(7 downto 0)); -- carrys to next stage
255
end add8c;
256
 
257
architecture behavior of add8c is
258
  signal zero : std_logic_vector(7 downto 0) := x"00";
259
  signal aa   : std_logic_vector(7 downto 0) := x"00";
260
  component fadd
261
    port(a    : in  std_logic;
262
         b    : in  std_logic;
263
         cin  : in  std_logic;
264
         s    : out std_logic;
265
         cout : out std_logic);
266
  end component fadd;
267
begin
268
  aa <= a when b = '1' else zero after 1 ns;
269
  stage: for I in 0 to 7 generate
270
    sta: fadd port map(aa(I), sum_in(I), cin(I) , sum_out(I), cout(I));
271
  end generate stage;
272
end architecture behavior; -- add8csa
273
 
274
-------------------------------------------------------------------------
275
library IEEE;
276
use IEEE.std_logic_1164.all;
277
 
278
entity mul8 is  -- 8 x 8 = 16 bit unsigned product multiplier
279
  port(a    : in  std_logic_vector(7 downto 0);  -- multiplicand
280
       b    : in  std_logic_vector(7 downto 0);  -- multiplier
281
       prod : out std_logic_vector(15 downto 0)); -- product
282
end mul8;
283
 
284
architecture behavior of mul8 is
285
  signal zero : std_logic_vector(7 downto 0) := x"00";
286
  signal nc1  : std_logic;
287
  type arr8 is array(0 to 7) of std_logic_vector(7 downto 0);
288
  signal s    : arr8; -- partial sums
289
  signal c    : arr8; -- partial carries
290
  signal ss   : arr8; -- shifted sums
291
 
292
  component add8c is
293
    port(b       : in  std_logic;
294
         a       : in  std_logic_vector(7 downto 0);
295
         sum_in  : in  std_logic_vector(7 downto 0);
296
         cin     : in  std_logic_vector(7 downto 0);
297
         sum_out : out std_logic_vector(7 downto 0);
298
         cout    : out std_logic_vector(7 downto 0));
299
  end component add8c;
300
  component add8
301
    port(a    : in  std_logic_vector(7 downto 0);
302
         b    : in  std_logic_vector(7 downto 0);
303
         cin  : in  std_logic;
304
         sum  : out std_logic_vector(7 downto 0);
305
         cout : out std_logic);
306
  end component add8;
307
begin
308
  st0: add8c port map(b(0), a, zero , zero, s(0), c(0));  -- CSA stage
309
  ss(0) <= '0' & s(0)(7 downto 1) after 1 ns;
310
  prod(0) <= s(0)(0) after 1 ns;
311
 
312
  stage: for I in 1 to 7 generate
313
    st: add8c port map(b(I), a, ss(I-1) , c(I-1), s(I), c(I));  -- CSA stage
314
    ss(I) <= '0' & s(I)(7 downto 1) after 1 ns;
315
    prod(I) <= s(I)(0) after 1 ns;
316
  end generate stage;
317
 
318
  add: add8 port map(ss(7), c(7), '0' , prod(15 downto 8), nc1);  -- adder
319
end architecture behavior; -- mul8
320
-------------------------------------------------------------------------
321
-- begin of 68HC08
322
LIBRARY ieee;
323
USE ieee.std_logic_1164.all;
324
USE ieee.std_logic_unsigned.all;
325
USE ieee.numeric_std.all;
326
 
327
ENTITY X68UR08 IS
328
   PORT(
329
     clk     : in  std_logic;
330
     rst     : in  std_logic;
331
     irq     : in  std_logic;
332
     addr    : out std_logic_vector(15 downto 0);
333
     wr      : out std_logic;
334
     datain  : in  std_logic_vector(7 downto 0);
335
     state   : out std_logic_vector(3 downto 0);
336
     dataout : out std_logic_vector(7 downto 0)
337
   );
338
END X68UR08;
339
 
340
ARCHITECTURE behavior OF X68UR08 IS
341
 
342
  component mul8 port(
343
    a    : in  std_logic_vector(7 downto 0);
344
    b    : in  std_logic_vector(7 downto 0);
345
    prod : out std_logic_vector(15 downto 0)
346
    );
347
  end component mul8;
348
 
349
  component divcas9 port (
350
    dividend  : in  std_logic_vector(16 downto 0);
351
    divisor   : in  std_logic_vector(8 downto 0);
352
    quotient  : out std_logic_vector(8 downto 0);
353
    remainder : out std_logic_vector(8 downto 0)
354
  );
355
  end component divcas9;
356
 
357
  constant CPUread  : std_logic := '1';
358
  constant CPUwrite : std_logic := '0';
359
  constant addrPC : std_logic_vector(2 downto 0) := "000";
360
  constant addrSP : std_logic_vector(2 downto 0) := "001";
361
  constant addrHX : std_logic_vector(2 downto 0) := "010";
362
  constant addrTM : std_logic_vector(2 downto 0) := "011";
363
  constant addrX2 : std_logic_vector(2 downto 0) := "100";
364
  constant addrS2 : std_logic_vector(2 downto 0) := "101";
365
  constant addrX1 : std_logic_vector(2 downto 0) := "110";
366
  constant addrS1 : std_logic_vector(2 downto 0) := "111";
367
  constant outA    : std_logic_vector(3 downto 0) := "0000";
368
  constant outH    : std_logic_vector(3 downto 0) := "0001";
369
  constant outX    : std_logic_vector(3 downto 0) := "0010";
370
  constant outSPL  : std_logic_vector(3 downto 0) := "0011";
371
  constant outSPH  : std_logic_vector(3 downto 0) := "0100";
372
  constant outPCL  : std_logic_vector(3 downto 0) := "0101";
373
  constant outPCH  : std_logic_vector(3 downto 0) := "0110";
374
  constant outTL   : std_logic_vector(3 downto 0) := "0111";
375
  constant outTH   : std_logic_vector(3 downto 0) := "1000";
376
  constant outHelp : std_logic_vector(3 downto 0) := "1001";
377
  constant outCode : std_logic_vector(3 downto 0) := "1010";
378
 
379
  type    masker is array (0 to 7) of std_logic_vector(7 downto 0);
380
  signal mask0  : masker;
381
  signal mask1  : masker;
382
  signal regA   : std_logic_vector(7 downto 0);
383
  signal regHX  : std_logic_vector(15 downto 0);
384
  signal regSP  : std_logic_vector(15 downto 0);
385
  signal regPC  : std_logic_vector(15 downto 0);
386
  signal flagV  : std_logic;
387
  signal flagH  : std_logic;
388
  signal flagI  : std_logic;
389
  signal flagN  : std_logic;
390
  signal flagZ  : std_logic;
391
  signal flagC  : std_logic;
392
  signal help   : std_logic_vector(7 downto 0);
393
  signal temp   : std_logic_vector(15 downto 0);
394
  signal mainFSM : std_logic_vector(3 downto 0);
395
  signal addrMux : std_logic_vector(2 downto 0);
396
  signal dataMux : std_logic_vector(3 downto 0);
397
  signal opcode  : std_logic_vector(7 downto 0);
398
  signal escape9E : std_logic;
399
  signal prod     : std_logic_vector(15 downto 0);
400
  signal dividend : std_logic_vector(16 downto 0);
401
  signal divisor  : std_logic_vector(8 downto 0);
402
  signal quotient : std_logic_vector(8 downto 0);
403
  signal remainder: std_logic_vector(8 downto 0);
404
  signal irq_d      : std_logic;
405
  signal irqRequest : std_logic;
406
 
407
  signal trace       : std_logic;
408
  signal trace_i     : std_logic;
409
  signal traceOpCode : std_logic_vector(7 downto 0);
410
 
411
begin
412
 
413
  mul: mul8 port map(
414
    a    => regA,
415
    b    => regHX(7 downto 0),
416
    prod => prod
417
  );
418
 
419
  dividend <= "0" & regHX(15 downto 8) & regA;
420
  divisor  <= "0" & regHX(7 downto 0);
421
  div: divcas9 port map(
422
    dividend  => dividend,
423
    divisor   => divisor,
424
    quotient  => quotient,
425
    remainder => remainder
426
  );
427
 
428
  addr <= regPC          when addrMux = addrPC else
429
          regSP          when addrMux = addrSP else
430
          regHX          when addrMux = addrHX else
431
          temp           when addrMux = addrTM else
432
          (regHX + temp) when addrMux = addrX2 else
433
          (regSP + temp) when addrMux = addrS2 else
434
          (regHX + (x"00" & temp(7 downto 0))) when addrMux = addrX1 else
435
          (regSP + (x"00" & temp(7 downto 0)));
436
  dataout <= regA               when dataMux = outA else
437
             regHX(15 downto 8) when dataMux = outH else
438
             regHX( 7 downto 0) when dataMux = outX else
439
             regSP( 7 downto 0) when dataMux = outSPL else
440
             regSP(15 downto 8) when dataMux = outSPH else
441
             regPC( 7 downto 0) when dataMux = outPCL else
442
             regPC(15 downto 8) when dataMux = outPCH else
443
             temp ( 7 downto 0) when dataMux = outTL  else
444
             temp (15 downto 8) when dataMux = outTH  else
445
             help               when dataMux = outHelp else
446
             traceOpCode;
447
 
448
  state <= mainFSM;
449
  process(clk, rst)
450
    variable tres : std_logic_vector(7 downto 0);
451
    variable lres : std_logic_vector(15 downto 0);
452
  begin
453
    if rst = '0' then
454
      trace    <= '0';
455
      trace_i  <= '0';
456
      escape9E <= '0';
457
      mask0(0) <= "11111110";
458
      mask0(1) <= "11111101";
459
      mask0(2) <= "11111011";
460
      mask0(3) <= "11110111";
461
      mask0(4) <= "11101111";
462
      mask0(5) <= "11011111";
463
      mask0(6) <= "10111111";
464
      mask0(7) <= "01111111";
465
      mask1(0) <= "00000001";
466
      mask1(1) <= "00000010";
467
      mask1(2) <= "00000100";
468
      mask1(3) <= "00001000";
469
      mask1(4) <= "00010000";
470
      mask1(5) <= "00100000";
471
      mask1(6) <= "01000000";
472
      mask1(7) <= "10000000";
473
      wr <= CPUread;
474
      flagV <= '0';
475
      flagH <= '0';
476
      flagI <= '1'; -- irq disabled
477
      flagN <= '0';
478
      flagZ <= '0';
479
      flagC <= '0';
480
      regA    <= x"00";
481
      regHX   <= x"0000";  -- clear H register for 6805 compatible mode
482
      regSP   <= x"00FF";
483
      regPC   <= x"FFFE";
484
      temp    <= x"FFFE";
485
      help    <= x"00";
486
      dataMux <= outA;
487
      addrMux <= addrTM;
488
      irq_d   <= '1';
489
      irqRequest <= '0';
490
      mainFSM <= "0000";
491
    else
492
      if rising_edge(clk) then
493
        irq_d <= irq;
494
        if (irq = '0') and (irq_d = '1') and (flagI = '0') then -- irq falling edge ?
495
          irqRequest <= '1';
496
        end if;
497
        case mainFSM is
498
          when "0000" => --############# reset fetch PCH from FFFE
499
            regPC(15 downto 8) <= datain;
500
            temp    <= temp + 1;
501
            mainFSM <= "0001";
502
          when "0001" => --############# reset fetch PCL from FFFF
503
            regPC(7 downto 0)  <= datain;
504
            addrMux <= addrPC;
505
            mainFSM <= "0010";
506
 
507
          when "0010" => --##################### fetch opcode, instruction cycle 1
508
            trace <= trace_i;
509
            if trace = '1' then
510
              opcode      <= x"83"; -- special SWI trace
511
              traceOpCode <= datain;
512
              addrMux     <= addrSP;
513
              mainFSM     <= "0011";
514
            elsif irqRequest = '1' then
515
              opcode      <= x"83"; -- special SWI interrupt
516
              addrMux     <= addrSP;
517
              mainFSM     <= "0011";
518
            else
519
              opcode <= datain;
520
              case datain is
521
                when x"82" =>  -- RTT return trace special propietary instruction
522
                  trace_i <= '1';  -- arm trace for next instruction
523
                  regSP   <= regSP + 1;
524
                  addrMux <= addrSP;
525
                  mainFSM <= "0011";
526
                when x"9E" =>  -- escape byte for SP address
527
                  escape9E <= '1';
528
                  regPC    <= regPC + 1;
529
                  mainFSM  <= "0010";
530
                when x"00" | x"02" | x"04" | x"06" | x"08" | x"0A" | x"0C" | x"0E" |   -- BRSET n,opr8a,rel
531
                     x"01" | x"03" | x"05" | x"07" | x"09" | x"0B" | x"0D" | x"0F" |   -- BRCLR n,opr8a,rel
532
                     x"10" | x"12" | x"14" | x"16" | x"18" | x"1A" | x"1C" | x"1E" |   -- BSET n,opr8a
533
                     x"11" | x"13" | x"15" | x"17" | x"19" | x"1B" | x"1D" | x"1F" |   -- BCLR n,opr8a
534
                     x"30" | x"31" | x"33" | x"34" |   -- NEG opr8a, CBEQ opr8a,rel, COM opr8a, LSR opr8a
535
                     x"35" | x"36" | x"37" | x"38" |   -- STHX opr8a, ROR opr8a, ASR opr8a, LSL opr8a
536
                     x"39" | x"3A" | x"3B" | x"3C" |   -- ROL opr8a, DEC opr8a, DBNZ opr8a,rel, INC opr8a
537
                     x"3D" | x"3F" | x"4E" | x"55" |  -- TST opr8a, CLR opr8a, MOV opr8a,opr8a, LDHX opr
538
                     x"5E" | x"6E" | x"75" |  -- MOV opr8a,X+, MOV #opr8i,opr8a, CPHX opr
539
                     x"B0" | x"B1" | x"B2" | x"B3" |  -- SUB opr8a, CMP opr8a, SBC opr8a, CPX opr8a
540
                     x"B4" | x"B5" | x"B6" | x"B7" |  -- AND opr8a, BIT opr8a, LDA opr8a, STA opr8a
541
                     x"B8" | x"B9" | x"BA" | x"BB" |  -- EOR opr8a, ADC opr8a, ORA opr8a, ADD opr8a
542
                     x"BC" | x"BE" | x"BF" =>         -- JMP opr8a, LDX opr8a, STX opr8a
543
                  temp    <= x"0000";
544
                  regPC   <= regPC + 1;
545
                  mainFSM <= "0011";
546
                when x"20" | x"21" | x"22" | x"23" | x"24" | x"25" | x"26" | x"27" |
547
                     x"28" | x"29" | x"2A" | x"2B" | x"2C" | x"2D" | x"2E" | x"2F" |   -- branches
548
                     x"41" | x"45" | x"51" | x"65" |  -- CBEQA #opr8i,rel, LDHX #opr, CBEQX #opr8i,rel, CPHX #opr
549
                     x"90" | x"91" | x"92" | x"93" |  -- branches
550
                     x"C0" | x"C1" | x"C2" | x"C3" |  -- SUB opr16a, CMP opr16a, SBC opr16a, CPX opr16a
551
                     x"C4" | x"C5" | x"C6" | x"C7" |  -- AND opr16a, BIT opr16a, LDA opr16a, STA opr16a
552
                     x"C8" | x"C9" | x"CA" | x"CB" |  -- EOR opr16a, ADC opr16a, ORA opr16a, ADD opr16a
553
                     x"CC" | x"CE" | x"CF" |          -- JMP opr16a, LDX opr16a, STX opr16a
554
                     x"D0" | x"D1" | x"D2" | x"D3" |  -- SUB oprx16,X, CMP oprx16,X, SBC oprx16,X, CPX oprx16,X
555
                     x"D4" | x"D5" | x"D6" | x"D7" |  -- AND oprx16,X, BIT oprx16,X, LDA oprx16,X, STA oprx16,X
556
                     x"D8" | x"D9" | x"DA" | x"DB" |  -- EOR oprx16,X, ADC oprx16,X, ORA oprx16,X, ADD oprx16,X
557
                     x"DC" | x"DE" | x"DF" =>         -- JMP oprx16,X, LDX oprx16,X, STX oprx16,X
558
                  regPC <= regPC + 1;
559
                  mainFSM <= "0011";
560
                when x"70" | x"71" | x"73" | x"74" | x"76" | x"77" |  -- NEG ,X, CBEQ ,X+,rel, COM ,X, LSR ,X, ROR ,X, ASR ,X
561
                     x"78" | x"79" | x"7A" | x"7B" | x"7C" | x"7D" |  -- LSL ,X, ROL ,X, DEC ,X, DBNZ ,X,rel, INC ,X, TXT ,X
562
                     x"7E" =>  -- MOV ,X+,opr8a
563
                  addrMux <= addrHX;
564
                  regPC   <= regPC + 1;
565
                  mainFSM <= "0100";
566
                when x"A0" | x"A1" | x"A2" | x"A3" |  -- SUB #opr8i, CMP #opr8i, SBC #opr8i, CPX #opr8i
567
                     x"A4" | x"A5" | x"A6" | x"A7" |  -- AND #opr8i, BIT #opr8i, LDA #opr8i, AIS
568
                     x"A8" | x"A9" | x"AA" | x"AB" |  -- EOR #opr8i, ADC #opr8i, ORA #opr8i, ADD #opr8i
569
                     x"AE" | x"AF" =>  -- LDX #opr8i, AIX
570
                  regPC <= regPC + 1;
571
                  mainFSM <= "0101";
572
                when x"E0" | x"E1" | x"E2" | x"E3" |  -- SUB oprx8,X, CMP oprx8,X, SBC oprx8,X, CPX oprx8,X
573
                     x"E4" | x"E5" | x"E6" | x"E7" |  -- AND oprx8,X, BIT oprx8,X, LDA oprx8,X, STA oprx8,X
574
                     x"E8" | x"E9" | x"EA" | x"EB" |  -- EOR oprx8,X, ADC oprx8,X, ORA oprx8,X, ADD oprx8,X
575
                     x"EC" | x"EE" | x"EF" =>         -- JMP oprx8,X, LDX oprx8,X, STX oprx8,X
576
                  regPC <= regPC + 1;
577
                  mainFSM <= "0100";
578
                when x"F0" | x"F1" | x"F2" | x"F3" |  -- SUB ,X, CMP ,X, SBC ,X, CPX ,X
579
                     x"F4" | x"F5" | x"F6" |          -- AND ,X, BIT ,X, LDA ,X
580
                     x"F8" | x"F9" | x"FA" | x"FB" |  -- EOR ,X, ADC ,X, ORA ,X, ADD ,X
581
                     x"FE" =>                         -- LDX ,X
582
                  addrMux <= addrHX;
583
                  regPC   <= regPC + 1;
584
                  mainFSM <= "0101";
585
                when x"FC" =>  -- JMP ,X
586
                  regPC <= regHX;
587
                  mainFSM <= "0010";
588
                when x"F7" =>  -- STA ,X
589
                  wr <= CPUwrite;
590
                  flagV <= '0';
591
                  flagN <= regA(7);
592
                  if regA = x"00" then
593
                    flagZ <= '1';
594
                  else
595
                    flagZ <= '0';
596
                  end if;
597
                  dataMux <= outA;
598
                  addrMux <= addrHX;
599
                  regPC <= regPC + 1;
600
                  mainFSM <= "0101";
601
                when x"FF" =>  -- STX ,X
602
                  wr <= CPUwrite;
603
                  flagV <= '0';
604
                  flagN <= regHX(7);
605
                  if regHX(7 downto 0) = x"00" then
606
                    flagZ <= '1';
607
                  else
608
                    flagZ <= '0';
609
                  end if;
610
                  dataMux <= outX;
611
                  addrMux <= addrHX;
612
                  regPC <= regPC + 1;
613
                  mainFSM <= "0101";
614
                when x"40" =>  -- NEGA
615
                  regA    <= x"00" - regA;
616
                  tres    := x"00" - regA;
617
                  flagV   <= tres(7) and regA(7);
618
                  flagN   <= tres(7);
619
                  if tres = x"00" then
620
                    flagZ <= '1';
621
                    flagC <= '0';
622
                  else
623
                    flagC <= '1';
624
                    flagZ <= '0';
625
                  end if;
626
                  regPC <= regPC + 1;
627
                  mainFSM <= "0010";
628
                when x"42" =>  -- MUL
629
                  flagH <= '0';
630
                  flagC <= '0';
631
                  regA              <= prod(7 downto 0);
632
                  regHX(7 downto 0) <= prod(15 downto 8);
633
                  regPC <= regPC + 1;
634
                  mainFSM <= "0010";
635
                when x"43" =>  -- COMA
636
                  regA    <= regA xor x"FF";
637
                  tres    := regA xor x"FF";
638
                  flagV   <= '0';
639
                  flagC   <= '1';
640
                  flagN   <= tres(7);
641
                  if tres = x"00" then
642
                    flagZ <= '1';
643
                  else
644
                    flagZ <= '0';
645
                  end if;
646
                  regPC <= regPC + 1;
647
                  mainFSM <= "0010";
648
                when x"44" =>  -- LSRA
649
                  regA    <= "0" & regA(7 downto 1);
650
                  tres    := "0" & regA(7 downto 1);
651
                  flagV   <= regA(0);
652
                  flagN   <= '0';
653
                  flagC   <= regA(0);
654
                  if tres = x"00" then
655
                    flagZ <= '1';
656
                  else
657
                    flagZ <= '0';
658
                  end if;
659
                  regPC <= regPC + 1;
660
                  mainFSM <= "0010";
661
                when x"46" =>  -- RORA
662
                  regA    <= flagC & regA(7 downto 1);
663
                  tres    := flagC & regA(7 downto 1);
664
                  flagN   <= flagC;
665
                  flagC   <= regA(0);
666
                  flagV   <= flagC xor regA(0);
667
                  if tres = x"00" then
668
                    flagZ <= '1';
669
                  else
670
                    flagZ <= '0';
671
                  end if;
672
                  regPC <= regPC + 1;
673
                  mainFSM <= "0010";
674
                when x"47" =>  -- ASRA
675
                  regA    <= regA(7) & regA(7 downto 1);
676
                  tres    := regA(7) & regA(7 downto 1);
677
                  flagN   <= regA(7);
678
                  flagC   <= regA(0);
679
                  flagV   <= regA(7) xor regA(0);
680
                  if tres = x"00" then
681
                    flagZ <= '1';
682
                  else
683
                    flagZ <= '0';
684
                  end if;
685
                  regPC <= regPC + 1;
686
                  mainFSM <= "0010";
687
                when x"48" =>  -- LSLA
688
                  regA    <= regA(6 downto 0) & "0";
689
                  tres    := regA(6 downto 0) & "0";
690
                  flagN   <= regA(6);
691
                  flagC   <= regA(7);
692
                  flagV   <= regA(7) xor regA(6);
693
                  if tres = x"00" then
694
                    flagZ <= '1';
695
                  else
696
                    flagZ <= '0';
697
                  end if;
698
                  regPC <= regPC + 1;
699
                  mainFSM <= "0010";
700
                when x"49" =>  -- ROLA
701
                  regA    <= regA(6 downto 0) & flagC;
702
                  tres    := regA(6 downto 0) & flagC;
703
                  flagN   <= regA(6);
704
                  flagC   <= regA(7);
705
                  flagV   <= regA(7) xor regA(6);
706
                  if tres = x"00" then
707
                    flagZ <= '1';
708
                  else
709
                    flagZ <= '0';
710
                  end if;
711
                  regPC <= regPC + 1;
712
                  mainFSM <= "0010";
713
                when x"4A" =>  -- DECA
714
                  regA    <= regA - 1;
715
                  tres    := regA - 1;
716
                  flagN   <= tres(7);
717
                  if regA = x"80" then
718
                    flagV <= '1';
719
                  else
720
                    flagV <= '0';
721
                  end if;
722
                  if tres = x"00" then
723
                    flagZ <= '1';
724
                  else
725
                    flagZ <= '0';
726
                  end if;
727
                  regPC <= regPC + 1;
728
                  mainFSM <= "0010";
729
                when x"4B" =>  -- DBNZA rel
730
                  regA <= regA - 1;
731
                  tres := regA - 1;
732
                  if tres = x"00" then
733
                    regPC <= regPC + 2;
734
                    mainFSM <= "0010";
735
                  else
736
                    regPC <= regPC + 1;
737
                    mainFSM <= "0011";
738
                  end if;
739
                when x"4C" =>  -- INCA
740
                  regA    <= regA + 1;
741
                  tres    := regA + 1;
742
                  flagN   <= tres(7);
743
                  if regA = x"7F" then
744
                    flagV <= '1';
745
                  else
746
                    flagV <= '0';
747
                  end if;
748
                  if tres = x"00" then
749
                    flagZ <= '1';
750
                  else
751
                    flagZ <= '0';
752
                  end if;
753
                  regPC <= regPC + 1;
754
                  mainFSM <= "0010";
755
                when x"4D" =>  -- TSTA
756
                  flagN   <= regA(7);
757
                  flagV   <= '0';
758
                  if regA = x"00" then
759
                    flagZ <= '1';
760
                  else
761
                    flagZ <= '0';
762
                  end if;
763
                  regPC <= regPC + 1;
764
                  mainFSM <= "0010";
765
                when x"4F" =>  -- CLRA
766
                  regA <= x"00";
767
                  flagV <= '0';
768
                  flagN <= '0';
769
                  flagZ <= '1';
770
                  regPC <= regPC + 1;
771
                  mainFSM <= "0010";
772
                when x"50" =>  -- NEGX
773
                  regHX(7 downto 0) <= x"00" - regHX(7 downto 0);
774
                  tres    := x"00" - regHX(7 downto 0);
775
                  flagV   <= tres(7) and regHX(7);
776
                  flagN   <= tres(7);
777
                  if tres = x"00" then
778
                    flagZ <= '1';
779
                    flagC <= '0';
780
                  else
781
                    flagC <= '1';
782
                    flagZ <= '0';
783
                  end if;
784
                  regPC <= regPC + 1;
785
                  mainFSM <= "0010";
786
                when x"52" =>  -- DIV
787
                  regPC <= regPC + 1;
788
                  mainFSM <= "0011";
789
                when x"53" =>  -- COMX
790
                  regHX(7 downto 0) <= regHX(7 downto 0) xor x"FF";
791
                  tres    := regHX(7 downto 0) xor x"FF";
792
                  flagV   <= '0';
793
                  flagC   <= '1';
794
                  flagN   <= tres(7);
795
                  if tres = x"00" then
796
                    flagZ <= '1';
797
                  else
798
                    flagZ <= '0';
799
                  end if;
800
                  regPC <= regPC + 1;
801
                  mainFSM <= "0010";
802
                when x"54" =>  -- LSRX
803
                  regHX(7 downto 0) <= "0" & regHX(7 downto 0)(7 downto 1);
804
                  tres    := "0" & regHX(7 downto 0)(7 downto 1);
805
                  flagV   <= regHX(0);
806
                  flagN   <= '0';
807
                  flagC   <= regHX(0);
808
                  if tres = x"00" then
809
                    flagZ <= '1';
810
                  else
811
                    flagZ <= '0';
812
                  end if;
813
                  regPC <= regPC + 1;
814
                  mainFSM <= "0010";
815
                when x"56" =>  -- RORX
816
                  regHX(7 downto 0) <= flagC & regHX(7 downto 1);
817
                  tres    := flagC & regHX(7 downto 1);
818
                  flagN   <= flagC;
819
                  flagC   <= regHX(0);
820
                  flagV   <= flagC xor regHX(0);
821
                  if tres = x"00" then
822
                    flagZ <= '1';
823
                  else
824
                    flagZ <= '0';
825
                  end if;
826
                  regPC <= regPC + 1;
827
                  mainFSM <= "0010";
828
                when x"57" =>  -- ASRX
829
                  regHX(7 downto 0) <= regHX(7) & regHX(7 downto 1);
830
                  tres    := regHX(7) & regHX(7 downto 1);
831
                  flagN   <= regHX(7);
832
                  flagC   <= regHX(0);
833
                  flagV   <= regHX(7) xor regHX(0);
834
                  if tres = x"00" then
835
                    flagZ <= '1';
836
                  else
837
                    flagZ <= '0';
838
                  end if;
839
                  regPC <= regPC + 1;
840
                  mainFSM <= "0010";
841
                when x"58" =>  -- LSLX
842
                  regHX(7 downto 0) <= regHX(6 downto 0) & "0";
843
                  tres    := regHX(6 downto 0) & "0";
844
                  flagN   <= regHX(6);
845
                  flagC   <= regHX(7);
846
                  flagV   <= regHX(7) xor regHX(6);
847
                  if tres = x"00" then
848
                    flagZ <= '1';
849
                  else
850
                    flagZ <= '0';
851
                  end if;
852
                  regPC <= regPC + 1;
853
                  mainFSM <= "0010";
854
                when x"59" =>  -- ROLX
855
                  regHX(7 downto 0) <= regHX(6 downto 0) & flagC;
856
                  tres    := regHX(6 downto 0) & flagC;
857
                  flagN   <= regHX(6);
858
                  flagC   <= regHX(7);
859
                  flagV   <= regHX(7) xor regHX(6);
860
                  if tres = x"00" then
861
                    flagZ <= '1';
862
                  else
863
                    flagZ <= '0';
864
                  end if;
865
                  regPC <= regPC + 1;
866
                  mainFSM <= "0010";
867
                when x"5A" =>  -- DECX
868
                  regHX(7 downto 0) <= regHX(7 downto 0) - 1;
869
                  tres    := regHX(7 downto 0) - 1;
870
                  flagN   <= tres(7);
871
                  if regHX(7 downto 0) = x"80" then
872
                    flagV <= '1';
873
                  else
874
                    flagV <= '0';
875
                  end if;
876
                  if tres = x"00" then
877
                    flagZ <= '1';
878
                  else
879
                    flagZ <= '0';
880
                  end if;
881
                  regPC <= regPC + 1;
882
                  mainFSM <= "0010";
883
                when x"5B" =>  -- DBNZX rel
884
                  regHX(7 downto 0) <= regHX(7 downto 0) - 1;
885
                  tres := regHX(7 downto 0) - 1;
886
                  if tres = x"00" then
887
                    regPC <= regPC + 2;
888
                    mainFSM <= "0010";
889
                  else
890
                    regPC <= regPC + 1;
891
                    mainFSM <= "0011";
892
                  end if;
893
                when x"5C" =>  -- INCX
894
                  regHX(7 downto 0) <= regHX(7 downto 0) + 1;
895
                  tres    := regHX(7 downto 0) + 1;
896
                  flagN   <= tres(7);
897
                  if regHX(7 downto 0) = x"7F" then
898
                    flagV <= '1';
899
                  else
900
                    flagV <= '0';
901
                  end if;
902
                  if tres = x"00" then
903
                    flagZ <= '1';
904
                  else
905
                    flagZ <= '0';
906
                  end if;
907
                  regPC <= regPC + 1;
908
                  mainFSM <= "0010";
909
                when x"5D" =>  -- TSTX
910
                  flagN   <= regHX(7);
911
                  flagV   <= '0';
912
                  if regHX(7 downto 0) = x"00" then
913
                    flagZ <= '1';
914
                  else
915
                    flagZ <= '0';
916
                  end if;
917
                  regPC <= regPC + 1;
918
                  mainFSM <= "0010";
919
                when x"5F" =>  -- CLRX
920
                  regHX(7 downto 0) <= x"00";
921
                  flagV <= '0';
922
                  flagN <= '0';
923
                  flagZ <= '1';
924
                  regPC <= regPC + 1;
925
                  mainFSM <= "0010";
926
                when x"60" | x"61" | x"63" | x"64" | x"66" | -- NEG oprx8,X, CBEQ oprx8,X+,rel, COM oprx8,X, LSR oprx8,X, ROR oprx8,X
927
                     x"67" | x"68" | x"69" | x"6A" | x"6B" |  -- ASR oprx8,X, LSL oprx8,X, ROL oprx8,X, DEC oprx8,X, DBNZ oprx8,X,rel
928
                     x"6C" | x"6D" | x"6F" =>  -- INC oprx8,X, TST oprx8,X, CLR oprx8,X
929
                  if escape9E = '1' then
930
                    if datain /= x"61" then
931
                      escape9E <= '0';
932
                    end if;
933
                    temp <= regSP;
934
                  else
935
                    temp <= regHX;
936
                  end if;
937
                  regPC   <= regPC + 1;
938
                  mainFSM <= "0011";
939
                when x"62" =>  -- NSA
940
                  escape9E <= '0';
941
                  regA <= regA(3 downto 0) & regA(7 downto 4);
942
                  regPC   <= regPC + 1;
943
                  mainFSM <= "0010";
944
                when x"72" =>  -- DAA
945
                  if flagC = '0' then
946
                    if flagH = '0' then
947
                      if (regA(7 downto 4) < 10) and (regA(3 downto 0) < 10) then
948
                        if regA = x"00" then
949
                          flagZ <= '1';
950
                        else
951
                          flagZ <= '0';
952
                        end if;
953
                        flagN <= regA(7);
954
                      elsif (regA(7 downto 4) < 9) and (regA(3 downto 0) > 9) then
955
                        regA <= regA + x"06";
956
                        tres := regA + x"06";
957
                        flagN <= tres(7);
958
                        if tres = x"00" then
959
                          flagZ <= '1';
960
                        else
961
                          flagZ <= '0';
962
                        end if;
963
                      elsif (regA(7 downto 4) > 9) and (regA(3 downto 0) < 10) then
964
                        regA <= regA + x"60";
965
                        tres := regA + x"60";
966
                        flagC <= '1';
967
                        flagN <= tres(7);
968
                        if tres = x"00" then
969
                          flagZ <= '1';
970
                        else
971
                          flagZ <= '0';
972
                        end if;
973
                      elsif (regA(7 downto 4) > 8) and (regA(3 downto 0) > 9) then
974
                        regA <= regA + x"66";
975
                        tres := regA + x"66";
976
                        flagC <= '1';
977
                        flagN <= tres(7);
978
                        if tres = x"00" then
979
                          flagZ <= '1';
980
                        else
981
                          flagZ <= '0';
982
                        end if;
983
                      end if;
984
                    else
985
                      if (regA(7 downto 4) < 10) and (regA(3 downto 0) < 4) then
986
                        regA <= regA + x"06";
987
                        tres := regA + x"06";
988
                        flagN <= tres(7);
989
                        if tres = x"00" then
990
                          flagZ <= '1';
991
                        else
992
                          flagZ <= '0';
993
                        end if;
994
                      elsif (regA(7 downto 4) > 9) and (regA(3 downto 0) < 4) then
995
                        regA <= regA + x"66";
996
                        tres := regA + x"66";
997
                        flagC <= '1';
998
                        flagN <= tres(7);
999
                        if tres = x"00" then
1000
                          flagZ <= '1';
1001
                        else
1002
                          flagZ <= '0';
1003
                        end if;
1004
                      end if;
1005
                    end if;
1006
                  else
1007
                    if flagH = '0' then
1008
                      if (regA(7 downto 3) < 3) and (regA(3 downto 0) < 10) then
1009
                        regA <= regA + x"60";
1010
                        tres := regA + x"60";
1011
                        flagC <= '1';
1012
                        flagN <= tres(7);
1013
                        if tres = x"00" then
1014
                          flagZ <= '1';
1015
                        else
1016
                          flagZ <= '0';
1017
                        end if;
1018
                      elsif (regA(7 downto 3) < 3) and (regA(3 downto 0) > 9) then
1019
                        regA <= regA + x"66";
1020
                        tres := regA + x"66";
1021
                        flagC <= '1';
1022
                        flagN <= tres(7);
1023
                        if tres = x"00" then
1024
                          flagZ <= '1';
1025
                        else
1026
                          flagZ <= '0';
1027
                        end if;
1028
                      end if;
1029
                    else
1030
                      if (regA(7 downto 3) < 4) and (regA(3 downto 0) < 4) then
1031
                        regA <= regA + x"66";
1032
                        tres := regA + x"66";
1033
                        flagC <= '1';
1034
                        flagN <= tres(7);
1035
                        if tres = x"00" then
1036
                          flagZ <= '1';
1037
                        else
1038
                          flagZ <= '0';
1039
                        end if;
1040
                      end if;
1041
                    end if;
1042
                  end if;
1043
                  regPC   <= regPC + 1;
1044
                  mainFSM <= "0010";
1045
                when x"7F" =>  -- CLR ,X
1046
                  flagV <= '0';
1047
                  flagN <= '0';
1048
                  flagZ <= '1';
1049
                  addrMux <= addrHX;
1050
                  dataMux <= outHelp;
1051
                  wr <= CPUwrite;
1052
                  help <= x"00";
1053
                  regPC <= regPC + 1;
1054
                  mainFSM <= "0011";
1055
                when x"80" | x"81" =>  -- RTI, RTS
1056
                  regSP   <= regSP + 1;
1057
                  addrMux <= addrSP;
1058
                  mainFSM <= "0011";
1059
                when x"83" =>  -- SWI
1060
                  regPC   <= regPC + 1;
1061
                  addrMux <= addrSP;
1062
                  mainFSM <= "0011";
1063
                when x"84" =>  -- TAP
1064
                  flagN <= regA(7);
1065
                  flagH <= regA(4);
1066
                  flagI <= regA(3);
1067
                  flagN <= regA(2);
1068
                  flagZ <= regA(1);
1069
                  flagC <= regA(0);
1070
                  regPC   <= regPC + 1;
1071
                  mainFSM <= "0010";
1072
                when x"85" =>  -- TPA
1073
                  regA(7) <= flagN;
1074
                  regA(6) <= '1';
1075
                  regA(5) <= '1';
1076
                  regA(4) <= flagH;
1077
                  regA(3) <= flagI;
1078
                  regA(2) <= flagN;
1079
                  regA(1) <= flagZ;
1080
                  regA(0) <= flagC;
1081
                  regPC   <= regPC + 1;
1082
                  mainFSM <= "0010";
1083
                when x"86" | x"88" | x"8A" =>  -- PULA, PULX, PULH
1084
                  addrMux <= addrSP;
1085
                  regSP   <= regSP + 1;
1086
                  regPC   <= regPC + 1;
1087
                  mainFSM <= "0011";
1088
                when x"87" =>  -- PSHA
1089
                  wr <= CPUwrite;
1090
                  dataMux <= outA;
1091
                  addrMux <= addrSP;
1092
                  regPC   <= regPC + 1;
1093
                  mainFSM <= "0011";
1094
                when x"89" =>  -- PSHX
1095
                  wr <= CPUwrite;
1096
                  dataMux <= outX;
1097
                  addrMux <= addrSP;
1098
                  regPC   <= regPC + 1;
1099
                  mainFSM <= "0011";
1100
                when x"8B" =>  -- PSHH
1101
                  wr <= CPUwrite;
1102
                  dataMux <= outH;
1103
                  addrMux <= addrSP;
1104
                  regPC   <= regPC + 1;
1105
                  mainFSM <= "0011";
1106
                when x"8C" =>  -- CLRH
1107
                  regHX(15 downto 8) <= x"00";
1108
                  flagV <= '0';
1109
                  flagN <= '0';
1110
                  flagZ <= '1';
1111
                  regPC   <= regPC + 1;
1112
                  mainFSM <= "0010";
1113
                when x"8E" =>  -- STOP currently unsupported
1114
                  regPC   <= regPC + 1;
1115
                  mainFSM <= "0010";
1116
                when x"8F" =>  -- WAIT currently unsupported
1117
                  regPC   <= regPC + 1;
1118
                  mainFSM <= "0010";
1119
                when x"94" =>  -- TXS   
1120
                  regSP <= regHX - 1;
1121
                  regPC   <= regPC + 1;
1122
                  mainFSM <= "0010";
1123
                when x"95" =>  -- TSX   
1124
                  regHX <= regSP + 1;
1125
                  regPC   <= regPC + 1;
1126
                  mainFSM <= "0010";
1127
                when x"97" =>  -- TAX
1128
                  regHX(7 downto 0) <= regA;
1129
                  regPC   <= regPC + 1;
1130
                  mainFSM <= "0010";
1131
                when x"98" | x"99" =>  -- CLC, SEC
1132
                  flagC <= datain(0);
1133
                  regPC   <= regPC + 1;
1134
                  mainFSM <= "0010";
1135
                when x"9A" | x"9B" =>  -- CLI, SEI  ATTENTION!!!
1136
                  flagI <= datain(0);
1137
                  regPC   <= regPC + 1;
1138
                  mainFSM <= "0010";
1139
                when x"9C" =>  -- RSP
1140
                  regSP <= x"00FF";
1141
                  regPC   <= regPC + 1;
1142
                  mainFSM <= "0010";
1143
                when x"9D" =>  -- NOP
1144
                  regPC   <= regPC + 1;
1145
                  mainFSM <= "0010";
1146
                when x"9F" =>  -- TXA
1147
                  regA <= regHX(7 downto 0);
1148
                  regPC   <= regPC + 1;
1149
                  mainFSM <= "0010";
1150
                when x"AD" | x"BD" | x"ED" =>  -- BSR rel, JSR opr8a, JSR oprx8,X
1151
                  temp    <= regPC + 2;
1152
                  regPC   <= regPC + 1;
1153
                  mainFSM <= "0011";
1154
                when x"CD" | x"DD" =>  -- JSR opr16a, JSR oprx16,X
1155
                  temp    <= regPC + 3;
1156
                  regPC   <= regPC + 1;
1157
                  mainFSM <= "0011";
1158
                when x"FD" =>  -- JSR ,X
1159
                  temp    <= regPC + 1;
1160
                  wr      <= CPUwrite;
1161
                  addrMux <= addrSP;
1162
                  dataMux <= outTL;
1163
                  regPC   <= regPC + 1;
1164
                  mainFSM <= "0100";
1165
 
1166
 
1167
                when others =>
1168
                  mainFSM <= "0000";
1169
              end case; -- datain
1170
            end if; -- trace = '1'
1171
 
1172
          when "0011" => --##################### instruction cycle 2  
1173
            case opcode is
1174
              when x"00" | x"02" | x"04" | x"06" | x"08" | x"0A" | x"0C" | x"0E" |   -- BRSET n,opr8a,rel
1175
                   x"01" | x"03" | x"05" | x"07" | x"09" | x"0B" | x"0D" | x"0F" |   -- BRCLR n,opr8a,rel
1176
                   x"10" | x"12" | x"14" | x"16" | x"18" | x"1A" | x"1C" | x"1E" |   -- BSET n,opr8a
1177
                   x"11" | x"13" | x"15" | x"17" | x"19" | x"1B" | x"1D" | x"1F" |   -- BCLR n,opr8a
1178
                   x"30" | x"31" | x"33" | x"34" | x"36" |          -- NEG opr8a, CBEQ opr8a,rel, COM opr8a, LSR opr8a, ROR opr8a
1179
                   x"37" | x"38" | x"39" | x"3A" | x"3B" | x"3C" |  -- ASR opr8a, LSL opr8a, ROL opr8a, DEC opr8a, DBNZ opr8a,rel, INC opr8a
1180
                   x"3D" | x"4E" | x"55" | x"5E" | x"75" =>         -- TST opr8a, MOV opr8a,opr8a, LDHX opr, MOV opr8a,X+, CPHX opr
1181
                temp(7 downto 0) <= datain;
1182
                addrMux <= addrTM;
1183
                regPC <= regPC + 1;
1184
                mainFSM <= "0100";
1185
              when x"C0" | x"C1" | x"C2" | x"C3" |  -- SUB opr16a, CMP opr16a, SBC opr16a, CPX opr16a
1186
                   x"C4" | x"C5" | x"C6" | x"C7" |  -- AND opr16a, BIT opr16a, LDA opr16a, STA opr16a
1187
                   x"C8" | x"C9" | x"CA" | x"CB" |  -- EOR opr16a, ADC opr16a, ORA opr16a, ADD opr16a
1188
                   x"CC" | x"CE" | x"CF" |          -- JMP opr16a, LDX opr16a, STX opr16a
1189
                   x"D0" | x"D1" | x"D2" | x"D3" |  -- SUB oprx16,X, CMP oprx16,X, SBC oprx16,X, CPX oprx16,X
1190
                   x"D4" | x"D5" | x"D6" | x"D7" |  -- AND oprx16,X, BIT oprx16,X, LDA oprx16,X, STA oprx16,X
1191
                   x"D8" | x"D9" | x"DA" | x"DB" |  -- EOR oprx16,X, ADC oprx16,X, ORA oprx16,X, ADD oprx16,X
1192
                   x"DC" | x"DE" | x"DF" =>         -- JMP oprx16,X, LDX oprx16,X, STX oprx16,X
1193
                temp(15 downto 8) <= datain;
1194
                regPC <= regPC + 1;
1195
                mainFSM <= "0100";
1196
              when x"52" =>  -- DIV
1197
                if quotient(7 downto 0) = x"00" then
1198
                  flagZ <= '1';
1199
                else
1200
                  flagZ <= '0';
1201
                end if;
1202
                if regHX(7 downto 0) = x"00" then -- divide by zero
1203
                  flagC <= '1';
1204
                else
1205
                  if regHX(15 downto 8) < regHX(7 downto 0) then
1206
                    flagC <= '0';
1207
                    regA  <= quotient(7 downto 0);
1208
                    if remainder(8) = '1' then
1209
                      lres  := ("0000000" & remainder) + (x"00" & regHX(7 downto 0));
1210
                    else
1211
                      lres  :=  "0000000" & remainder;
1212
                    end if;
1213
                    regHX(15 downto 8) <= lres(7 downto 0);
1214
                  else
1215
                    flagC <= '1';
1216
                  end if;
1217
                end if;
1218
                mainFsm <= "0010";
1219
              when x"B7" =>  -- STA opr8a
1220
                wr <= CPUwrite;
1221
                dataMux <= outA;
1222
                temp(7 downto 0) <= datain;
1223
                addrMux <= addrTM;
1224
                regPC <= regPC + 1;
1225
                mainFSM <= "0101";
1226
              when x"BF" =>  -- STX opr8a
1227
                wr <= CPUwrite;
1228
                dataMux <= outX;
1229
                temp(7 downto 0) <= datain;
1230
                addrMux <= addrTM;
1231
                regPC <= regPC + 1;
1232
                mainFSM <= "0101";
1233
              when x"B0" | x"B1" | x"B2" | x"B3" |  -- SUB opr8a, CMP opr8a, SBC opr8a, CPX opr8a
1234
                   x"B4" | x"B5" | x"B6" |          -- AND opr8a, BIT opr8a, LDA opr8a
1235
                   x"B8" | x"B9" | x"BA" | x"BB" |  -- EOR opr8a, ADC opr8a, ORA opr8a, ADD opr8a
1236
                   x"BE" =>                         -- LDX opr8a
1237
                temp(7 downto 0) <= datain;
1238
                addrMux <= addrTM;
1239
                regPC <= regPC + 1;
1240
                mainFSM <= "0101";
1241
 
1242
              when x"20" | x"4B" | x"5B" =>  -- BRA, DBNZA rel, DBNZX rel
1243
                if datain(7) = '0' then
1244
                  regPC <= regPC + (x"00" & datain) + x"0001";
1245
                else
1246
                  regPC <= regPC + (x"FF" & datain) + x"0001";
1247
                end if;
1248
                mainFSM <= "0010";
1249
              when x"21" =>  -- BRN
1250
                regPC <= regPC + 1;
1251
                mainFSM <= "0010";
1252
              when x"22" | x"23" =>  -- BHI, BLS
1253
                if (flagC or flagZ) = opcode(0) then
1254
                  if datain(7) = '0' then
1255
                    regPC <= regPC + (x"00" & datain) + x"0001";
1256
                  else
1257
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1258
                  end if;
1259
                else
1260
                  regPC <= regPC + 1;
1261
                end if;
1262
                mainFSM <= "0010";
1263
              when x"24" | x"25" =>  -- BCC, BCS
1264
                if (flagC = opcode(0)) then
1265
                  if datain(7) = '0' then
1266
                    regPC <= regPC + (x"00" & datain) + x"0001";
1267
                  else
1268
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1269
                  end if;
1270
                else
1271
                  regPC <= regPC + 1;
1272
                end if;
1273
                mainFSM <= "0010";
1274
              when x"26" | x"27" =>  -- BNE, BEQ
1275
                if (flagZ = opcode(0)) then
1276
                  if datain(7) = '0' then
1277
                    regPC <= regPC + (x"00" & datain) + x"0001";
1278
                  else
1279
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1280
                  end if;
1281
                else
1282
                  regPC <= regPC + 1;
1283
                end if;
1284
                mainFSM <= "0010";
1285
              when x"28" | x"29" =>  -- BHCC, BHCS
1286
                if (flagH = opcode(0)) then
1287
                  if datain(7) = '0' then
1288
                    regPC <= regPC + (x"00" & datain) + x"0001";
1289
                  else
1290
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1291
                  end if;
1292
                else
1293
                  regPC <= regPC + 1;
1294
                end if;
1295
                mainFSM <= "0010";
1296
              when x"2A" | x"2B" =>  -- BPL, BMI
1297
                if (flagN = opcode(0)) then
1298
                  if datain(7) = '0' then
1299
                    regPC <= regPC + (x"00" & datain) + x"0001";
1300
                  else
1301
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1302
                  end if;
1303
                else
1304
                  regPC <= regPC + 1;
1305
                end if;
1306
                mainFSM <= "0010";
1307
              when x"2C" | x"2D" =>  -- BMC, BMS
1308
                if (flagI = opcode(0)) then
1309
                  if datain(7) = '0' then
1310
                    regPC <= regPC + (x"00" & datain) + x"0001";
1311
                  else
1312
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1313
                  end if;
1314
                else
1315
                  regPC <= regPC + 1;
1316
                end if;
1317
                mainFSM <= "0010";
1318
              when x"2E" | x"2F" =>  -- BIL, BIH
1319
                if (irq = opcode(0)) then
1320
                  if datain(7) = '0' then
1321
                    regPC <= regPC + (x"00" & datain) + x"0001";
1322
                  else
1323
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1324
                  end if;
1325
                else
1326
                  regPC <= regPC + 1;
1327
                end if;
1328
                mainFSM <= "0010";
1329
              when x"35" =>  -- STHX opr8a
1330
                wr <= CPUwrite;
1331
                dataMux <= outH;
1332
                temp(7 downto 0) <= datain;
1333
                addrMux <= addrTM;
1334
                regPC <= regPC + 1;
1335
                flagV <= '0';
1336
                flagN <= regHX(15);
1337
                if regHX = x"0000" then
1338
                  flagZ <= '1';
1339
                else
1340
                  flagZ <= '0';
1341
                end if;
1342
                mainFSM <= "0100";
1343
              when x"3F" | x"6F" =>  -- CLR opr8a, CLR oprx8,X
1344
                wr <= CPUwrite;
1345
                case opcode is
1346
                  when x"3F" =>
1347
                    temp(7 downto 0) <= datain;
1348
                  when x"6F" =>
1349
                    temp    <= temp + (x"00" & datain);
1350
                  when others =>
1351
                    temp <= x"0000";
1352
                end case;
1353
                addrMux <= addrTM;
1354
                dataMux <= outHelp;
1355
                flagZ   <= '1';
1356
                flagV   <= '0';
1357
                flagN   <= '0';
1358
                help    <= x"00";
1359
                regPC   <= regPC + 1;
1360
                mainFSM <= "0100";
1361
              when x"41" =>  -- CBEQA #opr8i,rel
1362
                if datain = regA then
1363
                  regPC <= regPC + 1;
1364
                  mainFSM <= "0100";
1365
                else
1366
                  regPC <= regPC + 2;
1367
                  mainFSM <= "0010";
1368
                end if;
1369
              when x"45" =>  -- LDHX #opr
1370
                regHX(15 downto 8) <= datain;
1371
                flagN   <= datain(7);
1372
                flagV   <= '0';
1373
                regPC   <= regPC + 1;
1374
                mainFSM <= "0100";
1375
              when x"51" =>  -- CBEQA #opr8i,rel
1376
                if datain = regHX(7 downto 0) then
1377
                  regPC <= regPC + 1;
1378
                  mainFSM <= "0100";
1379
                else
1380
                  regPC <= regPC + 2;
1381
                  mainFSM <= "0010";
1382
                end if;
1383
              when x"60" | x"61" | x"63" | x"64" | x"66" |  -- NEG oprx8,X, CBEQ oprx8,X+,rel, COM oprx8,X, LSR oprx8,X, ROR oprx8,X
1384
                   x"67" | x"68" | x"69" | x"6A" | x"6B" |  -- ASR oprx8,X, LSL oprx8,X, ROL oprx8,X, DEC oprx8,X, DBNZ oprx8,X,rel
1385
                   x"6C" | x"6D" =>  -- INC oprx8,X, TST oprx8,X
1386
                temp    <= temp + (x"00" & datain);
1387
                regPC   <= regPC + 1;
1388
                addrMux <= addrTM;
1389
                mainFSM <= "0100";
1390
              when x"65" | x"6E" =>  -- CPHX #opr, MOV #opr8i,opr8a
1391
                escape9E <= '0';
1392
                help    <= datain;
1393
                regPC   <= regPC + 1;
1394
                mainFSM <= "0100";
1395
              when x"7F" =>  -- CLR ,X
1396
                wr <= CPUread;
1397
                addrMux <= addrPC;
1398
                mainFSM <= "0010";
1399
              when x"80" | x"82" =>  -- RTI, RTT
1400
                flagV <= datain(7);
1401
                flagH <= datain(4);
1402
                flagI <= datain(3);  ------- PLEASE RESTORE AT LATER TIME
1403
                flagN <= datain(2);
1404
                flagZ <= datain(1);
1405
                flagC <= datain(0);
1406
                regSP <= regSP + 1;
1407
                mainFSM <= "0100";
1408
              when x"81" =>  -- RTS
1409
                regPC(15 downto 8) <= datain;
1410
                regSP <= regSP + 1;
1411
                mainFSM <= "0100";
1412
              when x"83" =>  -- SWI
1413
                wr <= CPUwrite;
1414
                dataMux <= outPCL;
1415
                mainFSM <= "0100";
1416
              when x"86" =>  -- PULA
1417
                regA <= datain;
1418
                addrMux <= addrPC;
1419
                mainFSM <= "0010";
1420
              when x"87" | x"89" | x"8B" =>  -- PSHA, PSHX, PSHH
1421
                wr <= CPUread;
1422
                regSP <= regSP - 1;
1423
                addrMux <= addrPC;
1424
                mainFSM <= "0010";
1425
              when x"88" =>  -- PULX
1426
                regHX(7 downto 0) <= datain;
1427
                addrMux <= addrPC;
1428
                mainFSM <= "0010";
1429
              when x"8A" =>  -- PULH
1430
                regHX(15 downto 8) <= datain;
1431
                addrMux <= addrPC;
1432
                mainFSM <= "0010";
1433
              when x"90" | x"91" =>  -- BGE, BLT
1434
                if ((flagN xor flagV) = opcode(0)) then
1435
                  if datain(7) = '0' then
1436
                    regPC <= regPC + (x"00" & datain) + x"0001";
1437
                  else
1438
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1439
                  end if;
1440
                else
1441
                  regPC <= regPC + 1;
1442
                end if;
1443
                mainFSM <= "0010";
1444
              when x"92" | x"93" =>  -- BGT, BLE
1445
                if ((flagZ or (flagN xor flagV)) = opcode(0)) then
1446
                  if datain(7) = '0' then
1447
                    regPC <= regPC + (x"00" & datain) + x"0001";
1448
                  else
1449
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1450
                  end if;
1451
                else
1452
                  regPC <= regPC + 1;
1453
                end if;
1454
                mainFSM <= "0010";
1455
              when x"AD" | x"BD" | x"ED" =>  -- BSR rel, JSR opr8a, JSR oprx8,X
1456
                regPC <= regPC + 1;
1457
                wr   <= CPUwrite;
1458
                help <= datain;
1459
                addrMux <= addrSP;
1460
                dataMux <= outPCL;
1461
                mainFSM <= "0100";
1462
              when x"BC" =>  -- JMP opr8a
1463
                regPC <= (x"00" & datain);
1464
                mainFSM <= "0010";
1465
              when x"CD" | x"DD" =>  -- JSR opr16a, JSR oprx16,X
1466
                temp(15 downto 8) <= datain;
1467
                regPC <= regPC + 1;
1468
                mainFSM <= "0100";
1469
 
1470
              when others =>
1471
                mainFSM <= "0000";
1472
            end case; -- opcode
1473
 
1474
          when "0100" => --##################### instruction cycle 3
1475
            case opcode is
1476
              when x"00" | x"02" | x"04" | x"06" | x"08" | x"0A" | x"0C" | x"0E" |   -- BRSET n,opr8a,rel
1477
                   x"01" | x"03" | x"05" | x"07" | x"09" | x"0B" | x"0D" | x"0F" =>  -- BRCLR n,opr8a,rel
1478
                if (datain and mask1(conv_integer(opcode(3 downto 1)))) /= x"00" then
1479
                  flagC <= '1';
1480
                else
1481
                  flagC <= '0';
1482
                end if;
1483
                addrMux <= addrPC;
1484
                mainFSM <= "0101";
1485
              when x"10" | x"12" | x"14" | x"16" | x"18" | x"1A" | x"1C" | x"1E" |   -- BSET n,opr8a
1486
                   x"11" | x"13" | x"15" | x"17" | x"19" | x"1B" | x"1D" | x"1F" =>  -- BCLR n,opr8a
1487
                wr <= CPUwrite;
1488
                dataMux <= outHelp;
1489
                if opcode(0) = '0' then
1490
                  help <= datain or  mask1(conv_integer(opcode(3 downto 1)));
1491
                else
1492
                  help <= datain and mask0(conv_integer(opcode(3 downto 1)));
1493
                end if;
1494
                mainFSM <= "0101";
1495
              when x"C0" | x"C1" | x"C2" | x"C3" |  -- SUB opr16a, CMP opr16a, SBC opr16a, CPX opr16a
1496
                   x"C4" | x"C5" | x"C6" |          -- AND opr16a, BIT opr16a, LDA opr16a
1497
                   x"C8" | x"C9" | x"CA" | x"CB" |  -- EOR opr16a, ADC opr16a, ORA opr16a, ADD opr16a
1498
                   x"CE" |                          -- LDX opr16a
1499
                   x"D0" | x"D1" | x"D2" | x"D3" |  -- SUB oprx16,X, CMP oprx16,X, SBC oprx16,X, CPX oprx16,X
1500
                   x"D4" | x"D5" | x"D6" |          -- AND oprx16,X, BIT oprx16,X, LDA oprx16,X
1501
                   x"D8" | x"D9" | x"DA" | x"DB" |  -- EOR oprx16,X, ADC oprx16,X, ORA oprx16,X, ADD oprx16,X
1502
                   x"DE" |                          -- LDX oprx16,X
1503
                   x"E0" | x"E1" | x"E2" | x"E3" |  -- SUB oprx8,X, CMP oprx8,X, SBC oprx8,X, CPX oprx8,X
1504
                   x"E4" | x"E5" | x"E6" |          -- AND oprx8,X, BIT oprx8,X, LDA oprx8,X
1505
                   x"E8" | x"E9" | x"EA" | x"EB" |  -- EOR oprx8,X, ADC oprx8,X, ORA oprx8,X, ADD oprx8,X
1506
                   x"EE" =>                         -- LDX oprx8,X
1507
                temp(7 downto 0) <= datain;
1508
                case opcode(7 downto 4) is
1509
                  when x"C" =>
1510
                    addrMux <= addrTM;
1511
                  when x"D" =>
1512
                    if escape9E = '0' then
1513
                      addrMux <= addrX2;
1514
                    else
1515
                      escape9E <= '0';
1516
                      addrMux <= addrS2;
1517
                    end if;
1518
                  when x"E" =>
1519
                    if escape9E = '0' then
1520
                      addrMux <= addrX1;
1521
                    else
1522
                      escape9E <= '0';
1523
                      addrMux <= addrS1;
1524
                    end if;
1525
                  when others =>
1526
                    null;
1527
                end case;
1528
                regPC <= regPC + 1;
1529
                mainFSM <= "0101";
1530
              when x"CC" =>  -- JMP opr16a
1531
                regPC <= temp(15 downto 8) & datain;
1532
                mainFSM <= "0010";
1533
              when x"DC" =>  -- JMP oprx16,X
1534
                regPC <= (temp(15 downto 8) & datain) + regHX;
1535
                mainFSM <= "0010";
1536
              when x"EC" =>  -- JMP oprx8,X
1537
                regPC <= (x"00" & datain) + regHX;
1538
                mainFSM <= "0010";
1539
              when x"C7" =>  -- STA opr16a
1540
                wr <= CPUwrite;
1541
                flagV <= '0';
1542
                flagN <= regA(7);
1543
                if regA = x"00" then
1544
                  flagZ <= '1';
1545
                else
1546
                  flagZ <= '0';
1547
                end if;
1548
                dataMux <= outA;
1549
                temp(7 downto 0) <= datain;
1550
                addrMux <= addrTM;
1551
                regPC <= regPC + 1;
1552
                mainFSM <= "0101";
1553
              when x"D7" =>  -- STA oprx16,X
1554
                wr <= CPUwrite;
1555
                flagV <= '0';
1556
                flagN <= regA(7);
1557
                if regA = x"00" then
1558
                  flagZ <= '1';
1559
                else
1560
                  flagZ <= '0';
1561
                end if;
1562
                dataMux <= outA;
1563
                temp(7 downto 0) <= datain;
1564
                if escape9E = '0' then
1565
                  addrMux <= addrX2;
1566
                else
1567
                  escape9E <= '0';
1568
                  addrMux <= addrS2;
1569
                end if;
1570
                regPC <= regPC + 1;
1571
                mainFSM <= "0101";
1572
              when x"E7" =>  -- STA oprx8,X
1573
                wr <= CPUwrite;
1574
                flagV <= '0';
1575
                flagN <= regA(7);
1576
                if regA = x"00" then
1577
                  flagZ <= '1';
1578
                else
1579
                  flagZ <= '0';
1580
                end if;
1581
                dataMux <= outA;
1582
                temp(7 downto 0) <= datain;
1583
                if escape9E = '0' then
1584
                  addrMux <= addrX1;
1585
                else
1586
                  escape9E <= '0';
1587
                  addrMux <= addrS1;
1588
                end if;
1589
                regPC <= regPC + 1;
1590
                mainFSM <= "0101";
1591
              when x"CF" =>  -- STX opr16a
1592
                wr <= CPUwrite;
1593
                flagV <= '0';
1594
                flagN <= regHX(7);
1595
                if regHX(7 downto 0) = x"00" then
1596
                  flagZ <= '1';
1597
                else
1598
                  flagZ <= '0';
1599
                end if;
1600
                dataMux <= outX;
1601
                temp(7 downto 0) <= datain;
1602
                addrMux <= addrTM;
1603
                regPC <= regPC + 1;
1604
                mainFSM <= "0101";
1605
              when x"DF" =>  -- STX oprx16,X
1606
                wr <= CPUwrite;
1607
                flagV <= '0';
1608
                flagN <= regHX(7);
1609
                if regHX(7 downto 0) = x"00" then
1610
                  flagZ <= '1';
1611
                else
1612
                  flagZ <= '0';
1613
                end if;
1614
                dataMux <= outX;
1615
                temp(7 downto 0) <= datain;
1616
                if escape9E = '0' then
1617
                  addrMux <= addrX2;
1618
                else
1619
                  escape9E <= '0';
1620
                  addrMux <= addrS2;
1621
                end if;
1622
                regPC <= regPC + 1;
1623
                mainFSM <= "0101";
1624
              when x"EF" =>  -- STX oprx8,X
1625
                wr <= CPUwrite;
1626
                flagV <= '0';
1627
                flagN <= regHX(7);
1628
                if regHX(7 downto 0) = x"00" then
1629
                  flagZ <= '1';
1630
                else
1631
                  flagZ <= '0';
1632
                end if;
1633
                dataMux <= outX;
1634
                temp(7 downto 0) <= datain;
1635
                if escape9E = '0' then
1636
                  addrMux <= addrX1;
1637
                else
1638
                  escape9E <= '0';
1639
                  addrMux <= addrS1;
1640
                end if;
1641
                regPC <= regPC + 1;
1642
                mainFSM <= "0101";
1643
              when x"30" | x"60" | x"70" =>  -- NEG opr8a, NEG oprx8,X, NEG ,X
1644
                wr      <= CPUwrite;
1645
                dataMux <= outHelp;
1646
                help    <= x"00" - datain;
1647
                tres    := x"00" - datain;
1648
                flagV   <= tres(7) and datain(7);
1649
                flagN   <= tres(7);
1650
                if tres = x"00" then
1651
                  flagZ <= '1';
1652
                  flagC <= '0';
1653
                else
1654
                  flagC <= '1';
1655
                  flagZ <= '0';
1656
                end if;
1657
                mainFSM <= "0101";
1658
              when x"31" =>  -- CBEQ opr8a,rel
1659
                help    <= datain;
1660
                addrMux <= addrPC;
1661
                mainFSM <= "0101";
1662
              when x"33" | x"63" | x"73" =>  -- COM opr8a, COM oprx8,X, COM ,X
1663
                wr      <= CPUwrite;
1664
                dataMux <= outHelp;
1665
                help    <= datain xor x"FF";
1666
                tres    := datain xor x"FF";
1667
                flagV   <= '0';
1668
                flagC   <= '1';
1669
                flagN   <= tres(7);
1670
                if tres = x"00" then
1671
                  flagZ <= '1';
1672
                else
1673
                  flagZ <= '0';
1674
                end if;
1675
                mainFSM <= "0101";
1676
              when x"34" | x"64" | x"74" =>  -- LSR opr8a, LSR oprx8,X, LSR ,X
1677
                wr      <= CPUwrite;
1678
                dataMux <= outHelp;
1679
                help    <= "0" & datain(7 downto 1);
1680
                tres    := "0" & datain(7 downto 1);
1681
                flagV   <= datain(0);
1682
                flagN   <= '0';
1683
                flagC   <= datain(0);
1684
                if tres = x"00" then
1685
                  flagZ <= '1';
1686
                else
1687
                  flagZ <= '0';
1688
                end if;
1689
                mainFSM <= "0101";
1690
              when x"35" =>  -- STHX opr8a
1691
                dataMux <= outX;
1692
                temp <= temp + 1;
1693
                mainFSM <= "0101";
1694
              when x"36" | x"66" | x"76" =>  -- ROR opr8a, ROR oprx8,X, ROR ,X
1695
                wr      <= CPUwrite;
1696
                dataMux <= outHelp;
1697
                help    <= flagC & datain(7 downto 1);
1698
                tres    := flagC & datain(7 downto 1);
1699
                flagN   <= flagC;
1700
                flagC   <= datain(0);
1701
                flagV   <= flagC xor datain(0);
1702
                if tres = x"00" then
1703
                  flagZ <= '1';
1704
                else
1705
                  flagZ <= '0';
1706
                end if;
1707
                mainFSM <= "0101";
1708
              when x"37" | x"67" | x"77" =>  -- ASR opr8a, ASR oprx8,X, ASR ,X
1709
                wr      <= CPUwrite;
1710
                dataMux <= outHelp;
1711
                help    <= datain(7) & datain(7 downto 1);
1712
                tres    := datain(7) & datain(7 downto 1);
1713
                flagN   <= datain(7);
1714
                flagC   <= datain(0);
1715
                flagV   <= datain(7) xor datain(0);
1716
                if tres = x"00" then
1717
                  flagZ <= '1';
1718
                else
1719
                  flagZ <= '0';
1720
                end if;
1721
                mainFSM <= "0101";
1722
              when x"38" | x"68" | x"78" =>  -- LSL opr8a, LSL oprx8,X, LSL ,X
1723
                wr      <= CPUwrite;
1724
                dataMux <= outHelp;
1725
                help    <= datain(6 downto 0) & "0";
1726
                tres    := datain(6 downto 0) & "0";
1727
                flagN   <= datain(6);
1728
                flagC   <= datain(7);
1729
                flagV   <= datain(7) xor datain(6);
1730
                if tres = x"00" then
1731
                  flagZ <= '1';
1732
                else
1733
                  flagZ <= '0';
1734
                end if;
1735
                mainFSM <= "0101";
1736
              when x"39" | x"69" | x"79" =>  -- ROL opr8a, ROL oprx8,X, ROL ,X
1737
                wr      <= CPUwrite;
1738
                dataMux <= outHelp;
1739
                help    <= datain(6 downto 0) & flagC;
1740
                tres    := datain(6 downto 0) & flagC;
1741
                flagN   <= datain(6);
1742
                flagC   <= datain(7);
1743
                flagV   <= datain(7) xor datain(6);
1744
                if tres = x"00" then
1745
                  flagZ <= '1';
1746
                else
1747
                  flagZ <= '0';
1748
                end if;
1749
                mainFSM <= "0101";
1750
              when x"3A" | x"6A" | x"7A" =>  -- DEC opr8a, DEC oprx8,X, DEC ,X
1751
                wr      <= CPUwrite;
1752
                dataMux <= outHelp;
1753
                help    <= datain - 1;
1754
                tres    := datain - 1;
1755
                flagN   <= tres(7);
1756
                if datain = x"80" then
1757
                  flagV <= '1';
1758
                else
1759
                  flagV <= '0';
1760
                end if;
1761
                if tres = x"00" then
1762
                  flagZ <= '1';
1763
                else
1764
                  flagZ <= '0';
1765
                end if;
1766
                mainFSM <= "0101";
1767
              when x"3B" | x"6B" | x"7B" =>  -- DBNZ opr8a,rel, DBNZ oprx8,X,rel, DBNZ ,X,rel
1768
                wr      <= CPUwrite;
1769
                dataMux <= outHelp;
1770
                help    <= datain - 1;
1771
                mainFSM <= "0101";
1772
              when x"3C" | x"6C" | x"7C" =>  -- INC opr8a, INC oprx8,X, INC ,X
1773
                wr      <= CPUwrite;
1774
                dataMux <= outHelp;
1775
                help    <= datain + 1;
1776
                tres    := datain + 1;
1777
                flagN   <= tres(7);
1778
                if datain = x"7F" then
1779
                  flagV <= '1';
1780
                else
1781
                  flagV <= '0';
1782
                end if;
1783
                if tres = x"00" then
1784
                  flagZ <= '1';
1785
                else
1786
                  flagZ <= '0';
1787
                end if;
1788
                mainFSM <= "0101";
1789
              when x"3D" | x"6D" | x"7D" =>  -- TST opr8a, TST oprx8,X, TST ,X
1790
                flagV   <= '0';
1791
                flagN   <= datain(7);
1792
                if datain = x"00" then
1793
                  flagZ <= '1';
1794
                else
1795
                  flagZ <= '0';
1796
                end if;
1797
                addrMux <= addrPC;
1798
                mainFSM <= "0010";
1799
              when x"3F" | x"6F" =>  -- CLR opr8a, CLR oprx8,X
1800
                wr <= CPUread;
1801
                addrMux <= addrPC;
1802
                mainFSM <= "0010";
1803
              when x"41" =>  -- CBEQA #opr8i,rel
1804
                if datain(7) = '0' then
1805
                  regPC <= regPC + (x"00" & datain) + x"0001";
1806
                else
1807
                  regPC <= regPC + (x"FF" & datain) + x"0001";
1808
                end if;
1809
                mainFSM <= "0010";
1810
              when x"45" =>  -- LDHX #opr
1811
                regHX(7 downto 0) <= datain;
1812
                if regHX(15 downto 8) = x"00" and datain = x"00" then
1813
                  flagZ <= '1';
1814
                else
1815
                  flagZ <= '0';
1816
                end if;
1817
                regPC <= regPC + 1;
1818
                mainFSM <= "0010";
1819
              when x"4E" =>  -- MOV opr8a,opr8a
1820
                help    <= datain;
1821
                flagV   <= '0';
1822
                flagN   <= datain(7);
1823
                if datain = x"00" then
1824
                  flagZ <= '1';
1825
                else
1826
                  flagZ <= '0';
1827
                end if;
1828
                addrMux <= addrPC;
1829
                mainFSM <= "0101";
1830
              when x"55" =>  -- LDHX opr
1831
                regHX(15 downto 8) <= datain;
1832
                temp <= temp + 1;
1833
                mainFSM <= "0101";
1834
              when x"5E" =>  -- MOV opr8a,X+
1835
                help  <= datain;
1836
                flagV <= '0';
1837
                flagN <= datain(7);
1838
                if datain = x"00" then
1839
                  flagZ <= '1';
1840
                else
1841
                  flagZ <= '0';
1842
                end if;
1843
                dataMux <= outHelp;
1844
                addrMux <= addrHX;
1845
                wr      <= CPUwrite;
1846
                mainFSM <= "0101";
1847
              when x"61" =>  -- CBEQ oprx8,X+,rel
1848
                if escape9E = '0' then
1849
                  regHX   <= regHX + 1;
1850
                else
1851
                  escape9E <= '0';
1852
                end if;
1853
                addrMux <= addrPC;
1854
                if datain = regA then
1855
                  mainFSM <= "0101";
1856
                else
1857
                  regPC <= regPC + 2;
1858
                  mainFSM <= "0010";
1859
                end if;
1860
              when x"65" =>  -- CPHX #opr
1861
                lres := regHX - (help & datain);
1862
                flagN <= lres(15);
1863
                if lres = x"0000" then
1864
                  flagZ <= '1';
1865
                else
1866
                  flagZ <= '0';
1867
                end if;
1868
                flagV <= (regHX(15) and (not help(7)) and (not lres(15))) or
1869
                         ((not regHX(15)) and help(7) and lres(15));
1870
                flagC <= ((not regHX(15)) and help(7)) or
1871
                         (help(7) and lres(15)) or
1872
                         (lres(15) and (not help(7)));
1873
                regPC <= regPC + 1;
1874
                mainFSM <= "0010";
1875
              when x"6E" =>  -- MOV #opr8i,opr8a
1876
                temp(7 downto 0) <= datain;
1877
                flagV <= '0';
1878
                flagN <= help(7);
1879
                if help = x"00" then
1880
                  flagZ <= '1';
1881
                else
1882
                  flagZ <= '0';
1883
                end if;
1884
                wr      <= CPUwrite;
1885
                dataMux <= outHelp;
1886
                addrMux <= addrTM;
1887
                regPC   <= regPC + 1;
1888
                mainFSM <= "0101";
1889
              when x"71" =>  -- CBEQ ,X+,rel
1890
                addrMux <= addrPC;
1891
                regHX <= regHX + 1;
1892
                if datain = regA then
1893
                  mainFSM <= "0101";
1894
                else
1895
                  regPC <= regPC + 2;
1896
                  mainFSM <= "0010";
1897
                end if;
1898
              when x"75" =>  -- CPHX opr
1899
                help <= datain;
1900
                temp <= temp + 1;
1901
                mainFSM <= "0101";
1902
              when x"7E" =>  -- MOV ,X+,opr8a
1903
                help <= datain;
1904
                temp <= x"0000";
1905
                addrMux <= addrPC;
1906
                mainFSM <= "0101";
1907
              when x"80" | x"82" =>  -- RTI, RTT
1908
                regA  <= datain;
1909
                regSP <= regSP + 1;
1910
                mainFSM <= "0101";
1911
              when x"81" =>  -- RTS
1912
                regPC(7 downto 0) <= datain;
1913
                addrMux <= addrPC;
1914
                mainFSM <= "0010";
1915
              when x"83" =>  -- SWI
1916
                regSP <= regSP - 1;
1917
                dataMux <= outPCH;
1918
                mainFSM <= "0101";
1919
              when x"AD" | x"BD" | x"ED" =>  -- BSR rel, JSR opr8a, JSR oprx8,X
1920
                regSP <= regSP - 1;
1921
                dataMux <= outPCH;
1922
                mainFSM <= "0101";
1923
              when x"FD" =>  -- JSR ,X
1924
                regSP <= regSP - 1;
1925
                dataMux <= outTH;
1926
                mainFSM <= "0101";
1927
              when x"CD" | x"DD" =>  -- JSR opr16a, JSR oprx16,X
1928
                wr   <= CPUwrite;
1929
                temp(7 downto 0) <= datain;
1930
                regPC   <= regPC + 1;
1931
                addrMux <= addrSP;
1932
                dataMux <= outPCL;
1933
                mainFSM <= "0101";
1934
 
1935
              when others =>
1936
                mainFSM <= "0000";
1937
            end case; -- opcode
1938
 
1939
          when "0101" => --##################### instruction cycle 4
1940
            case opcode is
1941
              when x"00" | x"02" | x"04" | x"06" | x"08" | x"0A" | x"0C" | x"0E" |   -- BRSET n,opr8a,rel
1942
                   x"01" | x"03" | x"05" | x"07" | x"09" | x"0B" | x"0D" | x"0F" =>  -- BRCLR n,opr8a,rel
1943
                if (opcode(0) xor flagC) = '1' then
1944
                  if datain(7) = '0' then
1945
                    regPC <= regPC + (x"00" & datain) + x"0001";
1946
                  else
1947
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1948
                  end if;
1949
                else
1950
                  regPC <= regPC + 1;
1951
                end if;
1952
                addrMux <= addrPC;
1953
                mainFSM <= "0010";
1954
              when x"10" | x"12" | x"14" | x"16" | x"18" | x"1A" | x"1C" | x"1E" |   -- BSET n,opr8a
1955
                   x"11" | x"13" | x"15" | x"17" | x"19" | x"1B" | x"1D" | x"1F" |   -- BCLR n,opr8a
1956
                   x"30" | x"33" | x"34" | x"35" | x"36" |  -- NEG opr8a, COM opr8a, LSR opr8a, STHX opr8a, ROR opr8a
1957
                   x"37" | x"38" | x"39" | x"3A" | x"3C" |  -- ASR opr8a, LSL opr8a, ROL opr8a, DEC opr8a, INC opr8a
1958
                   x"60" | x"63" | x"64" | x"66" | x"67" |  -- NEG oprx8,X, COM oprx8,X, LSR oprx8,X, ROR oprx8,X, ASR oprx8,X
1959
                   x"68" | x"69" | x"6A" | x"6C" | x"6E" |  -- LSL oprx8,X, ROL oprx8,X, DEC oprx8,X, INC oprx8,X, MOV #opr8i,opr8a
1960
                   x"70" | x"73" | x"74" | x"76" | x"77" | x"78" | x"79" | -- NEG ,X, COM ,X, LSR ,X, ROR ,X, ASR ,X, LSL ,X, ROL ,X
1961
                   x"7A" | x"7C" |   -- DEC ,X, INC ,X
1962
                   x"B7" | x"BF" | x"C7" | x"CF" |  -- STA opr8a, STX opr8a, STA opr16a, STX opr16a
1963
                   x"D7" | x"DF" | x"E7" | x"EF" |  -- STA oprx16,X, STX oprx16,X, STA oprx8,X, STX oprx8,X
1964
                   x"F7" | x"FF" =>  -- STA ,X, STX ,X
1965
                wr      <= CPUread;
1966
                addrMux <= addrPC;
1967
                mainFSM <= "0010";
1968
              when x"31" =>  -- CBEQ opr8a,rel
1969
                if regA = help then
1970
                  if datain(7) = '0' then
1971
                    regPC <= regPC + (x"00" & datain) + x"0001";
1972
                  else
1973
                    regPC <= regPC + (x"FF" & datain) + x"0001";
1974
                  end if;
1975
                else
1976
                  regPC <= regPC + 1;
1977
                end if;
1978
                mainFSM <= "0010";
1979
              when x"3B" | x"6B" | x"7B" =>  -- DBNZ opr8a,rel, DBNZ oprx8,X,rel, DBNZ ,X,rel
1980
                wr      <= CPUread;
1981
                addrMux <= addrPC;
1982
                mainFSM <= "0110";
1983
              when x"4E" =>  -- MOV opr8a,opr8a
1984
                temp(7 downto 0) <= datain;
1985
                regPC <= regPC + 1;
1986
                wr <= CPUwrite;
1987
                addrMux <= addrTM;
1988
                dataMux <= outHelp;
1989
                mainFSM <= "0110";
1990
              when x"55" =>  -- LDHX opr
1991
                regHX(7 downto 0) <= datain;
1992
                flagV <= '0';
1993
                flagN <= regHX(15);
1994
                if (datain = x"00") and (regHX(15 downto 8) = x"00") then
1995
                  flagZ <= '1';
1996
                else
1997
                  flagZ <= '0';
1998
                end if;
1999
                addrMux <= addrPC;
2000
                mainFSM <= "0010";
2001
              when x"5E" =>  -- MOV opr8a,X+
2002
                wr      <= CPUread;
2003
                addrMux <= addrPC;
2004
                regHX   <= regHX + 1;
2005
                mainFSM <= "0010";
2006
              when x"61" | x"71" =>  -- CBEQ oprx8,X+,rel, CBEQ ,X+,rel
2007
                if datain(7) = '0' then
2008
                  regPC <= regPC + (x"00" & datain) + x"0001";
2009
                else
2010
                  regPC <= regPC + (x"FF" & datain) + x"0001";
2011
                end if;
2012
                mainFSM <= "0010";
2013
              when x"75" =>  -- CPHX opr
2014
                lres := regHX - (help & datain);
2015
                flagN <= lres(15);
2016
                if lres = x"0000" then
2017
                  flagZ <= '1';
2018
                else
2019
                  flagZ <= '0';
2020
                end if;
2021
                flagV <= (regHX(15) and (not help(7)) and (not lres(15))) or
2022
                         ((not regHX(15)) and help(7) and lres(15));
2023
                flagC <= ((not regHX(15)) and help(7)) or
2024
                         (help(7) and lres(15)) or
2025
                         (lres(15) and (not help(7)));
2026
                addrMux <= addrPC;
2027
                mainFSM <= "0010";
2028
              when x"7E" =>  -- MOV ,X+,opr8a
2029
                flagV <= '0';
2030
                flagN <= help(7);
2031
                if help = x"00" then
2032
                  flagZ <= '1';
2033
                else
2034
                  flagZ <= '0';
2035
                end if;
2036
                temp(7 downto 0) <= datain;
2037
                wr <= CPUwrite;
2038
                dataMux <= outHelp;
2039
                addrMux <= addrTM;
2040
                regPC   <= regPC + 1;
2041
                regHX   <= regHX + 1;
2042
                mainFSM <= "0110";
2043
              when x"80" | x"82" =>  -- RTI, RTT
2044
                regHX(7 downto 0) <= datain;
2045
                regSP <= regSP + 1;
2046
                mainFSM <= "0110";
2047
              when x"83" =>  -- SWI
2048
                regSP <= regSP - 1;
2049
                dataMux <= outX;
2050
                help(7) <= flagV;
2051
                help(6) <= '1';
2052
                help(5) <= '1';
2053
                help(4) <= flagH;
2054
                help(3) <= flagI;
2055
                help(2) <= flagN;
2056
                help(1) <= flagZ;
2057
                help(0) <= flagC;
2058
                mainFSM <= "0110";
2059
              when x"A0" | x"B0" | x"C0" | x"D0" | x"E0" | x"F0" =>  -- SUB #opr8i, SUB opr8a, SUB opr16a, SUB oprx16,X, SUB oprx8,X, SUB ,X
2060
                addrMux <= addrPC;
2061
                regA <= regA - datain;
2062
                tres := regA - datain;
2063
                flagN <= tres(7);
2064
                if tres = x"00" then
2065
                  flagZ <= '1';
2066
                else
2067
                  flagZ <= '0';
2068
                end if;
2069
                flagV <= (regA(7) and (not datain(7)) and (not tres(7))) or
2070
                         ((not regA(7)) and datain(7) and tres(7));
2071
                flagC <= ((not regA(7)) and datain(7)) or
2072
                         (datain(7) and tres(7)) or
2073
                         (tres(7) and (not regA(7)));
2074
                if opcode = x"A0" then
2075
                  regPC <= regPC + 1;
2076
                end if;
2077
                mainFSM <= "0010";
2078
              when x"A1" | x"B1" | x"C1" | x"D1" | x"E1" | x"F1" =>  -- CMP #opr8i, CMP opr8a, CMP opr16a, CMP oprx16,X, CMP oprx8,X, CMP ,X
2079
                addrMux <= addrPC;
2080
                tres := regA - datain;
2081
                flagN <= tres(7);
2082
                if tres = x"00" then
2083
                  flagZ <= '1';
2084
                else
2085
                  flagZ <= '0';
2086
                end if;
2087
                flagV <= (regA(7) and (not datain(7)) and (not tres(7))) or
2088
                         ((not regA(7)) and datain(7) and tres(7));
2089
                flagC <= ((not regA(7)) and datain(7)) or
2090
                         (datain(7) and tres(7)) or
2091
                         (tres(7) and (not regA(7)));
2092
                if opcode = x"A1" then
2093
                  regPC <= regPC + 1;
2094
                end if;
2095
                mainFSM <= "0010";
2096
              when x"A2" | x"B2" | x"C2" | x"D2" | x"E2" | x"F2" =>  -- SBC #opr8i, SBC opr8a, SBC opr16a, SBC oprx16,X, SBC oprx8,X, SBC ,X
2097
                addrMux <= addrPC;
2098
                regA <= regA - datain - ("0000000" & flagC);
2099
                tres := regA - datain - ("0000000" & flagC);
2100
                flagN <= tres(7);
2101
                if tres = x"00" then
2102
                  flagZ <= '1';
2103
                else
2104
                  flagZ <= '0';
2105
                end if;
2106
                flagV <= (regA(7) and (not datain(7)) and (not tres(7))) or
2107
                         ((not regA(7)) and datain(7) and tres(7));
2108
                flagC <= ((not regA(7)) and datain(7)) or
2109
                         (datain(7) and tres(7)) or
2110
                         (tres(7) and (not regA(7)));
2111
                if opcode = x"A2" then
2112
                  regPC <= regPC + 1;
2113
                end if;
2114
                mainFSM <= "0010";
2115
              when x"A3" | x"B3" | x"C3" | x"D3" | x"E3" | x"F3" =>  -- CPX #opr8i, CPX opr8a, CPX opr16a, CPX oprx16,X, CPX oprx8,X, CPX ,X
2116
                addrMux <= addrPC;
2117
                tres := regHX(7 downto 0) - datain;
2118
                flagN <= tres(7);
2119
                if tres = x"00" then
2120
                  flagZ <= '1';
2121
                else
2122
                  flagZ <= '0';
2123
                end if;
2124
                flagV <= (regHX(7) and (not datain(7)) and (not tres(7))) or
2125
                         ((not regHX(7)) and datain(7) and tres(7));
2126
                flagC <= ((not regHX(7)) and datain(7)) or
2127
                         (datain(7) and tres(7)) or
2128
                         (tres(7) and (not regHX(7)));
2129
                if opcode = x"A3" then
2130
                  regPC <= regPC + 1;
2131
                end if;
2132
                mainFSM <= "0010";
2133
              when x"A4" | x"B4" | x"C4" | x"D4" | x"E4" | x"F4" =>  -- AND #opr8i, AND opr8a, AND opr16a, AND oprx16,X, AND oprx8,X, AND ,X
2134
                addrMux <= addrPC;
2135
                regA <= regA and datain;
2136
                tres := regA and datain;
2137
                flagN <= tres(7);
2138
                if tres = x"00" then
2139
                  flagZ <= '1';
2140
                else
2141
                  flagZ <= '0';
2142
                end if;
2143
                flagV <= '0';
2144
                if opcode = x"A4" then
2145
                  regPC <= regPC + 1;
2146
                end if;
2147
                mainFSM <= "0010";
2148
              when x"A5" | x"B5" | x"C5" | x"D5" | x"E5" | x"F5" =>  -- BIT #opr8i, BIT opr8a, BIT opr16a, BIT oprx16,X, BIT oprx8,X, BIT ,X
2149
                addrMux <= addrPC;
2150
                tres := regA and datain;
2151
                flagN <= tres(7);
2152
                if tres = x"00" then
2153
                  flagZ <= '1';
2154
                else
2155
                  flagZ <= '0';
2156
                end if;
2157
                flagV <= '0';
2158
                if opcode = x"A5" then
2159
                  regPC <= regPC + 1;
2160
                end if;
2161
                mainFSM <= "0010";
2162
              when x"A6" | x"B6" | x"C6" | x"D6" | x"E6" | x"F6" =>  -- LDA #opr8i, LDA opr8a, LDA opr16a, LDA oprx16,X, LDA oprx8,X, LDA ,X
2163
                addrMux <= addrPC;
2164
                regA <= datain;
2165
                flagN <= datain(7);
2166
                if datain = x"00" then
2167
                  flagZ <= '1';
2168
                else
2169
                  flagZ <= '0';
2170
                end if;
2171
                flagV <= '0';
2172
                if opcode = x"A6" then
2173
                  regPC <= regPC + 1;
2174
                end if;
2175
                mainFSM <= "0010";
2176
              when x"A7" =>  -- AIS
2177
                if datain(7) = '0' then
2178
                  regSP <= regSP + (x"00" & datain);
2179
                else
2180
                  regSP <= regSP + (x"FF" & datain);
2181
                end if;
2182
                regPC <= regPC + 1;
2183
                mainFSM <= "0010";
2184
              when x"A8" | x"B8" | x"C8" | x"D8" | x"E8" | x"F8" =>  -- EOR #opr8i, EOR opr8a, EOR opr16a, EOR oprx16,X, EOR oprx8,X, EOR ,X
2185
                addrMux <= addrPC;
2186
                regA <= regA xor datain;
2187
                tres := regA xor datain;
2188
                flagN <= tres(7);
2189
                if tres = x"00" then
2190
                  flagZ <= '1';
2191
                else
2192
                  flagZ <= '0';
2193
                end if;
2194
                flagV <= '0';
2195
                if opcode = x"A8" then
2196
                  regPC <= regPC + 1;
2197
                end if;
2198
                mainFSM <= "0010";
2199
              when x"A9" | x"B9" | x"C9" | x"D9" | x"E9" | x"F9" =>  -- ADC #opr8i, ADC opr8a, ADC opr16a, ADC oprx16,X, ADC oprx8,X, ADC ,X
2200
                addrMux <= addrPC;
2201
                regA <= regA + datain + ("0000000" & flagC);
2202
                tres := regA + datain + ("0000000" & flagC);
2203
                flagN <= tres(7);
2204
                if tres = x"00" then
2205
                  flagZ <= '1';
2206
                else
2207
                  flagZ <= '0';
2208
                end if;
2209
                flagH <= (regA(3) and datain(3)) or
2210
                         (datain(3) and (not tres(3))) or
2211
                         ((not tres(3)) and regA(3));
2212
                flagV <= (regA(7) and datain(7) and (not tres(7))) or
2213
                         ((not regA(7)) and (not datain(7)) and tres(7));
2214
                flagC <= (regA(7) and datain(7)) or
2215
                         (datain(7) and (not tres(7))) or
2216
                         ((not tres(7)) and regA(7));
2217
                if opcode = x"A9" then
2218
                  regPC <= regPC + 1;
2219
                end if;
2220
                mainFSM <= "0010";
2221
              when x"AA" | x"BA" | x"CA" | x"DA" | x"EA" | x"FA" =>  -- ORA #opr8i, ORA opr8a, ORA opr16a, ORA oprx16,X, ORA oprx8,X, ORA ,X
2222
                addrMux <= addrPC;
2223
                regA <= regA or datain;
2224
                tres := regA or datain;
2225
                flagN <= tres(7);
2226
                if tres = x"00" then
2227
                  flagZ <= '1';
2228
                else
2229
                  flagZ <= '0';
2230
                end if;
2231
                flagV <= '0';
2232
                if opcode = x"AA" then
2233
                  regPC <= regPC + 1;
2234
                end if;
2235
                mainFSM <= "0010";
2236
              when x"AB" | x"BB" | x"CB" | x"DB" | x"EB" | x"FB" =>  -- ADD #opr8i, ADD opr8a, ADD opr16a, ADD oprx16,X, ADD oprx8,X, ADD ,X
2237
                addrMux <= addrPC;
2238
                regA <= regA + datain;
2239
                tres := regA + datain;
2240
                flagN <= tres(7);
2241
                if tres = x"00" then
2242
                  flagZ <= '1';
2243
                else
2244
                  flagZ <= '0';
2245
                end if;
2246
                flagH <= (regA(3) and datain(3)) or
2247
                         (datain(3) and (not tres(3))) or
2248
                         ((not tres(3)) and regA(3));
2249
                flagV <= (regA(7) and datain(7) and (not tres(7))) or
2250
                         ((not regA(7)) and (not datain(7)) and tres(7));
2251
                flagC <= (regA(7) and datain(7)) or
2252
                         (datain(7) and (not tres(7))) or
2253
                         ((not tres(7)) and regA(7));
2254
                if opcode = x"AB" then
2255
                  regPC <= regPC + 1;
2256
                end if;
2257
                mainFSM <= "0010";
2258
              when x"AE" | x"BE" | x"CE" | x"DE" | x"EE" | x"FE" =>  -- LDX #opr8i, LDX opr8a, LDX opr16a, LDX oprx16,X, LDX oprx8,X, LDX ,X
2259
                addrMux <= addrPC;
2260
                regHX(7 downto 0) <= datain;
2261
                flagN <= datain(7);
2262
                if datain = x"00" then
2263
                  flagZ <= '1';
2264
                else
2265
                  flagZ <= '0';
2266
                end if;
2267
                flagV <= '0';
2268
                if opcode = x"AE" then
2269
                  regPC <= regPC + 1;
2270
                end if;
2271
                mainFSM <= "0010";
2272
              when x"AF" =>  -- AIX
2273
                if datain(7) = '0' then
2274
                  regHX <= regHX + (x"00" & datain);
2275
                else
2276
                  regHX <= regHX + (x"FF" & datain);
2277
                end if;
2278
                regPC <= regPC + 1;
2279
                mainFSM <= "0010";
2280
              when x"AD" =>  -- BSR rel
2281
                wr <= CPUread;
2282
                addrMux <= addrPC;
2283
                if help(7) = '0' then
2284
                  regPC <= regPC + (x"00" & help);
2285
                else
2286
                  regPC <= regPC + (x"FF" & help);
2287
                end if;
2288
                regSP <= regSP - 1;
2289
                mainFSM <= "0010";
2290
              when x"BD" =>  -- JSR opr8a
2291
                wr <= CPUread;
2292
                addrMux <= addrPC;
2293
                regPC <= x"00" & help;
2294
                regSP <= regSP - 1;
2295
                mainFSM <= "0010";
2296
              when x"CD" | x"DD" =>  -- JSR opr16a, JSR oprx16,X
2297
                regSP <= regSP - 1;
2298
                dataMux <= outPCH;
2299
                mainFSM <= "0110";
2300
              when x"ED" =>  -- JSR oprx8,X
2301
                wr <= CPUread;
2302
                addrMux <= addrPC;
2303
                regPC <= (x"00" & help) + regHX;
2304
                regSP <= regSP - 1;
2305
                mainFSM <= "0010";
2306
              when x"FD" =>  -- JSR ,X
2307
                wr <= CPUread;
2308
                addrMux <= addrPC;
2309
                regPC <= regHX;
2310
                regSP <= regSP - 1;
2311
                mainFSM <= "0010";
2312
 
2313
              when others =>
2314
                mainFSM <= "0000";
2315
            end case; -- opcode
2316
 
2317
          when "0110" => --##################### instruction cycle 5
2318
            case opcode is
2319
              when x"3B" | x"6B" | x"7B" => -- DBNZ opr8a,rel, DBNZ oprx8,X,rel, DBNZ ,X,rel
2320
                if help = x"00" then
2321
                  regPC <= regPC + 1;
2322
                else
2323
                  if datain(7) = '0' then
2324
                    regPC <= regPC + (x"00" & datain) + x"0001";
2325
                  else
2326
                    regPC <= regPC + (x"FF" & datain) + x"0001";
2327
                  end if;
2328
                end if;
2329
                mainFSM <= "0010";
2330
              when x"4E" | x"7E" =>  -- MOV opr8a,opr8a, MOV ,X+,opr8a
2331
                wr <= CPUread;
2332
                addrMux <= addrPC;
2333
                mainFSM <= "0010";
2334
              when x"80" | x"82" =>  -- RTI, RTT
2335
                regPC(15 downto 8) <= datain;
2336
                regSP <= regSP + 1;
2337
                mainFSM <= "0111";
2338
              when x"83" =>  -- SWI
2339
                regSP <= regSP - 1;
2340
                dataMux <= outA;
2341
                mainFSM <= "0111";
2342
              when x"CD" =>  -- JSR opr16a
2343
                wr <= CPUread;
2344
                addrMUX <= addrPC;
2345
                regSP <= regSP - 1;
2346
                regPC <= temp;
2347
                mainFSM <= "0010";
2348
              when x"DD" =>  -- JSR oprx16,X
2349
                wr <= CPUread;
2350
                addrMUX <= addrPC;
2351
                regSP <= regSP - 1;
2352
                regPC <= temp + regHX;
2353
                mainFSM <= "0010";
2354
 
2355
              when others =>
2356
                mainFSM <= "0000";
2357
            end case; -- opcode
2358
 
2359
          when "0111" => --##################### instruction cycle 6
2360
            case opcode is
2361
              when x"80" | x"82" =>  -- RTI, RTT
2362
                regPC(7 downto 0) <= datain;
2363
                addrMux <= addrPC;
2364
                mainFSM <= "0010";
2365
              when x"83" =>  -- SWI
2366
                regSP   <= regSP - 1;
2367
                dataMux <= outHelp;
2368
                flagI   <= '1';
2369
                if trace = '0' then
2370
                  if irqRequest = '0' then
2371
                    temp    <= x"FFFC"; -- SWI vector
2372
                  else
2373
                    irqRequest <= '0';
2374
                    temp    <= x"FFFA"; -- IRQ vector
2375
                  end if;
2376
                  mainFSM <= "1000";
2377
                else
2378
                  temp    <= x"FFF8"; -- trace vector
2379
                  mainFSM <= "1011";
2380
                end if;
2381
 
2382
              when others =>
2383
                mainFSM <= "0000";
2384
            end case; -- opcode
2385
          when "1000" => --##################### instruction cycle 7
2386
            case opcode is
2387
              when x"83" =>  -- SWI
2388
                wr <= CPUread;
2389
                addrMux <= addrTM;
2390
                regSP   <= regSP - 1;
2391
                mainFSM <= "1001";
2392
 
2393
              when others =>
2394
                mainFSM <= "0000";
2395
            end case;
2396
          when "1001" => --##################### instruction cycle 8
2397
            case opcode is
2398
              when x"83" =>  -- SWI
2399
                regPC(15 downto 8) <= datain;
2400
                temp <= temp + 1;
2401
                mainFSM <= "1010";
2402
 
2403
              when others =>
2404
                mainFSM <= "0000";
2405
            end case;
2406
          when "1010" => --##################### instruction cycle 9
2407
            case opcode is
2408
              when x"83" =>  -- SWI
2409
                regPC(7 downto 0) <= datain;
2410
                addrMux <= addrPC;
2411
                mainFSM <= "0010";
2412
 
2413
              when others =>
2414
                mainFSM <= "0000";
2415
            end case;
2416
          when "1011" => --##################### instruction cycle 6a, trace
2417
            regSP   <= regSP - 1;
2418
            dataMux <= outCode;
2419
            trace   <= '0';
2420
            trace_i <= '0';
2421
            mainFSM <= "1000";
2422
 
2423
          when others =>
2424
            mainFSM <= "0000";
2425
        end case; -- mainFSM
2426
      end if;
2427
    end if;
2428
  end process;
2429
 
2430
end behavior;

powered by: WebSVN 2.1.0

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