§ Код процессора

Процессор проходит все тесты ZXALL.
Дата последней ревизии: 21 сен 2024.
1/* verilator lint_off WIDTH */
2/* verilator lint_off CASEX */
3/* verilator lint_off CASEINCOMPLETE */
4/* verilator lint_off CASEOVERLAP */
5module z80
6(
7    // -----------------------------------------------------------------
8    // Ввод-вывод
9    // -----------------------------------------------------------------
10    input               clock,          // 3.5 или 25 Мгц
11    input               reset_n,        // =0 Сброс процессора
12    input               compat,         // =1 Включена совместимость с Z80 Cycles
13    input               hold,           // Если 0: не выполнять инструкции
14    input               irq,            // Вызов IRQ на позитивном фронте
15    output       [15:0] address,        // Адресная шина
16    input        [ 7:0] i_data,         // Входящие данные с шины
17    output  reg  [ 7:0] o_data,         // Данные на запись
18    output  reg         we,             // =1 Запись в память
19    output              m0,             // =1 Сигнал начала инструкции
20    input        [ 7:0] portin,         // portin=port[address]
21    output  reg         portrd,         // Сигнал чтения из порта address
22    output  reg         portwe,         // Сигнал записи в порт address
23    // -----------------------------------------------------------------
24    // Регистры процессора z80 [здесь для отладки]
25    // -----------------------------------------------------------------
26    // Основной и дополнительный наборы регистров
27    output  reg  [15:0] bc,
28    output  reg  [15:0] de,
29    output  reg  [15:0] hl,
30    output  reg  [15:0] af,
31    output  reg  [15:0] bc_prime,
32    output  reg  [15:0] de_prime,
33    output  reg  [15:0] hl_prime,
34    output  reg  [15:0] af_prime,
35    // Индексные регистры
36    output  reg [15:0]  ix,
37    output  reg [15:0]  iy,
38    // Регистры управления программой
39    output  reg [15:0]  pc,
40    output  reg [15:0]  sp,
41    output  reg [15:0]  ir,
42    output  reg [ 1:0]  i_mode,
43    output  reg         iff1,
44    output  reg         iff2
45    // -----------------------------------------------------------------------------
46);
47// LOCALPARAM
48// -----------------------------------------------------------------------------
49localparam
50    CF = 8, NF = 9, PF = 10, F3F = 11, HF = 12, F5F = 13, ZF = 14, SF = 15;
51localparam
52    alu_add = 0, alu_rlc =  8, alu_inc = 16, alu_rlca = 24,
53    alu_adc = 1, alu_rrc =  9, alu_dec = 17, alu_rrca = 25,
54    alu_sub = 2, alu_rl  = 10,               alu_rla  = 26,
55    alu_sbc = 3, alu_rr  = 11,               alu_rra  = 27,
56    alu_and = 4, alu_sla = 12, alu_daa = 20, alu_bit  = 28,
57    alu_xor = 5, alu_sra = 13, alu_cpl = 21, alu_set  = 29,
58    alu_or  = 6, alu_sll = 14, alu_scf = 22, alu_res  = 30,
59    alu_cp  = 7, alu_srl = 15, alu_ccf = 23;
60localparam
61    spec_exaf   = 1,
62    spec_exx    = 2,
63    spec_exdehl = 3;
64localparam
65    ldcmd_ldi   = 1,
66    ldcmd_ldd   = 2,
67    ldcmd_cpi   = 3,
68    ldcmd_cpd   = 4;
69assign address = bus ? cp : pc;
70assign m0 = (t_state == 0 && prefix == 0 && delay == 0);
71// Основная логика работы процессора
72// -----------------------------------------------------------------------------
73always @(posedge clock) if (hold) begin
74// Сброс регистров управления
75exxw     <= 0;
76ldcmd    <= 0;
77reg_w8   <= 0;
78reg_w16  <= 0;
79reg_wf   <= 0;
80reg_wfex <= 0;
81we       <= 0;
82portwe   <= 0;
83portrd   <= 0;
84// Ожидание задержки после исполнения инструкции
85if (compat && delay) delay <= delay - 1;
86// Сброс процессора
87else if (reset_n == 1'b0) begin
88    pc          <= 0;
89    bus         <= 0;
90    t_state     <= 0;
91    set_prefix  <= 0;
92    i_mode      <= 0;
93    hptr        <= 0;
94    iff1 <= 1'b0; iff1_ <= 1'b0;
95    iff2 <= 1'b0; iff2_ <= 1'b0;
96end
97// Обработка прерывания
98else if (irq_process) case (t_state)
99    // Запись PC[7:0]
100    0: begin
101        t_state <= 1;
102        // Писать в память
103        bus <= 1; we <= 1; cp <= sp - 2; o_data <= pc[7:0];
104        // SP=SP-2
105        reg_w16 <= 1; reg_dt <= sp - 2; reg_id <= 3;
106    end
107    // Запись PC[15:8]
108    1: begin t_state <= 2; we <= 1; o_data <= pc[15:8]; cp <= cp + 1; end
109    // Считывание адреса
110    2: begin
111        if (i_mode == 2) begin
112            t_state <= 3;
113            hptr    <= ir[15:8];
114            cp      <= {ir[15:8], 8'hFF};
115        end
116        // imode=0 [8080], imode=1 [standart]
117        else begin
118            t_state <= 0;
119            bus     <= 0;
120            pc      <= 8'h38;
121            delay   <= 13-3-1;
122            irq_process <= 0;
123        end
124    end
125    3: begin t_state <= 4; cp <= cp + 1; pc[7:0] <= i_data; end
126    4: begin
127        t_state  <= 0;
128        bus      <= 0;
129        pc[15:8] <= i_data;
130        delay    <= 19-5-1;
131        irq_process <= 0;
132    end
133endcase
134// На первом такте инструкции обнаружен вызов IRQ (и прерывания разрешены)
135else if (iff1 && prefix == 0 && t_state == 0 && irq ^ irq_latch) begin
136    // Проверить, что прерывания разрешены и что IRQ=0->1
137    if (irq) begin
138        irq_process <= 1;
139        iff1 <= 1'b0; iff1_ <= 1'b0;
140        iff2 <= 1'b0; iff2_ <= 1'b0;
141        // Если текущая инструкция HALT
142        if (i_data == 8'h76) pc <= pc + 1;
143    end
144    irq_latch <= irq;
145end
146// Исполнение инструкции
147else begin
148    // Защелкнуть опкод и увеличить R+1
149    if (t_state == 0) begin
150        // Если запрошено прерывание imode=0, то выбирает FF
151        opcode_latch <= i_data;
152        pc      <= pc + 1;
153        ir[6:0] <= ir[6:0] + 1;
154        // Защелкивание DI/EI через одну инструкцию
155        if (prefix == 0) begin
156            iff1 <= iff1_;
157            iff2 <= iff2_;
158        end
159    end
160    t_state <= t_state + 1;
161    casex (opcode)
162        // 1T|4T: EX AF,AF'
163        8'b00_001_000: begin exxw <= spec_exaf; {set_prefix, t_state} <= 0; delay <= 4-1; end
164        // 1/2T|8/13T: DJNZ *
165        8'b00_010_000: case (t_state)
166            0: begin
167                // Запись в регистр B
168                reg_w8 <= 1;
169                reg_id <= 0;
170                reg_dt <= bc[15:8] - 1;
171                set_prefix <= 0;
172                // Выход из цикла
173                if (bc[15:8] == 1) begin pc <= pc + 2; t_state <= 0; delay <= 8-1; end
174            end
175            // Прочитать следующий байт и перейти
176            1: begin
177                pc <= pc + 1 + signex;
178                t_state <= 0;
179                delay   <= 13-2;
180            end
181        endcase
182        // 2T|12T: JR *
183        8'b00_011_000: case (t_state)
184            1: begin pc <= pc + signex + 1; {set_prefix, t_state} <= 0; delay <= 12-2; end
185        endcase
186        // 1/2T|12/7T: JR cc, *
187        8'b00_1xx_000: case (t_state)
188            0: begin
189                set_prefix <= 0;
190                // Если условие не совпало, пропуск +2 байта вперед
191                // Пример, opcode[4:3]=0, то если ZF=1, то произойдет выход из JR
192                if (condition[ opcode[4:3] ]) begin
193                    t_state <= 0;
194                    pc      <= pc + 2;
195                    delay   <= 7-1;
196                end
197            end
198            // Иначе дочитать байт и перейти по метке
199            1: begin
200                pc <= pc + 1 + signex;
201                t_state <= 0;
202                delay   <= 12-2;
203            end
204        endcase
205        // 3T|10T: LD r16, nn
206        8'b00_xx_0001: case (t_state)
207            1: begin pc <= pc + 1; reg_dt[ 7:0] <= i_data; end
208            2: begin pc <= pc + 1; reg_dt[15:8] <= i_data;
209                     reg_w16    <= 1;
210                     reg_id     <= opcode[5:4];
211                     {set_prefix, t_state} <= 0;
212                     delay <= 10-3;
213            end
214        endcase
215        // 1T/11T: ADD HL, r16
216        8'b00_xx_1001: case (t_state)
217            0: begin
218                reg_w16  <= 1;
219                reg_wfex <= 1;
220                reg_id   <= 2;
221                reg_dt   <= do_hl_add[15:0];
222                flag_ex  <= do_hl_flag;
223                {set_prefix, t_state} <= 0; delay <= 11-1;
224            end
225        endcase
226        // 2T|7T: LD (BC|DE), A
227        8'b00_0x_0010: case (t_state)
228            0: begin
229                cp      <= opcode[4] ? de : bc;
230                bus     <= 1;
231                we      <= 1;
232                o_data  <= af[7:0];
233                hptr    <= af[7:0];
234            end
235            1: begin {set_prefix, t_state, bus} <= 0; delay <= 7-2; end
236        endcase
237        // 2T|7T: LD A, (BC|DE)
238        8'b00_0x_1010: case (t_state)
239            0: begin cp <= opcode[4] ? de : bc; bus <= 1; end
240            1: begin
241                reg_w8 <= 1;
242                reg_id <= 7;
243                reg_dt <= i_data;
244                {set_prefix, t_state, bus} <= 0; delay <= 7-2;
245            end
246        endcase
247        // 5T|16T: LD (**), HL
248        8'b00_10_0010: case (t_state)
249            1: begin cp[ 7:0] <= i_data; pc <= pc + 1; end
250            2: begin
251                bus      <= 1;
252                cp[15:8] <= i_data;
253                hptr     <= i_data;
254                pc       <= pc + 1;
255                o_data   <= hlx[7:0];
256                we       <= 1;
257            end
258            3: begin cp <= cp + 1; o_data <= hlx[15:8]; we <= 1; end
259            4: begin {set_prefix, t_state, bus} <= 0; delay <= 16-5; end
260        endcase
261        // 4T|13T: LD (**), A
262        8'b00_11_0010: case (t_state)
263            1: begin cp[ 7:0] <= i_data; pc <= pc + 1; end
264            2: begin
265                we       <= 1;
266                bus      <= 1;
267                cp[15:8] <= i_data;
268                pc       <= pc + 1;
269                o_data   <= af[7:0];
270                hptr     <= af[7:0];
271            end
272            3: begin {set_prefix, t_state, bus} <= 0; delay <= 16-4; end
273        endcase
274        // 5T|16T: LD HL, (**)
275        8'b00_10_1010: case (t_state)
276            1: begin cp[ 7:0] <= i_data; pc <= pc + 1; end
277            2: begin cp[15:8] <= i_data; pc <= pc + 1; bus <= 1; hptr <= i_data; end
278            3: begin reg_id <= /*L*/ 5; reg_dt <= i_data; reg_w8 <= 1; cp <= cp + 1; end
279            4: begin
280                reg_id <= /*H*/ 4; reg_dt <= i_data; reg_w8 <= 1;
281                {set_prefix, t_state, bus} <= 0; delay <= 16-5;
282            end
283        endcase
284        // 4T|13T: LD A, (**)
285        8'b00_11_1010: case (t_state)
286            1: begin cp[ 7:0] <= i_data; pc <= pc + 1; end
287            2: begin cp[15:8] <= i_data; pc <= pc + 1; bus <= 1; hptr <= i_data; end
288            3: begin
289                reg_id <= /*A*/ 7; reg_dt <= i_data; reg_w8 <= 1;
290                {set_prefix, t_state, bus} <= 0; delay <= 13-4;
291            end
292        endcase
293        // 1T|6T: INC|DEC r16
294        8'b00_xx_x011: case (t_state)
295            0: begin
296                reg_w16 <= 1;
297                reg_id  <= opcode[5:4];
298                case (opcode[5:4])
299                    2'b00: reg_dt <= opcode[3] ? bc  - 1 : bc + 1;
300                    2'b01: reg_dt <= opcode[3] ? de  - 1 : de + 1;
301                    2'b10: reg_dt <= opcode[3] ? hlx - 1 : hlx + 1;
302                    2'b11: reg_dt <= opcode[3] ? sp  - 1 : sp + 1;
303                endcase
304                {set_prefix, t_state} <= 0; delay <= 6-1;
305            end
306        endcase
307        // 4T|11T: INC|DEC (HL)
308        // 6T|23T: INC|DEC (IX|IY+d)
309        8'b00_110_10x: case (t_state)
310            // Запрос в память или чтение смещения
311            0: begin
312                bus     <= prefix ? 0 : 1;
313                t_state <= prefix ? 1 : 2;
314                alu_m   <= opcode[0] ? alu_dec : alu_inc;
315                cp      <= hl;
316            end
317            // Дочитать смещение к IX|IY
318            1: begin
319                bus     <= 1;
320                cp      <= hlx + signex;
321                pc      <= pc + 1;
322            end
323            // Вычисление
324            2: begin op1 <= i_data; op2 <= 1; end
325            // Запись в память
326            3: begin we <= 1; o_data <= alu_r[7:0]; reg_wf <= 1; end
327            // Завершение инструкции
328            4: begin {set_prefix, t_state, bus} <= 0; delay <= prefix ? 23-4-5: 11-4; end
329        endcase
330        // 2T|4T: INC|DEC r8
331        8'b00_xxx_10x: case (t_state)
332            0: begin op1 <= reg8_53; op2 <= 1; alu_m <= opcode[0] ? alu_dec : alu_inc; end
333            1: begin
334                reg_wf <= 1;
335                reg_w8 <= 1;
336                reg_id <= opcode[5:3];
337                reg_dt <= alu_r[7:0];
338                {set_prefix, t_state} <= 0; delay <= 4-2;
339            end
340        endcase
341        // 3T|10T: LD (HL), *
342        // 5T|19T: LD (IX|IY+d), *
343        8'b00_110_110: case (t_state)
344            // Писать в зависимости от префикса
345            1: begin
346                we      <= prefix ? 0 : 1;
347                bus     <= prefix ? 0 : 1;
348                t_state <= prefix ? 2 : 3;
349                cp      <= prefix ? (hlx + signex) : hl;
350                pc      <= pc + 1;
351                o_data  <= i_data;
352            end
353            // Префиксированный
354            2: begin
355                we      <= 1;
356                bus     <= 1;
357                pc      <= pc + 1;
358                o_data  <= i_data;
359            end
360            3: begin {bus, set_prefix, t_state} <= 0; delay <= prefix ? 19-4-4 : 10-3; end
361        endcase
362        // 2T|7T: LD r8, *
363        8'b00_xxx_110: case (t_state)
364            1: begin
365                pc      <= pc + 1;
366                reg_w8  <= 1;
367                reg_id  <= opcode[5:3];
368                reg_dt  <= i_data;
369                {set_prefix, t_state} <= 0; delay <= 7-2;
370            end
371        endcase
372        // 4T: <RLCA,RRCA,RLA,RRA,DAA,CPL,SCF,CCF>
373        8'b00_xxx_111: case (t_state)
374            0: begin op1 <= af[7:0]; alu_m <= (opcode[5] ? alu_daa : alu_rlca) + opcode[4:3]; end
375            1: begin
376                reg_w8 <= 1;
377                reg_wf <= 1;
378                reg_id <= 7;
379                reg_dt <= alu_r;
380                {set_prefix, t_state} <= 0; delay <= 4-2;
381            end
382        endcase
383        // 1T: HALT
384        8'b01_110_110: begin pc <= pc; {set_prefix, t_state} <= 0; delay <= 4-1; end
385        // 2T|7T: LD (HL), r8
386        // 4T|19T: LD (IX|IY+d), r8
387        8'b01_110_xxx: case (t_state)
388            0: begin
389                bus     <= prefix ? 0 : 1;
390                we      <= prefix ? 0 : 1;
391                t_state <= prefix ? 1 : 2;
392                cp      <= hl;
393                o_data  <= reg8_20;
394            end
395            // Считывание смещения для префикса
396            1: begin
397                we      <= 1;
398                bus     <= 1;
399                cp      <= hlx + signex;
400                pc      <= pc + 1;
401                o_data  <= hl20_org;
402            end
403            2: begin {set_prefix, t_state, bus} <= 0; delay <= prefix ? 19-4-3 : 7-2; end
404        endcase
405        // 2T|7T: LD r8, (HL)
406        // 4T|19T: LD r8, (IX|IY+d)
407        8'b01_xxx_110: case (t_state)
408            0: begin
409                bus     <= prefix ? 0 : 1;
410                t_state <= prefix ? 1 : 2;
411                t_pref  <= prefix ? 1 : 0;
412                cp      <= hl;
413            end
414            // Считывание смещения для префикса
415            1: begin
416                bus     <= 1;
417                cp      <= hlx + signex;
418                pc      <= pc + 1;
419                set_prefix <= 0;
420            end
421            // Запись в регистр
422            2: begin
423                reg_w8 <= 1;
424                reg_id <= opcode[5:3];
425                reg_dt <= i_data;
426                {t_state, bus} <= 0; delay <= t_pref ? 19-4-3 : 7-2;
427            end
428        endcase
429        // 1T|4T: LD r8, r8
430        8'b01_xxx_xxx: case (t_state)
431            0: begin
432                reg_w8 <= 1;
433                reg_id <= opcode[5:3];
434                reg_dt <= reg8_20;
435                {set_prefix, t_state} <= 0; delay <= 4-1;
436            end
437        endcase
438        // 3T|7T: <ALU> a, (HL)
439        // 5T|19T: <ALU> a, (IX|IY+d)
440        8'b10_xxx_110: case (t_state)
441            // Установить адрес на шину (если это HL)
442            0: begin
443                bus     <= prefix ? 0 : 1;
444                t_state <= prefix ? 1 : 2;
445                alu_m   <= opcode[5:3];
446                op1     <= af[7:0];
447                cp      <= hl;
448            end
449            // Дочитывание смещения к префиксу и адрес IX|IY+d
450            1: begin
451                bus     <= 1;
452                cp      <= hlx + signex;
453                pc      <= pc + 1;
454            end
455            // Лишний такт тратится впустую
456            2: begin op2 <= i_data; bus <= 0; end
457            3: begin
458                reg_wf <= 1;
459                reg_id <= 7;
460                reg_w8 <= opcode[5:3] != alu_cp;
461                reg_dt <= alu_r[7:0];
462                {set_prefix, t_state} <= 0; delay <= prefix ? 19-4-4: 7-3;
463            end
464        endcase
465        // 2T|4T: <ALU> a, r8
466        8'b10_xxx_xxx: case (t_state)
467            0: begin op1 <= af[7:0]; op2 <= reg8_20; alu_m <= opcode[5:3]; end
468            1: begin
469                reg_wf <= 1;
470                reg_id <= 7;
471                reg_w8 <= opcode[5:3] != alu_cp;
472                reg_dt <= alu_r[7:0];
473                {set_prefix, t_state} <= 0; delay <= 4-2;
474            end
475        endcase
476        // 1/3T|10/11/5T: RET ccc|RET
477        8'b11_001_001,
478        8'b11_xxx_000: case (t_state)
479            0: begin
480                set_prefix <= 0;
481                // Условие не сработало, к следующей инструкции
482                // Если opcode[0]=1, то RET безусловный
483                if (condition[ opcode[5:3] ] && (opcode[0] == 1'b0)) begin
484                    t_state <= 0;
485                    delay   <= 5-1;
486                end
487                else begin
488                    bus     <= 1;
489                    cp      <= sp;
490                    reg_w16 <= 1;
491                    reg_dt  <= sp + 2;
492                    reg_id  <= 3;
493                end
494            end
495            1: begin pc[7:0] <= i_data; cp <= cp + 1; end
496            2: begin
497                pc[15:8] <= i_data;
498                {t_state, bus} <= 0; delay <= opcode[0] ? 10-3 : 11-3;
499            end
500        endcase
501        // 3T|10T: POP r16
502        8'b11_xx0_001: case (t_state)
503            0: begin
504                bus     <= 1;
505                cp      <= sp;
506                reg_w16 <= 1;
507                reg_dt  <= sp + 2;
508                reg_id  <= 3;
509            end
510            1: begin
511                // POP AF
512                if (opcode[5:4] == 2'b11) begin
513                    reg_wfex <= 1;
514                    flag_ex  <= i_data;
515                end else begin
516                    reg_w8 <= 1;
517                    reg_id <= {opcode[5:4], 1'b1};
518                    reg_dt <= i_data;
519                end
520                cp <= cp + 1;
521            end
522            2: begin
523                reg_w8 <= 1;
524                reg_id <= opcode[5:4] == 2'b11 ? 7 : {opcode[5:4], 1'b0};
525                reg_dt <= i_data;
526                {set_prefix, t_state, bus} <= 0; delay <= 10-3;
527            end
528        endcase
529        // 1T/4T: EXX
530        8'b11_011_001: case (t_state)
531            0: begin {set_prefix, t_state} <= 0; exxw <= spec_exx; delay <= 4-1; end
532        endcase
533        // 1T/4T: JP (HL)
534        8'b11_101_001: case (t_state)
535            0: begin pc <= hlx; {set_prefix, t_state} <= 0; delay <= 4-1; end
536        endcase
537        // 1T/6T: LD SP, HL
538        8'b11_111_001: case (t_state)
539            0: begin
540                reg_w16 <= 1;
541                reg_dt  <= hlx;
542                reg_id  <= 3;
543                {set_prefix, t_state} <= 0; delay <= 6-1;
544            end
545        endcase
546        // 2/3T|10T: JP ccc, **; JP **
547        8'b11_000_011,
548        8'b11_xxx_010: case (t_state)
549            0: begin
550                set_prefix <= 0;
551                // Условие не сработало, к следующей инструкции
552                // Если opcode[0]=1, то переход безусловный
553                if (condition[ opcode[5:3] ] && (opcode[0] == 1'b0)) begin
554                    pc      <= pc + 2;
555                    t_state <= 3;
556                end
557            end
558            1: begin reg_dt <= i_data; pc <= pc + 1; end
559            2: begin hptr <= i_data; pc <= {i_data, reg_dt[7:0]}; t_state <= 0; delay <= 10-3; end
560            // Необходимо для получения HPTR
561            3: begin hptr <= i_data; pc <= pc + 1; t_state <= 0; delay <= 10-2; end
562        endcase
563        // CB: Битовые инструкции
564        // 4T/8T:  <opcode> r8
565        // 5T/15T: <opcode> (HL)
566        // 5T/23T: <opcode> (IX+*)
567        // 4T/12T: BIT n,(HL)
568        // 4T/20T: BIT n,(IX+*)
569        8'b11_001_011: case (t_state)
570            // Чтение опкода или смещения
571            1: begin
572                pc  <= pc + 1;
573                cp  <= prefix ? hlx + signex : hl;
574                bus <= prefix ? 0 : 1; // Если (Ixy+*), дочитать PC+1
575                opcode_ext <= i_data;
576                ir[6:0]    <= ir[6:0] + 1;
577                if (prefix == 0) t_state <= 3;
578            end
579            // Считывание опкода для префиксированной инструкции
580            2: begin opcode_ext <= i_data; pc <= pc + 1; bus <= 1; end
581            // Чтение данных из памяти или регистра
582            3: begin
583                op1     <= prefix ? i_data : reg8_cb20;
584                op2     <= opcode_ext[6:3];
585                alu_m   <= opcode_ext[5:3] + alu_rlc;
586                // Убрать префиксирование для BIT
587                t_pref     <= prefix ? 1 : 0;
588                set_prefix <= 0;
589            end
590            // Исполнение и сохранение
591            4: casex (opcode_ext[7:6])
592                // BIT n, r8
593                // BIT n, (HL)
594                8'b01: begin
595                    reg_wfex <= 1;
596                    flag_ex  <= t_pref ? bit_flags_xx : bit_flags;
597                    // BIT n, (HL)
598                    if (t_pref == 0 && opcode_ext[2:0] == 6)
599                        {flag_ex[5],flag_ex[3]} <= {hptr[5],hptr[3]};
600                    // Все префиксированные выполняются за 20T
601                    {bus, t_state} <= 0;
602                    delay <= t_pref ? 20-4-5 : (opcode_ext[2:0] == 6 ? 12-4 : 8-4);
603                end
604                // SHIFT|RES|SET n, reg|idata
605                // Сохранение в регистры и в память (если выбрано)
606                8'b00,
607                8'b1x: begin
608                    // Кроме HL и префиксированных
609                    we      <= (opcode_ext[2:0] == 6) || t_pref;
610                    reg_w8  <= (opcode_ext[2:0] != 6);
611                    reg_id  <=  opcode_ext[2:0];
612                    // Если это RES|SET, то из rsop, иначе из alu_r
613                    reg_dt  <= opcode_ext[7] ? rsop : alu_r;
614                    o_data  <= opcode_ext[7] ? rsop : alu_r;
615                    // Операции сдвига меняют флаги
616                    if (opcode_ext[7] == 1'b0) reg_wf <= 1;
617                    // Нет префикса и нет (HL)
618                    if (t_pref == 0 && (opcode_ext[2:0] != 6)) begin
619                        {bus, t_state} <= 0; delay <= 8-4;
620                    end
621                end
622            endcase
623            // Завершение записи для инструкции [00-3F,80-FF]
624            5: begin {bus, t_state} <= 0; delay <= t_pref ? 23-4-6 : 15-5; end
625        endcase
626        // 3T/11T: OUT (*), A
627        8'b11_010_011: case (t_state)
628            1: begin
629                bus     <= 1;
630                portwe  <= 1;
631                o_data  <= af[7:0];
632                hptr    <= af[7:0];
633                cp      <= {af[7:0], i_data};
634                pc      <= pc + 1;
635            end
636            2: begin {set_prefix, t_state, bus} <= 0; delay <= 11-3; end
637        endcase
638        // 3T/11T: IN A,(*)
639        8'b11_011_011: case (t_state)
640            1: begin bus <= 1; cp <= {af[7:0], i_data}; hptr <= af[7:0]; pc <= pc + 1; portrd <= 1; end
641            2: begin
642                reg_id <= 7;
643                reg_w8 <= 1;
644                reg_dt <= portin;
645                {set_prefix, t_state, bus} <= 0; delay <= 11-3;
646            end
647        endcase
648        // 5T/19T: EX (SP), HL
649        8'b11_100_011: case (t_state)
650            0: begin bus <= 1; cp <= sp; end
651            1: begin reg_dt[ 7:0] <= i_data; cp <= cp + 1; end
652            2: begin reg_dt[15:8] <= i_data; cp <= cp - 1; we <= 1; o_data <= hlx[7:0]; end
653            3: begin
654                reg_w16 <= 1;
655                reg_id  <= 2;
656                we <= 1;
657                cp <= cp + 1;
658                o_data <= hlx[15:8];
659            end
660            4: begin {set_prefix, t_state, bus} <= 0; delay <= 19-5; end
661        endcase
662        // 1T/4T: EX DE,HL
663        8'b11_101_011: case (t_state)
664            0: begin {set_prefix, t_state} <= 0; exxw <= spec_exdehl; delay <= 4-1; end
665        endcase
666        // 1T/4T: DI/EI
667        8'b11_11x_011: case (t_state)
668            // Срабатывает активация iff1/2 через одну инструкцию
669            0: begin
670                iff1_ <= opcode[3];
671                iff2_ <= opcode[3];
672                {set_prefix, t_state} <= 0; delay <= 4-1;
673            end
674        endcase
675        // 2/5T|10/17T: CALL ccc, **; CALL **
676        8'b11_001_101,
677        8'b11_xxx_100: case (t_state)
678            0: begin
679                set_prefix <= 0;
680                // Условие не сработало, к следующей инструкции
681                // Если opcode[0]=1, то переход безусловный
682                if (condition[ opcode[5:3] ] && (opcode[0] == 1'b0)) begin
683                    pc      <= pc + 2;
684                    t_state <= 5;
685                end
686                // Иначе считывать адрес памяти
687                else begin
688                    reg_w16 <= 1;
689                    reg_dt  <= sp - 2;
690                    reg_id  <= 3;
691                end
692            end
693            1: begin reg_dt <= i_data; pc <= pc + 1; end
694            2: begin
695                bus     <= 1;
696                we      <= 1;
697                cp      <= sp;
698                pc      <= {i_data, reg_dt[7:0]};
699                hptr    <= i_data;
700                o_data  <= pc1[7:0];
701                reg_dt  <= pc1;
702            end
703            3: begin
704                we      <= 1;
705                cp      <= cp + 1;
706                o_data  <= reg_dt[15:8];
707            end
708            4: begin {t_state, bus} <= 0; delay <= 17-5; end
709            // Для получения HPTR
710            5: begin hptr <= i_data; pc <= pc + 1; t_state <= 0; delay <= 10-2; end
711        endcase
712        // 3T|11T: PUSH r16
713        8'b11_xx0_101: case (t_state)
714            // Запись младшего байта
715            0: begin
716                bus <= 1;
717                we  <= 1;
718                cp  <= sp - 2;
719                // sp = sp - 2
720                reg_w16 <= 1;
721                reg_dt  <= sp - 2;
722                reg_id  <= 3;
723                case (opcode[5:4])
724                    0: o_data <=  bc[ 7:0];
725                    1: o_data <=  de[ 7:0];
726                    2: o_data <= hlx[ 7:0];
727                    3: o_data <=  af[15:8]; // Флаги (LO)
728                endcase
729            end
730            // Запись старшего байта
731            1: begin
732                we <= 1;
733                cp <= cp + 1;
734                case (opcode[5:4])
735                    0: o_data <=  bc[15:8];
736                    1: o_data <=  de[15:8];
737                    2: o_data <= hlx[15:8];
738                    3: o_data <=  af[ 7:0]; // Аккумулятор (HI)
739                endcase
740            end
741            2: begin {set_prefix, t_state, bus} <= 0; delay <= 11-3; end
742        endcase
743        // EXTENDED
744        8'b11_101_101: case (t_state)
745            0: begin set_prefix <= 0; n_state <= 0; end
746            1: begin
747                pc <= pc + 1;
748                opcode_ext <= i_data;
749                casex (i_data)
750                    // IN r8, (C)
751                    8'b01_xxx_000: begin cp <= bc; bus <= 1; portrd <= 1; end
752                    // OUT (C), r8
753                    8'b01_xxx_001: begin
754                        bus     <= 1;
755                        portwe  <= 1;
756                        cp      <= bc;
757                        o_data  <= reg8_outc;
758                     end
759                    // 2T: SBC|ADC hl, r16
760                    8'b01_xxx_010: begin
761                        reg_w16  <= 1;
762                        reg_wfex <= 1;
763                        reg_id   <= 2; // HL
764                        reg_dt   <= i_data[3] ? ed_hl_adc   : ed_hl_sbc;
765                        flag_ex  <= i_data[3] ? hl_adc_flag : hl_sbc_flag;
766                        t_state <= 0; delay <= 15-2;
767                    end
768                    // 6T: LD (**),r16 | r16,(**)
769                    8'b01_xxx_011: begin /* nothing */ end
770                    // NEG
771                    8'b01_xxx_100: begin
772                        op1   <= 0;
773                        op2   <= af[7:0];
774                        alu_m <= alu_sub;
775                    end
776                    // RETN/RETI
777                    8'b01_xxx_101: begin
778                        bus     <= 1;
779                        cp      <= sp;
780                        reg_w16 <= 1;
781                        reg_dt  <= sp + 2;
782                        reg_id  <= 3;
783                        // RETN, кроме RETI
784                        if (i_data[5:3] != 3'b001) begin
785                            iff1  <= iff2;
786                            iff1_ <= iff2_;
787                        end
788                    end
789                    // IM n: [00120012]
790                    8'b01_xxx_110: begin
791                        i_mode <= i_data[4] ? (i_data[3] ? 2 : 1) : 0;
792                        t_state <= 0; delay <= 8-2;
793                    end
794                    // LD i|r, a
795                    // LD a, i|r
796                    8'b01_0xx_111: begin
797                        reg_id <= 7;
798                        reg_dt <= i_data[3] ? ir[7:0] : ir[15:8];
799                        if      (i_data[4]) reg_w8 <= 1;
800                        else if (i_data[3]) ir[7:0] <= af[7:0]; else ir[15:8] <= af[7:0];
801                        // LD A, I|R записывает флаги
802                        if (i_data[4]) begin
803                            reg_wfex <= 1;
804                            if (i_data[3]) // Если выполняется прерывание то PV=0
805                                 flag_ex <= {ir[ 7], ir[ 7:0] == 0, ir[ 5], 1'b0, ir[ 3], (irqcause ? 1'b0 : iff2), 1'b0, af[CF]};
806                            else flag_ex <= {ir[15], ir[15:8] == 0, ir[13], 1'b0, ir[11], (irqcause ? 1'b0 : iff2), 1'b0, af[CF]};
807                        end
808                        t_state <= 0; delay <= 9-2;
809                    end
810                    // RRD |RLD
811                    // LDI |LDD |LDIR|LDDR
812                    // CPI |CPD |CPIR|CPDR
813                    // OUTI|OUTD|OTIR|OTDR
814                    8'b01_10x_111,
815                    8'b10_1xx_00x,
816                    8'b10_1xx_011: begin cp <= hl; bus <= 1; end
817                    // INI |IND |INIR|INDR
818                    8'b10_1xx_010: begin
819                        cp      <= {b_dec, bc[7:0]};
820                        bus     <= 1;
821                        alu_m   <= alu_dec;
822                        op1     <= bc[15:8];
823                        op2     <= 1;
824                        portrd  <= 1;
825                    end
826                    // NOP инструкция
827                    default: begin t_state <= 0; delay <= 8-2; end
828                endcase
829            end
830            2: begin
831                t_state <= 2;
832                n_state <= n_state + 1;
833                casex (opcode_ext)
834                // 3T: IN r8, (C)
835                8'b01_xxx_000: begin
836                    reg_w8   <= 1;
837                    reg_wfex <= 1;
838                    // При записи в 6-й регистр ничего не происходит
839                    reg_id <= opcode_ext[5:3];
840                    reg_dt <= portin;
841                    // Вычисление флагов
842                    flag_ex <= {
843                        portin[7],      // S
844                        portin == 0,    // Z
845                        portin[5],      // F5
846                        1'b0,           // H
847                        portin[3],      // F3
848                        ~^portin[7:0],  // P
849                        1'b0,           // N
850                        af[CF]          // C
851                    };
852                    {t_state, bus} <= 0; delay <= 12-3;
853                end
854                // 3T: OUT (C), r8
855                8'b01_xxx_001: begin {t_state, bus} <= 0; delay <= 12-3; end
856                // 6T: LD (**), r16
857                8'b01_xx0_011: case (n_state)
858                    0: begin cp[7:0] <= i_data; pc <= pc + 1; end
859                    // Запись младшего байта
860                    1: begin
861                        cp[15:8] <= i_data;
862                        hptr     <= i_data;
863                        pc  <= pc + 1;
864                        bus <= 1;
865                        we  <= 1;
866                        case (opcode_ext[5:4])
867                            2'b00: o_data <= bc[7:0];
868                            2'b01: o_data <= de[7:0];
869                            2'b10: o_data <= hl[7:0];
870                            2'b11: o_data <= sp[7:0];
871                        endcase
872                    end
873                    // Запись старшего байта
874                    2: begin
875                        we <= 1;
876                        cp <= cp + 1;
877                        case (opcode_ext[5:4])
878                            2'b00: o_data <= bc[15:8];
879                            2'b01: o_data <= de[15:8];
880                            2'b10: o_data <= hl[15:8];
881                            2'b11: o_data <= sp[15:8];
882                        endcase
883                    end
884                    // Завершение записи
885                    3: begin {t_state, bus} <= 0; delay <= 20-6; end
886                endcase
887                // 6T: LD r16, (**)
888                8'b01_xx1_011: case (n_state)
889                    0: begin cp[ 7:0] <= i_data; pc <= pc + 1; end
890                    1: begin cp[15:8] <= i_data; pc <= pc + 1; bus <= 1; hptr <= i_data; end
891                    2: begin reg_dt[7:0] <= i_data; cp <= cp + 1; end
892                    3: begin
893                        reg_w16 <= 1;
894                        reg_id  <= opcode_ext[5:4];
895                        reg_dt[15:8] <= i_data;
896                        {t_state, bus} <= 0; delay <= 20-6;
897                    end
898                endcase
899                // 4T: RETN/RETI
900                8'b01_xxx_101: case (n_state)
901                    0: begin pc[ 7:0] <= i_data; cp <= cp + 1; end
902                    1: begin pc[15:8] <= i_data; {t_state, bus} <= 0; delay <= 14-4; end
903                endcase
904                // 3T: NEG
905                8'b01_xxx_100: begin
906                    reg_id <= 7;
907                    reg_wf <= 1;
908                    reg_w8 <= 1;
909                    reg_dt <= alu_r;
910                    t_state <= 0; delay <= 8-3;
911                end
912                // 4T: RRD|RLD
913                8'b01_10x_111: case (n_state)
914                    0: begin
915                        we       <= 1; // Запись в память
916                        reg_w8   <= 1; // Запись в регистр A
917                        reg_wfex <= 1; // Писать кастомные флаги
918                        reg_id   <= 7;
919                        o_data   <= opcode_ext[3] ? rld_w : rrd_w;
920                        reg_dt   <= opcode_ext[3] ? rld_a : rrd_a;
921                        flag_ex <= opcode_ext[3] ? {
922                            rld_a[7],   rld_a == 0, rld_a[5], 1'b0,
923                            rld_a[3], ~^rld_a[7:0],     1'b0, af[CF]
924                        } : {
925                            rrd_a[7],   rrd_a == 0, rrd_a[5], 1'b0,
926                            rrd_a[3], ~^rrd_a[7:0],     1'b0, af[CF]
927                        };
928                    end
929                    1: begin {t_state, bus} <= 0; delay <= 18-4; end
930                endcase
931                // 4T: LDI|LDD|LDIR|LDDR
932                8'b10_1xx_000: case (n_state)
933                    // Запись в память
934                    0: begin
935                        we       <= 1;
936                        cp       <= de;
937                        o_data   <= i_data;
938                        reg_wfex <= 1;
939                        flag_ex  <= {
940                            af[SF],   af[ZF],  ldixy[1], 1'b0,
941                            ldixy[3], bc != 1, 1'b0,     af[CF]
942                        };
943                        // Уменьшить BC--; икремент/декремент HL/DE
944                        ldcmd <= opcode_ext[3] ? ldcmd_ldd : ldcmd_ldi;
945                    end
946                    // Завершение инструкции
947                    1: begin
948                        delay <= 16-4;
949                        // Если это LDIR, LDDR то проверить BC на 0
950                        if (opcode_ext[4] && bc) begin pc <= pc - 2; delay <= 21-4; end
951                        {t_state, bus} <= 0;
952                    end
953                endcase
954                // 4T: CPI|CPD|CPIR|CPDR
955                8'b10_1xx_001: case (n_state)
956                    // Запрос к АЛУ на вычисление CP
957                    0: begin
958                        alu_m <= alu_cp;
959                        op1   <= af[7:0];
960                        op2   <= i_data;
961                        ldcmd <= opcode_ext[3] ? ldcmd_cpd : ldcmd_cpi;
962                    end
963                    // Обновление флагов
964                    1: begin
965                        reg_wfex <= 1;
966                        flag_ex  <= {
967                            alu_f[7], alu_f[6], cpixy[1], alu_f[4],
968                            cpixy[3], bc != 0,  1'b1,     af[CF]
969                        };
970                        delay <= 16-4;
971                        // Если это CPIR, CPDR то проверить BC на 0 и чтобы ZF=0
972                        if (opcode_ext[4] && !alu_f[6] && bc)
973                        begin pc <= pc - 2; delay <= 21-4; end
974                        {t_state, bus} <= 0;
975                    end
976                endcase
977                // 4T: INI|IND|INIR|INDR
978                8'b10_1xx_010: case (n_state)
979                    0: begin
980                        // Чтение из порта
981                        we      <= 1;
982                        cp      <= hl;
983                        o_data  <= portin;
984                        // Обновление B
985                        reg_wf  <= 1;
986                        reg_w8  <= 1;
987                        reg_id  <= 0;
988                        reg_dt  <= alu_r;
989                    end
990                    1: begin
991                        // Икремент или декремент HL
992                        reg_w16 <= 1;
993                        reg_id  <= 2;
994                        reg_dt  <= opcode_ext[3] ? hl - 1 : hl + 1;
995                        delay  <= 16-4;
996                        // Если это CPIR, CPDR то проверить B на 0
997                        if (opcode_ext[4] && alu_r[7:0]) begin pc <= pc - 2; delay <= 21-4; end
998                        {t_state, bus} <= 0;
999                    end
1000                endcase
1001                // 4T: OUTI|OUTD|OTIR|OTDR
1002                8'b10_1xx_011: case (n_state)
1003                    // Запись в порт, HL++/--, декремент B
1004                    0: begin
1005                        // Запись в порт значения из памяти
1006                        portwe  <= 1;
1007                        cp      <= bc;
1008                        o_data  <= i_data;
1009                        // Инкремент или декремент HL
1010                        reg_w16 <= 1;
1011                        reg_id  <= 2;
1012                        reg_dt  <= opcode_ext[3] ? hl - 1 : hl + 1;
1013                        // Декремент B через АЛУ
1014                        alu_m <= alu_dec;
1015                        op1   <= bc[15:8];
1016                        op2   <= 1;
1017                    end
1018                    1: begin
1019                        reg_wf <= 1;
1020                        reg_w8 <= 1;
1021                        reg_dt <= alu_r;
1022                        reg_id <= 0;
1023                        delay  <= 16-4;
1024                        // Если это CPIR, CPDR то проверить B на 0
1025                        if (opcode_ext[4] && alu_r[7:0]) begin pc <= pc - 2; delay <= 21-4; end
1026                        {t_state, bus} <= 0;
1027                    end
1028                endcase
1029                endcase
1030            end
1031        endcase
1032        // 3T|7T: <ALU> a,*
1033        8'b11_xxx_110: case (t_state)
1034            0: begin op1 <= af[7:0]; alu_m <= opcode[5:3]; end
1035            1: begin op2 <= i_data; pc <= pc + 1; end
1036            2: begin
1037                reg_wf <= 1;
1038                reg_id <= 7;
1039                reg_w8 <= opcode[5:3] != alu_cp;
1040                reg_dt <= alu_r[7:0];
1041                {set_prefix, t_state} <= 0; delay <= 7-3;
1042            end
1043        endcase
1044        // 3T|11T: RST #n
1045        8'b11_xxx_111: case (t_state)
1046            0: begin
1047                bus <= 1;
1048                we  <= 1;
1049                cp  <= sp - 2;
1050                o_data <= pc1[7:0];
1051                reg_w16 <= 1;
1052                reg_dt  <= sp - 2;
1053                reg_id  <= 3;
1054                set_prefix <= 0;
1055            end
1056            1: begin we <= 1; o_data <= pc[15:8]; cp <= cp + 1; end
1057            2: begin pc <= {opcode[5:3], 3'b000}; {t_state, bus} <= 0; delay <= 11-3; end
1058        endcase
1059        // 1T|4T: Префиксы IX и IY
1060        8'b1101_1101: begin t_state <= 0; set_prefix <= 1; delay <= 4-1; end
1061        8'b1111_1101: begin t_state <= 0; set_prefix <= 2; delay <= 4-1; end
1062        // Пропуск инструкции
1063        default: begin {set_prefix, t_state} <= 0; delay <= 4-1; end
1064    endcase
1065    // В "быстром режиме" работы нет задержек
1066    if (compat == 0) delay <= 0;
1067end
1068end
1069// Предварительные инициализации
1070// -----------------------------------------------------------------------------
1071initial begin o_data = 0; we = 0; portwe = 0; end
1072// Состояние процессора
1073// -----------------------------------------------------------------------------
1074reg [ 3:0]  t_state     = 0;        // Фаза исполнения опкода
1075reg [ 2:0]  n_state     = 0;        // Фаза исполнения EDh опкода
1076reg [ 4:0]  delay       = 0;        // Задержка для совместимости
1077reg         bus         = 1'b0;     // Выбор источника адреса
1078reg [15:0]  cp          = 16'h0000; // CurrentPointer: альтернативный address
1079reg [ 7:0]  opcode_latch;           // Защелка для опкода
1080reg [ 7:0]  opcode_ext;             // Дополнительный опкод
1081reg [ 1:0]  set_prefix  = 0;        // Команда для установки префикса на обратном фронте
1082reg [ 1:0]  prefix      = 0;        // Текущий префикс, 0=нет, 1=IX, 2=IY
1083reg         t_pref      = 0;        // Наличие префикса в запросе инструкции
1084reg [ 1:0]  exxw        = 0;        // Специальная запись в регистры
1085reg [ 2:0]  ldcmd       = 0;        // =1 HL++,DE++,BC--; =2 HL++,BC--;
1086                                    // =3 HL--,DE--,BC--; =4 HL--,BC--
1087reg         reg_w8      = 0;        // Писать результат в регистр 8 бит
1088reg         reg_w16     = 0;        // Писать результат в регистр 16 бит
1089reg         reg_wfex    = 0;        // Запись специальных флагов
1090reg         reg_wf      = 0;        // Запись флагов из alu_f в af[15:8]
1091reg [ 3:0]  reg_id      = 0;        // Номер регистра для записи
1092reg [15:0]  reg_dt      = 0;        // Данные для записи в регистр
1093reg [ 7:0]  flag_ex     = 0;        // Специальные флаги для reg_wfex=1
1094reg [ 7:0]  hptr        = 0;        // Специальный регистр для BIT n,(HL)
1095// Аппаратное прерывание
1096// -----------------------------------------------------------------------------
1097reg         iff1_       = 1'b0;
1098reg         iff2_       = 1'b1;
1099reg         irq_latch   = 1'b0;
1100reg         irq_process = 1'b0;
1101// Вычисление проводов
1102// -----------------------------------------------------------------------------
1103// Выбор опкода
1104wire [7:0]  opcode   = t_state? opcode_latch : i_data;
1105wire [15:0] hlx      = prefix == 1 ? ix : (prefix == 2 ? iy : hl);
1106wire [15:0] signex   = {{8{i_data[7]}}, i_data[7:0]};
1107wire        irqcause = irq ^ irq_latch;
1108// Выбор регистра из opcode[2:0]
1109wire [7:0] reg8_20 =
1110    opcode[2:0] == 0 ?  bc[15:8] : opcode[2:0] == 1 ?  bc[ 7:0] :
1111    opcode[2:0] == 2 ?  de[15:8] : opcode[2:0] == 3 ?  de[ 7:0] :
1112    opcode[2:0] == 4 ? hlx[15:8] : opcode[2:0] == 5 ? hlx[ 7:0] :
1113    opcode[2:0] == 6 ? i_data    : af[7:0];
1114// Выбор регистра из opcode[5:3]
1115wire [7:0] reg8_53 =
1116    opcode[5:3] == 0 ?  bc[15:8] : opcode[5:3] == 1 ?  bc[ 7:0] :
1117    opcode[5:3] == 2 ?  de[15:8] : opcode[5:3] == 3 ?  de[ 7:0] :
1118    opcode[5:3] == 4 ? hlx[15:8] : opcode[5:3] == 5 ? hlx[ 7:0] :
1119    opcode[5:3] == 6 ? i_data    : af[7:0];
1120// Для префикса CB **
1121wire [7:0] reg8_cb20 =
1122    opcode_ext[2:0] == 0 ? bc[15:8] : opcode_ext[2:0] == 1 ? bc[ 7:0] :
1123    opcode_ext[2:0] == 2 ? de[15:8] : opcode_ext[2:0] == 3 ? de[ 7:0] :
1124    opcode_ext[2:0] == 4 ? hl[15:8] : opcode_ext[2:0] == 5 ? hl[ 7:0] :
1125    opcode_ext[2:0] == 6 ? i_data   : af[7:0];
1126// Для OUT (C), r8
1127wire [7:0] reg8_outc =
1128    i_data[5:3] == 0 ? bc[15:8] : i_data[5:3] == 1 ? bc[ 7:0] :
1129    i_data[5:3] == 2 ? de[15:8] : i_data[5:3] == 3 ? de[ 7:0] :
1130    i_data[5:3] == 4 ? hl[15:8] : i_data[5:3] == 5 ? hl[ 7:0] :
1131    i_data[5:3] == 6 ? 0        : af[7:0];
1132// Выбор оригинального H,L при префиксированных инструкциях
1133wire [7:0] hl20_org = opcode[2:0] == 4 ? hl[15:8] :
1134                      opcode[2:0] == 5 ? hl[ 7:0] : reg8_20;
1135wire [15:0] pc1 = pc + 1;
1136// 0-nz, 1-z,  2-nc, 3-c
1137// 4-po, 5-pe, 6-p,  7-m
1138wire [7:0] condition = {
1139    ~af[SF], af[SF], // 7,6 s
1140    ~af[PF], af[PF], // 5,4 p
1141    ~af[CF], af[CF], // 3,2 c
1142    ~af[ZF], af[ZF]  // 1,0 Z
1143};
1144// АЛУ
1145// -----------------------------------------------------------------------------
1146reg  [4:0] alu_m;   // Режим работы АЛУ
1147reg  [7:0] op1;     // Операнды
1148reg  [7:0] op2;
1149wire zf8 = alu_r[7:0]==0;           // Zero
1150wire pf8 = ~^alu_r[7:0];            // Parity
1151wire sf8 = alu_r[7];                // Sign
1152wire cf8 = alu_r[8];                // Carry
1153wire f58 = alu_r[5];                // H5 Undocumented
1154wire f38 = alu_r[3];                // H3 Undocumented
1155wire hf8 = alu_r[4]^op1[4]^op2[4];  // Half-Carry
1156wire oa8 = (op1[7] == op2[7]) & (op1[7] != alu_r[7]);
1157wire os8 = (op1[7] != op2[7]) & (op1[7] != alu_r[7]);
1158// Специальный расчет флага H
1159wire [4:0] ha8 = op1[3:0] + op2[3:0] + af[CF];
1160wire [4:0] hs8 = op1[3:0] - op2[3:0] - af[CF];
1161// Вычисление результата
1162wire [8:0] alu_r =
1163    alu_m == alu_add  ? op1 + op2 :
1164    alu_m == alu_adc  ? op1 + op2 + af[CF] :
1165    alu_m == alu_sub  ? op1 - op2 :
1166    alu_m == alu_sbc  ? op1 - op2 - af[CF] :
1167    alu_m == alu_and  ? op1 & op2 :
1168    alu_m == alu_xor  ? op1 ^ op2 :
1169    alu_m == alu_or   ? op1 | op2 :
1170    alu_m == alu_cp   ? op1 - op2 :
1171    alu_m == alu_inc  ? op1 + op2 :
1172    alu_m == alu_dec  ? op1 - op2 :
1173    // Сдвиговые операции
1174    alu_m == alu_rlca || alu_m == alu_rlc ? {op1[6:0], op1[7]}   : // a << 1
1175    alu_m == alu_rrca || alu_m == alu_rrc ? {op1[0],   op1[7:1]} : // a >> 1
1176    alu_m == alu_rla  || alu_m == alu_rl  ? {op1[6:0], af[CF]}   : // a << 1
1177    alu_m == alu_rra  || alu_m == alu_rr  ? {af[CF],   op1[7:1]} : // a >> 1
1178    alu_m == alu_sla ? {op1[6:0], 1'b0}   : // a << 1
1179    alu_m == alu_sll ? {op1[6:0], 1'b1}   : // a << 1
1180    alu_m == alu_sra ? {op1[7], op1[7:1]} : // a >> 1
1181    alu_m == alu_srl ? {1'b0,   op1[7:1]} : // a >> 1
1182    // Коррекции
1183    alu_m == alu_daa  ? daa_2 :
1184    alu_m == alu_cpl  ? ~op1 :
1185    // Все остальные
1186    op1;
1187// Результат флаговых вычислений [S Z F5 H F3 P/V N C]
1188wire [7:0] alu_f =
1189    // Группа ADD, ADC
1190    (alu_m == alu_add) ? {sf8, zf8, f58,    hf8,    f38,    oa8, 1'b0, cf8} :
1191    (alu_m == alu_adc) ? {sf8, zf8, f58,    ha8[4], f38,    oa8, 1'b0, cf8} :
1192    (alu_m == alu_sbc) ? {sf8, zf8, f58,    hs8[4], f38,    os8, 1'b1, cf8} :
1193    (alu_m == alu_sub) ? {sf8, zf8, f58,    hf8,    f38,    os8, 1'b1, cf8} :
1194    (alu_m == alu_cp)  ? {sf8, zf8, op2[5], hf8,    op2[3], os8, 1'b1, cf8} :
1195    // Для AND выставляет H=1
1196    (alu_m == alu_and) ? {sf8, zf8, f58, 1'b1, f38, pf8, 2'b00} :
1197    // Другие логические (XOR|OR)
1198    (alu_m == alu_xor || alu_m == alu_or) ? {sf8, zf8, f58, 1'b0, f38, pf8, 2'b00} :
1199    // INC, DEC не меняют флаг CF
1200    (alu_m == alu_inc)  ? {sf8, zf8, f58, hf8, f38, oa8, 1'b0, af[CF]} :
1201    (alu_m == alu_dec)  ? {sf8, zf8, f58, hf8, f38, os8, 1'b1, af[CF]} :
1202    // Сдвиговые
1203    (alu_m == alu_rlca || alu_m == alu_rla) ?
1204        {af[SF], af[ZF], f58, 1'b0, f38, af[PF], 1'b0, op1[7]} :
1205    (alu_m == alu_rrca || alu_m == alu_rra) ?
1206        {af[SF], af[ZF], f58, 1'b0, f38, af[PF], 1'b0, op1[0]} :
1207    (alu_m == alu_rlc || alu_m == alu_rl || alu_m == alu_sla || alu_m == alu_sll) ?
1208        {sf8, zf8, f58, 1'b0, f38, pf8, 1'b0, op1[7]} :
1209    (alu_m == alu_rrc || alu_m == alu_rr || alu_m == alu_sra || alu_m == alu_srl) ?
1210        {sf8, zf8, f58, 1'b0, f38, pf8, 1'b0, op1[0]} :
1211    // Специальные
1212    (alu_m == alu_daa) ? {sf8, zf8, f58, af[4]^daa_2[4], f38, pf8, af[NF], daa_cf} :
1213    (alu_m == alu_cpl) ? {af[SF], af[ZF], f58, 1'b1,   f38, af[PF], 1'b1, af[CF]} :
1214    (alu_m == alu_scf) ? {af[SF], af[ZF], f58, 1'b0,   f38, af[PF], 1'b0, 1'b1} :
1215    (alu_m == alu_ccf) ? {af[SF], af[ZF], f58, af[CF], f38, af[PF], 1'b0, ~af[CF]} :
1216    // Все остальные
1217        af[15:8];
1218// DAA
1219// -----------------------------------------------------------------------------
1220wire daa_hf = af[HF] | (af[3:0] > 8'h09);
1221wire daa_cf = af[CF] | (af[7:0] > 8'h99);
1222// Первый этап
1223wire [7:0] daa_1 =
1224    af[NF] ? (daa_hf ? af[7:0] - 6 : af[7:0]) : // SUB
1225             (daa_hf ? af[7:0] + 6 : af[7:0]);  // ADD
1226// Второй этап
1227wire [7:0] daa_2 =
1228    af[NF] ? (daa_cf ? daa_1 - 16'h60 : daa_1) : // SUB
1229             (daa_cf ? daa_1 + 16'h60 : daa_1);  // ADD
1230// 16-битная операция HL +/- r16
1231// -----------------------------------------------------------------------------
1232// Второй операнд для ADD HL, r16
1233wire [15:0] do_hl_op2 =
1234    opcode[5:4] == 2'b00 ? bc :
1235    opcode[5:4] == 2'b01 ? de :
1236    opcode[5:4] == 2'b10 ? hlx : sp;
1237// Второй операнд для ADC|SBC HL, r16
1238wire [16:0] ed_hl_op2 = (
1239    i_data[5:4] == 2'b00 ? bc :
1240    i_data[5:4] == 2'b01 ? de :
1241    i_data[5:4] == 2'b10 ? hl : sp) + af[CF];
1242// Расчет результата
1243wire [16:0] do_hl_add = hlx + do_hl_op2;
1244wire [16:0] ed_hl_adc = hl  + ed_hl_op2;
1245wire [16:0] ed_hl_sbc = hl  - ed_hl_op2;
1246// Расстановка флагов
1247wire [ 7:0] do_hl_flag = {
1248    af[SF],
1249    af[ZF],
1250    do_hl_add[5+8],
1251    hlx[12]^do_hl_op2[12]^do_hl_add[12], // H
1252    do_hl_add[3+8],
1253    af[PF],
1254    1'b0,           // N=0
1255    do_hl_add[16]   // C=x
1256};
1257// Флаги после сложения HL + r16
1258wire [ 7:0] hl_adc_flag = {
1259    ed_hl_adc[15],
1260    ed_hl_adc[15:0] == 0,
1261    ed_hl_adc[13],
1262    ed_hl_adc[12]^hl[12]^ed_hl_op2[12],
1263    ed_hl_adc[11],
1264    (hl[15] == ed_hl_op2[15]) && (ed_hl_adc[15] ^ hl[15]),
1265    1'b0,
1266    ed_hl_adc[16]
1267};
1268// Флаги после вычитания HL - r16
1269wire [ 7:0] hl_sbc_flag = {
1270    ed_hl_sbc[15],
1271    ed_hl_sbc[15:0] == 0,
1272    ed_hl_sbc[13],
1273    ed_hl_sbc[12]^hl[12]^ed_hl_op2[12],
1274    ed_hl_sbc[11],
1275    (hl[15] ^ ed_hl_op2[15]) && (ed_hl_sbc[15] ^ hl[15]),
1276    1'b1,
1277    ed_hl_sbc[16]
1278};
1279// RLD|RRD
1280// -----------------------------------------------------------------------------
1281wire [7:0] rrd_w = {af[3:0], i_data[7:4]};
1282wire [7:0] rrd_a = {af[7:4], i_data[3:0]};
1283wire [7:0] rld_w = {i_data[3:0], af[3:0]};
1284wire [7:0] rld_a = {af[7:4], i_data[7:4]};
1285// LDI, CPI, INI, OUTI
1286// -----------------------------------------------------------------------------
1287wire [3:0] ldixy = af[7:0] + i_data;
1288wire [3:0] cpixy = op1 - op2 - alu_f[4];
1289wire [7:0] b_dec = bc[15:8] - 1;
1290// BIT
1291// -----------------------------------------------------------------------------
1292wire bit_zf = ~op1[ op2[2:0] ];
1293wire bit_sf = (op2[2:0] == 7) && !bit_zf;
1294// Не префиксированные BITs устанавливают Y/X флаги
1295wire [7:0] bit_flags    = {bit_sf, bit_zf, op1[5],  1'b1, op1[3],  bit_zf, 1'b0, af[CF]};
1296wire [7:0] bit_flags_xx = {bit_sf, bit_zf, af[F5F], 1'b1, af[F3F], bit_zf, 1'b0, af[CF]};
1297// RES|SET, зависит от op2[3]
1298// -----------------------------------------------------------------------------
1299wire [7:0] rsop =
1300    op2[2:0] == 0 ? {op1[7:1], op2[3]} :
1301    op2[2:0] == 1 ? {op1[7:2], op2[3], op1[  0]} :
1302    op2[2:0] == 2 ? {op1[7:3], op2[3], op1[1:0]} :
1303    op2[2:0] == 3 ? {op1[7:4], op2[3], op1[2:0]} :
1304    op2[2:0] == 4 ? {op1[7:5], op2[3], op1[3:0]} :
1305    op2[2:0] == 5 ? {op1[7:6], op2[3], op1[4:0]} :
1306    op2[2:0] == 6 ? {op1[7],   op2[3], op1[5:0]} :
1307                   {           op2[3], op1[6:0]};
1308// Запись в регистры на обратном фронте
1309// -----------------------------------------------------------------------------
1310always @(negedge clock)
1311if (reset_n == 1'b0) begin
1312    af <= 16'hFFFF;
1313    sp <= 16'hFFFF;
1314end
1315else if (hold) begin
1316    // Особая запись в регистры
1317    if (exxw)
1318    case (exxw)
1319        // EX AF, AF'
1320        spec_exaf: begin af <= af_prime; af_prime <= af; end
1321        // EXX
1322        spec_exx: begin
1323            bc_prime <= bc; bc <= bc_prime;
1324            de_prime <= de; de <= de_prime;
1325            hl_prime <= hl; hl <= hl_prime;
1326        end
1327        // EX DE, HL
1328        spec_exdehl: begin de <= hl; hl <= de; end
1329    endcase
1330    // Работа со строками
1331    else if (ldcmd)
1332    case (ldcmd)
1333        ldcmd_ldi: begin bc <= bc - 1; hl <= hl + 1; de <= de + 1; end
1334        ldcmd_ldd: begin bc <= bc - 1; hl <= hl - 1; de <= de - 1; end
1335        ldcmd_cpi: begin bc <= bc - 1; hl <= hl + 1; end
1336        ldcmd_cpd: begin bc <= bc - 1; hl <= hl - 1; end
1337    endcase
1338    // Запись результата в 16-битный регистр
1339    else if (reg_w16)
1340    case (reg_id)
1341        0: bc <= reg_dt;
1342        1: de <= reg_dt;
1343        2: case (prefix) 0: hl <= reg_dt; 1: ix <= reg_dt; 2: iy <= reg_dt; endcase
1344        3: sp <= reg_dt;
1345    endcase
1346    // Запись в 8-битный регистр
1347    else if (reg_w8)
1348    case (reg_id)
1349        0: bc[15:8] <= reg_dt;
1350        1: bc[ 7:0] <= reg_dt;
1351        2: de[15:8] <= reg_dt;
1352        3: de[ 7:0] <= reg_dt;
1353        4: case (prefix) 0: hl[15:8] <= reg_dt; 1: ix[15:8] <= reg_dt; 2: iy[15:8] <= reg_dt; endcase
1354        5: case (prefix) 0: hl[ 7:0] <= reg_dt; 1: ix[ 7:0] <= reg_dt; 2: iy[ 7:0] <= reg_dt; endcase
1355        7: af[ 7:0] <= reg_dt;
1356    endcase
1357    // Запись флагов из АЛУ
1358    if      (reg_wfex) af[15:8] <= flag_ex;
1359    else if (reg_wf)   af[15:8] <= alu_f;
1360    // Установка следующего префикса
1361    prefix <= set_prefix;
1362end
1363endmodule