§ Код процессора
Процессор проходит все тесты 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